]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Jul 2017 19:26:13 +0000 (12:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Jul 2017 19:26:13 +0000 (12:26 -0700)
Pull clk updates from Stephen Boyd:
 "This time we've got one core change to introduce a bulk clk_get API,
  some new clk drivers and updates for old ones. The diff is pretty
  spread out across a handful of different SoC clk drivers for Broadcom,
  TI, Qualcomm, Renesas, Rockchip, Samsung, and Allwinner, mostly due to
  the introduction of new drivers.

  Core:
   - New clk bulk get APIs
   - Clk divider APIs gained the ability to consider a different parent
     than the current one

  New Drivers:
   - Renesas r8a779{0,1,2,4} CPG/MSSR
   - TI Keystone SCI firmware controlled clks and OMAP4 clkctrl
   - Qualcomm IPQ8074 SoCs
   - Cortina Systems Gemini (SL3516/CS3516)
   - Rockchip rk3128 SoCs
   - Allwinner A83T clk control units
   - Broadcom Stingray SoCs
   - CPU clks for Mediatek MT8173/MT2701/MT7623 SoCs

  Removed Drivers:
   - Old non-DT version of the Realview clk driver

  Updates:
   - Renesas Kconfig/Makefile cleanups
   - Amlogic CEC EE clk support
   - Improved Armada 7K/8K cp110 clk support
   - Rockchip clk id exposing, critical clk markings
   - Samsung converted to clk_hw registration APIs
   - Fixes for Samsung exynos5420 audio clks
   - USB2 clks for Hisilicon hi3798cv200 SoC and video/camera clks for
     hi3660"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (147 commits)
  clk: gemini: Read status before using the value
  clk: scpi: error when clock fails to register
  clk: at91: Add sama5d2 suspend/resume
  gpio: dt-bindings: Add documentation for gpio controllers on Armada 7K/8K
  clk: keystone: TI_SCI_PROTOCOL is needed for clk driver
  clk: samsung: audss: Fix silent hang on Exynos4412 due to disabled EPLL
  clk: uniphier: provide NAND controller clock rate
  clk: hisilicon: add usb2 clocks for hi3798cv200 SoC
  clk: Add Gemini SoC clock controller
  clk: iproc: Remove __init marking on iproc_pll_clk_setup()
  clk: bcm: Add clocks for Stingray SOC
  dt-bindings: clk: Extend binding doc for Stingray SOC
  clk: mediatek: export cpu multiplexer clock for MT8173 SoCs
  clk: mediatek: export cpu multiplexer clock for MT2701/MT7623 SoCs
  clk: mediatek: add missing cpu mux causing Mediatek cpufreq can't work
  clk: renesas: cpg-mssr: Use of_device_get_match_data() helper
  clk: hi6220: add acpu clock
  clk: zx296718: export I2S mux clocks
  clk: imx7d: create clocks behind rawnand clock gate
  clk: hi3660: Set PPLL2 to 2880M
  ...

145 files changed:
Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt
Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
Documentation/devicetree/bindings/clock/hi6220-clock.txt
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Documentation/devicetree/bindings/clock/qoriq-clock.txt
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/sun8i-de2.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
Documentation/devicetree/bindings/clock/ti,sci-clk.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/ti-clkctrl.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio-mvebu.txt
MAINTAINERS
arch/mips/lantiq/clk.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/clk-generated.c
drivers/clk/at91/clk-peripheral.c
drivers/clk/at91/pmc.c
drivers/clk/at91/pmc.h
drivers/clk/bcm/Kconfig
drivers/clk/bcm/Makefile
drivers/clk/bcm/clk-bcm2835.c
drivers/clk/bcm/clk-iproc-pll.c
drivers/clk/bcm/clk-sr.c [new file with mode: 0644]
drivers/clk/clk-bulk.c [new file with mode: 0644]
drivers/clk/clk-conf.c
drivers/clk/clk-devres.c
drivers/clk/clk-divider.c
drivers/clk/clk-gemini.c [new file with mode: 0644]
drivers/clk/clk-palmas.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-scpi.c
drivers/clk/hisilicon/clk-hi3660.c
drivers/clk/hisilicon/clk-hi6220.c
drivers/clk/hisilicon/crg-hi3798cv200.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk-pllv3.c
drivers/clk/imx/clk.h
drivers/clk/keystone/Kconfig [new file with mode: 0644]
drivers/clk/keystone/Makefile
drivers/clk/keystone/sci-clk.c [new file with mode: 0644]
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-cpumux.c [new file with mode: 0644]
drivers/clk/mediatek/clk-cpumux.h [new file with mode: 0644]
drivers/clk/mediatek/clk-mt2701.c
drivers/clk/mediatek/clk-mt8173.c
drivers/clk/meson/Kconfig
drivers/clk/meson/gxbb.c
drivers/clk/meson/gxbb.h
drivers/clk/meson/meson8b.c
drivers/clk/mvebu/ap806-system-controller.c
drivers/clk/mvebu/armada-38x.c
drivers/clk/mvebu/cp110-system-controller.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/gcc-ipq8074.c [new file with mode: 0644]
drivers/clk/qcom/gcc-msm8916.c
drivers/clk/renesas/Kconfig
drivers/clk/renesas/Makefile
drivers/clk/renesas/clk-mstp.c
drivers/clk/renesas/clk-rcar-gen2.c
drivers/clk/renesas/r8a7745-cpg-mssr.c
drivers/clk/renesas/r8a7790-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a7791-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a7792-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a7794-cpg-mssr.c [new file with mode: 0644]
drivers/clk/renesas/r8a7795-cpg-mssr.c
drivers/clk/renesas/r8a7796-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.c
drivers/clk/renesas/renesas-cpg-mssr.h
drivers/clk/rockchip/Makefile
drivers/clk/rockchip/clk-rk3036.c
drivers/clk/rockchip/clk-rk3128.c [new file with mode: 0644]
drivers/clk/rockchip/clk-rk3228.c
drivers/clk/rockchip/clk-rk3288.c
drivers/clk/rockchip/clk-rk3368.c
drivers/clk/rockchip/clk-rk3399.c
drivers/clk/samsung/clk-cpu.c
drivers/clk/samsung/clk-exynos-audss.c
drivers/clk/samsung/clk-exynos-clkout.c
drivers/clk/samsung/clk-exynos5420.c
drivers/clk/samsung/clk-pll.c
drivers/clk/samsung/clk-pll.h
drivers/clk/samsung/clk-s3c2410-dclk.c
drivers/clk/samsung/clk-s5pv210-audss.c
drivers/clk/samsung/clk.c
drivers/clk/samsung/clk.h
drivers/clk/socfpga/clk-gate-a10.c
drivers/clk/socfpga/clk.h
drivers/clk/sunxi-ng/Kconfig
drivers/clk/sunxi-ng/Makefile
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun5i.h
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
drivers/clk/sunxi-ng/ccu-sun8i-a33.c
drivers/clk/sunxi-ng/ccu-sun8i-a83t.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun8i-a83t.h [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun8i-de2.c [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun8i-de2.h [new file with mode: 0644]
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
drivers/clk/sunxi-ng/ccu-sun8i-r.c
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
drivers/clk/sunxi-ng/ccu_div.c
drivers/clk/sunxi-ng/ccu_mp.c
drivers/clk/sunxi-ng/ccu_mult.c
drivers/clk/sunxi-ng/ccu_mux.c
drivers/clk/sunxi-ng/ccu_mux.h
drivers/clk/sunxi-ng/ccu_nkm.c
drivers/clk/sunxi-ng/ccu_reset.h
drivers/clk/ti/Makefile
drivers/clk/ti/clk-44xx.c
drivers/clk/ti/clkctrl.c [new file with mode: 0644]
drivers/clk/ti/clock.h
drivers/clk/uniphier/clk-uniphier-sys.c
drivers/clk/versatile/Makefile
drivers/clk/versatile/clk-realview.c [deleted file]
drivers/clk/zte/clk-zx296718.c
include/dt-bindings/clock/cortina,gemini-clock.h [new file with mode: 0644]
include/dt-bindings/clock/exynos5420.h
include/dt-bindings/clock/hi3660-clock.h
include/dt-bindings/clock/hi6220-clock.h
include/dt-bindings/clock/histb-clock.h
include/dt-bindings/clock/imx7d-clock.h
include/dt-bindings/clock/mt2701-clk.h
include/dt-bindings/clock/mt8173-clk.h
include/dt-bindings/clock/omap4.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-ipq8074.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7790-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7791-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7792-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7793-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/r8a7794-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/rk3128-cru.h [new file with mode: 0644]
include/dt-bindings/clock/sun5i-ccu.h
include/dt-bindings/clock/sun8i-a83t-ccu.h [new file with mode: 0644]
include/dt-bindings/clock/sun8i-de2.h [new file with mode: 0644]
include/dt-bindings/clock/zx296718-clock.h
include/dt-bindings/reset/sun8i-a83t-ccu.h [new file with mode: 0644]
include/dt-bindings/reset/sun8i-de2.h [new file with mode: 0644]
include/linux/clk-provider.h
include/linux/clk.h
include/linux/platform_data/clk-realview.h [deleted file]

index 8968371d84e240c607eaef5ab9ed4000969c14aa..0b887440e08a3bd606a07c34b7960dc1970b3cf3 100644 (file)
@@ -7,6 +7,14 @@ registers giving access to numerous features: clocks, pin-muxing and
 many other SoC configuration items. This DT binding allows to describe
 this system controller.
 
+For the top level node:
+ - compatible: must be: "syscon", "simple-mfd";
+  - reg: register area of the AP806 system controller
+
+Clocks:
+-------
+
+
 The Device Tree node representing the AP806 system controller provides
 a number of clocks:
 
@@ -17,19 +25,76 @@ a number of clocks:
 
 Required properties:
 
- - compatible: must be:
-     "marvell,ap806-system-controller", "syscon"
- - reg: register area of the AP806 system controller
+ - compatible: must be: "marvell,ap806-clock"
  - #clock-cells: must be set to 1
- - clock-output-names: must be defined to:
-    "ap-cpu-cluster-0", "ap-cpu-cluster-1", "ap-fixed", "ap-mss"
+
+Pinctrl:
+--------
+
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt.
+
+Required properties:
+- compatible must be "marvell,ap806-pinctrl",
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+name   pins    functions
+================================================================================
+mpp0   0       gpio, sdio(clk), spi0(clk)
+mpp1   1       gpio, sdio(cmd), spi0(miso)
+mpp2   2       gpio, sdio(d0), spi0(mosi)
+mpp3   3       gpio, sdio(d1), spi0(cs0n)
+mpp4   4       gpio, sdio(d2), i2c0(sda)
+mpp5   5       gpio, sdio(d3), i2c0(sdk)
+mpp6   6       gpio, sdio(ds)
+mpp7   7       gpio, sdio(d4), uart1(rxd)
+mpp8   8       gpio, sdio(d5), uart1(txd)
+mpp9   9       gpio, sdio(d6), spi0(cs1n)
+mpp10  10      gpio, sdio(d7)
+mpp11  11      gpio, uart0(txd)
+mpp12  12      gpio, sdio(pw_off), sdio(hw_rst)
+mpp13  13      gpio
+mpp14  14      gpio
+mpp15  15      gpio
+mpp16  16      gpio
+mpp17  17      gpio
+mpp18  18      gpio
+mpp19  19      gpio, uart0(rxd), sdio(pw_off)
+
+GPIO:
+-----
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/gpio/gpio-mvebu.txt.
+
+Required properties:
+
+- compatible: "marvell,armada-8k-gpio"
+
+- offset: offset address inside the syscon block
 
 Example:
+ap_syscon: system-controller@6f4000 {
+       compatible = "syscon", "simple-mfd";
+       reg = <0x6f4000 0x1000>;
 
-       syscon: system-controller@6f4000 {
-               compatible = "marvell,ap806-system-controller", "syscon";
+       ap_clk: clock {
+               compatible = "marvell,ap806-clock";
                #clock-cells = <1>;
-               clock-output-names = "ap-cpu-cluster-0", "ap-cpu-cluster-1",
-                                    "ap-fixed", "ap-mss";
-               reg = <0x6f4000 0x1000>;
        };
+
+       ap_pinctrl: pinctrl {
+               compatible = "marvell,ap806-pinctrl";
+       };
+
+       ap_gpio: gpio {
+               compatible = "marvell,armada-8k-gpio";
+               offset = <0x1040>;
+               ngpios = <19>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&ap_pinctrl 0 0 19>;
+       };
+};
index 07dbb358182ccd255baf2ed1220d5df9044f9dd7..171d02cadea478f50d5e95f52b489b8b11d77dc0 100644 (file)
@@ -7,6 +7,13 @@ Controller 0 and System Controller 1. This Device Tree binding allows
 to describe the first system controller, which provides registers to
 configure various aspects of the SoC.
 
+For the top level node:
+ - compatible: must be: "syscon", "simple-mfd";
+ - reg: register area of the CP110 system controller 0
+
+Clocks:
+-------
+
 The Device Tree node representing this System Controller 0 provides a
 number of clocks:
 
@@ -27,6 +34,7 @@ The following clocks are available:
    - 0 2       EIP
    - 0 3       Core
    - 0 4       NAND core
+   - 0 5       SDIO core
  - Gatable clocks
    - 1 0       Audio
    - 1 1       Comm Unit
@@ -56,28 +64,126 @@ The following clocks are available:
 Required properties:
 
  - compatible: must be:
-     "marvell,cp110-system-controller0", "syscon";
- - reg: register area of the CP110 system controller 0
+     "marvell,cp110-clock"
  - #clock-cells: must be set to 2
- - core-clock-output-names must be set to:
-       "cpm-apll", "cpm-ppv2-core", "cpm-eip", "cpm-core", "cpm-nand-core"
- - gate-clock-output-names must be set to:
-       "cpm-audio", "cpm-communit", "cpm-nand", "cpm-ppv2", "cpm-sdio",
-       "cpm-mg-domain", "cpm-mg-core", "cpm-xor1", "cpm-xor0", "cpm-gop-dp", "none",
-       "cpm-pcie_x10", "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", "cpm-sata",
-       "cpm-sata-usb", "cpm-main", "cpm-sd-mmc-gop", "none", "none", "cpm-slow-io",
-       "cpm-usb3h0", "cpm-usb3h1", "cpm-usb3dev", "cpm-eip150", "cpm-eip197";
+
+Pinctrl:
+--------
+
+For common binding part and usage, refer to the file
+Documentation/devicetree/bindings/pinctrl/marvell,mvebu-pinctrl.txt.
+
+Required properties:
+
+- compatible: "marvell,armada-7k-pinctrl",
+  "marvell,armada-8k-cpm-pinctrl" or "marvell,armada-8k-cps-pinctrl"
+  depending on the specific variant of the SoC being used.
+
+Available mpp pins/groups and functions:
+Note: brackets (x) are not part of the mpp name for marvell,function and given
+only for more detailed description in this document.
+
+name   pins    functions
+================================================================================
+mpp0   0       gpio, dev(ale1), au(i2smclk), ge0(rxd3), tdm(pclk), ptp(pulse), mss_i2c(sda), uart0(rxd), sata0(present_act), ge(mdio)
+mpp1   1       gpio, dev(ale0), au(i2sdo_spdifo), ge0(rxd2), tdm(drx), ptp(clk), mss_i2c(sck), uart0(txd), sata1(present_act), ge(mdc)
+mpp2   2       gpio, dev(ad15), au(i2sextclk), ge0(rxd1), tdm(dtx), mss_uart(rxd), ptp(pclk_out), i2c1(sck), uart1(rxd), sata0(present_act), xg(mdc)
+mpp3   3       gpio, dev(ad14), au(i2slrclk), ge0(rxd0), tdm(fsync), mss_uart(txd), pcie(rstoutn), i2c1(sda), uart1(txd), sata1(present_act), xg(mdio)
+mpp4   4       gpio, dev(ad13), au(i2sbclk), ge0(rxctl), tdm(rstn), mss_uart(rxd), uart1(cts), pcie0(clkreq), uart3(rxd), ge(mdc)
+mpp5   5       gpio, dev(ad12), au(i2sdi), ge0(rxclk), tdm(intn), mss_uart(txd), uart1(rts), pcie1(clkreq), uart3(txd), ge(mdio)
+mpp6   6       gpio, dev(ad11), ge0(txd3), spi0(csn2), au(i2sextclk), sata1(present_act), pcie2(clkreq), uart0(rxd), ptp(pulse)
+mpp7   7       gpio, dev(ad10), ge0(txd2), spi0(csn1), spi1(csn1), sata0(present_act), led(data), uart0(txd), ptp(clk)
+mpp8   8       gpio, dev(ad9), ge0(txd1), spi0(csn0), spi1(csn0), uart0(cts), led(stb), uart2(rxd), ptp(pclk_out), synce1(clk)
+mpp9   9       gpio, dev(ad8), ge0(txd0), spi0(mosi), spi1(mosi), pcie(rstoutn), synce2(clk)
+mpp10  10      gpio, dev(readyn), ge0(txctl), spi0(miso), spi1(miso), uart0(cts), sata1(present_act)
+mpp11  11      gpio, dev(wen1), ge0(txclkout), spi0(clk), spi1(clk), uart0(rts), led(clk), uart2(txd), sata0(present_act)
+mpp12  12      gpio, dev(clk_out), nf(rbn1), spi1(csn1), ge0(rxclk)
+mpp13  13      gpio, dev(burstn), nf(rbn0), spi1(miso), ge0(rxctl), mss_spi(miso)
+mpp14  14      gpio, dev(bootcsn), dev(csn0), spi1(csn0), spi0(csn3), au(i2sextclk), spi0(miso), sata0(present_act), mss_spi(csn)
+mpp15  15      gpio, dev(ad7), spi1(mosi), spi0(mosi), mss_spi(mosi), ptp(pulse_cp2cp)
+mpp16  16      gpio, dev(ad6), spi1(clk), mss_spi(clk)
+mpp17  17      gpio, dev(ad5), ge0(txd3)
+mpp18  18      gpio, dev(ad4), ge0(txd2), ptp(clk_cp2cp)
+mpp19  19      gpio, dev(ad3), ge0(txd1), wakeup(out_cp2cp)
+mpp20  20      gpio, dev(ad2), ge0(txd0)
+mpp21  21      gpio, dev(ad1), ge0(txctl), sei(in_cp2cp)
+mpp22  22      gpio, dev(ad0), ge0(txclkout), wakeup(in_cp2cp)
+mpp23  23      gpio, dev(a1), au(i2smclk), link(rd_in_cp2cp)
+mpp24  24      gpio, dev(a0), au(i2slrclk)
+mpp25  25      gpio, dev(oen), au(i2sdo_spdifo)
+mpp26  26      gpio, dev(wen0), au(i2sbclk)
+mpp27  27      gpio, dev(csn0), spi1(miso), mss_gpio4, ge0(rxd3), spi0(csn4), ge(mdio), sata0(present_act), uart0(rts), rei(in_cp2cp)
+mpp28  28      gpio, dev(csn1), spi1(csn0), mss_gpio5, ge0(rxd2), spi0(csn5), pcie2(clkreq), ptp(pulse), ge(mdc), sata1(present_act), uart0(cts), led(data)
+mpp29  29      gpio, dev(csn2), spi1(mosi), mss_gpio6, ge0(rxd1), spi0(csn6), pcie1(clkreq), ptp(clk), mss_i2c(sda), sata0(present_act), uart0(rxd), led(stb)
+mpp30  30      gpio, dev(csn3), spi1(clk), mss_gpio7, ge0(rxd0), spi0(csn7), pcie0(clkreq), ptp(pclk_out), mss_i2c(sck), sata1(present_act), uart0(txd), led(clk)
+mpp31  31      gpio, dev(a2), mss_gpio4, pcie(rstoutn), ge(mdc)
+mpp32  32      gpio, mii(col), mii(txerr), mss_spi(miso), tdm(drx), au(i2sextclk), au(i2sdi), ge(mdio), sdio(v18_en), pcie1(clkreq), mss_gpio0
+mpp33  33      gpio, mii(txclk), sdio(pwr10), mss_spi(csn), tdm(fsync), au(i2smclk), sdio(bus_pwr), xg(mdio), pcie2(clkreq), mss_gpio1
+mpp34  34      gpio, mii(rxerr), sdio(pwr11), mss_spi(mosi), tdm(dtx), au(i2slrclk), sdio(wr_protect), ge(mdc), pcie0(clkreq), mss_gpio2
+mpp35  35      gpio, sata1(present_act), i2c1(sda), mss_spi(clk), tdm(pclk), au(i2sdo_spdifo), sdio(card_detect), xg(mdio), ge(mdio), pcie(rstoutn), mss_gpio3
+mpp36  36      gpio, synce2(clk), i2c1(sck), ptp(clk), synce1(clk), au(i2sbclk), sata0(present_act), xg(mdc), ge(mdc), pcie2(clkreq), mss_gpio5
+mpp37  37      gpio, uart2(rxd), i2c0(sck), ptp(pclk_out), tdm(intn), mss_i2c(sck), sata1(present_act), ge(mdc), xg(mdc), pcie1(clkreq), mss_gpio6, link(rd_out_cp2cp)
+mpp38  38      gpio, uart2(txd), i2c0(sda), ptp(pulse), tdm(rstn), mss_i2c(sda), sata0(present_act), ge(mdio), xg(mdio), au(i2sextclk), mss_gpio7, ptp(pulse_cp2cp)
+mpp39  39      gpio, sdio(wr_protect), au(i2sbclk), ptp(clk), spi0(csn1), sata1(present_act), mss_gpio0
+mpp40  40      gpio, sdio(pwr11), synce1(clk), mss_i2c(sda), au(i2sdo_spdifo), ptp(pclk_out), spi0(clk), uart1(txd), ge(mdio), sata0(present_act), mss_gpio1
+mpp41  41      gpio, sdio(pwr10), sdio(bus_pwr), mss_i2c(sck), au(i2slrclk), ptp(pulse), spi0(mosi), uart1(rxd), ge(mdc), sata1(present_act), mss_gpio2, rei(out_cp2cp)
+mpp42  42      gpio, sdio(v18_en), sdio(wr_protect), synce2(clk), au(i2smclk), mss_uart(txd), spi0(miso), uart1(cts), xg(mdc), sata0(present_act), mss_gpio4
+mpp43  43      gpio, sdio(card_detect), synce1(clk), au(i2sextclk), mss_uart(rxd), spi0(csn0), uart1(rts), xg(mdio), sata1(present_act), mss_gpio5, wakeup(out_cp2cp)
+mpp44  44      gpio, ge1(txd2), uart0(rts), ptp(clk_cp2cp)
+mpp45  45      gpio, ge1(txd3), uart0(txd), pcie(rstoutn)
+mpp46  46      gpio, ge1(txd1), uart1(rts)
+mpp47  47      gpio, ge1(txd0), spi1(clk), uart1(txd), ge(mdc)
+mpp48  48      gpio, ge1(txctl_txen), spi1(mosi), xg(mdc), wakeup(in_cp2cp)
+mpp49  49      gpio, ge1(txclkout), mii(crs), spi1(miso), uart1(rxd), ge(mdio), pcie0(clkreq), sdio(v18_en), sei(out_cp2cp)
+mpp50  50      gpio, ge1(rxclk), mss_i2c(sda), spi1(csn0), uart2(txd), uart0(rxd), xg(mdio), sdio(pwr11)
+mpp51  51      gpio, ge1(rxd0), mss_i2c(sck), spi1(csn1), uart2(rxd), uart0(cts), sdio(pwr10)
+mpp52  52      gpio, ge1(rxd1), synce1(clk), synce2(clk), spi1(csn2), uart1(cts), led(clk), pcie(rstoutn), pcie0(clkreq)
+mpp53  53      gpio, ge1(rxd2), ptp(clk), spi1(csn3), uart1(rxd), led(stb), sdio(led)
+mpp54  54      gpio, ge1(rxd3), synce2(clk), ptp(pclk_out), synce1(clk), led(data), sdio(hw_rst), sdio(wr_protect)
+mpp55  55      gpio, ge1(rxctl_rxdv), ptp(pulse), sdio(led), sdio(card_detect)
+mpp56  56      gpio, tdm(drx), au(i2sdo_spdifo), spi0(clk), uart1(rxd), sata1(present_act), sdio(clk)
+mpp57  57      gpio, mss_i2c(sda), ptp(pclk_out), tdm(intn), au(i2sbclk), spi0(mosi), uart1(txd), sata0(present_act), sdio(cmd)
+mpp58  58      gpio, mss_i2c(sck), ptp(clk), tdm(rstn), au(i2sdi), spi0(miso), uart1(cts), led(clk), sdio(d0)
+mpp59  59      gpio, mss_gpio7, synce2(clk), tdm(fsync), au(i2slrclk), spi0(csn0), uart0(cts), led(stb), uart1(txd), sdio(d1)
+mpp60  60      gpio, mss_gpio6, ptp(pulse), tdm(dtx), au(i2smclk), spi0(csn1), uart0(rts), led(data), uart1(rxd), sdio(d2)
+mpp61  61      gpio, mss_gpio5, ptp(clk), tdm(pclk), au(i2sextclk), spi0(csn2), uart0(txd), uart2(txd), sata1(present_act), ge(mdio), sdio(d3)
+mpp62  62      gpio, mss_gpio4, synce1(clk), ptp(pclk_out), sata1(present_act), spi0(csn3), uart0(rxd), uart2(rxd), sata0(present_act), ge(mdc)
+
+GPIO:
+-----
+
+For common binding part and usage, refer to
+Documentation/devicetree/bindings/gpio/gpio-mvebu.txt.
+
+Required properties:
+
+- compatible: "marvell,armada-8k-gpio"
+
+- offset: offset address inside the syscon block
 
 Example:
 
-       cpm_syscon0: system-controller@440000 {
-               compatible = "marvell,cp110-system-controller0", "syscon";
-               reg = <0x440000 0x1000>;
+cpm_syscon0: system-controller@440000 {
+       compatible = "syscon", "simple-mfd";
+       reg = <0x440000 0x1000>;
+
+       cpm_clk: clock {
+               compatible = "marvell,cp110-clock";
                #clock-cells = <2>;
-               core-clock-output-names = "cpm-apll", "cpm-ppv2-core", "cpm-eip", "cpm-core", "cpm-nand-core";
-               gate-clock-output-names = "cpm-audio", "cpm-communit", "cpm-nand", "cpm-ppv2", "cpm-sdio",
-                       "cpm-mg-domain", "cpm-mg-core", "cpm-xor1", "cpm-xor0", "cpm-gop-dp", "none",
-                       "cpm-pcie_x10", "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", "cpm-sata",
-                       "cpm-sata-usb", "cpm-main", "cpm-sd-mmc-gop", "none", "none", "cpm-slow-io",
-                       "cpm-usb3h0", "cpm-usb3h1", "cpm-usb3dev", "cpm-eip150", "cpm-eip197";
        };
+
+       cpm_pinctrl: pinctrl {
+               compatible = "marvell,armada-8k-cpm-pinctrl";
+       };
+
+       cpm_gpio1: gpio@100 {
+               compatible = "marvell,armada-8k-gpio";
+               offset = <0x100>;
+               ngpios = <32>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               gpio-ranges = <&cpm_pinctrl 0 0 32>;
+               status = "disabled";
+       };
+
+};
index 2b7b3fa588d7e57b666ae13d1587bd218558e01f..606da38c095951f3559fb89ab763f0b6d748ccad 100644 (file)
@@ -1,11 +1,14 @@
-* Amlogic Meson8b Clock and Reset Unit
+* Amlogic Meson8, Meson8b and Meson8m2 Clock and Reset Unit
 
-The Amlogic Meson8b clock controller generates and supplies clock to various
-controllers within the SoC.
+The Amlogic Meson8 / Meson8b / Meson8m2 clock controller generates and
+supplies clock to various controllers within the SoC.
 
 Required Properties:
 
-- compatible: should be "amlogic,meson8b-clkc"
+- compatible: must be one of:
+       - "amlogic,meson8-clkc" for Meson8 (S802) SoCs
+       - "amlogic,meson8b-clkc" for Meson8 (S805) SoCs
+       - "amlogic,meson8m2-clkc" for Meson8m2 (S812) SoCs
 - reg: it must be composed by two tuples:
        0) physical base address of the xtal register and length of memory
           mapped region.
index e4d5feaebc292c7944f32fe5484c2839444f7658..ef3deb7b86eaf18468a2b779c9b7786c92d158d0 100644 (file)
@@ -11,6 +11,7 @@ Required Properties:
 - compatible: the compatible should be one of the following strings to
        indicate the clock controller functionality.
 
+       - "hisilicon,hi6220-acpu-sctrl"
        - "hisilicon,hi6220-aoctrl"
        - "hisilicon,hi6220-sysctrl"
        - "hisilicon,hi6220-mediactrl"
index 5b4dfc1ea54fb592cc1ce3fd10d9d6a1c105d525..551d03be966587fe27d9f486c0f5b712a9f6f016 100644 (file)
@@ -8,6 +8,7 @@ Required properties :
                        "qcom,gcc-apq8084"
                        "qcom,gcc-ipq8064"
                        "qcom,gcc-ipq4019"
+                       "qcom,gcc-ipq8074"
                        "qcom,gcc-msm8660"
                        "qcom,gcc-msm8916"
                        "qcom,gcc-msm8960"
index 6ed469c66b32f42c4bfb62849ce5451618d5067e..6498e1fdbb33a2a4661638d501dca842b500bb0d 100644 (file)
@@ -57,6 +57,11 @@ Optional properties:
 - clocks: If clock-frequency is not specified, sysclk may be provided
        as an input clock.  Either clock-frequency or clocks must be
        provided.
+       A second input clock, called "coreclk", may be provided if
+       core PLLs are based on a different input clock from the
+       platform PLL.
+- clock-names: Required if a coreclk is present.  Valid names are
+       "sysclk" and "coreclk".
 
 2. Clock Provider
 
@@ -73,6 +78,7 @@ second cell is the clock index for the specified type.
        2       hwaccel         index (n in CLKCGnHWACSR)
        3       fman            0 for fm1, 1 for fm2
        4       platform pll    0=pll, 1=pll/2, 2=pll/3, 3=pll/4
+       5       coreclk         must be 0
 
 3. Example
 
index f4f944d8130818570e1b58eae012be77b4872935..0cd894f987a38e8137acf03b3a441bfd5070d0c4 100644 (file)
@@ -15,6 +15,11 @@ Required Properties:
   - compatible: Must be one of:
       - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M)
       - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E)
+      - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2)
+      - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W)
+      - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H)
+      - "renesas,r8a7793-cpg-mssr" for the r8a7793 SoC (R-Car M2-N)
+      - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2)
       - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3)
       - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W)
 
@@ -24,9 +29,10 @@ Required Properties:
   - clocks: References to external parent clocks, one entry for each entry in
     clock-names
   - clock-names: List of external parent clock names. Valid names are:
-      - "extal" (r8a7743, r8a7745, r8a7795, r8a7796)
+      - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794,
+                r8a7795, r8a7796)
       - "extalr" (r8a7795, r8a7796)
-      - "usb_extal" (r8a7743, r8a7745)
+      - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794)
 
   - #clock-cells: Must be 2
       - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt
new file mode 100644 (file)
index 0000000..455a9a0
--- /dev/null
@@ -0,0 +1,56 @@
+* Rockchip RK3128 Clock and Reset Unit
+
+The RK3128 clock controller generates and supplies clock to various
+controllers within the SoC and also implements a reset controller for SoC
+peripherals.
+
+Required Properties:
+
+- compatible: should be "rockchip,rk3128-cru"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Optional Properties:
+
+- rockchip,grf: phandle to the syscon managing the "general register files"
+  If missing pll rates are not changeable, due to the missing pll lock status.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. All available clocks are defined as
+preprocessor macros in the dt-bindings/clock/rk3128-cru.h headers and can be
+used in device tree sources. Similar macros exist for the reset sources in
+these files.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It is expected
+that they are defined using standard clock bindings with following
+clock-output-names:
+ - "xin24m" - crystal input - required,
+ - "ext_i2s" - external I2S clock - optional,
+ - "gmac_clkin" - external GMAC clock - optional
+
+Example: Clock controller node:
+
+       cru: cru@20000000 {
+               compatible = "rockchip,rk3128-cru";
+               reg = <0x20000000 0x1000>;
+               rockchip,grf = <&grf>;
+
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller:
+
+       uart2: serial@20068000 {
+               compatible = "rockchip,serial";
+               reg = <0x20068000 0x100>;
+               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+               clock-frequency = <24000000>;
+               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+               clock-names = "sclk_uart", "pclk_uart";
+       };
diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
new file mode 100644 (file)
index 0000000..631d27c
--- /dev/null
@@ -0,0 +1,31 @@
+Allwinner Display Engine 2.0 Clock Control Binding
+--------------------------------------------------
+
+Required properties :
+- compatible: must contain one of the following compatibles:
+               - "allwinner,sun8i-a83t-de2-clk"
+               - "allwinner,sun8i-v3s-de2-clk"
+               - "allwinner,sun50i-h5-de2-clk"
+
+- reg: Must contain the registers base address and length
+- clocks: phandle to the clocks feeding the display engine subsystem.
+         Three are needed:
+  - "mod": the display engine module clock
+  - "bus": the bus clock for the whole display engine subsystem
+- clock-names: Must contain the clock names described just above
+- resets: phandle to the reset control for the display engine subsystem.
+- #clock-cells : must contain 1
+- #reset-cells : must contain 1
+
+Example:
+de2_clocks: clock@1000000 {
+       compatible = "allwinner,sun8i-a83t-de2-clk";
+       reg = <0x01000000 0x100000>;
+       clocks = <&ccu CLK_BUS_DE>,
+                <&ccu CLK_DE>;
+       clock-names = "bus",
+                     "mod";
+       resets = <&ccu RST_BUS_DE>;
+       #clock-cells = <1>;
+       #reset-cells = <1>;
+};
index f465647a4dd219a7718c26c88725a42dc5106f0d..df9fad58facdc22b995e9066275cac3344724a6d 100644 (file)
@@ -6,6 +6,8 @@ Required properties :
                - "allwinner,sun6i-a31-ccu"
                - "allwinner,sun8i-a23-ccu"
                - "allwinner,sun8i-a33-ccu"
+               - "allwinner,sun8i-a83t-ccu"
+               - "allwinner,sun8i-a83t-r-ccu"
                - "allwinner,sun8i-h3-ccu"
                - "allwinner,sun8i-h3-r-ccu"
                - "allwinner,sun8i-v3s-ccu"
@@ -18,11 +20,12 @@ Required properties :
 - clocks: phandle to the oscillators feeding the CCU. Two are needed:
   - "hosc": the high frequency oscillator (usually at 24MHz)
   - "losc": the low frequency oscillator (usually at 32kHz)
+           On the A83T, this is the internal 16MHz oscillator divided by 512
 - clock-names: Must contain the clock names described just above
 - #clock-cells : must contain 1
 - #reset-cells : must contain 1
 
-For the PRCM CCUs on H3/A64, two more clocks are needed:
+For the PRCM CCUs on A83T/H3/A64, two more clocks are needed:
 - "pll-periph": the SoC's peripheral PLL from the main CCU
 - "iosc": the SoC's internal frequency oscillator
 
diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
new file mode 100644 (file)
index 0000000..1e884c4
--- /dev/null
@@ -0,0 +1,37 @@
+Texas Instruments TI-SCI Clocks
+===============================
+
+All clocks on Texas Instruments' SoCs that contain a System Controller,
+are only controlled by this entity. Communication between a host processor
+running an OS and the System Controller happens through a protocol known
+as TI-SCI[1]. This clock implementation plugs into the common clock
+framework and makes use of the TI-SCI protocol on clock API requests.
+
+[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+Required properties:
+-------------------
+- compatible: Must be "ti,k2g-sci-clk"
+- #clock-cells: Shall be 2.
+  In clock consumers, this cell represents the device ID and clock ID
+  exposed by the PM firmware. The assignments can be found in the header
+  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
+  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
+  is the SoC involved, for example 'k2g'.
+
+Examples:
+--------
+
+pmmc: pmmc {
+       compatible = "ti,k2g-sci";
+
+       k2g_clks: clocks {
+               compatible = "ti,k2g-sci-clk";
+               #clock-cells = <2>;
+       };
+};
+
+uart0: serial@2530c00 {
+       compatible = "ns16550a";
+       clocks = <&k2g_clks 0x2c 0>;
+};
diff --git a/Documentation/devicetree/bindings/clock/ti-clkctrl.txt b/Documentation/devicetree/bindings/clock/ti-clkctrl.txt
new file mode 100644 (file)
index 0000000..48ee699
--- /dev/null
@@ -0,0 +1,56 @@
+Texas Instruments clkctrl clock binding
+
+Texas Instruments SoCs can have a clkctrl clock controller for each
+interconnect target module. The clkctrl clock controller manages functional
+and interface clocks for each module. Each clkctrl controller can also
+gate one or more optional functional clocks for a module, and can have one
+or more clock muxes. There is a clkctrl clock controller typically for each
+interconnect target module on omap4 and later variants.
+
+The clock consumers can specify the index of the clkctrl clock using
+the hardware offset from the clkctrl instance register space. The optional
+clocks can be specified by clkctrl hardware offset and the index of the
+optional clock.
+
+For more information, please see the Linux clock framework binding at
+Documentation/devicetree/bindings/clock/clock-bindings.txt.
+
+Required properties :
+- compatible : shall be "ti,clkctrl"
+- #clock-cells : shall contain 2 with the first entry being the instance
+                offset from the clock domain base and the second being the
+                clock index
+
+Example: Clock controller node on omap 4430:
+
+&cm2 {
+       l4per: cm@1400 {
+               cm_l4per@0 {
+                       cm_l4per_clkctrl: clk@20 {
+                               compatible = "ti,clkctrl";
+                               reg = <0x20 0x1b0>;
+                               #clock-cells = <2>;
+                       };
+               };
+       };
+};
+
+Example: Preprocessor helper macros in dt-bindings/clock/ti-clkctrl.h
+
+#define OMAP4_CLKCTRL_OFFSET           0x20
+#define OMAP4_CLKCTRL_INDEX(offset)    ((offset) - OMAP4_CLKCTRL_OFFSET)
+#define MODULEMODE_HWCTRL              1
+#define MODULEMODE_SWCTRL              2
+
+#define OMAP4_GPTIMER10_CLKTRL         OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_GPTIMER11_CLKTRL         OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_GPTIMER2_CLKTRL          OMAP4_CLKCTRL_INDEX(0x38)
+...
+#define OMAP4_GPIO2_CLKCTRL            OMAP_CLKCTRL_INDEX(0x60)
+
+Example: Clock consumer node for GPIO2:
+
+&gpio2 {
+       clocks = <&cm_l4per_clkctrl OMAP4_GPIO2_CLKCTRL 0
+                &cm_l4per_clkctrl OMAP4_GPIO2_CLKCTRL 8>;
+};
index 01e331a5f3e7491fba25188b5a12e91722057e42..38ca2201e8ae1f99f83eb6c8e10fca42955c1eed 100644 (file)
@@ -2,17 +2,27 @@
 
 Required properties:
 
-- compatible : Should be "marvell,orion-gpio", "marvell,mv78200-gpio"
-  or "marvell,armadaxp-gpio". "marvell,orion-gpio" should be used for
-  Orion, Kirkwood, Dove, Discovery (except MV78200) and Armada
-  370. "marvell,mv78200-gpio" should be used for the Discovery
-  MV78200. "marvel,armadaxp-gpio" should be used for all Armada XP
-  SoCs (MV78230, MV78260, MV78460).
+- compatible : Should be "marvell,orion-gpio", "marvell,mv78200-gpio",
+  "marvell,armadaxp-gpio" or "marvell,armada-8k-gpio".
+
+    "marvell,orion-gpio" should be used for Orion, Kirkwood, Dove,
+    Discovery (except MV78200) and Armada 370. "marvell,mv78200-gpio"
+    should be used for the Discovery MV78200.
+
+    "marvel,armadaxp-gpio" should be used for all Armada XP SoCs
+    (MV78230, MV78260, MV78460).
+
+    "marvell,armada-8k-gpio" should be used for the Armada 7K and 8K
+    SoCs (either from AP or CP), see
+    Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt
+    and
+    Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
+    for specific details about the offset property.
 
 - reg: Address and length of the register set for the device. Only one
   entry is expected, except for the "marvell,armadaxp-gpio" variant
   for which two entries are expected: one for the general registers,
-  one for the per-cpu registers.
+  one for the per-cpu registers. Not used for marvell,armada-8k-gpio.
 
 - interrupts: The list of interrupts that are used for all the pins
   managed by this GPIO bank. There can be more than one interrupt
index 8c89ce7435d91ab51af3e0070130064902965cd2..101af8787cac9dae1a0bf18b16fdb2bdcb542ad8 100644 (file)
@@ -12872,6 +12872,8 @@ F:      Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
 F:     include/dt-bindings/genpd/k2g.h
 F:     drivers/soc/ti/ti_sci_pm_domains.c
 F:     Documentation/devicetree/bindings/reset/ti,sci-reset.txt
+F:     Documentation/devicetree/bindings/clock/ti,sci-clk.txt
+F:     drivers/clk/keystone/sci-clk.c
 F:     drivers/reset/reset-ti-sci.c
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
index 149f0513c4f5d0d4d5f37dfc009b1684eae5df07..a263d1b751ffe48d5f247d4c22ef2055e9e6cb31 100644 (file)
@@ -160,11 +160,6 @@ void clk_deactivate(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_deactivate);
 
-struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
-{
-       return NULL;
-}
-
 static inline u32 get_counter_resolution(void)
 {
        u32 res;
index 36cfea38135f6afc2266aecf19fee862e8110951..d406b087553fcbc436619168fa2fb434509b8fd9 100644 (file)
@@ -126,6 +126,15 @@ config COMMON_CLK_CS2000_CP
        help
          If you say yes here you get support for the CS2000 clock multiplier.
 
+config COMMON_CLK_GEMINI
+       bool "Clock driver for Cortina Systems Gemini SoC"
+       depends on ARCH_GEMINI || COMPILE_TEST
+       select MFD_SYSCON
+       select RESET_CONTROLLER
+       ---help---
+         This driver supports the SoC clocks on the Cortina Systems Gemini
+         platform, also known as SL3516 or CS3516.
+
 config COMMON_CLK_S2MPS11
        tristate "Clock driver for S2MPS1X/S5M8767 MFD"
        depends on MFD_SEC_CORE || COMPILE_TEST
@@ -164,13 +173,6 @@ config COMMON_CLK_XGENE
        ---help---
          Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
 
-config COMMON_CLK_KEYSTONE
-       tristate "Clock drivers for Keystone based SOCs"
-       depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
-       ---help---
-          Supports clock drivers for Keystone based SOCs. These SOCs have local
-         a power sleep control module that gate the clock to the IPs and PLLs.
-
 config COMMON_CLK_NXP
        def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
        select REGMAP_MMIO if ARCH_LPC32XX
@@ -219,6 +221,7 @@ config COMMON_CLK_VC5
 
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
+source "drivers/clk/keystone/Kconfig"
 source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
index c19983afcb81c9d1ec8e5059a1a29d70e97a4ca1..4f6a812342ed8ae7509d963e008110519241424c 100644 (file)
@@ -1,5 +1,5 @@
 # common clock types
-obj-$(CONFIG_HAVE_CLK)         += clk-devres.o
+obj-$(CONFIG_HAVE_CLK)         += clk-devres.o clk-bulk.o
 obj-$(CONFIG_CLKDEV_LOOKUP)    += clkdev.o
 obj-$(CONFIG_COMMON_CLK)       += clk.o
 obj-$(CONFIG_COMMON_CLK)       += clk-divider.o
@@ -25,6 +25,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925)      += clk-cdce925.o
 obj-$(CONFIG_ARCH_CLPS711X)            += clk-clps711x.o
 obj-$(CONFIG_COMMON_CLK_CS2000_CP)     += clk-cs2000-cp.o
 obj-$(CONFIG_ARCH_EFM32)               += clk-efm32gg.o
+obj-$(CONFIG_COMMON_CLK_GEMINI)                += clk-gemini.o
 obj-$(CONFIG_ARCH_HIGHBANK)            += clk-highbank.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)      += clk-max77686.o
 obj-$(CONFIG_ARCH_MB86S7X)             += clk-mb86s7x.o
@@ -61,7 +62,7 @@ obj-$(CONFIG_H8300)                   += h8300/
 obj-$(CONFIG_ARCH_HISI)                        += hisilicon/
 obj-$(CONFIG_ARCH_MXC)                 += imx/
 obj-$(CONFIG_MACH_INGENIC)             += ingenic/
-obj-$(CONFIG_COMMON_CLK_KEYSTONE)      += keystone/
+obj-$(CONFIG_ARCH_KEYSTONE)            += keystone/
 obj-$(CONFIG_MACH_LOONGSON32)          += loongson1/
 obj-$(CONFIG_ARCH_MEDIATEK)            += mediatek/
 obj-$(CONFIG_COMMON_CLK_AMLOGIC)       += meson/
@@ -75,7 +76,7 @@ obj-$(CONFIG_COMMON_CLK_NXP)          += nxp/
 obj-$(CONFIG_MACH_PISTACHIO)           += pistachio/
 obj-$(CONFIG_COMMON_CLK_PXA)           += pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)          += qcom/
-obj-$(CONFIG_ARCH_RENESAS)             += renesas/
+obj-y                                  += renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
 obj-$(CONFIG_COMMON_CLK_SAMSUNG)       += samsung/
 obj-$(CONFIG_ARCH_SIRF)                        += sirf/
index 4e1cd5aa69d8aa6c884a5a51198c7ce499b8ee93..f0b7ae904ce2c991d8a5f998734a77235de194ee 100644 (file)
@@ -260,13 +260,15 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
        gck->lock = lock;
        gck->range = *range;
 
+       clk_generated_startup(gck);
        hw = &gck->hw;
        ret = clk_hw_register(NULL, &gck->hw);
        if (ret) {
                kfree(gck);
                hw = ERR_PTR(ret);
-       } else
-               clk_generated_startup(gck);
+       } else {
+               pmc_register_id(id);
+       }
 
        return hw;
 }
index dc29fd979d3fc33695e68fcf48fd4de599f2d44f..7701183692308e8870a669658e8c24b4d14700e4 100644 (file)
@@ -367,8 +367,10 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
        if (ret) {
                kfree(periph);
                hw = ERR_PTR(ret);
-       } else
+       } else {
                clk_sam9x5_peripheral_autodiv(periph);
+               pmc_register_id(id);
+       }
 
        return hw;
 }
index 526df5ba042ddfd11a2bbe6441bccc6c1eb81f8d..775af473fe115b28f9963ff9fb44202249ecfdd6 100644 (file)
 #include <linux/clk/at91_pmc.h>
 #include <linux/of.h>
 #include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/proc-fns.h>
 
 #include "pmc.h"
 
+#define PMC_MAX_IDS 128
+
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
                          struct clk_range *range)
 {
@@ -41,3 +45,128 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname,
        return 0;
 }
 EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
+
+#ifdef CONFIG_PM
+static struct regmap *pmcreg;
+
+static u8 registered_ids[PMC_MAX_IDS];
+
+static struct
+{
+       u32 scsr;
+       u32 pcsr0;
+       u32 uckr;
+       u32 mor;
+       u32 mcfr;
+       u32 pllar;
+       u32 mckr;
+       u32 usb;
+       u32 imr;
+       u32 pcsr1;
+       u32 pcr[PMC_MAX_IDS];
+       u32 audio_pll0;
+       u32 audio_pll1;
+} pmc_cache;
+
+void pmc_register_id(u8 id)
+{
+       int i;
+
+       for (i = 0; i < PMC_MAX_IDS; i++) {
+               if (registered_ids[i] == 0) {
+                       registered_ids[i] = id;
+                       break;
+               }
+               if (registered_ids[i] == id)
+                       break;
+       }
+}
+
+static int pmc_suspend(void)
+{
+       int i;
+
+       regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.scsr);
+       regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0);
+       regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr);
+       regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor);
+       regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr);
+       regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar);
+       regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr);
+       regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb);
+       regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr);
+       regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1);
+
+       for (i = 0; registered_ids[i]; i++) {
+               regmap_write(pmcreg, AT91_PMC_PCR,
+                            (registered_ids[i] & AT91_PMC_PCR_PID_MASK));
+               regmap_read(pmcreg, AT91_PMC_PCR,
+                           &pmc_cache.pcr[registered_ids[i]]);
+       }
+
+       return 0;
+}
+
+static void pmc_resume(void)
+{
+       int i, ret = 0;
+       u32 tmp;
+
+       regmap_read(pmcreg, AT91_PMC_MCKR, &tmp);
+       if (pmc_cache.mckr != tmp)
+               pr_warn("MCKR was not configured properly by the firmware\n");
+       regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp);
+       if (pmc_cache.pllar != tmp)
+               pr_warn("PLLAR was not configured properly by the firmware\n");
+
+       regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.scsr);
+       regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0);
+       regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr);
+       regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor);
+       regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr);
+       regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb);
+       regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr);
+       regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1);
+
+       for (i = 0; registered_ids[i]; i++) {
+               regmap_write(pmcreg, AT91_PMC_PCR,
+                            pmc_cache.pcr[registered_ids[i]] |
+                            AT91_PMC_PCR_CMD);
+       }
+
+       if (pmc_cache.uckr & AT91_PMC_UPLLEN) {
+               ret = regmap_read_poll_timeout(pmcreg, AT91_PMC_SR, tmp,
+                                              !(tmp & AT91_PMC_LOCKU),
+                                              10, 5000);
+               if (ret)
+                       pr_crit("USB PLL didn't lock when resuming\n");
+       }
+}
+
+static struct syscore_ops pmc_syscore_ops = {
+       .suspend = pmc_suspend,
+       .resume = pmc_resume,
+};
+
+static const struct of_device_id sama5d2_pmc_dt_ids[] = {
+       { .compatible = "atmel,sama5d2-pmc" },
+       { /* sentinel */ }
+};
+
+static int __init pmc_register_ops(void)
+{
+       struct device_node *np;
+
+       np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
+
+       pmcreg = syscon_node_to_regmap(np);
+       if (IS_ERR(pmcreg))
+               return PTR_ERR(pmcreg);
+
+       register_syscore_ops(&pmc_syscore_ops);
+
+       return 0;
+}
+/* This has to happen before arch_initcall because of the tcb_clksrc driver */
+postcore_initcall(pmc_register_ops);
+#endif
index 5771fff0ee3fdf345422baa54903b1864027f2c3..858e8ef7e8dbc1d252a9dc7a6d91989a7e3d77f3 100644 (file)
@@ -29,4 +29,10 @@ struct clk_range {
 int of_at91_get_clk_range(struct device_node *np, const char *propname,
                          struct clk_range *range);
 
+#ifdef CONFIG_PM
+void pmc_register_id(u8 id);
+#else
+static inline void pmc_register_id(u8 id) {}
+#endif
+
 #endif /* __PMC_H_ */
index b5ae5311b0a24ecb5738d8f00eddebae6f3f72e0..1d9187df167bc0ee86dde7f2d938cfbabd1a57f6 100644 (file)
@@ -46,3 +46,11 @@ config CLK_BCM_NS2
        default ARCH_BCM_IPROC
        help
          Enable common clock framework support for the Broadcom Northstar 2 SoC
+
+config CLK_BCM_SR
+       bool "Broadcom Stingray clock support"
+       depends on ARCH_BCM_IPROC || COMPILE_TEST
+       select COMMON_CLK_IPROC
+       default ARCH_BCM_IPROC
+       help
+         Enable common clock framework support for the Broadcom Stingray SoC
index d9dc848f18c943be594b1380e458842109dc1870..a0c14fa4aa1e7f8408b61952cbb1c7c41b490735 100644 (file)
@@ -10,3 +10,4 @@ obj-$(CONFIG_ARCH_BCM_53573)  += clk-bcm53573-ilp.o
 obj-$(CONFIG_CLK_BCM_CYGNUS)   += clk-cygnus.o
 obj-$(CONFIG_CLK_BCM_NSP)      += clk-nsp.o
 obj-$(CONFIG_CLK_BCM_NS2)      += clk-ns2.o
+obj-$(CONFIG_CLK_BCM_SR)       += clk-sr.o
index 02585387061967ac9408e18ac1bce67e9e9414c0..58ce6af8452db9ca8b4d3c380a06e448919f6a8d 100644 (file)
@@ -530,6 +530,7 @@ struct bcm2835_clock_data {
 
        bool is_vpu_clock;
        bool is_mash_clock;
+       bool low_jitter;
 
        u32 tcnt_mux;
 };
@@ -616,8 +617,10 @@ static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw,
        using_prediv = cprman_read(cprman, data->ana_reg_base + 4) &
                data->ana->fb_prediv_mask;
 
-       if (using_prediv)
+       if (using_prediv) {
                ndiv *= 2;
+               fdiv *= 2;
+       }
 
        return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv);
 }
@@ -1124,7 +1127,8 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
                                                        int parent_idx,
                                                        unsigned long rate,
                                                        u32 *div,
-                                                       unsigned long *prate)
+                                                       unsigned long *prate,
+                                                       unsigned long *avgrate)
 {
        struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
        struct bcm2835_cprman *cprman = clock->cprman;
@@ -1139,8 +1143,25 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
                *prate = clk_hw_get_rate(parent);
                *div = bcm2835_clock_choose_div(hw, rate, *prate, true);
 
-               return bcm2835_clock_rate_from_divisor(clock, *prate,
-                                                      *div);
+               *avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div);
+
+               if (data->low_jitter && (*div & CM_DIV_FRAC_MASK)) {
+                       unsigned long high, low;
+                       u32 int_div = *div & ~CM_DIV_FRAC_MASK;
+
+                       high = bcm2835_clock_rate_from_divisor(clock, *prate,
+                                                              int_div);
+                       int_div += CM_DIV_FRAC_MASK + 1;
+                       low = bcm2835_clock_rate_from_divisor(clock, *prate,
+                                                             int_div);
+
+                       /*
+                        * Return a value which is the maximum deviation
+                        * below the ideal rate, for use as a metric.
+                        */
+                       return *avgrate - max(*avgrate - low, high - *avgrate);
+               }
+               return *avgrate;
        }
 
        if (data->frac_bits)
@@ -1167,6 +1188,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw,
 
        *div = curdiv << CM_DIV_FRAC_BITS;
        *prate = curdiv * best_rate;
+       *avgrate = best_rate;
 
        return best_rate;
 }
@@ -1178,6 +1200,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
        bool current_parent_is_pllc;
        unsigned long rate, best_rate = 0;
        unsigned long prate, best_prate = 0;
+       unsigned long avgrate, best_avgrate = 0;
        size_t i;
        u32 div;
 
@@ -1202,11 +1225,13 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
                        continue;
 
                rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate,
-                                                         &div, &prate);
+                                                         &div, &prate,
+                                                         &avgrate);
                if (rate > best_rate && rate <= req->rate) {
                        best_parent = parent;
                        best_prate = prate;
                        best_rate = rate;
+                       best_avgrate = avgrate;
                }
        }
 
@@ -1216,7 +1241,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
        req->best_parent_hw = best_parent;
        req->best_parent_rate = best_prate;
 
-       req->rate = best_rate;
+       req->rate = best_avgrate;
 
        return 0;
 }
@@ -1516,6 +1541,31 @@ static const char *const bcm2835_clock_per_parents[] = {
        .parents = bcm2835_clock_per_parents,                           \
        __VA_ARGS__)
 
+/*
+ * Restrict clock sources for the PCM peripheral to the oscillator and
+ * PLLD_PER because other source may have varying rates or be switched
+ * off.
+ *
+ * Prevent other sources from being selected by replacing their names in
+ * the list of potential parents with dummy entries (entry index is
+ * significant).
+ */
+static const char *const bcm2835_pcm_per_parents[] = {
+       "-",
+       "xosc",
+       "-",
+       "-",
+       "-",
+       "-",
+       "plld_per",
+       "-",
+};
+
+#define REGISTER_PCM_CLK(...)  REGISTER_CLK(                           \
+       .num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents),         \
+       .parents = bcm2835_pcm_per_parents,                             \
+       __VA_ARGS__)
+
 /* main vpu parent mux */
 static const char *const bcm2835_clock_vpu_parents[] = {
        "gnd",
@@ -1993,13 +2043,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
                .int_bits = 4,
                .frac_bits = 8,
                .tcnt_mux = 22),
-       [BCM2835_CLOCK_PCM]     = REGISTER_PER_CLK(
+       [BCM2835_CLOCK_PCM]     = REGISTER_PCM_CLK(
                .name = "pcm",
                .ctl_reg = CM_PCMCTL,
                .div_reg = CM_PCMDIV,
                .int_bits = 12,
                .frac_bits = 12,
                .is_mash_clock = true,
+               .low_jitter = true,
                .tcnt_mux = 23),
        [BCM2835_CLOCK_PWM]     = REGISTER_PER_CLK(
                .name = "pwm",
index 2d61893da0244d9acecc735afd02278cd5582108..375d8dd80d456f785abe109786ab8e3ded483355 100644 (file)
@@ -617,12 +617,12 @@ static void iproc_pll_sw_cfg(struct iproc_pll *pll)
        }
 }
 
-void __init iproc_pll_clk_setup(struct device_node *node,
-                               const struct iproc_pll_ctrl *pll_ctrl,
-                               const struct iproc_pll_vco_param *vco,
-                               unsigned int num_vco_entries,
-                               const struct iproc_clk_ctrl *clk_ctrl,
-                               unsigned int num_clks)
+void iproc_pll_clk_setup(struct device_node *node,
+                        const struct iproc_pll_ctrl *pll_ctrl,
+                        const struct iproc_pll_vco_param *vco,
+                        unsigned int num_vco_entries,
+                        const struct iproc_clk_ctrl *clk_ctrl,
+                        unsigned int num_clks)
 {
        int i, ret;
        struct iproc_pll *pll;
diff --git a/drivers/clk/bcm/clk-sr.c b/drivers/clk/bcm/clk-sr.c
new file mode 100644 (file)
index 0000000..adc74f4
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2017 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/bcm-sr.h>
+#include "clk-iproc.h"
+
+#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
+
+#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
+       .pwr_shift = ps, .iso_shift = is }
+
+#define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
+
+#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
+       .p_reset_shift = prs }
+
+#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \
+       .ki_shift = kis, .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, \
+       .ka_shift = kas, .ka_width = kaw }
+
+#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
+
+#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
+       .hold_shift = hs, .bypass_shift = bs }
+
+
+static const struct iproc_pll_ctrl sr_genpll0 = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
+               IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 5, 1, 0),
+       .reset = RESET_VAL(0x0, 12, 11),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
+       .sw_ctrl = SW_CTRL_VAL(0x10, 31),
+       .ndiv_int = REG_VAL(0x10, 20, 10),
+       .ndiv_frac = REG_VAL(0x10, 0, 20),
+       .pdiv = REG_VAL(0x14, 0, 4),
+       .status = REG_VAL(0x30, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_genpll0_clk[] = {
+       [BCM_SR_GENPLL0_SATA_CLK] = {
+               .channel = BCM_SR_GENPLL0_SATA_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 6, 0, 12),
+               .mdiv = REG_VAL(0x18, 0, 9),
+       },
+       [BCM_SR_GENPLL0_SCR_CLK] = {
+               .channel = BCM_SR_GENPLL0_SCR_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 7, 1, 13),
+               .mdiv = REG_VAL(0x18, 10, 9),
+       },
+       [BCM_SR_GENPLL0_250M_CLK] = {
+               .channel = BCM_SR_GENPLL0_250M_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 8, 2, 14),
+               .mdiv = REG_VAL(0x18, 20, 9),
+       },
+       [BCM_SR_GENPLL0_PCIE_AXI_CLK] = {
+               .channel = BCM_SR_GENPLL0_PCIE_AXI_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 9, 3, 15),
+               .mdiv = REG_VAL(0x1c, 0, 9),
+       },
+       [BCM_SR_GENPLL0_PAXC_AXI_X2_CLK] = {
+               .channel = BCM_SR_GENPLL0_PAXC_AXI_X2_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 10, 4, 16),
+               .mdiv = REG_VAL(0x1c, 10, 9),
+       },
+       [BCM_SR_GENPLL0_PAXC_AXI_CLK] = {
+               .channel = BCM_SR_GENPLL0_PAXC_AXI_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 11, 5, 17),
+               .mdiv = REG_VAL(0x1c, 20, 9),
+       },
+};
+
+static int sr_genpll0_clk_init(struct platform_device *pdev)
+{
+       iproc_pll_clk_setup(pdev->dev.of_node,
+                           &sr_genpll0, NULL, 0, sr_genpll0_clk,
+                           ARRAY_SIZE(sr_genpll0_clk));
+       return 0;
+}
+
+static const struct iproc_pll_ctrl sr_genpll3 = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
+               IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 1, 19, 18),
+       .reset = RESET_VAL(0x0, 12, 11),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
+       .sw_ctrl = SW_CTRL_VAL(0x10, 31),
+       .ndiv_int = REG_VAL(0x10, 20, 10),
+       .ndiv_frac = REG_VAL(0x10, 0, 20),
+       .pdiv = REG_VAL(0x14, 0, 4),
+       .status = REG_VAL(0x30, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_genpll3_clk[] = {
+       [BCM_SR_GENPLL3_HSLS_CLK] = {
+               .channel = BCM_SR_GENPLL3_HSLS_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 6, 0, 12),
+               .mdiv = REG_VAL(0x18, 0, 9),
+       },
+       [BCM_SR_GENPLL3_SDIO_CLK] = {
+               .channel = BCM_SR_GENPLL3_SDIO_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 7, 1, 13),
+               .mdiv = REG_VAL(0x18, 10, 9),
+       },
+};
+
+static void sr_genpll3_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &sr_genpll3, NULL, 0, sr_genpll3_clk,
+                           ARRAY_SIZE(sr_genpll3_clk));
+}
+CLK_OF_DECLARE(sr_genpll3_clk, "brcm,sr-genpll3", sr_genpll3_clk_init);
+
+static const struct iproc_pll_ctrl sr_genpll4 = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
+               IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 1, 25, 24),
+       .reset = RESET_VAL(0x0, 12, 11),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
+       .sw_ctrl = SW_CTRL_VAL(0x10, 31),
+       .ndiv_int = REG_VAL(0x10, 20, 10),
+       .ndiv_frac = REG_VAL(0x10, 0, 20),
+       .pdiv = REG_VAL(0x14, 0, 4),
+       .status = REG_VAL(0x30, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_genpll4_clk[] = {
+       [BCM_SR_GENPLL4_CCN_CLK] = {
+               .channel = BCM_SR_GENPLL4_CCN_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 6, 0, 12),
+               .mdiv = REG_VAL(0x18, 0, 9),
+       },
+};
+
+static int sr_genpll4_clk_init(struct platform_device *pdev)
+{
+       iproc_pll_clk_setup(pdev->dev.of_node,
+                           &sr_genpll4, NULL, 0, sr_genpll4_clk,
+                           ARRAY_SIZE(sr_genpll4_clk));
+       return 0;
+}
+
+static const struct iproc_pll_ctrl sr_genpll5 = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
+               IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 1, 1, 0),
+       .reset = RESET_VAL(0x0, 12, 11),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
+       .sw_ctrl = SW_CTRL_VAL(0x10, 31),
+       .ndiv_int = REG_VAL(0x10, 20, 10),
+       .ndiv_frac = REG_VAL(0x10, 0, 20),
+       .pdiv = REG_VAL(0x14, 0, 4),
+       .status = REG_VAL(0x30, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_genpll5_clk[] = {
+       [BCM_SR_GENPLL5_FS_CLK] = {
+               .channel = BCM_SR_GENPLL5_FS_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 6, 0, 12),
+               .mdiv = REG_VAL(0x18, 0, 9),
+       },
+       [BCM_SR_GENPLL5_SPU_CLK] = {
+               .channel = BCM_SR_GENPLL5_SPU_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 6, 0, 12),
+               .mdiv = REG_VAL(0x18, 10, 9),
+       },
+};
+
+static int sr_genpll5_clk_init(struct platform_device *pdev)
+{
+       iproc_pll_clk_setup(pdev->dev.of_node,
+                           &sr_genpll5, NULL, 0, sr_genpll5_clk,
+                           ARRAY_SIZE(sr_genpll5_clk));
+       return 0;
+}
+
+static const struct iproc_pll_ctrl sr_lcpll0 = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 2, 19, 18),
+       .reset = RESET_VAL(0x0, 31, 30),
+       .sw_ctrl = SW_CTRL_VAL(0x4, 31),
+       .ndiv_int = REG_VAL(0x4, 16, 10),
+       .pdiv = REG_VAL(0x4, 26, 4),
+       .status = REG_VAL(0x38, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_lcpll0_clk[] = {
+       [BCM_SR_LCPLL0_SATA_REF_CLK] = {
+               .channel = BCM_SR_LCPLL0_SATA_REF_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 7, 1, 13),
+               .mdiv = REG_VAL(0x14, 0, 9),
+       },
+       [BCM_SR_LCPLL0_USB_REF_CLK] = {
+               .channel = BCM_SR_LCPLL0_USB_REF_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 8, 2, 14),
+               .mdiv = REG_VAL(0x14, 10, 9),
+       },
+       [BCM_SR_LCPLL0_SATA_REFPN_CLK] = {
+               .channel = BCM_SR_LCPLL0_SATA_REFPN_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 9, 3, 15),
+               .mdiv = REG_VAL(0x14, 20, 9),
+       },
+};
+
+static int sr_lcpll0_clk_init(struct platform_device *pdev)
+{
+       iproc_pll_clk_setup(pdev->dev.of_node,
+                           &sr_lcpll0, NULL, 0, sr_lcpll0_clk,
+                           ARRAY_SIZE(sr_lcpll0_clk));
+       return 0;
+}
+
+static const struct iproc_pll_ctrl sr_lcpll1 = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 2, 22, 21),
+       .reset = RESET_VAL(0x0, 31, 30),
+       .sw_ctrl = SW_CTRL_VAL(0x4, 31),
+       .ndiv_int = REG_VAL(0x4, 16, 10),
+       .pdiv = REG_VAL(0x4, 26, 4),
+       .status = REG_VAL(0x38, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_lcpll1_clk[] = {
+       [BCM_SR_LCPLL1_WAN_CLK] = {
+               .channel = BCM_SR_LCPLL1_WAN_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 7, 1, 13),
+               .mdiv = REG_VAL(0x14, 0, 9),
+       },
+};
+
+static int sr_lcpll1_clk_init(struct platform_device *pdev)
+{
+       iproc_pll_clk_setup(pdev->dev.of_node,
+                           &sr_lcpll1, NULL, 0, sr_lcpll1_clk,
+                           ARRAY_SIZE(sr_lcpll1_clk));
+       return 0;
+}
+
+static const struct iproc_pll_ctrl sr_lcpll_pcie = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
+       .aon = AON_VAL(0x0, 2, 25, 24),
+       .reset = RESET_VAL(0x0, 31, 30),
+       .sw_ctrl = SW_CTRL_VAL(0x4, 31),
+       .ndiv_int = REG_VAL(0x4, 16, 10),
+       .pdiv = REG_VAL(0x4, 26, 4),
+       .status = REG_VAL(0x38, 12, 1),
+};
+
+static const struct iproc_clk_ctrl sr_lcpll_pcie_clk[] = {
+       [BCM_SR_LCPLL_PCIE_PHY_REF_CLK] = {
+               .channel = BCM_SR_LCPLL_PCIE_PHY_REF_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 7, 1, 13),
+               .mdiv = REG_VAL(0x14, 0, 9),
+       },
+};
+
+static int sr_lcpll_pcie_clk_init(struct platform_device *pdev)
+{
+       iproc_pll_clk_setup(pdev->dev.of_node,
+                           &sr_lcpll_pcie, NULL, 0, sr_lcpll_pcie_clk,
+                           ARRAY_SIZE(sr_lcpll_pcie_clk));
+       return 0;
+}
+
+static const struct of_device_id sr_clk_dt_ids[] = {
+       { .compatible = "brcm,sr-genpll0", .data = sr_genpll0_clk_init },
+       { .compatible = "brcm,sr-genpll4", .data = sr_genpll4_clk_init },
+       { .compatible = "brcm,sr-genpll5", .data = sr_genpll5_clk_init },
+       { .compatible = "brcm,sr-lcpll0", .data = sr_lcpll0_clk_init },
+       { .compatible = "brcm,sr-lcpll1", .data = sr_lcpll1_clk_init },
+       { .compatible = "brcm,sr-lcpll-pcie", .data = sr_lcpll_pcie_clk_init },
+       { /* sentinel */ }
+};
+
+static int sr_clk_probe(struct platform_device *pdev)
+{
+       int (*probe_func)(struct platform_device *);
+
+       probe_func = of_device_get_match_data(&pdev->dev);
+       if (!probe_func)
+               return -ENODEV;
+
+       return probe_func(pdev);
+}
+
+static struct platform_driver sr_clk_driver = {
+       .driver = {
+               .name = "sr-clk",
+               .of_match_table = sr_clk_dt_ids,
+       },
+       .probe = sr_clk_probe,
+};
+builtin_platform_driver(sr_clk_driver);
diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
new file mode 100644 (file)
index 0000000..c834f5a
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * Dong Aisheng <aisheng.dong@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
+
+void clk_bulk_put(int num_clks, struct clk_bulk_data *clks)
+{
+       while (--num_clks >= 0) {
+               clk_put(clks[num_clks].clk);
+               clks[num_clks].clk = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(clk_bulk_put);
+
+int __must_check clk_bulk_get(struct device *dev, int num_clks,
+                             struct clk_bulk_data *clks)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < num_clks; i++)
+               clks[i].clk = NULL;
+
+       for (i = 0; i < num_clks; i++) {
+               clks[i].clk = clk_get(dev, clks[i].id);
+               if (IS_ERR(clks[i].clk)) {
+                       ret = PTR_ERR(clks[i].clk);
+                       dev_err(dev, "Failed to get clk '%s': %d\n",
+                               clks[i].id, ret);
+                       clks[i].clk = NULL;
+                       goto err;
+               }
+       }
+
+       return 0;
+
+err:
+       clk_bulk_put(i, clks);
+
+       return ret;
+}
+EXPORT_SYMBOL(clk_bulk_get);
+
+#ifdef CONFIG_HAVE_CLK_PREPARE
+
+/**
+ * clk_bulk_unprepare - undo preparation of a set of clock sources
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table being unprepared
+ *
+ * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable.
+ * Returns 0 on success, -EERROR otherwise.
+ */
+void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks)
+{
+       while (--num_clks >= 0)
+               clk_unprepare(clks[num_clks].clk);
+}
+EXPORT_SYMBOL_GPL(clk_bulk_unprepare);
+
+/**
+ * clk_bulk_prepare - prepare a set of clocks
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table being prepared
+ *
+ * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable.
+ * Returns 0 on success, -EERROR otherwise.
+ */
+int __must_check clk_bulk_prepare(int num_clks,
+                                 const struct clk_bulk_data *clks)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < num_clks; i++) {
+               ret = clk_prepare(clks[i].clk);
+               if (ret) {
+                       pr_err("Failed to prepare clk '%s': %d\n",
+                               clks[i].id, ret);
+                       goto err;
+               }
+       }
+
+       return 0;
+
+err:
+       clk_bulk_unprepare(i, clks);
+
+       return  ret;
+}
+
+#endif /* CONFIG_HAVE_CLK_PREPARE */
+
+/**
+ * clk_bulk_disable - gate a set of clocks
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table being gated
+ *
+ * clk_bulk_disable must not sleep, which differentiates it from
+ * clk_bulk_unprepare. clk_bulk_disable must be called before
+ * clk_bulk_unprepare.
+ */
+void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks)
+{
+
+       while (--num_clks >= 0)
+               clk_disable(clks[num_clks].clk);
+}
+EXPORT_SYMBOL_GPL(clk_bulk_disable);
+
+/**
+ * clk_bulk_enable - ungate a set of clocks
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table being ungated
+ *
+ * clk_bulk_enable must not sleep
+ * Returns 0 on success, -EERROR otherwise.
+ */
+int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < num_clks; i++) {
+               ret = clk_enable(clks[i].clk);
+               if (ret) {
+                       pr_err("Failed to enable clk '%s': %d\n",
+                               clks[i].id, ret);
+                       goto err;
+               }
+       }
+
+       return 0;
+
+err:
+       clk_bulk_disable(i, clks);
+
+       return  ret;
+}
+EXPORT_SYMBOL_GPL(clk_bulk_enable);
index e0e02a6e59009e7ac56ae85ddaecc8624568e5b3..7ec36722f8ab0f4cac82b18a91283696268c781f 100644 (file)
@@ -109,7 +109,7 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
 
                        rc = clk_set_rate(clk, rate);
                        if (rc < 0)
-                               pr_err("clk: couldn't set %s clk rate to %d (%d), current rate: %ld\n",
+                               pr_err("clk: couldn't set %s clk rate to %u (%d), current rate: %lu\n",
                                       __clk_get_name(clk), rate, rc,
                                       clk_get_rate(clk));
                        clk_put(clk);
index 3a218c3a06ae8d8169c384b722b5f08dd738ca5a..d854e26a8ddbca3dfb96aad123e974f2175cc455 100644 (file)
@@ -34,6 +34,42 @@ struct clk *devm_clk_get(struct device *dev, const char *id)
 }
 EXPORT_SYMBOL(devm_clk_get);
 
+struct clk_bulk_devres {
+       struct clk_bulk_data *clks;
+       int num_clks;
+};
+
+static void devm_clk_bulk_release(struct device *dev, void *res)
+{
+       struct clk_bulk_devres *devres = res;
+
+       clk_bulk_put(devres->num_clks, devres->clks);
+}
+
+int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
+                     struct clk_bulk_data *clks)
+{
+       struct clk_bulk_devres *devres;
+       int ret;
+
+       devres = devres_alloc(devm_clk_bulk_release,
+                             sizeof(*devres), GFP_KERNEL);
+       if (!devres)
+               return -ENOMEM;
+
+       ret = clk_bulk_get(dev, num_clks, clks);
+       if (!ret) {
+               devres->clks = clks;
+               devres->num_clks = num_clks;
+               devres_add(dev, devres);
+       } else {
+               devres_free(devres);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(devm_clk_bulk_get);
+
 static int devm_clk_match(struct device *dev, void *res, void *data)
 {
        struct clk **c = res;
index 96386ffc84835f121c2888e3c67a9b230173db64..9bb472cccca6e044e46bebc0ec57f4c74641b11b 100644 (file)
@@ -275,7 +275,8 @@ static int _next_div(const struct clk_div_table *table, int div,
        return div;
 }
 
-static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
+                              unsigned long rate,
                               unsigned long *best_parent_rate,
                               const struct clk_div_table *table, u8 width,
                               unsigned long flags)
@@ -314,8 +315,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
                        *best_parent_rate = parent_rate_saved;
                        return i;
                }
-               parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
-                                              rate * i);
+               parent_rate = clk_hw_round_rate(parent, rate * i);
                now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
                if (_is_best_div(rate, now, best, flags)) {
                        bestdiv = i;
@@ -326,23 +326,24 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
 
        if (!bestdiv) {
                bestdiv = _get_maxdiv(table, width, flags);
-               *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1);
+               *best_parent_rate = clk_hw_round_rate(parent, 1);
        }
 
        return bestdiv;
 }
 
-long divider_round_rate(struct clk_hw *hw, unsigned long rate,
-                       unsigned long *prate, const struct clk_div_table *table,
-                       u8 width, unsigned long flags)
+long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
+                              unsigned long rate, unsigned long *prate,
+                              const struct clk_div_table *table,
+                              u8 width, unsigned long flags)
 {
        int div;
 
-       div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
+       div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags);
 
        return DIV_ROUND_UP_ULL((u64)*prate, div);
 }
-EXPORT_SYMBOL_GPL(divider_round_rate);
+EXPORT_SYMBOL_GPL(divider_round_rate_parent);
 
 static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
                                unsigned long *prate)
diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c
new file mode 100644 (file)
index 0000000..c391a49
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * Cortina Gemini SoC Clock Controller driver
+ * Copyright (c) 2017 Linus Walleij <linus.walleij@linaro.org>
+ */
+
+#define pr_fmt(fmt) "clk-gemini: " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <linux/reset-controller.h>
+#include <dt-bindings/reset/cortina,gemini-reset.h>
+#include <dt-bindings/clock/cortina,gemini-clock.h>
+
+/* Globally visible clocks */
+static DEFINE_SPINLOCK(gemini_clk_lock);
+
+#define GEMINI_GLOBAL_STATUS           0x04
+#define PLL_OSC_SEL                    BIT(30)
+#define AHBSPEED_SHIFT                 (15)
+#define AHBSPEED_MASK                  0x07
+#define CPU_AHB_RATIO_SHIFT            (18)
+#define CPU_AHB_RATIO_MASK             0x03
+
+#define GEMINI_GLOBAL_PLL_CONTROL      0x08
+
+#define GEMINI_GLOBAL_SOFT_RESET       0x0c
+
+#define GEMINI_GLOBAL_MISC_CONTROL     0x30
+#define PCI_CLK_66MHZ                  BIT(18)
+#define PCI_CLK_OE                     BIT(17)
+
+#define GEMINI_GLOBAL_CLOCK_CONTROL    0x34
+#define PCI_CLKRUN_EN                  BIT(16)
+#define TVC_HALFDIV_SHIFT              (24)
+#define TVC_HALFDIV_MASK               0x1f
+#define SECURITY_CLK_SEL               BIT(29)
+
+#define GEMINI_GLOBAL_PCI_DLL_CONTROL  0x44
+#define PCI_DLL_BYPASS                 BIT(31)
+#define PCI_DLL_TAP_SEL_MASK           0x1f
+
+/**
+ * struct gemini_data_data - Gemini gated clocks
+ * @bit_idx: the bit used to gate this clock in the clock register
+ * @name: the clock name
+ * @parent_name: the name of the parent clock
+ * @flags: standard clock framework flags
+ */
+struct gemini_gate_data {
+       u8 bit_idx;
+       const char *name;
+       const char *parent_name;
+       unsigned long flags;
+};
+
+/**
+ * struct clk_gemini_pci - Gemini PCI clock
+ * @hw: corresponding clock hardware entry
+ * @map: regmap to access the registers
+ * @rate: current rate
+ */
+struct clk_gemini_pci {
+       struct clk_hw hw;
+       struct regmap *map;
+       unsigned long rate;
+};
+
+/**
+ * struct gemini_reset - gemini reset controller
+ * @map: regmap to access the containing system controller
+ * @rcdev: reset controller device
+ */
+struct gemini_reset {
+       struct regmap *map;
+       struct reset_controller_dev rcdev;
+};
+
+/* Keeps track of all clocks */
+static struct clk_hw_onecell_data *gemini_clk_data;
+
+static const struct gemini_gate_data gemini_gates[] = {
+       { 1, "security-gate", "secdiv", 0 },
+       { 2, "gmac0-gate", "ahb", 0 },
+       { 3, "gmac1-gate", "ahb", 0 },
+       { 4, "sata0-gate", "ahb", 0 },
+       { 5, "sata1-gate", "ahb", 0 },
+       { 6, "usb0-gate", "ahb", 0 },
+       { 7, "usb1-gate", "ahb", 0 },
+       { 8, "ide-gate", "ahb", 0 },
+       { 9, "pci-gate", "ahb", 0 },
+       /*
+        * The DDR controller may never have a driver, but certainly must
+        * not be gated off.
+        */
+       { 10, "ddr-gate", "ahb", CLK_IS_CRITICAL },
+       /*
+        * The flash controller must be on to access NOR flash through the
+        * memory map.
+        */
+       { 11, "flash-gate", "ahb", CLK_IGNORE_UNUSED },
+       { 12, "tvc-gate", "ahb", 0 },
+       { 13, "boot-gate", "apb", 0 },
+};
+
+#define to_pciclk(_hw) container_of(_hw, struct clk_gemini_pci, hw)
+
+#define to_gemini_reset(p) container_of((p), struct gemini_reset, rcdev)
+
+static unsigned long gemini_pci_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       struct clk_gemini_pci *pciclk = to_pciclk(hw);
+       u32 val;
+
+       regmap_read(pciclk->map, GEMINI_GLOBAL_MISC_CONTROL, &val);
+       if (val & PCI_CLK_66MHZ)
+               return 66000000;
+       return 33000000;
+}
+
+static long gemini_pci_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *prate)
+{
+       /* We support 33 and 66 MHz */
+       if (rate < 48000000)
+               return 33000000;
+       return 66000000;
+}
+
+static int gemini_pci_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct clk_gemini_pci *pciclk = to_pciclk(hw);
+
+       if (rate == 33000000)
+               return regmap_update_bits(pciclk->map,
+                                         GEMINI_GLOBAL_MISC_CONTROL,
+                                         PCI_CLK_66MHZ, 0);
+       if (rate == 66000000)
+               return regmap_update_bits(pciclk->map,
+                                         GEMINI_GLOBAL_MISC_CONTROL,
+                                         0, PCI_CLK_66MHZ);
+       return -EINVAL;
+}
+
+static int gemini_pci_enable(struct clk_hw *hw)
+{
+       struct clk_gemini_pci *pciclk = to_pciclk(hw);
+
+       regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
+                          0, PCI_CLKRUN_EN);
+       regmap_update_bits(pciclk->map,
+                          GEMINI_GLOBAL_MISC_CONTROL,
+                          0, PCI_CLK_OE);
+       return 0;
+}
+
+static void gemini_pci_disable(struct clk_hw *hw)
+{
+       struct clk_gemini_pci *pciclk = to_pciclk(hw);
+
+       regmap_update_bits(pciclk->map,
+                          GEMINI_GLOBAL_MISC_CONTROL,
+                          PCI_CLK_OE, 0);
+       regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL,
+                          PCI_CLKRUN_EN, 0);
+}
+
+static int gemini_pci_is_enabled(struct clk_hw *hw)
+{
+       struct clk_gemini_pci *pciclk = to_pciclk(hw);
+       unsigned int val;
+
+       regmap_read(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, &val);
+       return !!(val & PCI_CLKRUN_EN);
+}
+
+static const struct clk_ops gemini_pci_clk_ops = {
+       .recalc_rate = gemini_pci_recalc_rate,
+       .round_rate = gemini_pci_round_rate,
+       .set_rate = gemini_pci_set_rate,
+       .enable = gemini_pci_enable,
+       .disable = gemini_pci_disable,
+       .is_enabled = gemini_pci_is_enabled,
+};
+
+static struct clk_hw *gemini_pci_clk_setup(const char *name,
+                                          const char *parent_name,
+                                          struct regmap *map)
+{
+       struct clk_gemini_pci *pciclk;
+       struct clk_init_data init;
+       int ret;
+
+       pciclk = kzalloc(sizeof(*pciclk), GFP_KERNEL);
+       if (!pciclk)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &gemini_pci_clk_ops;
+       init.flags = 0;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+       pciclk->map = map;
+       pciclk->hw.init = &init;
+
+       ret = clk_hw_register(NULL, &pciclk->hw);
+       if (ret) {
+               kfree(pciclk);
+               return ERR_PTR(ret);
+       }
+
+       return &pciclk->hw;
+}
+
+/*
+ * This is a self-deasserting reset controller.
+ */
+static int gemini_reset(struct reset_controller_dev *rcdev,
+                       unsigned long id)
+{
+       struct gemini_reset *gr = to_gemini_reset(rcdev);
+
+       /* Manual says to always set BIT 30 (CPU1) to 1 */
+       return regmap_write(gr->map,
+                           GEMINI_GLOBAL_SOFT_RESET,
+                           BIT(GEMINI_RESET_CPU1) | BIT(id));
+}
+
+static int gemini_reset_status(struct reset_controller_dev *rcdev,
+                            unsigned long id)
+{
+       struct gemini_reset *gr = to_gemini_reset(rcdev);
+       u32 val;
+       int ret;
+
+       ret = regmap_read(gr->map, GEMINI_GLOBAL_SOFT_RESET, &val);
+       if (ret)
+               return ret;
+
+       return !!(val & BIT(id));
+}
+
+static const struct reset_control_ops gemini_reset_ops = {
+       .reset = gemini_reset,
+       .status = gemini_reset_status,
+};
+
+static int gemini_clk_probe(struct platform_device *pdev)
+{
+       /* Gives the fracions 1x, 1.5x, 1.85x and 2x */
+       unsigned int cpu_ahb_mult[4] = { 1, 3, 24, 2 };
+       unsigned int cpu_ahb_div[4] = { 1, 2, 13, 1 };
+       void __iomem *base;
+       struct gemini_reset *gr;
+       struct regmap *map;
+       struct clk_hw *hw;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       unsigned int mult, div;
+       struct resource *res;
+       u32 val;
+       int ret;
+       int i;
+
+       gr = devm_kzalloc(dev, sizeof(*gr), GFP_KERNEL);
+       if (!gr)
+               return -ENOMEM;
+
+       /* Remap the system controller for the exclusive register */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       map = syscon_node_to_regmap(np);
+       if (IS_ERR(map)) {
+               dev_err(dev, "no syscon regmap\n");
+               return PTR_ERR(map);
+       }
+
+       gr->map = map;
+       gr->rcdev.owner = THIS_MODULE;
+       gr->rcdev.nr_resets = 32;
+       gr->rcdev.ops = &gemini_reset_ops;
+       gr->rcdev.of_node = np;
+
+       ret = devm_reset_controller_register(dev, &gr->rcdev);
+       if (ret) {
+               dev_err(dev, "could not register reset controller\n");
+               return ret;
+       }
+
+       /* RTC clock 32768 Hz */
+       hw = clk_hw_register_fixed_rate(NULL, "rtc", NULL, 0, 32768);
+       gemini_clk_data->hws[GEMINI_CLK_RTC] = hw;
+
+       /* CPU clock derived as a fixed ratio from the AHB clock */
+       regmap_read(map, GEMINI_GLOBAL_STATUS, &val);
+       val >>= CPU_AHB_RATIO_SHIFT;
+       val &= CPU_AHB_RATIO_MASK;
+       hw = clk_hw_register_fixed_factor(NULL, "cpu", "ahb", 0,
+                                         cpu_ahb_mult[val],
+                                         cpu_ahb_div[val]);
+       gemini_clk_data->hws[GEMINI_CLK_CPU] = hw;
+
+       /* Security clock is 1:1 or 0.75 of APB */
+       regmap_read(map, GEMINI_GLOBAL_CLOCK_CONTROL, &val);
+       if (val & SECURITY_CLK_SEL) {
+               mult = 1;
+               div = 1;
+       } else {
+               mult = 3;
+               div = 4;
+       }
+       hw = clk_hw_register_fixed_factor(NULL, "secdiv", "ahb", 0, mult, div);
+
+       /*
+        * These are the leaf gates, at boot no clocks are gated.
+        */
+       for (i = 0; i < ARRAY_SIZE(gemini_gates); i++) {
+               const struct gemini_gate_data *gd;
+
+               gd = &gemini_gates[i];
+               gemini_clk_data->hws[GEMINI_CLK_GATES + i] =
+                       clk_hw_register_gate(NULL, gd->name,
+                                            gd->parent_name,
+                                            gd->flags,
+                                            base + GEMINI_GLOBAL_CLOCK_CONTROL,
+                                            gd->bit_idx,
+                                            CLK_GATE_SET_TO_DISABLE,
+                                            &gemini_clk_lock);
+       }
+
+       /*
+        * The TV Interface Controller has a 5-bit half divider register.
+        * This clock is supposed to be 27MHz as this is an exact multiple
+        * of PAL and NTSC frequencies. The register is undocumented :(
+        * FIXME: figure out the parent and how the divider works.
+        */
+       mult = 1;
+       div = ((val >> TVC_HALFDIV_SHIFT) & TVC_HALFDIV_MASK);
+       dev_dbg(dev, "TVC half divider value = %d\n", div);
+       div += 1;
+       hw = clk_hw_register_fixed_rate(NULL, "tvcdiv", "xtal", 0, 27000000);
+       gemini_clk_data->hws[GEMINI_CLK_TVC] = hw;
+
+       /* FIXME: very unclear what the parent is */
+       hw = gemini_pci_clk_setup("PCI", "xtal", map);
+       gemini_clk_data->hws[GEMINI_CLK_PCI] = hw;
+
+       /* FIXME: very unclear what the parent is */
+       hw = clk_hw_register_fixed_rate(NULL, "uart", "xtal", 0, 48000000);
+       gemini_clk_data->hws[GEMINI_CLK_UART] = hw;
+
+       return 0;
+}
+
+static const struct of_device_id gemini_clk_dt_ids[] = {
+       { .compatible = "cortina,gemini-syscon", },
+       { /* sentinel */ },
+};
+
+static struct platform_driver gemini_clk_driver = {
+       .probe  = gemini_clk_probe,
+       .driver = {
+               .name = "gemini-clk",
+               .of_match_table = gemini_clk_dt_ids,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(gemini_clk_driver);
+
+static void __init gemini_cc_init(struct device_node *np)
+{
+       struct regmap *map;
+       struct clk_hw *hw;
+       unsigned long freq;
+       unsigned int mult, div;
+       u32 val;
+       int ret;
+       int i;
+
+       gemini_clk_data = kzalloc(sizeof(*gemini_clk_data) +
+                       sizeof(*gemini_clk_data->hws) * GEMINI_NUM_CLKS,
+                       GFP_KERNEL);
+       if (!gemini_clk_data)
+               return;
+
+       /*
+        * This way all clock fetched before the platform device probes,
+        * except those we assign here for early use, will be deferred.
+        */
+       for (i = 0; i < GEMINI_NUM_CLKS; i++)
+               gemini_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
+
+       map = syscon_node_to_regmap(np);
+       if (IS_ERR(map)) {
+               pr_err("no syscon regmap\n");
+               return;
+       }
+       /*
+        * We check that the regmap works on this very first access,
+        * but as this is an MMIO-backed regmap, subsequent regmap
+        * access is not going to fail and we skip error checks from
+        * this point.
+        */
+       ret = regmap_read(map, GEMINI_GLOBAL_STATUS, &val);
+       if (ret) {
+               pr_err("failed to read global status register\n");
+               return;
+       }
+
+       /*
+        * XTAL is the crystal oscillator, 60 or 30 MHz selected from
+        * strap pin E6
+        */
+       if (val & PLL_OSC_SEL)
+               freq = 30000000;
+       else
+               freq = 60000000;
+       hw = clk_hw_register_fixed_rate(NULL, "xtal", NULL, 0, freq);
+       pr_debug("main crystal @%lu MHz\n", freq / 1000000);
+
+       /* VCO clock derived from the crystal */
+       mult = 13 + ((val >> AHBSPEED_SHIFT) & AHBSPEED_MASK);
+       div = 2;
+       /* If we run on 30 MHz crystal we have to multiply with two */
+       if (val & PLL_OSC_SEL)
+               mult *= 2;
+       hw = clk_hw_register_fixed_factor(NULL, "vco", "xtal", 0, mult, div);
+
+       /* The AHB clock is always 1/3 of the VCO */
+       hw = clk_hw_register_fixed_factor(NULL, "ahb", "vco", 0, 1, 3);
+       gemini_clk_data->hws[GEMINI_CLK_AHB] = hw;
+
+       /* The APB clock is always 1/6 of the AHB */
+       hw = clk_hw_register_fixed_factor(NULL, "apb", "ahb", 0, 1, 6);
+       gemini_clk_data->hws[GEMINI_CLK_APB] = hw;
+
+       /* Register the clocks to be accessed by the device tree */
+       gemini_clk_data->num = GEMINI_NUM_CLKS;
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, gemini_clk_data);
+}
+CLK_OF_DECLARE_DRIVER(gemini_cc, "cortina,gemini-syscon", gemini_cc_init);
index 31f590cea493be6cb3faebfb740b479c4af7b004..7f51c01085abee76a30828f08b52bac935f172d5 100644 (file)
@@ -229,6 +229,7 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
                if (ret < 0) {
                        dev_err(cinfo->dev, "Ext config for %s failed, %d\n",
                                cinfo->clk_desc->clk_name, ret);
+                       clk_unprepare(cinfo->hw.clk);
                        return ret;
                }
        }
index d0bf8b1c67de51ba27e756af870cea4ccfa67eec..f3931e38fac0fb58a9bb6262e0fe7d9da33a6269 100644 (file)
@@ -87,7 +87,7 @@ struct clockgen {
        struct device_node *node;
        void __iomem *regs;
        struct clockgen_chipinfo info; /* mutable copy */
-       struct clk *sysclk;
+       struct clk *sysclk, *coreclk;
        struct clockgen_pll pll[6];
        struct clk *cmux[NUM_CMUX];
        struct clk *hwaccel[NUM_HWACCEL];
@@ -904,7 +904,12 @@ static void __init create_muxes(struct clockgen *cg)
 
 static void __init clockgen_init(struct device_node *np);
 
-/* Legacy nodes may get probed before the parent clockgen node */
+/*
+ * Legacy nodes may get probed before the parent clockgen node.
+ * It is assumed that device trees with legacy nodes will not
+ * contain a "clocks" property -- otherwise the input clocks may
+ * not be initialized at this point.
+ */
 static void __init legacy_init_clockgen(struct device_node *np)
 {
        if (!clockgen.node)
@@ -945,18 +950,13 @@ static struct clk __init
        return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
 }
 
-static struct clk *sysclk_from_parent(const char *name)
+static struct clk __init *input_clock(const char *name, struct clk *clk)
 {
-       struct clk *clk;
-       const char *parent_name;
-
-       clk = of_clk_get(clockgen.node, 0);
-       if (IS_ERR(clk))
-               return clk;
+       const char *input_name;
 
        /* Register the input clock under the desired name. */
-       parent_name = __clk_get_name(clk);
-       clk = clk_register_fixed_factor(NULL, name, parent_name,
+       input_name = __clk_get_name(clk);
+       clk = clk_register_fixed_factor(NULL, name, input_name,
                                        0, 1, 1);
        if (IS_ERR(clk))
                pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
@@ -965,6 +965,29 @@ static struct clk *sysclk_from_parent(const char *name)
        return clk;
 }
 
+static struct clk __init *input_clock_by_name(const char *name,
+                                             const char *dtname)
+{
+       struct clk *clk;
+
+       clk = of_clk_get_by_name(clockgen.node, dtname);
+       if (IS_ERR(clk))
+               return clk;
+
+       return input_clock(name, clk);
+}
+
+static struct clk __init *input_clock_by_index(const char *name, int idx)
+{
+       struct clk *clk;
+
+       clk = of_clk_get(clockgen.node, 0);
+       if (IS_ERR(clk))
+               return clk;
+
+       return input_clock(name, clk);
+}
+
 static struct clk * __init create_sysclk(const char *name)
 {
        struct device_node *sysclk;
@@ -974,7 +997,11 @@ static struct clk * __init create_sysclk(const char *name)
        if (!IS_ERR(clk))
                return clk;
 
-       clk = sysclk_from_parent(name);
+       clk = input_clock_by_name(name, "sysclk");
+       if (!IS_ERR(clk))
+               return clk;
+
+       clk = input_clock_by_index(name, 0);
        if (!IS_ERR(clk))
                return clk;
 
@@ -985,7 +1012,27 @@ static struct clk * __init create_sysclk(const char *name)
                        return clk;
        }
 
-       pr_err("%s: No input clock\n", __func__);
+       pr_err("%s: No input sysclk\n", __func__);
+       return NULL;
+}
+
+static struct clk * __init create_coreclk(const char *name)
+{
+       struct clk *clk;
+
+       clk = input_clock_by_name(name, "coreclk");
+       if (!IS_ERR(clk))
+               return clk;
+
+       /*
+        * This indicates a mix of legacy nodes with the new coreclk
+        * mechanism, which should never happen.  If this error occurs,
+        * don't use the wrong input clock just because coreclk isn't
+        * ready yet.
+        */
+       if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER))
+               return clk;
+
        return NULL;
 }
 
@@ -1008,11 +1055,19 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
        u32 __iomem *reg;
        u32 mult;
        struct clockgen_pll *pll = &cg->pll[idx];
+       const char *input = "cg-sysclk";
        int i;
 
        if (!(cg->info.pll_mask & (1 << idx)))
                return;
 
+       if (cg->coreclk && idx != PLATFORM_PLL) {
+               if (IS_ERR(cg->coreclk))
+                       return;
+
+               input = "cg-coreclk";
+       }
+
        if (cg->info.flags & CG_VER3) {
                switch (idx) {
                case PLATFORM_PLL:
@@ -1063,7 +1118,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx)
                         "cg-pll%d-div%d", idx, i + 1);
 
                clk = clk_register_fixed_factor(NULL,
-                               pll->div[i].name, "cg-sysclk", 0, mult, i + 1);
+                               pll->div[i].name, input, 0, mult, i + 1);
                if (IS_ERR(clk)) {
                        pr_err("%s: %s: register failed %ld\n",
                               __func__, pll->div[i].name, PTR_ERR(clk));
@@ -1200,6 +1255,13 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data)
                        goto bad_args;
                clk = pll->div[idx].clk;
                break;
+       case 5:
+               if (idx != 0)
+                       goto bad_args;
+               clk = cg->coreclk;
+               if (IS_ERR(clk))
+                       clk = NULL;
+               break;
        default:
                goto bad_args;
        }
@@ -1311,6 +1373,7 @@ static void __init clockgen_init(struct device_node *np)
                clockgen.info.flags |= CG_CMUX_GE_PLAT;
 
        clockgen.sysclk = create_sysclk("cg-sysclk");
+       clockgen.coreclk = create_coreclk("cg-coreclk");
        create_plls(&clockgen);
        create_muxes(&clockgen);
 
index 96d37175d0ad59f47abd218db271f558c5921a4d..25854722810ed7791afd9830de51794e20ad676f 100644 (file)
@@ -71,15 +71,15 @@ static const struct clk_ops scpi_clk_ops = {
 };
 
 /* find closest match to given frequency in OPP table */
-static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
+static long __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
 {
        int idx;
-       u32 fmin = 0, fmax = ~0, ftmp;
+       unsigned long fmin = 0, fmax = ~0, ftmp;
        const struct scpi_opp *opp = clk->info->opps;
 
        for (idx = 0; idx < clk->info->count; idx++, opp++) {
                ftmp = opp->freq;
-               if (ftmp >= (u32)rate) {
+               if (ftmp >= rate) {
                        if (ftmp <= fmax)
                                fmax = ftmp;
                        break;
@@ -245,10 +245,12 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
                sclk->id = val;
 
                err = scpi_clk_ops_init(dev, match, sclk, name);
-               if (err)
+               if (err) {
                        dev_err(dev, "failed to register clock '%s'\n", name);
-               else
-                       dev_dbg(dev, "Registered clock '%s'\n", name);
+                       return err;
+               }
+
+               dev_dbg(dev, "Registered clock '%s'\n", name);
                clk_data->clk[idx] = sclk;
        }
 
index 96a9697b06cf4afcad0ed931f44cd866701dfdf4..a18258eb89cb1b1767a5335b7bf8938e66fafab2 100644 (file)
@@ -20,7 +20,7 @@ static const struct hisi_fixed_rate_clock hi3660_fixed_rate_clks[] = {
        { HI3660_CLK_FLL_SRC, "clk_fll_src", NULL, 0, 128000000, },
        { HI3660_CLK_PPLL0, "clk_ppll0", NULL, 0, 1600000000, },
        { HI3660_CLK_PPLL1, "clk_ppll1", NULL, 0, 1866000000, },
-       { HI3660_CLK_PPLL2, "clk_ppll2", NULL, 0, 960000000, },
+       { HI3660_CLK_PPLL2, "clk_ppll2", NULL, 0, 2880000000UL, },
        { HI3660_CLK_PPLL3, "clk_ppll3", NULL, 0, 1290000000, },
        { HI3660_CLK_SCPLL, "clk_scpll", NULL, 0, 245760000, },
        { HI3660_PCLK, "pclk", NULL, 0, 20000000, },
@@ -42,14 +42,19 @@ static const struct hisi_fixed_factor_clock hi3660_crg_fixed_factor_clks[] = {
        { HI3660_CLK_GATE_I2C6, "clk_gate_i2c6", "clk_i2c6_iomcu", 1, 4, 0, },
        { HI3660_CLK_DIV_SYSBUS, "clk_div_sysbus", "clk_mux_sysbus", 1, 7, 0, },
        { HI3660_CLK_DIV_320M, "clk_div_320m", "clk_320m_pll_gt", 1, 5, 0, },
-       { HI3660_CLK_DIV_A53, "clk_div_a53hpm", "clk_a53hpm_andgt", 1, 2, 0, },
+       { HI3660_CLK_DIV_A53, "clk_div_a53hpm", "clk_a53hpm_andgt", 1, 6, 0, },
        { HI3660_CLK_GATE_SPI0, "clk_gate_spi0", "clk_ppll0", 1, 8, 0, },
        { HI3660_CLK_GATE_SPI2, "clk_gate_spi2", "clk_ppll0", 1, 8, 0, },
        { HI3660_PCIEPHY_REF, "clk_pciephy_ref", "clk_div_pciephy", 1, 1, 0, },
        { HI3660_CLK_ABB_USB, "clk_abb_usb", "clk_gate_usb_tcxo_en", 1, 1, 0 },
+       { HI3660_VENC_VOLT_HOLD, "venc_volt_hold", "peri_volt_hold", 1, 1, 0, },
+       { HI3660_CLK_FAC_ISP_SNCLK, "clk_isp_snclk_fac", "clk_isp_snclk_angt",
+         1, 10, 0, },
 };
 
 static const struct hisi_gate_clock hi3660_crgctrl_gate_sep_clks[] = {
+       { HI3660_PERI_VOLT_HOLD, "peri_volt_hold", "clkin_sys",
+         CLK_SET_RATE_PARENT, 0x0, 0, 0, },
        { HI3660_HCLK_GATE_SDIO0, "hclk_gate_sdio0", "clk_div_sysbus",
          CLK_SET_RATE_PARENT, 0x0, 21, 0, },
        { HI3660_HCLK_GATE_SD, "hclk_gate_sd", "clk_div_sysbus",
@@ -120,6 +125,10 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_sep_clks[] = {
          CLK_SET_RATE_PARENT, 0x20, 27, 0, },
        { HI3660_CLK_GATE_DMAC, "clk_gate_dmac", "clk_div_sysbus",
          CLK_SET_RATE_PARENT, 0x30, 1, 0, },
+       { HI3660_CLK_GATE_VENC, "clk_gate_venc", "clk_div_venc",
+         CLK_SET_RATE_PARENT, 0x30, 10, 0, },
+       { HI3660_CLK_GATE_VDEC, "clk_gate_vdec", "clk_div_vdec",
+         CLK_SET_RATE_PARENT, 0x30, 11, 0, },
        { HI3660_PCLK_GATE_DSS, "pclk_gate_dss", "clk_div_cfgbus",
          CLK_SET_RATE_PARENT, 0x30, 12, 0, },
        { HI3660_ACLK_GATE_DSS, "aclk_gate_dss", "clk_gate_vivobus",
@@ -148,6 +157,12 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_sep_clks[] = {
          CLK_SET_RATE_PARENT, 0x40, 17, 0, },
        { HI3660_CLK_GATE_SDIO0, "clk_gate_sdio0", "clk_mux_sdio_sys",
          CLK_SET_RATE_PARENT, 0x40, 19, 0, },
+       { HI3660_CLK_GATE_ISP_SNCLK0, "clk_gate_isp_snclk0",
+         "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 16, 0, },
+       { HI3660_CLK_GATE_ISP_SNCLK1, "clk_gate_isp_snclk1",
+         "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 17, 0, },
+       { HI3660_CLK_GATE_ISP_SNCLK2, "clk_gate_isp_snclk2",
+         "clk_isp_snclk_mux", CLK_SET_RATE_PARENT, 0x50, 18, 0, },
        { HI3660_CLK_GATE_UFS_SUBSYS, "clk_gate_ufs_subsys", "clk_div_sysbus",
          CLK_SET_RATE_PARENT, 0x50, 21, 0, },
        { HI3660_PCLK_GATE_DSI0, "pclk_gate_dsi0", "clk_div_cfgbus",
@@ -171,6 +186,10 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_clks[] = {
          CLK_SET_RATE_PARENT, 0xf0, 7, CLK_GATE_HIWORD_MASK, },
        { HI3660_CLK_ANDGT_EDC0, "clk_andgt_edc0", "clk_mux_edc0",
          CLK_SET_RATE_PARENT, 0xf0, 8, CLK_GATE_HIWORD_MASK, },
+       { HI3660_CLK_ANDGT_VDEC, "clk_andgt_vdec", "clk_mux_vdec",
+         CLK_SET_RATE_PARENT, 0xf0, 15, CLK_GATE_HIWORD_MASK, },
+       { HI3660_CLK_ANDGT_VENC, "clk_andgt_venc", "clk_mux_venc",
+         CLK_SET_RATE_PARENT, 0xf4, 0, CLK_GATE_HIWORD_MASK, },
        { HI3660_CLK_GATE_UFSPHY_GT, "clk_gate_ufsphy_gt", "clk_div_ufsperi",
          CLK_SET_RATE_PARENT, 0xf4, 1, CLK_GATE_HIWORD_MASK, },
        { HI3660_CLK_ANDGT_MMC, "clk_andgt_mmc", "clk_mux_mmc_pll",
@@ -195,6 +214,8 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_clks[] = {
          CLK_SET_RATE_PARENT, 0xf8, 3, CLK_GATE_HIWORD_MASK, },
        { HI3660_CLK_320M_PLL_GT, "clk_320m_pll_gt", "clk_mux_320m",
          CLK_SET_RATE_PARENT, 0xf8, 10, 0, },
+       { HI3660_CLK_ANGT_ISP_SNCLK, "clk_isp_snclk_angt", "clk_div_a53hpm",
+         CLK_SET_RATE_PARENT, 0x108, 2, CLK_GATE_HIWORD_MASK, },
        { HI3660_AUTODIV_EMMC0BUS, "autodiv_emmc0bus", "autodiv_sysbus",
          CLK_SET_RATE_PARENT, 0x404, 1, CLK_GATE_HIWORD_MASK, },
        { HI3660_AUTODIV_SYSBUS, "autodiv_sysbus", "clk_div_sysbus",
@@ -205,6 +226,8 @@ static const struct hisi_gate_clock hi3660_crgctrl_gate_clks[] = {
          "clk_gate_ufs_tcxo_en", CLK_SET_RATE_PARENT, 0x420, 14, 0, },
 };
 
+static const char *const
+clk_mux_sysbus_p[] = {"clk_ppll1", "clk_ppll0"};
 static const char *const
 clk_mux_sdio_sys_p[] = {"clk_factor_mmc", "clk_div_sdio",};
 static const char *const
@@ -237,10 +260,14 @@ static const char *const
 clk_mux_spi_p[] = {"clkin_sys", "clk_div_spi",};
 static const char *const
 clk_mux_i2c_p[] = {"clkin_sys", "clk_div_i2c",};
+static const char *const
+clk_mux_venc_p[] = {"clk_ppll0", "clk_ppll1", "clk_ppll3", "clk_ppll3",};
+static const char *const
+clk_mux_isp_snclk_p[] = {"clkin_sys", "clk_isp_snclk_div"};
 
 static const struct hisi_mux_clock hi3660_crgctrl_mux_clks[] = {
-       { HI3660_CLK_MUX_SYSBUS, "clk_mux_sysbus", clk_mux_sdio_sys_p,
-         ARRAY_SIZE(clk_mux_sdio_sys_p), CLK_SET_RATE_PARENT, 0xac, 0, 1,
+       { HI3660_CLK_MUX_SYSBUS, "clk_mux_sysbus", clk_mux_sysbus_p,
+         ARRAY_SIZE(clk_mux_sysbus_p), CLK_SET_RATE_PARENT, 0xac, 0, 1,
          CLK_MUX_HIWORD_MASK, },
        { HI3660_CLK_MUX_UART0, "clk_mux_uart0", clk_mux_uart0_p,
          ARRAY_SIZE(clk_mux_uart0_p), CLK_SET_RATE_PARENT, 0xac, 2, 1,
@@ -281,6 +308,12 @@ static const struct hisi_mux_clock hi3660_crgctrl_mux_clks[] = {
        { HI3660_CLK_MUX_SDIO_PLL, "clk_mux_sdio_pll", clk_mux_pll_p,
          ARRAY_SIZE(clk_mux_pll_p), CLK_SET_RATE_PARENT, 0xc0, 4, 2,
          CLK_MUX_HIWORD_MASK, },
+       { HI3660_CLK_MUX_VENC, "clk_mux_venc", clk_mux_venc_p,
+         ARRAY_SIZE(clk_mux_venc_p), CLK_SET_RATE_PARENT, 0xc8, 11, 2,
+         CLK_MUX_HIWORD_MASK, },
+       { HI3660_CLK_MUX_VDEC, "clk_mux_vdec", clk_mux_pll0123_p,
+         ARRAY_SIZE(clk_mux_pll0123_p), CLK_SET_RATE_PARENT, 0xcc, 5, 2,
+         CLK_MUX_HIWORD_MASK, },
        { HI3660_CLK_MUX_VIVOBUS, "clk_mux_vivobus", clk_mux_pll0123_p,
          ARRAY_SIZE(clk_mux_pll0123_p), CLK_SET_RATE_PARENT, 0xd0, 12, 2,
          CLK_MUX_HIWORD_MASK, },
@@ -290,6 +323,9 @@ static const struct hisi_mux_clock hi3660_crgctrl_mux_clks[] = {
        { HI3660_CLK_MUX_320M, "clk_mux_320m", clk_mux_pll02p,
          ARRAY_SIZE(clk_mux_pll02p), CLK_SET_RATE_PARENT, 0x100, 0, 1,
          CLK_MUX_HIWORD_MASK, },
+       { HI3660_CLK_MUX_ISP_SNCLK, "clk_isp_snclk_mux", clk_mux_isp_snclk_p,
+         ARRAY_SIZE(clk_mux_isp_snclk_p), CLK_SET_RATE_PARENT, 0x108, 3, 1,
+         CLK_MUX_HIWORD_MASK, },
        { HI3660_CLK_MUX_IOPERI, "clk_mux_ioperi", clk_mux_ioperi_p,
          ARRAY_SIZE(clk_mux_ioperi_p), CLK_SET_RATE_PARENT, 0x108, 10, 1,
          CLK_MUX_HIWORD_MASK, },
@@ -316,6 +352,10 @@ static const struct hisi_divider_clock hi3660_crgctrl_divider_clks[] = {
          CLK_SET_RATE_PARENT, 0xc0, 8, 6, CLK_DIVIDER_HIWORD_MASK, 0, },
        { HI3660_CLK_DIV_SPI, "clk_div_spi", "clk_andgt_spi",
          CLK_SET_RATE_PARENT, 0xc4, 12, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3660_CLK_DIV_VENC, "clk_div_venc", "clk_andgt_venc",
+         CLK_SET_RATE_PARENT, 0xc8, 6, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3660_CLK_DIV_VDEC, "clk_div_vdec", "clk_andgt_vdec",
+         CLK_SET_RATE_PARENT, 0xcc, 0, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
        { HI3660_CLK_DIV_VIVOBUS, "clk_div_vivobus", "clk_vivobus_andgt",
          CLK_SET_RATE_PARENT, 0xd0, 7, 5, CLK_DIVIDER_HIWORD_MASK, 0, },
        { HI3660_CLK_DIV_I2C, "clk_div_i2c", "clk_div_320m",
@@ -332,6 +372,8 @@ static const struct hisi_divider_clock hi3660_crgctrl_divider_clks[] = {
          CLK_SET_RATE_PARENT, 0xec, 14, 1, CLK_DIVIDER_HIWORD_MASK, 0, },
        { HI3660_CLK_DIV_AOMM, "clk_div_aomm", "clk_aomm_andgt",
          CLK_SET_RATE_PARENT, 0x100, 7, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
+       { HI3660_CLK_DIV_ISP_SNCLK, "clk_isp_snclk_div", "clk_isp_snclk_fac",
+         CLK_SET_RATE_PARENT, 0x108, 0, 2, CLK_DIVIDER_HIWORD_MASK, 0, },
        { HI3660_CLK_DIV_IOPERI, "clk_div_ioperi", "clk_mux_ioperi",
          CLK_SET_RATE_PARENT, 0x108, 11, 4, CLK_DIVIDER_HIWORD_MASK, 0, },
 };
@@ -427,6 +469,8 @@ static const struct hisi_gate_clock hi3660_iomcu_gate_sep_clks[] = {
          CLK_SET_RATE_PARENT, 0x90, 0, 0, },
 };
 
+static struct hisi_clock_data *clk_crgctrl_data;
+
 static void hi3660_clk_iomcu_init(struct device_node *np)
 {
        struct hisi_clock_data *clk_data;
@@ -489,38 +533,64 @@ static void hi3660_clk_sctrl_init(struct device_node *np)
                                  clk_data);
 }
 
-static void hi3660_clk_crgctrl_init(struct device_node *np)
+static void hi3660_clk_crgctrl_early_init(struct device_node *np)
 {
-       struct hisi_clock_data *clk_data;
        int nr = ARRAY_SIZE(hi3660_fixed_rate_clks) +
                 ARRAY_SIZE(hi3660_crgctrl_gate_sep_clks) +
                 ARRAY_SIZE(hi3660_crgctrl_gate_clks) +
                 ARRAY_SIZE(hi3660_crgctrl_mux_clks) +
                 ARRAY_SIZE(hi3660_crg_fixed_factor_clks) +
                 ARRAY_SIZE(hi3660_crgctrl_divider_clks);
+       int i;
 
-       clk_data = hisi_clk_init(np, nr);
-       if (!clk_data)
+       clk_crgctrl_data = hisi_clk_init(np, nr);
+       if (!clk_crgctrl_data)
                return;
 
+       for (i = 0; i < nr; i++)
+               clk_crgctrl_data->clk_data.clks[i] = ERR_PTR(-EPROBE_DEFER);
+
        hisi_clk_register_fixed_rate(hi3660_fixed_rate_clks,
                                     ARRAY_SIZE(hi3660_fixed_rate_clks),
-                                    clk_data);
+                                    clk_crgctrl_data);
+}
+CLK_OF_DECLARE_DRIVER(hi3660_clk_crgctrl, "hisilicon,hi3660-crgctrl",
+                     hi3660_clk_crgctrl_early_init);
+
+static void hi3660_clk_crgctrl_init(struct device_node *np)
+{
+       struct clk **clks;
+       int i;
+
+       if (!clk_crgctrl_data)
+               hi3660_clk_crgctrl_early_init(np);
+
+       /* clk_crgctrl_data initialization failed */
+       if (!clk_crgctrl_data)
+               return;
+
        hisi_clk_register_gate_sep(hi3660_crgctrl_gate_sep_clks,
                                   ARRAY_SIZE(hi3660_crgctrl_gate_sep_clks),
-                                  clk_data);
+                                  clk_crgctrl_data);
        hisi_clk_register_gate(hi3660_crgctrl_gate_clks,
                               ARRAY_SIZE(hi3660_crgctrl_gate_clks),
-                              clk_data);
+                              clk_crgctrl_data);
        hisi_clk_register_mux(hi3660_crgctrl_mux_clks,
                              ARRAY_SIZE(hi3660_crgctrl_mux_clks),
-                             clk_data);
+                             clk_crgctrl_data);
        hisi_clk_register_fixed_factor(hi3660_crg_fixed_factor_clks,
                                       ARRAY_SIZE(hi3660_crg_fixed_factor_clks),
-                                      clk_data);
+                                      clk_crgctrl_data);
        hisi_clk_register_divider(hi3660_crgctrl_divider_clks,
                                  ARRAY_SIZE(hi3660_crgctrl_divider_clks),
-                                 clk_data);
+                                 clk_crgctrl_data);
+
+       clks = clk_crgctrl_data->clk_data.clks;
+       for (i = 0; i < clk_crgctrl_data->clk_data.clk_num; i++) {
+               if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -EPROBE_DEFER)
+                       pr_err("Failed to register crgctrl clock[%d] err=%ld\n",
+                              i, PTR_ERR(clks[i]));
+       }
 }
 
 static const struct of_device_id hi3660_clk_match_table[] = {
index 2ae151ce623a9602f389c09a6817eb5698c3a32e..4181b68085456d9cc8f9f0ff0b8bbca5eb3fa7f5 100644 (file)
@@ -285,3 +285,25 @@ static void __init hi6220_clk_power_init(struct device_node *np)
                                ARRAY_SIZE(hi6220_div_clks_power), clk_data);
 }
 CLK_OF_DECLARE(hi6220_clk_power, "hisilicon,hi6220-pmctrl", hi6220_clk_power_init);
+
+/* clocks in acpu */
+static const struct hisi_gate_clock hi6220_acpu_sc_gate_sep_clks[] = {
+       { HI6220_ACPU_SFT_AT_S, "sft_at_s", "cs_atb",
+         CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0xc, 11, 0, },
+};
+
+static void __init hi6220_clk_acpu_init(struct device_node *np)
+{
+       struct hisi_clock_data *clk_data;
+       int nr = ARRAY_SIZE(hi6220_acpu_sc_gate_sep_clks);
+
+       clk_data = hisi_clk_init(np, nr);
+       if (!clk_data)
+               return;
+
+       hisi_clk_register_gate_sep(hi6220_acpu_sc_gate_sep_clks,
+                                  ARRAY_SIZE(hi6220_acpu_sc_gate_sep_clks),
+                                  clk_data);
+}
+
+CLK_OF_DECLARE(hi6220_clk_acpu, "hisilicon,hi6220-acpu-sctrl", hi6220_clk_acpu_init);
index fc8b5bc2d50d2fdf77a2cc5cc0e744667dece411..ed8bb5f7507f2c22aa750367721dbfad8ed5355c 100644 (file)
@@ -44,6 +44,9 @@
 #define HI3798CV200_ETH_BUS0_CLK       78
 #define HI3798CV200_ETH_BUS1_CLK       79
 #define HI3798CV200_COMBPHY1_MUX       80
+#define HI3798CV200_FIXED_12M  81
+#define HI3798CV200_FIXED_48M  82
+#define HI3798CV200_FIXED_60M  83
 
 #define HI3798CV200_CRG_NR_CLKS                128
 
@@ -51,9 +54,12 @@ static const struct hisi_fixed_rate_clock hi3798cv200_fixed_rate_clks[] = {
        { HISTB_OSC_CLK, "clk_osc", NULL, 0, 24000000, },
        { HISTB_APB_CLK, "clk_apb", NULL, 0, 100000000, },
        { HISTB_AHB_CLK, "clk_ahb", NULL, 0, 200000000, },
+       { HI3798CV200_FIXED_12M, "12m", NULL, 0, 12000000, },
        { HI3798CV200_FIXED_24M, "24m", NULL, 0, 24000000, },
        { HI3798CV200_FIXED_25M, "25m", NULL, 0, 25000000, },
+       { HI3798CV200_FIXED_48M, "48m", NULL, 0, 48000000, },
        { HI3798CV200_FIXED_50M, "50m", NULL, 0, 50000000, },
+       { HI3798CV200_FIXED_60M, "60m", NULL, 0, 60000000, },
        { HI3798CV200_FIXED_75M, "75m", NULL, 0, 75000000, },
        { HI3798CV200_FIXED_100M, "100m", NULL, 0, 100000000, },
        { HI3798CV200_FIXED_150M, "150m", NULL, 0, 150000000, },
@@ -134,6 +140,21 @@ static const struct hisi_gate_clock hi3798cv200_gate_clks[] = {
        /* COMBPHY1 */
        { HISTB_COMBPHY1_CLK, "clk_combphy1", "combphy1_mux",
                CLK_SET_RATE_PARENT, 0x188, 8, 0, },
+       /* USB2 */
+       { HISTB_USB2_BUS_CLK, "clk_u2_bus", "clk_ahb",
+               CLK_SET_RATE_PARENT, 0xb8, 0, 0, },
+       { HISTB_USB2_PHY_CLK, "clk_u2_phy", "60m",
+               CLK_SET_RATE_PARENT, 0xb8, 4, 0, },
+       { HISTB_USB2_12M_CLK, "clk_u2_12m", "12m",
+               CLK_SET_RATE_PARENT, 0xb8, 2, 0 },
+       { HISTB_USB2_48M_CLK, "clk_u2_48m", "48m",
+               CLK_SET_RATE_PARENT, 0xb8, 1, 0 },
+       { HISTB_USB2_UTMI_CLK, "clk_u2_utmi", "60m",
+               CLK_SET_RATE_PARENT, 0xb8, 5, 0 },
+       { HISTB_USB2_PHY1_REF_CLK, "clk_u2_phy1_ref", "24m",
+               CLK_SET_RATE_PARENT, 0xbc, 0, 0 },
+       { HISTB_USB2_PHY2_REF_CLK, "clk_u2_phy2_ref", "24m",
+               CLK_SET_RATE_PARENT, 0xbc, 2, 0 },
 };
 
 static struct hisi_clock_data *hi3798cv200_clk_register(
index 93b03640da9bef56d02dd513bf3d203e1eebd845..3da121826b1baba4667858e01579dfb7d1acab12 100644 (file)
@@ -25,6 +25,7 @@
 static u32 share_count_sai1;
 static u32 share_count_sai2;
 static u32 share_count_sai3;
+static u32 share_count_nand;
 
 static struct clk_div_table test_div_table[] = {
        { .val = 3, .div = 1, },
@@ -424,7 +425,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
 
        clks[IMX7D_PLL_ARM_MAIN]  = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "osc", base + 0x60, 0x7f);
-       clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_dram_main", "osc", base + 0x70, 0x7f);
+       clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_DDR_IMX7, "pll_dram_main", "osc", base + 0x70, 0x7f);
        clks[IMX7D_PLL_SYS_MAIN]  = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1);
        clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0);
        clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "osc", base + 0xf0, 0x7f);
@@ -748,7 +749,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
        clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider2("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
        clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
-       clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider2("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6);
+       clks[IMX7D_NAND_ROOT_CLK] = imx_clk_divider2("nand_root_clk", "nand_pre_div", base + 0xaa00, 0, 6);
        clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
        clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider2("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6);
        clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider2("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6);
@@ -825,7 +826,8 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
        clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
        clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0);
-       clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate4("nand_root_clk", "nand_post_div", base + 0x4140, 0);
+       clks[IMX7D_NAND_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140, 0, &share_count_nand);
+       clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk", base + 0x4140, 0, &share_count_nand);
        clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate4("qspi_root_clk", "qspi_post_div", base + 0x4150, 0);
        clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate4("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0);
        clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate4("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0);
index f1099167ba3138732cf277e19912dfcf4f263f6c..9af62ee8f347af29bfd474c0475957aa2da85c8a 100644 (file)
@@ -27,6 +27,7 @@
 #define BM_PLL_POWER           (0x1 << 12)
 #define BM_PLL_LOCK            (0x1 << 31)
 #define IMX7_ENET_PLL_POWER    (0x1 << 5)
+#define IMX7_DDR_PLL_POWER     (0x1 << 20)
 
 /**
  * struct clk_pllv3 - IMX PLL clock version 3
@@ -451,6 +452,10 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
                pll->ref_clock = 500000000;
                ops = &clk_pllv3_enet_ops;
                break;
+       case IMX_PLLV3_DDR_IMX7:
+               pll->power_bit = IMX7_DDR_PLL_POWER;
+               ops = &clk_pllv3_av_ops;
+               break;
        default:
                ops = &clk_pllv3_ops;
        }
index e1f5e425db732b9fd5230bb34d26fa42311cb634..d54f0720afbaa7f274e30b966ca6f92bae10c391 100644 (file)
@@ -35,6 +35,7 @@ enum imx_pllv3_type {
        IMX_PLLV3_ENET,
        IMX_PLLV3_ENET_IMX7,
        IMX_PLLV3_SYS_VF610,
+       IMX_PLLV3_DDR_IMX7,
 };
 
 struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig
new file mode 100644 (file)
index 0000000..7e9f017
--- /dev/null
@@ -0,0 +1,16 @@
+config COMMON_CLK_KEYSTONE
+       tristate "Clock drivers for Keystone based SOCs"
+       depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
+       ---help---
+         Supports clock drivers for Keystone based SOCs. These SOCs have local
+         a power sleep control module that gate the clock to the IPs and PLLs.
+
+config TI_SCI_CLK
+       tristate "TI System Control Interface clock drivers"
+       depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
+       depends on TI_SCI_PROTOCOL
+       default ARCH_KEYSTONE
+       ---help---
+         This adds the clock driver support over TI System Control Interface.
+         If you wish to use clock resources from the PMMC firmware, say Y.
+         Otherwise, say N.
index 0477cf63f132b56673aec27578eb580bb4862e70..c12593966f9b6a7c51f4d721739f01bdd2643caa 100644 (file)
@@ -1 +1,2 @@
-obj-y                  += pll.o gate.o
+obj-$(CONFIG_COMMON_CLK_KEYSTONE)      += pll.o gate.o
+obj-$(CONFIG_TI_SCI_CLK)               += sci-clk.o
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
new file mode 100644 (file)
index 0000000..43b0f2f
--- /dev/null
@@ -0,0 +1,724 @@
+/*
+ * SCI Clock driver for keystone based devices
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *     Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#define SCI_CLK_SSC_ENABLE             BIT(0)
+#define SCI_CLK_ALLOW_FREQ_CHANGE      BIT(1)
+#define SCI_CLK_INPUT_TERMINATION      BIT(2)
+
+/**
+ * struct sci_clk_data - TI SCI clock data
+ * @dev: device index
+ * @num_clks: number of clocks for this device
+ */
+struct sci_clk_data {
+       u16 dev;
+       u16 num_clks;
+};
+
+/**
+ * struct sci_clk_provider - TI SCI clock provider representation
+ * @sci: Handle to the System Control Interface protocol handler
+ * @ops: Pointer to the SCI ops to be used by the clocks
+ * @dev: Device pointer for the clock provider
+ * @clk_data: Clock data
+ * @clocks: Clocks array for this device
+ */
+struct sci_clk_provider {
+       const struct ti_sci_handle *sci;
+       const struct ti_sci_clk_ops *ops;
+       struct device *dev;
+       const struct sci_clk_data *clk_data;
+       struct clk_hw **clocks;
+};
+
+/**
+ * struct sci_clk - TI SCI clock representation
+ * @hw:                 Hardware clock cookie for common clock framework
+ * @dev_id:     Device index
+ * @clk_id:     Clock index
+ * @node:       Clocks list link
+ * @provider:   Master clock provider
+ * @flags:      Flags for the clock
+ */
+struct sci_clk {
+       struct clk_hw hw;
+       u16 dev_id;
+       u8 clk_id;
+       struct list_head node;
+       struct sci_clk_provider *provider;
+       u8 flags;
+};
+
+#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
+
+/**
+ * sci_clk_prepare - Prepare (enable) a TI SCI clock
+ * @hw: clock to prepare
+ *
+ * Prepares a clock to be actively used. Returns the SCI protocol status.
+ */
+static int sci_clk_prepare(struct clk_hw *hw)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+       bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE;
+       bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE;
+       bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION;
+
+       return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id,
+                                            clk->clk_id, enable_ssc,
+                                            allow_freq_change,
+                                            input_termination);
+}
+
+/**
+ * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
+ * @hw: clock to unprepare
+ *
+ * Un-prepares a clock from active state.
+ */
+static void sci_clk_unprepare(struct clk_hw *hw)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+       int ret;
+
+       ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id,
+                                           clk->clk_id);
+       if (ret)
+               dev_err(clk->provider->dev,
+                       "unprepare failed for dev=%d, clk=%d, ret=%d\n",
+                       clk->dev_id, clk->clk_id, ret);
+}
+
+/**
+ * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
+ * @hw: clock to check status for
+ *
+ * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
+ * value if clock is enabled, zero otherwise.
+ */
+static int sci_clk_is_prepared(struct clk_hw *hw)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+       bool req_state, current_state;
+       int ret;
+
+       ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id,
+                                       clk->clk_id, &req_state,
+                                       &current_state);
+       if (ret) {
+               dev_err(clk->provider->dev,
+                       "is_prepared failed for dev=%d, clk=%d, ret=%d\n",
+                       clk->dev_id, clk->clk_id, ret);
+               return 0;
+       }
+
+       return req_state;
+}
+
+/**
+ * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a TI SCI clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
+                                        unsigned long parent_rate)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+       u64 freq;
+       int ret;
+
+       ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
+                                          clk->clk_id, &freq);
+       if (ret) {
+               dev_err(clk->provider->dev,
+                       "recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
+                       clk->dev_id, clk->clk_id, ret);
+               return 0;
+       }
+
+       return freq;
+}
+
+/**
+ * sci_clk_determine_rate - Determines a clock rate a clock can be set to
+ * @hw: clock to change rate for
+ * @req: requested rate configuration for the clock
+ *
+ * Determines a suitable clock rate and parent for a TI SCI clock.
+ * The parent handling is un-used, as generally the parent clock rates
+ * are not known by the kernel; instead these are internally handled
+ * by the firmware. Returns 0 on success, negative error value on failure.
+ */
+static int sci_clk_determine_rate(struct clk_hw *hw,
+                                 struct clk_rate_request *req)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+       int ret;
+       u64 new_rate;
+
+       ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
+                                                     clk->dev_id,
+                                                     clk->clk_id,
+                                                     req->min_rate,
+                                                     req->rate,
+                                                     req->max_rate,
+                                                     &new_rate);
+       if (ret) {
+               dev_err(clk->provider->dev,
+                       "determine-rate failed for dev=%d, clk=%d, ret=%d\n",
+                       clk->dev_id, clk->clk_id, ret);
+               return ret;
+       }
+
+       req->rate = new_rate;
+
+       return 0;
+}
+
+/**
+ * sci_clk_set_rate - Set rate for a TI SCI clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for TI SCI clocks
+ *
+ * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
+ * protocol status.
+ */
+static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                           unsigned long parent_rate)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+
+       return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
+                                           clk->clk_id, rate, rate, rate);
+}
+
+/**
+ * sci_clk_get_parent - Get the current parent of a TI SCI clock
+ * @hw: clock to get parent for
+ *
+ * Returns the index of the currently selected parent for a TI SCI clock.
+ */
+static u8 sci_clk_get_parent(struct clk_hw *hw)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+       u8 parent_id;
+       int ret;
+
+       ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id,
+                                            clk->clk_id, &parent_id);
+       if (ret) {
+               dev_err(clk->provider->dev,
+                       "get-parent failed for dev=%d, clk=%d, ret=%d\n",
+                       clk->dev_id, clk->clk_id, ret);
+               return 0;
+       }
+
+       return parent_id - clk->clk_id - 1;
+}
+
+/**
+ * sci_clk_set_parent - Set the parent of a TI SCI clock
+ * @hw: clock to set parent for
+ * @index: new parent index for the clock
+ *
+ * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
+ */
+static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct sci_clk *clk = to_sci_clk(hw);
+
+       return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
+                                             clk->clk_id,
+                                             index + 1 + clk->clk_id);
+}
+
+static const struct clk_ops sci_clk_ops = {
+       .prepare = sci_clk_prepare,
+       .unprepare = sci_clk_unprepare,
+       .is_prepared = sci_clk_is_prepared,
+       .recalc_rate = sci_clk_recalc_rate,
+       .determine_rate = sci_clk_determine_rate,
+       .set_rate = sci_clk_set_rate,
+       .get_parent = sci_clk_get_parent,
+       .set_parent = sci_clk_set_parent,
+};
+
+/**
+ * _sci_clk_get - Gets a handle for an SCI clock
+ * @provider: Handle to SCI clock provider
+ * @dev_id: device ID for the clock to register
+ * @clk_id: clock ID for the clock to register
+ *
+ * Gets a handle to an existing TI SCI hw clock, or builds a new clock
+ * entry and registers it with the common clock framework. Called from
+ * the common clock framework, when a corresponding of_clk_get call is
+ * executed, or recursively from itself when parsing parent clocks.
+ * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *_sci_clk_build(struct sci_clk_provider *provider,
+                                    u16 dev_id, u8 clk_id)
+{
+       struct clk_init_data init = { NULL };
+       struct sci_clk *sci_clk = NULL;
+       char *name = NULL;
+       char **parent_names = NULL;
+       int i;
+       int ret;
+
+       sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
+       if (!sci_clk)
+               return ERR_PTR(-ENOMEM);
+
+       sci_clk->dev_id = dev_id;
+       sci_clk->clk_id = clk_id;
+       sci_clk->provider = provider;
+
+       ret = provider->ops->get_num_parents(provider->sci, dev_id,
+                                            clk_id,
+                                            &init.num_parents);
+       if (ret)
+               goto err;
+
+       name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
+                        sci_clk->dev_id, sci_clk->clk_id);
+
+       init.name = name;
+
+       /*
+        * From kernel point of view, we only care about a clocks parents,
+        * if it has more than 1 possible parent. In this case, it is going
+        * to have mux functionality. Otherwise it is going to act as a root
+        * clock.
+        */
+       if (init.num_parents < 2)
+               init.num_parents = 0;
+
+       if (init.num_parents) {
+               parent_names = kcalloc(init.num_parents, sizeof(char *),
+                                      GFP_KERNEL);
+
+               if (!parent_names) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               for (i = 0; i < init.num_parents; i++) {
+                       char *parent_name;
+
+                       parent_name = kasprintf(GFP_KERNEL, "%s:%d:%d",
+                                               dev_name(provider->dev),
+                                               sci_clk->dev_id,
+                                               sci_clk->clk_id + 1 + i);
+                       if (!parent_name) {
+                               ret = -ENOMEM;
+                               goto err;
+                       }
+                       parent_names[i] = parent_name;
+               }
+               init.parent_names = (void *)parent_names;
+       }
+
+       init.ops = &sci_clk_ops;
+       sci_clk->hw.init = &init;
+
+       ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
+       if (ret)
+               dev_err(provider->dev, "failed clk register with %d\n", ret);
+
+err:
+       if (parent_names) {
+               for (i = 0; i < init.num_parents; i++)
+                       kfree(parent_names[i]);
+
+               kfree(parent_names);
+       }
+
+       kfree(name);
+
+       if (ret)
+               return ERR_PTR(ret);
+
+       return &sci_clk->hw;
+}
+
+/**
+ * sci_clk_get - Xlate function for getting clock handles
+ * @clkspec: device tree clock specifier
+ * @data: pointer to the clock provider
+ *
+ * Xlate function for retrieving clock TI SCI hw clock handles based on
+ * device tree clock specifier. Called from the common clock framework,
+ * when a corresponding of_clk_get call is executed. Returns a pointer
+ * to the TI SCI hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct sci_clk_provider *provider = data;
+       u16 dev_id;
+       u8 clk_id;
+       const struct sci_clk_data *clks = provider->clk_data;
+       struct clk_hw **clocks = provider->clocks;
+
+       if (clkspec->args_count != 2)
+               return ERR_PTR(-EINVAL);
+
+       dev_id = clkspec->args[0];
+       clk_id = clkspec->args[1];
+
+       while (clks->num_clks) {
+               if (clks->dev == dev_id) {
+                       if (clk_id >= clks->num_clks)
+                               return ERR_PTR(-EINVAL);
+
+                       return clocks[clk_id];
+               }
+
+               clks++;
+       }
+
+       return ERR_PTR(-ENODEV);
+}
+
+static int ti_sci_init_clocks(struct sci_clk_provider *p)
+{
+       const struct sci_clk_data *data = p->clk_data;
+       struct clk_hw *hw;
+       int i;
+
+       while (data->num_clks) {
+               p->clocks = devm_kcalloc(p->dev, data->num_clks,
+                                        sizeof(struct sci_clk),
+                                        GFP_KERNEL);
+               if (!p->clocks)
+                       return -ENOMEM;
+
+               for (i = 0; i < data->num_clks; i++) {
+                       hw = _sci_clk_build(p, data->dev, i);
+                       if (!IS_ERR(hw)) {
+                               p->clocks[i] = hw;
+                               continue;
+                       }
+
+                       /* Skip any holes in the clock lists */
+                       if (PTR_ERR(hw) == -ENODEV)
+                               continue;
+
+                       return PTR_ERR(hw);
+               }
+               data++;
+       }
+
+       return 0;
+}
+
+static const struct sci_clk_data k2g_clk_data[] = {
+       /* pmmc */
+       { .dev = 0x0, .num_clks = 4 },
+
+       /* mlb0 */
+       { .dev = 0x1, .num_clks = 5 },
+
+       /* dss0 */
+       { .dev = 0x2, .num_clks = 2 },
+
+       /* mcbsp0 */
+       { .dev = 0x3, .num_clks = 8 },
+
+       /* mcasp0 */
+       { .dev = 0x4, .num_clks = 8 },
+
+       /* mcasp1 */
+       { .dev = 0x5, .num_clks = 8 },
+
+       /* mcasp2 */
+       { .dev = 0x6, .num_clks = 8 },
+
+       /* dcan0 */
+       { .dev = 0x8, .num_clks = 2 },
+
+       /* dcan1 */
+       { .dev = 0x9, .num_clks = 2 },
+
+       /* emif0 */
+       { .dev = 0xa, .num_clks = 6 },
+
+       /* mmchs0 */
+       { .dev = 0xb, .num_clks = 3 },
+
+       /* mmchs1 */
+       { .dev = 0xc, .num_clks = 3 },
+
+       /* gpmc0 */
+       { .dev = 0xd, .num_clks = 1 },
+
+       /* elm0 */
+       { .dev = 0xe, .num_clks = 1 },
+
+       /* spi0 */
+       { .dev = 0x10, .num_clks = 1 },
+
+       /* spi1 */
+       { .dev = 0x11, .num_clks = 1 },
+
+       /* spi2 */
+       { .dev = 0x12, .num_clks = 1 },
+
+       /* spi3 */
+       { .dev = 0x13, .num_clks = 1 },
+
+       /* icss0 */
+       { .dev = 0x14, .num_clks = 6 },
+
+       /* icss1 */
+       { .dev = 0x15, .num_clks = 6 },
+
+       /* usb0 */
+       { .dev = 0x16, .num_clks = 7 },
+
+       /* usb1 */
+       { .dev = 0x17, .num_clks = 7 },
+
+       /* nss0 */
+       { .dev = 0x18, .num_clks = 14 },
+
+       /* pcie0 */
+       { .dev = 0x19, .num_clks = 1 },
+
+       /* gpio0 */
+       { .dev = 0x1b, .num_clks = 1 },
+
+       /* gpio1 */
+       { .dev = 0x1c, .num_clks = 1 },
+
+       /* timer64_0 */
+       { .dev = 0x1d, .num_clks = 9 },
+
+       /* timer64_1 */
+       { .dev = 0x1e, .num_clks = 9 },
+
+       /* timer64_2 */
+       { .dev = 0x1f, .num_clks = 9 },
+
+       /* timer64_3 */
+       { .dev = 0x20, .num_clks = 9 },
+
+       /* timer64_4 */
+       { .dev = 0x21, .num_clks = 9 },
+
+       /* timer64_5 */
+       { .dev = 0x22, .num_clks = 9 },
+
+       /* timer64_6 */
+       { .dev = 0x23, .num_clks = 9 },
+
+       /* msgmgr0 */
+       { .dev = 0x25, .num_clks = 1 },
+
+       /* bootcfg0 */
+       { .dev = 0x26, .num_clks = 1 },
+
+       /* arm_bootrom0 */
+       { .dev = 0x27, .num_clks = 1 },
+
+       /* dsp_bootrom0 */
+       { .dev = 0x29, .num_clks = 1 },
+
+       /* debugss0 */
+       { .dev = 0x2b, .num_clks = 8 },
+
+       /* uart0 */
+       { .dev = 0x2c, .num_clks = 1 },
+
+       /* uart1 */
+       { .dev = 0x2d, .num_clks = 1 },
+
+       /* uart2 */
+       { .dev = 0x2e, .num_clks = 1 },
+
+       /* ehrpwm0 */
+       { .dev = 0x2f, .num_clks = 1 },
+
+       /* ehrpwm1 */
+       { .dev = 0x30, .num_clks = 1 },
+
+       /* ehrpwm2 */
+       { .dev = 0x31, .num_clks = 1 },
+
+       /* ehrpwm3 */
+       { .dev = 0x32, .num_clks = 1 },
+
+       /* ehrpwm4 */
+       { .dev = 0x33, .num_clks = 1 },
+
+       /* ehrpwm5 */
+       { .dev = 0x34, .num_clks = 1 },
+
+       /* eqep0 */
+       { .dev = 0x35, .num_clks = 1 },
+
+       /* eqep1 */
+       { .dev = 0x36, .num_clks = 1 },
+
+       /* eqep2 */
+       { .dev = 0x37, .num_clks = 1 },
+
+       /* ecap0 */
+       { .dev = 0x38, .num_clks = 1 },
+
+       /* ecap1 */
+       { .dev = 0x39, .num_clks = 1 },
+
+       /* i2c0 */
+       { .dev = 0x3a, .num_clks = 1 },
+
+       /* i2c1 */
+       { .dev = 0x3b, .num_clks = 1 },
+
+       /* i2c2 */
+       { .dev = 0x3c, .num_clks = 1 },
+
+       /* edma0 */
+       { .dev = 0x3f, .num_clks = 2 },
+
+       /* semaphore0 */
+       { .dev = 0x40, .num_clks = 1 },
+
+       /* intc0 */
+       { .dev = 0x41, .num_clks = 1 },
+
+       /* gic0 */
+       { .dev = 0x42, .num_clks = 1 },
+
+       /* qspi0 */
+       { .dev = 0x43, .num_clks = 5 },
+
+       /* arm_64b_counter0 */
+       { .dev = 0x44, .num_clks = 2 },
+
+       /* tetris0 */
+       { .dev = 0x45, .num_clks = 2 },
+
+       /* cgem0 */
+       { .dev = 0x46, .num_clks = 2 },
+
+       /* msmc0 */
+       { .dev = 0x47, .num_clks = 1 },
+
+       /* cbass0 */
+       { .dev = 0x49, .num_clks = 1 },
+
+       /* board0 */
+       { .dev = 0x4c, .num_clks = 36 },
+
+       /* edma1 */
+       { .dev = 0x4f, .num_clks = 2 },
+       { .num_clks = 0 },
+};
+
+static const struct of_device_id ti_sci_clk_of_match[] = {
+       { .compatible = "ti,k2g-sci-clk", .data = &k2g_clk_data },
+       { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
+
+/**
+ * ti_sci_clk_probe - Probe function for the TI SCI clock driver
+ * @pdev: platform device pointer to be probed
+ *
+ * Probes the TI SCI clock device. Allocates a new clock provider
+ * and registers this to the common clock framework. Also applies
+ * any required flags to the identified clocks via clock lists
+ * supplied from DT. Returns 0 for success, negative error value
+ * for failure.
+ */
+static int ti_sci_clk_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct sci_clk_provider *provider;
+       const struct ti_sci_handle *handle;
+       const struct sci_clk_data *data;
+       int ret;
+
+       data = of_device_get_match_data(dev);
+       if (!data)
+               return -EINVAL;
+
+       handle = devm_ti_sci_get_handle(dev);
+       if (IS_ERR(handle))
+               return PTR_ERR(handle);
+
+       provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+       if (!provider)
+               return -ENOMEM;
+
+       provider->clk_data = data;
+
+       provider->sci = handle;
+       provider->ops = &handle->ops.clk_ops;
+       provider->dev = dev;
+
+       ret = ti_sci_init_clocks(provider);
+       if (ret) {
+               pr_err("ti-sci-init-clocks failed.\n");
+               return ret;
+       }
+
+       return of_clk_add_hw_provider(np, sci_clk_get, provider);
+}
+
+/**
+ * ti_sci_clk_remove - Remove TI SCI clock device
+ * @pdev: platform device pointer for the device to be removed
+ *
+ * Removes the TI SCI device. Unregisters the clock provider registered
+ * via common clock framework. Any memory allocated for the device will
+ * be free'd silently via the devm framework. Returns 0 always.
+ */
+static int ti_sci_clk_remove(struct platform_device *pdev)
+{
+       of_clk_del_provider(pdev->dev.of_node);
+
+       return 0;
+}
+
+static struct platform_driver ti_sci_clk_driver = {
+       .probe = ti_sci_clk_probe,
+       .remove = ti_sci_clk_remove,
+       .driver = {
+               .name = "ti-sci-clk",
+               .of_match_table = of_match_ptr(ti_sci_clk_of_match),
+       },
+};
+module_platform_driver(ti_sci_clk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
+MODULE_AUTHOR("Tero Kristo");
+MODULE_ALIAS("platform:ti-sci-clk");
index 5c3afb86b9ec6a0f29f443a9bf309f45aadee4b5..2a755b5fb51b96a96561ec5f72519524dbf9476a 100644 (file)
@@ -1,4 +1,4 @@
-obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
+obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
 obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
new file mode 100644 (file)
index 0000000..edd8e69
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015 Linaro Ltd.
+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+#include "clk-cpumux.h"
+
+static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw)
+{
+       return container_of(_hw, struct mtk_clk_cpumux, hw);
+}
+
+static u8 clk_cpumux_get_parent(struct clk_hw *hw)
+{
+       struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw);
+       int num_parents = clk_hw_get_num_parents(hw);
+       unsigned int val;
+
+       regmap_read(mux->regmap, mux->reg, &val);
+
+       val >>= mux->shift;
+       val &= mux->mask;
+
+       if (val >= num_parents)
+               return -EINVAL;
+
+       return val;
+}
+
+static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw);
+       u32 mask, val;
+
+       val = index << mux->shift;
+       mask = mux->mask << mux->shift;
+
+       return regmap_update_bits(mux->regmap, mux->reg, mask, val);
+}
+
+static const struct clk_ops clk_cpumux_ops = {
+       .get_parent = clk_cpumux_get_parent,
+       .set_parent = clk_cpumux_set_parent,
+};
+
+static struct clk __init *
+mtk_clk_register_cpumux(const struct mtk_composite *mux,
+                       struct regmap *regmap)
+{
+       struct mtk_clk_cpumux *cpumux;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
+       if (!cpumux)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = mux->name;
+       init.ops = &clk_cpumux_ops;
+       init.parent_names = mux->parent_names;
+       init.num_parents = mux->num_parents;
+       init.flags = mux->flags;
+
+       cpumux->reg = mux->mux_reg;
+       cpumux->shift = mux->mux_shift;
+       cpumux->mask = BIT(mux->mux_width) - 1;
+       cpumux->regmap = regmap;
+       cpumux->hw.init = &init;
+
+       clk = clk_register(NULL, &cpumux->hw);
+       if (IS_ERR(clk))
+               kfree(cpumux);
+
+       return clk;
+}
+
+int __init mtk_clk_register_cpumuxes(struct device_node *node,
+                                    const struct mtk_composite *clks, int num,
+                                    struct clk_onecell_data *clk_data)
+{
+       int i;
+       struct clk *clk;
+       struct regmap *regmap;
+
+       regmap = syscon_node_to_regmap(node);
+       if (IS_ERR(regmap)) {
+               pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
+                      PTR_ERR(regmap));
+               return PTR_ERR(regmap);
+       }
+
+       for (i = 0; i < num; i++) {
+               const struct mtk_composite *mux = &clks[i];
+
+               clk = mtk_clk_register_cpumux(mux, regmap);
+               if (IS_ERR(clk)) {
+                       pr_err("Failed to register clk %s: %ld\n",
+                              mux->name, PTR_ERR(clk));
+                       continue;
+               }
+
+               clk_data->clks[mux->id] = clk;
+       }
+
+       return 0;
+}
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
new file mode 100644 (file)
index 0000000..dddaad5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2015 Linaro Ltd.
+ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DRV_CLK_CPUMUX_H
+#define __DRV_CLK_CPUMUX_H
+
+struct mtk_clk_cpumux {
+       struct clk_hw   hw;
+       struct regmap   *regmap;
+       u32             reg;
+       u32             mask;
+       u8              shift;
+};
+
+int mtk_clk_register_cpumuxes(struct device_node *node,
+                             const struct mtk_composite *clks, int num,
+                             struct clk_onecell_data *clk_data);
+
+#endif /* __DRV_CLK_CPUMUX_H */
index 6f26e6a37a6b320b3c86c68856a51213f3173434..9598889f972b0dd7b163354861a508e8ad8e3ce0 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-cpumux.h"
 
 #include <dt-bindings/clock/mt2701-clk.h>
 
@@ -493,6 +494,10 @@ static const char * const cpu_parents[] = {
        "mmpll"
 };
 
+static const struct mtk_composite cpu_muxes[] __initconst = {
+       MUX(CLK_INFRA_CPUSEL, "infra_cpu_sel", cpu_parents, 0x0000, 2, 2),
+};
+
 static const struct mtk_composite top_muxes[] = {
        MUX_GATE_FLAGS(CLK_TOP_AXI_SEL, "axi_sel", axi_parents,
                0x0040, 0, 3, 7, CLK_IS_CRITICAL),
@@ -759,6 +764,9 @@ static void mtk_infrasys_init_early(struct device_node *node)
        mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
                                                infra_clk_data);
 
+       mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
+                                 infra_clk_data);
+
        r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
        if (r)
                pr_err("%s(): could not register clock provider: %d\n",
index 0ac3aee87726eb4ab9dbb083ce55e22a8e408266..96c292c3e440a3ca9ebf15039447209f58a01c61 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-cpumux.h"
 
 #include <dt-bindings/clock/mt8173-clk.h>
 
@@ -525,6 +526,25 @@ static const char * const i2s3_b_ck_parents[] __initconst = {
        "apll2_div5"
 };
 
+static const char * const ca53_parents[] __initconst = {
+       "clk26m",
+       "armca7pll",
+       "mainpll",
+       "univpll"
+};
+
+static const char * const ca57_parents[] __initconst = {
+       "clk26m",
+       "armca15pll",
+       "mainpll",
+       "univpll"
+};
+
+static const struct mtk_composite cpu_muxes[] __initconst = {
+       MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
+       MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
+};
+
 static const struct mtk_composite top_muxes[] __initconst = {
        /* CLK_CFG_0 */
        MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
@@ -948,6 +968,9 @@ static void __init mtk_infrasys_init(struct device_node *node)
                                                clk_data);
        mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
 
+       mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
+                                 clk_data);
+
        r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
        if (r)
                pr_err("%s(): could not register clock provider: %d\n",
index 2f29ee1a4d005422a087de38efc3b5274b8f7a04..5588f75a8414d5b7cefa9529cba44ec734d52b91 100644 (file)
@@ -7,9 +7,9 @@ config COMMON_CLK_MESON8B
        bool
        depends on COMMON_CLK_AMLOGIC
        help
-         Support for the clock controller on AmLogic S805 devices, aka
-         meson8b. Say Y if you want peripherals and CPU frequency scaling to
-         work.
+         Support for the clock controller on AmLogic S802 (Meson8),
+         S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
+         want peripherals and CPU frequency scaling to work.
 
 config COMMON_CLK_GXBB
        bool
index ad5f027af1a20cf1738adbdcb3a1496c793bf5ec..a897ea45327c985b189e9c5e81ac40028a682d7d 100644 (file)
@@ -278,20 +278,6 @@ static const struct pll_rate_table gxl_gp0_pll_rate_table[] = {
        { /* sentinel */ },
 };
 
-static const struct clk_div_table cpu_div_table[] = {
-       { .val = 1, .div = 1 },
-       { .val = 2, .div = 2 },
-       { .val = 3, .div = 3 },
-       { .val = 2, .div = 4 },
-       { .val = 3, .div = 6 },
-       { .val = 4, .div = 8 },
-       { .val = 5, .div = 10 },
-       { .val = 6, .div = 12 },
-       { .val = 7, .div = 14 },
-       { .val = 8, .div = 16 },
-       { /* sentinel */ },
-};
-
 static struct meson_clk_pll gxbb_fixed_pll = {
        .m = {
                .reg_off = HHI_MPLL_CNTL,
@@ -612,23 +598,16 @@ static struct meson_clk_mpll gxbb_mpll2 = {
 };
 
 /*
- * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
- * post-dividers and should be modeled with their respective PLLs via the
- * forthcoming coordinated clock rates feature
+ * FIXME The legacy composite clocks (e.g. clk81) are both PLL post-dividers
+ * and should be modeled with their respective PLLs via the forthcoming
+ * coordinated clock rates feature
  */
-static struct meson_clk_cpu gxbb_cpu_clk = {
-       .reg_off = HHI_SYS_CPU_CLK_CNTL1,
-       .div_table = cpu_div_table,
-       .clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
-       .hw.init = &(struct clk_init_data){
-               .name = "cpu_clk",
-               .ops = &meson_clk_cpu_ops,
-               .parent_names = (const char *[]){ "sys_pll" },
-               .num_parents = 1,
-       },
-};
 
-static u32 mux_table_clk81[]   = { 6, 5, 7 };
+static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
+static const char * const clk81_parent_names[] = {
+       "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
+       "fclk_div3", "fclk_div5"
+};
 
 static struct clk_mux gxbb_mpeg_clk_sel = {
        .reg = (void *)HHI_MPEG_CLK_CNTL,
@@ -641,13 +620,12 @@ static struct clk_mux gxbb_mpeg_clk_sel = {
                .name = "mpeg_clk_sel",
                .ops = &clk_mux_ro_ops,
                /*
-                * FIXME bits 14:12 selects from 8 possible parents:
+                * bits 14:12 selects from 8 possible parents:
                 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
-                       "fclk_div5" },
-               .num_parents = 3,
+               .parent_names = clk81_parent_names,
+               .num_parents = ARRAY_SIZE(clk81_parent_names),
                .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
        },
 };
@@ -676,7 +654,7 @@ static struct clk_gate gxbb_clk81 = {
                .ops = &clk_gate_ops,
                .parent_names = (const char *[]){ "mpeg_clk_div" },
                .num_parents = 1,
-               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL),
+               .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        },
 };
 
@@ -726,7 +704,7 @@ static struct clk_gate gxbb_sar_adc_clk = {
  */
 
 static u32 mux_table_mali_0_1[] = {0, 1, 2, 3, 4, 5, 6, 7};
-static const char *gxbb_mali_0_1_parent_names[] = {
+static const char * const gxbb_mali_0_1_parent_names[] = {
        "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7",
        "fclk_div4", "fclk_div3", "fclk_div5"
 };
@@ -826,7 +804,7 @@ static struct clk_gate gxbb_mali_1 = {
 };
 
 static u32 mux_table_mali[] = {0, 1};
-static const char *gxbb_mali_parent_names[] = {
+static const char * const gxbb_mali_parent_names[] = {
        "mali_0", "mali_1"
 };
 
@@ -951,6 +929,51 @@ static struct clk_mux gxbb_cts_i958 = {
        },
 };
 
+static struct clk_divider gxbb_32k_clk_div = {
+       .reg = (void *)HHI_32K_CLK_CNTL,
+       .shift = 0,
+       .width = 14,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "32k_clk_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "32k_clk_sel" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
+       },
+};
+
+static struct clk_gate gxbb_32k_clk = {
+       .reg = (void *)HHI_32K_CLK_CNTL,
+       .bit_idx = 15,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "32k_clk",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "32k_clk_div" },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const char * const gxbb_32k_clk_parent_names[] = {
+       "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5"
+};
+
+static struct clk_mux gxbb_32k_clk_sel = {
+       .reg = (void *)HHI_32K_CLK_CNTL,
+       .mask = 0x3,
+       .shift = 16,
+       .lock = &clk_lock,
+               .hw.init = &(struct clk_init_data){
+               .name = "32k_clk_sel",
+               .ops = &clk_mux_ops,
+               .parent_names = gxbb_32k_clk_parent_names,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
 static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
@@ -1045,7 +1068,6 @@ static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4);
 static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
        .hws = {
                [CLKID_SYS_PLL]             = &gxbb_sys_pll.hw,
-               [CLKID_CPUCLK]              = &gxbb_cpu_clk.hw,
                [CLKID_HDMI_PLL]            = &gxbb_hdmi_pll.hw,
                [CLKID_FIXED_PLL]           = &gxbb_fixed_pll.hw,
                [CLKID_FCLK_DIV2]           = &gxbb_fclk_div2.hw,
@@ -1158,6 +1180,9 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
                [CLKID_CTS_MCLK_I958_SEL]   = &gxbb_cts_mclk_i958_sel.hw,
                [CLKID_CTS_MCLK_I958_DIV]   = &gxbb_cts_mclk_i958_div.hw,
                [CLKID_CTS_I958]            = &gxbb_cts_i958.hw,
+               [CLKID_32K_CLK]             = &gxbb_32k_clk.hw,
+               [CLKID_32K_CLK_SEL]         = &gxbb_32k_clk_sel.hw,
+               [CLKID_32K_CLK_DIV]         = &gxbb_32k_clk_div.hw,
        },
        .num = NR_CLKS,
 };
@@ -1165,7 +1190,6 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
 static struct clk_hw_onecell_data gxl_hw_onecell_data = {
        .hws = {
                [CLKID_SYS_PLL]             = &gxbb_sys_pll.hw,
-               [CLKID_CPUCLK]              = &gxbb_cpu_clk.hw,
                [CLKID_HDMI_PLL]            = &gxbb_hdmi_pll.hw,
                [CLKID_FIXED_PLL]           = &gxbb_fixed_pll.hw,
                [CLKID_FCLK_DIV2]           = &gxbb_fclk_div2.hw,
@@ -1278,6 +1302,9 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
                [CLKID_CTS_MCLK_I958_SEL]   = &gxbb_cts_mclk_i958_sel.hw,
                [CLKID_CTS_MCLK_I958_DIV]   = &gxbb_cts_mclk_i958_div.hw,
                [CLKID_CTS_I958]            = &gxbb_cts_i958.hw,
+               [CLKID_32K_CLK]             = &gxbb_32k_clk.hw,
+               [CLKID_32K_CLK_SEL]         = &gxbb_32k_clk_sel.hw,
+               [CLKID_32K_CLK_DIV]         = &gxbb_32k_clk_div.hw,
        },
        .num = NR_CLKS,
 };
@@ -1392,6 +1419,7 @@ static struct clk_gate *const gxbb_clk_gates[] = {
        &gxbb_mali_1,
        &gxbb_cts_amclk,
        &gxbb_cts_mclk_i958,
+       &gxbb_32k_clk,
 };
 
 static struct clk_mux *const gxbb_clk_muxes[] = {
@@ -1403,6 +1431,7 @@ static struct clk_mux *const gxbb_clk_muxes[] = {
        &gxbb_cts_amclk_sel,
        &gxbb_cts_mclk_i958_sel,
        &gxbb_cts_i958,
+       &gxbb_32k_clk_sel,
 };
 
 static struct clk_divider *const gxbb_clk_dividers[] = {
@@ -1411,6 +1440,7 @@ static struct clk_divider *const gxbb_clk_dividers[] = {
        &gxbb_mali_0_div,
        &gxbb_mali_1_div,
        &gxbb_cts_mclk_i958_div,
+       &gxbb_32k_clk_div,
 };
 
 static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
@@ -1430,7 +1460,6 @@ struct clkc_data {
        unsigned int clk_dividers_count;
        struct meson_clk_audio_divider *const *clk_audio_dividers;
        unsigned int clk_audio_dividers_count;
-       struct meson_clk_cpu *cpu_clk;
        struct clk_hw_onecell_data *hw_onecell_data;
 };
 
@@ -1447,7 +1476,6 @@ static const struct clkc_data gxbb_clkc_data = {
        .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
        .clk_audio_dividers = gxbb_audio_dividers,
        .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
-       .cpu_clk = &gxbb_cpu_clk,
        .hw_onecell_data = &gxbb_hw_onecell_data,
 };
 
@@ -1464,7 +1492,6 @@ static const struct clkc_data gxl_clkc_data = {
        .clk_dividers_count = ARRAY_SIZE(gxbb_clk_dividers),
        .clk_audio_dividers = gxbb_audio_dividers,
        .clk_audio_dividers_count = ARRAY_SIZE(gxbb_audio_dividers),
-       .cpu_clk = &gxbb_cpu_clk,
        .hw_onecell_data = &gxl_hw_onecell_data,
 };
 
@@ -1479,8 +1506,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
        const struct clkc_data *clkc_data;
        void __iomem *clk_base;
        int ret, clkid, i;
-       struct clk_hw *parent_hw;
-       struct clk *parent_clk;
        struct device *dev = &pdev->dev;
 
        clkc_data = of_device_get_match_data(&pdev->dev);
@@ -1502,9 +1527,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
        for (i = 0; i < clkc_data->clk_mplls_count; i++)
                clkc_data->clk_mplls[i]->base = clk_base;
 
-       /* Populate the base address for CPU clk */
-       clkc_data->cpu_clk->base = clk_base;
-
        /* Populate base address for gates */
        for (i = 0; i < clkc_data->clk_gates_count; i++)
                clkc_data->clk_gates[i]->reg = clk_base +
@@ -1538,29 +1560,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
                        goto iounmap;
        }
 
-       /*
-        * Register CPU clk notifier
-        *
-        * FIXME this is wrong for a lot of reasons. First, the muxes should be
-        * struct clk_hw objects. Second, we shouldn't program the muxes in
-        * notifier handlers. The tricky programming sequence will be handled
-        * by the forthcoming coordinated clock rates mechanism once that
-        * feature is released.
-        *
-        * Furthermore, looking up the parent this way is terrible. At some
-        * point we will stop allocating a default struct clk when registering
-        * a new clk_hw, and this hack will no longer work. Releasing the ccr
-        * feature before that time solves the problem :-)
-        */
-       parent_hw = clk_hw_get_parent(&clkc_data->cpu_clk->hw);
-       parent_clk = parent_hw->clk;
-       ret = clk_notifier_register(parent_clk, &clkc_data->cpu_clk->clk_nb);
-       if (ret) {
-               pr_err("%s: failed to register clock notifier for cpu_clk\n",
-                               __func__);
-               goto iounmap;
-       }
-
        return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
                        clkc_data->hw_onecell_data);
 
index 4d04f4a3cd59cd399749607fe3a0268a10c9ce5b..d63e77e8433d1f73fbcf52ce0122b6350c0dd15d 100644 (file)
  * to be exposed to client nodes in DT: include/dt-bindings/clock/gxbb-clkc.h
  */
 #define CLKID_SYS_PLL            0
-#define CLKID_CPUCLK             1
+/* ID 1 is unused (it was used by the non-existing CLKID_CPUCLK before) */
 /* CLKID_HDMI_PLL */
 #define CLKID_FIXED_PLL                  3
 /* CLKID_FCLK_DIV2 */
 #define CLKID_CTS_MCLK_I958_SEL          111
 #define CLKID_CTS_MCLK_I958_DIV          112
 /* CLKID_CTS_I958 */
+#define CLKID_32K_CLK            114
+#define CLKID_32K_CLK_SEL        115
+#define CLKID_32K_CLK_DIV        116
 
-#define NR_CLKS                          114
+#define NR_CLKS                          117
 
 /* include the CLKIDs that have been made part of the stable DT binding */
 #include <dt-bindings/clock/gxbb-clkc.h>
index e9985503165ce87a1e1aabd179e49281ce22f145..bb3f1de876b1a8cd6bd5f191c6f2ff0737751aa7 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * AmLogic S805 / Meson8b Clock Controller Driver
+ * AmLogic S802 (Meson8) / S805 (Meson8b) / S812 (Meson8m2) Clock Controller
+ * Driver
  *
  * Copyright (c) 2015 Endless Mobile, Inc.
  * Author: Carlo Caione <carlo@endlessm.com>
@@ -399,7 +400,7 @@ struct clk_gate meson8b_clk81 = {
                .ops = &clk_gate_ops,
                .parent_names = (const char *[]){ "mpeg_clk_div" },
                .num_parents = 1,
-               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+               .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        },
 };
 
@@ -777,7 +778,9 @@ iounmap:
 }
 
 static const struct of_device_id meson8b_clkc_match_table[] = {
+       { .compatible = "amlogic,meson8-clkc" },
        { .compatible = "amlogic,meson8b-clkc" },
+       { .compatible = "amlogic,meson8m2-clkc" },
        { }
 };
 
index 8155baccc98e499204463241f18f20a6b53ff8ac..fa2fbd2cef4a343b50ccec04224c7dfc07dd6c52 100644 (file)
@@ -32,24 +32,38 @@ static struct clk_onecell_data ap806_clk_data = {
        .clk_num = AP806_CLK_NUM,
 };
 
-static int ap806_syscon_clk_probe(struct platform_device *pdev)
+static char *ap806_unique_name(struct device *dev, struct device_node *np,
+                              char *name)
+{
+       const __be32 *reg;
+       u64 addr;
+
+       reg = of_get_property(np, "reg", NULL);
+       addr = of_translate_address(np, reg);
+       return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
+                       (unsigned long long)addr, name);
+}
+
+static int ap806_syscon_common_probe(struct platform_device *pdev,
+                                    struct device_node *syscon_node)
 {
        unsigned int freq_mode, cpuclk_freq;
        const char *name, *fixedclk_name;
-       struct device_node *np = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
        struct regmap *regmap;
        u32 reg;
        int ret;
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = syscon_node_to_regmap(syscon_node);
        if (IS_ERR(regmap)) {
-               dev_err(&pdev->dev, "cannot get regmap\n");
+               dev_err(dev, "cannot get regmap\n");
                return PTR_ERR(regmap);
        }
 
        ret = regmap_read(regmap, AP806_SAR_REG, &reg);
        if (ret) {
-               dev_err(&pdev->dev, "cannot read from regmap\n");
+               dev_err(dev, "cannot read from regmap\n");
                return ret;
        }
 
@@ -89,7 +103,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
                cpuclk_freq = 600;
                break;
        default:
-               dev_err(&pdev->dev, "invalid SAR value\n");
+               dev_err(dev, "invalid SAR value\n");
                return -EINVAL;
        }
 
@@ -97,18 +111,16 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
        cpuclk_freq *= 1000 * 1000;
 
        /* CPU clocks depend on the Sample At Reset configuration */
-       of_property_read_string_index(np, "clock-output-names",
-                                     0, &name);
-       ap806_clks[0] = clk_register_fixed_rate(&pdev->dev, name, NULL,
+       name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0");
+       ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL,
                                                0, cpuclk_freq);
        if (IS_ERR(ap806_clks[0])) {
                ret = PTR_ERR(ap806_clks[0]);
                goto fail0;
        }
 
-       of_property_read_string_index(np, "clock-output-names",
-                                     1, &name);
-       ap806_clks[1] = clk_register_fixed_rate(&pdev->dev, name, NULL, 0,
+       name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1");
+       ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0,
                                                cpuclk_freq);
        if (IS_ERR(ap806_clks[1])) {
                ret = PTR_ERR(ap806_clks[1]);
@@ -116,9 +128,8 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
        }
 
        /* Fixed clock is always 1200 Mhz */
-       of_property_read_string_index(np, "clock-output-names",
-                                     2, &fixedclk_name);
-       ap806_clks[2] = clk_register_fixed_rate(&pdev->dev, fixedclk_name, NULL,
+       fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed");
+       ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL,
                                                0, 1200 * 1000 * 1000);
        if (IS_ERR(ap806_clks[2])) {
                ret = PTR_ERR(ap806_clks[2]);
@@ -126,8 +137,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
        }
 
        /* MSS Clock is fixed clock divided by 6 */
-       of_property_read_string_index(np, "clock-output-names",
-                                     3, &name);
+       name = ap806_unique_name(dev, syscon_node, "mss");
        ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name,
                                                  0, 1, 6);
        if (IS_ERR(ap806_clks[3])) {
@@ -135,20 +145,14 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
                goto fail3;
        }
 
-       /* eMMC Clock is fixed clock divided by 3 */
-       if (of_property_read_string_index(np, "clock-output-names",
-                                         4, &name)) {
-               ap806_clk_data.clk_num--;
-               dev_warn(&pdev->dev,
-                        "eMMC clock missing: update the device tree!\n");
-       } else {
-               ap806_clks[4] = clk_register_fixed_factor(NULL, name,
-                                                         fixedclk_name,
-                                                         0, 1, 3);
-               if (IS_ERR(ap806_clks[4])) {
-                       ret = PTR_ERR(ap806_clks[4]);
-                       goto fail4;
-               }
+       /* SDIO(/eMMC) Clock is fixed clock divided by 3 */
+       name = ap806_unique_name(dev, syscon_node, "sdio");
+       ap806_clks[4] = clk_register_fixed_factor(NULL, name,
+                                                 fixedclk_name,
+                                                 0, 1, 3);
+       if (IS_ERR(ap806_clks[4])) {
+               ret = PTR_ERR(ap806_clks[4]);
+               goto fail4;
        }
 
        of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data);
@@ -172,17 +176,48 @@ fail0:
        return ret;
 }
 
-static const struct of_device_id ap806_syscon_of_match[] = {
+static int ap806_syscon_legacy_probe(struct platform_device *pdev)
+{
+       dev_warn(&pdev->dev, FW_WARN "Using legacy device tree binding\n");
+       dev_warn(&pdev->dev, FW_WARN "Update your device tree:\n");
+       dev_warn(&pdev->dev, FW_WARN
+                "This binding won't be supported in future kernel\n");
+
+       return ap806_syscon_common_probe(pdev, pdev->dev.of_node);
+
+}
+
+static int ap806_clock_probe(struct platform_device *pdev)
+{
+       return ap806_syscon_common_probe(pdev, pdev->dev.of_node->parent);
+}
+
+static const struct of_device_id ap806_syscon_legacy_of_match[] = {
        { .compatible = "marvell,ap806-system-controller", },
        { }
 };
 
-static struct platform_driver ap806_syscon_driver = {
-       .probe = ap806_syscon_clk_probe,
+static struct platform_driver ap806_syscon_legacy_driver = {
+       .probe = ap806_syscon_legacy_probe,
        .driver         = {
                .name   = "marvell-ap806-system-controller",
-               .of_match_table = ap806_syscon_of_match,
+               .of_match_table = ap806_syscon_legacy_of_match,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(ap806_syscon_legacy_driver);
+
+static const struct of_device_id ap806_clock_of_match[] = {
+       { .compatible = "marvell,ap806-clock", },
+       { }
+};
+
+static struct platform_driver ap806_clock_driver = {
+       .probe = ap806_clock_probe,
+       .driver         = {
+               .name   = "marvell-ap806-clock",
+               .of_match_table = ap806_clock_of_match,
                .suppress_bind_attrs = true,
        },
 };
-builtin_platform_driver(ap806_syscon_driver);
+builtin_platform_driver(ap806_clock_driver);
index 8bccf4ecdab641bf0a24d2db15ccf419023d7357..394aa6f03f01ffee1ed370896dbc2946a06b17df 100644 (file)
@@ -49,7 +49,8 @@ static const u32 armada_38x_cpu_frequencies[] __initconst = {
        0, 0, 0, 0,
        1066 * 1000 * 1000, 0, 0, 0,
        1332 * 1000 * 1000, 0, 0, 0,
-       1600 * 1000 * 1000,
+       1600 * 1000 * 1000, 0, 0, 0,
+       1866 * 1000 * 1000,
 };
 
 static u32 __init armada_38x_get_cpu_freq(void __iomem *sar)
@@ -79,7 +80,7 @@ static const int armada_38x_cpu_l2_ratios[32][2] __initconst = {
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
-       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
@@ -90,7 +91,7 @@ static const int armada_38x_cpu_ddr_ratios[32][2] __initconst = {
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {1, 2}, {0, 1}, {0, 1}, {0, 1},
-       {0, 1}, {0, 1}, {0, 1}, {0, 1},
+       {1, 2}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
        {0, 1}, {0, 1}, {0, 1}, {0, 1},
index 6b11d7b3e0e090a9369ca264f08038c34cf8d0cd..ca9a0a53617471f3e92154a4657dee9ef88988e8 100644 (file)
  */
 
 /*
- * CP110 has 5 core clocks:
+ * CP110 has 6 core clocks:
  *
  *  - APLL             (1 Ghz)
  *    - PPv2 core      (1/3 APLL)
  *    - EIP            (1/2 APLL)
- *      - Core         (1/2 EIP)
+ *     - Core          (1/2 EIP)
+ *    - SDIO           (2/5 APLL)
  *
  *  - NAND clock, which is either:
- *    - Equal to the core clock
+ *    - Equal to SDIO clock
  *    - 2/5 APLL
  *
  * CP110 has 32 gatable clocks, for the various peripherals in the
@@ -46,7 +47,7 @@ enum {
        CP110_CLK_TYPE_GATABLE,
 };
 
-#define CP110_MAX_CORE_CLOCKS          5
+#define CP110_MAX_CORE_CLOCKS          6
 #define CP110_MAX_GATABLE_CLOCKS       32
 
 #define CP110_CLK_NUM \
@@ -57,6 +58,7 @@ enum {
 #define CP110_CORE_EIP                 2
 #define CP110_CORE_CORE                        3
 #define CP110_CORE_NAND                        4
+#define CP110_CORE_SDIO                        5
 
 /* A number of gatable clocks need special handling */
 #define CP110_GATE_AUDIO               0
@@ -84,6 +86,33 @@ enum {
 #define CP110_GATE_EIP150              25
 #define CP110_GATE_EIP197              26
 
+static const char * const gate_base_names[] = {
+       [CP110_GATE_AUDIO]      = "audio",
+       [CP110_GATE_COMM_UNIT]  = "communit",
+       [CP110_GATE_NAND]       = "nand",
+       [CP110_GATE_PPV2]       = "ppv2",
+       [CP110_GATE_SDIO]       = "sdio",
+       [CP110_GATE_MG]         = "mg-domain",
+       [CP110_GATE_MG_CORE]    = "mg-core",
+       [CP110_GATE_XOR1]       = "xor1",
+       [CP110_GATE_XOR0]       = "xor0",
+       [CP110_GATE_GOP_DP]     = "gop-dp",
+       [CP110_GATE_PCIE_X1_0]  = "pcie_x10",
+       [CP110_GATE_PCIE_X1_1]  = "pcie_x11",
+       [CP110_GATE_PCIE_X4]    = "pcie_x4",
+       [CP110_GATE_PCIE_XOR]   = "pcie-xor",
+       [CP110_GATE_SATA]       = "sata",
+       [CP110_GATE_SATA_USB]   = "sata-usb",
+       [CP110_GATE_MAIN]       = "main",
+       [CP110_GATE_SDMMC_GOP]  = "sd-mmc-gop",
+       [CP110_GATE_SLOW_IO]    = "slow-io",
+       [CP110_GATE_USB3H0]     = "usb3h0",
+       [CP110_GATE_USB3H1]     = "usb3h1",
+       [CP110_GATE_USB3DEV]    = "usb3dev",
+       [CP110_GATE_EIP150]     = "eip150",
+       [CP110_GATE_EIP197]     = "eip197"
+};
+
 struct cp110_gate_clk {
        struct clk_hw hw;
        struct regmap *regmap;
@@ -186,17 +215,37 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
        return ERR_PTR(-EINVAL);
 }
 
-static int cp110_syscon_clk_probe(struct platform_device *pdev)
+static char *cp110_unique_name(struct device *dev, struct device_node *np,
+                              const char *name)
+{
+       const __be32 *reg;
+       u64 addr;
+
+       /* Do not create a name if there is no clock */
+       if (!name)
+               return NULL;
+
+       reg = of_get_property(np, "reg", NULL);
+       addr = of_translate_address(np, reg);
+       return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
+                             (unsigned long long)addr, name);
+}
+
+static int cp110_syscon_common_probe(struct platform_device *pdev,
+                                    struct device_node *syscon_node)
 {
        struct regmap *regmap;
-       struct device_node *np = pdev->dev.of_node;
-       const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name,
+               *sdio_name;
        struct clk_hw_onecell_data *cp110_clk_data;
        struct clk_hw *hw, **cp110_clks;
        u32 nand_clk_ctrl;
        int i, ret;
+       char *gate_name[ARRAY_SIZE(gate_base_names)];
 
-       regmap = syscon_node_to_regmap(np);
+       regmap = syscon_node_to_regmap(syscon_node);
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
@@ -205,7 +254,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       cp110_clk_data = devm_kzalloc(&pdev->dev, sizeof(*cp110_clk_data) +
+       cp110_clk_data = devm_kzalloc(dev, sizeof(*cp110_clk_data) +
                                      sizeof(struct clk_hw *) * CP110_CLK_NUM,
                                      GFP_KERNEL);
        if (!cp110_clk_data)
@@ -215,53 +264,47 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
        cp110_clk_data->num = CP110_CLK_NUM;
 
        /* Register the APLL which is the root of the hw tree */
-       of_property_read_string_index(np, "core-clock-output-names",
-                                     CP110_CORE_APLL, &apll_name);
+       apll_name = cp110_unique_name(dev, syscon_node, "apll");
        hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0,
                                        1000 * 1000 * 1000);
        if (IS_ERR(hw)) {
                ret = PTR_ERR(hw);
-               goto fail0;
+               goto fail_apll;
        }
 
        cp110_clks[CP110_CORE_APLL] = hw;
 
        /* PPv2 is APLL/3 */
-       of_property_read_string_index(np, "core-clock-output-names",
-                                     CP110_CORE_PPV2, &ppv2_name);
+       ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core");
        hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
        if (IS_ERR(hw)) {
                ret = PTR_ERR(hw);
-               goto fail1;
+               goto fail_ppv2;
        }
 
        cp110_clks[CP110_CORE_PPV2] = hw;
 
        /* EIP clock is APLL/2 */
-       of_property_read_string_index(np, "core-clock-output-names",
-                                     CP110_CORE_EIP, &eip_name);
+       eip_name = cp110_unique_name(dev, syscon_node, "eip");
        hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
        if (IS_ERR(hw)) {
                ret = PTR_ERR(hw);
-               goto fail2;
+               goto fail_eip;
        }
 
        cp110_clks[CP110_CORE_EIP] = hw;
 
        /* Core clock is EIP/2 */
-       of_property_read_string_index(np, "core-clock-output-names",
-                                     CP110_CORE_CORE, &core_name);
+       core_name = cp110_unique_name(dev, syscon_node, "core");
        hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
        if (IS_ERR(hw)) {
                ret = PTR_ERR(hw);
-               goto fail3;
+               goto fail_core;
        }
 
        cp110_clks[CP110_CORE_CORE] = hw;
-
        /* NAND can be either APLL/2.5 or core clock */
-       of_property_read_string_index(np, "core-clock-output-names",
-                                     CP110_CORE_NAND, &nand_name);
+       nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
        if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
                hw = clk_hw_register_fixed_factor(NULL, nand_name,
                                                   apll_name, 0, 2, 5);
@@ -270,23 +313,31 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
                                                   core_name, 0, 1, 1);
        if (IS_ERR(hw)) {
                ret = PTR_ERR(hw);
-               goto fail4;
+               goto fail_nand;
        }
 
        cp110_clks[CP110_CORE_NAND] = hw;
 
-       for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) {
-               const char *parent, *name;
-               int ret;
-
-               ret = of_property_read_string_index(np,
-                                                   "gate-clock-output-names",
-                                                   i, &name);
-               /* Reached the end of the list? */
-               if (ret < 0)
-                       break;
+       /* SDIO clock is APLL/2.5 */
+       sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core");
+       hw = clk_hw_register_fixed_factor(NULL, sdio_name,
+                                         apll_name, 0, 2, 5);
+       if (IS_ERR(hw)) {
+               ret = PTR_ERR(hw);
+               goto fail_sdio;
+       }
+
+       cp110_clks[CP110_CORE_SDIO] = hw;
+
+       /* create the unique name for all the gate clocks */
+       for (i = 0; i < ARRAY_SIZE(gate_base_names); i++)
+               gate_name[i] =  cp110_unique_name(dev, syscon_node,
+                                                 gate_base_names[i]);
+
+       for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) {
+               const char *parent;
 
-               if (!strcmp(name, "none"))
+               if (gate_name[i] == NULL)
                        continue;
 
                switch (i) {
@@ -295,14 +346,10 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
                case CP110_GATE_EIP150:
                case CP110_GATE_EIP197:
                case CP110_GATE_SLOW_IO:
-                       of_property_read_string_index(np,
-                                                     "gate-clock-output-names",
-                                                     CP110_GATE_MAIN, &parent);
+                       parent = gate_name[CP110_GATE_MAIN];
                        break;
                case CP110_GATE_MG:
-                       of_property_read_string_index(np,
-                                                     "gate-clock-output-names",
-                                                     CP110_GATE_MG_CORE, &parent);
+                       parent = gate_name[CP110_GATE_MG_CORE];
                        break;
                case CP110_GATE_NAND:
                        parent = nand_name;
@@ -311,34 +358,30 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
                        parent = ppv2_name;
                        break;
                case CP110_GATE_SDIO:
+                       parent = sdio_name;
+                       break;
                case CP110_GATE_GOP_DP:
-                       of_property_read_string_index(np,
-                                                     "gate-clock-output-names",
-                                                     CP110_GATE_SDMMC_GOP, &parent);
+                       parent = gate_name[CP110_GATE_SDMMC_GOP];
                        break;
                case CP110_GATE_XOR1:
                case CP110_GATE_XOR0:
                case CP110_GATE_PCIE_X1_0:
                case CP110_GATE_PCIE_X1_1:
                case CP110_GATE_PCIE_X4:
-                       of_property_read_string_index(np,
-                                                     "gate-clock-output-names",
-                                                     CP110_GATE_PCIE_XOR, &parent);
+                       parent = gate_name[CP110_GATE_PCIE_XOR];
                        break;
                case CP110_GATE_SATA:
                case CP110_GATE_USB3H0:
                case CP110_GATE_USB3H1:
                case CP110_GATE_USB3DEV:
-                       of_property_read_string_index(np,
-                                                     "gate-clock-output-names",
-                                                     CP110_GATE_SATA_USB, &parent);
+                       parent = gate_name[CP110_GATE_SATA_USB];
                        break;
                default:
                        parent = core_name;
                        break;
                }
+               hw = cp110_register_gate(gate_name[i], parent, regmap, i);
 
-               hw = cp110_register_gate(name, parent, regmap, i);
                if (IS_ERR(hw)) {
                        ret = PTR_ERR(hw);
                        goto fail_gate;
@@ -364,30 +407,62 @@ fail_gate:
                        cp110_unregister_gate(hw);
        }
 
+       clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_SDIO]);
+fail_sdio:
        clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]);
-fail4:
+fail_nand:
        clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]);
-fail3:
+fail_core:
        clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]);
-fail2:
+fail_eip:
        clk_hw_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]);
-fail1:
+fail_ppv2:
        clk_hw_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]);
-fail0:
+fail_apll:
        return ret;
 }
 
-static const struct of_device_id cp110_syscon_of_match[] = {
+static int cp110_syscon_legacy_clk_probe(struct platform_device *pdev)
+{
+       dev_warn(&pdev->dev, FW_WARN "Using legacy device tree binding\n");
+       dev_warn(&pdev->dev, FW_WARN "Update your device tree:\n");
+       dev_warn(&pdev->dev, FW_WARN
+                "This binding won't be supported in future kernels\n");
+
+       return cp110_syscon_common_probe(pdev, pdev->dev.of_node);
+}
+
+static int cp110_clk_probe(struct platform_device *pdev)
+{
+       return cp110_syscon_common_probe(pdev, pdev->dev.of_node->parent);
+}
+
+static const struct of_device_id cp110_syscon_legacy_of_match[] = {
        { .compatible = "marvell,cp110-system-controller0", },
        { }
 };
 
-static struct platform_driver cp110_syscon_driver = {
-       .probe = cp110_syscon_clk_probe,
+static struct platform_driver cp110_syscon_legacy_driver = {
+       .probe = cp110_syscon_legacy_clk_probe,
        .driver         = {
                .name   = "marvell-cp110-system-controller0",
-               .of_match_table = cp110_syscon_of_match,
+               .of_match_table = cp110_syscon_legacy_of_match,
+               .suppress_bind_attrs = true,
+       },
+};
+builtin_platform_driver(cp110_syscon_legacy_driver);
+
+static const struct of_device_id cp110_clock_of_match[] = {
+       { .compatible = "marvell,cp110-clock", },
+       { }
+};
+
+static struct platform_driver cp110_clock_driver = {
+       .probe = cp110_clk_probe,
+       .driver         = {
+               .name   = "marvell-cp110-clock",
+               .of_match_table = cp110_clock_of_match,
                .suppress_bind_attrs = true,
        },
 };
-builtin_platform_driver(cp110_syscon_driver);
+builtin_platform_driver(cp110_clock_driver);
index 5fb8d7430908414effcf6842e7ac7db042bddc81..9f6c278deead0b7437ca3bfd6c073bc948f7e3d5 100644 (file)
@@ -82,6 +82,15 @@ config IPQ_LCC_806X
          Say Y if you want to use audio devices such as i2s, pcm,
          S/PDIF, etc.
 
+config IPQ_GCC_8074
+       tristate "IPQ8074 Global Clock Controller"
+       depends on COMMON_CLK_QCOM
+       help
+         Support for global clock controller on ipq8074 devices.
+         Say Y if you want to use peripheral devices such as UART, SPI,
+         i2c, USB, SD/eMMC, etc. Select this for the root clock
+         of ipq8074.
+
 config MSM_GCC_8660
        tristate "MSM8660 Global Clock Controller"
        depends on COMMON_CLK_QCOM
index 1c3e222b917be0695b562a15b797e2bdff9006fe..3f3aff229fb785a8935b4d59013b0a5d583d1459 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
 obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
+obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
 obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
 obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
 obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
diff --git a/drivers/clk/qcom/gcc-ipq8074.c b/drivers/clk/qcom/gcc-ipq8074.c
new file mode 100644 (file)
index 0000000..0f735d3
--- /dev/null
@@ -0,0 +1,1007 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gcc-ipq8074.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#include "reset.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+       P_XO,
+       P_GPLL0,
+       P_GPLL0_DIV2,
+};
+
+static const char * const gcc_xo_gpll0_gpll0_out_main_div2[] = {
+       "xo",
+       "gpll0",
+       "gpll0_out_main_div2",
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_alpha_pll gpll0_main = {
+       .offset = 0x21000,
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_main",
+                       .parent_names = (const char *[]){
+                               "xo"
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll0_out_main_div2 = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_main_div2",
+               .parent_names = (const char *[]){
+                       "gpll0_main"
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+       .offset = 0x21000,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+               .parent_names = (const char *[]){
+                       "gpll0_main"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x27000,
+       .freq_tbl = ftbl_pcnoc_bfdcd_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcnoc_bfdcd_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_IS_CRITICAL,
+       },
+};
+
+static struct clk_fixed_factor pcnoc_clk_src = {
+       .mult = 1,
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "pcnoc_clk_src",
+               .parent_names = (const char *[]){
+                       "pcnoc_bfdcd_clk_src"
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_branch gcc_sleep_clk_src = {
+       .halt_reg = 0x30000,
+       .clkr = {
+               .enable_reg = 0x30000,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sleep_clk_src",
+                       .parent_names = (const char *[]){
+                               "sleep_clk"
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup_i2c_apps_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0200c,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 1, 2),
+       F(4800000, P_XO, 4, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(12500000, P_GPLL0_DIV2, 16, 1, 2),
+       F(16000000, P_GPLL0, 10, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x02024,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x03000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x03014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x04000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x04014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x05000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x05014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x06000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+       .cmd_rcgr = 0x06014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x07000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_i2c_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+       .cmd_rcgr = 0x07014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_spi_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_uart_apps_clk_src[] = {
+       F(3686400, P_GPLL0_DIV2, 1, 144, 15625),
+       F(7372800, P_GPLL0_DIV2, 1, 288, 15625),
+       F(14745600, P_GPLL0_DIV2, 1, 576, 15625),
+       F(16000000, P_GPLL0_DIV2, 5, 1, 5),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0, 1, 3, 100),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(32000000, P_GPLL0, 1, 1, 25),
+       F(40000000, P_GPLL0, 1, 1, 20),
+       F(46400000, P_GPLL0, 1, 29, 500),
+       F(48000000, P_GPLL0, 1, 3, 50),
+       F(51200000, P_GPLL0, 1, 8, 125),
+       F(56000000, P_GPLL0, 1, 7, 100),
+       F(58982400, P_GPLL0, 1, 1152, 15625),
+       F(60000000, P_GPLL0, 1, 3, 40),
+       F(64000000, P_GPLL0, 12.5, 1, 1),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x02044,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x03034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+       .cmd_rcgr = 0x04034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart3_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart4_apps_clk_src = {
+       .cmd_rcgr = 0x05034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart4_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
+       .cmd_rcgr = 0x06034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart5_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
+       .cmd_rcgr = 0x07034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart6_apps_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x01008,
+       .clkr = {
+               .enable_reg = 0x01008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "pcnoc_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x02008,
+       .clkr = {
+               .enable_reg = 0x02008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup1_i2c_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x02004,
+       .clkr = {
+               .enable_reg = 0x02004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup1_spi_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x03010,
+       .clkr = {
+               .enable_reg = 0x03010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup2_i2c_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x0300c,
+       .clkr = {
+               .enable_reg = 0x0300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup2_spi_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x04010,
+       .clkr = {
+               .enable_reg = 0x04010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup3_i2c_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x0400c,
+       .clkr = {
+               .enable_reg = 0x0400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup3_spi_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x05010,
+       .clkr = {
+               .enable_reg = 0x05010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup4_i2c_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x0500c,
+       .clkr = {
+               .enable_reg = 0x0500c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup4_spi_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+       .halt_reg = 0x06010,
+       .clkr = {
+               .enable_reg = 0x06010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup5_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup5_i2c_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+       .halt_reg = 0x0600c,
+       .clkr = {
+               .enable_reg = 0x0600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup5_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup5_spi_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
+       .halt_reg = 0x07010,
+       .clkr = {
+               .enable_reg = 0x07010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup6_i2c_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup6_i2c_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+       .halt_reg = 0x0700c,
+       .clkr = {
+               .enable_reg = 0x0700c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup6_spi_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_qup6_spi_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x0203c,
+       .clkr = {
+               .enable_reg = 0x0203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart1_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x0302c,
+       .clkr = {
+               .enable_reg = 0x0302c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart2_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+       .halt_reg = 0x0402c,
+       .clkr = {
+               .enable_reg = 0x0402c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart3_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart3_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart4_apps_clk = {
+       .halt_reg = 0x0502c,
+       .clkr = {
+               .enable_reg = 0x0502c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart4_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart4_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart5_apps_clk = {
+       .halt_reg = 0x0602c,
+       .clkr = {
+               .enable_reg = 0x0602c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart5_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart5_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart6_apps_clk = {
+       .halt_reg = 0x0702c,
+       .clkr = {
+               .enable_reg = 0x0702c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart6_apps_clk",
+                       .parent_names = (const char *[]){
+                               "blsp1_uart6_apps_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x13004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "pcnoc_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qpic_ahb_clk = {
+       .halt_reg = 0x57024,
+       .clkr = {
+               .enable_reg = 0x57024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qpic_ahb_clk",
+                       .parent_names = (const char *[]){
+                               "pcnoc_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qpic_clk = {
+       .halt_reg = 0x57020,
+       .clkr = {
+               .enable_reg = 0x57020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qpic_clk",
+                       .parent_names = (const char *[]){
+                               "pcnoc_clk_src"
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_hw *gcc_ipq8074_hws[] = {
+       &gpll0_out_main_div2.hw,
+       &pcnoc_clk_src.hw,
+};
+
+static struct clk_regmap *gcc_ipq8074_clks[] = {
+       [GPLL0_MAIN] = &gpll0_main.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
+       [GCC_SLEEP_CLK_SRC] = &gcc_sleep_clk_src.clkr,
+       [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
+       [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
+       [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr,
+       [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr,
+       [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr,
+       [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr,
+       [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr,
+       [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr,
+       [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
+       [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_ipq8074_resets[] = {
+       [GCC_BLSP1_BCR] = { 0x01000, 0 },
+       [GCC_BLSP1_QUP1_BCR] = { 0x02000, 0 },
+       [GCC_BLSP1_UART1_BCR] = { 0x02038, 0 },
+       [GCC_BLSP1_QUP2_BCR] = { 0x03008, 0 },
+       [GCC_BLSP1_UART2_BCR] = { 0x03028, 0 },
+       [GCC_BLSP1_QUP3_BCR] = { 0x04008, 0 },
+       [GCC_BLSP1_UART3_BCR] = { 0x04028, 0 },
+       [GCC_BLSP1_QUP4_BCR] = { 0x05008, 0 },
+       [GCC_BLSP1_UART4_BCR] = { 0x05028, 0 },
+       [GCC_BLSP1_QUP5_BCR] = { 0x06008, 0 },
+       [GCC_BLSP1_UART5_BCR] = { 0x06028, 0 },
+       [GCC_BLSP1_QUP6_BCR] = { 0x07008, 0 },
+       [GCC_BLSP1_UART6_BCR] = { 0x07028, 0 },
+       [GCC_IMEM_BCR] = { 0x0e000, 0 },
+       [GCC_SMMU_BCR] = { 0x12000, 0 },
+       [GCC_APSS_TCU_BCR] = { 0x12050, 0 },
+       [GCC_SMMU_XPU_BCR] = { 0x12054, 0 },
+       [GCC_PCNOC_TBU_BCR] = { 0x12058, 0 },
+       [GCC_SMMU_CFG_BCR] = { 0x1208c, 0 },
+       [GCC_PRNG_BCR] = { 0x13000, 0 },
+       [GCC_BOOT_ROM_BCR] = { 0x13008, 0 },
+       [GCC_CRYPTO_BCR] = { 0x16000, 0 },
+       [GCC_WCSS_BCR] = { 0x18000, 0 },
+       [GCC_WCSS_Q6_BCR] = { 0x18100, 0 },
+       [GCC_NSS_BCR] = { 0x19000, 0 },
+       [GCC_SEC_CTRL_BCR] = { 0x1a000, 0 },
+       [GCC_ADSS_BCR] = { 0x1c000, 0 },
+       [GCC_DDRSS_BCR] = { 0x1e000, 0 },
+       [GCC_SYSTEM_NOC_BCR] = { 0x26000, 0 },
+       [GCC_PCNOC_BCR] = { 0x27018, 0 },
+       [GCC_TCSR_BCR] = { 0x28000, 0 },
+       [GCC_QDSS_BCR] = { 0x29000, 0 },
+       [GCC_DCD_BCR] = { 0x2a000, 0 },
+       [GCC_MSG_RAM_BCR] = { 0x2b000, 0 },
+       [GCC_MPM_BCR] = { 0x2c000, 0 },
+       [GCC_SPMI_BCR] = { 0x2e000, 0 },
+       [GCC_SPDM_BCR] = { 0x2f000, 0 },
+       [GCC_RBCPR_BCR] = { 0x33000, 0 },
+       [GCC_RBCPR_MX_BCR] = { 0x33014, 0 },
+       [GCC_TLMM_BCR] = { 0x34000, 0 },
+       [GCC_RBCPR_WCSS_BCR] = { 0x3a000, 0 },
+       [GCC_USB0_PHY_BCR] = { 0x3e034, 0 },
+       [GCC_USB3PHY_0_PHY_BCR] = { 0x3e03c, 0 },
+       [GCC_USB0_BCR] = { 0x3e070, 0 },
+       [GCC_USB1_PHY_BCR] = { 0x3f034, 0 },
+       [GCC_USB3PHY_1_PHY_BCR] = { 0x3f03c, 0 },
+       [GCC_USB1_BCR] = { 0x3f070, 0 },
+       [GCC_QUSB2_0_PHY_BCR] = { 0x4103c, 0 },
+       [GCC_QUSB2_1_PHY_BCR] = { 0x41040, 0 },
+       [GCC_SDCC1_BCR] = { 0x42000, 0 },
+       [GCC_SDCC2_BCR] = { 0x43000, 0 },
+       [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x47000, 0 },
+       [GCC_SNOC_BUS_TIMEOUT2_BCR] = { 0x47008, 0 },
+       [GCC_SNOC_BUS_TIMEOUT3_BCR] = { 0x47010, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT0_BCR] = { 0x48000, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT1_BCR] = { 0x48008, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT2_BCR] = { 0x48010, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT3_BCR] = { 0x48018, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT4_BCR] = { 0x48020, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT5_BCR] = { 0x48028, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT6_BCR] = { 0x48030, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT7_BCR] = { 0x48038, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT8_BCR] = { 0x48040, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT9_BCR] = { 0x48048, 0 },
+       [GCC_UNIPHY0_BCR] = { 0x56000, 0 },
+       [GCC_UNIPHY1_BCR] = { 0x56100, 0 },
+       [GCC_UNIPHY2_BCR] = { 0x56200, 0 },
+       [GCC_CMN_12GPLL_BCR] = { 0x56300, 0 },
+       [GCC_QPIC_BCR] = { 0x57018, 0 },
+       [GCC_MDIO_BCR] = { 0x58000, 0 },
+       [GCC_PCIE1_TBU_BCR] = { 0x65000, 0 },
+       [GCC_WCSS_CORE_TBU_BCR] = { 0x66000, 0 },
+       [GCC_WCSS_Q6_TBU_BCR] = { 0x67000, 0 },
+       [GCC_USB0_TBU_BCR] = { 0x6a000, 0 },
+       [GCC_USB1_TBU_BCR] = { 0x6a004, 0 },
+       [GCC_PCIE0_TBU_BCR] = { 0x6b000, 0 },
+       [GCC_NSS_NOC_TBU_BCR] = { 0x6e000, 0 },
+       [GCC_PCIE0_BCR] = { 0x75004, 0 },
+       [GCC_PCIE0_PHY_BCR] = { 0x75038, 0 },
+       [GCC_PCIE0PHY_PHY_BCR] = { 0x7503c, 0 },
+       [GCC_PCIE0_LINK_DOWN_BCR] = { 0x75044, 0 },
+       [GCC_PCIE1_BCR] = { 0x76004, 0 },
+       [GCC_PCIE1_PHY_BCR] = { 0x76038, 0 },
+       [GCC_PCIE1PHY_PHY_BCR] = { 0x7603c, 0 },
+       [GCC_PCIE1_LINK_DOWN_BCR] = { 0x76044, 0 },
+       [GCC_DCC_BCR] = { 0x77000, 0 },
+       [GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR] = { 0x78000, 0 },
+       [GCC_APC1_VOLTAGE_DROOP_DETECTOR_BCR] = { 0x79000, 0 },
+       [GCC_SMMU_CATS_BCR] = { 0x7c000, 0 },
+};
+
+static const struct of_device_id gcc_ipq8074_match_table[] = {
+       { .compatible = "qcom,gcc-ipq8074" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_ipq8074_match_table);
+
+static const struct regmap_config gcc_ipq8074_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x7fffc,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_ipq8074_desc = {
+       .config = &gcc_ipq8074_regmap_config,
+       .clks = gcc_ipq8074_clks,
+       .num_clks = ARRAY_SIZE(gcc_ipq8074_clks),
+       .resets = gcc_ipq8074_resets,
+       .num_resets = ARRAY_SIZE(gcc_ipq8074_resets),
+};
+
+static int gcc_ipq8074_probe(struct platform_device *pdev)
+{
+       int ret, i;
+
+       for (i = 0; i < ARRAY_SIZE(gcc_ipq8074_hws); i++) {
+               ret = devm_clk_hw_register(&pdev->dev, gcc_ipq8074_hws[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return qcom_cc_probe(pdev, &gcc_ipq8074_desc);
+}
+
+static struct platform_driver gcc_ipq8074_driver = {
+       .probe = gcc_ipq8074_probe,
+       .driver = {
+               .name   = "qcom,gcc-ipq8074",
+               .of_match_table = gcc_ipq8074_match_table,
+       },
+};
+
+static int __init gcc_ipq8074_init(void)
+{
+       return platform_driver_register(&gcc_ipq8074_driver);
+}
+core_initcall(gcc_ipq8074_init);
+
+static void __exit gcc_ipq8074_exit(void)
+{
+       platform_driver_unregister(&gcc_ipq8074_driver);
+}
+module_exit(gcc_ipq8074_exit);
+
+MODULE_DESCRIPTION("QCOM GCC IPQ8074 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gcc-ipq8074");
index 628e6ca276ec827c865b0d53dfa9281cc57db43c..2cfe7000fc60465028bc55567dedbfd540d0729e 100644 (file)
@@ -1430,6 +1430,7 @@ static struct clk_branch gcc_ultaudio_stc_xo_clk = {
 };
 
 static const struct freq_tbl ftbl_codec_clk[] = {
+       F(9600000, P_XO, 2, 0, 0),
        F(19200000, P_XO, 1, 0, 0),
        F(11289600, P_EXT_MCLK, 1, 0, 0),
        { }
index 2586dfa0026bb015a1a0e81d3b60a1eff7e5a785..78d1df9112ba3932fe993c5f9700f00bb830a786 100644 (file)
+config CLK_RENESAS
+       bool "Renesas SoC clock support" if COMPILE_TEST && !ARCH_RENESAS
+       default y if ARCH_RENESAS
+       select CLK_EMEV2 if ARCH_EMEV2
+       select CLK_RZA1 if ARCH_R7S72100
+       select CLK_R8A73A4 if ARCH_R8A73A4
+       select CLK_R8A7740 if ARCH_R8A7740
+       select CLK_R8A7743 if ARCH_R8A7743
+       select CLK_R8A7745 if ARCH_R8A7745
+       select CLK_R8A7778 if ARCH_R8A7778
+       select CLK_R8A7779 if ARCH_R8A7779
+       select CLK_R8A7790 if ARCH_R8A7790
+       select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
+       select CLK_R8A7792 if ARCH_R8A7792
+       select CLK_R8A7794 if ARCH_R8A7794
+       select CLK_R8A7795 if ARCH_R8A7795
+       select CLK_R8A7796 if ARCH_R8A7796
+       select CLK_SH73A0 if ARCH_SH73A0
+
+if CLK_RENESAS
+
+config CLK_RENESAS_LEGACY
+       bool "Legacy DT clock support"
+       depends on CLK_R8A7790 || CLK_R8A7791 || CLK_R8A7792 || CLK_R8A7794
+       default y
+       help
+         Enable backward compatibility with old device trees describing a
+         hierarchical representation of the various CPG and MSTP clocks.
+
+         Say Y if you want your kernel to work with old DTBs.
+
+# SoC
+config CLK_EMEV2
+       bool "Emma Mobile EV2 clock support" if COMPILE_TEST
+
+config CLK_RZA1
+       bool
+       select CLK_RENESAS_CPG_MSTP
+
+config CLK_R8A73A4
+       bool
+       select CLK_RENESAS_CPG_MSTP
+       select CLK_RENESAS_DIV6
+
+config CLK_R8A7740
+       bool
+       select CLK_RENESAS_CPG_MSTP
+       select CLK_RENESAS_DIV6
+
+config CLK_R8A7743
+       bool
+       select CLK_RCAR_GEN2_CPG
+
+config CLK_R8A7745
+       bool
+       select CLK_RCAR_GEN2_CPG
+
+config CLK_R8A7778
+       bool
+       select CLK_RENESAS_CPG_MSTP
+
+config CLK_R8A7779
+       bool
+       select CLK_RENESAS_CPG_MSTP
+
+config CLK_R8A7790
+       bool
+       select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
+       select CLK_RCAR_GEN2_CPG
+       select CLK_RENESAS_DIV6
+
+config CLK_R8A7791
+       bool
+       select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
+       select CLK_RCAR_GEN2_CPG
+       select CLK_RENESAS_DIV6
+
+config CLK_R8A7792
+       bool
+       select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
+       select CLK_RCAR_GEN2_CPG
+
+config CLK_R8A7794
+       bool
+       select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY
+       select CLK_RCAR_GEN2_CPG
+       select CLK_RENESAS_DIV6
+
+config CLK_R8A7795
+       bool
+       select CLK_RCAR_GEN3_CPG
+
+config CLK_R8A7796
+       bool
+       select CLK_RCAR_GEN3_CPG
+
+config CLK_SH73A0
+       bool
+       select CLK_RENESAS_CPG_MSTP
+       select CLK_RENESAS_DIV6
+
+
+# Family
+config CLK_RCAR_GEN2
+       bool
+       select CLK_RENESAS_CPG_MSTP
+       select CLK_RENESAS_DIV6
+
+config CLK_RCAR_GEN2_CPG
+       bool
+       select CLK_RENESAS_CPG_MSSR
+
+config CLK_RCAR_GEN3_CPG
+       bool
+       select CLK_RENESAS_CPG_MSSR
+
+
+# Generic
 config CLK_RENESAS_CPG_MSSR
        bool
-       default y if ARCH_R8A7743
-       default y if ARCH_R8A7745
-       default y if ARCH_R8A7795
-       default y if ARCH_R8A7796
+       select CLK_RENESAS_DIV6
 
 config CLK_RENESAS_CPG_MSTP
        bool
-       default y if ARCH_R7S72100
-       default y if ARCH_R8A73A4
-       default y if ARCH_R8A7740
-       default y if ARCH_R8A7778
-       default y if ARCH_R8A7779
-       default y if ARCH_R8A7790
-       default y if ARCH_R8A7791
-       default y if ARCH_R8A7792
-       default y if ARCH_R8A7793
-       default y if ARCH_R8A7794
-       default y if ARCH_SH73A0
+
+config CLK_RENESAS_DIV6
+       bool "DIV6 clock support" if COMPILE_TEST
+
+endif # CLK_RENESAS
index 1072f7653c0c5e701b15c678b8a7dd550b40dba1..02d04124371f717afee9ee21147144e38952586d 100644 (file)
@@ -1,19 +1,26 @@
-obj-$(CONFIG_ARCH_EMEV2)               += clk-emev2.o
-obj-$(CONFIG_ARCH_R7S72100)            += clk-rz.o
-obj-$(CONFIG_ARCH_R8A73A4)             += clk-r8a73a4.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7740)             += clk-r8a7740.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7743)             += r8a7743-cpg-mssr.o rcar-gen2-cpg.o
-obj-$(CONFIG_ARCH_R8A7745)             += r8a7745-cpg-mssr.o rcar-gen2-cpg.o
-obj-$(CONFIG_ARCH_R8A7778)             += clk-r8a7778.o
-obj-$(CONFIG_ARCH_R8A7779)             += clk-r8a7779.o
-obj-$(CONFIG_ARCH_R8A7790)             += clk-rcar-gen2.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7791)             += clk-rcar-gen2.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7792)             += clk-rcar-gen2.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7793)             += clk-rcar-gen2.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7794)             += clk-rcar-gen2.o clk-div6.o
-obj-$(CONFIG_ARCH_R8A7795)             += r8a7795-cpg-mssr.o rcar-gen3-cpg.o
-obj-$(CONFIG_ARCH_R8A7796)             += r8a7796-cpg-mssr.o rcar-gen3-cpg.o
-obj-$(CONFIG_ARCH_SH73A0)              += clk-sh73a0.o clk-div6.o
+# SoC
+obj-$(CONFIG_CLK_EMEV2)                        += clk-emev2.o
+obj-$(CONFIG_CLK_RZA1)                 += clk-rz.o
+obj-$(CONFIG_CLK_R8A73A4)              += clk-r8a73a4.o
+obj-$(CONFIG_CLK_R8A7740)              += clk-r8a7740.o
+obj-$(CONFIG_CLK_R8A7743)              += r8a7743-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7745)              += r8a7745-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7778)              += clk-r8a7778.o
+obj-$(CONFIG_CLK_R8A7779)              += clk-r8a7779.o
+obj-$(CONFIG_CLK_R8A7790)              += r8a7790-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7791)              += r8a7791-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7792)              += r8a7792-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7794)              += r8a7794-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7795)              += r8a7795-cpg-mssr.o
+obj-$(CONFIG_CLK_R8A7796)              += r8a7796-cpg-mssr.o
+obj-$(CONFIG_CLK_SH73A0)               += clk-sh73a0.o
 
-obj-$(CONFIG_CLK_RENESAS_CPG_MSSR)     += renesas-cpg-mssr.o clk-div6.o
+# Family
+obj-$(CONFIG_CLK_RCAR_GEN2)            += clk-rcar-gen2.o
+obj-$(CONFIG_CLK_RCAR_GEN2_CPG)                += rcar-gen2-cpg.o
+obj-$(CONFIG_CLK_RCAR_GEN3_CPG)                += rcar-gen3-cpg.o
+
+# Generic
+obj-$(CONFIG_CLK_RENESAS_CPG_MSSR)     += renesas-cpg-mssr.o
 obj-$(CONFIG_CLK_RENESAS_CPG_MSTP)     += clk-mstp.o
+obj-$(CONFIG_CLK_RENESAS_DIV6)         += clk-div6.o
index 4067216bf31fbce9d3b62454b5565a80a92aa5a4..f1617dd044cbbe15bdd8c4722a9c7c2042d609b8 100644 (file)
@@ -325,7 +325,7 @@ fail_put:
 
 void cpg_mstp_detach_dev(struct generic_pm_domain *unused, struct device *dev)
 {
-       if (!list_empty(&dev->power.subsys_data->clock_list))
+       if (!pm_clk_no_clocks(dev))
                pm_clk_destroy(dev);
 }
 
index f39519edc645ca87887f30a259aab9b9de6d5991..51a2479ed5d7c817b719c299ef1875d6e3f72a61 100644 (file)
@@ -272,11 +272,14 @@ struct cpg_pll_config {
        unsigned int extal_div;
        unsigned int pll1_mult;
        unsigned int pll3_mult;
+       unsigned int pll0_mult;         /* For R-Car V2H and E2 only */
 };
 
 static const struct cpg_pll_config cpg_pll_configs[8] __initconst = {
-       { 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
-       { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+       { 1, 208, 106, 200 }, { 1, 208,  88, 200 },
+       { 1, 156,  80, 150 }, { 1, 156,  66, 150 },
+       { 2, 240, 122, 230 }, { 2, 240, 102, 230 },
+       { 2, 208, 106, 200 }, { 2, 208,  88, 200 },
 };
 
 /* SDHI divisors */
@@ -298,6 +301,12 @@ static const struct clk_div_table cpg_sd01_div_table[] = {
 
 static u32 cpg_mode __initdata;
 
+static const char * const pll0_mult_match[] = {
+       "renesas,r8a7792-cpg-clocks",
+       "renesas,r8a7794-cpg-clocks",
+       NULL
+};
+
 static struct clk * __init
 rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
                             const struct cpg_pll_config *config,
@@ -318,9 +327,15 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
                 * clock implementation and we currently have no need to change
                 * the multiplier value.
                 */
-               u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+               if (of_device_compatible_match(np, pll0_mult_match)) {
+                       /* R-Car V2H and E2 do not have PLL0CR */
+                       mult = config->pll0_mult;
+                       div = 3;
+               } else {
+                       u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
+                       mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
+               }
                parent_name = "main";
-               mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
        } else if (!strcmp(name, "pll1")) {
                parent_name = "main";
                mult = config->pll1_mult / 2;
index 2f15ba786c3b0ea15dd790df02c35696bf12ab80..9e2360a8e14b860ec4a3a5e9982c370b772be178 100644 (file)
@@ -167,16 +167,12 @@ static const struct mssr_mod_clk r8a7745_mod_clks[] __initconst = {
        DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
-       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
-       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
-       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
        DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
-       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
        DEF_MOD("scifa3",               1106,   R8A7745_CLK_MP),
        DEF_MOD("scifa4",               1107,   R8A7745_CLK_MP),
        DEF_MOD("scifa5",               1108,   R8A7745_CLK_MP),
@@ -194,31 +190,22 @@ static const unsigned int r8a7745_crit_mod_clks[] __initconst = {
  *    MD       EXTAL           PLL0    PLL1    PLL3
  * 14 13 19    (MHz)           *1      *2
  *---------------------------------------------------
- * 0  0  0     15              x200/3  x208/2  x106
  * 0  0  1     15              x200/3  x208/2  x88
- * 0  1  0     20              x150/3  x156/2  x80
  * 0  1  1     20              x150/3  x156/2  x66
- * 1  0  0     26 / 2          x230/3  x240/2  x122
  * 1  0  1     26 / 2          x230/3  x240/2  x102
- * 1  1  0     30 / 2          x200/3  x208/2  x106
  * 1  1  1     30 / 2          x200/3  x208/2  x88
  *
  * *1 :        Table 7.5b indicates VCO output (PLL0 = VCO/3)
  * *2 :        Table 7.5b indicates VCO output (PLL1 = VCO/2)
  */
-#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 12) | \
-                                        (((md) & BIT(13)) >> 12) | \
-                                        (((md) & BIT(19)) >> 19))
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 13) | \
+                                        (((md) & BIT(13)) >> 13))
 
 static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
        /* EXTAL div    PLL1 mult       PLL3 mult       PLL0 mult */
-       { 1,            208,            106,            200     },
        { 1,            208,            88,             200     },
-       { 1,            156,            80,             150     },
        { 1,            156,            66,             150     },
-       { 2,            240,            122,            230     },
        { 2,            240,            102,            230     },
-       { 2,            208,            106,            200     },
        { 2,            208,            88,             200     },
 };
 
diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c
new file mode 100644 (file)
index 0000000..46bb55b
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * r8a7790 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2017 Glider bvba
+ *
+ * Based on clk-rcar-gen2.c
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a7790-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen2-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A7790_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_USB_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL1_DIV2,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a7790_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",     CLK_EXTAL),
+       DEF_INPUT("usb_extal", CLK_USB_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+
+       /* Core Clock Outputs */
+       DEF_BASE("z",    R8A7790_CLK_Z,    CLK_TYPE_GEN2_Z,    CLK_PLL0),
+       DEF_BASE("lb",   R8A7790_CLK_LB,   CLK_TYPE_GEN2_LB,   CLK_PLL1),
+       DEF_BASE("adsp", R8A7790_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1),
+       DEF_BASE("sdh",  R8A7790_CLK_SDH,  CLK_TYPE_GEN2_SDH,  CLK_PLL1),
+       DEF_BASE("sd0",  R8A7790_CLK_SD0,  CLK_TYPE_GEN2_SD0,  CLK_PLL1),
+       DEF_BASE("sd1",  R8A7790_CLK_SD1,  CLK_TYPE_GEN2_SD1,  CLK_PLL1),
+       DEF_BASE("qspi", R8A7790_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2),
+       DEF_BASE("rcan", R8A7790_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL),
+
+       DEF_FIXED("z2",     R8A7790_CLK_Z2,    CLK_PLL1,          2, 1),
+       DEF_FIXED("zg",     R8A7790_CLK_ZG,    CLK_PLL1,          3, 1),
+       DEF_FIXED("zx",     R8A7790_CLK_ZX,    CLK_PLL1,          3, 1),
+       DEF_FIXED("zs",     R8A7790_CLK_ZS,    CLK_PLL1,          6, 1),
+       DEF_FIXED("hp",     R8A7790_CLK_HP,    CLK_PLL1,         12, 1),
+       DEF_FIXED("i",      R8A7790_CLK_I,     CLK_PLL1,          2, 1),
+       DEF_FIXED("b",      R8A7790_CLK_B,     CLK_PLL1,         12, 1),
+       DEF_FIXED("p",      R8A7790_CLK_P,     CLK_PLL1,         24, 1),
+       DEF_FIXED("cl",     R8A7790_CLK_CL,    CLK_PLL1,         48, 1),
+       DEF_FIXED("m2",     R8A7790_CLK_M2,    CLK_PLL1,          8, 1),
+       DEF_FIXED("imp",    R8A7790_CLK_IMP,   CLK_PLL1,          4, 1),
+       DEF_FIXED("zb3",    R8A7790_CLK_ZB3,   CLK_PLL3,          4, 1),
+       DEF_FIXED("zb3d2",  R8A7790_CLK_ZB3D2, CLK_PLL3,          8, 1),
+       DEF_FIXED("ddr",    R8A7790_CLK_DDR,   CLK_PLL3,          8, 1),
+       DEF_FIXED("mp",     R8A7790_CLK_MP,    CLK_PLL1_DIV2,    15, 1),
+       DEF_FIXED("cp",     R8A7790_CLK_CP,    CLK_EXTAL,         2, 1),
+       DEF_FIXED("r",      R8A7790_CLK_R,     CLK_PLL1,      49152, 1),
+       DEF_FIXED("osc",    R8A7790_CLK_OSC,   CLK_PLL1,      12288, 1),
+
+       DEF_DIV6P1("sd2",   R8A7790_CLK_SD2,   CLK_PLL1_DIV2, 0x078),
+       DEF_DIV6P1("sd3",   R8A7790_CLK_SD3,   CLK_PLL1_DIV2, 0x26c),
+       DEF_DIV6P1("mmc0",  R8A7790_CLK_MMC0,  CLK_PLL1_DIV2, 0x240),
+       DEF_DIV6P1("mmc1",  R8A7790_CLK_MMC1,  CLK_PLL1_DIV2, 0x244),
+       DEF_DIV6P1("ssp",   R8A7790_CLK_SSP,   CLK_PLL1_DIV2, 0x248),
+       DEF_DIV6P1("ssprs", R8A7790_CLK_SSPRS, CLK_PLL1_DIV2, 0x24c),
+};
+
+static const struct mssr_mod_clk r8a7790_mod_clks[] __initconst = {
+       DEF_MOD("msiof0",                  0,   R8A7790_CLK_MP),
+       DEF_MOD("vcp1",                  100,   R8A7790_CLK_ZS),
+       DEF_MOD("vcp0",                  101,   R8A7790_CLK_ZS),
+       DEF_MOD("vpc1",                  102,   R8A7790_CLK_ZS),
+       DEF_MOD("vpc0",                  103,   R8A7790_CLK_ZS),
+       DEF_MOD("jpu",                   106,   R8A7790_CLK_M2),
+       DEF_MOD("ssp1",                  109,   R8A7790_CLK_ZS),
+       DEF_MOD("tmu1",                  111,   R8A7790_CLK_P),
+       DEF_MOD("3dg",                   112,   R8A7790_CLK_ZG),
+       DEF_MOD("2d-dmac",               115,   R8A7790_CLK_ZS),
+       DEF_MOD("fdp1-2",                117,   R8A7790_CLK_ZS),
+       DEF_MOD("fdp1-1",                118,   R8A7790_CLK_ZS),
+       DEF_MOD("fdp1-0",                119,   R8A7790_CLK_ZS),
+       DEF_MOD("tmu3",                  121,   R8A7790_CLK_P),
+       DEF_MOD("tmu2",                  122,   R8A7790_CLK_P),
+       DEF_MOD("cmt0",                  124,   R8A7790_CLK_R),
+       DEF_MOD("tmu0",                  125,   R8A7790_CLK_CP),
+       DEF_MOD("vsp1du1",               127,   R8A7790_CLK_ZS),
+       DEF_MOD("vsp1du0",               128,   R8A7790_CLK_ZS),
+       DEF_MOD("vsp1-rt",               130,   R8A7790_CLK_ZS),
+       DEF_MOD("vsp1-sy",               131,   R8A7790_CLK_ZS),
+       DEF_MOD("scifa2",                202,   R8A7790_CLK_MP),
+       DEF_MOD("scifa1",                203,   R8A7790_CLK_MP),
+       DEF_MOD("scifa0",                204,   R8A7790_CLK_MP),
+       DEF_MOD("msiof2",                205,   R8A7790_CLK_MP),
+       DEF_MOD("scifb0",                206,   R8A7790_CLK_MP),
+       DEF_MOD("scifb1",                207,   R8A7790_CLK_MP),
+       DEF_MOD("msiof1",                208,   R8A7790_CLK_MP),
+       DEF_MOD("msiof3",                215,   R8A7790_CLK_MP),
+       DEF_MOD("scifb2",                216,   R8A7790_CLK_MP),
+       DEF_MOD("sys-dmac1",             218,   R8A7790_CLK_ZS),
+       DEF_MOD("sys-dmac0",             219,   R8A7790_CLK_ZS),
+       DEF_MOD("iic2",                  300,   R8A7790_CLK_HP),
+       DEF_MOD("tpu0",                  304,   R8A7790_CLK_CP),
+       DEF_MOD("mmcif1",                305,   R8A7790_CLK_MMC1),
+       DEF_MOD("scif2",                 310,   R8A7790_CLK_P),
+       DEF_MOD("sdhi3",                 311,   R8A7790_CLK_SD3),
+       DEF_MOD("sdhi2",                 312,   R8A7790_CLK_SD2),
+       DEF_MOD("sdhi1",                 313,   R8A7790_CLK_SD1),
+       DEF_MOD("sdhi0",                 314,   R8A7790_CLK_SD0),
+       DEF_MOD("mmcif0",                315,   R8A7790_CLK_MMC0),
+       DEF_MOD("iic0",                  318,   R8A7790_CLK_HP),
+       DEF_MOD("pciec",                 319,   R8A7790_CLK_MP),
+       DEF_MOD("iic1",                  323,   R8A7790_CLK_HP),
+       DEF_MOD("usb3.0",                328,   R8A7790_CLK_MP),
+       DEF_MOD("cmt1",                  329,   R8A7790_CLK_R),
+       DEF_MOD("usbhs-dmac0",           330,   R8A7790_CLK_HP),
+       DEF_MOD("usbhs-dmac1",           331,   R8A7790_CLK_HP),
+       DEF_MOD("irqc",                  407,   R8A7790_CLK_CP),
+       DEF_MOD("intc-sys",              408,   R8A7790_CLK_ZS),
+       DEF_MOD("audio-dmac1",           501,   R8A7790_CLK_HP),
+       DEF_MOD("audio-dmac0",           502,   R8A7790_CLK_HP),
+       DEF_MOD("adsp_mod",              506,   R8A7790_CLK_ADSP),
+       DEF_MOD("thermal",               522,   CLK_EXTAL),
+       DEF_MOD("pwm",                   523,   R8A7790_CLK_P),
+       DEF_MOD("usb-ehci",              703,   R8A7790_CLK_MP),
+       DEF_MOD("usbhs",                 704,   R8A7790_CLK_HP),
+       DEF_MOD("hscif1",                716,   R8A7790_CLK_ZS),
+       DEF_MOD("hscif0",                717,   R8A7790_CLK_ZS),
+       DEF_MOD("scif1",                 720,   R8A7790_CLK_P),
+       DEF_MOD("scif0",                 721,   R8A7790_CLK_P),
+       DEF_MOD("du2",                   722,   R8A7790_CLK_ZX),
+       DEF_MOD("du1",                   723,   R8A7790_CLK_ZX),
+       DEF_MOD("du0",                   724,   R8A7790_CLK_ZX),
+       DEF_MOD("lvds1",                 725,   R8A7790_CLK_ZX),
+       DEF_MOD("lvds0",                 726,   R8A7790_CLK_ZX),
+       DEF_MOD("mlb",                   802,   R8A7790_CLK_HP),
+       DEF_MOD("vin3",                  808,   R8A7790_CLK_ZG),
+       DEF_MOD("vin2",                  809,   R8A7790_CLK_ZG),
+       DEF_MOD("vin1",                  810,   R8A7790_CLK_ZG),
+       DEF_MOD("vin0",                  811,   R8A7790_CLK_ZG),
+       DEF_MOD("etheravb",              812,   R8A7790_CLK_HP),
+       DEF_MOD("ether",                 813,   R8A7790_CLK_P),
+       DEF_MOD("sata1",                 814,   R8A7790_CLK_ZS),
+       DEF_MOD("sata0",                 815,   R8A7790_CLK_ZS),
+       DEF_MOD("gyro-adc",              901,   R8A7790_CLK_P),
+       DEF_MOD("gpio5",                 907,   R8A7790_CLK_CP),
+       DEF_MOD("gpio4",                 908,   R8A7790_CLK_CP),
+       DEF_MOD("gpio3",                 909,   R8A7790_CLK_CP),
+       DEF_MOD("gpio2",                 910,   R8A7790_CLK_CP),
+       DEF_MOD("gpio1",                 911,   R8A7790_CLK_CP),
+       DEF_MOD("gpio0",                 912,   R8A7790_CLK_CP),
+       DEF_MOD("can1",                  915,   R8A7790_CLK_P),
+       DEF_MOD("can0",                  916,   R8A7790_CLK_P),
+       DEF_MOD("qspi_mod",              917,   R8A7790_CLK_QSPI),
+       DEF_MOD("iicdvfs",               926,   R8A7790_CLK_CP),
+       DEF_MOD("i2c3",                  928,   R8A7790_CLK_HP),
+       DEF_MOD("i2c2",                  929,   R8A7790_CLK_HP),
+       DEF_MOD("i2c1",                  930,   R8A7790_CLK_HP),
+       DEF_MOD("i2c0",                  931,   R8A7790_CLK_HP),
+       DEF_MOD("ssi-all",              1005,   R8A7790_CLK_P),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A7790_CLK_P),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
+};
+
+static const unsigned int r8a7790_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-SYS (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)           *1      *1
+ *---------------------------------------------------
+ * 0  0  0     15              x172/2  x208/2  x106
+ * 0  0  1     15              x172/2  x208/2  x88
+ * 0  1  0     20              x130/2  x156/2  x80
+ * 0  1  1     20              x130/2  x156/2  x66
+ * 1  0  0     26 / 2          x200/2  x240/2  x122
+ * 1  0  1     26 / 2          x200/2  x240/2  x102
+ * 1  1  0     30 / 2          x172/2  x208/2  x106
+ * 1  1  1     30 / 2          x172/2  x208/2  x88
+ *
+ * *1 :        Table 7.5a indicates VCO output (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 12) | \
+                                        (((md) & BIT(13)) >> 12) | \
+                                        (((md) & BIT(19)) >> 19))
+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
+       { 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
+       { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+};
+
+static int __init r8a7790_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+       return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a7790_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a7790_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a7790_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a7790_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a7790_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a7790_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a7790_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a7790_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen2_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c
new file mode 100644 (file)
index 0000000..c0b51f9
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * r8a7791 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2015-2017 Glider bvba
+ *
+ * Based on clk-rcar-gen2.c
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a7791-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen2-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A7791_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_USB_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL1_DIV2,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static struct cpg_core_clk r8a7791_core_clks[] __initdata = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",     CLK_EXTAL),
+       DEF_INPUT("usb_extal", CLK_USB_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+
+       /* Core Clock Outputs */
+       DEF_BASE("z",    R8A7791_CLK_Z,    CLK_TYPE_GEN2_Z,    CLK_PLL0),
+       DEF_BASE("lb",   R8A7791_CLK_LB,   CLK_TYPE_GEN2_LB,   CLK_PLL1),
+       DEF_BASE("adsp", R8A7791_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1),
+       DEF_BASE("sdh",  R8A7791_CLK_SDH,  CLK_TYPE_GEN2_SDH,  CLK_PLL1),
+       DEF_BASE("sd0",  R8A7791_CLK_SD0,  CLK_TYPE_GEN2_SD0,  CLK_PLL1),
+       DEF_BASE("qspi", R8A7791_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2),
+       DEF_BASE("rcan", R8A7791_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL),
+
+       DEF_FIXED("zg",     R8A7791_CLK_ZG,    CLK_PLL1,          3, 1),
+       DEF_FIXED("zx",     R8A7791_CLK_ZX,    CLK_PLL1,          3, 1),
+       DEF_FIXED("zs",     R8A7791_CLK_ZS,    CLK_PLL1,          6, 1),
+       DEF_FIXED("hp",     R8A7791_CLK_HP,    CLK_PLL1,         12, 1),
+       DEF_FIXED("i",      R8A7791_CLK_I,     CLK_PLL1,          2, 1),
+       DEF_FIXED("b",      R8A7791_CLK_B,     CLK_PLL1,         12, 1),
+       DEF_FIXED("p",      R8A7791_CLK_P,     CLK_PLL1,         24, 1),
+       DEF_FIXED("cl",     R8A7791_CLK_CL,    CLK_PLL1,         48, 1),
+       DEF_FIXED("m2",     R8A7791_CLK_M2,    CLK_PLL1,          8, 1),
+       DEF_FIXED("zb3",    R8A7791_CLK_ZB3,   CLK_PLL3,          4, 1),
+       DEF_FIXED("zb3d2",  R8A7791_CLK_ZB3D2, CLK_PLL3,          8, 1),
+       DEF_FIXED("ddr",    R8A7791_CLK_DDR,   CLK_PLL3,          8, 1),
+       DEF_FIXED("mp",     R8A7791_CLK_MP,    CLK_PLL1_DIV2,    15, 1),
+       DEF_FIXED("cp",     R8A7791_CLK_CP,    CLK_EXTAL,         2, 1),
+       DEF_FIXED("r",      R8A7791_CLK_R,     CLK_PLL1,      49152, 1),
+       DEF_FIXED("osc",    R8A7791_CLK_OSC,   CLK_PLL1,      12288, 1),
+
+       DEF_DIV6P1("sd2",   R8A7791_CLK_SD2,   CLK_PLL1_DIV2, 0x078),
+       DEF_DIV6P1("sd3",   R8A7791_CLK_SD3,   CLK_PLL1_DIV2, 0x26c),
+       DEF_DIV6P1("mmc0",  R8A7791_CLK_MMC0,  CLK_PLL1_DIV2, 0x240),
+       DEF_DIV6P1("ssp",   R8A7791_CLK_SSP,   CLK_PLL1_DIV2, 0x248),
+       DEF_DIV6P1("ssprs", R8A7791_CLK_SSPRS, CLK_PLL1_DIV2, 0x24c),
+};
+
+static const struct mssr_mod_clk r8a7791_mod_clks[] __initconst = {
+       DEF_MOD("msiof0",                  0,   R8A7791_CLK_MP),
+       DEF_MOD("vcp0",                  101,   R8A7791_CLK_ZS),
+       DEF_MOD("vpc0",                  103,   R8A7791_CLK_ZS),
+       DEF_MOD("jpu",                   106,   R8A7791_CLK_M2),
+       DEF_MOD("ssp1",                  109,   R8A7791_CLK_ZS),
+       DEF_MOD("tmu1",                  111,   R8A7791_CLK_P),
+       DEF_MOD("3dg",                   112,   R8A7791_CLK_ZG),
+       DEF_MOD("2d-dmac",               115,   R8A7791_CLK_ZS),
+       DEF_MOD("fdp1-1",                118,   R8A7791_CLK_ZS),
+       DEF_MOD("fdp1-0",                119,   R8A7791_CLK_ZS),
+       DEF_MOD("tmu3",                  121,   R8A7791_CLK_P),
+       DEF_MOD("tmu2",                  122,   R8A7791_CLK_P),
+       DEF_MOD("cmt0",                  124,   R8A7791_CLK_R),
+       DEF_MOD("tmu0",                  125,   R8A7791_CLK_CP),
+       DEF_MOD("vsp1du1",               127,   R8A7791_CLK_ZS),
+       DEF_MOD("vsp1du0",               128,   R8A7791_CLK_ZS),
+       DEF_MOD("vsp1-sy",               131,   R8A7791_CLK_ZS),
+       DEF_MOD("scifa2",                202,   R8A7791_CLK_MP),
+       DEF_MOD("scifa1",                203,   R8A7791_CLK_MP),
+       DEF_MOD("scifa0",                204,   R8A7791_CLK_MP),
+       DEF_MOD("msiof2",                205,   R8A7791_CLK_MP),
+       DEF_MOD("scifb0",                206,   R8A7791_CLK_MP),
+       DEF_MOD("scifb1",                207,   R8A7791_CLK_MP),
+       DEF_MOD("msiof1",                208,   R8A7791_CLK_MP),
+       DEF_MOD("scifb2",                216,   R8A7791_CLK_MP),
+       DEF_MOD("sys-dmac1",             218,   R8A7791_CLK_ZS),
+       DEF_MOD("sys-dmac0",             219,   R8A7791_CLK_ZS),
+       DEF_MOD("tpu0",                  304,   R8A7791_CLK_CP),
+       DEF_MOD("sdhi3",                 311,   R8A7791_CLK_SD3),
+       DEF_MOD("sdhi2",                 312,   R8A7791_CLK_SD2),
+       DEF_MOD("sdhi0",                 314,   R8A7791_CLK_SD0),
+       DEF_MOD("mmcif0",                315,   R8A7791_CLK_MMC0),
+       DEF_MOD("iic0",                  318,   R8A7791_CLK_HP),
+       DEF_MOD("pciec",                 319,   R8A7791_CLK_MP),
+       DEF_MOD("iic1",                  323,   R8A7791_CLK_HP),
+       DEF_MOD("usb3.0",                328,   R8A7791_CLK_MP),
+       DEF_MOD("cmt1",                  329,   R8A7791_CLK_R),
+       DEF_MOD("usbhs-dmac0",           330,   R8A7791_CLK_HP),
+       DEF_MOD("usbhs-dmac1",           331,   R8A7791_CLK_HP),
+       DEF_MOD("irqc",                  407,   R8A7791_CLK_CP),
+       DEF_MOD("intc-sys",              408,   R8A7791_CLK_ZS),
+       DEF_MOD("audio-dmac1",           501,   R8A7791_CLK_HP),
+       DEF_MOD("audio-dmac0",           502,   R8A7791_CLK_HP),
+       DEF_MOD("adsp_mod",              506,   R8A7791_CLK_ADSP),
+       DEF_MOD("thermal",               522,   CLK_EXTAL),
+       DEF_MOD("pwm",                   523,   R8A7791_CLK_P),
+       DEF_MOD("usb-ehci",              703,   R8A7791_CLK_MP),
+       DEF_MOD("usbhs",                 704,   R8A7791_CLK_HP),
+       DEF_MOD("hscif2",                713,   R8A7791_CLK_ZS),
+       DEF_MOD("scif5",                 714,   R8A7791_CLK_P),
+       DEF_MOD("scif4",                 715,   R8A7791_CLK_P),
+       DEF_MOD("hscif1",                716,   R8A7791_CLK_ZS),
+       DEF_MOD("hscif0",                717,   R8A7791_CLK_ZS),
+       DEF_MOD("scif3",                 718,   R8A7791_CLK_P),
+       DEF_MOD("scif2",                 719,   R8A7791_CLK_P),
+       DEF_MOD("scif1",                 720,   R8A7791_CLK_P),
+       DEF_MOD("scif0",                 721,   R8A7791_CLK_P),
+       DEF_MOD("du1",                   723,   R8A7791_CLK_ZX),
+       DEF_MOD("du0",                   724,   R8A7791_CLK_ZX),
+       DEF_MOD("lvds0",                 726,   R8A7791_CLK_ZX),
+       DEF_MOD("ipmmu-sgx",             800,   R8A7791_CLK_ZX),
+       DEF_MOD("mlb",                   802,   R8A7791_CLK_HP),
+       DEF_MOD("vin2",                  809,   R8A7791_CLK_ZG),
+       DEF_MOD("vin1",                  810,   R8A7791_CLK_ZG),
+       DEF_MOD("vin0",                  811,   R8A7791_CLK_ZG),
+       DEF_MOD("etheravb",              812,   R8A7791_CLK_HP),
+       DEF_MOD("ether",                 813,   R8A7791_CLK_P),
+       DEF_MOD("sata1",                 814,   R8A7791_CLK_ZS),
+       DEF_MOD("sata0",                 815,   R8A7791_CLK_ZS),
+       DEF_MOD("gyro-adc",              901,   R8A7791_CLK_P),
+       DEF_MOD("gpio7",                 904,   R8A7791_CLK_CP),
+       DEF_MOD("gpio6",                 905,   R8A7791_CLK_CP),
+       DEF_MOD("gpio5",                 907,   R8A7791_CLK_CP),
+       DEF_MOD("gpio4",                 908,   R8A7791_CLK_CP),
+       DEF_MOD("gpio3",                 909,   R8A7791_CLK_CP),
+       DEF_MOD("gpio2",                 910,   R8A7791_CLK_CP),
+       DEF_MOD("gpio1",                 911,   R8A7791_CLK_CP),
+       DEF_MOD("gpio0",                 912,   R8A7791_CLK_CP),
+       DEF_MOD("can1",                  915,   R8A7791_CLK_P),
+       DEF_MOD("can0",                  916,   R8A7791_CLK_P),
+       DEF_MOD("qspi_mod",              917,   R8A7791_CLK_QSPI),
+       DEF_MOD("i2c5",                  925,   R8A7791_CLK_HP),
+       DEF_MOD("iicdvfs",               926,   R8A7791_CLK_CP),
+       DEF_MOD("i2c4",                  927,   R8A7791_CLK_HP),
+       DEF_MOD("i2c3",                  928,   R8A7791_CLK_HP),
+       DEF_MOD("i2c2",                  929,   R8A7791_CLK_HP),
+       DEF_MOD("i2c1",                  930,   R8A7791_CLK_HP),
+       DEF_MOD("i2c0",                  931,   R8A7791_CLK_HP),
+       DEF_MOD("ssi-all",              1005,   R8A7791_CLK_P),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A7791_CLK_P),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
+       DEF_MOD("scifa3",               1106,   R8A7791_CLK_MP),
+       DEF_MOD("scifa4",               1107,   R8A7791_CLK_MP),
+       DEF_MOD("scifa5",               1108,   R8A7791_CLK_MP),
+};
+
+static const unsigned int r8a7791_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-SYS (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)           *1      *1
+ *---------------------------------------------------
+ * 0  0  0     15              x172/2  x208/2  x106
+ * 0  0  1     15              x172/2  x208/2  x88
+ * 0  1  0     20              x130/2  x156/2  x80
+ * 0  1  1     20              x130/2  x156/2  x66
+ * 1  0  0     26 / 2          x200/2  x240/2  x122
+ * 1  0  1     26 / 2          x200/2  x240/2  x102
+ * 1  1  0     30 / 2          x172/2  x208/2  x106
+ * 1  1  1     30 / 2          x172/2  x208/2  x88
+ *
+ * *1 :        Table 7.5a indicates VCO output (PLLx = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 12) | \
+                                        (((md) & BIT(13)) >> 12) | \
+                                        (((md) & BIT(19)) >> 19))
+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
+       { 1, 208, 106 }, { 1, 208,  88 }, { 1, 156,  80 }, { 1, 156,  66 },
+       { 2, 240, 122 }, { 2, 240, 102 }, { 2, 208, 106 }, { 2, 208,  88 },
+};
+
+static int __init r8a7791_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
+       struct device_node *np = dev->of_node;
+       unsigned int i;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+       if (of_device_is_compatible(np, "renesas,r8a7793-cpg-mssr")) {
+               /* R-Car M2-N uses a 1/5 divider for ZG */
+               for (i = 0; i < ARRAY_SIZE(r8a7791_core_clks); i++)
+                       if (r8a7791_core_clks[i].id == R8A7791_CLK_ZG) {
+                               r8a7791_core_clks[i].div = 5;
+                               break;
+                       }
+       }
+       return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a7791_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a7791_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a7791_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a7791_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a7791_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a7791_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a7791_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a7791_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen2_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c
new file mode 100644 (file)
index 0000000..a832b9b
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * r8a7792 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2017 Glider bvba
+ *
+ * Based on clk-rcar-gen2.c
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a7792-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen2-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A7792_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL1_DIV2,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a7792_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",     CLK_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+
+       /* Core Clock Outputs */
+       DEF_BASE("lb",   R8A7792_CLK_LB,   CLK_TYPE_GEN2_LB,   CLK_PLL1),
+       DEF_BASE("qspi", R8A7792_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2),
+
+       DEF_FIXED("z",      R8A7792_CLK_Z,     CLK_PLL0,          1, 1),
+       DEF_FIXED("zg",     R8A7792_CLK_ZG,    CLK_PLL1,          5, 1),
+       DEF_FIXED("zx",     R8A7792_CLK_ZX,    CLK_PLL1,          3, 1),
+       DEF_FIXED("zs",     R8A7792_CLK_ZS,    CLK_PLL1,          6, 1),
+       DEF_FIXED("hp",     R8A7792_CLK_HP,    CLK_PLL1,         12, 1),
+       DEF_FIXED("i",      R8A7792_CLK_I,     CLK_PLL1,          3, 1),
+       DEF_FIXED("b",      R8A7792_CLK_B,     CLK_PLL1,         12, 1),
+       DEF_FIXED("p",      R8A7792_CLK_P,     CLK_PLL1,         24, 1),
+       DEF_FIXED("cl",     R8A7792_CLK_CL,    CLK_PLL1,         48, 1),
+       DEF_FIXED("m2",     R8A7792_CLK_M2,    CLK_PLL1,          8, 1),
+       DEF_FIXED("imp",    R8A7792_CLK_IMP,   CLK_PLL1,          4, 1),
+       DEF_FIXED("zb3",    R8A7792_CLK_ZB3,   CLK_PLL3,          4, 1),
+       DEF_FIXED("zb3d2",  R8A7792_CLK_ZB3D2, CLK_PLL3,          8, 1),
+       DEF_FIXED("ddr",    R8A7792_CLK_DDR,   CLK_PLL3,          8, 1),
+       DEF_FIXED("sd",     R8A7792_CLK_SD,    CLK_PLL1_DIV2,     8, 1),
+       DEF_FIXED("mp",     R8A7792_CLK_MP,    CLK_PLL1_DIV2,    15, 1),
+       DEF_FIXED("cp",     R8A7792_CLK_CP,    CLK_PLL1,         48, 1),
+       DEF_FIXED("cpex",   R8A7792_CLK_CPEX,  CLK_EXTAL,         2, 1),
+       DEF_FIXED("rcan",   R8A7792_CLK_RCAN,  CLK_PLL1_DIV2,    49, 1),
+       DEF_FIXED("r",      R8A7792_CLK_R,     CLK_PLL1,      49152, 1),
+       DEF_FIXED("osc",    R8A7792_CLK_OSC,   CLK_PLL1,      12288, 1),
+};
+
+static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = {
+       DEF_MOD("msiof0",                  0,   R8A7792_CLK_MP),
+       DEF_MOD("jpu",                   106,   R8A7792_CLK_M2),
+       DEF_MOD("tmu1",                  111,   R8A7792_CLK_P),
+       DEF_MOD("3dg",                   112,   R8A7792_CLK_ZG),
+       DEF_MOD("2d-dmac",               115,   R8A7792_CLK_ZS),
+       DEF_MOD("tmu3",                  121,   R8A7792_CLK_P),
+       DEF_MOD("tmu2",                  122,   R8A7792_CLK_P),
+       DEF_MOD("cmt0",                  124,   R8A7792_CLK_R),
+       DEF_MOD("tmu0",                  125,   R8A7792_CLK_CP),
+       DEF_MOD("vsp1du1",               127,   R8A7792_CLK_ZS),
+       DEF_MOD("vsp1du0",               128,   R8A7792_CLK_ZS),
+       DEF_MOD("vsp1-sy",               131,   R8A7792_CLK_ZS),
+       DEF_MOD("msiof1",                208,   R8A7792_CLK_MP),
+       DEF_MOD("sys-dmac1",             218,   R8A7792_CLK_ZS),
+       DEF_MOD("sys-dmac0",             219,   R8A7792_CLK_ZS),
+       DEF_MOD("tpu0",                  304,   R8A7792_CLK_CP),
+       DEF_MOD("sdhi0",                 314,   R8A7792_CLK_SD),
+       DEF_MOD("cmt1",                  329,   R8A7792_CLK_R),
+       DEF_MOD("irqc",                  407,   R8A7792_CLK_CP),
+       DEF_MOD("intc-sys",              408,   R8A7792_CLK_ZS),
+       DEF_MOD("audio-dmac0",           502,   R8A7792_CLK_HP),
+       DEF_MOD("thermal",               522,   CLK_EXTAL),
+       DEF_MOD("pwm",                   523,   R8A7792_CLK_P),
+       DEF_MOD("hscif1",                716,   R8A7792_CLK_ZS),
+       DEF_MOD("hscif0",                717,   R8A7792_CLK_ZS),
+       DEF_MOD("scif3",                 718,   R8A7792_CLK_P),
+       DEF_MOD("scif2",                 719,   R8A7792_CLK_P),
+       DEF_MOD("scif1",                 720,   R8A7792_CLK_P),
+       DEF_MOD("scif0",                 721,   R8A7792_CLK_P),
+       DEF_MOD("du1",                   723,   R8A7792_CLK_ZX),
+       DEF_MOD("du0",                   724,   R8A7792_CLK_ZX),
+       DEF_MOD("vin5",                  804,   R8A7792_CLK_ZG),
+       DEF_MOD("vin4",                  805,   R8A7792_CLK_ZG),
+       DEF_MOD("vin3",                  808,   R8A7792_CLK_ZG),
+       DEF_MOD("vin2",                  809,   R8A7792_CLK_ZG),
+       DEF_MOD("vin1",                  810,   R8A7792_CLK_ZG),
+       DEF_MOD("vin0",                  811,   R8A7792_CLK_ZG),
+       DEF_MOD("etheravb",              812,   R8A7792_CLK_HP),
+       DEF_MOD("gyro-adc",              901,   R8A7792_CLK_P),
+       DEF_MOD("gpio7",                 904,   R8A7792_CLK_CP),
+       DEF_MOD("gpio6",                 905,   R8A7792_CLK_CP),
+       DEF_MOD("gpio5",                 907,   R8A7792_CLK_CP),
+       DEF_MOD("gpio4",                 908,   R8A7792_CLK_CP),
+       DEF_MOD("gpio3",                 909,   R8A7792_CLK_CP),
+       DEF_MOD("gpio2",                 910,   R8A7792_CLK_CP),
+       DEF_MOD("gpio1",                 911,   R8A7792_CLK_CP),
+       DEF_MOD("gpio0",                 912,   R8A7792_CLK_CP),
+       DEF_MOD("gpio11",                913,   R8A7792_CLK_CP),
+       DEF_MOD("gpio10",                914,   R8A7792_CLK_CP),
+       DEF_MOD("can1",                  915,   R8A7792_CLK_P),
+       DEF_MOD("can0",                  916,   R8A7792_CLK_P),
+       DEF_MOD("qspi_mod",              917,   R8A7792_CLK_QSPI),
+       DEF_MOD("gpio9",                 919,   R8A7792_CLK_CP),
+       DEF_MOD("gpio8",                 921,   R8A7792_CLK_CP),
+       DEF_MOD("i2c5",                  925,   R8A7792_CLK_HP),
+       DEF_MOD("iicdvfs",               926,   R8A7792_CLK_CP),
+       DEF_MOD("i2c4",                  927,   R8A7792_CLK_HP),
+       DEF_MOD("i2c3",                  928,   R8A7792_CLK_HP),
+       DEF_MOD("i2c2",                  929,   R8A7792_CLK_HP),
+       DEF_MOD("i2c1",                  930,   R8A7792_CLK_HP),
+       DEF_MOD("i2c0",                  931,   R8A7792_CLK_HP),
+       DEF_MOD("ssi-all",              1005,   R8A7792_CLK_P),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+};
+
+static const unsigned int r8a7792_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-SYS (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)           *1      *2
+ *---------------------------------------------------
+ * 0  0  0     15              x200/3  x208/2  x106
+ * 0  0  1     15              x200/3  x208/2  x88
+ * 0  1  0     20              x150/3  x156/2  x80
+ * 0  1  1     20              x150/3  x156/2  x66
+ * 1  0  0     26 / 2          x230/3  x240/2  x122
+ * 1  0  1     26 / 2          x230/3  x240/2  x102
+ * 1  1  0     30 / 2          x200/3  x208/2  x106
+ * 1  1  1     30 / 2          x200/3  x208/2  x88
+ *
+ * *1 :        Table 7.5b indicates VCO output (PLL0 = VCO/3)
+ * *2 :        Table 7.5b indicates VCO output (PLL1 = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 12) | \
+                                        (((md) & BIT(13)) >> 12) | \
+                                        (((md) & BIT(19)) >> 19))
+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = {
+       { 1, 208, 106, 200 },
+       { 1, 208,  88, 200 },
+       { 1, 156,  80, 150 },
+       { 1, 156,  66, 150 },
+       { 2, 240, 122, 230 },
+       { 2, 240, 102, 230 },
+       { 2, 208, 106, 200 },
+       { 2, 208,  88, 200 },
+};
+
+static int __init r8a7792_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+       return rcar_gen2_cpg_init(cpg_pll_config, 3, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a7792_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a7792_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a7792_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a7792_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a7792_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a7792_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a7792_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a7792_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen2_cpg_clk_register,
+};
diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c
new file mode 100644 (file)
index 0000000..ec091a4
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * r8a7794 Clock Pulse Generator / Module Standby and Software Reset
+ *
+ * Copyright (C) 2017 Glider bvba
+ *
+ * Based on clk-rcar-gen2.c
+ *
+ * Copyright (C) 2013 Ideas On Board SPRL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/soc/renesas/rcar-rst.h>
+
+#include <dt-bindings/clock/r8a7794-cpg-mssr.h>
+
+#include "renesas-cpg-mssr.h"
+#include "rcar-gen2-cpg.h"
+
+enum clk_ids {
+       /* Core Clock Outputs exported to DT */
+       LAST_DT_CORE_CLK = R8A7794_CLK_OSC,
+
+       /* External Input Clocks */
+       CLK_EXTAL,
+       CLK_USB_EXTAL,
+
+       /* Internal Core Clocks */
+       CLK_MAIN,
+       CLK_PLL0,
+       CLK_PLL1,
+       CLK_PLL3,
+       CLK_PLL1_DIV2,
+
+       /* Module Clocks */
+       MOD_CLK_BASE
+};
+
+static const struct cpg_core_clk r8a7794_core_clks[] __initconst = {
+       /* External Clock Inputs */
+       DEF_INPUT("extal",     CLK_EXTAL),
+       DEF_INPUT("usb_extal", CLK_USB_EXTAL),
+
+       /* Internal Core Clocks */
+       DEF_BASE(".main",       CLK_MAIN, CLK_TYPE_GEN2_MAIN, CLK_EXTAL),
+       DEF_BASE(".pll0",       CLK_PLL0, CLK_TYPE_GEN2_PLL0, CLK_MAIN),
+       DEF_BASE(".pll1",       CLK_PLL1, CLK_TYPE_GEN2_PLL1, CLK_MAIN),
+       DEF_BASE(".pll3",       CLK_PLL3, CLK_TYPE_GEN2_PLL3, CLK_MAIN),
+
+       DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
+
+       /* Core Clock Outputs */
+       DEF_BASE("lb",   R8A7794_CLK_LB,   CLK_TYPE_GEN2_LB,   CLK_PLL1),
+       DEF_BASE("adsp", R8A7794_CLK_ADSP, CLK_TYPE_GEN2_ADSP, CLK_PLL1),
+       DEF_BASE("sdh",  R8A7794_CLK_SDH,  CLK_TYPE_GEN2_SDH,  CLK_PLL1),
+       DEF_BASE("sd0",  R8A7794_CLK_SD0,  CLK_TYPE_GEN2_SD0,  CLK_PLL1),
+       DEF_BASE("qspi", R8A7794_CLK_QSPI, CLK_TYPE_GEN2_QSPI, CLK_PLL1_DIV2),
+       DEF_BASE("rcan", R8A7794_CLK_RCAN, CLK_TYPE_GEN2_RCAN, CLK_USB_EXTAL),
+
+       DEF_FIXED("z2",     R8A7794_CLK_Z2,    CLK_PLL0,          1, 1),
+       DEF_FIXED("zg",     R8A7794_CLK_ZG,    CLK_PLL1,          6, 1),
+       DEF_FIXED("zx",     R8A7794_CLK_ZX,    CLK_PLL1,          3, 1),
+       DEF_FIXED("zs",     R8A7794_CLK_ZS,    CLK_PLL1,          6, 1),
+       DEF_FIXED("hp",     R8A7794_CLK_HP,    CLK_PLL1,         12, 1),
+       DEF_FIXED("i",      R8A7794_CLK_I,     CLK_PLL1,          2, 1),
+       DEF_FIXED("b",      R8A7794_CLK_B,     CLK_PLL1,         12, 1),
+       DEF_FIXED("p",      R8A7794_CLK_P,     CLK_PLL1,         24, 1),
+       DEF_FIXED("cl",     R8A7794_CLK_CL,    CLK_PLL1,         48, 1),
+       DEF_FIXED("cp",     R8A7794_CLK_CP,    CLK_PLL1,         48, 1),
+       DEF_FIXED("m2",     R8A7794_CLK_M2,    CLK_PLL1,          8, 1),
+       DEF_FIXED("zb3",    R8A7794_CLK_ZB3,   CLK_PLL3,          4, 1),
+       DEF_FIXED("zb3d2",  R8A7794_CLK_ZB3D2, CLK_PLL3,          8, 1),
+       DEF_FIXED("ddr",    R8A7794_CLK_DDR,   CLK_PLL3,          8, 1),
+       DEF_FIXED("mp",     R8A7794_CLK_MP,    CLK_PLL1_DIV2,    15, 1),
+       DEF_FIXED("cpex",   R8A7794_CLK_CPEX,  CLK_EXTAL,         2, 1),
+       DEF_FIXED("r",      R8A7794_CLK_R,     CLK_PLL1,      49152, 1),
+       DEF_FIXED("osc",    R8A7794_CLK_OSC,   CLK_PLL1,      12288, 1),
+
+       DEF_DIV6P1("sd2",   R8A7794_CLK_SD2,   CLK_PLL1_DIV2, 0x078),
+       DEF_DIV6P1("sd3",   R8A7794_CLK_SD3,   CLK_PLL1_DIV2, 0x26c),
+       DEF_DIV6P1("mmc0",  R8A7794_CLK_MMC0,  CLK_PLL1_DIV2, 0x240),
+};
+
+static const struct mssr_mod_clk r8a7794_mod_clks[] __initconst = {
+       DEF_MOD("msiof0",                  0,   R8A7794_CLK_MP),
+       DEF_MOD("vcp0",                  101,   R8A7794_CLK_ZS),
+       DEF_MOD("vpc0",                  103,   R8A7794_CLK_ZS),
+       DEF_MOD("jpu",                   106,   R8A7794_CLK_M2),
+       DEF_MOD("tmu1",                  111,   R8A7794_CLK_P),
+       DEF_MOD("3dg",                   112,   R8A7794_CLK_ZG),
+       DEF_MOD("2d-dmac",               115,   R8A7794_CLK_ZS),
+       DEF_MOD("fdp1-0",                119,   R8A7794_CLK_ZS),
+       DEF_MOD("tmu3",                  121,   R8A7794_CLK_P),
+       DEF_MOD("tmu2",                  122,   R8A7794_CLK_P),
+       DEF_MOD("cmt0",                  124,   R8A7794_CLK_R),
+       DEF_MOD("tmu0",                  125,   R8A7794_CLK_CP),
+       DEF_MOD("vsp1du0",               128,   R8A7794_CLK_ZS),
+       DEF_MOD("vsp1-sy",               131,   R8A7794_CLK_ZS),
+       DEF_MOD("scifa2",                202,   R8A7794_CLK_MP),
+       DEF_MOD("scifa1",                203,   R8A7794_CLK_MP),
+       DEF_MOD("scifa0",                204,   R8A7794_CLK_MP),
+       DEF_MOD("msiof2",                205,   R8A7794_CLK_MP),
+       DEF_MOD("scifb0",                206,   R8A7794_CLK_MP),
+       DEF_MOD("scifb1",                207,   R8A7794_CLK_MP),
+       DEF_MOD("msiof1",                208,   R8A7794_CLK_MP),
+       DEF_MOD("scifb2",                216,   R8A7794_CLK_MP),
+       DEF_MOD("sys-dmac1",             218,   R8A7794_CLK_ZS),
+       DEF_MOD("sys-dmac0",             219,   R8A7794_CLK_ZS),
+       DEF_MOD("tpu0",                  304,   R8A7794_CLK_CP),
+       DEF_MOD("sdhi3",                 311,   R8A7794_CLK_SD3),
+       DEF_MOD("sdhi2",                 312,   R8A7794_CLK_SD2),
+       DEF_MOD("sdhi0",                 314,   R8A7794_CLK_SD0),
+       DEF_MOD("mmcif0",                315,   R8A7794_CLK_MMC0),
+       DEF_MOD("iic0",                  318,   R8A7794_CLK_HP),
+       DEF_MOD("iic1",                  323,   R8A7794_CLK_HP),
+       DEF_MOD("cmt1",                  329,   R8A7794_CLK_R),
+       DEF_MOD("usbhs-dmac0",           330,   R8A7794_CLK_HP),
+       DEF_MOD("usbhs-dmac1",           331,   R8A7794_CLK_HP),
+       DEF_MOD("irqc",                  407,   R8A7794_CLK_CP),
+       DEF_MOD("intc-sys",              408,   R8A7794_CLK_ZS),
+       DEF_MOD("audio-dmac0",           502,   R8A7794_CLK_HP),
+       DEF_MOD("adsp_mod",              506,   R8A7794_CLK_ADSP),
+       DEF_MOD("pwm",                   523,   R8A7794_CLK_P),
+       DEF_MOD("usb-ehci",              703,   R8A7794_CLK_MP),
+       DEF_MOD("usbhs",                 704,   R8A7794_CLK_HP),
+       DEF_MOD("hscif2",                713,   R8A7794_CLK_ZS),
+       DEF_MOD("scif5",                 714,   R8A7794_CLK_P),
+       DEF_MOD("scif4",                 715,   R8A7794_CLK_P),
+       DEF_MOD("hscif1",                716,   R8A7794_CLK_ZS),
+       DEF_MOD("hscif0",                717,   R8A7794_CLK_ZS),
+       DEF_MOD("scif3",                 718,   R8A7794_CLK_P),
+       DEF_MOD("scif2",                 719,   R8A7794_CLK_P),
+       DEF_MOD("scif1",                 720,   R8A7794_CLK_P),
+       DEF_MOD("scif0",                 721,   R8A7794_CLK_P),
+       DEF_MOD("du1",                   723,   R8A7794_CLK_ZX),
+       DEF_MOD("du0",                   724,   R8A7794_CLK_ZX),
+       DEF_MOD("ipmmu-sgx",             800,   R8A7794_CLK_ZX),
+       DEF_MOD("mlb",                   802,   R8A7794_CLK_HP),
+       DEF_MOD("vin1",                  810,   R8A7794_CLK_ZG),
+       DEF_MOD("vin0",                  811,   R8A7794_CLK_ZG),
+       DEF_MOD("etheravb",              812,   R8A7794_CLK_HP),
+       DEF_MOD("ether",                 813,   R8A7794_CLK_P),
+       DEF_MOD("gyro-adc",              901,   R8A7794_CLK_P),
+       DEF_MOD("gpio6",                 905,   R8A7794_CLK_CP),
+       DEF_MOD("gpio5",                 907,   R8A7794_CLK_CP),
+       DEF_MOD("gpio4",                 908,   R8A7794_CLK_CP),
+       DEF_MOD("gpio3",                 909,   R8A7794_CLK_CP),
+       DEF_MOD("gpio2",                 910,   R8A7794_CLK_CP),
+       DEF_MOD("gpio1",                 911,   R8A7794_CLK_CP),
+       DEF_MOD("gpio0",                 912,   R8A7794_CLK_CP),
+       DEF_MOD("can1",                  915,   R8A7794_CLK_P),
+       DEF_MOD("can0",                  916,   R8A7794_CLK_P),
+       DEF_MOD("qspi_mod",              917,   R8A7794_CLK_QSPI),
+       DEF_MOD("i2c5",                  925,   R8A7794_CLK_HP),
+       DEF_MOD("i2c4",                  927,   R8A7794_CLK_HP),
+       DEF_MOD("i2c3",                  928,   R8A7794_CLK_HP),
+       DEF_MOD("i2c2",                  929,   R8A7794_CLK_HP),
+       DEF_MOD("i2c1",                  930,   R8A7794_CLK_HP),
+       DEF_MOD("i2c0",                  931,   R8A7794_CLK_HP),
+       DEF_MOD("ssi-all",              1005,   R8A7794_CLK_P),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A7794_CLK_P),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scifa3",               1106,   R8A7794_CLK_MP),
+       DEF_MOD("scifa4",               1107,   R8A7794_CLK_MP),
+       DEF_MOD("scifa5",               1108,   R8A7794_CLK_MP),
+};
+
+static const unsigned int r8a7794_crit_mod_clks[] __initconst = {
+       MOD_CLK_ID(408),        /* INTC-SYS (GIC) */
+};
+
+/*
+ * CPG Clock Data
+ */
+
+/*
+ *   MD                EXTAL           PLL0    PLL1    PLL3
+ * 14 13 19    (MHz)           *1      *2
+ *---------------------------------------------------
+ * 0  0  1     15              x200/3  x208/2  x88
+ * 0  1  1     20              x150/3  x156/2  x66
+ * 1  0  1     26 / 2          x230/3  x240/2  x102
+ * 1  1  1     30 / 2          x200/3  x208/2  x88
+ *
+ * *1 :        Table 7.5c indicates VCO output (PLL0 = VCO/3)
+ * *2 :        Table 7.5c indicates VCO output (PLL1 = VCO/2)
+ */
+#define CPG_PLL_CONFIG_INDEX(md)       ((((md) & BIT(14)) >> 13) | \
+                                        (((md) & BIT(13)) >> 13))
+static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[4] __initconst = {
+       { 1, 208,  88, 200 },
+       { 1, 156,  66, 150 },
+       { 2, 240, 102, 230 },
+       { 2, 208,  88, 200 },
+};
+
+static int __init r8a7794_cpg_mssr_init(struct device *dev)
+{
+       const struct rcar_gen2_cpg_pll_config *cpg_pll_config;
+       u32 cpg_mode;
+       int error;
+
+       error = rcar_rst_read_mode_pins(&cpg_mode);
+       if (error)
+               return error;
+
+       cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
+
+       return rcar_gen2_cpg_init(cpg_pll_config, 3, cpg_mode);
+}
+
+const struct cpg_mssr_info r8a7794_cpg_mssr_info __initconst = {
+       /* Core Clocks */
+       .core_clks = r8a7794_core_clks,
+       .num_core_clks = ARRAY_SIZE(r8a7794_core_clks),
+       .last_dt_core_clk = LAST_DT_CORE_CLK,
+       .num_total_core_clks = MOD_CLK_BASE,
+
+       /* Module Clocks */
+       .mod_clks = r8a7794_mod_clks,
+       .num_mod_clks = ARRAY_SIZE(r8a7794_mod_clks),
+       .num_hw_mod_clks = 12 * 32,
+
+       /* Critical Module Clocks */
+       .crit_mod_clks = r8a7794_crit_mod_clks,
+       .num_crit_mod_clks = ARRAY_SIZE(r8a7794_crit_mod_clks),
+
+       /* Callbacks */
+       .init = r8a7794_cpg_mssr_init,
+       .cpg_clk_register = rcar_gen2_cpg_clk_register,
+};
index eaa98b488f015944c847274d7430205ec3cdf4a0..c091a8e024b88d32d09fa37be491016cbbf314a7 100644 (file)
@@ -141,8 +141,10 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
        DEF_MOD("sdif0",                 314,   R8A7795_CLK_SD0),
        DEF_MOD("pcie1",                 318,   R8A7795_CLK_S3D1),
        DEF_MOD("pcie0",                 319,   R8A7795_CLK_S3D1),
+       DEF_MOD("usb-dmac30",            326,   R8A7795_CLK_S3D1),
        DEF_MOD("usb3-if1",              327,   R8A7795_CLK_S3D1), /* ES1.x */
        DEF_MOD("usb3-if0",              328,   R8A7795_CLK_S3D1),
+       DEF_MOD("usb-dmac31",            329,   R8A7795_CLK_S3D1),
        DEF_MOD("usb-dmac0",             330,   R8A7795_CLK_S3D1),
        DEF_MOD("usb-dmac1",             331,   R8A7795_CLK_S3D1),
        DEF_MOD("rwdt",                  402,   R8A7795_CLK_R),
@@ -164,7 +166,7 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
        DEF_MOD("hscif1",                519,   R8A7795_CLK_S3D1),
        DEF_MOD("hscif0",                520,   R8A7795_CLK_S3D1),
        DEF_MOD("thermal",               522,   R8A7795_CLK_CP),
-       DEF_MOD("pwm",                   523,   R8A7795_CLK_S3D4),
+       DEF_MOD("pwm",                   523,   R8A7795_CLK_S0D12),
        DEF_MOD("fcpvd3",                600,   R8A7795_CLK_S2D1), /* ES1.x */
        DEF_MOD("fcpvd2",                601,   R8A7795_CLK_S0D2),
        DEF_MOD("fcpvd1",                602,   R8A7795_CLK_S0D2),
@@ -189,10 +191,12 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
        DEF_MOD("vspi2",                 629,   R8A7795_CLK_S2D1), /* ES1.x */
        DEF_MOD("vspi1",                 630,   R8A7795_CLK_S0D1),
        DEF_MOD("vspi0",                 631,   R8A7795_CLK_S0D1),
+       DEF_MOD("ehci3",                 700,   R8A7795_CLK_S3D4),
        DEF_MOD("ehci2",                 701,   R8A7795_CLK_S3D4),
        DEF_MOD("ehci1",                 702,   R8A7795_CLK_S3D4),
        DEF_MOD("ehci0",                 703,   R8A7795_CLK_S3D4),
        DEF_MOD("hsusb",                 704,   R8A7795_CLK_S3D4),
+       DEF_MOD("hsusb3",                705,   R8A7795_CLK_S3D4),
        DEF_MOD("csi21",                 713,   R8A7795_CLK_CSI0), /* ES1.x */
        DEF_MOD("csi20",                 714,   R8A7795_CLK_CSI0),
        DEF_MOD("csi41",                 715,   R8A7795_CLK_CSI0),
@@ -218,22 +222,22 @@ static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
        DEF_MOD("imr2",                  821,   R8A7795_CLK_S0D2),
        DEF_MOD("imr1",                  822,   R8A7795_CLK_S0D2),
        DEF_MOD("imr0",                  823,   R8A7795_CLK_S0D2),
-       DEF_MOD("gpio7",                 905,   R8A7795_CLK_CP),
-       DEF_MOD("gpio6",                 906,   R8A7795_CLK_CP),
-       DEF_MOD("gpio5",                 907,   R8A7795_CLK_CP),
-       DEF_MOD("gpio4",                 908,   R8A7795_CLK_CP),
-       DEF_MOD("gpio3",                 909,   R8A7795_CLK_CP),
-       DEF_MOD("gpio2",                 910,   R8A7795_CLK_CP),
-       DEF_MOD("gpio1",                 911,   R8A7795_CLK_CP),
-       DEF_MOD("gpio0",                 912,   R8A7795_CLK_CP),
+       DEF_MOD("gpio7",                 905,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio6",                 906,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio5",                 907,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio4",                 908,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio3",                 909,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio2",                 910,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio1",                 911,   R8A7795_CLK_S3D4),
+       DEF_MOD("gpio0",                 912,   R8A7795_CLK_S3D4),
        DEF_MOD("can-fd",                914,   R8A7795_CLK_S3D2),
        DEF_MOD("can-if1",               915,   R8A7795_CLK_S3D4),
        DEF_MOD("can-if0",               916,   R8A7795_CLK_S3D4),
-       DEF_MOD("i2c6",                  918,   R8A7795_CLK_S3D2),
-       DEF_MOD("i2c5",                  919,   R8A7795_CLK_S3D2),
+       DEF_MOD("i2c6",                  918,   R8A7795_CLK_S0D6),
+       DEF_MOD("i2c5",                  919,   R8A7795_CLK_S0D6),
        DEF_MOD("i2c-dvfs",              926,   R8A7795_CLK_CP),
-       DEF_MOD("i2c4",                  927,   R8A7795_CLK_S3D2),
-       DEF_MOD("i2c3",                  928,   R8A7795_CLK_S3D2),
+       DEF_MOD("i2c4",                  927,   R8A7795_CLK_S0D6),
+       DEF_MOD("i2c3",                  928,   R8A7795_CLK_S0D6),
        DEF_MOD("i2c2",                  929,   R8A7795_CLK_S3D2),
        DEF_MOD("i2c1",                  930,   R8A7795_CLK_S3D2),
        DEF_MOD("i2c0",                  931,   R8A7795_CLK_S3D2),
@@ -346,6 +350,7 @@ static const struct mssr_mod_reparent r8a7795es1_mod_reparent[] __initconst = {
        { MOD_CLK_ID(219), R8A7795_CLK_S3D1 },  /* SYS-DMAC0 */
        { MOD_CLK_ID(501), R8A7795_CLK_S3D1 },  /* AUDMAC1 */
        { MOD_CLK_ID(502), R8A7795_CLK_S3D1 },  /* AUDMAC0 */
+       { MOD_CLK_ID(523), R8A7795_CLK_S3D4 },  /* PWM */
        { MOD_CLK_ID(601), R8A7795_CLK_S2D1 },  /* FCPVD2 */
        { MOD_CLK_ID(602), R8A7795_CLK_S2D1 },  /* FCPVD1 */
        { MOD_CLK_ID(603), R8A7795_CLK_S2D1 },  /* FCPVD0 */
@@ -376,6 +381,18 @@ static const struct mssr_mod_reparent r8a7795es1_mod_reparent[] __initconst = {
        { MOD_CLK_ID(821), R8A7795_CLK_S2D1 },  /* IMR2 */
        { MOD_CLK_ID(822), R8A7795_CLK_S2D1 },  /* IMR1 */
        { MOD_CLK_ID(823), R8A7795_CLK_S2D1 },  /* IMR0 */
+       { MOD_CLK_ID(905), R8A7795_CLK_CP },    /* GPIO7 */
+       { MOD_CLK_ID(906), R8A7795_CLK_CP },    /* GPIO6 */
+       { MOD_CLK_ID(907), R8A7795_CLK_CP },    /* GPIO5 */
+       { MOD_CLK_ID(908), R8A7795_CLK_CP },    /* GPIO4 */
+       { MOD_CLK_ID(909), R8A7795_CLK_CP },    /* GPIO3 */
+       { MOD_CLK_ID(910), R8A7795_CLK_CP },    /* GPIO2 */
+       { MOD_CLK_ID(911), R8A7795_CLK_CP },    /* GPIO1 */
+       { MOD_CLK_ID(912), R8A7795_CLK_CP },    /* GPIO0 */
+       { MOD_CLK_ID(918), R8A7795_CLK_S3D2 },  /* I2C6 */
+       { MOD_CLK_ID(919), R8A7795_CLK_S3D2 },  /* I2C5 */
+       { MOD_CLK_ID(927), R8A7795_CLK_S3D2 },  /* I2C4 */
+       { MOD_CLK_ID(928), R8A7795_CLK_S3D2 },  /* I2C3 */
 };
 
 
index 9d114b31b0731b5ec691717a8519bc8ba2614218..acc6d0f153e1b233b9bd9a6293648d4a50b0ba07 100644 (file)
@@ -106,6 +106,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
        DEF_DIV6P1("canfd",     R8A7796_CLK_CANFD, CLK_PLL1_DIV4, 0x244),
        DEF_DIV6P1("csi0",      R8A7796_CLK_CSI0,  CLK_PLL1_DIV4, 0x00c),
        DEF_DIV6P1("mso",       R8A7796_CLK_MSO,   CLK_PLL1_DIV4, 0x014),
+       DEF_DIV6P1("hdmi",      R8A7796_CLK_HDMI,  CLK_PLL1_DIV4, 0x250),
 
        DEF_DIV6_RO("osc",      R8A7796_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
        DEF_DIV6_RO("r_int",    CLK_RINT,          CLK_EXTAL, CPG_RCKCR, 32),
@@ -135,8 +136,15 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
        DEF_MOD("sdif2",                 312,   R8A7796_CLK_SD2),
        DEF_MOD("sdif1",                 313,   R8A7796_CLK_SD1),
        DEF_MOD("sdif0",                 314,   R8A7796_CLK_SD0),
+       DEF_MOD("pcie1",                 318,   R8A7796_CLK_S3D1),
+       DEF_MOD("pcie0",                 319,   R8A7796_CLK_S3D1),
+       DEF_MOD("usb-dmac0",             330,   R8A7796_CLK_S3D1),
+       DEF_MOD("usb-dmac1",             331,   R8A7796_CLK_S3D1),
        DEF_MOD("rwdt",                  402,   R8A7796_CLK_R),
+       DEF_MOD("intc-ex",               407,   R8A7796_CLK_CP),
        DEF_MOD("intc-ap",               408,   R8A7796_CLK_S3D1),
+       DEF_MOD("audmac1",               501,   R8A7796_CLK_S0D3),
+       DEF_MOD("audmac0",               502,   R8A7796_CLK_S0D3),
        DEF_MOD("drif7",                 508,   R8A7796_CLK_S3D2),
        DEF_MOD("drif6",                 509,   R8A7796_CLK_S3D2),
        DEF_MOD("drif5",                 510,   R8A7796_CLK_S3D2),
@@ -151,6 +159,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
        DEF_MOD("hscif1",                519,   R8A7796_CLK_S3D1),
        DEF_MOD("hscif0",                520,   R8A7796_CLK_S3D1),
        DEF_MOD("thermal",               522,   R8A7796_CLK_CP),
+       DEF_MOD("pwm",                   523,   R8A7796_CLK_S0D12),
        DEF_MOD("fcpvd2",                601,   R8A7796_CLK_S0D2),
        DEF_MOD("fcpvd1",                602,   R8A7796_CLK_S0D2),
        DEF_MOD("fcpvd0",                603,   R8A7796_CLK_S0D2),
@@ -164,12 +173,16 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
        DEF_MOD("vspd0",                 623,   R8A7796_CLK_S0D2),
        DEF_MOD("vspb",                  626,   R8A7796_CLK_S0D1),
        DEF_MOD("vspi0",                 631,   R8A7796_CLK_S0D1),
+       DEF_MOD("ehci1",                 702,   R8A7796_CLK_S3D4),
+       DEF_MOD("ehci0",                 703,   R8A7796_CLK_S3D4),
+       DEF_MOD("hsusb",                 704,   R8A7796_CLK_S3D4),
        DEF_MOD("csi20",                 714,   R8A7796_CLK_CSI0),
        DEF_MOD("csi40",                 716,   R8A7796_CLK_CSI0),
        DEF_MOD("du2",                   722,   R8A7796_CLK_S2D1),
        DEF_MOD("du1",                   723,   R8A7796_CLK_S2D1),
        DEF_MOD("du0",                   724,   R8A7796_CLK_S2D1),
        DEF_MOD("lvds",                  727,   R8A7796_CLK_S2D1),
+       DEF_MOD("hdmi0",                 729,   R8A7796_CLK_HDMI),
        DEF_MOD("vin7",                  804,   R8A7796_CLK_S0D2),
        DEF_MOD("vin6",                  805,   R8A7796_CLK_S0D2),
        DEF_MOD("vin5",                  806,   R8A7796_CLK_S0D2),
@@ -200,6 +213,32 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
        DEF_MOD("i2c2",                  929,   R8A7796_CLK_S3D2),
        DEF_MOD("i2c1",                  930,   R8A7796_CLK_S3D2),
        DEF_MOD("i2c0",                  931,   R8A7796_CLK_S3D2),
+       DEF_MOD("ssi-all",              1005,   R8A7796_CLK_S3D4),
+       DEF_MOD("ssi9",                 1006,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi8",                 1007,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi7",                 1008,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi6",                 1009,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi5",                 1010,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi4",                 1011,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi3",                 1012,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi2",                 1013,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi1",                 1014,   MOD_CLK_ID(1005)),
+       DEF_MOD("ssi0",                 1015,   MOD_CLK_ID(1005)),
+       DEF_MOD("scu-all",              1017,   R8A7796_CLK_S3D4),
+       DEF_MOD("scu-dvc1",             1018,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-dvc0",             1019,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu1-mix1",        1020,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-ctu0-mix0",        1021,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src9",             1022,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src8",             1023,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src7",             1024,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src6",             1025,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src5",             1026,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src4",             1027,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src3",             1028,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src2",             1029,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src1",             1030,   MOD_CLK_ID(1017)),
+       DEF_MOD("scu-src0",             1031,   MOD_CLK_ID(1017)),
 };
 
 static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
index 99eeec6f24ec6c6b29b60de7ad4c5644b37630d4..1f607c806f9b9ec3a13b370368ce302550c5787c 100644 (file)
@@ -257,7 +257,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
                                              const struct cpg_mssr_info *info,
                                              struct cpg_mssr_priv *priv)
 {
-       struct clk *clk = NULL, *parent;
+       struct clk *clk = ERR_PTR(-ENOTSUPP), *parent;
        struct device *dev = priv->dev;
        unsigned int id = core->id, div = core->div;
        const char *parent_name;
@@ -477,7 +477,7 @@ fail_put:
 
 void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev)
 {
-       if (!list_empty(&dev->power.subsys_data->clock_list))
+       if (!pm_clk_no_clocks(dev))
                pm_clk_destroy(dev);
 }
 
@@ -627,25 +627,54 @@ static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
 
 
 static const struct of_device_id cpg_mssr_match[] = {
-#ifdef CONFIG_ARCH_R8A7743
+#ifdef CONFIG_CLK_R8A7743
        {
                .compatible = "renesas,r8a7743-cpg-mssr",
                .data = &r8a7743_cpg_mssr_info,
        },
 #endif
-#ifdef CONFIG_ARCH_R8A7745
+#ifdef CONFIG_CLK_R8A7745
        {
                .compatible = "renesas,r8a7745-cpg-mssr",
                .data = &r8a7745_cpg_mssr_info,
        },
 #endif
-#ifdef CONFIG_ARCH_R8A7795
+#ifdef CONFIG_CLK_R8A7790
+       {
+               .compatible = "renesas,r8a7790-cpg-mssr",
+               .data = &r8a7790_cpg_mssr_info,
+       },
+#endif
+#ifdef CONFIG_CLK_R8A7791
+       {
+               .compatible = "renesas,r8a7791-cpg-mssr",
+               .data = &r8a7791_cpg_mssr_info,
+       },
+       /* R-Car M2-N is (almost) identical to R-Car M2-W w.r.t. clocks. */
+       {
+               .compatible = "renesas,r8a7793-cpg-mssr",
+               .data = &r8a7791_cpg_mssr_info,
+       },
+#endif
+#ifdef CONFIG_CLK_R8A7792
+       {
+               .compatible = "renesas,r8a7792-cpg-mssr",
+               .data = &r8a7792_cpg_mssr_info,
+       },
+#endif
+#ifdef CONFIG_CLK_R8A7794
+       {
+               .compatible = "renesas,r8a7794-cpg-mssr",
+               .data = &r8a7794_cpg_mssr_info,
+       },
+#endif
+#ifdef CONFIG_CLK_R8A7795
        {
                .compatible = "renesas,r8a7795-cpg-mssr",
                .data = &r8a7795_cpg_mssr_info,
        },
 #endif
-#ifdef CONFIG_ARCH_R8A7796
+#ifdef CONFIG_CLK_R8A7796
        {
                .compatible = "renesas,r8a7796-cpg-mssr",
                .data = &r8a7796_cpg_mssr_info,
@@ -670,7 +699,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
        struct clk **clks;
        int error;
 
-       info = of_match_node(cpg_mssr_match, np)->data;
+       info = of_device_get_match_data(dev);
        if (info->init) {
                error = info->init(dev);
                if (error)
index 148f4f0aa2a487b05da154fcde6e7d626bdd58fc..43d7c7f6832df0b2e0b3aae788fb71beba122671 100644 (file)
@@ -132,6 +132,10 @@ struct cpg_mssr_info {
 
 extern const struct cpg_mssr_info r8a7743_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7745_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a7790_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a7791_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a7792_cpg_mssr_info;
+extern const struct cpg_mssr_info r8a7794_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
 extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
 
index 26b220c988b29cd74104b46bc5598701b79565c4..6f19826cc4473ee2d65f39ead8d8611d5c178108 100644 (file)
@@ -14,6 +14,7 @@ obj-$(CONFIG_RESET_CONTROLLER)        += softrst.o
 
 obj-y  += clk-rv1108.o
 obj-y  += clk-rk3036.o
+obj-y  += clk-rk3128.o
 obj-y  += clk-rk3188.o
 obj-y  += clk-rk3228.o
 obj-y  += clk-rk3288.o
index 00d4150e33c37434c056ba27867db908d6117bdf..c3001980dbdc50fd0201db64cc958a1fc8b02d47 100644 (file)
@@ -436,6 +436,7 @@ static const char *const rk3036_critical_clocks[] __initconst = {
        "aclk_peri",
        "hclk_peri",
        "pclk_peri",
+       "pclk_ddrupctl",
 };
 
 static void __init rk3036_clk_init(struct device_node *np)
diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c
new file mode 100644 (file)
index 0000000..e243f2e
--- /dev/null
@@ -0,0 +1,612 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rk3128-cru.h>
+#include "clk.h"
+
+#define RK3128_GRF_SOC_STATUS0 0x14c
+
+enum rk3128_plls {
+       apll, dpll, cpll, gpll,
+};
+
+static struct rockchip_pll_rate_table rk3128_pll_rates[] = {
+       /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+       RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+       RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+       RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+       RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
+       RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+       RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
+       RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+       RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0),
+       RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
+       RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
+       RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
+       RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+       RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
+       RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0),
+       RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0),
+       RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
+       RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+       RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0),
+       RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
+       RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+       RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0),
+       RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+       RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0),
+       { /* sentinel */ },
+};
+
+#define RK3128_DIV_CPU_MASK            0x1f
+#define RK3128_DIV_CPU_SHIFT           8
+
+#define RK3128_DIV_PERI_MASK           0xf
+#define RK3128_DIV_PERI_SHIFT          0
+#define RK3128_DIV_ACLK_MASK           0x7
+#define RK3128_DIV_ACLK_SHIFT          4
+#define RK3128_DIV_HCLK_MASK           0x3
+#define RK3128_DIV_HCLK_SHIFT          8
+#define RK3128_DIV_PCLK_MASK           0x7
+#define RK3128_DIV_PCLK_SHIFT          12
+
+#define RK3128_CLKSEL1(_core_aclk_div, _pclk_dbg_div)                  \
+{                                                                      \
+       .reg = RK2928_CLKSEL_CON(1),                                    \
+       .val = HIWORD_UPDATE(_pclk_dbg_div, RK3128_DIV_PERI_MASK,       \
+                            RK3128_DIV_PERI_SHIFT) |                   \
+              HIWORD_UPDATE(_core_aclk_div, RK3128_DIV_ACLK_MASK,      \
+                            RK3128_DIV_ACLK_SHIFT),                    \
+}
+
+#define RK3128_CPUCLK_RATE(_prate, _core_aclk_div, _pclk_dbg_div)      \
+{                                                                      \
+       .prate = _prate,                                                \
+       .divs = {                                                       \
+               RK3128_CLKSEL1(_core_aclk_div, _pclk_dbg_div),          \
+       },                                                              \
+}
+
+static struct rockchip_cpuclk_rate_table rk3128_cpuclk_rates[] __initdata = {
+       RK3128_CPUCLK_RATE(1800000000, 1, 7),
+       RK3128_CPUCLK_RATE(1704000000, 1, 7),
+       RK3128_CPUCLK_RATE(1608000000, 1, 7),
+       RK3128_CPUCLK_RATE(1512000000, 1, 7),
+       RK3128_CPUCLK_RATE(1488000000, 1, 5),
+       RK3128_CPUCLK_RATE(1416000000, 1, 5),
+       RK3128_CPUCLK_RATE(1392000000, 1, 5),
+       RK3128_CPUCLK_RATE(1296000000, 1, 5),
+       RK3128_CPUCLK_RATE(1200000000, 1, 5),
+       RK3128_CPUCLK_RATE(1104000000, 1, 5),
+       RK3128_CPUCLK_RATE(1008000000, 1, 5),
+       RK3128_CPUCLK_RATE(912000000, 1, 5),
+       RK3128_CPUCLK_RATE(816000000, 1, 3),
+       RK3128_CPUCLK_RATE(696000000, 1, 3),
+       RK3128_CPUCLK_RATE(600000000, 1, 3),
+       RK3128_CPUCLK_RATE(408000000, 1, 1),
+       RK3128_CPUCLK_RATE(312000000, 1, 1),
+       RK3128_CPUCLK_RATE(216000000,  1, 1),
+       RK3128_CPUCLK_RATE(96000000, 1, 1),
+};
+
+static const struct rockchip_cpuclk_reg_data rk3128_cpuclk_data = {
+       .core_reg = RK2928_CLKSEL_CON(0),
+       .div_core_shift = 0,
+       .div_core_mask = 0x1f,
+       .mux_core_alt = 1,
+       .mux_core_main = 0,
+       .mux_core_shift = 7,
+       .mux_core_mask = 0x1,
+};
+
+PNAME(mux_pll_p)               = { "clk_24m", "xin24m" };
+
+PNAME(mux_ddrphy_p)            = { "dpll_ddr", "gpll_div2_ddr" };
+PNAME(mux_armclk_p)            = { "apll_core", "gpll_div2_core" };
+PNAME(mux_usb480m_p)           = { "usb480m_phy", "xin24m" };
+PNAME(mux_aclk_cpu_src_p)      = { "cpll", "gpll", "gpll_div2", "gpll_div3" };
+
+PNAME(mux_pll_src_5plls_p)     = { "cpll", "gpll", "gpll_div2", "gpll_div3", "usb480m" };
+PNAME(mux_pll_src_4plls_p)     = { "cpll", "gpll", "gpll_div2", "usb480m" };
+PNAME(mux_pll_src_3plls_p)     = { "cpll", "gpll", "gpll_div2" };
+
+PNAME(mux_aclk_peri_src_p)     = { "gpll_peri", "cpll_peri", "gpll_div2_peri", "gpll_div3_peri" };
+PNAME(mux_mmc_src_p)           = { "cpll", "gpll", "gpll_div2", "xin24m" };
+PNAME(mux_clk_cif_out_src_p)           = { "clk_cif_src", "xin24m" };
+PNAME(mux_sclk_vop_src_p)      = { "cpll", "gpll", "gpll_div2", "gpll_div3" };
+
+PNAME(mux_i2s0_p)              = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" };
+PNAME(mux_i2s1_pre_p)          = { "i2s1_src", "i2s1_frac", "ext_i2s", "xin12m" };
+PNAME(mux_i2s_out_p)           = { "i2s1_pre", "xin12m" };
+PNAME(mux_sclk_spdif_p)                = { "sclk_spdif_src", "spdif_frac", "xin12m" };
+
+PNAME(mux_uart0_p)             = { "uart0_src", "uart0_frac", "xin24m" };
+PNAME(mux_uart1_p)             = { "uart1_src", "uart1_frac", "xin24m" };
+PNAME(mux_uart2_p)             = { "uart2_src", "uart2_frac", "xin24m" };
+
+PNAME(mux_sclk_gmac_p) = { "sclk_gmac_src", "gmac_clkin" };
+PNAME(mux_sclk_sfc_src_p)      = { "cpll", "gpll", "gpll_div2", "xin24m" };
+
+static struct rockchip_pll_clock rk3128_pll_clks[] __initdata = {
+       [apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
+                    RK2928_MODE_CON, 0, 1, 0, rk3128_pll_rates),
+       [dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
+                    RK2928_MODE_CON, 4, 0, 0, NULL),
+       [cpll] = PLL(pll_rk3036, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8),
+                    RK2928_MODE_CON, 8, 2, 0, rk3128_pll_rates),
+       [gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
+                    RK2928_MODE_CON, 12, 3, ROCKCHIP_PLL_SYNC_RATE, rk3128_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rk3128_i2s0_fracmux __initdata =
+       MUX(0, "i2s0_pre", mux_i2s0_p, CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(9), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3128_i2s1_fracmux __initdata =
+       MUX(0, "i2s1_pre", mux_i2s1_pre_p, CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(3), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3128_spdif_fracmux __initdata =
+       MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(6), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3128_uart0_fracmux __initdata =
+       MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(13), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3128_uart1_fracmux __initdata =
+       MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(14), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3128_uart2_fracmux __initdata =
+       MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = {
+       /*
+        * Clock-Architecture Diagram 1
+        */
+
+       FACTOR(PLL_GPLL_DIV2, "gpll_div2", "gpll", 0, 1, 2),
+       FACTOR(PLL_GPLL_DIV3, "gpll_div3", "gpll", 0, 1, 3),
+
+       DIV(0, "clk_24m", "xin24m", CLK_IGNORE_UNUSED,
+                       RK2928_CLKSEL_CON(4), 8, 5, DFLAGS),
+
+       /* PD_DDR */
+       GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(0), 2, GFLAGS),
+       GATE(0, "gpll_div2_ddr", "gpll_div2", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(0), 2, GFLAGS),
+       COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+                       RK2928_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+       FACTOR(SCLK_DDRC, "clk_ddrc", "ddrphy2x", 0, 1, 2),
+       FACTOR(0, "clk_ddrphy", "ddrphy2x", 0, 1, 2),
+
+       /* PD_CORE */
+       GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(0), 6, GFLAGS),
+       GATE(0, "gpll_div2_core", "gpll_div2", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(0), 6, GFLAGS),
+       COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
+                       RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK2928_CLKGATE_CON(0), 0, GFLAGS),
+       COMPOSITE_NOMUX(0, "armcore", "armclk", CLK_IGNORE_UNUSED,
+                       RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+                       RK2928_CLKGATE_CON(0), 7, GFLAGS),
+
+       /* PD_MISC */
+       MUX(SCLK_USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
+                       RK2928_MISC_CON, 15, 1, MFLAGS),
+
+       /* PD_CPU */
+       COMPOSITE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0,
+                       RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(0), 1, GFLAGS),
+       GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0,
+                       RK2928_CLKGATE_CON(0), 3, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0,
+                       RK2928_CLKSEL_CON(1), 8, 2, DFLAGS,
+                       RK2928_CLKGATE_CON(0), 4, GFLAGS),
+       COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_src", 0,
+                       RK2928_CLKSEL_CON(1), 12, 2, DFLAGS,
+                       RK2928_CLKGATE_CON(0), 5, GFLAGS),
+       COMPOSITE_NOMUX(SCLK_CRYPTO, "clk_crypto", "aclk_cpu_src", 0,
+                       RK2928_CLKSEL_CON(24), 0, 2, DFLAGS,
+                       RK2928_CLKGATE_CON(0), 12, GFLAGS),
+
+       /* PD_VIDEO */
+       COMPOSITE(ACLK_VEPU, "aclk_vepu", mux_pll_src_5plls_p, 0,
+                       RK2928_CLKSEL_CON(32), 5, 3, MFLAGS, 0, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 9, GFLAGS),
+       FACTOR(HCLK_VEPU, "hclk_vepu", "aclk_vepu", 0, 1, 4),
+
+       COMPOSITE(ACLK_VDPU, "aclk_vdpu", mux_pll_src_5plls_p, 0,
+                       RK2928_CLKSEL_CON(32), 13, 3, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 11, GFLAGS),
+       FACTOR_GATE(HCLK_VDPU, "hclk_vdpu", "aclk_vdpu", 0, 1, 4,
+                       RK2928_CLKGATE_CON(3), 12, GFLAGS),
+
+       COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_5plls_p, 0,
+                       RK2928_CLKSEL_CON(34), 13, 3, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 10, GFLAGS),
+
+       /* PD_VIO */
+       COMPOSITE(ACLK_VIO0, "aclk_vio0", mux_pll_src_5plls_p, 0,
+                       RK2928_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 0, GFLAGS),
+       COMPOSITE(ACLK_VIO1, "aclk_vio1", mux_pll_src_5plls_p, 0,
+                       RK2928_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 4, GFLAGS),
+       COMPOSITE(HCLK_VIO, "hclk_vio", mux_pll_src_4plls_p, 0,
+                       RK2928_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(0), 11, GFLAGS),
+
+       /* PD_PERI */
+       GATE(0, "gpll_peri", "gpll", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(0, "cpll_peri", "cpll", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(0, "gpll_div2_peri", "gpll_div2", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(2), 0, GFLAGS),
+       GATE(0, "gpll_div3_peri", "gpll_div3", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(2), 0, GFLAGS),
+       COMPOSITE_NOGATE(0, "aclk_peri_src", mux_aclk_peri_src_p, 0,
+                       RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS),
+       COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0,
+                       RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+                       RK2928_CLKGATE_CON(2), 3, GFLAGS),
+       COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0,
+                       RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+                       RK2928_CLKGATE_CON(2), 2, GFLAGS),
+       GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
+                       RK2928_CLKGATE_CON(2), 1, GFLAGS),
+
+       GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 3, GFLAGS),
+       GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 4, GFLAGS),
+       GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 5, GFLAGS),
+       GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 6, GFLAGS),
+       GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 7, GFLAGS),
+       GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 8, GFLAGS),
+
+       GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 8, GFLAGS),
+       GATE(SCLK_PVTM_GPU, "clk_pvtm_gpu", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 8, GFLAGS),
+       GATE(SCLK_PVTM_FUNC, "clk_pvtm_func", "xin24m", 0,
+                       RK2928_CLKGATE_CON(10), 8, GFLAGS),
+       GATE(SCLK_MIPI_24M, "clk_mipi_24m", "xin24m", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(10), 8, GFLAGS),
+
+       COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0,
+                       RK2928_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 6, DFLAGS,
+                       RK2928_CLKGATE_CON(2), 11, GFLAGS),
+
+       COMPOSITE(SCLK_SDIO, "sclk_sdio", mux_mmc_src_p, 0,
+                       RK2928_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 6, DFLAGS,
+                       RK2928_CLKGATE_CON(2), 13, GFLAGS),
+
+       COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
+                       RK2928_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 6, DFLAGS,
+                       RK2928_CLKGATE_CON(2), 14, GFLAGS),
+
+       DIV(SCLK_PVTM, "clk_pvtm", "clk_pvtm_func", 0,
+                       RK2928_CLKSEL_CON(2), 0, 7, DFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 2
+        */
+       COMPOSITE(DCLK_VOP, "dclk_vop", mux_sclk_vop_src_p, 0,
+                       RK2928_CLKSEL_CON(27), 0, 2, MFLAGS, 8, 8, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 1, GFLAGS),
+       COMPOSITE(SCLK_VOP, "sclk_vop", mux_sclk_vop_src_p, 0,
+                       RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 2, GFLAGS),
+       COMPOSITE(DCLK_EBC, "dclk_ebc", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(23), 0, 2, MFLAGS, 8, 8, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 4, GFLAGS),
+
+       FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+
+       COMPOSITE_NODIV(SCLK_CIF_SRC, "sclk_cif_src", mux_pll_src_4plls_p, 0,
+                       RK2928_CLKSEL_CON(29), 0, 2, MFLAGS,
+                       RK2928_CLKGATE_CON(3), 7, GFLAGS),
+       MUX(SCLK_CIF_OUT_SRC, "sclk_cif_out_src", mux_clk_cif_out_src_p, 0,
+                       RK2928_CLKSEL_CON(13), 14, 2, MFLAGS),
+       DIV(SCLK_CIF_OUT, "sclk_cif_out", "sclk_cif_out_src", 0,
+                       RK2928_CLKSEL_CON(29), 2, 5, DFLAGS),
+
+       COMPOSITE(0, "i2s0_src", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(9), 14, 2, MFLAGS, 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(4), 4, GFLAGS),
+       COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(8), 0,
+                       RK2928_CLKGATE_CON(4), 5, GFLAGS,
+                       &rk3128_i2s0_fracmux),
+       GATE(SCLK_I2S0, "sclk_i2s0", "i2s0_pre", CLK_SET_RATE_PARENT,
+                       RK2928_CLKGATE_CON(4), 6, GFLAGS),
+
+       COMPOSITE(0, "i2s1_src", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(0), 9, GFLAGS),
+       COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(7), 0,
+                       RK2928_CLKGATE_CON(0), 10, GFLAGS,
+                       &rk3128_i2s1_fracmux),
+       GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT,
+                       RK2928_CLKGATE_CON(0), 14, GFLAGS),
+       COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_out", mux_i2s_out_p, 0,
+                       RK2928_CLKSEL_CON(3), 12, 1, MFLAGS,
+                       RK2928_CLKGATE_CON(0), 13, GFLAGS),
+
+       COMPOSITE(0, "sclk_spdif_src", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(6), 14, 2, MFLAGS, 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(2), 10, GFLAGS),
+       COMPOSITE_FRACMUX(0, "spdif_frac", "sclk_spdif_src", CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(20), 0,
+                       RK2928_CLKGATE_CON(2), 12, GFLAGS,
+                       &rk3128_spdif_fracmux),
+
+       GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED,
+                       RK2928_CLKGATE_CON(1), 3, GFLAGS),
+
+       GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin12m", 0,
+                       RK2928_CLKGATE_CON(1), 5, GFLAGS),
+       GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin12m", 0,
+                       RK2928_CLKGATE_CON(1), 6, GFLAGS),
+
+       COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0,
+                       RK2928_CLKSEL_CON(24), 8, 8, DFLAGS,
+                       RK2928_CLKGATE_CON(2), 8, GFLAGS),
+
+       COMPOSITE(ACLK_GPU, "aclk_gpu", mux_pll_src_5plls_p, 0,
+                       RK2928_CLKSEL_CON(34), 5, 3, MFLAGS, 0, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 13, GFLAGS),
+
+       COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(2), 9, GFLAGS),
+
+       /* PD_UART */
+       COMPOSITE(0, "uart0_src", mux_pll_src_4plls_p, 0,
+                       RK2928_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 8, GFLAGS),
+       MUX(0, "uart12_src", mux_pll_src_4plls_p, 0,
+                       RK2928_CLKSEL_CON(13), 14, 2, MFLAGS),
+       COMPOSITE_NOMUX(0, "uart1_src", "uart12_src", 0,
+                       RK2928_CLKSEL_CON(14), 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 10, GFLAGS),
+       COMPOSITE_NOMUX(0, "uart2_src", "uart12_src", 0,
+                       RK2928_CLKSEL_CON(15), 0, 7, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 13, GFLAGS),
+       COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(17), 0,
+                       RK2928_CLKGATE_CON(1), 9, GFLAGS,
+                       &rk3128_uart0_fracmux),
+       COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(18), 0,
+                       RK2928_CLKGATE_CON(1), 11, GFLAGS,
+                       &rk3128_uart1_fracmux),
+       COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
+                       RK2928_CLKSEL_CON(19), 0,
+                       RK2928_CLKGATE_CON(1), 13, GFLAGS,
+                       &rk3128_uart2_fracmux),
+
+       COMPOSITE(SCLK_MAC_SRC, "sclk_gmac_src", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 7, GFLAGS),
+       MUX(SCLK_MAC, "sclk_gmac", mux_sclk_gmac_p, 0,
+                       RK2928_CLKSEL_CON(5), 15, 1, MFLAGS),
+       GATE(SCLK_MAC_REFOUT, "sclk_mac_refout", "sclk_gmac", 0,
+                       RK2928_CLKGATE_CON(2), 5, GFLAGS),
+       GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_gmac", 0,
+                       RK2928_CLKGATE_CON(2), 4, GFLAGS),
+       GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_gmac", 0,
+                       RK2928_CLKGATE_CON(2), 6, GFLAGS),
+       GATE(SCLK_MAC_TX, "sclk_mac_tx", "sclk_gmac", 0,
+                       RK2928_CLKGATE_CON(2), 7, GFLAGS),
+
+       COMPOSITE(SCLK_TSP, "sclk_tsp", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 14, GFLAGS),
+
+       COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_3plls_p, 0,
+                       RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(10), 15, GFLAGS),
+
+       COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0,
+                       RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
+                       RK2928_CLKGATE_CON(3), 15, GFLAGS),
+
+       COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0,
+                       RK2928_CLKSEL_CON(29), 8, 6, DFLAGS,
+                       RK2928_CLKGATE_CON(1), 0, GFLAGS),
+
+       /*
+        * Clock-Architecture Diagram 3
+        */
+
+       /* PD_VOP */
+       GATE(ACLK_LCDC0, "aclk_lcdc0", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 0, GFLAGS),
+       GATE(ACLK_CIF, "aclk_cif", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 5, GFLAGS),
+       GATE(ACLK_RGA, "aclk_rga", "aclk_vio0", 0, RK2928_CLKGATE_CON(6), 11, GFLAGS),
+       GATE(0, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS),
+
+       GATE(ACLK_IEP, "aclk_iep", "aclk_vio1", 0, RK2928_CLKGATE_CON(9), 8, GFLAGS),
+       GATE(0, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 10, GFLAGS),
+
+       GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS),
+       GATE(PCLK_MIPI, "pclk_mipi", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
+       GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS),
+       GATE(HCLK_LCDC0, "hclk_lcdc0", "hclk_vio", 0, RK2928_CLKGATE_CON(6), 1, GFLAGS),
+       GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 7, GFLAGS),
+       GATE(0, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS),
+       GATE(HCLK_CIF, "hclk_cif", "hclk_vio", 0, RK2928_CLKGATE_CON(6), 4, GFLAGS),
+       GATE(HCLK_EBC, "hclk_ebc", "hclk_vio", 0, RK2928_CLKGATE_CON(9), 9, GFLAGS),
+
+       /* PD_PERI */
+       GATE(0, "aclk_peri_axi", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS),
+       GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK2928_CLKGATE_CON(10), 10, GFLAGS),
+       GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
+       GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
+       GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
+       GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS),
+
+       GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
+       GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
+       GATE(HCLK_I2S_2CH, "hclk_i2s_2ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
+       GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS),
+       GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
+       GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 13, GFLAGS),
+       GATE(0, "hclk_peri_ahb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS),
+       GATE(HCLK_SPDIF, "hclk_spdif", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS),
+       GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 12, GFLAGS),
+       GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
+       GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS),
+       GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
+       GATE(0, "hclk_emmc_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 6, GFLAGS),
+       GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
+       GATE(HCLK_USBHOST, "hclk_usbhost", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 14, GFLAGS),
+
+       GATE(PCLK_SIM_CARD, "pclk_sim_card", "pclk_peri", 0, RK2928_CLKGATE_CON(9), 12, GFLAGS),
+       GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS),
+       GATE(0, "pclk_peri_axi", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
+       GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
+       GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
+       GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
+       GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS),
+       GATE(PCLK_PWM, "pclk_pwm", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS),
+       GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
+       GATE(PCLK_I2C0, "pclk_i2c0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
+       GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS),
+       GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
+       GATE(PCLK_I2C3, "pclk_i2c3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS),
+       GATE(PCLK_SARADC, "pclk_saradc", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS),
+       GATE(PCLK_EFUSE, "pclk_efuse", "pclk_peri", 0, RK2928_CLKGATE_CON(5), 2, GFLAGS),
+       GATE(PCLK_TIMER, "pclk_timer", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 7, GFLAGS),
+       GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
+       GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
+       GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
+       GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
+
+       /* PD_BUS */
+       GATE(0, "aclk_initmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS),
+       GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS),
+
+       GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
+       GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
+
+       GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
+       GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
+       GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS),
+       GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
+       GATE(0, "pclk_mipiphy", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 0, GFLAGS),
+
+       GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 2, GFLAGS),
+       GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 3, GFLAGS),
+
+       /* PD_MMC */
+       MMC(SCLK_SDMMC_DRV,    "sdmmc_drv",    "sclk_sdmmc", RK3228_SDMMC_CON0, 1),
+       MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0),
+
+       MMC(SCLK_SDIO_DRV,     "sdio_drv",     "sclk_sdio",  RK3228_SDIO_CON0,  1),
+       MMC(SCLK_SDIO_SAMPLE,  "sdio_sample",  "sclk_sdio",  RK3228_SDIO_CON1,  0),
+
+       MMC(SCLK_EMMC_DRV,     "emmc_drv",     "sclk_emmc",  RK3228_EMMC_CON0,  1),
+       MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc",  RK3228_EMMC_CON1,  0),
+};
+
+static const char *const rk3128_critical_clocks[] __initconst = {
+       "aclk_cpu",
+       "hclk_cpu",
+       "pclk_cpu",
+       "aclk_peri",
+       "hclk_peri",
+       "pclk_peri",
+};
+
+static void __init rk3128_clk_init(struct device_node *np)
+{
+       struct rockchip_clk_provider *ctx;
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base) {
+               pr_err("%s: could not map cru region\n", __func__);
+               return;
+       }
+
+       ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+       if (IS_ERR(ctx)) {
+               pr_err("%s: rockchip clk init failed\n", __func__);
+               iounmap(reg_base);
+               return;
+       }
+
+       rockchip_clk_register_plls(ctx, rk3128_pll_clks,
+                                  ARRAY_SIZE(rk3128_pll_clks),
+                                  RK3128_GRF_SOC_STATUS0);
+       rockchip_clk_register_branches(ctx, rk3128_clk_branches,
+                                 ARRAY_SIZE(rk3128_clk_branches));
+       rockchip_clk_protect_critical(rk3128_critical_clocks,
+                                     ARRAY_SIZE(rk3128_critical_clocks));
+
+       rockchip_clk_register_armclk(ctx, ARMCLK, "armclk",
+                       mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+                       &rk3128_cpuclk_data, rk3128_cpuclk_rates,
+                       ARRAY_SIZE(rk3128_cpuclk_rates));
+
+       rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
+                                 ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+       rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL);
+
+       rockchip_clk_of_add_provider(np, ctx);
+}
+
+CLK_OF_DECLARE(rk3128_cru, "rockchip,rk3128-cru", rk3128_clk_init);
index db6e5a9e6de64a781122695a8e807f937c9e0933..bb405d9044a3b35c5c7afc49afd8c7cffa741a53 100644 (file)
@@ -86,25 +86,43 @@ static struct rockchip_pll_rate_table rk3228_pll_rates[] = {
 #define RK3228_DIV_PCLK_MASK           0x7
 #define RK3228_DIV_PCLK_SHIFT          12
 
-#define RK3228_CLKSEL1(_core_peri_div)                                 \
+#define RK3228_CLKSEL1(_core_aclk_div, _core_peri_div)                         \
        {                                                                       \
                .reg = RK2928_CLKSEL_CON(1),                                    \
                .val = HIWORD_UPDATE(_core_peri_div, RK3228_DIV_PERI_MASK,      \
-                               RK3228_DIV_PERI_SHIFT)                          \
-       }
+                                    RK3228_DIV_PERI_SHIFT) |                   \
+                      HIWORD_UPDATE(_core_aclk_div, RK3228_DIV_ACLK_MASK,      \
+                                    RK3228_DIV_ACLK_SHIFT),                    \
+}
 
-#define RK3228_CPUCLK_RATE(_prate, _core_peri_div)                     \
-       {                                                               \
-               .prate = _prate,                                        \
-               .divs = {                                               \
-                       RK3228_CLKSEL1(_core_peri_div),         \
-               },                                                      \
+#define RK3228_CPUCLK_RATE(_prate, _core_aclk_div, _core_peri_div)             \
+       {                                                                       \
+               .prate = _prate,                                                \
+               .divs = {                                                       \
+                       RK3228_CLKSEL1(_core_aclk_div, _core_peri_div),         \
+               },                                                              \
        }
 
 static struct rockchip_cpuclk_rate_table rk3228_cpuclk_rates[] __initdata = {
-       RK3228_CPUCLK_RATE(816000000, 4),
-       RK3228_CPUCLK_RATE(600000000, 4),
-       RK3228_CPUCLK_RATE(312000000, 4),
+       RK3228_CPUCLK_RATE(1800000000, 1, 7),
+       RK3228_CPUCLK_RATE(1704000000, 1, 7),
+       RK3228_CPUCLK_RATE(1608000000, 1, 7),
+       RK3228_CPUCLK_RATE(1512000000, 1, 7),
+       RK3228_CPUCLK_RATE(1488000000, 1, 5),
+       RK3228_CPUCLK_RATE(1416000000, 1, 5),
+       RK3228_CPUCLK_RATE(1392000000, 1, 5),
+       RK3228_CPUCLK_RATE(1296000000, 1, 5),
+       RK3228_CPUCLK_RATE(1200000000, 1, 5),
+       RK3228_CPUCLK_RATE(1104000000, 1, 5),
+       RK3228_CPUCLK_RATE(1008000000, 1, 5),
+       RK3228_CPUCLK_RATE(912000000, 1, 5),
+       RK3228_CPUCLK_RATE(816000000, 1, 3),
+       RK3228_CPUCLK_RATE(696000000, 1, 3),
+       RK3228_CPUCLK_RATE(600000000, 1, 3),
+       RK3228_CPUCLK_RATE(408000000, 1, 1),
+       RK3228_CPUCLK_RATE(312000000, 1, 1),
+       RK3228_CPUCLK_RATE(216000000,  1, 1),
+       RK3228_CPUCLK_RATE(96000000, 1, 1),
 };
 
 static const struct rockchip_cpuclk_reg_data rk3228_cpuclk_data = {
@@ -252,15 +270,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(0), 1, GFLAGS),
        COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0,
                        RK2928_CLKSEL_CON(0), 13, 2, MFLAGS, 8, 5, DFLAGS),
-       GATE(ARMCLK, "aclk_cpu", "aclk_cpu_src", 0,
+       GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0,
                        RK2928_CLKGATE_CON(6), 0, GFLAGS),
-       COMPOSITE_NOMUX(0, "hclk_cpu", "aclk_cpu_src", 0,
+       COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0,
                        RK2928_CLKSEL_CON(1), 8, 2, DFLAGS,
                        RK2928_CLKGATE_CON(6), 1, GFLAGS),
        COMPOSITE_NOMUX(0, "pclk_bus_src", "aclk_cpu_src", 0,
                        RK2928_CLKSEL_CON(1), 12, 3, DFLAGS,
                        RK2928_CLKGATE_CON(6), 2, GFLAGS),
-       GATE(0, "pclk_cpu", "pclk_bus_src", 0,
+       GATE(PCLK_CPU, "pclk_cpu", "pclk_bus_src", 0,
                        RK2928_CLKGATE_CON(6), 3, GFLAGS),
        GATE(0, "pclk_phy_pre", "pclk_bus_src", 0,
                        RK2928_CLKGATE_CON(6), 4, GFLAGS),
@@ -268,58 +286,58 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(6), 13, GFLAGS),
 
        /* PD_VIDEO */
-       COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0,
+       COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 11, GFLAGS),
-       FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4,
+       FACTOR_GATE(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4,
                        RK2928_CLKGATE_CON(4), 4, GFLAGS),
 
-       COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0,
+       COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 2, GFLAGS),
-       FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4,
+       FACTOR_GATE(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4,
                        RK2928_CLKGATE_CON(4), 5, GFLAGS),
 
-       COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0,
+       COMPOSITE(SCLK_VDEC_CABAC, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 3, GFLAGS),
 
-       COMPOSITE(0, "sclk_vdec_core", mux_pll_src_4plls_p, 0,
+       COMPOSITE(SCLK_VDEC_CORE, "sclk_vdec_core", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(34), 13, 2, MFLAGS, 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 4, GFLAGS),
 
        /* PD_VIO */
-       COMPOSITE(0, "aclk_iep_pre", mux_pll_src_4plls_p, 0,
+       COMPOSITE(ACLK_IEP_PRE, "aclk_iep_pre", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(31), 5, 2, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 0, GFLAGS),
-       DIV(0, "hclk_vio_pre", "aclk_iep_pre", 0,
+       DIV(HCLK_VIO_PRE, "hclk_vio_pre", "aclk_iep_pre", 0,
                        RK2928_CLKSEL_CON(2), 0, 5, DFLAGS),
 
-       COMPOSITE(0, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0,
+       COMPOSITE(ACLK_HDCP_PRE, "aclk_hdcp_pre", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(31), 13, 2, MFLAGS, 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(1), 4, GFLAGS),
 
        MUX(0, "sclk_rga_src", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(33), 13, 2, MFLAGS),
-       COMPOSITE_NOMUX(0, "aclk_rga_pre", "sclk_rga_src", 0,
+       COMPOSITE_NOMUX(ACLK_RGA_PRE, "aclk_rga_pre", "sclk_rga_src", 0,
                        RK2928_CLKSEL_CON(33), 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(1), 2, GFLAGS),
-       COMPOSITE(0, "sclk_rga", mux_sclk_rga_p, 0,
+       COMPOSITE(SCLK_RGA, "sclk_rga", mux_sclk_rga_p, 0,
                        RK2928_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 6, GFLAGS),
 
-       COMPOSITE(0, "aclk_vop_pre", mux_pll_src_4plls_p, 0,
+       COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", mux_pll_src_4plls_p, 0,
                        RK2928_CLKSEL_CON(33), 5, 2, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(1), 1, GFLAGS),
 
-       COMPOSITE(0, "sclk_hdcp", mux_pll_src_3plls_p, 0,
+       COMPOSITE(SCLK_HDCP, "sclk_hdcp", mux_pll_src_3plls_p, 0,
                        RK2928_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 6, DFLAGS,
                        RK2928_CLKGATE_CON(3), 5, GFLAGS),
 
        GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0,
                        RK2928_CLKGATE_CON(3), 7, GFLAGS),
 
-       COMPOSITE(0, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0,
+       COMPOSITE(SCLK_HDMI_CEC, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0,
                        RK2928_CLKSEL_CON(21), 14, 2, MFLAGS, 0, 14, DFLAGS,
                        RK2928_CLKGATE_CON(3), 8, GFLAGS),
 
@@ -354,18 +372,18 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
        GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0,
                        RK2928_CLKGATE_CON(6), 10, GFLAGS),
 
-       COMPOSITE(0, "sclk_crypto", mux_pll_src_2plls_p, 0,
+       COMPOSITE(SCLK_CRYPTO, "sclk_crypto", mux_pll_src_2plls_p, 0,
                        RK2928_CLKSEL_CON(24), 5, 1, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(2), 7, GFLAGS),
 
-       COMPOSITE(0, "sclk_tsp", mux_pll_src_2plls_p, 0,
+       COMPOSITE(SCLK_TSP, "sclk_tsp", mux_pll_src_2plls_p, 0,
                        RK2928_CLKSEL_CON(22), 15, 1, MFLAGS, 8, 5, DFLAGS,
                        RK2928_CLKGATE_CON(2), 6, GFLAGS),
 
-       GATE(0, "sclk_hsadc", "ext_hsadc", 0,
+       GATE(SCLK_HSADC, "sclk_hsadc", "ext_hsadc", 0,
                        RK2928_CLKGATE_CON(10), 12, GFLAGS),
 
-       COMPOSITE(0, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0,
+       COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0,
                        RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS,
                        RK2928_CLKGATE_CON(2), 15, GFLAGS),
 
@@ -445,12 +463,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(2), 12, GFLAGS,
                        &rk3228_spdif_fracmux),
 
-       GATE(0, "jtag", "ext_jtag", 0,
+       GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(1), 3, GFLAGS),
 
-       GATE(0, "sclk_otgphy0", "xin24m", 0,
+       GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", 0,
                        RK2928_CLKGATE_CON(1), 5, GFLAGS),
-       GATE(0, "sclk_otgphy1", "xin24m", 0,
+       GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", 0,
                        RK2928_CLKGATE_CON(1), 6, GFLAGS),
 
        COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0,
@@ -526,28 +544,28 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
         */
 
        /* PD_VOP */
-       GATE(0, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS),
+       GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 0, GFLAGS),
        GATE(0, "aclk_rga_noc", "aclk_rga_pre", 0, RK2928_CLKGATE_CON(13), 11, GFLAGS),
-       GATE(0, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS),
+       GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS),
        GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS),
 
        GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS),
        GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS),
 
-       GATE(0, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS),
+       GATE(ACLK_HDCP, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS),
        GATE(0, "aclk_hdcp_noc", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(13), 10, GFLAGS),
 
-       GATE(0, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS),
-       GATE(0, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS),
+       GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS),
+       GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS),
        GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS),
        GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS),
        GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS),
        GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS),
-       GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS),
-       GATE(0, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS),
+       GATE(HCLK_VIO_H2P, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS),
+       GATE(HCLK_HDCP_MMU, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS),
        GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS),
-       GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS),
-       GATE(0, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS),
+       GATE(PCLK_VIO_H2P, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS),
+       GATE(PCLK_HDCP, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS),
 
        /* PD_PERI */
        GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 0, GFLAGS),
@@ -557,12 +575,12 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
        GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 1, GFLAGS),
        GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 2, GFLAGS),
        GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 3, GFLAGS),
-       GATE(0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS),
+       GATE(HCLK_HOST0, "hclk_host0", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 6, GFLAGS),
        GATE(0, "hclk_host0_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 7, GFLAGS),
-       GATE(0, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS),
+       GATE(HCLK_HOST1, "hclk_host1", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 8, GFLAGS),
        GATE(0, "hclk_host1_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 9, GFLAGS),
-       GATE(0, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS),
-       GATE(0, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS),
+       GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 10, GFLAGS),
+       GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 12, GFLAGS),
        GATE(0, "hclk_otg_pmu", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 13, GFLAGS),
        GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS),
        GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS),
@@ -571,7 +589,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
        GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS),
 
        /* PD_GPU */
-       GATE(0, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS),
+       GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS),
        GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS),
 
        /* PD_BUS */
@@ -585,16 +603,16 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
        GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS),
        GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
        GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
-       GATE(0, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS),
-       GATE(0, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
-       GATE(0, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
+       GATE(HCLK_TSP, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS),
+       GATE(HCLK_M_CRYPTO, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
+       GATE(HCLK_S_CRYPTO, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
 
        GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
        GATE(0, "pclk_ddrmon", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
        GATE(0, "pclk_msch_noc", "pclk_ddr_pre", 0, RK2928_CLKGATE_CON(10), 2, GFLAGS),
 
-       GATE(0, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
-       GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS),
+       GATE(PCLK_EFUSE_1024, "pclk_efuse_1024", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
+       GATE(PCLK_EFUSE_256, "pclk_efuse_256", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 14, GFLAGS),
        GATE(PCLK_I2C0, "pclk_i2c0", "pclk_cpu", 0, RK2928_CLKGATE_CON(8), 15, GFLAGS),
        GATE(PCLK_I2C1, "pclk_i2c1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 0, GFLAGS),
        GATE(PCLK_I2C2, "pclk_i2c2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
@@ -622,13 +640,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
        GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
        GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS),
 
-       GATE(0, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS),
+       GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 0, GFLAGS),
        GATE(0, "aclk_vpu_noc", "aclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 4, GFLAGS),
-       GATE(0, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS),
+       GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 2, GFLAGS),
        GATE(0, "aclk_rkvdec_noc", "aclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 6, GFLAGS),
-       GATE(0, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS),
+       GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 1, GFLAGS),
        GATE(0, "hclk_vpu_noc", "hclk_vpu_pre", 0, RK2928_CLKGATE_CON(15), 5, GFLAGS),
-       GATE(0, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS),
+       GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 3, GFLAGS),
        GATE(0, "hclk_rkvdec_noc", "hclk_rkvdec_pre", 0, RK2928_CLKGATE_CON(15), 7, GFLAGS),
 
        /* PD_MMC */
@@ -644,9 +662,37 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
 
 static const char *const rk3228_critical_clocks[] __initconst = {
        "aclk_cpu",
+       "pclk_cpu",
+       "hclk_cpu",
        "aclk_peri",
        "hclk_peri",
        "pclk_peri",
+       "aclk_rga_noc",
+       "aclk_iep_noc",
+       "aclk_vop_noc",
+       "aclk_hdcp_noc",
+       "hclk_vio_ahb_arbi",
+       "hclk_vio_noc",
+       "hclk_vop_noc",
+       "hclk_host0_arb",
+       "hclk_host1_arb",
+       "hclk_host2_arb",
+       "hclk_otg_pmu",
+       "aclk_gpu_noc",
+       "sclk_initmem_mbist",
+       "aclk_initmem",
+       "hclk_rom",
+       "pclk_ddrupctl",
+       "pclk_ddrmon",
+       "pclk_msch_noc",
+       "pclk_stimer",
+       "pclk_ddrphy",
+       "pclk_acodecphy",
+       "pclk_phy_noc",
+       "aclk_vpu_noc",
+       "aclk_rkvdec_noc",
+       "hclk_vpu_noc",
+       "hclk_rkvdec_noc",
 };
 
 static void __init rk3228_clk_init(struct device_node *np)
index 68ba7d4105e76ee3d202c6ccd940ddf15937ebd5..450de24a1b4224cd9386881c7c25471f32899060 100644 (file)
@@ -292,13 +292,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 6, GFLAGS),
-       COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
+       COMPOSITE_NOMUX(0, "atclk", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 7, GFLAGS),
        COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 8, GFLAGS),
-       GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
+       GATE(0, "pclk_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(12), 9, GFLAGS),
        GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(12), 10, GFLAGS),
@@ -626,7 +626,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
                        RK3288_CLKSEL_CON(22), 7, IFLAGS),
 
-       GATE(0, "jtag", "ext_jtag", 0,
+       GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(4), 14, GFLAGS),
 
        COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
@@ -635,7 +635,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
                        RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
                        RK3288_CLKGATE_CON(3), 6, GFLAGS),
-       GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
+       GATE(0, "hsicphy12m_xin12m", "xin12m", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(13), 9, GFLAGS),
        DIV(0, "hsicphy12m_usbphy", "sclk_hsicphy480m", 0,
                        RK3288_CLKSEL_CON(11), 8, 6, DFLAGS),
@@ -816,6 +816,12 @@ static const char *const rk3288_critical_clocks[] __initconst = {
        "pclk_alive_niu",
        "pclk_pd_pmu",
        "pclk_pmu_niu",
+       "pclk_core_niu",
+       "pclk_ddrupctl0",
+       "pclk_publ0",
+       "pclk_ddrupctl1",
+       "pclk_publ1",
+       "pmu_hclk_otg0",
 };
 
 static void __iomem *rk3288_cru_base;
index 024762d3214d6a01ad9e85236c6d6942129c5bd1..fc56565379dd46123c31982c691bd44dacd5912b 100644 (file)
@@ -638,7 +638,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = {
        GATE(SCLK_MAC_TX, "sclk_mac_tx", "mac_clk", 0,
                        RK3368_CLKGATE_CON(7), 5, GFLAGS),
 
-       GATE(0, "jtag", "ext_jtag", 0,
+       GATE(0, "jtag", "ext_jtag", CLK_IGNORE_UNUSED,
                        RK3368_CLKGATE_CON(7), 0, GFLAGS),
 
        COMPOSITE_NODIV(0, "hsic_usbphy_480m", mux_hsic_usbphy480m_p, 0,
@@ -861,6 +861,9 @@ static const char *const rk3368_critical_clocks[] __initconst = {
        "pclk_pd_alive",
        "pclk_peri",
        "hclk_peri",
+       "pclk_ddrphy",
+       "pclk_ddrupctl",
+       "pmu_hclk_otg0",
 };
 
 static void __init rk3368_clk_init(struct device_node *np)
index fa3cbef0877632de2954c6861eccb457e4da105a..6847120b61cdeff87b7de7995c412df5a7d6449c 100644 (file)
@@ -1066,13 +1066,13 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        /* cif_testout */
        MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0,
                        RK3399_CLKSEL_CON(38), 6, 2, MFLAGS),
-       COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0,
+       COMPOSITE(SCLK_TESTCLKOUT1, "clk_testout1", mux_clk_testout1_p, 0,
                        RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS,
                        RK3399_CLKGATE_CON(13), 14, GFLAGS),
 
        MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0,
                        RK3399_CLKSEL_CON(38), 14, 2, MFLAGS),
-       COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0,
+       COMPOSITE(SCLK_TESTCLKOUT2, "clk_testout2", mux_clk_testout2_p, 0,
                        RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS,
                        RK3399_CLKGATE_CON(13), 15, GFLAGS),
 
index 8bf7e805fd34913ad08622824309753a86850b3a..6686e8ba61f9f768681810b4ceaa3afcb5ff43b6 100644 (file)
@@ -410,7 +410,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
 {
        struct exynos_cpuclk *cpuclk;
        struct clk_init_data init;
-       struct clk *clk;
+       struct clk *parent_clk;
        int ret = 0;
 
        cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
@@ -440,15 +440,15 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
                goto free_cpuclk;
        }
 
-       clk = __clk_lookup(parent);
-       if (!clk) {
+       parent_clk = __clk_lookup(parent);
+       if (!parent_clk) {
                pr_err("%s: could not lookup parent clock %s\n",
                                __func__, parent);
                ret = -EINVAL;
                goto free_cpuclk;
        }
 
-       ret = clk_notifier_register(clk, &cpuclk->clk_nb);
+       ret = clk_notifier_register(parent_clk, &cpuclk->clk_nb);
        if (ret) {
                pr_err("%s: failed to register clock notifier for %s\n",
                                __func__, name);
@@ -463,20 +463,19 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
                goto unregister_clk_nb;
        }
 
-       clk = clk_register(NULL, &cpuclk->hw);
-       if (IS_ERR(clk)) {
+       ret = clk_hw_register(NULL, &cpuclk->hw);
+       if (ret) {
                pr_err("%s: could not register cpuclk %s\n", __func__,  name);
-               ret = PTR_ERR(clk);
                goto free_cpuclk_data;
        }
 
-       samsung_clk_add_lookup(ctx, clk, lookup_id);
+       samsung_clk_add_lookup(ctx, &cpuclk->hw, lookup_id);
        return 0;
 
 free_cpuclk_data:
        kfree(cpuclk->cfg);
 unregister_clk_nb:
-       clk_notifier_unregister(__clk_lookup(parent), &cpuclk->clk_nb);
+       clk_notifier_unregister(parent_clk, &cpuclk->clk_nb);
 free_cpuclk:
        kfree(cpuclk);
        return ret;
index cb7df358a27d7838b8752c758951ed5e5e4205ee..1fab56f396d48ab28db2c8c3b5ea2008b49a9a97 100644 (file)
@@ -22,9 +22,8 @@
 #include <dt-bindings/clock/exynos-audss-clk.h>
 
 static DEFINE_SPINLOCK(lock);
-static struct clk **clk_table;
 static void __iomem *reg_base;
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_data;
 /*
  * On Exynos5420 this will be a clock which has to be enabled before any
  * access to audss registers. Typically a child of EPLL.
@@ -74,6 +73,7 @@ struct exynos_audss_clk_drvdata {
 
 static const struct exynos_audss_clk_drvdata exynos4210_drvdata = {
        .num_clks       = EXYNOS_AUDSS_MAX_CLKS - 1,
+       .enable_epll    = 1,
 };
 
 static const struct exynos_audss_clk_drvdata exynos5410_drvdata = {
@@ -110,18 +110,18 @@ static void exynos_audss_clk_teardown(void)
        int i;
 
        for (i = EXYNOS_MOUT_AUDSS; i < EXYNOS_DOUT_SRP; i++) {
-               if (!IS_ERR(clk_table[i]))
-                       clk_unregister_mux(clk_table[i]);
+               if (!IS_ERR(clk_data->hws[i]))
+                       clk_hw_unregister_mux(clk_data->hws[i]);
        }
 
        for (; i < EXYNOS_SRP_CLK; i++) {
-               if (!IS_ERR(clk_table[i]))
-                       clk_unregister_divider(clk_table[i]);
+               if (!IS_ERR(clk_data->hws[i]))
+                       clk_hw_unregister_divider(clk_data->hws[i]);
        }
 
-       for (; i < clk_data.clk_num; i++) {
-               if (!IS_ERR(clk_table[i]))
-                       clk_unregister_gate(clk_table[i]);
+       for (; i < clk_data->num; i++) {
+               if (!IS_ERR(clk_data->hws[i]))
+                       clk_hw_unregister_gate(clk_data->hws[i]);
        }
 }
 
@@ -133,6 +133,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
        const char *sclk_pcm_p = "sclk_pcm0";
        struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
        const struct exynos_audss_clk_drvdata *variant;
+       struct clk_hw **clk_table;
        struct resource *res;
        int i, ret = 0;
 
@@ -149,14 +150,15 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
 
        epll = ERR_PTR(-ENODEV);
 
-       clk_table = devm_kzalloc(&pdev->dev,
-                               sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
+       clk_data = devm_kzalloc(&pdev->dev,
+                               sizeof(*clk_data) +
+                               sizeof(*clk_data->hws) * EXYNOS_AUDSS_MAX_CLKS,
                                GFP_KERNEL);
-       if (!clk_table)
+       if (!clk_data)
                return -ENOMEM;
 
-       clk_data.clks = clk_table;
-       clk_data.clk_num = variant->num_clks;
+       clk_data->num = variant->num_clks;
+       clk_table = clk_data->hws;
 
        pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
        pll_in = devm_clk_get(&pdev->dev, "pll_in");
@@ -176,7 +178,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
                        }
                }
        }
-       clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
+       clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
                                mout_audss_p, ARRAY_SIZE(mout_audss_p),
                                CLK_SET_RATE_NO_REPARENT,
                                reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
@@ -187,53 +189,53 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
                mout_i2s_p[1] = __clk_get_name(cdclk);
        if (!IS_ERR(sclk_audio))
                mout_i2s_p[2] = __clk_get_name(sclk_audio);
-       clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
+       clk_table[EXYNOS_MOUT_I2S] = clk_hw_register_mux(NULL, "mout_i2s",
                                mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
                                CLK_SET_RATE_NO_REPARENT,
                                reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
 
-       clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp",
+       clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp",
                                "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4,
                                0, &lock);
 
-       clk_table[EXYNOS_DOUT_AUD_BUS] = clk_register_divider(NULL,
+       clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
                                "dout_aud_bus", "dout_srp", 0,
                                reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
 
-       clk_table[EXYNOS_DOUT_I2S] = clk_register_divider(NULL, "dout_i2s",
+       clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s",
                                "mout_i2s", 0, reg_base + ASS_CLK_DIV, 8, 4, 0,
                                &lock);
 
-       clk_table[EXYNOS_SRP_CLK] = clk_register_gate(NULL, "srp_clk",
+       clk_table[EXYNOS_SRP_CLK] = clk_hw_register_gate(NULL, "srp_clk",
                                "dout_srp", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 0, 0, &lock);
 
-       clk_table[EXYNOS_I2S_BUS] = clk_register_gate(NULL, "i2s_bus",
+       clk_table[EXYNOS_I2S_BUS] = clk_hw_register_gate(NULL, "i2s_bus",
                                "dout_aud_bus", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 2, 0, &lock);
 
-       clk_table[EXYNOS_SCLK_I2S] = clk_register_gate(NULL, "sclk_i2s",
+       clk_table[EXYNOS_SCLK_I2S] = clk_hw_register_gate(NULL, "sclk_i2s",
                                "dout_i2s", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 3, 0, &lock);
 
-       clk_table[EXYNOS_PCM_BUS] = clk_register_gate(NULL, "pcm_bus",
+       clk_table[EXYNOS_PCM_BUS] = clk_hw_register_gate(NULL, "pcm_bus",
                                 "sclk_pcm", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 4, 0, &lock);
 
        sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in");
        if (!IS_ERR(sclk_pcm_in))
                sclk_pcm_p = __clk_get_name(sclk_pcm_in);
-       clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm",
+       clk_table[EXYNOS_SCLK_PCM] = clk_hw_register_gate(NULL, "sclk_pcm",
                                sclk_pcm_p, CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 5, 0, &lock);
 
        if (variant->has_adma_clk) {
-               clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma",
+               clk_table[EXYNOS_ADMA] = clk_hw_register_gate(NULL, "adma",
                                "dout_srp", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 9, 0, &lock);
        }
 
-       for (i = 0; i < clk_data.clk_num; i++) {
+       for (i = 0; i < clk_data->num; i++) {
                if (IS_ERR(clk_table[i])) {
                        dev_err(&pdev->dev, "failed to register clock %d\n", i);
                        ret = PTR_ERR(clk_table[i]);
@@ -241,8 +243,8 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
                }
        }
 
-       ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
-                                       &clk_data);
+       ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
+                                    clk_data);
        if (ret) {
                dev_err(&pdev->dev, "failed to add clock provider\n");
                goto unregister;
index 6c6afb87b4ce3babf8d7625581a5f7a288b1a1d5..a21aea062baed6716bcc937aaf149506cd1f65ad 100644 (file)
@@ -29,10 +29,9 @@ struct exynos_clkout {
        struct clk_gate gate;
        struct clk_mux mux;
        spinlock_t slock;
-       struct clk_onecell_data data;
-       struct clk *clk_table[EXYNOS_CLKOUT_NR_CLKS];
        void __iomem *reg;
        u32 pmu_debug_save;
+       struct clk_hw_onecell_data data;
 };
 
 static struct exynos_clkout *clkout;
@@ -62,7 +61,9 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
        int ret;
        int i;
 
-       clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
+       clkout = kzalloc(sizeof(*clkout) +
+                        sizeof(*clkout->data.hws) * EXYNOS_CLKOUT_NR_CLKS,
+                        GFP_KERNEL);
        if (!clkout)
                return;
 
@@ -100,17 +101,16 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
        clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
        clkout->mux.lock = &clkout->slock;
 
-       clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
+       clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout",
                                parent_names, parent_count, &clkout->mux.hw,
                                &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
                                &clk_gate_ops, CLK_SET_RATE_PARENT
                                | CLK_SET_RATE_NO_REPARENT);
-       if (IS_ERR(clkout->clk_table[0]))
+       if (IS_ERR(clkout->data.hws[0]))
                goto err_unmap;
 
-       clkout->data.clks = clkout->clk_table;
-       clkout->data.clk_num = EXYNOS_CLKOUT_NR_CLKS;
-       ret = of_clk_add_provider(node, of_clk_src_onecell_get, &clkout->data);
+       clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
+       ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, &clkout->data);
        if (ret)
                goto err_clk_unreg;
 
@@ -119,7 +119,7 @@ static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
        return;
 
 err_clk_unreg:
-       clk_unregister(clkout->clk_table[0]);
+       clk_hw_unregister(clkout->data.hws[0]);
 err_unmap:
        iounmap(clkout->reg);
 clks_put:
index cdc092a1d9effd7815fbd43314977059a52e0ec8..0748a0b333c54c4a4a4b888ddd9e83a25d4323f7 100644 (file)
@@ -487,6 +487,7 @@ PNAME(mout_group12_5800_p)  = { "dout_aclkfl1_550_cam", "dout_sclk_sw" };
 PNAME(mout_group13_5800_p)     = { "dout_osc_div", "mout_sw_aclkfl1_550_cam" };
 PNAME(mout_group14_5800_p)     = { "dout_aclk550_cam", "dout_sclk_sw" };
 PNAME(mout_group15_5800_p)     = { "dout_osc_div", "mout_sw_aclk550_cam" };
+PNAME(mout_group16_5800_p)     = { "dout_osc_div", "mout_mau_epll_clk" };
 
 /* fixed rate clocks generated outside the soc */
 static struct samsung_fixed_rate_clock
@@ -536,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
 
        MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore",
                        mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2),
-       MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, SRC_TOP7,
-                       20, 2),
+       MUX(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p,
+                                                       SRC_TOP7, 20, 2),
        MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1),
        MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1),
 
@@ -546,6 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
        MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2),
        MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2),
 
+       MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p,
+                                                       SRC_TOP9, 8, 1),
        MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p,
                                                        SRC_TOP9, 16, 1),
        MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p,
@@ -703,7 +706,7 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
        MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1),
        MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1),
        MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1),
-       MUX(0, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1),
+       MUX(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1),
        MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1),
        MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1),
 
@@ -1277,6 +1280,21 @@ static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __ini
        PLL_35XX_RATE(200000000,  200, 3, 3),
 };
 
+static const struct samsung_pll_rate_table exynos5420_epll_24mhz_tbl[] = {
+       PLL_36XX_RATE(600000000U, 100, 2, 1, 0),
+       PLL_36XX_RATE(400000000U, 200, 3, 2, 0),
+       PLL_36XX_RATE(393216000U, 197, 3, 2, 25690),
+       PLL_36XX_RATE(361267200U, 301, 5, 2, 3671),
+       PLL_36XX_RATE(200000000U, 200, 3, 3, 0),
+       PLL_36XX_RATE(196608000U, 197, 3, 3, -25690),
+       PLL_36XX_RATE(180633600U, 301, 5, 3, 3671),
+       PLL_36XX_RATE(131072000U, 131, 3, 3, 4719),
+       PLL_36XX_RATE(100000000U, 200, 3, 4, 0),
+       PLL_36XX_RATE(65536000U, 131, 3, 4, 4719),
+       PLL_36XX_RATE(49152000U, 197, 3, 5, 25690),
+       PLL_36XX_RATE(32768000U, 131, 3, 5, 4719),
+};
+
 static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
        [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
                APLL_CON0, NULL),
@@ -1284,7 +1302,7 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
                CPLL_CON0, NULL),
        [dpll] = PLL(pll_2550, CLK_FOUT_DPLL, "fout_dpll", "fin_pll", DPLL_LOCK,
                DPLL_CON0, NULL),
-       [epll] = PLL(pll_2650, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK,
+       [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK,
                EPLL_CON0, NULL),
        [rpll] = PLL(pll_2650, CLK_FOUT_RPLL, "fout_rpll", "fin_pll", RPLL_LOCK,
                RPLL_CON0, NULL),
@@ -1399,6 +1417,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
 
        if (_get_rate("fin_pll") == 24 * MHZ) {
                exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl;
+               exynos5x_plls[epll].rate_table = exynos5420_epll_24mhz_tbl;
                exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
                exynos5x_plls[bpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
        }
index 52290894857a546bda106c573d35dc54c193fbf8..037c6148409872b46f35f9613244742fd52b3a09 100644 (file)
@@ -23,6 +23,10 @@ struct samsung_clk_pll {
        struct clk_hw           hw;
        void __iomem            *lock_reg;
        void __iomem            *con_reg;
+       /* PLL enable control bit offset in @con_reg register */
+       unsigned short          enable_offs;
+       /* PLL lock status bit offset in @con_reg register */
+       unsigned short          lock_offs;
        enum samsung_pll_type   type;
        unsigned int            rate_count;
        const struct samsung_pll_rate_table *rate_table;
@@ -61,6 +65,34 @@ static long samsung_pll_round_rate(struct clk_hw *hw,
        return rate_table[i - 1].rate;
 }
 
+static int samsung_pll3xxx_enable(struct clk_hw *hw)
+{
+       struct samsung_clk_pll *pll = to_clk_pll(hw);
+       u32 tmp;
+
+       tmp = readl_relaxed(pll->con_reg);
+       tmp |= BIT(pll->enable_offs);
+       writel_relaxed(tmp, pll->con_reg);
+
+       /* wait lock time */
+       do {
+               cpu_relax();
+               tmp = readl_relaxed(pll->con_reg);
+       } while (!(tmp & BIT(pll->lock_offs)));
+
+       return 0;
+}
+
+static void samsung_pll3xxx_disable(struct clk_hw *hw)
+{
+       struct samsung_clk_pll *pll = to_clk_pll(hw);
+       u32 tmp;
+
+       tmp = readl_relaxed(pll->con_reg);
+       tmp &= ~BIT(pll->enable_offs);
+       writel_relaxed(tmp, pll->con_reg);
+}
+
 /*
  * PLL2126 Clock Type
  */
@@ -142,34 +174,6 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
 #define PLL35XX_LOCK_STAT_SHIFT        (29)
 #define PLL35XX_ENABLE_SHIFT   (31)
 
-static int samsung_pll35xx_enable(struct clk_hw *hw)
-{
-       struct samsung_clk_pll *pll = to_clk_pll(hw);
-       u32 tmp;
-
-       tmp = readl_relaxed(pll->con_reg);
-       tmp |= BIT(PLL35XX_ENABLE_SHIFT);
-       writel_relaxed(tmp, pll->con_reg);
-
-       /* wait_lock_time */
-       do {
-               cpu_relax();
-               tmp = readl_relaxed(pll->con_reg);
-       } while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
-
-       return 0;
-}
-
-static void samsung_pll35xx_disable(struct clk_hw *hw)
-{
-       struct samsung_clk_pll *pll = to_clk_pll(hw);
-       u32 tmp;
-
-       tmp = readl_relaxed(pll->con_reg);
-       tmp &= ~BIT(PLL35XX_ENABLE_SHIFT);
-       writel_relaxed(tmp, pll->con_reg);
-}
-
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
                                unsigned long parent_rate)
 {
@@ -238,12 +242,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
                        (rate->sdiv << PLL35XX_SDIV_SHIFT);
        writel_relaxed(tmp, pll->con_reg);
 
-       /* wait_lock_time if enabled */
-       if (tmp & BIT(PLL35XX_ENABLE_SHIFT)) {
+       /* Wait until the PLL is locked if it is enabled. */
+       if (tmp & BIT(pll->enable_offs)) {
                do {
                        cpu_relax();
                        tmp = readl_relaxed(pll->con_reg);
-               } while (!(tmp & BIT(PLL35XX_LOCK_STAT_SHIFT)));
+               } while (!(tmp & BIT(pll->lock_offs)));
        }
        return 0;
 }
@@ -252,8 +256,8 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
        .recalc_rate = samsung_pll35xx_recalc_rate,
        .round_rate = samsung_pll_round_rate,
        .set_rate = samsung_pll35xx_set_rate,
-       .enable = samsung_pll35xx_enable,
-       .disable = samsung_pll35xx_disable,
+       .enable = samsung_pll3xxx_enable,
+       .disable = samsung_pll3xxx_disable,
 };
 
 static const struct clk_ops samsung_pll35xx_clk_min_ops = {
@@ -275,6 +279,7 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 #define PLL36XX_SDIV_SHIFT     (0)
 #define PLL36XX_KDIV_SHIFT     (0)
 #define PLL36XX_LOCK_STAT_SHIFT        (29)
+#define PLL36XX_ENABLE_SHIFT   (31)
 
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
                                unsigned long parent_rate)
@@ -354,10 +359,12 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
        writel_relaxed(pll_con1, pll->con_reg + 4);
 
        /* wait_lock_time */
-       do {
-               cpu_relax();
-               tmp = readl_relaxed(pll->con_reg);
-       } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
+       if (pll_con0 & BIT(pll->enable_offs)) {
+               do {
+                       cpu_relax();
+                       tmp = readl_relaxed(pll->con_reg);
+               } while (!(tmp & BIT(pll->lock_offs)));
+       }
 
        return 0;
 }
@@ -366,6 +373,8 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
        .recalc_rate = samsung_pll36xx_recalc_rate,
        .set_rate = samsung_pll36xx_set_rate,
        .round_rate = samsung_pll_round_rate,
+       .enable = samsung_pll3xxx_enable,
+       .disable = samsung_pll3xxx_disable,
 };
 
 static const struct clk_ops samsung_pll36xx_clk_min_ops = {
@@ -1244,7 +1253,6 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
                                void __iomem *base)
 {
        struct samsung_clk_pll *pll;
-       struct clk *clk;
        struct clk_init_data init;
        int ret, len;
 
@@ -1288,6 +1296,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
        case pll_1450x:
        case pll_1451x:
        case pll_1452x:
+               pll->enable_offs = PLL35XX_ENABLE_SHIFT;
+               pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
                if (!pll->rate_table)
                        init.ops = &samsung_pll35xx_clk_min_ops;
                else
@@ -1306,6 +1316,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
        /* clk_ops for 36xx and 2650 are similar */
        case pll_36xx:
        case pll_2650:
+               pll->enable_offs = PLL36XX_ENABLE_SHIFT;
+               pll->lock_offs = PLL36XX_LOCK_STAT_SHIFT;
                if (!pll->rate_table)
                        init.ops = &samsung_pll36xx_clk_min_ops;
                else
@@ -1376,20 +1388,21 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
        pll->lock_reg = base + pll_clk->lock_offset;
        pll->con_reg = base + pll_clk->con_offset;
 
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: failed to register pll clock %s : %ld\n",
-                       __func__, pll_clk->name, PTR_ERR(clk));
+       ret = clk_hw_register(NULL, &pll->hw);
+       if (ret) {
+               pr_err("%s: failed to register pll clock %s : %d\n",
+                       __func__, pll_clk->name, ret);
                kfree(pll);
                return;
        }
 
-       samsung_clk_add_lookup(ctx, clk, pll_clk->id);
+       samsung_clk_add_lookup(ctx, &pll->hw, pll_clk->id);
 
        if (!pll_clk->alias)
                return;
 
-       ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
+       ret = clk_hw_register_clkdev(&pll->hw, pll_clk->alias,
+                                    pll_clk->dev_name);
        if (ret)
                pr_err("%s: failed to register lookup for %s : %d",
                        __func__, pll_clk->name, ret);
index a1ca0233cb4b0dcef3312883acc7d5ca4c96a6c8..61eb8abbfd9c3142ae8173f0311686e3dfc937ad 100644 (file)
@@ -103,8 +103,4 @@ struct samsung_pll_rate_table {
        unsigned int vsel;
 };
 
-extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
-                       const char *pname, const void __iomem *reg_base,
-                       const unsigned long offset);
-
 #endif /* __SAMSUNG_CLK_PLL_H */
index ae9a595c72d0e3489036b93aba3acae2c934a9e9..077df3e539a71fef9a1ebfd98424525aeabb4885 100644 (file)
@@ -90,13 +90,13 @@ static const struct clk_ops s3c24xx_clkout_ops = {
        .determine_rate = __clk_mux_determine_rate,
 };
 
-static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
-               const char **parent_names, u8 num_parents,
+static struct clk_hw *s3c24xx_register_clkout(struct device *dev,
+               const char *name, const char **parent_names, u8 num_parents,
                u8 shift, u32 mask)
 {
        struct s3c24xx_clkout *clkout;
-       struct clk *clk;
        struct clk_init_data init;
+       int ret;
 
        /* allocate the clkout */
        clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
@@ -113,9 +113,11 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
        clkout->mask = mask;
        clkout->hw.init = &init;
 
-       clk = clk_register(dev, &clkout->hw);
+       ret = clk_hw_register(dev, &clkout->hw);
+       if (ret)
+               return ERR_PTR(ret);
 
-       return clk;
+       return &clkout->hw;
 }
 
 /*
@@ -125,11 +127,12 @@ static struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
 struct s3c24xx_dclk {
        struct device *dev;
        void __iomem *base;
-       struct clk_onecell_data clk_data;
        struct notifier_block dclk0_div_change_nb;
        struct notifier_block dclk1_div_change_nb;
        spinlock_t dclk_lock;
        unsigned long reg_save;
+       /* clk_data must be the last entry in the structure */
+       struct clk_hw_onecell_data clk_data;
 };
 
 #define to_s3c24xx_dclk0(x) \
@@ -240,28 +243,23 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
 {
        struct s3c24xx_dclk *s3c24xx_dclk;
        struct resource *mem;
-       struct clk **clk_table;
        struct s3c24xx_dclk_drv_data *dclk_variant;
+       struct clk_hw **clk_table;
        int ret, i;
 
-       s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
-                                   GFP_KERNEL);
+       s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk) +
+                           sizeof(*s3c24xx_dclk->clk_data.hws) * DCLK_MAX_CLKS,
+                           GFP_KERNEL);
        if (!s3c24xx_dclk)
                return -ENOMEM;
 
+       clk_table = s3c24xx_dclk->clk_data.hws;
+
        s3c24xx_dclk->dev = &pdev->dev;
+       s3c24xx_dclk->clk_data.num = DCLK_MAX_CLKS;
        platform_set_drvdata(pdev, s3c24xx_dclk);
        spin_lock_init(&s3c24xx_dclk->dclk_lock);
 
-       clk_table = devm_kzalloc(&pdev->dev,
-                                sizeof(struct clk *) * DCLK_MAX_CLKS,
-                                GFP_KERNEL);
-       if (!clk_table)
-               return -ENOMEM;
-
-       s3c24xx_dclk->clk_data.clks = clk_table;
-       s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
-
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
        if (IS_ERR(s3c24xx_dclk->base))
@@ -271,29 +269,29 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
                                platform_get_device_id(pdev)->driver_data;
 
 
-       clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev, "mux_dclk0",
+       clk_table[MUX_DCLK0] = clk_hw_register_mux(&pdev->dev, "mux_dclk0",
                                dclk_variant->mux_parent_names,
                                dclk_variant->mux_num_parents, 0,
                                s3c24xx_dclk->base, 1, 1, 0,
                                &s3c24xx_dclk->dclk_lock);
-       clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev, "mux_dclk1",
+       clk_table[MUX_DCLK1] = clk_hw_register_mux(&pdev->dev, "mux_dclk1",
                                dclk_variant->mux_parent_names,
                                dclk_variant->mux_num_parents, 0,
                                s3c24xx_dclk->base, 17, 1, 0,
                                &s3c24xx_dclk->dclk_lock);
 
-       clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
+       clk_table[DIV_DCLK0] = clk_hw_register_divider(&pdev->dev, "div_dclk0",
                                "mux_dclk0", 0, s3c24xx_dclk->base,
                                4, 4, 0, &s3c24xx_dclk->dclk_lock);
-       clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
+       clk_table[DIV_DCLK1] = clk_hw_register_divider(&pdev->dev, "div_dclk1",
                                "mux_dclk1", 0, s3c24xx_dclk->base,
                                20, 4, 0, &s3c24xx_dclk->dclk_lock);
 
-       clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
+       clk_table[GATE_DCLK0] = clk_hw_register_gate(&pdev->dev, "gate_dclk0",
                                "div_dclk0", CLK_SET_RATE_PARENT,
                                s3c24xx_dclk->base, 0, 0,
                                &s3c24xx_dclk->dclk_lock);
-       clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
+       clk_table[GATE_DCLK1] = clk_hw_register_gate(&pdev->dev, "gate_dclk1",
                                "div_dclk1", CLK_SET_RATE_PARENT,
                                s3c24xx_dclk->base, 16, 0,
                                &s3c24xx_dclk->dclk_lock);
@@ -312,15 +310,16 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
                        goto err_clk_register;
                }
 
-       ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
+       ret = clk_hw_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
        if (!ret)
-               ret = clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
+               ret = clk_hw_register_clkdev(clk_table[MUX_DCLK1], "dclk1",
+                                            NULL);
        if (!ret)
-               ret = clk_register_clkdev(clk_table[MUX_CLKOUT0],
-                                         "clkout0", NULL);
+               ret = clk_hw_register_clkdev(clk_table[MUX_CLKOUT0],
+                                            "clkout0", NULL);
        if (!ret)
-               ret = clk_register_clkdev(clk_table[MUX_CLKOUT1],
-                                         "clkout1", NULL);
+               ret = clk_hw_register_clkdev(clk_table[MUX_CLKOUT1],
+                                            "clkout1", NULL);
        if (ret) {
                dev_err(&pdev->dev, "failed to register aliases, %d\n", ret);
                goto err_clk_register;
@@ -332,12 +331,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
        s3c24xx_dclk->dclk1_div_change_nb.notifier_call =
                                                s3c24xx_dclk1_div_notify;
 
-       ret = clk_notifier_register(clk_table[DIV_DCLK0],
+       ret = clk_notifier_register(clk_table[DIV_DCLK0]->clk,
                                    &s3c24xx_dclk->dclk0_div_change_nb);
        if (ret)
                goto err_clk_register;
 
-       ret = clk_notifier_register(clk_table[DIV_DCLK1],
+       ret = clk_notifier_register(clk_table[DIV_DCLK1]->clk,
                                    &s3c24xx_dclk->dclk1_div_change_nb);
        if (ret)
                goto err_dclk_notify;
@@ -345,12 +344,12 @@ static int s3c24xx_dclk_probe(struct platform_device *pdev)
        return 0;
 
 err_dclk_notify:
-       clk_notifier_unregister(clk_table[DIV_DCLK0],
+       clk_notifier_unregister(clk_table[DIV_DCLK0]->clk,
                                &s3c24xx_dclk->dclk0_div_change_nb);
 err_clk_register:
        for (i = 0; i < DCLK_MAX_CLKS; i++)
                if (clk_table[i] && !IS_ERR(clk_table[i]))
-                       clk_unregister(clk_table[i]);
+                       clk_hw_unregister(clk_table[i]);
 
        return ret;
 }
@@ -358,16 +357,16 @@ err_clk_register:
 static int s3c24xx_dclk_remove(struct platform_device *pdev)
 {
        struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
-       struct clk **clk_table = s3c24xx_dclk->clk_data.clks;
+       struct clk_hw **clk_table = s3c24xx_dclk->clk_data.hws;
        int i;
 
-       clk_notifier_unregister(clk_table[DIV_DCLK1],
+       clk_notifier_unregister(clk_table[DIV_DCLK1]->clk,
                                &s3c24xx_dclk->dclk1_div_change_nb);
-       clk_notifier_unregister(clk_table[DIV_DCLK0],
+       clk_notifier_unregister(clk_table[DIV_DCLK0]->clk,
                                &s3c24xx_dclk->dclk0_div_change_nb);
 
        for (i = 0; i < DCLK_MAX_CLKS; i++)
-               clk_unregister(clk_table[i]);
+               clk_hw_unregister(clk_table[i]);
 
        return 0;
 }
index c66ed2d1450e5c52c894eacf72b3d7794b6fd093..b9641414ddc6a59b1ea4e510658cd6acd7739af0 100644 (file)
@@ -24,9 +24,8 @@
 #include <dt-bindings/clock/s5pv210-audss.h>
 
 static DEFINE_SPINLOCK(lock);
-static struct clk **clk_table;
 static void __iomem *reg_base;
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_data;
 
 #define ASS_CLK_SRC 0x0
 #define ASS_CLK_DIV 0x4
@@ -71,6 +70,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
        const char *mout_audss_p[2];
        const char *mout_i2s_p[3];
        const char *hclk_p;
+       struct clk_hw **clk_table;
        struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -80,14 +80,16 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
                return PTR_ERR(reg_base);
        }
 
-       clk_table = devm_kzalloc(&pdev->dev,
-                               sizeof(struct clk *) * AUDSS_MAX_CLKS,
+       clk_data = devm_kzalloc(&pdev->dev,
+                               sizeof(*clk_data) +
+                               sizeof(*clk_data->hws) * AUDSS_MAX_CLKS,
                                GFP_KERNEL);
-       if (!clk_table)
+
+       if (!clk_data)
                return -ENOMEM;
 
-       clk_data.clks = clk_table;
-       clk_data.clk_num = AUDSS_MAX_CLKS;
+       clk_data->num = AUDSS_MAX_CLKS;
+       clk_table = clk_data->hws;
 
        hclk = devm_clk_get(&pdev->dev, "hclk");
        if (IS_ERR(hclk)) {
@@ -116,7 +118,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
        else
                mout_audss_p[0] = "xxti";
        mout_audss_p[1] = __clk_get_name(pll_in);
-       clk_table[CLK_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
+       clk_table[CLK_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss",
                                mout_audss_p, ARRAY_SIZE(mout_audss_p),
                                CLK_SET_RATE_NO_REPARENT,
                                reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
@@ -127,44 +129,44 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
        else
                mout_i2s_p[1] = "iiscdclk0";
        mout_i2s_p[2] = __clk_get_name(sclk_audio);
-       clk_table[CLK_MOUT_I2S_A] = clk_register_mux(NULL, "mout_i2s_audss",
+       clk_table[CLK_MOUT_I2S_A] = clk_hw_register_mux(NULL, "mout_i2s_audss",
                                mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
                                CLK_SET_RATE_NO_REPARENT,
                                reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
 
-       clk_table[CLK_DOUT_AUD_BUS] = clk_register_divider(NULL,
+       clk_table[CLK_DOUT_AUD_BUS] = clk_hw_register_divider(NULL,
                                "dout_aud_bus", "mout_audss", 0,
                                reg_base + ASS_CLK_DIV, 0, 4, 0, &lock);
-       clk_table[CLK_DOUT_I2S_A] = clk_register_divider(NULL, "dout_i2s_audss",
-                               "mout_i2s_audss", 0, reg_base + ASS_CLK_DIV,
-                               4, 4, 0, &lock);
+       clk_table[CLK_DOUT_I2S_A] = clk_hw_register_divider(NULL,
+                               "dout_i2s_audss", "mout_i2s_audss", 0,
+                               reg_base + ASS_CLK_DIV, 4, 4, 0, &lock);
 
-       clk_table[CLK_I2S] = clk_register_gate(NULL, "i2s_audss",
+       clk_table[CLK_I2S] = clk_hw_register_gate(NULL, "i2s_audss",
                                "dout_i2s_audss", CLK_SET_RATE_PARENT,
                                reg_base + ASS_CLK_GATE, 6, 0, &lock);
 
        hclk_p = __clk_get_name(hclk);
 
-       clk_table[CLK_HCLK_I2S] = clk_register_gate(NULL, "hclk_i2s_audss",
+       clk_table[CLK_HCLK_I2S] = clk_hw_register_gate(NULL, "hclk_i2s_audss",
                                hclk_p, CLK_IGNORE_UNUSED,
                                reg_base + ASS_CLK_GATE, 5, 0, &lock);
-       clk_table[CLK_HCLK_UART] = clk_register_gate(NULL, "hclk_uart_audss",
+       clk_table[CLK_HCLK_UART] = clk_hw_register_gate(NULL, "hclk_uart_audss",
                                hclk_p, CLK_IGNORE_UNUSED,
                                reg_base + ASS_CLK_GATE, 4, 0, &lock);
-       clk_table[CLK_HCLK_HWA] = clk_register_gate(NULL, "hclk_hwa_audss",
+       clk_table[CLK_HCLK_HWA] = clk_hw_register_gate(NULL, "hclk_hwa_audss",
                                hclk_p, CLK_IGNORE_UNUSED,
                                reg_base + ASS_CLK_GATE, 3, 0, &lock);
-       clk_table[CLK_HCLK_DMA] = clk_register_gate(NULL, "hclk_dma_audss",
+       clk_table[CLK_HCLK_DMA] = clk_hw_register_gate(NULL, "hclk_dma_audss",
                                hclk_p, CLK_IGNORE_UNUSED,
                                reg_base + ASS_CLK_GATE, 2, 0, &lock);
-       clk_table[CLK_HCLK_BUF] = clk_register_gate(NULL, "hclk_buf_audss",
+       clk_table[CLK_HCLK_BUF] = clk_hw_register_gate(NULL, "hclk_buf_audss",
                                hclk_p, CLK_IGNORE_UNUSED,
                                reg_base + ASS_CLK_GATE, 1, 0, &lock);
-       clk_table[CLK_HCLK_RP] = clk_register_gate(NULL, "hclk_rp_audss",
+       clk_table[CLK_HCLK_RP] = clk_hw_register_gate(NULL, "hclk_rp_audss",
                                hclk_p, CLK_IGNORE_UNUSED,
                                reg_base + ASS_CLK_GATE, 0, 0, &lock);
 
-       for (i = 0; i < clk_data.clk_num; i++) {
+       for (i = 0; i < clk_data->num; i++) {
                if (IS_ERR(clk_table[i])) {
                        dev_err(&pdev->dev, "failed to register clock %d\n", i);
                        ret = PTR_ERR(clk_table[i]);
@@ -172,8 +174,8 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
                }
        }
 
-       ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
-                                       &clk_data);
+       ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
+                                    clk_data);
        if (ret) {
                dev_err(&pdev->dev, "failed to add clock provider\n");
                goto unregister;
@@ -186,9 +188,9 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev)
        return 0;
 
 unregister:
-       for (i = 0; i < clk_data.clk_num; i++) {
+       for (i = 0; i < clk_data->num; i++) {
                if (!IS_ERR(clk_table[i]))
-                       clk_unregister(clk_table[i]);
+                       clk_hw_unregister(clk_table[i]);
        }
 
        return ret;
index b7d87d6db9dc4de9cc186bdd2717bc5edb958245..7ce0fa86c5ff821b0a2745e589b8f047b66b4e1b 100644 (file)
@@ -60,23 +60,18 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
                        void __iomem *base, unsigned long nr_clks)
 {
        struct samsung_clk_provider *ctx;
-       struct clk **clk_table;
        int i;
 
-       ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL);
+       ctx = kzalloc(sizeof(struct samsung_clk_provider) +
+                     sizeof(*ctx->clk_data.hws) * nr_clks, GFP_KERNEL);
        if (!ctx)
                panic("could not allocate clock provider context.\n");
 
-       clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
-       if (!clk_table)
-               panic("could not allocate clock lookup table\n");
-
        for (i = 0; i < nr_clks; ++i)
-               clk_table[i] = ERR_PTR(-ENOENT);
+               ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
 
        ctx->reg_base = base;
-       ctx->clk_data.clks = clk_table;
-       ctx->clk_data.clk_num = nr_clks;
+       ctx->clk_data.num = nr_clks;
        spin_lock_init(&ctx->lock);
 
        return ctx;
@@ -86,18 +81,18 @@ void __init samsung_clk_of_add_provider(struct device_node *np,
                                struct samsung_clk_provider *ctx)
 {
        if (np) {
-               if (of_clk_add_provider(np, of_clk_src_onecell_get,
+               if (of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
                                        &ctx->clk_data))
                        panic("could not register clk provider\n");
        }
 }
 
 /* add a clock instance to the clock lookup table used for dt based lookup */
-void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk,
-                               unsigned int id)
+void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
+                           struct clk_hw *clk_hw, unsigned int id)
 {
-       if (ctx->clk_data.clks && id)
-               ctx->clk_data.clks[id] = clk;
+       if (id)
+               ctx->clk_data.hws[id] = clk_hw;
 }
 
 /* register a list of aliases */
@@ -105,14 +100,9 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
                                const struct samsung_clock_alias *list,
                                unsigned int nr_clk)
 {
-       struct clk *clk;
+       struct clk_hw *clk_hw;
        unsigned int idx, ret;
 
-       if (!ctx->clk_data.clks) {
-               pr_err("%s: clock table missing\n", __func__);
-               return;
-       }
-
        for (idx = 0; idx < nr_clk; idx++, list++) {
                if (!list->id) {
                        pr_err("%s: clock id missing for index %d\n", __func__,
@@ -120,14 +110,15 @@ void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
                        continue;
                }
 
-               clk = ctx->clk_data.clks[list->id];
-               if (!clk) {
+               clk_hw = ctx->clk_data.hws[list->id];
+               if (!clk_hw) {
                        pr_err("%s: failed to find clock %d\n", __func__,
                                list->id);
                        continue;
                }
 
-               ret = clk_register_clkdev(clk, list->alias, list->dev_name);
+               ret = clk_hw_register_clkdev(clk_hw, list->alias,
+                                            list->dev_name);
                if (ret)
                        pr_err("%s: failed to register lookup %s\n",
                                        __func__, list->alias);
@@ -139,25 +130,25 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
                const struct samsung_fixed_rate_clock *list,
                unsigned int nr_clk)
 {
-       struct clk *clk;
+       struct clk_hw *clk_hw;
        unsigned int idx, ret;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk = clk_register_fixed_rate(NULL, list->name,
+               clk_hw = clk_hw_register_fixed_rate(NULL, list->name,
                        list->parent_name, list->flags, list->fixed_rate);
-               if (IS_ERR(clk)) {
+               if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
                        continue;
                }
 
-               samsung_clk_add_lookup(ctx, clk, list->id);
+               samsung_clk_add_lookup(ctx, clk_hw, list->id);
 
                /*
                 * Unconditionally add a clock lookup for the fixed rate clocks.
                 * There are not many of these on any of Samsung platforms.
                 */
-               ret = clk_register_clkdev(clk, list->name, NULL);
+               ret = clk_hw_register_clkdev(clk_hw, list->name, NULL);
                if (ret)
                        pr_err("%s: failed to register clock lookup for %s",
                                __func__, list->name);
@@ -168,19 +159,19 @@ void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx,
 void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx,
                const struct samsung_fixed_factor_clock *list, unsigned int nr_clk)
 {
-       struct clk *clk;
+       struct clk_hw *clk_hw;
        unsigned int idx;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk = clk_register_fixed_factor(NULL, list->name,
+               clk_hw = clk_hw_register_fixed_factor(NULL, list->name,
                        list->parent_name, list->flags, list->mult, list->div);
-               if (IS_ERR(clk)) {
+               if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
                        continue;
                }
 
-               samsung_clk_add_lookup(ctx, clk, list->id);
+               samsung_clk_add_lookup(ctx, clk_hw, list->id);
        }
 }
 
@@ -189,25 +180,25 @@ void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx,
                                const struct samsung_mux_clock *list,
                                unsigned int nr_clk)
 {
-       struct clk *clk;
+       struct clk_hw *clk_hw;
        unsigned int idx, ret;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk = clk_register_mux(NULL, list->name, list->parent_names,
-                       list->num_parents, list->flags,
+               clk_hw = clk_hw_register_mux(NULL, list->name,
+                       list->parent_names, list->num_parents, list->flags,
                        ctx->reg_base + list->offset,
                        list->shift, list->width, list->mux_flags, &ctx->lock);
-               if (IS_ERR(clk)) {
+               if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
                        continue;
                }
 
-               samsung_clk_add_lookup(ctx, clk, list->id);
+               samsung_clk_add_lookup(ctx, clk_hw, list->id);
 
                /* register a clock lookup only if a clock alias is specified */
                if (list->alias) {
-                       ret = clk_register_clkdev(clk, list->alias,
+                       ret = clk_hw_register_clkdev(clk_hw, list->alias,
                                                list->dev_name);
                        if (ret)
                                pr_err("%s: failed to register lookup %s\n",
@@ -221,32 +212,32 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
                                const struct samsung_div_clock *list,
                                unsigned int nr_clk)
 {
-       struct clk *clk;
+       struct clk_hw *clk_hw;
        unsigned int idx, ret;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
                if (list->table)
-                       clk = clk_register_divider_table(NULL, list->name,
-                               list->parent_name, list->flags,
+                       clk_hw = clk_hw_register_divider_table(NULL,
+                               list->name, list->parent_name, list->flags,
                                ctx->reg_base + list->offset,
                                list->shift, list->width, list->div_flags,
                                list->table, &ctx->lock);
                else
-                       clk = clk_register_divider(NULL, list->name,
+                       clk_hw = clk_hw_register_divider(NULL, list->name,
                                list->parent_name, list->flags,
                                ctx->reg_base + list->offset, list->shift,
                                list->width, list->div_flags, &ctx->lock);
-               if (IS_ERR(clk)) {
+               if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
                        continue;
                }
 
-               samsung_clk_add_lookup(ctx, clk, list->id);
+               samsung_clk_add_lookup(ctx, clk_hw, list->id);
 
                /* register a clock lookup only if a clock alias is specified */
                if (list->alias) {
-                       ret = clk_register_clkdev(clk, list->alias,
+                       ret = clk_hw_register_clkdev(clk_hw, list->alias,
                                                list->dev_name);
                        if (ret)
                                pr_err("%s: failed to register lookup %s\n",
@@ -260,14 +251,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
                                const struct samsung_gate_clock *list,
                                unsigned int nr_clk)
 {
-       struct clk *clk;
+       struct clk_hw *clk_hw;
        unsigned int idx, ret;
 
        for (idx = 0; idx < nr_clk; idx++, list++) {
-               clk = clk_register_gate(NULL, list->name, list->parent_name,
+               clk_hw = clk_hw_register_gate(NULL, list->name, list->parent_name,
                                list->flags, ctx->reg_base + list->offset,
                                list->bit_idx, list->gate_flags, &ctx->lock);
-               if (IS_ERR(clk)) {
+               if (IS_ERR(clk_hw)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
                        continue;
@@ -275,14 +266,14 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
 
                /* register a clock lookup only if a clock alias is specified */
                if (list->alias) {
-                       ret = clk_register_clkdev(clk, list->alias,
+                       ret = clk_hw_register_clkdev(clk_hw, list->alias,
                                                        list->dev_name);
                        if (ret)
                                pr_err("%s: failed to register lookup %s\n",
                                        __func__, list->alias);
                }
 
-               samsung_clk_add_lookup(ctx, clk, list->id);
+               samsung_clk_add_lookup(ctx, clk_hw, list->id);
        }
 }
 
index da3bdebabf1e32674c6875fb059461e09fef56ae..b8ca0dd3a38b771f2b2af998ad19cfff5e216fde 100644 (file)
 #include <linux/clk-provider.h>
 #include "clk-pll.h"
 
-struct clk;
-
 /**
  * struct samsung_clk_provider: information about clock provider
  * @reg_base: virtual address for the register base.
- * @clk_data: holds clock related data like clk* and number of clocks.
  * @lock: maintains exclusion between callbacks for a given clock-provider.
+ * @clk_data: holds clock related data like clk_hw* and number of clocks.
  */
 struct samsung_clk_provider {
        void __iomem *reg_base;
-       struct clk_onecell_data clk_data;
        spinlock_t lock;
+       /* clk_data must be the last entry due to variable lenght 'hws' array */
+       struct clk_hw_onecell_data clk_data;
 };
 
 /**
@@ -367,7 +366,7 @@ extern void __init samsung_clk_of_register_fixed_ext(
                        const struct of_device_id *clk_matches);
 
 extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx,
-                       struct clk *clk, unsigned int id);
+                       struct clk_hw *clk_hw, unsigned int id);
 
 extern void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx,
                        const struct samsung_clock_alias *list,
index c2d5727481671b57f0cde52e31f9122297c1bb5b..36376c542055cd94c319c6700f33c68f4ad13b21 100644 (file)
@@ -86,7 +86,7 @@ static int socfpga_clk_prepare(struct clk_hw *hwclk)
                        }
                }
 
-               hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
+               hs_timing = SYSMGR_SDMMC_CTRL_SET_AS10(clk_phase[0], clk_phase[1]);
                if (!IS_ERR(socfpgaclk->sys_mgr_base_addr))
                        regmap_write(socfpgaclk->sys_mgr_base_addr,
                                     SYSMGR_SDMMCGRP_CTRL_OFFSET, hs_timing);
index 814c7247bf73b071fcc2f19770a005425b404294..9cf1230115b176d42d6143232383e685c2b44b7b 100644 (file)
@@ -32,6 +32,9 @@
 #define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
        ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
 
+#define SYSMGR_SDMMC_CTRL_SET_AS10(smplsel, drvsel) \
+       ((((smplsel) & 0x7) << 4) | (((drvsel) & 0x7) << 0))
+
 extern void __iomem *clk_mgr_base_addr;
 extern void __iomem *clk_mgr_a10_base_addr;
 
index eb89c7801f001b4a0ea0fde521fe695a298036b9..7342928c35cd7d4caac62eee144896480e7210f6 100644 (file)
@@ -6,157 +6,55 @@ config SUNXI_CCU
 
 if SUNXI_CCU
 
-# Base clock types
-
-config SUNXI_CCU_DIV
-       bool
-       select SUNXI_CCU_MUX
-
-config SUNXI_CCU_FRAC
-       bool
-
-config SUNXI_CCU_GATE
-       def_bool y
-
-config SUNXI_CCU_MUX
-       bool
-
-config SUNXI_CCU_MULT
-       bool
-       select SUNXI_CCU_MUX
-
-config SUNXI_CCU_PHASE
-       bool
-
-# Multi-factor clocks
-
-config SUNXI_CCU_NK
-       bool
-       select SUNXI_CCU_GATE
-
-config SUNXI_CCU_NKM
-       bool
-       select SUNXI_CCU_GATE
-
-config SUNXI_CCU_NKMP
-       bool
-       select SUNXI_CCU_GATE
-
-config SUNXI_CCU_NM
-       bool
-       select SUNXI_CCU_FRAC
-       select SUNXI_CCU_GATE
-
-config SUNXI_CCU_MP
-       bool
-       select SUNXI_CCU_GATE
-       select SUNXI_CCU_MUX
-
-# SoC Drivers
-
 config SUN50I_A64_CCU
        bool "Support for the Allwinner A64 CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default ARM64 && ARCH_SUNXI
        depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN5I_CCU
        bool "Support for the Allwinner sun5i family CCM"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_MULT
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN5I
        depends on MACH_SUN5I || COMPILE_TEST
 
 config SUN6I_A31_CCU
        bool "Support for the Allwinner A31/A31s CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN6I
        depends on MACH_SUN6I || COMPILE_TEST
 
 config SUN8I_A23_CCU
        bool "Support for the Allwinner A23 CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_MULT
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
 config SUN8I_A33_CCU
        bool "Support for the Allwinner A33 CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_MULT
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
+config SUN8I_A83T_CCU
+       bool "Support for the Allwinner A83T CCU"
+       default MACH_SUN8I
+
 config SUN8I_H3_CCU
        bool "Support for the Allwinner H3 CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
        depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
 
 config SUN8I_V3S_CCU
        bool "Support for the Allwinner V3s CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_NK
-       select SUNXI_CCU_NKM
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN8I
        depends on MACH_SUN8I || COMPILE_TEST
 
+config SUN8I_DE2_CCU
+       bool "Support for the Allwinner SoCs DE2 CCU"
+
 config SUN9I_A80_CCU
        bool "Support for the Allwinner A80 CCU"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_MULT
-       select SUNXI_CCU_GATE
-       select SUNXI_CCU_NKMP
-       select SUNXI_CCU_NM
-       select SUNXI_CCU_MP
-       select SUNXI_CCU_PHASE
        default MACH_SUN9I
        depends on MACH_SUN9I || COMPILE_TEST
 
 config SUN8I_R_CCU
        bool "Support for Allwinner SoCs' PRCM CCUs"
-       select SUNXI_CCU_DIV
-       select SUNXI_CCU_GATE
-       select SUNXI_CCU_MP
        default MACH_SUN8I || (ARCH_SUNXI && ARM64)
 
 endif
index 0ec02fe14c502c595ede0139aae8c4095cd8869d..0c45fa50283dadf45880dc1b6145d05ad648356a 100644 (file)
@@ -1,21 +1,21 @@
 # Common objects
-obj-$(CONFIG_SUNXI_CCU)                += ccu_common.o
-obj-$(CONFIG_SUNXI_CCU)                += ccu_reset.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_common.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_reset.o
 
 # Base clock types
-obj-$(CONFIG_SUNXI_CCU_DIV)    += ccu_div.o
-obj-$(CONFIG_SUNXI_CCU_FRAC)   += ccu_frac.o
-obj-$(CONFIG_SUNXI_CCU_GATE)   += ccu_gate.o
-obj-$(CONFIG_SUNXI_CCU_MUX)    += ccu_mux.o
-obj-$(CONFIG_SUNXI_CCU_MULT)   += ccu_mult.o
-obj-$(CONFIG_SUNXI_CCU_PHASE)  += ccu_phase.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_div.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_frac.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_gate.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_mux.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_mult.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_phase.o
 
 # Multi-factor clocks
-obj-$(CONFIG_SUNXI_CCU_NK)     += ccu_nk.o
-obj-$(CONFIG_SUNXI_CCU_NKM)    += ccu_nkm.o
-obj-$(CONFIG_SUNXI_CCU_NKMP)   += ccu_nkmp.o
-obj-$(CONFIG_SUNXI_CCU_NM)     += ccu_nm.o
-obj-$(CONFIG_SUNXI_CCU_MP)     += ccu_mp.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_nk.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_nkm.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_nkmp.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_nm.o
+lib-$(CONFIG_SUNXI_CCU)                += ccu_mp.o
 
 # SoC support
 obj-$(CONFIG_SUN50I_A64_CCU)   += ccu-sun50i-a64.o
@@ -23,9 +23,20 @@ obj-$(CONFIG_SUN5I_CCU)              += ccu-sun5i.o
 obj-$(CONFIG_SUN6I_A31_CCU)    += ccu-sun6i-a31.o
 obj-$(CONFIG_SUN8I_A23_CCU)    += ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)    += ccu-sun8i-a33.o
+obj-$(CONFIG_SUN8I_A83T_CCU)   += ccu-sun8i-a83t.o
 obj-$(CONFIG_SUN8I_H3_CCU)     += ccu-sun8i-h3.o
 obj-$(CONFIG_SUN8I_V3S_CCU)    += ccu-sun8i-v3s.o
+obj-$(CONFIG_SUN8I_DE2_CCU)    += ccu-sun8i-de2.o
 obj-$(CONFIG_SUN8I_R_CCU)      += ccu-sun8i-r.o
 obj-$(CONFIG_SUN9I_A80_CCU)    += ccu-sun9i-a80.o
 obj-$(CONFIG_SUN9I_A80_CCU)    += ccu-sun9i-a80-de.o
 obj-$(CONFIG_SUN9I_A80_CCU)    += ccu-sun9i-a80-usb.o
+
+# The lib-y file goals is supposed to work only in arch/*/lib or lib/. In our
+# case, we want to use that goal, but even though lib.a will be properly
+# generated, it will not be linked in, eventually resulting in a linker error
+# for missing symbols.
+#
+# We can work around that by explicitly adding lib.a to the obj-y goal. This is
+# an undocumented behaviour, but works well for now.
+obj-$(CONFIG_SUNXI_CCU)                += lib.a
index f54114c607df76edeb77c70e0f7c97656e67634c..2bb4cabf802f0f1a5e77b2539a8bd7436a4019c0 100644 (file)
@@ -211,6 +211,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
 
 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
                                             "axi", "pll-periph0" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 3, .shift = 6, .width = 2 },
+};
 static struct ccu_div ahb1_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 
@@ -218,11 +221,8 @@ static struct ccu_div ahb1_clk = {
                .shift  = 12,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 3,
-                       .shift  = 6,
-                       .width  = 2,
-               },
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
        },
 
        .common         = {
index 8144487eb7caa4394c7f785a1e458eb9cf684521..93a275fbd9a907277c5ce49353dad95d73b61adf 100644 (file)
 #define CLK_PLL_AUDIO_4X       6
 #define CLK_PLL_AUDIO_8X       7
 #define CLK_PLL_VIDEO0         8
-#define CLK_PLL_VIDEO0_2X      9
+
+/* The PLL_VIDEO0_2X is exported for HDMI */
+
 #define CLK_PLL_VE             10
 #define CLK_PLL_DDR_BASE       11
 #define CLK_PLL_DDR            12
 #define CLK_PLL_DDR_OTHER      13
 #define CLK_PLL_PERIPH         14
 #define CLK_PLL_VIDEO1         15
-#define CLK_PLL_VIDEO1_2X      16
 
+/* The PLL_VIDEO1_2X is exported for HDMI */
 /* The CPU clock is exported */
 
 #define CLK_AXI                        18
index df97e25aec76b505ddb88ab7d4b3dc76475fb035..4d6078fca9aca641df08071cb3b003a75d395eb5 100644 (file)
@@ -195,6 +195,9 @@ static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu",
 
 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
                                             "axi", "pll-periph" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 3, .shift = 6, .width = 2 },
+};
 
 static struct ccu_div ahb1_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
@@ -203,11 +206,8 @@ static struct ccu_div ahb1_clk = {
                .shift  = 12,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 3,
-                       .shift  = 6,
-                       .width  = 2,
-               },
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
        },
 
        .common         = {
index 5c6d37bdf247cfef1b4da1bcf185d1b56082f036..8a753ed0426d40d2a58717424d2e6023258cec2d 100644 (file)
@@ -169,6 +169,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
 
 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
                                             "axi" , "pll-periph" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 3, .shift = 6, .width = 2 },
+};
 static struct ccu_div ahb1_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 
@@ -176,11 +179,8 @@ static struct ccu_div ahb1_clk = {
                .shift  = 12,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 3,
-                       .shift  = 6,
-                       .width  = 2,
-               },
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
        },
 
        .common         = {
index 8d38e6510e2959646a3959222e590f8fd4adc9a2..10b38dc46f7595fb1c709aa5eb076c4c818eba17 100644 (file)
@@ -180,6 +180,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
 
 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
                                             "axi" , "pll-periph" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 3, .shift = 6, .width = 2 },
+};
 static struct ccu_div ahb1_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 
@@ -187,11 +190,8 @@ static struct ccu_div ahb1_clk = {
                .shift  = 12,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 3,
-                       .shift  = 6,
-                       .width  = 2,
-               },
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
        },
 
        .common         = {
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c
new file mode 100644 (file)
index 0000000..947f9f6
--- /dev/null
@@ -0,0 +1,922 @@
+/*
+ * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mux.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun8i-a83t.h"
+
+#define CCU_SUN8I_A83T_LOCK_REG        0x20c
+
+/*
+ * The CPU PLLs are actually NP clocks, with P being /1 or /4. However
+ * P should only be used for output frequencies lower than 228 MHz.
+ * Neither mainline Linux, U-boot, nor the vendor BSPs use these.
+ *
+ * For now we can just model it as a multiplier clock, and force P to /1.
+ */
+#define SUN8I_A83T_PLL_C0CPUX_REG      0x000
+#define SUN8I_A83T_PLL_C1CPUX_REG      0x004
+
+static struct ccu_mult pll_c0cpux_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(0),
+       .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .common         = {
+               .reg            = SUN8I_A83T_PLL_C0CPUX_REG,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-c0cpux", "osc24M",
+                                             &ccu_mult_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_mult pll_c1cpux_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(1),
+       .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .common         = {
+               .reg            = SUN8I_A83T_PLL_C1CPUX_REG,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-c1cpux", "osc24M",
+                                             &ccu_mult_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+/*
+ * The Audio PLL has d1, d2 dividers in addition to the usual N, M
+ * factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
+ * and 24.576 MHz, ignore them for now. Enforce the default for them,
+ * which is d1 = 0, d2 = 1.
+ */
+#define SUN8I_A83T_PLL_AUDIO_REG       0x008
+
+static struct ccu_nm pll_audio_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(2),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(0, 6),
+       .common         = {
+               .reg            = SUN8I_A83T_PLL_AUDIO_REG,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-audio", "osc24M",
+                                             &ccu_nm_ops, CLK_SET_RATE_UNGATE),
+       },
+};
+
+/* Some PLLs are input * N / div1 / P. Model them as NKMP with no K */
+static struct ccu_nkmp pll_video0_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(3),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 2), /* output divider */
+       .common         = {
+               .reg            = 0x010,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-video0", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_ve_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(4),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
+       .common         = {
+               .reg            = 0x018,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-ve", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_ddr_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(5),
+       .n              = _SUNXI_CCU_MULT_MIN(8, 8, 12),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
+       .common         = {
+               .reg            = 0x020,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-ddr", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_periph_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(6),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
+       .common         = {
+               .reg            = 0x028,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-periph", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_gpu_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(7),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
+       .common         = {
+               .reg            = 0x038,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-gpu", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_hsic_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(8),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
+       .common         = {
+               .reg            = 0x044,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-hsic", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_de_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(9),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(18, 1), /* output divider */
+       .common         = {
+               .reg            = 0x048,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-de", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static struct ccu_nkmp pll_video1_clk = {
+       .enable         = BIT(31),
+       .lock           = BIT(10),
+       .n              = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
+       .m              = _SUNXI_CCU_DIV(16, 1), /* input divider */
+       .p              = _SUNXI_CCU_DIV(0, 2), /* external divider p */
+       .common         = {
+               .reg            = 0x04c,
+               .lock_reg       = CCU_SUN8I_A83T_LOCK_REG,
+               .features       = CCU_FEATURE_LOCK_REG,
+               .hw.init        = CLK_HW_INIT("pll-video1", "osc24M",
+                                             &ccu_nkmp_ops,
+                                             CLK_SET_RATE_UNGATE),
+       },
+};
+
+static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" };
+static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents,
+                    0x50, 12, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+
+static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" };
+static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents,
+                    0x50, 28, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+
+static SUNXI_CCU_M(axi0_clk, "axi0", "c0cpux", 0x050, 0, 2, 0);
+static SUNXI_CCU_M(axi1_clk, "axi1", "c1cpux", 0x050, 16, 2, 0);
+
+static const char * const ahb1_parents[] = { "osc16M-d512", "osc24M",
+                                            "pll-periph",
+                                            "pll-periph" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 2, .shift = 6, .width = 2 },
+       { .index = 3, .shift = 6, .width = 2 },
+};
+static struct ccu_div ahb1_clk = {
+       .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+       .mux            = {
+               .shift  = 12,
+               .width  = 2,
+
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
+       },
+       .common         = {
+               .reg            = 0x054,
+               .hw.init        = CLK_HW_INIT_PARENTS("ahb1",
+                                                     ahb1_parents,
+                                                     &ccu_div_ops,
+                                                     0),
+       },
+};
+
+static SUNXI_CCU_M(apb1_clk, "apb1", "ahb1", 0x054, 8, 2, 0);
+
+static const char * const apb2_parents[] = { "osc16M-d512", "osc24M",
+                                            "pll-periph", "pll-periph" };
+
+static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
+                            0, 5,      /* M */
+                            16, 2,     /* P */
+                            24, 2,     /* mux */
+                            0);
+
+static const char * const ahb2_parents[] = { "ahb1", "pll-periph" };
+static const struct ccu_mux_fixed_prediv ahb2_prediv = {
+       .index = 1, .div = 2
+};
+static struct ccu_mux ahb2_clk = {
+       .mux            = {
+               .shift          = 0,
+               .width          = 2,
+               .fixed_predivs  = &ahb2_prediv,
+               .n_predivs      = 1,
+       },
+       .common         = {
+               .reg            = 0x05c,
+               .hw.init        = CLK_HW_INIT_PARENTS("ahb2",
+                                                     ahb2_parents,
+                                                     &ccu_mux_ops,
+                                                     0),
+       },
+};
+
+static SUNXI_CCU_GATE(bus_mipi_dsi_clk,        "bus-mipi-dsi", "ahb1",
+                     0x060, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_ss_clk,      "bus-ss",       "ahb1",
+                     0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_dma_clk,     "bus-dma",      "ahb1",
+                     0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(bus_mmc0_clk,    "bus-mmc0",     "ahb1",
+                     0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(bus_mmc1_clk,    "bus-mmc1",     "ahb1",
+                     0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(bus_mmc2_clk,    "bus-mmc2",     "ahb1",
+                     0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(bus_nand_clk,    "bus-nand",     "ahb1",
+                     0x060, BIT(13), 0);
+static SUNXI_CCU_GATE(bus_dram_clk,    "bus-dram",     "ahb1",
+                     0x060, BIT(14), 0);
+static SUNXI_CCU_GATE(bus_emac_clk,    "bus-emac",     "ahb2",
+                     0x060, BIT(17), 0);
+static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer",  "ahb1",
+                     0x060, BIT(19), 0);
+static SUNXI_CCU_GATE(bus_spi0_clk,    "bus-spi0",     "ahb1",
+                     0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(bus_spi1_clk,    "bus-spi1",     "ahb1",
+                     0x060, BIT(21), 0);
+static SUNXI_CCU_GATE(bus_otg_clk,     "bus-otg",      "ahb1",
+                     0x060, BIT(24), 0);
+static SUNXI_CCU_GATE(bus_ehci0_clk,   "bus-ehci0",    "ahb2",
+                     0x060, BIT(26), 0);
+static SUNXI_CCU_GATE(bus_ehci1_clk,   "bus-ehci1",    "ahb2",
+                     0x060, BIT(27), 0);
+static SUNXI_CCU_GATE(bus_ohci0_clk,   "bus-ohci0",    "ahb2",
+                     0x060, BIT(29), 0);
+
+static SUNXI_CCU_GATE(bus_ve_clk,      "bus-ve",       "ahb1",
+                     0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_tcon0_clk,   "bus-tcon0",    "ahb1",
+                     0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(bus_tcon1_clk,   "bus-tcon1",    "ahb1",
+                     0x064, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_csi_clk,     "bus-csi",      "ahb1",
+                     0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(bus_hdmi_clk,    "bus-hdmi",     "ahb1",
+                     0x064, BIT(11), 0);
+static SUNXI_CCU_GATE(bus_de_clk,      "bus-de",       "ahb1",
+                     0x064, BIT(12), 0);
+static SUNXI_CCU_GATE(bus_gpu_clk,     "bus-gpu",      "ahb1",
+                     0x064, BIT(20), 0);
+static SUNXI_CCU_GATE(bus_msgbox_clk,  "bus-msgbox",   "ahb1",
+                     0x064, BIT(21), 0);
+static SUNXI_CCU_GATE(bus_spinlock_clk,        "bus-spinlock", "ahb1",
+                     0x064, BIT(22), 0);
+
+static SUNXI_CCU_GATE(bus_spdif_clk,   "bus-spdif",    "apb1",
+                     0x068, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_pio_clk,     "bus-pio",      "apb1",
+                     0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(bus_i2s0_clk,    "bus-i2s0",     "apb1",
+                     0x068, BIT(12), 0);
+static SUNXI_CCU_GATE(bus_i2s1_clk,    "bus-i2s1",     "apb1",
+                     0x068, BIT(13), 0);
+static SUNXI_CCU_GATE(bus_i2s2_clk,    "bus-i2s2",     "apb1",
+                     0x068, BIT(14), 0);
+static SUNXI_CCU_GATE(bus_tdm_clk,     "bus-tdm",      "apb1",
+                     0x068, BIT(15), 0);
+
+static SUNXI_CCU_GATE(bus_i2c0_clk,    "bus-i2c0",     "apb2",
+                     0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c1_clk,    "bus-i2c1",     "apb2",
+                     0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_i2c2_clk,    "bus-i2c2",     "apb2",
+                     0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_uart0_clk,   "bus-uart0",    "apb2",
+                     0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(bus_uart1_clk,   "bus-uart1",    "apb2",
+                     0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(bus_uart2_clk,   "bus-uart2",    "apb2",
+                     0x06c, BIT(18), 0);
+static SUNXI_CCU_GATE(bus_uart3_clk,   "bus-uart3",    "apb2",
+                     0x06c, BIT(19), 0);
+static SUNXI_CCU_GATE(bus_uart4_clk,   "bus-uart4",    "apb2",
+                     0x06c, BIT(20), 0);
+
+static const char * const cci400_parents[] = { "osc24M", "pll-periph",
+                                              "pll-hsic" };
+static struct ccu_div cci400_clk = {
+       .div            = _SUNXI_CCU_DIV_FLAGS(0, 2, 0),
+       .mux            = _SUNXI_CCU_MUX(24, 2),
+       .common         = {
+               .reg            = 0x078,
+               .hw.init        = CLK_HW_INIT_PARENTS("cci400",
+                                                     cci400_parents,
+                                                     &ccu_div_ops,
+                                                     CLK_IS_CRITICAL),
+       },
+};
+
+static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents,
+                                 0x080,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 2,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
+                                 0x088,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 2,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0-sample", "mmc0",
+                      0x088, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0-output", "mmc0",
+                      0x088, 8, 3, 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
+                                 0x08c,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 2,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1",
+                      0x08c, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1",
+                      0x08c, 8, 3, 0);
+
+/* TODO Support MMC2 clock's new timing mode. */
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
+                                 0x090,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 2,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2",
+                      0x090, 20, 3, 0);
+static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2-output", "mmc2",
+                      0x090, 8, 3, 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents,
+                                 0x09c,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 2,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents,
+                                 0x0a0,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 4,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents,
+                                 0x0a4,
+                                 0, 4,         /* M */
+                                 16, 2,        /* P */
+                                 24, 4,        /* mux */
+                                 BIT(31),      /* gate */
+                                 0);
+
+static SUNXI_CCU_M_WITH_GATE(i2s0_clk, "i2s0", "pll-audio",
+                            0x0b0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M_WITH_GATE(i2s1_clk, "i2s1", "pll-audio",
+                            0x0b4, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M_WITH_GATE(i2s2_clk, "i2s2", "pll-audio",
+                            0x0b8, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M_WITH_GATE(tdm_clk, "tdm", "pll-audio",
+                            0x0bc, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
+                            0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(usb_phy0_clk,    "usb-phy0",     "osc24M",
+                     0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk,    "usb-phy1",     "osc24M",
+                     0x0cc, BIT(9), 0);
+static SUNXI_CCU_GATE(usb_hsic_clk,    "usb-hsic",     "pll-hsic",
+                     0x0cc, BIT(10), 0);
+static struct ccu_gate usb_hsic_12m_clk = {
+       .enable = BIT(11),
+       .common = {
+               .reg            = 0x0cc,
+               .prediv         = 2,
+               .features       = CCU_FEATURE_ALL_PREDIV,
+               .hw.init        = CLK_HW_INIT("usb-hsic-12m", "osc24M",
+                                             &ccu_gate_ops, 0),
+       }
+};
+static SUNXI_CCU_GATE(usb_ohci0_clk,   "usb-ohci0",    "osc24M",
+                     0x0cc, BIT(16), 0);
+
+/* TODO divider has minimum of 2 */
+static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", 0x0f4, 0, 4, CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE(dram_ve_clk,     "dram-ve",      "dram",
+                     0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk,    "dram-csi",     "dram",
+                     0x100, BIT(1), 0);
+
+static const char * const tcon0_parents[] = { "pll-video0" };
+static SUNXI_CCU_MUX_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
+                                0x118, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
+
+static const char * const tcon1_parents[] = { "pll-video1" };
+static SUNXI_CCU_MUX_WITH_GATE(tcon1_clk, "tcon1", tcon1_parents,
+                                0x11c, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
+
+static SUNXI_CCU_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x130, BIT(31), 0);
+
+static const char * const csi_mclk_parents[] = { "pll-de", "osc24M" };
+static const u8 csi_mclk_table[] = { 3, 5 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
+                                      csi_mclk_parents, csi_mclk_table,
+                                      0x134,
+                                      0, 5,    /* M */
+                                      10, 3,   /* mux */
+                                      BIT(15), /* gate */
+                                      0);
+
+static const char * const csi_sclk_parents[] = { "pll-periph", "pll-ve" };
+static const u8 csi_sclk_table[] = { 0, 5 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
+                                      csi_sclk_parents, csi_sclk_table,
+                                      0x134,
+                                      16, 4,   /* M */
+                                      24, 3,   /* mux */
+                                      BIT(31), /* gate */
+                                      0);
+
+static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c,
+                            16, 3, BIT(31), CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0);
+
+static const char * const hdmi_parents[] = { "pll-video1" };
+static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
+                                0x150,
+                                0, 4,  /* M */
+                                24, 2, /* mux */
+                                BIT(31),       /* gate */
+                                CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0x154, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "osc24M", "pll-periph",
+                                            "pll-ddr" };
+static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+                                0x15c,
+                                0, 3,  /* M */
+                                24, 2, /* mux */
+                                BIT(31),       /* gate */
+                                CLK_IS_CRITICAL);
+
+static const char * const mipi_dsi0_parents[] = { "pll-video0" };
+static const u8 mipi_dsi0_table[] = { 8 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk, "mipi-dsi0",
+                                      mipi_dsi0_parents, mipi_dsi0_table,
+                                      0x168,
+                                      0, 4,    /* M */
+                                      24, 4,   /* mux */
+                                      BIT(31), /* gate */
+                                      CLK_SET_RATE_PARENT);
+
+static const char * const mipi_dsi1_parents[] = { "osc24M", "pll-video0" };
+static const u8 mipi_dsi1_table[] = { 0, 9 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk, "mipi-dsi1",
+                                      mipi_dsi1_parents, mipi_dsi1_table,
+                                      0x16c,
+                                      0, 4,    /* M */
+                                      24, 4,   /* mux */
+                                      BIT(31), /* gate */
+                                      CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu", 0x1a0,
+                            0, 3, BIT(31), CLK_SET_RATE_PARENT);
+
+static const char * const gpu_memory_parents[] = { "pll-gpu", "pll-ddr" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_memory_clk, "gpu-memory",
+                                gpu_memory_parents,
+                                0x1a4,
+                                0, 3,          /* M */
+                                24, 1,         /* mux */
+                                BIT(31),       /* gate */
+                                CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_M_WITH_GATE(gpu_hyd_clk, "gpu-hyd", "pll-gpu", 0x1a8,
+                            0, 3, BIT(31), CLK_SET_RATE_PARENT);
+
+static struct ccu_common *sun8i_a83t_ccu_clks[] = {
+       &pll_c0cpux_clk.common,
+       &pll_c1cpux_clk.common,
+       &pll_audio_clk.common,
+       &pll_video0_clk.common,
+       &pll_ve_clk.common,
+       &pll_ddr_clk.common,
+       &pll_periph_clk.common,
+       &pll_gpu_clk.common,
+       &pll_hsic_clk.common,
+       &pll_de_clk.common,
+       &pll_video1_clk.common,
+       &c0cpux_clk.common,
+       &c1cpux_clk.common,
+       &axi0_clk.common,
+       &axi1_clk.common,
+       &ahb1_clk.common,
+       &ahb2_clk.common,
+       &apb1_clk.common,
+       &apb2_clk.common,
+       &bus_mipi_dsi_clk.common,
+       &bus_ss_clk.common,
+       &bus_dma_clk.common,
+       &bus_mmc0_clk.common,
+       &bus_mmc1_clk.common,
+       &bus_mmc2_clk.common,
+       &bus_nand_clk.common,
+       &bus_dram_clk.common,
+       &bus_emac_clk.common,
+       &bus_hstimer_clk.common,
+       &bus_spi0_clk.common,
+       &bus_spi1_clk.common,
+       &bus_otg_clk.common,
+       &bus_ehci0_clk.common,
+       &bus_ehci1_clk.common,
+       &bus_ohci0_clk.common,
+       &bus_ve_clk.common,
+       &bus_tcon0_clk.common,
+       &bus_tcon1_clk.common,
+       &bus_csi_clk.common,
+       &bus_hdmi_clk.common,
+       &bus_de_clk.common,
+       &bus_gpu_clk.common,
+       &bus_msgbox_clk.common,
+       &bus_spinlock_clk.common,
+       &bus_spdif_clk.common,
+       &bus_pio_clk.common,
+       &bus_i2s0_clk.common,
+       &bus_i2s1_clk.common,
+       &bus_i2s2_clk.common,
+       &bus_tdm_clk.common,
+       &bus_i2c0_clk.common,
+       &bus_i2c1_clk.common,
+       &bus_i2c2_clk.common,
+       &bus_uart0_clk.common,
+       &bus_uart1_clk.common,
+       &bus_uart2_clk.common,
+       &bus_uart3_clk.common,
+       &bus_uart4_clk.common,
+       &cci400_clk.common,
+       &nand_clk.common,
+       &mmc0_clk.common,
+       &mmc0_sample_clk.common,
+       &mmc0_output_clk.common,
+       &mmc1_clk.common,
+       &mmc1_sample_clk.common,
+       &mmc1_output_clk.common,
+       &mmc2_clk.common,
+       &mmc2_sample_clk.common,
+       &mmc2_output_clk.common,
+       &ss_clk.common,
+       &spi0_clk.common,
+       &spi1_clk.common,
+       &i2s0_clk.common,
+       &i2s1_clk.common,
+       &i2s2_clk.common,
+       &tdm_clk.common,
+       &spdif_clk.common,
+       &usb_phy0_clk.common,
+       &usb_phy1_clk.common,
+       &usb_hsic_clk.common,
+       &usb_hsic_12m_clk.common,
+       &usb_ohci0_clk.common,
+       &dram_clk.common,
+       &dram_ve_clk.common,
+       &dram_csi_clk.common,
+       &tcon0_clk.common,
+       &tcon1_clk.common,
+       &csi_misc_clk.common,
+       &mipi_csi_clk.common,
+       &csi_mclk_clk.common,
+       &csi_sclk_clk.common,
+       &ve_clk.common,
+       &avs_clk.common,
+       &hdmi_clk.common,
+       &hdmi_slow_clk.common,
+       &mbus_clk.common,
+       &mipi_dsi0_clk.common,
+       &mipi_dsi1_clk.common,
+       &gpu_core_clk.common,
+       &gpu_memory_clk.common,
+       &gpu_hyd_clk.common,
+};
+
+static struct clk_hw_onecell_data sun8i_a83t_hw_clks = {
+       .hws    = {
+               [CLK_PLL_C0CPUX]        = &pll_c0cpux_clk.common.hw,
+               [CLK_PLL_C1CPUX]        = &pll_c1cpux_clk.common.hw,
+               [CLK_PLL_AUDIO]         = &pll_audio_clk.common.hw,
+               [CLK_PLL_VIDEO0]        = &pll_video0_clk.common.hw,
+               [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
+               [CLK_PLL_DDR]           = &pll_ddr_clk.common.hw,
+               [CLK_PLL_PERIPH]        = &pll_periph_clk.common.hw,
+               [CLK_PLL_GPU]           = &pll_gpu_clk.common.hw,
+               [CLK_PLL_HSIC]          = &pll_hsic_clk.common.hw,
+               [CLK_PLL_DE]            = &pll_de_clk.common.hw,
+               [CLK_PLL_VIDEO1]        = &pll_video1_clk.common.hw,
+               [CLK_C0CPUX]            = &c0cpux_clk.common.hw,
+               [CLK_C1CPUX]            = &c1cpux_clk.common.hw,
+               [CLK_AXI0]              = &axi0_clk.common.hw,
+               [CLK_AXI1]              = &axi1_clk.common.hw,
+               [CLK_AHB1]              = &ahb1_clk.common.hw,
+               [CLK_AHB2]              = &ahb2_clk.common.hw,
+               [CLK_APB1]              = &apb1_clk.common.hw,
+               [CLK_APB2]              = &apb2_clk.common.hw,
+               [CLK_BUS_MIPI_DSI]      = &bus_mipi_dsi_clk.common.hw,
+               [CLK_BUS_SS]            = &bus_ss_clk.common.hw,
+               [CLK_BUS_DMA]           = &bus_dma_clk.common.hw,
+               [CLK_BUS_MMC0]          = &bus_mmc0_clk.common.hw,
+               [CLK_BUS_MMC1]          = &bus_mmc1_clk.common.hw,
+               [CLK_BUS_MMC2]          = &bus_mmc2_clk.common.hw,
+               [CLK_BUS_NAND]          = &bus_nand_clk.common.hw,
+               [CLK_BUS_DRAM]          = &bus_dram_clk.common.hw,
+               [CLK_BUS_EMAC]          = &bus_emac_clk.common.hw,
+               [CLK_BUS_HSTIMER]       = &bus_hstimer_clk.common.hw,
+               [CLK_BUS_SPI0]          = &bus_spi0_clk.common.hw,
+               [CLK_BUS_SPI1]          = &bus_spi1_clk.common.hw,
+               [CLK_BUS_OTG]           = &bus_otg_clk.common.hw,
+               [CLK_BUS_EHCI0]         = &bus_ehci0_clk.common.hw,
+               [CLK_BUS_EHCI1]         = &bus_ehci1_clk.common.hw,
+               [CLK_BUS_OHCI0]         = &bus_ohci0_clk.common.hw,
+               [CLK_BUS_VE]            = &bus_ve_clk.common.hw,
+               [CLK_BUS_TCON0]         = &bus_tcon0_clk.common.hw,
+               [CLK_BUS_TCON1]         = &bus_tcon1_clk.common.hw,
+               [CLK_BUS_CSI]           = &bus_csi_clk.common.hw,
+               [CLK_BUS_HDMI]          = &bus_hdmi_clk.common.hw,
+               [CLK_BUS_DE]            = &bus_de_clk.common.hw,
+               [CLK_BUS_GPU]           = &bus_gpu_clk.common.hw,
+               [CLK_BUS_MSGBOX]        = &bus_msgbox_clk.common.hw,
+               [CLK_BUS_SPINLOCK]      = &bus_spinlock_clk.common.hw,
+               [CLK_BUS_SPDIF]         = &bus_spdif_clk.common.hw,
+               [CLK_BUS_PIO]           = &bus_pio_clk.common.hw,
+               [CLK_BUS_I2S0]          = &bus_i2s0_clk.common.hw,
+               [CLK_BUS_I2S1]          = &bus_i2s1_clk.common.hw,
+               [CLK_BUS_I2S2]          = &bus_i2s2_clk.common.hw,
+               [CLK_BUS_TDM]           = &bus_tdm_clk.common.hw,
+               [CLK_BUS_I2C0]          = &bus_i2c0_clk.common.hw,
+               [CLK_BUS_I2C1]          = &bus_i2c1_clk.common.hw,
+               [CLK_BUS_I2C2]          = &bus_i2c2_clk.common.hw,
+               [CLK_BUS_UART0]         = &bus_uart0_clk.common.hw,
+               [CLK_BUS_UART1]         = &bus_uart1_clk.common.hw,
+               [CLK_BUS_UART2]         = &bus_uart2_clk.common.hw,
+               [CLK_BUS_UART3]         = &bus_uart3_clk.common.hw,
+               [CLK_BUS_UART4]         = &bus_uart4_clk.common.hw,
+               [CLK_CCI400]            = &cci400_clk.common.hw,
+               [CLK_NAND]              = &nand_clk.common.hw,
+               [CLK_MMC0]              = &mmc0_clk.common.hw,
+               [CLK_MMC0_SAMPLE]       = &mmc0_sample_clk.common.hw,
+               [CLK_MMC0_OUTPUT]       = &mmc0_output_clk.common.hw,
+               [CLK_MMC1]              = &mmc1_clk.common.hw,
+               [CLK_MMC1_SAMPLE]       = &mmc1_sample_clk.common.hw,
+               [CLK_MMC1_OUTPUT]       = &mmc1_output_clk.common.hw,
+               [CLK_MMC2]              = &mmc2_clk.common.hw,
+               [CLK_MMC2_SAMPLE]       = &mmc2_sample_clk.common.hw,
+               [CLK_MMC2_OUTPUT]       = &mmc2_output_clk.common.hw,
+               [CLK_SS]                = &ss_clk.common.hw,
+               [CLK_SPI0]              = &spi0_clk.common.hw,
+               [CLK_SPI1]              = &spi1_clk.common.hw,
+               [CLK_I2S0]              = &i2s0_clk.common.hw,
+               [CLK_I2S1]              = &i2s1_clk.common.hw,
+               [CLK_I2S2]              = &i2s2_clk.common.hw,
+               [CLK_TDM]               = &tdm_clk.common.hw,
+               [CLK_SPDIF]             = &spdif_clk.common.hw,
+               [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
+               [CLK_USB_PHY1]          = &usb_phy1_clk.common.hw,
+               [CLK_USB_HSIC]          = &usb_hsic_clk.common.hw,
+               [CLK_USB_HSIC_12M]      = &usb_hsic_12m_clk.common.hw,
+               [CLK_USB_OHCI0]         = &usb_ohci0_clk.common.hw,
+               [CLK_DRAM]              = &dram_clk.common.hw,
+               [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
+               [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
+               [CLK_TCON0]             = &tcon0_clk.common.hw,
+               [CLK_TCON1]             = &tcon1_clk.common.hw,
+               [CLK_CSI_MISC]          = &csi_misc_clk.common.hw,
+               [CLK_MIPI_CSI]          = &mipi_csi_clk.common.hw,
+               [CLK_CSI_MCLK]          = &csi_mclk_clk.common.hw,
+               [CLK_CSI_SCLK]          = &csi_sclk_clk.common.hw,
+               [CLK_VE]                = &ve_clk.common.hw,
+               [CLK_AVS]               = &avs_clk.common.hw,
+               [CLK_HDMI]              = &hdmi_clk.common.hw,
+               [CLK_HDMI_SLOW]         = &hdmi_slow_clk.common.hw,
+               [CLK_MBUS]              = &mbus_clk.common.hw,
+               [CLK_MIPI_DSI0]         = &mipi_dsi0_clk.common.hw,
+               [CLK_MIPI_DSI1]         = &mipi_dsi1_clk.common.hw,
+               [CLK_GPU_CORE]          = &gpu_core_clk.common.hw,
+               [CLK_GPU_MEMORY]        = &gpu_memory_clk.common.hw,
+               [CLK_GPU_HYD]           = &gpu_hyd_clk.common.hw,
+       },
+       .num    = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun8i_a83t_ccu_resets[] = {
+       [RST_USB_PHY0]          = { 0x0cc, BIT(0) },
+       [RST_USB_PHY1]          = { 0x0cc, BIT(1) },
+       [RST_USB_HSIC]          = { 0x0cc, BIT(2) },
+       [RST_DRAM]              = { 0x0f4, BIT(31) },
+       [RST_MBUS]              = { 0x0fc, BIT(31) },
+       [RST_BUS_MIPI_DSI]      = { 0x2c0, BIT(1) },
+       [RST_BUS_SS]            = { 0x2c0, BIT(5) },
+       [RST_BUS_DMA]           = { 0x2c0, BIT(6) },
+       [RST_BUS_MMC0]          = { 0x2c0, BIT(8) },
+       [RST_BUS_MMC1]          = { 0x2c0, BIT(9) },
+       [RST_BUS_MMC2]          = { 0x2c0, BIT(10) },
+       [RST_BUS_NAND]          = { 0x2c0, BIT(13) },
+       [RST_BUS_DRAM]          = { 0x2c0, BIT(14) },
+       [RST_BUS_EMAC]          = { 0x2c0, BIT(17) },
+       [RST_BUS_HSTIMER]       = { 0x2c0, BIT(19) },
+       [RST_BUS_SPI0]          = { 0x2c0, BIT(20) },
+       [RST_BUS_SPI1]          = { 0x2c0, BIT(21) },
+       [RST_BUS_OTG]           = { 0x2c0, BIT(24) },
+       [RST_BUS_EHCI0]         = { 0x2c0, BIT(26) },
+       [RST_BUS_EHCI1]         = { 0x2c0, BIT(27) },
+       [RST_BUS_OHCI0]         = { 0x2c0, BIT(29) },
+       [RST_BUS_VE]            = { 0x2c4, BIT(0) },
+       [RST_BUS_TCON0]         = { 0x2c4, BIT(4) },
+       [RST_BUS_TCON1]         = { 0x2c4, BIT(5) },
+       [RST_BUS_CSI]           = { 0x2c4, BIT(8) },
+       [RST_BUS_HDMI0]         = { 0x2c4, BIT(10) },
+       [RST_BUS_HDMI1]         = { 0x2c4, BIT(11) },
+       [RST_BUS_DE]            = { 0x2c4, BIT(12) },
+       [RST_BUS_GPU]           = { 0x2c4, BIT(20) },
+       [RST_BUS_MSGBOX]        = { 0x2c4, BIT(21) },
+       [RST_BUS_SPINLOCK]      = { 0x2c4, BIT(22) },
+       [RST_BUS_LVDS]          = { 0x2c8, BIT(0) },
+       [RST_BUS_SPDIF]         = { 0x2d0, BIT(1) },
+       [RST_BUS_I2S0]          = { 0x2d0, BIT(12) },
+       [RST_BUS_I2S1]          = { 0x2d0, BIT(13) },
+       [RST_BUS_I2S2]          = { 0x2d0, BIT(14) },
+       [RST_BUS_TDM]           = { 0x2d0, BIT(15) },
+       [RST_BUS_I2C0]          = { 0x2d8, BIT(0) },
+       [RST_BUS_I2C1]          = { 0x2d8, BIT(1) },
+       [RST_BUS_I2C2]          = { 0x2d8, BIT(2) },
+       [RST_BUS_UART0]         = { 0x2d8, BIT(16) },
+       [RST_BUS_UART1]         = { 0x2d8, BIT(17) },
+       [RST_BUS_UART2]         = { 0x2d8, BIT(18) },
+       [RST_BUS_UART3]         = { 0x2d8, BIT(19) },
+       [RST_BUS_UART4]         = { 0x2d8, BIT(20) },
+};
+
+static const struct sunxi_ccu_desc sun8i_a83t_ccu_desc = {
+       .ccu_clks       = sun8i_a83t_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_ccu_clks),
+
+       .hw_clks        = &sun8i_a83t_hw_clks,
+
+       .resets         = sun8i_a83t_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun8i_a83t_ccu_resets),
+};
+
+#define SUN8I_A83T_PLL_P_SHIFT 16
+#define SUN8I_A83T_PLL_N_SHIFT 8
+#define SUN8I_A83T_PLL_N_WIDTH 8
+
+static void sun8i_a83t_cpu_pll_fixup(void __iomem *reg)
+{
+       u32 val = readl(reg);
+
+       /* bail out if P divider is not used */
+       if (!(val & BIT(SUN8I_A83T_PLL_P_SHIFT)))
+               return;
+
+       /*
+        * If P is used, output should be less than 288 MHz. When we
+        * set P to 1, we should also decrease the multiplier so the
+        * output doesn't go out of range, but not too much such that
+        * the multiplier stays above 12, the minimal operation value.
+        *
+        * To keep it simple, set the multiplier to 17, the reset value.
+        */
+       val &= ~GENMASK(SUN8I_A83T_PLL_N_SHIFT + SUN8I_A83T_PLL_N_WIDTH - 1,
+                       SUN8I_A83T_PLL_N_SHIFT);
+       val |= 17 << SUN8I_A83T_PLL_N_SHIFT;
+
+       /* And clear P */
+       val &= ~BIT(SUN8I_A83T_PLL_P_SHIFT);
+
+       writel(val, reg);
+}
+
+static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       void __iomem *reg;
+       u32 val;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       /* Enforce d1 = 0, d2 = 0 for Audio PLL */
+       val = readl(reg + SUN8I_A83T_PLL_AUDIO_REG);
+       val &= ~(BIT(16) | BIT(18));
+       writel(val, reg + SUN8I_A83T_PLL_AUDIO_REG);
+
+       /* Enforce P = 1 for both CPU cluster PLLs */
+       sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG);
+       sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG);
+
+       return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc);
+}
+
+static const struct of_device_id sun8i_a83t_ccu_ids[] = {
+       { .compatible = "allwinner,sun8i-a83t-ccu" },
+       { }
+};
+
+static struct platform_driver sun8i_a83t_ccu_driver = {
+       .probe  = sun8i_a83t_ccu_probe,
+       .driver = {
+               .name   = "sun8i-a83t-ccu",
+               .of_match_table = sun8i_a83t_ccu_ids,
+       },
+};
+builtin_platform_driver(sun8i_a83t_ccu_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.h b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.h
new file mode 100644 (file)
index 0000000..d67edaf
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens@csie.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SUN8I_A83T_H_
+#define _CCU_SUN8I_A83T_H_
+
+#include <dt-bindings/clock/sun8i-a83t-ccu.h>
+#include <dt-bindings/reset/sun8i-a83t-ccu.h>
+
+#define CLK_PLL_C0CPUX         0
+#define CLK_PLL_C1CPUX         1
+#define CLK_PLL_AUDIO          2
+#define CLK_PLL_VIDEO0         3
+#define CLK_PLL_VE             4
+#define CLK_PLL_DDR            5
+
+/* pll-periph is exported to the PRCM block */
+
+#define CLK_PLL_GPU            7
+#define CLK_PLL_HSIC           8
+
+/* pll-de is exported for the display engine */
+
+#define CLK_PLL_VIDEO1         10
+
+/* The CPUX clocks are exported */
+
+#define CLK_AXI0               13
+#define CLK_AXI1               14
+#define CLK_AHB1               15
+#define CLK_AHB2               16
+#define CLK_APB1               17
+#define CLK_APB2               18
+
+/* bus gates exported */
+
+#define CLK_CCI400             58
+
+/* module and usb clocks exported */
+
+#define CLK_DRAM               82
+
+/* dram gates and more module clocks exported */
+
+#define CLK_MBUS               95
+
+/* more module clocks exported */
+
+#define CLK_NUMBER             (CLK_GPU_HYD + 1)
+
+#endif /* _CCU_SUN8I_A83T_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
new file mode 100644 (file)
index 0000000..5cdaf52
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include "ccu_common.h"
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_reset.h"
+
+#include "ccu-sun8i-de2.h"
+
+static SUNXI_CCU_GATE(bus_mixer0_clk,  "bus-mixer0",   "bus-de",
+                     0x04, BIT(0), 0);
+static SUNXI_CCU_GATE(bus_mixer1_clk,  "bus-mixer1",   "bus-de",
+                     0x04, BIT(1), 0);
+static SUNXI_CCU_GATE(bus_wb_clk,      "bus-wb",       "bus-de",
+                     0x04, BIT(2), 0);
+
+static SUNXI_CCU_GATE(mixer0_clk,      "mixer0",       "mixer0-div",
+                     0x00, BIT(0), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE(mixer1_clk,      "mixer1",       "mixer1-div",
+                     0x00, BIT(1), CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE(wb_clk,          "wb",           "wb-div",
+                     0x00, BIT(2), CLK_SET_RATE_PARENT);
+
+static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
+                  CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
+                  CLK_SET_RATE_PARENT);
+static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
+                  CLK_SET_RATE_PARENT);
+
+static struct ccu_common *sun8i_a83t_de2_clks[] = {
+       &mixer0_clk.common,
+       &mixer1_clk.common,
+       &wb_clk.common,
+
+       &bus_mixer0_clk.common,
+       &bus_mixer1_clk.common,
+       &bus_wb_clk.common,
+
+       &mixer0_div_clk.common,
+       &mixer1_div_clk.common,
+       &wb_div_clk.common,
+};
+
+static struct ccu_common *sun8i_v3s_de2_clks[] = {
+       &mixer0_clk.common,
+       &wb_clk.common,
+
+       &bus_mixer0_clk.common,
+       &bus_wb_clk.common,
+
+       &mixer0_div_clk.common,
+       &wb_div_clk.common,
+};
+
+static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
+       .hws    = {
+               [CLK_MIXER0]            = &mixer0_clk.common.hw,
+               [CLK_MIXER1]            = &mixer1_clk.common.hw,
+               [CLK_WB]                = &wb_clk.common.hw,
+
+               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
+               [CLK_BUS_MIXER1]        = &bus_mixer1_clk.common.hw,
+               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
+
+               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
+               [CLK_MIXER1_DIV]        = &mixer1_div_clk.common.hw,
+               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
+       },
+       .num    = CLK_NUMBER,
+};
+
+static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = {
+       .hws    = {
+               [CLK_MIXER0]            = &mixer0_clk.common.hw,
+               [CLK_WB]                = &wb_clk.common.hw,
+
+               [CLK_BUS_MIXER0]        = &bus_mixer0_clk.common.hw,
+               [CLK_BUS_WB]            = &bus_wb_clk.common.hw,
+
+               [CLK_MIXER0_DIV]        = &mixer0_div_clk.common.hw,
+               [CLK_WB_DIV]            = &wb_div_clk.common.hw,
+       },
+       .num    = CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun8i_a83t_de2_resets[] = {
+       [RST_MIXER0]    = { 0x08, BIT(0) },
+       /*
+        * For A83T, H3 and R40, mixer1 reset line is shared with wb, so
+        * only RST_WB is exported here.
+        * For V3s there's just no mixer1, so it also shares this struct.
+        */
+       [RST_WB]        = { 0x08, BIT(2) },
+};
+
+static struct ccu_reset_map sun50i_a64_de2_resets[] = {
+       [RST_MIXER0]    = { 0x08, BIT(0) },
+       [RST_MIXER1]    = { 0x08, BIT(1) },
+       [RST_WB]        = { 0x08, BIT(2) },
+};
+
+static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
+       .ccu_clks       = sun8i_a83t_de2_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_de2_clks),
+
+       .hw_clks        = &sun8i_a83t_de2_hw_clks,
+
+       .resets         = sun8i_a83t_de2_resets,
+       .num_resets     = ARRAY_SIZE(sun8i_a83t_de2_resets),
+};
+
+static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
+       .ccu_clks       = sun8i_a83t_de2_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_de2_clks),
+
+       .hw_clks        = &sun8i_a83t_de2_hw_clks,
+
+       .resets         = sun50i_a64_de2_resets,
+       .num_resets     = ARRAY_SIZE(sun50i_a64_de2_resets),
+};
+
+static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
+       .ccu_clks       = sun8i_v3s_de2_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun8i_v3s_de2_clks),
+
+       .hw_clks        = &sun8i_v3s_de2_hw_clks,
+
+       .resets         = sun8i_a83t_de2_resets,
+       .num_resets     = ARRAY_SIZE(sun8i_a83t_de2_resets),
+};
+
+static int sunxi_de2_clk_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct clk *bus_clk, *mod_clk;
+       struct reset_control *rstc;
+       void __iomem *reg;
+       const struct sunxi_ccu_desc *ccu_desc;
+       int ret;
+
+       ccu_desc = of_device_get_match_data(&pdev->dev);
+       if (!ccu_desc)
+               return -EINVAL;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       bus_clk = devm_clk_get(&pdev->dev, "bus");
+       if (IS_ERR(bus_clk)) {
+               ret = PTR_ERR(bus_clk);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
+               return ret;
+       }
+
+       mod_clk = devm_clk_get(&pdev->dev, "mod");
+       if (IS_ERR(mod_clk)) {
+               ret = PTR_ERR(mod_clk);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "Couldn't get mod clk: %d\n", ret);
+               return ret;
+       }
+
+       rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+       if (IS_ERR(rstc)) {
+               ret = PTR_ERR(rstc);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "Couldn't get reset control: %d\n", ret);
+               return ret;
+       }
+
+       /* The clocks need to be enabled for us to access the registers */
+       ret = clk_prepare_enable(bus_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(mod_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Couldn't enable mod clk: %d\n", ret);
+               goto err_disable_bus_clk;
+       }
+
+       /* The reset control needs to be asserted for the controls to work */
+       ret = reset_control_deassert(rstc);
+       if (ret) {
+               dev_err(&pdev->dev,
+                       "Couldn't deassert reset control: %d\n", ret);
+               goto err_disable_mod_clk;
+       }
+
+       ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc);
+       if (ret)
+               goto err_assert_reset;
+
+       return 0;
+
+err_assert_reset:
+       reset_control_assert(rstc);
+err_disable_mod_clk:
+       clk_disable_unprepare(mod_clk);
+err_disable_bus_clk:
+       clk_disable_unprepare(bus_clk);
+       return ret;
+}
+
+static const struct of_device_id sunxi_de2_clk_ids[] = {
+       {
+               .compatible = "allwinner,sun8i-a83t-de2-clk",
+               .data = &sun8i_a83t_de2_clk_desc,
+       },
+       {
+               .compatible = "allwinner,sun8i-v3s-de2-clk",
+               .data = &sun8i_v3s_de2_clk_desc,
+       },
+       {
+               .compatible = "allwinner,sun50i-h5-de2-clk",
+               .data = &sun50i_a64_de2_clk_desc,
+       },
+       /*
+        * The Allwinner A64 SoC needs some bit to be poke in syscon to make
+        * DE2 really working.
+        * So there's currently no A64 compatible here.
+        * H5 shares the same reset line with A64, so here H5 is using the
+        * clock description of A64.
+        */
+       { }
+};
+
+static struct platform_driver sunxi_de2_clk_driver = {
+       .probe  = sunxi_de2_clk_probe,
+       .driver = {
+               .name   = "sunxi-de2-clks",
+               .of_match_table = sunxi_de2_clk_ids,
+       },
+};
+builtin_platform_driver(sunxi_de2_clk_driver);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.h b/drivers/clk/sunxi-ng/ccu-sun8i-de2.h
new file mode 100644 (file)
index 0000000..530c006
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2016 Icenowy Zheng <icenowy@aosc.io>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SUN8I_DE2_H_
+#define _CCU_SUN8I_DE2_H_
+
+#include <dt-bindings/clock/sun8i-de2.h>
+#include <dt-bindings/reset/sun8i-de2.h>
+
+/* Intermediary clock dividers are not exported */
+#define CLK_MIXER0_DIV 3
+#define CLK_MIXER1_DIV 4
+#define CLK_WB_DIV     5
+
+#define CLK_NUMBER     (CLK_WB + 1)
+
+#endif /* _CCU_SUN8I_DE2_H_ */
index 4cbc1b701b7cf51d1131f34b934a533e48472a63..62e4f0d2b2fcfd181ba23476ad0953836dcfa026 100644 (file)
@@ -141,6 +141,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
 
 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
                                             "axi" , "pll-periph0" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 3, .shift = 6, .width = 2 },
+};
 static struct ccu_div ahb1_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 
@@ -148,11 +151,8 @@ static struct ccu_div ahb1_clk = {
                .shift  = 12,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 3,
-                       .shift  = 6,
-                       .width  = 2,
-               },
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
        },
 
        .common         = {
index 119f47b568eaefea2cb2a6f8fa8ae6ecd4acdb0e..e54816ec1dbe33205a75c7a46e6de130c87718c8 100644 (file)
 
 static const char * const ar100_parents[] = { "osc32k", "osc24M",
                                             "pll-periph0", "iosc" };
+static const char * const a83t_ar100_parents[] = { "osc16M-d512", "osc24M",
+                                                  "pll-periph0", "iosc" };
+static const struct ccu_mux_var_prediv ar100_predivs[] = {
+       { .index = 2, .shift = 8, .width = 5 },
+};
 
 static struct ccu_div ar100_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
@@ -35,11 +40,8 @@ static struct ccu_div ar100_clk = {
                .shift  = 16,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 2,
-                       .shift  = 8,
-                       .width  = 5,
-               },
+               .var_predivs    = ar100_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ar100_predivs),
        },
 
        .common         = {
@@ -52,6 +54,27 @@ static struct ccu_div ar100_clk = {
        },
 };
 
+static struct ccu_div a83t_ar100_clk = {
+       .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+       .mux            = {
+               .shift  = 16,
+               .width  = 2,
+
+               .var_predivs    = ar100_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ar100_predivs),
+       },
+
+       .common         = {
+               .reg            = 0x00,
+               .features       = CCU_FEATURE_VARIABLE_PREDIV,
+               .hw.init        = CLK_HW_INIT_PARENTS("ar100",
+                                                     a83t_ar100_parents,
+                                                     &ccu_div_ops,
+                                                     0),
+       },
+};
+
 static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0);
 
 static struct ccu_div apb0_clk = {
@@ -66,6 +89,8 @@ static struct ccu_div apb0_clk = {
        },
 };
 
+static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0);
+
 static SUNXI_CCU_GATE(apb0_pio_clk,    "apb0-pio",     "apb0",
                      0x28, BIT(0), 0);
 static SUNXI_CCU_GATE(apb0_ir_clk,     "apb0-ir",      "apb0",
@@ -90,6 +115,46 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
                                  BIT(31),      /* gate */
                                  0);
 
+static const char *const a83t_r_mod0_parents[] = { "osc16M", "osc24M" };
+static const struct ccu_mux_fixed_prediv a83t_ir_predivs[] = {
+       { .index = 0, .div = 16 },
+};
+static struct ccu_mp a83t_ir_clk = {
+       .enable = BIT(31),
+
+       .m      = _SUNXI_CCU_DIV(0, 4),
+       .p      = _SUNXI_CCU_DIV(16, 2),
+
+       .mux    = {
+               .shift  = 24,
+               .width  = 2,
+               .fixed_predivs  = a83t_ir_predivs,
+               .n_predivs      = ARRAY_SIZE(a83t_ir_predivs),
+       },
+
+       .common         = {
+               .reg            = 0x54,
+               .features       = CCU_FEATURE_VARIABLE_PREDIV,
+               .hw.init        = CLK_HW_INIT_PARENTS("ir",
+                                                     a83t_r_mod0_parents,
+                                                     &ccu_mp_ops,
+                                                     0),
+       },
+};
+
+static struct ccu_common *sun8i_a83t_r_ccu_clks[] = {
+       &a83t_ar100_clk.common,
+       &a83t_apb0_clk.common,
+       &apb0_pio_clk.common,
+       &apb0_ir_clk.common,
+       &apb0_timer_clk.common,
+       &apb0_rsb_clk.common,
+       &apb0_uart_clk.common,
+       &apb0_i2c_clk.common,
+       &apb0_twd_clk.common,
+       &a83t_ir_clk.common,
+};
+
 static struct ccu_common *sun8i_h3_r_ccu_clks[] = {
        &ar100_clk.common,
        &apb0_clk.common,
@@ -115,6 +180,23 @@ static struct ccu_common *sun50i_a64_r_ccu_clks[] = {
        &ir_clk.common,
 };
 
+static struct clk_hw_onecell_data sun8i_a83t_r_hw_clks = {
+       .hws    = {
+               [CLK_AR100]             = &a83t_ar100_clk.common.hw,
+               [CLK_AHB0]              = &ahb0_clk.hw,
+               [CLK_APB0]              = &a83t_apb0_clk.common.hw,
+               [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
+               [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
+               [CLK_APB0_TIMER]        = &apb0_timer_clk.common.hw,
+               [CLK_APB0_RSB]          = &apb0_rsb_clk.common.hw,
+               [CLK_APB0_UART]         = &apb0_uart_clk.common.hw,
+               [CLK_APB0_I2C]          = &apb0_i2c_clk.common.hw,
+               [CLK_APB0_TWD]          = &apb0_twd_clk.common.hw,
+               [CLK_IR]                = &a83t_ir_clk.common.hw,
+       },
+       .num    = CLK_NUMBER,
+};
+
 static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = {
        .hws    = {
                [CLK_AR100]             = &ar100_clk.common.hw,
@@ -148,6 +230,14 @@ static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = {
        .num    = CLK_NUMBER,
 };
 
+static struct ccu_reset_map sun8i_a83t_r_ccu_resets[] = {
+       [RST_APB0_IR]           =  { 0xb0, BIT(1) },
+       [RST_APB0_TIMER]        =  { 0xb0, BIT(2) },
+       [RST_APB0_RSB]          =  { 0xb0, BIT(3) },
+       [RST_APB0_UART]         =  { 0xb0, BIT(4) },
+       [RST_APB0_I2C]          =  { 0xb0, BIT(6) },
+};
+
 static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = {
        [RST_APB0_IR]           =  { 0xb0, BIT(1) },
        [RST_APB0_TIMER]        =  { 0xb0, BIT(2) },
@@ -163,6 +253,16 @@ static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = {
        [RST_APB0_I2C]          =  { 0xb0, BIT(6) },
 };
 
+static const struct sunxi_ccu_desc sun8i_a83t_r_ccu_desc = {
+       .ccu_clks       = sun8i_a83t_r_ccu_clks,
+       .num_ccu_clks   = ARRAY_SIZE(sun8i_a83t_r_ccu_clks),
+
+       .hw_clks        = &sun8i_a83t_r_hw_clks,
+
+       .resets         = sun8i_a83t_r_ccu_resets,
+       .num_resets     = ARRAY_SIZE(sun8i_a83t_r_ccu_resets),
+};
+
 static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = {
        .ccu_clks       = sun8i_h3_r_ccu_clks,
        .num_ccu_clks   = ARRAY_SIZE(sun8i_h3_r_ccu_clks),
@@ -198,6 +298,13 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
        sunxi_ccu_probe(node, reg, desc);
 }
 
+static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
+{
+       sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
+}
+CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",
+              sun8i_a83t_r_ccu_setup);
+
 static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
 {
        sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
index 6297add857b53112a851f9bc0f1205db5996fe1b..a34a78d7fb280e7ca11089203c289ed57a46cf3a 100644 (file)
@@ -132,6 +132,9 @@ static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0);
 
 static const char * const ahb1_parents[] = { "osc32k", "osc24M",
                                             "axi", "pll-periph0" };
+static const struct ccu_mux_var_prediv ahb1_predivs[] = {
+       { .index = 3, .shift = 6, .width = 2 },
+};
 static struct ccu_div ahb1_clk = {
        .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
 
@@ -139,11 +142,8 @@ static struct ccu_div ahb1_clk = {
                .shift  = 12,
                .width  = 2,
 
-               .variable_prediv        = {
-                       .index  = 3,
-                       .shift  = 6,
-                       .width  = 2,
-               },
+               .var_predivs    = ahb1_predivs,
+               .n_var_predivs  = ARRAY_SIZE(ahb1_predivs),
        },
 
        .common         = {
index 4057e6021aa9f74a1cd91acef616d48fe1fc1b1a..c0e5c10d00910325558203f66f288d1f352ec4ef 100644 (file)
 #include "ccu_div.h"
 
 static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
-                                       unsigned long parent_rate,
+                                       struct clk_hw *parent,
+                                       unsigned long *parent_rate,
                                        unsigned long rate,
                                        void *data)
 {
        struct ccu_div *cd = data;
-       unsigned long val;
-
-       /*
-        * We can't use divider_round_rate that assumes that there's
-        * several parents, while we might be called to evaluate
-        * several different parents.
-        */
-       val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
-                             cd->div.flags);
 
-       return divider_recalc_rate(&cd->common.hw, parent_rate, val,
-                                  cd->div.table, cd->div.flags);
+       return divider_round_rate_parent(&cd->common.hw, parent,
+                                        rate, parent_rate,
+                                        cd->div.table, cd->div.width,
+                                        cd->div.flags);
 }
 
 static void ccu_div_disable(struct clk_hw *hw)
@@ -65,8 +59,8 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
        val = reg >> cd->div.shift;
        val &= (1 << cd->div.width) - 1;
 
-       ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1,
-                                               &parent_rate);
+       parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
+                                                 parent_rate);
 
        return divider_recalc_rate(hw, parent_rate, val, cd->div.table,
                                   cd->div.flags);
@@ -77,18 +71,6 @@ static int ccu_div_determine_rate(struct clk_hw *hw,
 {
        struct ccu_div *cd = hw_to_ccu_div(hw);
 
-       if (clk_hw_get_num_parents(hw) == 1) {
-               req->rate = divider_round_rate(hw, req->rate,
-                                              &req->best_parent_rate,
-                                              cd->div.table,
-                                              cd->div.width,
-                                              cd->div.flags);
-
-               req->best_parent_hw = clk_hw_get_parent(hw);
-
-               return 0;
-       }
-
        return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
                                             req, ccu_div_round_rate, cd);
 }
@@ -101,8 +83,8 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
        unsigned long val;
        u32 reg;
 
-       ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1,
-                                               &parent_rate);
+       parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
+                                                 parent_rate);
 
        val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
                              cd->div.flags);
index b583f186a804df669e974f811e6bef91c4aaa877..b917ad7a386c0eddbb34b3b6c06bd3a0d452a851 100644 (file)
@@ -41,7 +41,8 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
 }
 
 static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
-                                      unsigned long parent_rate,
+                                      struct clk_hw *hw,
+                                      unsigned long *parent_rate,
                                       unsigned long rate,
                                       void *data)
 {
@@ -52,9 +53,9 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
        max_m = cmp->m.max ?: 1 << cmp->m.width;
        max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
 
-       ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);
+       ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
 
-       return parent_rate / p / m;
+       return *parent_rate / p / m;
 }
 
 static void ccu_mp_disable(struct clk_hw *hw)
@@ -86,8 +87,8 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
        u32 reg;
 
        /* Adjust parent_rate according to pre-dividers */
-       ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux,
-                                               -1, &parent_rate);
+       parent_rate = ccu_mux_helper_apply_prediv(&cmp->common, &cmp->mux, -1,
+                                                 parent_rate);
 
        reg = readl(cmp->common.base + cmp->common.reg);
 
@@ -122,8 +123,8 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
        u32 reg;
 
        /* Adjust parent_rate according to pre-dividers */
-       ccu_mux_helper_adjust_parent_for_prediv(&cmp->common, &cmp->mux,
-                                               -1, &parent_rate);
+       parent_rate = ccu_mux_helper_apply_prediv(&cmp->common, &cmp->mux, -1,
+                                                 parent_rate);
 
        max_m = cmp->m.max ?: 1 << cmp->m.width;
        max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
index 671141359895290a9dc6d6ea20efa9e8347eb421..20d0300867f29afbc15448b9224b7070c7808e11 100644 (file)
@@ -33,9 +33,10 @@ static void ccu_mult_find_best(unsigned long parent, unsigned long rate,
 }
 
 static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
-                                       unsigned long parent_rate,
-                                       unsigned long rate,
-                                       void *data)
+                                        struct clk_hw *parent,
+                                        unsigned long *parent_rate,
+                                        unsigned long rate,
+                                        void *data)
 {
        struct ccu_mult *cm = data;
        struct _ccu_mult _cm;
@@ -47,9 +48,9 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
        else
                _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
 
-       ccu_mult_find_best(parent_rate, rate, &_cm);
+       ccu_mult_find_best(*parent_rate, rate, &_cm);
 
-       return parent_rate * _cm.mult;
+       return *parent_rate * _cm.mult;
 }
 
 static void ccu_mult_disable(struct clk_hw *hw)
@@ -87,8 +88,8 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
        val = reg >> cm->mult.shift;
        val &= (1 << cm->mult.width) - 1;
 
-       ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
-                                               &parent_rate);
+       parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
+                                                 parent_rate);
 
        return parent_rate * (val + cm->mult.offset);
 }
@@ -115,8 +116,8 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
        else
                ccu_frac_helper_disable(&cm->common, &cm->frac);
 
-       ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
-                                               &parent_rate);
+       parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
+                                                 parent_rate);
 
        _cm.min = cm->mult.min;
 
index c6bb1f5232326f982e496d00767c38d85bfde9ea..312664155a5416bb9a4d6d6a753374f7463868f2 100644 (file)
 #include "ccu_gate.h"
 #include "ccu_mux.h"
 
-void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
-                                            struct ccu_mux_internal *cm,
-                                            int parent_index,
-                                            unsigned long *parent_rate)
+static u16 ccu_mux_get_prediv(struct ccu_common *common,
+                             struct ccu_mux_internal *cm,
+                             int parent_index)
 {
        u16 prediv = 1;
        u32 reg;
-       int i;
 
        if (!((common->features & CCU_FEATURE_FIXED_PREDIV) ||
              (common->features & CCU_FEATURE_VARIABLE_PREDIV) ||
              (common->features & CCU_FEATURE_ALL_PREDIV)))
-               return;
+               return 1;
 
-       if (common->features & CCU_FEATURE_ALL_PREDIV) {
-               *parent_rate = *parent_rate / common->prediv;
-               return;
-       }
+       if (common->features & CCU_FEATURE_ALL_PREDIV)
+               return common->prediv;
 
        reg = readl(common->base + common->reg);
        if (parent_index < 0) {
@@ -40,28 +36,52 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
                parent_index &= (1 << cm->width) - 1;
        }
 
-       if (common->features & CCU_FEATURE_FIXED_PREDIV)
+       if (common->features & CCU_FEATURE_FIXED_PREDIV) {
+               int i;
+
                for (i = 0; i < cm->n_predivs; i++)
                        if (parent_index == cm->fixed_predivs[i].index)
                                prediv = cm->fixed_predivs[i].div;
+       }
 
-       if (common->features & CCU_FEATURE_VARIABLE_PREDIV)
-               if (parent_index == cm->variable_prediv.index) {
-                       u8 div;
+       if (common->features & CCU_FEATURE_VARIABLE_PREDIV) {
+               int i;
 
-                       div = reg >> cm->variable_prediv.shift;
-                       div &= (1 << cm->variable_prediv.width) - 1;
-                       prediv = div + 1;
-               }
+               for (i = 0; i < cm->n_var_predivs; i++)
+                       if (parent_index == cm->var_predivs[i].index) {
+                               u8 div;
+
+                               div = reg >> cm->var_predivs[i].shift;
+                               div &= (1 << cm->var_predivs[i].width) - 1;
+                               prediv = div + 1;
+                       }
+       }
+
+       return prediv;
+}
 
-       *parent_rate = *parent_rate / prediv;
+unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
+                                         struct ccu_mux_internal *cm,
+                                         int parent_index,
+                                         unsigned long parent_rate)
+{
+       return parent_rate / ccu_mux_get_prediv(common, cm, parent_index);
+}
+
+static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
+                                           struct ccu_mux_internal *cm,
+                                           int parent_index,
+                                           unsigned long parent_rate)
+{
+       return parent_rate * ccu_mux_get_prediv(common, cm, parent_index);
 }
 
 int ccu_mux_helper_determine_rate(struct ccu_common *common,
                                  struct ccu_mux_internal *cm,
                                  struct clk_rate_request *req,
                                  unsigned long (*round)(struct ccu_mux_internal *,
-                                                        unsigned long,
+                                                        struct clk_hw *,
+                                                        unsigned long *,
                                                         unsigned long,
                                                         void *),
                                  void *data)
@@ -75,41 +95,43 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
 
                best_parent = clk_hw_get_parent(hw);
                best_parent_rate = clk_hw_get_rate(best_parent);
+               adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
+                                                             best_parent_rate);
 
-               adj_parent_rate = best_parent_rate;
-               ccu_mux_helper_adjust_parent_for_prediv(common, cm, -1,
-                                                       &adj_parent_rate);
+               best_rate = round(cm, best_parent, &adj_parent_rate,
+                                 req->rate, data);
 
-               best_rate = round(cm, adj_parent_rate, req->rate, data);
+               /*
+                * adj_parent_rate might have been modified by our clock.
+                * Unapply the pre-divider if there's one, and give
+                * the actual frequency the parent needs to run at.
+                */
+               best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1,
+                                                                adj_parent_rate);
 
                goto out;
        }
 
        for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
-               unsigned long tmp_rate, parent_rate, adj_parent_rate;
+               unsigned long tmp_rate, parent_rate;
                struct clk_hw *parent;
 
                parent = clk_hw_get_parent_by_index(hw, i);
                if (!parent)
                        continue;
 
-               if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
-                       struct clk_rate_request parent_req = *req;
-                       int ret = __clk_determine_rate(parent, &parent_req);
-
-                       if (ret)
-                               continue;
+               parent_rate = ccu_mux_helper_apply_prediv(common, cm, i,
+                                                         clk_hw_get_rate(parent));
 
-                       parent_rate = parent_req.rate;
-               } else {
-                       parent_rate = clk_hw_get_rate(parent);
-               }
+               tmp_rate = round(cm, parent, &parent_rate, req->rate, data);
 
-               adj_parent_rate = parent_rate;
-               ccu_mux_helper_adjust_parent_for_prediv(common, cm, i,
-                                                       &adj_parent_rate);
-
-               tmp_rate = round(cm, adj_parent_rate, req->rate, data);
+               /*
+                * parent_rate might have been modified by our clock.
+                * Unapply the pre-divider if there's one, and give
+                * the actual frequency the parent needs to run at.
+                */
+               parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i,
+                                                           parent_rate);
                if (tmp_rate == req->rate) {
                        best_parent = parent;
                        best_parent_rate = parent_rate;
@@ -217,10 +239,8 @@ static unsigned long ccu_mux_recalc_rate(struct clk_hw *hw,
 {
        struct ccu_mux *cm = hw_to_ccu_mux(hw);
 
-       ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
-                                               &parent_rate);
-
-       return parent_rate;
+       return ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
+                                          parent_rate);
 }
 
 const struct clk_ops ccu_mux_ops = {
index 47aba3a48245f8ff2093e9dacfe5d9439765eb9e..f20c0bd62a47fb4d34af81fa7bd521ef4b392eb1 100644 (file)
@@ -10,6 +10,12 @@ struct ccu_mux_fixed_prediv {
        u16     div;
 };
 
+struct ccu_mux_var_prediv {
+       u8      index;
+       u8      shift;
+       u8      width;
+};
+
 struct ccu_mux_internal {
        u8              shift;
        u8              width;
@@ -18,11 +24,8 @@ struct ccu_mux_internal {
        const struct ccu_mux_fixed_prediv       *fixed_predivs;
        u8              n_predivs;
 
-       struct {
-               u8      index;
-               u8      shift;
-               u8      width;
-       } variable_prediv;
+       const struct ccu_mux_var_prediv         *var_predivs;
+       u8              n_var_predivs;
 };
 
 #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table)   \
@@ -78,15 +81,16 @@ static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
 
 extern const struct clk_ops ccu_mux_ops;
 
-void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
-                                            struct ccu_mux_internal *cm,
-                                            int parent_index,
-                                            unsigned long *parent_rate);
+unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
+                                         struct ccu_mux_internal *cm,
+                                         int parent_index,
+                                         unsigned long parent_rate);
 int ccu_mux_helper_determine_rate(struct ccu_common *common,
                                  struct ccu_mux_internal *cm,
                                  struct clk_rate_request *req,
                                  unsigned long (*round)(struct ccu_mux_internal *,
-                                                        unsigned long,
+                                                        struct clk_hw *,
+                                                        unsigned long *,
                                                         unsigned long,
                                                         void *),
                                  void *data);
index cba84afe1cf1d4a1a60294f118a91561168355f2..44b16dc8fea6b849bf6485b1bcd136488fc805e1 100644 (file)
@@ -102,7 +102,8 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
 }
 
 static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
-                                       unsigned long parent_rate,
+                                       struct clk_hw *hw,
+                                       unsigned long *parent_rate,
                                        unsigned long rate,
                                        void *data)
 {
@@ -116,9 +117,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
        _nkm.min_m = 1;
        _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
 
-       ccu_nkm_find_best(parent_rate, rate, &_nkm);
+       ccu_nkm_find_best(*parent_rate, rate, &_nkm);
 
-       return parent_rate * _nkm.n * _nkm.k / _nkm.m;
+       return *parent_rate * _nkm.n * _nkm.k / _nkm.m;
 }
 
 static int ccu_nkm_determine_rate(struct clk_hw *hw,
index 36a4679210bd4dce76cec043097d29c749b1bbce..ff8f5ebca43575c20c78636c51d26304f10642b0 100644 (file)
@@ -15,6 +15,7 @@
 #define _CCU_RESET_H_
 
 #include <linux/reset-controller.h>
+#include <linux/spinlock.h>
 
 struct ccu_reset_map {
        u16     reg;
index 0deac98210392c8098e281c980cad5d271c2c992..edb9f471e525c55f7119f9da88bb20d614352742 100644 (file)
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_ARCH_OMAP2PLUS), y)
 obj-y                                  += clk.o autoidle.o clockdomain.o
 clk-common                             = dpll.o composite.o divider.o gate.o \
                                          fixed-factor.o mux.o apll.o \
-                                         clkt_dpll.o clkt_iclk.o clkt_dflt.o
+                                         clkt_dpll.o clkt_iclk.o clkt_dflt.o \
+                                         clkctrl.o
 obj-$(CONFIG_SOC_AM33XX)               += $(clk-common) clk-33xx.o dpll3xxx.o
 obj-$(CONFIG_SOC_TI81XX)               += $(clk-common) fapll.o clk-814x.o clk-816x.o
 obj-$(CONFIG_ARCH_OMAP2)               += $(clk-common) interface.o clk-2xxx.o
index 1c8bb83003bfe344fe15e34ad50f1b6953e39c32..2005f032c02f0ad3b9628f1f9d7f22023f442dd1 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk/ti.h>
+#include <dt-bindings/clock/omap4.h>
 
 #include "clock.h"
 
  */
 #define OMAP4_DPLL_USB_DEFFREQ                         960000000
 
+static const struct omap_clkctrl_reg_data omap4_mpuss_clkctrl_regs[] __initconst = {
+       { OMAP4_MPU_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_mpu_m2_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_tesla_clkctrl_regs[] __initconst = {
+       { OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m4x2_ck" },
+       { 0 },
+};
+
+static const char * const omap4_aess_fclk_parents[] __initconst = {
+       "abe_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_aess_fclk_data __initconst = {
+       .max_div = 2,
+};
+
+static const struct omap_clkctrl_bit_data omap4_aess_bit_data[] __initconst = {
+       { 24, TI_CLK_DIVIDER, omap4_aess_fclk_parents, &omap4_aess_fclk_data },
+       { 0 },
+};
+
+static const char * const omap4_func_dmic_abe_gfclk_parents[] __initconst = {
+       "dmic_sync_mux_ck",
+       "pad_clks_ck",
+       "slimbus_clk",
+       NULL,
+};
+
+static const char * const omap4_dmic_sync_mux_ck_parents[] __initconst = {
+       "abe_24m_fclk",
+       "syc_clk_div_ck",
+       "func_24m_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_dmic_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_func_dmic_abe_gfclk_parents, NULL },
+       { 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_func_mcasp_abe_gfclk_parents[] __initconst = {
+       "mcasp_sync_mux_ck",
+       "pad_clks_ck",
+       "slimbus_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcasp_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_func_mcasp_abe_gfclk_parents, NULL },
+       { 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_func_mcbsp1_gfclk_parents[] __initconst = {
+       "mcbsp1_sync_mux_ck",
+       "pad_clks_ck",
+       "slimbus_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_func_mcbsp1_gfclk_parents, NULL },
+       { 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_func_mcbsp2_gfclk_parents[] __initconst = {
+       "mcbsp2_sync_mux_ck",
+       "pad_clks_ck",
+       "slimbus_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp2_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_func_mcbsp2_gfclk_parents, NULL },
+       { 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_func_mcbsp3_gfclk_parents[] __initconst = {
+       "mcbsp3_sync_mux_ck",
+       "pad_clks_ck",
+       "slimbus_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp3_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_func_mcbsp3_gfclk_parents, NULL },
+       { 26, TI_CLK_MUX, omap4_dmic_sync_mux_ck_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_slimbus1_fclk_0_parents[] __initconst = {
+       "abe_24m_fclk",
+       NULL,
+};
+
+static const char * const omap4_slimbus1_fclk_1_parents[] __initconst = {
+       "func_24m_clk",
+       NULL,
+};
+
+static const char * const omap4_slimbus1_fclk_2_parents[] __initconst = {
+       "pad_clks_ck",
+       NULL,
+};
+
+static const char * const omap4_slimbus1_slimbus_clk_parents[] __initconst = {
+       "slimbus_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_slimbus1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_slimbus1_fclk_0_parents, NULL },
+       { 9, TI_CLK_GATE, omap4_slimbus1_fclk_1_parents, NULL },
+       { 10, TI_CLK_GATE, omap4_slimbus1_fclk_2_parents, NULL },
+       { 11, TI_CLK_GATE, omap4_slimbus1_slimbus_clk_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_timer5_sync_mux_parents[] __initconst = {
+       "syc_clk_div_ck",
+       "sys_32k_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer5_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer6_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer7_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer8_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_timer5_sync_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_abe_clkctrl_regs[] __initconst = {
+       { OMAP4_L4_ABE_CLKCTRL, NULL, 0, "ocp_abe_iclk" },
+       { OMAP4_AESS_CLKCTRL, omap4_aess_bit_data, CLKF_SW_SUP, "aess_fclk" },
+       { OMAP4_MCPDM_CLKCTRL, NULL, CLKF_SW_SUP, "pad_clks_ck" },
+       { OMAP4_DMIC_CLKCTRL, omap4_dmic_bit_data, CLKF_SW_SUP, "func_dmic_abe_gfclk" },
+       { OMAP4_MCASP_CLKCTRL, omap4_mcasp_bit_data, CLKF_SW_SUP, "func_mcasp_abe_gfclk" },
+       { OMAP4_MCBSP1_CLKCTRL, omap4_mcbsp1_bit_data, CLKF_SW_SUP, "func_mcbsp1_gfclk" },
+       { OMAP4_MCBSP2_CLKCTRL, omap4_mcbsp2_bit_data, CLKF_SW_SUP, "func_mcbsp2_gfclk" },
+       { OMAP4_MCBSP3_CLKCTRL, omap4_mcbsp3_bit_data, CLKF_SW_SUP, "func_mcbsp3_gfclk" },
+       { OMAP4_SLIMBUS1_CLKCTRL, omap4_slimbus1_bit_data, CLKF_SW_SUP, "slimbus1_fclk_0" },
+       { OMAP4_TIMER5_CLKCTRL, omap4_timer5_bit_data, CLKF_SW_SUP, "timer5_sync_mux" },
+       { OMAP4_TIMER6_CLKCTRL, omap4_timer6_bit_data, CLKF_SW_SUP, "timer6_sync_mux" },
+       { OMAP4_TIMER7_CLKCTRL, omap4_timer7_bit_data, CLKF_SW_SUP, "timer7_sync_mux" },
+       { OMAP4_TIMER8_CLKCTRL, omap4_timer8_bit_data, CLKF_SW_SUP, "timer8_sync_mux" },
+       { OMAP4_WD_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_ao_clkctrl_regs[] __initconst = {
+       { OMAP4_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "l4_wkup_clk_mux_ck" },
+       { OMAP4_SMARTREFLEX_IVA_CLKCTRL, NULL, CLKF_SW_SUP, "l4_wkup_clk_mux_ck" },
+       { OMAP4_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "l4_wkup_clk_mux_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_1_clkctrl_regs[] __initconst = {
+       { OMAP4_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_2_clkctrl_regs[] __initconst = {
+       { OMAP4_L3_MAIN_2_CLKCTRL, NULL, 0, "l3_div_ck" },
+       { OMAP4_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+       { OMAP4_OCMC_RAM_CLKCTRL, NULL, 0, "l3_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_ducati_clkctrl_regs[] __initconst = {
+       { OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "ducati_clk_mux_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_dma_clkctrl_regs[] __initconst = {
+       { OMAP4_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_emif_clkctrl_regs[] __initconst = {
+       { OMAP4_DMM_CLKCTRL, NULL, 0, "l3_div_ck" },
+       { OMAP4_EMIF1_CLKCTRL, NULL, CLKF_HW_SUP, "ddrphy_ck" },
+       { OMAP4_EMIF2_CLKCTRL, NULL, CLKF_HW_SUP, "ddrphy_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_d2d_clkctrl_regs[] __initconst = {
+       { OMAP4_C2C_CLKCTRL, NULL, 0, "div_core_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_cfg_clkctrl_regs[] __initconst = {
+       { OMAP4_L4_CFG_CLKCTRL, NULL, 0, "l4_div_ck" },
+       { OMAP4_SPINLOCK_CLKCTRL, NULL, 0, "l4_div_ck" },
+       { OMAP4_MAILBOX_CLKCTRL, NULL, 0, "l4_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_instr_clkctrl_regs[] __initconst = {
+       { OMAP4_L3_MAIN_3_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+       { OMAP4_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+       { OMAP4_OCP_WP_NOC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_div_ck" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_ivahd_clkctrl_regs[] __initconst = {
+       { OMAP4_IVA_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m5x2_ck" },
+       { OMAP4_SL2IF_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m5x2_ck" },
+       { 0 },
+};
+
+static const char * const omap4_iss_ctrlclk_parents[] __initconst = {
+       "func_96m_fclk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_iss_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_iss_ctrlclk_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_fdif_fck_parents[] __initconst = {
+       "dpll_per_m4x2_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_fdif_fck_data __initconst = {
+       .max_div = 4,
+};
+
+static const struct omap_clkctrl_bit_data omap4_fdif_bit_data[] __initconst = {
+       { 24, TI_CLK_DIVIDER, omap4_fdif_fck_parents, &omap4_fdif_fck_data },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_iss_clkctrl_regs[] __initconst = {
+       { OMAP4_ISS_CLKCTRL, omap4_iss_bit_data, CLKF_SW_SUP, "ducati_clk_mux_ck" },
+       { OMAP4_FDIF_CLKCTRL, omap4_fdif_bit_data, CLKF_SW_SUP, "fdif_fck" },
+       { 0 },
+};
+
+static const char * const omap4_dss_dss_clk_parents[] __initconst = {
+       "dpll_per_m5x2_ck",
+       NULL,
+};
+
+static const char * const omap4_dss_48mhz_clk_parents[] __initconst = {
+       "func_48mc_fclk",
+       NULL,
+};
+
+static const char * const omap4_dss_sys_clk_parents[] __initconst = {
+       "syc_clk_div_ck",
+       NULL,
+};
+
+static const char * const omap4_dss_tv_clk_parents[] __initconst = {
+       "extalt_clkin_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_dss_core_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_dss_dss_clk_parents, NULL },
+       { 9, TI_CLK_GATE, omap4_dss_48mhz_clk_parents, NULL },
+       { 10, TI_CLK_GATE, omap4_dss_sys_clk_parents, NULL },
+       { 11, TI_CLK_GATE, omap4_dss_tv_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_dss_clkctrl_regs[] __initconst = {
+       { OMAP4_DSS_CORE_CLKCTRL, omap4_dss_core_bit_data, CLKF_SW_SUP, "dss_dss_clk" },
+       { 0 },
+};
+
+static const char * const omap4_sgx_clk_mux_parents[] __initconst = {
+       "dpll_core_m7x2_ck",
+       "dpll_per_m7x2_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpu_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_sgx_clk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_gfx_clkctrl_regs[] __initconst = {
+       { OMAP4_GPU_CLKCTRL, omap4_gpu_bit_data, CLKF_SW_SUP, "sgx_clk_mux" },
+       { 0 },
+};
+
+static const char * const omap4_hsmmc1_fclk_parents[] __initconst = {
+       "func_64m_fclk",
+       "func_96m_fclk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mmc1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_hsmmc1_fclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_mmc2_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_hsmmc1_fclk_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_hsi_fck_parents[] __initconst = {
+       "dpll_per_m2x2_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_hsi_fck_data __initconst = {
+       .max_div = 4,
+};
+
+static const struct omap_clkctrl_bit_data omap4_hsi_bit_data[] __initconst = {
+       { 24, TI_CLK_DIVIDER, omap4_hsi_fck_parents, &omap4_hsi_fck_data },
+       { 0 },
+};
+
+static const char * const omap4_usb_host_hs_utmi_p1_clk_parents[] __initconst = {
+       "utmi_p1_gfclk",
+       NULL,
+};
+
+static const char * const omap4_usb_host_hs_utmi_p2_clk_parents[] __initconst = {
+       "utmi_p2_gfclk",
+       NULL,
+};
+
+static const char * const omap4_usb_host_hs_utmi_p3_clk_parents[] __initconst = {
+       "init_60m_fclk",
+       NULL,
+};
+
+static const char * const omap4_usb_host_hs_hsic480m_p1_clk_parents[] __initconst = {
+       "dpll_usb_m2_ck",
+       NULL,
+};
+
+static const char * const omap4_utmi_p1_gfclk_parents[] __initconst = {
+       "init_60m_fclk",
+       "xclk60mhsp1_ck",
+       NULL,
+};
+
+static const char * const omap4_utmi_p2_gfclk_parents[] __initconst = {
+       "init_60m_fclk",
+       "xclk60mhsp2_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_usb_host_hs_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_usb_host_hs_utmi_p1_clk_parents, NULL },
+       { 9, TI_CLK_GATE, omap4_usb_host_hs_utmi_p2_clk_parents, NULL },
+       { 10, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+       { 11, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+       { 12, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+       { 13, TI_CLK_GATE, omap4_usb_host_hs_hsic480m_p1_clk_parents, NULL },
+       { 14, TI_CLK_GATE, omap4_usb_host_hs_hsic480m_p1_clk_parents, NULL },
+       { 15, TI_CLK_GATE, omap4_dss_48mhz_clk_parents, NULL },
+       { 24, TI_CLK_MUX, omap4_utmi_p1_gfclk_parents, NULL },
+       { 25, TI_CLK_MUX, omap4_utmi_p2_gfclk_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_usb_otg_hs_xclk_parents[] __initconst = {
+       "otg_60m_gfclk",
+       NULL,
+};
+
+static const char * const omap4_otg_60m_gfclk_parents[] __initconst = {
+       "utmi_phy_clkout_ck",
+       "xclk60motg_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_usb_otg_hs_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_usb_otg_hs_xclk_parents, NULL },
+       { 24, TI_CLK_MUX, omap4_otg_60m_gfclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_usb_tll_hs_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+       { 9, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+       { 10, TI_CLK_GATE, omap4_usb_host_hs_utmi_p3_clk_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_ocp2scp_usb_phy_phy_48m_parents[] __initconst = {
+       "func_48m_fclk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_ocp2scp_usb_phy_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_ocp2scp_usb_phy_phy_48m_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l3_init_clkctrl_regs[] __initconst = {
+       { OMAP4_MMC1_CLKCTRL, omap4_mmc1_bit_data, CLKF_SW_SUP, "hsmmc1_fclk" },
+       { OMAP4_MMC2_CLKCTRL, omap4_mmc2_bit_data, CLKF_SW_SUP, "hsmmc2_fclk" },
+       { OMAP4_HSI_CLKCTRL, omap4_hsi_bit_data, CLKF_HW_SUP, "hsi_fck" },
+       { OMAP4_USB_HOST_HS_CLKCTRL, omap4_usb_host_hs_bit_data, CLKF_SW_SUP, "init_60m_fclk" },
+       { OMAP4_USB_OTG_HS_CLKCTRL, omap4_usb_otg_hs_bit_data, CLKF_HW_SUP, "l3_div_ck" },
+       { OMAP4_USB_TLL_HS_CLKCTRL, omap4_usb_tll_hs_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+       { OMAP4_USB_HOST_FS_CLKCTRL, NULL, CLKF_SW_SUP, "func_48mc_fclk" },
+       { OMAP4_OCP2SCP_USB_PHY_CLKCTRL, omap4_ocp2scp_usb_phy_bit_data, CLKF_HW_SUP, "ocp2scp_usb_phy_phy_48m" },
+       { 0 },
+};
+
+static const char * const omap4_cm2_dm10_mux_parents[] __initconst = {
+       "sys_clkin_ck",
+       "sys_32k_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer10_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer11_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer2_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer3_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer4_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer9_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_gpio2_dbclk_parents[] __initconst = {
+       "sys_32k_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio3_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio4_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio5_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio6_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_per_mcbsp4_gfclk_parents[] __initconst = {
+       "mcbsp4_sync_mux_ck",
+       "pad_clks_ck",
+       NULL,
+};
+
+static const char * const omap4_mcbsp4_sync_mux_ck_parents[] __initconst = {
+       "func_96m_fclk",
+       "per_abe_nc_fclk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_mcbsp4_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_per_mcbsp4_gfclk_parents, NULL },
+       { 25, TI_CLK_MUX, omap4_mcbsp4_sync_mux_ck_parents, NULL },
+       { 0 },
+};
+
+static const char * const omap4_slimbus2_fclk_0_parents[] __initconst = {
+       "func_24mc_fclk",
+       NULL,
+};
+
+static const char * const omap4_slimbus2_fclk_1_parents[] __initconst = {
+       "per_abe_24m_fclk",
+       NULL,
+};
+
+static const char * const omap4_slimbus2_slimbus_clk_parents[] __initconst = {
+       "pad_slimbus_core_clks_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data omap4_slimbus2_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_slimbus2_fclk_0_parents, NULL },
+       { 9, TI_CLK_GATE, omap4_slimbus2_fclk_1_parents, NULL },
+       { 10, TI_CLK_GATE, omap4_slimbus2_slimbus_clk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initconst = {
+       { OMAP4_TIMER10_CLKCTRL, omap4_timer10_bit_data, CLKF_SW_SUP, "cm2_dm10_mux" },
+       { OMAP4_TIMER11_CLKCTRL, omap4_timer11_bit_data, CLKF_SW_SUP, "cm2_dm11_mux" },
+       { OMAP4_TIMER2_CLKCTRL, omap4_timer2_bit_data, CLKF_SW_SUP, "cm2_dm2_mux" },
+       { OMAP4_TIMER3_CLKCTRL, omap4_timer3_bit_data, CLKF_SW_SUP, "cm2_dm3_mux" },
+       { OMAP4_TIMER4_CLKCTRL, omap4_timer4_bit_data, CLKF_SW_SUP, "cm2_dm4_mux" },
+       { OMAP4_TIMER9_CLKCTRL, omap4_timer9_bit_data, CLKF_SW_SUP, "cm2_dm9_mux" },
+       { OMAP4_ELM_CLKCTRL, NULL, 0, "l4_div_ck" },
+       { OMAP4_GPIO2_CLKCTRL, omap4_gpio2_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+       { OMAP4_GPIO3_CLKCTRL, omap4_gpio3_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+       { OMAP4_GPIO4_CLKCTRL, omap4_gpio4_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+       { OMAP4_GPIO5_CLKCTRL, omap4_gpio5_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+       { OMAP4_GPIO6_CLKCTRL, omap4_gpio6_bit_data, CLKF_HW_SUP, "l4_div_ck" },
+       { OMAP4_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" },
+       { OMAP4_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { OMAP4_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { OMAP4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { OMAP4_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" },
+       { OMAP4_L4_PER_CLKCTRL, NULL, 0, "l4_div_ck" },
+       { OMAP4_MCBSP4_CLKCTRL, omap4_mcbsp4_bit_data, CLKF_SW_SUP, "per_mcbsp4_gfclk" },
+       { OMAP4_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_MMC4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_SLIMBUS2_CLKCTRL, omap4_slimbus2_bit_data, CLKF_SW_SUP, "slimbus2_fclk_0" },
+       { OMAP4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { OMAP4_MMC5_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_gpio1_bit_data[] __initconst = {
+       { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_bit_data omap4_timer1_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, omap4_cm2_dm10_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_l4_wkup_clkctrl_regs[] __initconst = {
+       { OMAP4_L4_WKUP_CLKCTRL, NULL, 0, "l4_wkup_clk_mux_ck" },
+       { OMAP4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { OMAP4_GPIO1_CLKCTRL, omap4_gpio1_bit_data, CLKF_HW_SUP, "l4_wkup_clk_mux_ck" },
+       { OMAP4_TIMER1_CLKCTRL, omap4_timer1_bit_data, CLKF_SW_SUP, "dmt1_clk_mux" },
+       { OMAP4_COUNTER_32K_CLKCTRL, NULL, 0, "sys_32k_ck" },
+       { OMAP4_KBD_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" },
+       { 0 },
+};
+
+static const char * const omap4_pmd_stm_clock_mux_ck_parents[] __initconst = {
+       "sys_clkin_ck",
+       "dpll_core_m6x2_ck",
+       "tie_low_clock_ck",
+       NULL,
+};
+
+static const char * const omap4_trace_clk_div_div_ck_parents[] __initconst = {
+       "pmd_trace_clk_mux_ck",
+       NULL,
+};
+
+static const int omap4_trace_clk_div_div_ck_divs[] __initconst = {
+       0,
+       1,
+       2,
+       0,
+       4,
+       -1,
+};
+
+static const struct omap_clkctrl_div_data omap4_trace_clk_div_div_ck_data __initconst = {
+       .dividers = omap4_trace_clk_div_div_ck_divs,
+};
+
+static const char * const omap4_stm_clk_div_ck_parents[] __initconst = {
+       "pmd_stm_clock_mux_ck",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data omap4_stm_clk_div_ck_data __initconst = {
+       .max_div = 64,
+};
+
+static const struct omap_clkctrl_bit_data omap4_debugss_bit_data[] __initconst = {
+       { 20, TI_CLK_MUX, omap4_pmd_stm_clock_mux_ck_parents, NULL },
+       { 22, TI_CLK_MUX, omap4_pmd_stm_clock_mux_ck_parents, NULL },
+       { 24, TI_CLK_DIVIDER, omap4_trace_clk_div_div_ck_parents, &omap4_trace_clk_div_div_ck_data },
+       { 27, TI_CLK_DIVIDER, omap4_stm_clk_div_ck_parents, &omap4_stm_clk_div_ck_data },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data omap4_emu_sys_clkctrl_regs[] __initconst = {
+       { OMAP4_DEBUGSS_CLKCTRL, omap4_debugss_bit_data, 0, "trace_clk_div_ck" },
+       { 0 },
+};
+
+const struct omap_clkctrl_data omap4_clkctrl_data[] __initconst = {
+       { 0x4a004320, omap4_mpuss_clkctrl_regs },
+       { 0x4a004420, omap4_tesla_clkctrl_regs },
+       { 0x4a004520, omap4_abe_clkctrl_regs },
+       { 0x4a008620, omap4_l4_ao_clkctrl_regs },
+       { 0x4a008720, omap4_l3_1_clkctrl_regs },
+       { 0x4a008820, omap4_l3_2_clkctrl_regs },
+       { 0x4a008920, omap4_ducati_clkctrl_regs },
+       { 0x4a008a20, omap4_l3_dma_clkctrl_regs },
+       { 0x4a008b20, omap4_l3_emif_clkctrl_regs },
+       { 0x4a008c20, omap4_d2d_clkctrl_regs },
+       { 0x4a008d20, omap4_l4_cfg_clkctrl_regs },
+       { 0x4a008e20, omap4_l3_instr_clkctrl_regs },
+       { 0x4a008f20, omap4_ivahd_clkctrl_regs },
+       { 0x4a009020, omap4_iss_clkctrl_regs },
+       { 0x4a009120, omap4_l3_dss_clkctrl_regs },
+       { 0x4a009220, omap4_l3_gfx_clkctrl_regs },
+       { 0x4a009320, omap4_l3_init_clkctrl_regs },
+       { 0x4a009420, omap4_l4_per_clkctrl_regs },
+       { 0x4a307820, omap4_l4_wkup_clkctrl_regs },
+       { 0x4a307a20, omap4_emu_sys_clkctrl_regs },
+       { 0 },
+};
+
 static struct ti_dt_clk omap44xx_clks[] = {
        DT_CLK("smp_twd", NULL, "mpu_periphclk"),
        DT_CLK("omapdss_dss", "ick", "dss_fck"),
diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c
new file mode 100644 (file)
index 0000000..53e71d0
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+ * OMAP clkctrl clock support
+ *
+ * Copyright (C) 2017 Texas Instruments, Inc.
+ *
+ * Tero Kristo <t-kristo@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk/ti.h>
+#include <linux/delay.h>
+#include "clock.h"
+
+#define NO_IDLEST                      0x1
+
+#define OMAP4_MODULEMODE_MASK          0x3
+
+#define MODULEMODE_HWCTRL              0x1
+#define MODULEMODE_SWCTRL              0x2
+
+#define OMAP4_IDLEST_MASK              (0x3 << 16)
+#define OMAP4_IDLEST_SHIFT             16
+
+#define CLKCTRL_IDLEST_FUNCTIONAL      0x0
+#define CLKCTRL_IDLEST_INTERFACE_IDLE  0x2
+#define CLKCTRL_IDLEST_DISABLED                0x3
+
+/* These timeouts are in us */
+#define OMAP4_MAX_MODULE_READY_TIME    2000
+#define OMAP4_MAX_MODULE_DISABLE_TIME  5000
+
+static bool _early_timeout = true;
+
+struct omap_clkctrl_provider {
+       void __iomem *base;
+       struct list_head clocks;
+};
+
+struct omap_clkctrl_clk {
+       struct clk_hw *clk;
+       u16 reg_offset;
+       int bit_offset;
+       struct list_head node;
+};
+
+union omap4_timeout {
+       u32 cycles;
+       ktime_t start;
+};
+
+static const struct omap_clkctrl_data default_clkctrl_data[] __initconst = {
+       { 0 },
+};
+
+static u32 _omap4_idlest(u32 val)
+{
+       val &= OMAP4_IDLEST_MASK;
+       val >>= OMAP4_IDLEST_SHIFT;
+
+       return val;
+}
+
+static bool _omap4_is_idle(u32 val)
+{
+       val = _omap4_idlest(val);
+
+       return val == CLKCTRL_IDLEST_DISABLED;
+}
+
+static bool _omap4_is_ready(u32 val)
+{
+       val = _omap4_idlest(val);
+
+       return val == CLKCTRL_IDLEST_FUNCTIONAL ||
+              val == CLKCTRL_IDLEST_INTERFACE_IDLE;
+}
+
+static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
+{
+       if (unlikely(_early_timeout)) {
+               if (time->cycles++ < timeout) {
+                       udelay(1);
+                       return false;
+               }
+       } else {
+               if (!ktime_to_ns(time->start)) {
+                       time->start = ktime_get();
+                       return false;
+               }
+
+               if (ktime_us_delta(ktime_get(), time->start) < timeout) {
+                       cpu_relax();
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+static int __init _omap4_disable_early_timeout(void)
+{
+       _early_timeout = false;
+
+       return 0;
+}
+arch_initcall(_omap4_disable_early_timeout);
+
+static int _omap4_clkctrl_clk_enable(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       u32 val;
+       int ret;
+       union omap4_timeout timeout = { 0 };
+
+       if (!clk->enable_bit)
+               return 0;
+
+       if (clk->clkdm) {
+               ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
+               if (ret) {
+                       WARN(1,
+                            "%s: could not enable %s's clockdomain %s: %d\n",
+                            __func__, clk_hw_get_name(hw),
+                            clk->clkdm_name, ret);
+                       return ret;
+               }
+       }
+
+       val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
+
+       val &= ~OMAP4_MODULEMODE_MASK;
+       val |= clk->enable_bit;
+
+       ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
+
+       if (clk->flags & NO_IDLEST)
+               return 0;
+
+       /* Wait until module is enabled */
+       while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) {
+               if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) {
+                       pr_err("%s: failed to enable\n", clk_hw_get_name(hw));
+                       return -EBUSY;
+               }
+       }
+
+       return 0;
+}
+
+static void _omap4_clkctrl_clk_disable(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       u32 val;
+       union omap4_timeout timeout = { 0 };
+
+       if (!clk->enable_bit)
+               return;
+
+       val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
+
+       val &= ~OMAP4_MODULEMODE_MASK;
+
+       ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
+
+       if (clk->flags & NO_IDLEST)
+               goto exit;
+
+       /* Wait until module is disabled */
+       while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) {
+               if (_omap4_is_timeout(&timeout,
+                                     OMAP4_MAX_MODULE_DISABLE_TIME)) {
+                       pr_err("%s: failed to disable\n", clk_hw_get_name(hw));
+                       break;
+               }
+       }
+
+exit:
+       if (clk->clkdm)
+               ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk);
+}
+
+static int _omap4_clkctrl_clk_is_enabled(struct clk_hw *hw)
+{
+       struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+       u32 val;
+
+       val = ti_clk_ll_ops->clk_readl(&clk->enable_reg);
+
+       if (val & clk->enable_bit)
+               return 1;
+
+       return 0;
+}
+
+static const struct clk_ops omap4_clkctrl_clk_ops = {
+       .enable         = _omap4_clkctrl_clk_enable,
+       .disable        = _omap4_clkctrl_clk_disable,
+       .is_enabled     = _omap4_clkctrl_clk_is_enabled,
+};
+
+static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec,
+                                             void *data)
+{
+       struct omap_clkctrl_provider *provider = data;
+       struct omap_clkctrl_clk *entry;
+
+       if (clkspec->args_count != 2)
+               return ERR_PTR(-EINVAL);
+
+       pr_debug("%s: looking for %x:%x\n", __func__,
+                clkspec->args[0], clkspec->args[1]);
+
+       list_for_each_entry(entry, &provider->clocks, node) {
+               if (entry->reg_offset == clkspec->args[0] &&
+                   entry->bit_offset == clkspec->args[1])
+                       break;
+       }
+
+       if (!entry)
+               return ERR_PTR(-EINVAL);
+
+       return entry->clk;
+}
+
+static int __init
+_ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
+                        struct device_node *node, struct clk_hw *clk_hw,
+                        u16 offset, u8 bit, const char * const *parents,
+                        int num_parents, const struct clk_ops *ops)
+{
+       struct clk_init_data init = { NULL };
+       struct clk *clk;
+       struct omap_clkctrl_clk *clkctrl_clk;
+       int ret = 0;
+
+       init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name,
+                             node->name, offset, bit);
+       clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
+       if (!init.name || !clkctrl_clk) {
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+
+       clk_hw->init = &init;
+       init.parent_names = parents;
+       init.num_parents = num_parents;
+       init.ops = ops;
+       init.flags = CLK_IS_BASIC;
+
+       clk = ti_clk_register(NULL, clk_hw, init.name);
+       if (IS_ERR_OR_NULL(clk)) {
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       clkctrl_clk->reg_offset = offset;
+       clkctrl_clk->bit_offset = bit;
+       clkctrl_clk->clk = clk_hw;
+
+       list_add(&clkctrl_clk->node, &provider->clocks);
+
+       return 0;
+
+cleanup:
+       kfree(init.name);
+       kfree(clkctrl_clk);
+       return ret;
+}
+
+static void __init
+_ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider,
+                      struct device_node *node, u16 offset,
+                      const struct omap_clkctrl_bit_data *data,
+                      void __iomem *reg)
+{
+       struct clk_hw_omap *clk_hw;
+
+       clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
+       if (!clk_hw)
+               return;
+
+       clk_hw->enable_bit = data->bit;
+       clk_hw->enable_reg.ptr = reg;
+
+       if (_ti_clkctrl_clk_register(provider, node, &clk_hw->hw, offset,
+                                    data->bit, data->parents, 1,
+                                    &omap_gate_clk_ops))
+               kfree(clk_hw);
+}
+
+static void __init
+_ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider,
+                     struct device_node *node, u16 offset,
+                     const struct omap_clkctrl_bit_data *data,
+                     void __iomem *reg)
+{
+       struct clk_omap_mux *mux;
+       int num_parents = 0;
+       const char * const *pname;
+
+       mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+       if (!mux)
+               return;
+
+       pname = data->parents;
+       while (*pname) {
+               num_parents++;
+               pname++;
+       }
+
+       mux->mask = num_parents;
+       mux->mask = (1 << fls(mux->mask)) - 1;
+
+       mux->shift = data->bit;
+       mux->reg.ptr = reg;
+
+       if (_ti_clkctrl_clk_register(provider, node, &mux->hw, offset,
+                                    data->bit, data->parents, num_parents,
+                                    &ti_clk_mux_ops))
+               kfree(mux);
+}
+
+static void __init
+_ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider,
+                     struct device_node *node, u16 offset,
+                     const struct omap_clkctrl_bit_data *data,
+                     void __iomem *reg)
+{
+       struct clk_omap_divider *div;
+       const struct omap_clkctrl_div_data *div_data = data->data;
+
+       div = kzalloc(sizeof(*div), GFP_KERNEL);
+       if (!div)
+               return;
+
+       div->reg.ptr = reg;
+       div->shift = data->bit;
+
+       if (ti_clk_parse_divider_data((int *)div_data->dividers,
+                                     div_data->max_div, 0, 0,
+                                     &div->width, &div->table)) {
+               pr_err("%s: Data parsing for %s:%04x:%d failed\n", __func__,
+                      node->name, offset, data->bit);
+               kfree(div);
+               return;
+       }
+
+       if (_ti_clkctrl_clk_register(provider, node, &div->hw, offset,
+                                    data->bit, data->parents, 1,
+                                    &ti_clk_divider_ops))
+               kfree(div);
+}
+
+static void __init
+_ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider,
+                         struct device_node *node,
+                         const struct omap_clkctrl_reg_data *data,
+                         void __iomem *reg)
+{
+       const struct omap_clkctrl_bit_data *bits = data->bit_data;
+
+       if (!bits)
+               return;
+
+       while (bits->bit) {
+               switch (bits->type) {
+               case TI_CLK_GATE:
+                       _ti_clkctrl_setup_gate(provider, node, data->offset,
+                                              bits, reg);
+                       break;
+
+               case TI_CLK_DIVIDER:
+                       _ti_clkctrl_setup_div(provider, node, data->offset,
+                                             bits, reg);
+                       break;
+
+               case TI_CLK_MUX:
+                       _ti_clkctrl_setup_mux(provider, node, data->offset,
+                                             bits, reg);
+                       break;
+
+               default:
+                       pr_err("%s: bad subclk type: %d\n", __func__,
+                              bits->type);
+                       return;
+               }
+               bits++;
+       }
+}
+
+static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
+{
+       struct omap_clkctrl_provider *provider;
+       const struct omap_clkctrl_data *data = default_clkctrl_data;
+       const struct omap_clkctrl_reg_data *reg_data;
+       struct clk_init_data init = { NULL };
+       struct clk_hw_omap *hw;
+       struct clk *clk;
+       struct omap_clkctrl_clk *clkctrl_clk;
+       const __be32 *addrp;
+       u32 addr;
+
+       addrp = of_get_address(node, 0, NULL, NULL);
+       addr = (u32)of_translate_address(node, addrp);
+
+#ifdef CONFIG_ARCH_OMAP4
+       if (of_machine_is_compatible("ti,omap4"))
+               data = omap4_clkctrl_data;
+#endif
+
+       while (data->addr) {
+               if (addr == data->addr)
+                       break;
+
+               data++;
+       }
+
+       if (!data->addr) {
+               pr_err("%s not found from clkctrl data.\n", node->name);
+               return;
+       }
+
+       provider = kzalloc(sizeof(*provider), GFP_KERNEL);
+       if (!provider)
+               return;
+
+       provider->base = of_iomap(node, 0);
+
+       INIT_LIST_HEAD(&provider->clocks);
+
+       /* Generate clocks */
+       reg_data = data->regs;
+
+       while (reg_data->parent) {
+               hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+               if (!hw)
+                       return;
+
+               hw->enable_reg.ptr = provider->base + reg_data->offset;
+
+               _ti_clkctrl_setup_subclks(provider, node, reg_data,
+                                         hw->enable_reg.ptr);
+
+               if (reg_data->flags & CLKF_SW_SUP)
+                       hw->enable_bit = MODULEMODE_SWCTRL;
+               if (reg_data->flags & CLKF_HW_SUP)
+                       hw->enable_bit = MODULEMODE_HWCTRL;
+               if (reg_data->flags & CLKF_NO_IDLEST)
+                       hw->flags |= NO_IDLEST;
+
+               init.parent_names = &reg_data->parent;
+               init.num_parents = 1;
+               init.flags = 0;
+               init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
+                                     node->parent->name, node->name,
+                                     reg_data->offset, 0);
+               clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
+               if (!init.name || !clkctrl_clk)
+                       goto cleanup;
+
+               init.ops = &omap4_clkctrl_clk_ops;
+               hw->hw.init = &init;
+
+               clk = ti_clk_register(NULL, &hw->hw, init.name);
+               if (IS_ERR_OR_NULL(clk))
+                       goto cleanup;
+
+               clkctrl_clk->reg_offset = reg_data->offset;
+               clkctrl_clk->clk = &hw->hw;
+
+               list_add(&clkctrl_clk->node, &provider->clocks);
+
+               reg_data++;
+       }
+
+       of_clk_add_hw_provider(node, _ti_omap4_clkctrl_xlate, provider);
+       return;
+
+cleanup:
+       kfree(hw);
+       kfree(init.name);
+       kfree(clkctrl_clk);
+}
+CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl",
+              _ti_omap4_clkctrl_setup);
index 3f7b26540be86d01ad5d7d2a93884a445290ff84..561dbe99ced72122b5b33a808830c0706891a01d 100644 (file)
@@ -203,6 +203,37 @@ struct ti_dt_clk {
                .node_name = name,      \
        }
 
+/* CLKCTRL type definitions */
+struct omap_clkctrl_div_data {
+       const int *dividers;
+       int max_div;
+};
+
+struct omap_clkctrl_bit_data {
+       u8 bit;
+       u8 type;
+       const char * const *parents;
+       const void *data;
+};
+
+struct omap_clkctrl_reg_data {
+       u16 offset;
+       const struct omap_clkctrl_bit_data *bit_data;
+       u16 flags;
+       const char *parent;
+};
+
+struct omap_clkctrl_data {
+       u32 addr;
+       const struct omap_clkctrl_reg_data *regs;
+};
+
+extern const struct omap_clkctrl_data omap4_clkctrl_data[];
+
+#define CLKF_SW_SUP    BIT(0)
+#define CLKF_HW_SUP    BIT(1)
+#define CLKF_NO_IDLEST BIT(2)
+
 typedef void (*ti_of_clk_init_cb_t)(struct clk_hw *, struct device_node *);
 
 struct clk *ti_clk_register_gate(struct ti_clk *setup);
index c8027d909429a352990bc848089e24099e9e9b68..ad0218182a9f33a59b9067aaba6d03b7c052ff06 100644 (file)
        UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10),              \
        UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15)
 
+/* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */
 #define UNIPHIER_SLD3_SYS_CLK_NAND(idx)                                        \
-       UNIPHIER_CLK_GATE("nand", (idx), NULL, 0x2104, 2)
+       UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8),             \
+       UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2)
+
+#define UNIPHIER_PRO5_SYS_CLK_NAND(idx)                                        \
+       UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 12),            \
+       UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2)
 
 #define UNIPHIER_LD11_SYS_CLK_NAND(idx)                                        \
-       UNIPHIER_CLK_GATE("nand", (idx), NULL, 0x210c, 0)
+       UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 10),            \
+       UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x210c, 0)
 
 #define UNIPHIER_LD11_SYS_CLK_EMMC(idx)                                        \
        UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2)
@@ -114,7 +121,7 @@ const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
        UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125),     /* 2949.12 MHz */
        UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40),
        UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
-       UNIPHIER_SLD3_SYS_CLK_NAND(2),
+       UNIPHIER_PRO5_SYS_CLK_NAND(2),
        UNIPHIER_PRO5_SYS_CLK_SD,
        UNIPHIER_SLD3_SYS_CLK_STDMAC(8),                        /* HSC */
        UNIPHIER_PRO4_SYS_CLK_GIO(12),                          /* PCIe, USB3 */
@@ -127,7 +134,7 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
        UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1),          /* 2400 MHz */
        UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27),
        UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
-       UNIPHIER_SLD3_SYS_CLK_NAND(2),
+       UNIPHIER_PRO5_SYS_CLK_NAND(2),
        UNIPHIER_PRO5_SYS_CLK_SD,
        UNIPHIER_SLD3_SYS_CLK_STDMAC(8),                        /* HSC, RLE */
        /* GIO is always clock-enabled: no function for 0x2104 bit6 */
index 794130402c8dca01985d9142fdeea2be2a1f013a..58b54b814a6d1ac5bca12d86e24efed21c4f3904 100644 (file)
@@ -1,6 +1,5 @@
 # Makefile for Versatile-specific clocks
 obj-$(CONFIG_ICST)             += icst.o clk-icst.o clk-versatile.o
 obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o
-obj-$(CONFIG_ARCH_REALVIEW)    += clk-realview.o
 obj-$(CONFIG_CLK_SP810)                += clk-sp810.o
 obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk-vexpress-osc.o
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
deleted file mode 100644 (file)
index 6fdfee3..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Clock driver for the ARM RealView boards
- * Copyright (C) 2012 Linus Walleij
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/clkdev.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/clk-provider.h>
-
-#include "icst.h"
-#include "clk-icst.h"
-
-#define REALVIEW_SYS_OSC0_OFFSET             0x0C
-#define REALVIEW_SYS_OSC1_OFFSET             0x10
-#define REALVIEW_SYS_OSC2_OFFSET             0x14
-#define REALVIEW_SYS_OSC3_OFFSET             0x18
-#define REALVIEW_SYS_OSC4_OFFSET             0x1C      /* OSC1 for RealView/AB */
-#define REALVIEW_SYS_LOCK_OFFSET             0x20
-
-/*
- * Implementation of the ARM RealView clock trees.
- */
-
-static const struct icst_params realview_oscvco_params = {
-       .ref            = 24000000,
-       .vco_max        = ICST307_VCO_MAX,
-       .vco_min        = ICST307_VCO_MIN,
-       .vd_min         = 4 + 8,
-       .vd_max         = 511 + 8,
-       .rd_min         = 1 + 2,
-       .rd_max         = 127 + 2,
-       .s2div          = icst307_s2div,
-       .idx2s          = icst307_idx2s,
-};
-
-static const struct clk_icst_desc realview_osc0_desc __initconst = {
-       .params = &realview_oscvco_params,
-       .vco_offset = REALVIEW_SYS_OSC0_OFFSET,
-       .lock_offset = REALVIEW_SYS_LOCK_OFFSET,
-};
-
-static const struct clk_icst_desc realview_osc4_desc __initconst = {
-       .params = &realview_oscvco_params,
-       .vco_offset = REALVIEW_SYS_OSC4_OFFSET,
-       .lock_offset = REALVIEW_SYS_LOCK_OFFSET,
-};
-
-/*
- * realview_clk_init() - set up the RealView clock tree
- */
-void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176)
-{
-       struct clk *clk;
-
-       /* APB clock dummy */
-       clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0);
-       clk_register_clkdev(clk, "apb_pclk", NULL);
-
-       /* 24 MHz clock */
-       clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, 0, 24000000);
-       clk_register_clkdev(clk, NULL, "dev:uart0");
-       clk_register_clkdev(clk, NULL, "dev:uart1");
-       clk_register_clkdev(clk, NULL, "dev:uart2");
-       clk_register_clkdev(clk, NULL, "fpga:kmi0");
-       clk_register_clkdev(clk, NULL, "fpga:kmi1");
-       clk_register_clkdev(clk, NULL, "fpga:mmc0");
-       clk_register_clkdev(clk, NULL, "dev:ssp0");
-       if (is_pb1176) {
-               /*
-                * UART3 is on the dev chip in PB1176
-                * UART4 only exists in PB1176
-                */
-               clk_register_clkdev(clk, NULL, "dev:uart3");
-               clk_register_clkdev(clk, NULL, "dev:uart4");
-       } else
-               clk_register_clkdev(clk, NULL, "fpga:uart3");
-
-
-       /* 1 MHz clock */
-       clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, 0, 1000000);
-       clk_register_clkdev(clk, NULL, "sp804");
-
-       /* ICST VCO clock */
-       if (is_pb1176)
-               clk = icst_clk_register(NULL, &realview_osc0_desc,
-                                       "osc0", NULL, sysbase);
-       else
-               clk = icst_clk_register(NULL, &realview_osc4_desc,
-                                       "osc4", NULL, sysbase);
-
-       clk_register_clkdev(clk, NULL, "dev:clcd");
-       clk_register_clkdev(clk, NULL, "issp:clcd");
-}
index a10962988ba8efd9441ca22c327899d0fbc05fb1..27f853d4c76bfe2598ba9d8e70557272c8110f1f 100644 (file)
@@ -932,10 +932,10 @@ PNAME(audio_timer_p) = {
 };
 
 static struct zx_clk_mux audio_mux_clk[] = {
-       MUX(0, "i2s0_wclk_mux", audio_wclk_common_p, AUDIO_I2S0_CLK, 0, 1),
-       MUX(0, "i2s1_wclk_mux", audio_wclk_common_p, AUDIO_I2S1_CLK, 0, 1),
-       MUX(0, "i2s2_wclk_mux", audio_wclk_common_p, AUDIO_I2S2_CLK, 0, 1),
-       MUX(0, "i2s3_wclk_mux", audio_wclk_common_p, AUDIO_I2S3_CLK, 0, 1),
+       MUX(I2S0_WCLK_MUX, "i2s0_wclk_mux", audio_wclk_common_p, AUDIO_I2S0_CLK, 0, 1),
+       MUX(I2S1_WCLK_MUX, "i2s1_wclk_mux", audio_wclk_common_p, AUDIO_I2S1_CLK, 0, 1),
+       MUX(I2S2_WCLK_MUX, "i2s2_wclk_mux", audio_wclk_common_p, AUDIO_I2S2_CLK, 0, 1),
+       MUX(I2S3_WCLK_MUX, "i2s3_wclk_mux", audio_wclk_common_p, AUDIO_I2S3_CLK, 0, 1),
        MUX(0, "i2c0_wclk_mux", audio_wclk_common_p, AUDIO_I2C0_CLK, 0, 1),
        MUX(0, "spdif0_wclk_mux", audio_wclk_common_p, AUDIO_SPDIF0_CLK, 0, 1),
        MUX(0, "spdif1_wclk_mux", audio_wclk_common_p, AUDIO_SPDIF1_CLK, 0, 1),
diff --git a/include/dt-bindings/clock/cortina,gemini-clock.h b/include/dt-bindings/clock/cortina,gemini-clock.h
new file mode 100644 (file)
index 0000000..acf5cd5
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef DT_BINDINGS_CORTINA_GEMINI_CLOCK_H
+#define DT_BINDINGS_CORTINA_GEMINI_CLOCK_H
+
+/* RTC, AHB, APB, CPU, PCI, TVC, UART clocks and 13 gates */
+#define GEMINI_NUM_CLKS 20
+
+#define GEMINI_CLK_RTC 0
+#define GEMINI_CLK_AHB 1
+#define GEMINI_CLK_APB 2
+#define GEMINI_CLK_CPU 3
+#define GEMINI_CLK_PCI 4
+#define GEMINI_CLK_TVC 5
+#define GEMINI_CLK_UART 6
+#define GEMINI_CLK_GATES 7
+#define GEMINI_CLK_GATE_SECURITY 7
+#define GEMINI_CLK_GATE_GMAC0 8
+#define GEMINI_CLK_GATE_GMAC1 9
+#define GEMINI_CLK_GATE_SATA0 10
+#define GEMINI_CLK_GATE_SATA1 11
+#define GEMINI_CLK_GATE_USB0 12
+#define GEMINI_CLK_GATE_USB1 13
+#define GEMINI_CLK_GATE_IDE 14
+#define GEMINI_CLK_GATE_PCI 15
+#define GEMINI_CLK_GATE_DDR 16
+#define GEMINI_CLK_GATE_FLASH 17
+#define GEMINI_CLK_GATE_TVC 18
+#define GEMINI_CLK_GATE_BOOT 19
+
+#endif /* DT_BINDINGS_CORTINA_GEMINI_CLOCK_H */
index 6fd21c291416eb02227e66ecfed24f897914a768..2740ae0424a97836cc3212f773fea13f4e91a53d 100644 (file)
 #define CLK_MOUT_MCLK_CDREX    654
 #define CLK_MOUT_BPLL          655
 #define CLK_MOUT_MX_MSPLL_CCORE        656
+#define CLK_MOUT_EPLL          657
+#define CLK_MOUT_MAU_EPLL      658
+#define CLK_MOUT_USER_MAU_EPLL 659
 
 /* divider clocks */
 #define CLK_DOUT_PIXEL         768
index 1c00b7fe296f8319055476243854f7af8a256b7d..adb768d447a523043f3936746ac59004af689c6c 100644 (file)
 #define HI3660_CLK_DIV_UFSPERI         137
 #define HI3660_CLK_DIV_AOMM            138
 #define HI3660_CLK_DIV_IOPERI          139
+#define HI3660_VENC_VOLT_HOLD          140
+#define HI3660_PERI_VOLT_HOLD          141
+#define HI3660_CLK_GATE_VENC           142
+#define HI3660_CLK_GATE_VDEC           143
+#define HI3660_CLK_ANDGT_VENC          144
+#define HI3660_CLK_ANDGT_VDEC          145
+#define HI3660_CLK_MUX_VENC            146
+#define HI3660_CLK_MUX_VDEC            147
+#define HI3660_CLK_DIV_VENC            148
+#define HI3660_CLK_DIV_VDEC            149
+#define HI3660_CLK_FAC_ISP_SNCLK       150
+#define HI3660_CLK_GATE_ISP_SNCLK0     151
+#define HI3660_CLK_GATE_ISP_SNCLK1     152
+#define HI3660_CLK_GATE_ISP_SNCLK2     153
+#define HI3660_CLK_ANGT_ISP_SNCLK      154
+#define HI3660_CLK_MUX_ISP_SNCLK       155
+#define HI3660_CLK_DIV_ISP_SNCLK       156
 
 /* clk in pmuctrl */
 #define HI3660_GATE_ABB_192            0
index b8ba665aab7b3486ad39777acda4a4aa0a249a5d..409cc02cd844c5f4760164795671ba61e6ef5e13 100644 (file)
 #define HI6220_DDRC_AXI1       7
 
 #define HI6220_POWER_NR_CLKS   8
+
+/* clk in Hi6220 acpu sctrl */
+#define HI6220_ACPU_SFT_AT_S           0
+
 #endif
index 181c0f070f7c91f0e305c6e10cadb9d8908415ce..067f5e501b0c4f2c75f979d221c5cf37d234e244 100644 (file)
 #define HISTB_ETH1_MAC_CLK             31
 #define HISTB_ETH1_MACIF_CLK           32
 #define HISTB_COMBPHY1_CLK             33
-
+#define HISTB_USB2_BUS_CLK     34
+#define HISTB_USB2_PHY_CLK     35
+#define HISTB_USB2_UTMI_CLK    36
+#define HISTB_USB2_12M_CLK     37
+#define HISTB_USB2_48M_CLK     38
+#define HISTB_USB2_OTG_UTMI_CLK        39
+#define HISTB_USB2_PHY1_REF_CLK        40
+#define HISTB_USB2_PHY2_REF_CLK        41
 
 /* clocks provided by mcu CRG */
 #define HISTB_MCE_CLK  1
index a7a1a50f33efe98b00f6f818d2cca609019673bc..de62a83b6c802661b5f7cecae28a7fbabcd34076 100644 (file)
 #define IMX7D_CLK_ARM                  437
 #define IMX7D_CKIL                     438
 #define IMX7D_OCOTP_CLK                        439
-#define IMX7D_CLK_END                  440
+#define IMX7D_NAND_RAWNAND_CLK         440
+#define IMX7D_NAND_USDHC_BUS_RAWNAND_CLK 441
+#define IMX7D_CLK_END                  442
 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
index 2062c67e2e515845a1f2bbff6fbb6f934e8a00ca..551f7600ab586a46ff90548e9fcf977d9083674a 100644 (file)
 #define CLK_INFRA_PMICWRAP                     17
 #define CLK_INFRA_DDCCI                                18
 #define CLK_INFRA_CLK_13M                      19
-#define CLK_INFRA_NR                           20
+#define CLK_INFRA_CPUSEL                        20
+#define CLK_INFRA_NR                           21
 
 /* PERICFG */
 
index 6094bf7e50abb6146c18c013b49d93c7ab1f52ce..8aea623dd518e0e3571adf89f5866e4c520f4c42 100644 (file)
 #define CLK_INFRA_PMICSPI              10
 #define CLK_INFRA_PMICWRAP             11
 #define CLK_INFRA_CLK_13M              12
-#define CLK_INFRA_NR_CLK               13
+#define CLK_INFRA_CA53SEL               13
+#define CLK_INFRA_CA57SEL               14
+#define CLK_INFRA_NR_CLK                15
 
 /* PERI_SYS */
 
diff --git a/include/dt-bindings/clock/omap4.h b/include/dt-bindings/clock/omap4.h
new file mode 100644 (file)
index 0000000..e86c758
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017 Texas Instruments, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __DT_BINDINGS_CLK_OMAP4_H
+#define __DT_BINDINGS_CLK_OMAP4_H
+
+#define OMAP4_CLKCTRL_OFFSET   0x20
+#define OMAP4_CLKCTRL_INDEX(offset)    ((offset) - OMAP4_CLKCTRL_OFFSET)
+
+/* mpuss clocks */
+#define OMAP4_MPU_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+
+/* tesla clocks */
+#define OMAP4_DSP_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+
+/* abe clocks */
+#define OMAP4_L4_ABE_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_AESS_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_MCPDM_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_DMIC_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_MCASP_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x40)
+#define OMAP4_MCBSP1_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x48)
+#define OMAP4_MCBSP2_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x50)
+#define OMAP4_MCBSP3_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x58)
+#define OMAP4_SLIMBUS1_CLKCTRL OMAP4_CLKCTRL_INDEX(0x60)
+#define OMAP4_TIMER5_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x68)
+#define OMAP4_TIMER6_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x70)
+#define OMAP4_TIMER7_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x78)
+#define OMAP4_TIMER8_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x80)
+#define OMAP4_WD_TIMER3_CLKCTRL        OMAP4_CLKCTRL_INDEX(0x88)
+
+/* l4_ao clocks */
+#define OMAP4_SMARTREFLEX_MPU_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_SMARTREFLEX_IVA_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_SMARTREFLEX_CORE_CLKCTRL OMAP4_CLKCTRL_INDEX(0x38)
+
+/* l3_1 clocks */
+#define OMAP4_L3_MAIN_1_CLKCTRL        OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_2 clocks */
+#define OMAP4_L3_MAIN_2_CLKCTRL        OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_GPMC_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_OCMC_RAM_CLKCTRL OMAP4_CLKCTRL_INDEX(0x30)
+
+/* ducati clocks */
+#define OMAP4_IPU_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_dma clocks */
+#define OMAP4_DMA_SYSTEM_CLKCTRL       OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_emif clocks */
+#define OMAP4_DMM_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_EMIF1_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_EMIF2_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x38)
+
+/* d2d clocks */
+#define OMAP4_C2C_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l4_cfg clocks */
+#define OMAP4_L4_CFG_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_SPINLOCK_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_MAILBOX_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x30)
+
+/* l3_instr clocks */
+#define OMAP4_L3_MAIN_3_CLKCTRL        OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_L3_INSTR_CLKCTRL OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_OCP_WP_NOC_CLKCTRL       OMAP4_CLKCTRL_INDEX(0x40)
+
+/* ivahd clocks */
+#define OMAP4_IVA_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_SL2IF_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x28)
+
+/* iss clocks */
+#define OMAP4_ISS_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_FDIF_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x28)
+
+/* l3_dss clocks */
+#define OMAP4_DSS_CORE_CLKCTRL OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_gfx clocks */
+#define OMAP4_GPU_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x20)
+
+/* l3_init clocks */
+#define OMAP4_MMC1_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_MMC2_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_HSI_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_USB_HOST_HS_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x58)
+#define OMAP4_USB_OTG_HS_CLKCTRL       OMAP4_CLKCTRL_INDEX(0x60)
+#define OMAP4_USB_TLL_HS_CLKCTRL       OMAP4_CLKCTRL_INDEX(0x68)
+#define OMAP4_USB_HOST_FS_CLKCTRL      OMAP4_CLKCTRL_INDEX(0xd0)
+#define OMAP4_OCP2SCP_USB_PHY_CLKCTRL  OMAP4_CLKCTRL_INDEX(0xe0)
+
+/* l4_per clocks */
+#define OMAP4_TIMER10_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x28)
+#define OMAP4_TIMER11_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_TIMER2_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_TIMER3_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x40)
+#define OMAP4_TIMER4_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x48)
+#define OMAP4_TIMER9_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x50)
+#define OMAP4_ELM_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x58)
+#define OMAP4_GPIO2_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x60)
+#define OMAP4_GPIO3_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x68)
+#define OMAP4_GPIO4_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x70)
+#define OMAP4_GPIO5_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x78)
+#define OMAP4_GPIO6_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x80)
+#define OMAP4_HDQ1W_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x88)
+#define OMAP4_I2C1_CLKCTRL     OMAP4_CLKCTRL_INDEX(0xa0)
+#define OMAP4_I2C2_CLKCTRL     OMAP4_CLKCTRL_INDEX(0xa8)
+#define OMAP4_I2C3_CLKCTRL     OMAP4_CLKCTRL_INDEX(0xb0)
+#define OMAP4_I2C4_CLKCTRL     OMAP4_CLKCTRL_INDEX(0xb8)
+#define OMAP4_L4_PER_CLKCTRL   OMAP4_CLKCTRL_INDEX(0xc0)
+#define OMAP4_MCBSP4_CLKCTRL   OMAP4_CLKCTRL_INDEX(0xe0)
+#define OMAP4_MCSPI1_CLKCTRL   OMAP4_CLKCTRL_INDEX(0xf0)
+#define OMAP4_MCSPI2_CLKCTRL   OMAP4_CLKCTRL_INDEX(0xf8)
+#define OMAP4_MCSPI3_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x100)
+#define OMAP4_MCSPI4_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x108)
+#define OMAP4_MMC3_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x120)
+#define OMAP4_MMC4_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x128)
+#define OMAP4_SLIMBUS2_CLKCTRL OMAP4_CLKCTRL_INDEX(0x138)
+#define OMAP4_UART1_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x140)
+#define OMAP4_UART2_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x148)
+#define OMAP4_UART3_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x150)
+#define OMAP4_UART4_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x158)
+#define OMAP4_MMC5_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x160)
+
+/* l4_wkup clocks */
+#define OMAP4_L4_WKUP_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x20)
+#define OMAP4_WD_TIMER2_CLKCTRL        OMAP4_CLKCTRL_INDEX(0x30)
+#define OMAP4_GPIO1_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x38)
+#define OMAP4_TIMER1_CLKCTRL   OMAP4_CLKCTRL_INDEX(0x40)
+#define OMAP4_COUNTER_32K_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x50)
+#define OMAP4_KBD_CLKCTRL      OMAP4_CLKCTRL_INDEX(0x78)
+
+/* emu_sys clocks */
+#define OMAP4_DEBUGSS_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x20)
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq8074.h b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
new file mode 100644 (file)
index 0000000..370c83c
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_IPQ_GCC_8074_H
+#define _DT_BINDINGS_CLOCK_IPQ_GCC_8074_H
+
+#define GPLL0                                  0
+#define GPLL0_MAIN                             1
+#define GCC_SLEEP_CLK_SRC                      2
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC            3
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC            4
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC            5
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC            6
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC            7
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC            8
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC            9
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC            10
+#define BLSP1_QUP5_I2C_APPS_CLK_SRC            11
+#define BLSP1_QUP5_SPI_APPS_CLK_SRC            12
+#define BLSP1_QUP6_I2C_APPS_CLK_SRC            13
+#define BLSP1_QUP6_SPI_APPS_CLK_SRC            14
+#define BLSP1_UART1_APPS_CLK_SRC               15
+#define BLSP1_UART2_APPS_CLK_SRC               16
+#define BLSP1_UART3_APPS_CLK_SRC               17
+#define BLSP1_UART4_APPS_CLK_SRC               18
+#define BLSP1_UART5_APPS_CLK_SRC               19
+#define BLSP1_UART6_APPS_CLK_SRC               20
+#define GCC_BLSP1_AHB_CLK                      21
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK            22
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK            23
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK            24
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK            25
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK            26
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK            27
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK            28
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK            29
+#define GCC_BLSP1_QUP5_I2C_APPS_CLK            30
+#define GCC_BLSP1_QUP5_SPI_APPS_CLK            31
+#define GCC_BLSP1_QUP6_I2C_APPS_CLK            32
+#define GCC_BLSP1_QUP6_SPI_APPS_CLK            33
+#define GCC_BLSP1_UART1_APPS_CLK               34
+#define GCC_BLSP1_UART2_APPS_CLK               35
+#define GCC_BLSP1_UART3_APPS_CLK               36
+#define GCC_BLSP1_UART4_APPS_CLK               37
+#define GCC_BLSP1_UART5_APPS_CLK               38
+#define GCC_BLSP1_UART6_APPS_CLK               39
+#define GCC_PRNG_AHB_CLK                       40
+#define GCC_QPIC_AHB_CLK                       41
+#define GCC_QPIC_CLK                           42
+#define PCNOC_BFDCD_CLK_SRC                    43
+
+#define GCC_BLSP1_BCR                          0
+#define GCC_BLSP1_QUP1_BCR                     1
+#define GCC_BLSP1_UART1_BCR                    2
+#define GCC_BLSP1_QUP2_BCR                     3
+#define GCC_BLSP1_UART2_BCR                    4
+#define GCC_BLSP1_QUP3_BCR                     5
+#define GCC_BLSP1_UART3_BCR                    6
+#define GCC_BLSP1_QUP4_BCR                     7
+#define GCC_BLSP1_UART4_BCR                    8
+#define GCC_BLSP1_QUP5_BCR                     9
+#define GCC_BLSP1_UART5_BCR                    10
+#define GCC_BLSP1_QUP6_BCR                     11
+#define GCC_BLSP1_UART6_BCR                    12
+#define GCC_IMEM_BCR                           13
+#define GCC_SMMU_BCR                           14
+#define GCC_APSS_TCU_BCR                       15
+#define GCC_SMMU_XPU_BCR                       16
+#define GCC_PCNOC_TBU_BCR                      17
+#define GCC_SMMU_CFG_BCR                       18
+#define GCC_PRNG_BCR                           19
+#define GCC_BOOT_ROM_BCR                       20
+#define GCC_CRYPTO_BCR                         21
+#define GCC_WCSS_BCR                           22
+#define GCC_WCSS_Q6_BCR                                23
+#define GCC_NSS_BCR                            24
+#define GCC_SEC_CTRL_BCR                       25
+#define GCC_ADSS_BCR                           26
+#define GCC_DDRSS_BCR                          27
+#define GCC_SYSTEM_NOC_BCR                     28
+#define GCC_PCNOC_BCR                          29
+#define GCC_TCSR_BCR                           30
+#define GCC_QDSS_BCR                           31
+#define GCC_DCD_BCR                            32
+#define GCC_MSG_RAM_BCR                                33
+#define GCC_MPM_BCR                            34
+#define GCC_SPMI_BCR                           35
+#define GCC_SPDM_BCR                           36
+#define GCC_RBCPR_BCR                          37
+#define GCC_RBCPR_MX_BCR                       38
+#define GCC_TLMM_BCR                           39
+#define GCC_RBCPR_WCSS_BCR                     40
+#define GCC_USB0_PHY_BCR                       41
+#define GCC_USB3PHY_0_PHY_BCR                  42
+#define GCC_USB0_BCR                           43
+#define GCC_USB1_PHY_BCR                       44
+#define GCC_USB3PHY_1_PHY_BCR                  45
+#define GCC_USB1_BCR                           46
+#define GCC_QUSB2_0_PHY_BCR                    47
+#define GCC_QUSB2_1_PHY_BCR                    48
+#define GCC_SDCC1_BCR                          49
+#define GCC_SDCC2_BCR                          50
+#define GCC_SNOC_BUS_TIMEOUT0_BCR              51
+#define GCC_SNOC_BUS_TIMEOUT2_BCR              52
+#define GCC_SNOC_BUS_TIMEOUT3_BCR              53
+#define GCC_PCNOC_BUS_TIMEOUT0_BCR             54
+#define GCC_PCNOC_BUS_TIMEOUT1_BCR             55
+#define GCC_PCNOC_BUS_TIMEOUT2_BCR             56
+#define GCC_PCNOC_BUS_TIMEOUT3_BCR             57
+#define GCC_PCNOC_BUS_TIMEOUT4_BCR             58
+#define GCC_PCNOC_BUS_TIMEOUT5_BCR             59
+#define GCC_PCNOC_BUS_TIMEOUT6_BCR             60
+#define GCC_PCNOC_BUS_TIMEOUT7_BCR             61
+#define GCC_PCNOC_BUS_TIMEOUT8_BCR             62
+#define GCC_PCNOC_BUS_TIMEOUT9_BCR             63
+#define GCC_UNIPHY0_BCR                                64
+#define GCC_UNIPHY1_BCR                                65
+#define GCC_UNIPHY2_BCR                                66
+#define GCC_CMN_12GPLL_BCR                     67
+#define GCC_QPIC_BCR                           68
+#define GCC_MDIO_BCR                           69
+#define GCC_PCIE1_TBU_BCR                      70
+#define GCC_WCSS_CORE_TBU_BCR                  71
+#define GCC_WCSS_Q6_TBU_BCR                    72
+#define GCC_USB0_TBU_BCR                       73
+#define GCC_USB1_TBU_BCR                       74
+#define GCC_PCIE0_TBU_BCR                      75
+#define GCC_NSS_NOC_TBU_BCR                    76
+#define GCC_PCIE0_BCR                          77
+#define GCC_PCIE0_PHY_BCR                      78
+#define GCC_PCIE0PHY_PHY_BCR                   79
+#define GCC_PCIE0_LINK_DOWN_BCR                        80
+#define GCC_PCIE1_BCR                          81
+#define GCC_PCIE1_PHY_BCR                      82
+#define GCC_PCIE1PHY_PHY_BCR                   83
+#define GCC_PCIE1_LINK_DOWN_BCR                        84
+#define GCC_DCC_BCR                            85
+#define GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR    86
+#define GCC_APC1_VOLTAGE_DROOP_DETECTOR_BCR    87
+#define GCC_SMMU_CATS_BCR                      88
+
+#endif
diff --git a/include/dt-bindings/clock/r8a7790-cpg-mssr.h b/include/dt-bindings/clock/r8a7790-cpg-mssr.h
new file mode 100644 (file)
index 0000000..1625b8b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7790 CPG Core Clocks */
+#define R8A7790_CLK_Z                  0
+#define R8A7790_CLK_Z2                 1
+#define R8A7790_CLK_ZG                 2
+#define R8A7790_CLK_ZTR                        3
+#define R8A7790_CLK_ZTRD2              4
+#define R8A7790_CLK_ZT                 5
+#define R8A7790_CLK_ZX                 6
+#define R8A7790_CLK_ZS                 7
+#define R8A7790_CLK_HP                 8
+#define R8A7790_CLK_I                  9
+#define R8A7790_CLK_B                  10
+#define R8A7790_CLK_LB                 11
+#define R8A7790_CLK_P                  12
+#define R8A7790_CLK_CL                 13
+#define R8A7790_CLK_M2                 14
+#define R8A7790_CLK_ADSP               15
+#define R8A7790_CLK_IMP                        16
+#define R8A7790_CLK_ZB3                        17
+#define R8A7790_CLK_ZB3D2              18
+#define R8A7790_CLK_DDR                        19
+#define R8A7790_CLK_SDH                        20
+#define R8A7790_CLK_SD0                        21
+#define R8A7790_CLK_SD1                        22
+#define R8A7790_CLK_SD2                        23
+#define R8A7790_CLK_SD3                        24
+#define R8A7790_CLK_MMC0               25
+#define R8A7790_CLK_MMC1               26
+#define R8A7790_CLK_MP                 27
+#define R8A7790_CLK_SSP                        28
+#define R8A7790_CLK_SSPRS              29
+#define R8A7790_CLK_QSPI               30
+#define R8A7790_CLK_CP                 31
+#define R8A7790_CLK_RCAN               32
+#define R8A7790_CLK_R                  33
+#define R8A7790_CLK_OSC                        34
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a7791-cpg-mssr.h b/include/dt-bindings/clock/r8a7791-cpg-mssr.h
new file mode 100644 (file)
index 0000000..e882341
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7791 CPG Core Clocks */
+#define R8A7791_CLK_Z                  0
+#define R8A7791_CLK_ZG                 1
+#define R8A7791_CLK_ZTR                        2
+#define R8A7791_CLK_ZTRD2              3
+#define R8A7791_CLK_ZT                 4
+#define R8A7791_CLK_ZX                 5
+#define R8A7791_CLK_ZS                 6
+#define R8A7791_CLK_HP                 7
+#define R8A7791_CLK_I                  8
+#define R8A7791_CLK_B                  9
+#define R8A7791_CLK_LB                 10
+#define R8A7791_CLK_P                  11
+#define R8A7791_CLK_CL                 12
+#define R8A7791_CLK_M2                 13
+#define R8A7791_CLK_ADSP               14
+#define R8A7791_CLK_ZB3                        15
+#define R8A7791_CLK_ZB3D2              16
+#define R8A7791_CLK_DDR                        17
+#define R8A7791_CLK_SDH                        18
+#define R8A7791_CLK_SD0                        19
+#define R8A7791_CLK_SD2                        20
+#define R8A7791_CLK_SD3                        21
+#define R8A7791_CLK_MMC0               22
+#define R8A7791_CLK_MP                 23
+#define R8A7791_CLK_SSP                        24
+#define R8A7791_CLK_SSPRS              25
+#define R8A7791_CLK_QSPI               26
+#define R8A7791_CLK_CP                 27
+#define R8A7791_CLK_RCAN               28
+#define R8A7791_CLK_R                  29
+#define R8A7791_CLK_OSC                        30
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a7792-cpg-mssr.h b/include/dt-bindings/clock/r8a7792-cpg-mssr.h
new file mode 100644 (file)
index 0000000..72ce85c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7792 CPG Core Clocks */
+#define R8A7792_CLK_Z                  0
+#define R8A7792_CLK_ZG                 1
+#define R8A7792_CLK_ZTR                        2
+#define R8A7792_CLK_ZTRD2              3
+#define R8A7792_CLK_ZT                 4
+#define R8A7792_CLK_ZX                 5
+#define R8A7792_CLK_ZS                 6
+#define R8A7792_CLK_HP                 7
+#define R8A7792_CLK_I                  8
+#define R8A7792_CLK_B                  9
+#define R8A7792_CLK_LB                 10
+#define R8A7792_CLK_P                  11
+#define R8A7792_CLK_CL                 12
+#define R8A7792_CLK_M2                 13
+#define R8A7792_CLK_IMP                        14
+#define R8A7792_CLK_ZB3                        15
+#define R8A7792_CLK_ZB3D2              16
+#define R8A7792_CLK_DDR                        17
+#define R8A7792_CLK_SD                 18
+#define R8A7792_CLK_MP                 19
+#define R8A7792_CLK_QSPI               20
+#define R8A7792_CLK_CP                 21
+#define R8A7792_CLK_CPEX               22
+#define R8A7792_CLK_RCAN               23
+#define R8A7792_CLK_R                  24
+#define R8A7792_CLK_OSC                        25
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a7793-cpg-mssr.h b/include/dt-bindings/clock/r8a7793-cpg-mssr.h
new file mode 100644 (file)
index 0000000..8809b0f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7793 CPG Core Clocks */
+#define R8A7793_CLK_Z                  0
+#define R8A7793_CLK_ZG                 1
+#define R8A7793_CLK_ZTR                        2
+#define R8A7793_CLK_ZTRD2              3
+#define R8A7793_CLK_ZT                 4
+#define R8A7793_CLK_ZX                 5
+#define R8A7793_CLK_ZS                 6
+#define R8A7793_CLK_HP                 7
+#define R8A7793_CLK_I                  8
+#define R8A7793_CLK_B                  9
+#define R8A7793_CLK_LB                 10
+#define R8A7793_CLK_P                  11
+#define R8A7793_CLK_CL                 12
+#define R8A7793_CLK_M2                 13
+#define R8A7793_CLK_ADSP               14
+#define R8A7793_CLK_ZB3                        15
+#define R8A7793_CLK_ZB3D2              16
+#define R8A7793_CLK_DDR                        17
+#define R8A7793_CLK_SDH                        18
+#define R8A7793_CLK_SD0                        19
+#define R8A7793_CLK_SD2                        20
+#define R8A7793_CLK_SD3                        21
+#define R8A7793_CLK_MMC0               22
+#define R8A7793_CLK_MP                 23
+#define R8A7793_CLK_SSP                        24
+#define R8A7793_CLK_SSPRS              25
+#define R8A7793_CLK_QSPI               26
+#define R8A7793_CLK_CP                 27
+#define R8A7793_CLK_RCAN               28
+#define R8A7793_CLK_R                  29
+#define R8A7793_CLK_OSC                        30
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/r8a7794-cpg-mssr.h b/include/dt-bindings/clock/r8a7794-cpg-mssr.h
new file mode 100644 (file)
index 0000000..9d72031
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7794 CPG Core Clocks */
+#define R8A7794_CLK_Z2                 0
+#define R8A7794_CLK_ZG                 1
+#define R8A7794_CLK_ZTR                        2
+#define R8A7794_CLK_ZTRD2              3
+#define R8A7794_CLK_ZT                 4
+#define R8A7794_CLK_ZX                 5
+#define R8A7794_CLK_ZS                 6
+#define R8A7794_CLK_HP                 7
+#define R8A7794_CLK_I                  8
+#define R8A7794_CLK_B                  9
+#define R8A7794_CLK_LB                 10
+#define R8A7794_CLK_P                  11
+#define R8A7794_CLK_CL                 12
+#define R8A7794_CLK_CP                 13
+#define R8A7794_CLK_M2                 14
+#define R8A7794_CLK_ADSP               15
+#define R8A7794_CLK_ZB3                        16
+#define R8A7794_CLK_ZB3D2              17
+#define R8A7794_CLK_DDR                        18
+#define R8A7794_CLK_SDH                        19
+#define R8A7794_CLK_SD0                        20
+#define R8A7794_CLK_SD2                        21
+#define R8A7794_CLK_SD3                        22
+#define R8A7794_CLK_MMC0               23
+#define R8A7794_CLK_MP                 24
+#define R8A7794_CLK_QSPI               25
+#define R8A7794_CLK_CPEX               26
+#define R8A7794_CLK_RCAN               27
+#define R8A7794_CLK_R                  28
+#define R8A7794_CLK_OSC                        29
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/rk3128-cru.h b/include/dt-bindings/clock/rk3128-cru.h
new file mode 100644 (file)
index 0000000..92894f4
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3128_H
+
+/* core clocks */
+#define PLL_APLL               1
+#define PLL_DPLL               2
+#define PLL_CPLL               3
+#define PLL_GPLL               4
+#define ARMCLK                 5
+#define PLL_GPLL_DIV2          6
+#define PLL_GPLL_DIV3          7
+
+/* sclk gates (special clocks) */
+#define SCLK_SPI0              65
+#define SCLK_NANDC             67
+#define SCLK_SDMMC             68
+#define SCLK_SDIO              69
+#define SCLK_EMMC              71
+#define SCLK_UART0             77
+#define SCLK_UART1             78
+#define SCLK_UART2             79
+#define SCLK_I2S0              80
+#define SCLK_I2S1              81
+#define SCLK_SPDIF             83
+#define SCLK_TIMER0            85
+#define SCLK_TIMER1            86
+#define SCLK_TIMER2            87
+#define SCLK_TIMER3            88
+#define SCLK_TIMER4            89
+#define SCLK_TIMER5            90
+#define SCLK_SARADC            91
+#define SCLK_I2S_OUT           113
+#define SCLK_SDMMC_DRV         114
+#define SCLK_SDIO_DRV          115
+#define SCLK_EMMC_DRV          117
+#define SCLK_SDMMC_SAMPLE      118
+#define SCLK_SDIO_SAMPLE       119
+#define SCLK_EMMC_SAMPLE       121
+#define SCLK_VOP               122
+#define SCLK_MAC_SRC           124
+#define SCLK_MAC               126
+#define SCLK_MAC_REFOUT                127
+#define SCLK_MAC_REF           128
+#define SCLK_MAC_RX            129
+#define SCLK_MAC_TX            130
+#define SCLK_HEVC_CORE         134
+#define SCLK_RGA               135
+#define SCLK_CRYPTO            138
+#define SCLK_TSP               139
+#define SCLK_OTGPHY0           142
+#define SCLK_OTGPHY1           143
+#define SCLK_DDRC              144
+#define SCLK_PVTM_FUNC         145
+#define SCLK_PVTM_CORE         146
+#define SCLK_PVTM_GPU          147
+#define SCLK_MIPI_24M          148
+#define SCLK_PVTM              149
+#define SCLK_CIF_SRC           150
+#define SCLK_CIF_OUT_SRC       151
+#define SCLK_CIF_OUT           152
+#define SCLK_SFC               153
+#define SCLK_USB480M           154
+
+/* dclk gates */
+#define DCLK_VOP               190
+#define DCLK_EBC               191
+
+/* aclk gates */
+#define ACLK_VIO0              192
+#define ACLK_VIO1              193
+#define ACLK_DMAC              194
+#define ACLK_CPU               195
+#define ACLK_VEPU              196
+#define ACLK_VDPU              197
+#define ACLK_CIF               198
+#define ACLK_IEP               199
+#define ACLK_LCDC0             204
+#define ACLK_RGA               205
+#define ACLK_PERI              210
+#define ACLK_VOP               211
+#define ACLK_GMAC              212
+#define ACLK_GPU               213
+
+/* pclk gates */
+#define PCLK_SARADC            318
+#define PCLK_WDT               319
+#define PCLK_GPIO0             320
+#define PCLK_GPIO1             321
+#define PCLK_GPIO2             322
+#define PCLK_GPIO3             323
+#define PCLK_VIO_H2P           324
+#define PCLK_MIPI              325
+#define PCLK_EFUSE             326
+#define PCLK_HDMI              327
+#define PCLK_ACODEC            328
+#define PCLK_GRF               329
+#define PCLK_I2C0              332
+#define PCLK_I2C1              333
+#define PCLK_I2C2              334
+#define PCLK_I2C3              335
+#define PCLK_SPI0              338
+#define PCLK_UART0             341
+#define PCLK_UART1             342
+#define PCLK_UART2             343
+#define PCLK_TSADC             344
+#define PCLK_PWM               350
+#define PCLK_TIMER             353
+#define PCLK_CPU               354
+#define PCLK_PERI              363
+#define PCLK_GMAC              367
+#define PCLK_PMU_PRE           368
+#define PCLK_SIM_CARD          369
+
+/* hclk gates */
+#define HCLK_SPDIF             440
+#define HCLK_GPS               441
+#define HCLK_USBHOST           442
+#define HCLK_I2S_8CH           443
+#define HCLK_I2S_2CH           444
+#define HCLK_VOP               452
+#define HCLK_NANDC             453
+#define HCLK_SDMMC             456
+#define HCLK_SDIO              457
+#define HCLK_EMMC              459
+#define HCLK_CPU               460
+#define HCLK_VEPU              461
+#define HCLK_VDPU              462
+#define HCLK_LCDC0             463
+#define HCLK_EBC               465
+#define HCLK_VIO               466
+#define HCLK_RGA               467
+#define HCLK_IEP               468
+#define HCLK_VIO_H2P           469
+#define HCLK_CIF               470
+#define HCLK_HOST2             473
+#define HCLK_OTG               474
+#define HCLK_TSP               475
+#define HCLK_CRYPTO            476
+#define HCLK_PERI              478
+
+#define CLK_NR_CLKS            (HCLK_PERI + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0_PO          0
+#define SRST_CORE1_PO          1
+#define SRST_CORE2_PO          2
+#define SRST_CORE3_PO          3
+#define SRST_CORE0             4
+#define SRST_CORE1             5
+#define SRST_CORE2             6
+#define SRST_CORE3             7
+#define SRST_CORE0_DBG         8
+#define SRST_CORE1_DBG         9
+#define SRST_CORE2_DBG         10
+#define SRST_CORE3_DBG         11
+#define SRST_TOPDBG            12
+#define SRST_ACLK_CORE         13
+#define SRST_STRC_SYS_A                14
+#define SRST_L2C               15
+
+#define SRST_CPUSYS_H          18
+#define SRST_AHB2APBSYS_H      19
+#define SRST_SPDIF             20
+#define SRST_INTMEM            21
+#define SRST_ROM               22
+#define SRST_PERI_NIU          23
+#define SRST_I2S_2CH           24
+#define SRST_I2S_8CH           25
+#define SRST_GPU_PVTM          26
+#define SRST_FUNC_PVTM         27
+#define SRST_CORE_PVTM         29
+#define SRST_EFUSE_P           30
+#define SRST_ACODEC_P          31
+
+#define SRST_GPIO0             32
+#define SRST_GPIO1             33
+#define SRST_GPIO2             34
+#define SRST_GPIO3             35
+#define SRST_MIPIPHY_P         36
+#define SRST_UART0             39
+#define SRST_UART1             40
+#define SRST_UART2             41
+#define SRST_I2C0              43
+#define SRST_I2C1              44
+#define SRST_I2C2              45
+#define SRST_I2C3              46
+#define SRST_SFC               47
+
+#define SRST_PWM               48
+#define SRST_DAP_PO            50
+#define SRST_DAP               51
+#define SRST_DAP_SYS           52
+#define SRST_CRYPTO            53
+#define SRST_GRF               55
+#define SRST_GMAC              56
+#define SRST_PERIPH_SYS_A      57
+#define SRST_PERIPH_SYS_H      58
+#define SRST_PERIPH_SYS_P       59
+#define SRST_SMART_CARD                60
+#define SRST_CPU_PERI          61
+#define SRST_EMEM_PERI         62
+#define SRST_USB_PERI          63
+
+#define SRST_DMA               64
+#define SRST_GPS               67
+#define SRST_NANDC             68
+#define SRST_USBOTG0           69
+#define SRST_OTGC0             71
+#define SRST_USBOTG1           72
+#define SRST_OTGC1             74
+#define SRST_DDRMSCH           79
+
+#define SRST_SDMMC             81
+#define SRST_SDIO              82
+#define SRST_EMMC              83
+#define SRST_SPI               84
+#define SRST_WDT               86
+#define SRST_SARADC            87
+#define SRST_DDRPHY            88
+#define SRST_DDRPHY_P          89
+#define SRST_DDRCTRL           90
+#define SRST_DDRCTRL_P         91
+#define SRST_TSP               92
+#define SRST_TSP_CLKIN         93
+#define SRST_HOST0_ECHI                94
+
+#define SRST_HDMI_P            96
+#define SRST_VIO_ARBI_H                97
+#define SRST_VIO0_A            98
+#define SRST_VIO_BUS_H         99
+#define SRST_VOP_A             100
+#define SRST_VOP_H             101
+#define SRST_VOP_D             102
+#define SRST_UTMI0             103
+#define SRST_UTMI1             104
+#define SRST_USBPOR            105
+#define SRST_IEP_A             106
+#define SRST_IEP_H             107
+#define SRST_RGA_A             108
+#define SRST_RGA_H             109
+#define SRST_CIF0              110
+#define SRST_PMU               111
+
+#define SRST_VCODEC_A          112
+#define SRST_VCODEC_H          113
+#define SRST_VIO1_A            114
+#define SRST_HEVC_CORE         115
+#define SRST_VCODEC_NIU_A      116
+#define SRST_PMU_NIU_P         117
+#define SRST_LCDC0_S           119
+#define SRST_GPU               120
+#define SRST_GPU_NIU_A         122
+#define SRST_EBC_A             123
+#define SRST_EBC_H             124
+
+#define SRST_CORE_DBG          128
+#define SRST_DBG_P             129
+#define SRST_TIMER0            130
+#define SRST_TIMER1            131
+#define SRST_TIMER2            132
+#define SRST_TIMER3            133
+#define SRST_TIMER4            134
+#define SRST_TIMER5            135
+#define SRST_VIO_H2P           136
+#define SRST_VIO_MIPI_DSI      137
+
+#endif
index aeb2e2f781fb13c9274f6a3807c2afad5aac33d4..81f34d477aeba7ef4e7baa2512d21dfed2db569b 100644 (file)
@@ -19,6 +19,9 @@
 
 #define CLK_HOSC               1
 
+#define CLK_PLL_VIDEO0_2X      9
+
+#define CLK_PLL_VIDEO1_2X      16
 #define CLK_CPU                        17
 
 #define CLK_AHB_OTG            23
diff --git a/include/dt-bindings/clock/sun8i-a83t-ccu.h b/include/dt-bindings/clock/sun8i-a83t-ccu.h
new file mode 100644 (file)
index 0000000..78af508
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_
+#define _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_
+
+#define CLK_PLL_PERIPH         6
+
+#define CLK_PLL_DE             9
+
+#define CLK_C0CPUX             11
+#define CLK_C1CPUX             12
+
+#define CLK_BUS_MIPI_DSI       19
+#define CLK_BUS_SS             20
+#define CLK_BUS_DMA            21
+#define CLK_BUS_MMC0           22
+#define CLK_BUS_MMC1           23
+#define CLK_BUS_MMC2           24
+#define CLK_BUS_NAND           25
+#define CLK_BUS_DRAM           26
+#define CLK_BUS_EMAC           27
+#define CLK_BUS_HSTIMER                28
+#define CLK_BUS_SPI0           29
+#define CLK_BUS_SPI1           30
+#define CLK_BUS_OTG            31
+#define CLK_BUS_EHCI0          32
+#define CLK_BUS_EHCI1          33
+#define CLK_BUS_OHCI0          34
+
+#define CLK_BUS_VE             35
+#define CLK_BUS_TCON0          36
+#define CLK_BUS_TCON1          37
+#define CLK_BUS_CSI            38
+#define CLK_BUS_HDMI           39
+#define CLK_BUS_DE             40
+#define CLK_BUS_GPU            41
+#define CLK_BUS_MSGBOX         42
+#define CLK_BUS_SPINLOCK       43
+
+#define CLK_BUS_SPDIF          44
+#define CLK_BUS_PIO            45
+#define CLK_BUS_I2S0           46
+#define CLK_BUS_I2S1           47
+#define CLK_BUS_I2S2           48
+#define CLK_BUS_TDM            49
+
+#define CLK_BUS_I2C0           50
+#define CLK_BUS_I2C1           51
+#define CLK_BUS_I2C2           52
+#define CLK_BUS_UART0          53
+#define CLK_BUS_UART1          54
+#define CLK_BUS_UART2          55
+#define CLK_BUS_UART3          56
+#define CLK_BUS_UART4          57
+
+#define CLK_NAND               59
+#define CLK_MMC0               60
+#define CLK_MMC0_SAMPLE                61
+#define CLK_MMC0_OUTPUT                62
+#define CLK_MMC1               63
+#define CLK_MMC1_SAMPLE                64
+#define CLK_MMC1_OUTPUT                65
+#define CLK_MMC2               66
+#define CLK_MMC2_SAMPLE                67
+#define CLK_MMC2_OUTPUT                68
+#define CLK_SS                 69
+#define CLK_SPI0               70
+#define CLK_SPI1               71
+#define CLK_I2S0               72
+#define CLK_I2S1               73
+#define CLK_I2S2               74
+#define CLK_TDM                        75
+#define CLK_SPDIF              76
+#define CLK_USB_PHY0           77
+#define CLK_USB_PHY1           78
+#define CLK_USB_HSIC           79
+#define CLK_USB_HSIC_12M       80
+#define CLK_USB_OHCI0          81
+
+#define CLK_DRAM_VE            83
+#define CLK_DRAM_CSI           84
+
+#define CLK_TCON0              85
+#define CLK_TCON1              86
+#define CLK_CSI_MISC           87
+#define CLK_MIPI_CSI           88
+#define CLK_CSI_MCLK           89
+#define CLK_CSI_SCLK           90
+#define CLK_VE                 91
+#define CLK_AVS                        92
+#define CLK_HDMI               93
+#define CLK_HDMI_SLOW          94
+
+#define CLK_MIPI_DSI0          96
+#define CLK_MIPI_DSI1          97
+#define CLK_GPU_CORE           98
+#define CLK_GPU_MEMORY         99
+#define CLK_GPU_HYD            100
+
+#endif /* _DT_BINDINGS_CLOCK_SUN8I_A83T_CCU_H_ */
diff --git a/include/dt-bindings/clock/sun8i-de2.h b/include/dt-bindings/clock/sun8i-de2.h
new file mode 100644 (file)
index 0000000..3bed63b
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.io>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SUN8I_DE2_H_
+#define _DT_BINDINGS_CLOCK_SUN8I_DE2_H_
+
+#define CLK_BUS_MIXER0         0
+#define CLK_BUS_MIXER1         1
+#define CLK_BUS_WB             2
+
+#define CLK_MIXER0             6
+#define CLK_MIXER1             7
+#define CLK_WB                 8
+
+#endif /* _DT_BINDINGS_CLOCK_SUN8I_DE2_H_ */
index 822d523850803a2fc67d952c95a55e36314052db..092c9751a697eaea73e1e44b370dfa2082e974a2 100644 (file)
 #define AUDIO_TDM_WCLK         17
 #define AUDIO_TDM_PCLK         18
 #define AUDIO_TS_PCLK          19
+#define I2S0_WCLK_MUX          20
+#define I2S1_WCLK_MUX          21
+#define I2S2_WCLK_MUX          22
+#define I2S3_WCLK_MUX          23
 
-#define AUDIO_NR_CLKS          20
+#define AUDIO_NR_CLKS          24
 
 #endif
diff --git a/include/dt-bindings/reset/sun8i-a83t-ccu.h b/include/dt-bindings/reset/sun8i-a83t-ccu.h
new file mode 100644 (file)
index 0000000..784f6e1
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017 Chen-Yu Tsai <wens@csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_
+#define _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_
+
+#define RST_USB_PHY0           0
+#define RST_USB_PHY1           1
+#define RST_USB_HSIC           2
+
+#define RST_DRAM               3
+#define RST_MBUS               4
+
+#define RST_BUS_MIPI_DSI       5
+#define RST_BUS_SS             6
+#define RST_BUS_DMA            7
+#define RST_BUS_MMC0           8
+#define RST_BUS_MMC1           9
+#define RST_BUS_MMC2           10
+#define RST_BUS_NAND           11
+#define RST_BUS_DRAM           12
+#define RST_BUS_EMAC           13
+#define RST_BUS_HSTIMER                14
+#define RST_BUS_SPI0           15
+#define RST_BUS_SPI1           16
+#define RST_BUS_OTG            17
+#define RST_BUS_EHCI0          18
+#define RST_BUS_EHCI1          19
+#define RST_BUS_OHCI0          20
+
+#define RST_BUS_VE             21
+#define RST_BUS_TCON0          22
+#define RST_BUS_TCON1          23
+#define RST_BUS_CSI            24
+#define RST_BUS_HDMI0          25
+#define RST_BUS_HDMI1          26
+#define RST_BUS_DE             27
+#define RST_BUS_GPU            28
+#define RST_BUS_MSGBOX         29
+#define RST_BUS_SPINLOCK       30
+
+#define RST_BUS_LVDS           31
+
+#define RST_BUS_SPDIF          32
+#define RST_BUS_I2S0           33
+#define RST_BUS_I2S1           34
+#define RST_BUS_I2S2           35
+#define RST_BUS_TDM            36
+
+#define RST_BUS_I2C0           37
+#define RST_BUS_I2C1           38
+#define RST_BUS_I2C2           39
+#define RST_BUS_UART0          40
+#define RST_BUS_UART1          41
+#define RST_BUS_UART2          42
+#define RST_BUS_UART3          43
+#define RST_BUS_UART4          44
+
+#endif /* _DT_BINDINGS_RESET_SUN8I_A83T_CCU_H_ */
diff --git a/include/dt-bindings/reset/sun8i-de2.h b/include/dt-bindings/reset/sun8i-de2.h
new file mode 100644 (file)
index 0000000..9526017
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.io>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#ifndef _DT_BINDINGS_RESET_SUN8I_DE2_H_
+#define _DT_BINDINGS_RESET_SUN8I_DE2_H_
+
+#define RST_MIXER0     0
+#define RST_MIXER1     1
+#define RST_WB         2
+
+#endif /* _DT_BINDINGS_RESET_SUN8I_DE2_H_ */
index a428aec36aceeb22da48e9d3d755d2423e71969b..c59c62571e4fe6a8c3ec5a9f48759b84c67e6a4a 100644 (file)
@@ -412,9 +412,10 @@ extern const struct clk_ops clk_divider_ro_ops;
 unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
                unsigned int val, const struct clk_div_table *table,
                unsigned long flags);
-long divider_round_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long *prate, const struct clk_div_table *table,
-               u8 width, unsigned long flags);
+long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
+                              unsigned long rate, unsigned long *prate,
+                              const struct clk_div_table *table,
+                              u8 width, unsigned long flags);
 int divider_get_val(unsigned long rate, unsigned long parent_rate,
                const struct clk_div_table *table, u8 width,
                unsigned long flags);
@@ -757,6 +758,15 @@ static inline void __clk_hw_set_clk(struct clk_hw *dst, struct clk_hw *src)
        dst->core = src->core;
 }
 
+static inline long divider_round_rate(struct clk_hw *hw, unsigned long rate,
+                                     unsigned long *prate,
+                                     const struct clk_div_table *table,
+                                     u8 width, unsigned long flags)
+{
+       return divider_round_rate_parent(hw, clk_hw_get_parent(hw),
+                                        rate, prate, table, width, flags);
+}
+
 /*
  * FIXME clock api without lock protection
  */
index 024cd07870d0e240c48f1eeb2793659150a57eef..91bd464f4c9b1c61d9e929f124a980cb1b370856 100644 (file)
@@ -77,6 +77,21 @@ struct clk_notifier_data {
        unsigned long           new_rate;
 };
 
+/**
+ * struct clk_bulk_data - Data used for bulk clk operations.
+ *
+ * @id: clock consumer ID
+ * @clk: struct clk * to store the associated clock
+ *
+ * The CLK APIs provide a series of clk_bulk_() API calls as
+ * a convenience to consumers which require multiple clks.  This
+ * structure is used to manage data for these calls.
+ */
+struct clk_bulk_data {
+       const char              *id;
+       struct clk              *clk;
+};
+
 #ifdef CONFIG_COMMON_CLK
 
 /**
@@ -185,12 +200,20 @@ static inline bool clk_is_match(const struct clk *p, const struct clk *q)
  */
 #ifdef CONFIG_HAVE_CLK_PREPARE
 int clk_prepare(struct clk *clk);
+int __must_check clk_bulk_prepare(int num_clks,
+                                 const struct clk_bulk_data *clks);
 #else
 static inline int clk_prepare(struct clk *clk)
 {
        might_sleep();
        return 0;
 }
+
+static inline int clk_bulk_prepare(int num_clks, struct clk_bulk_data *clks)
+{
+       might_sleep();
+       return 0;
+}
 #endif
 
 /**
@@ -204,11 +227,16 @@ static inline int clk_prepare(struct clk *clk)
  */
 #ifdef CONFIG_HAVE_CLK_PREPARE
 void clk_unprepare(struct clk *clk);
+void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks);
 #else
 static inline void clk_unprepare(struct clk *clk)
 {
        might_sleep();
 }
+static inline void clk_bulk_unprepare(int num_clks, struct clk_bulk_data *clks)
+{
+       might_sleep();
+}
 #endif
 
 #ifdef CONFIG_HAVE_CLK
@@ -229,6 +257,44 @@ static inline void clk_unprepare(struct clk *clk)
  */
 struct clk *clk_get(struct device *dev, const char *id);
 
+/**
+ * clk_bulk_get - lookup and obtain a number of references to clock producer.
+ * @dev: device for clock "consumer"
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table of consumer
+ *
+ * This helper function allows drivers to get several clk consumers in one
+ * operation. If any of the clk cannot be acquired then any clks
+ * that were obtained will be freed before returning to the caller.
+ *
+ * Returns 0 if all clocks specified in clk_bulk_data table are obtained
+ * successfully, or valid IS_ERR() condition containing errno.
+ * The implementation uses @dev and @clk_bulk_data.id to determine the
+ * clock consumer, and thereby the clock producer.
+ * The clock returned is stored in each @clk_bulk_data.clk field.
+ *
+ * Drivers must assume that the clock source is not enabled.
+ *
+ * clk_bulk_get should not be called from within interrupt context.
+ */
+int __must_check clk_bulk_get(struct device *dev, int num_clks,
+                             struct clk_bulk_data *clks);
+
+/**
+ * devm_clk_bulk_get - managed get multiple clk consumers
+ * @dev: device for clock "consumer"
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table of consumer
+ *
+ * Return 0 on success, an errno on failure.
+ *
+ * This helper function allows drivers to get several clk
+ * consumers in one operation with management, the clks will
+ * automatically be freed when the device is unbound.
+ */
+int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
+                                  struct clk_bulk_data *clks);
+
 /**
  * devm_clk_get - lookup and obtain a managed reference to a clock producer.
  * @dev: device for clock "consumer"
@@ -278,6 +344,18 @@ struct clk *devm_get_clk_from_child(struct device *dev,
  */
 int clk_enable(struct clk *clk);
 
+/**
+ * clk_bulk_enable - inform the system when the set of clks should be running.
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table of consumer
+ *
+ * May be called from atomic contexts.
+ *
+ * Returns success (0) or negative errno.
+ */
+int __must_check clk_bulk_enable(int num_clks,
+                                const struct clk_bulk_data *clks);
+
 /**
  * clk_disable - inform the system when the clock source is no longer required.
  * @clk: clock source
@@ -294,6 +372,24 @@ int clk_enable(struct clk *clk);
  */
 void clk_disable(struct clk *clk);
 
+/**
+ * clk_bulk_disable - inform the system when the set of clks is no
+ *                   longer required.
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table of consumer
+ *
+ * Inform the system that a set of clks is no longer required by
+ * a driver and may be shut down.
+ *
+ * May be called from atomic contexts.
+ *
+ * Implementation detail: if the set of clks is shared between
+ * multiple drivers, clk_bulk_enable() calls must be balanced by the
+ * same number of clk_bulk_disable() calls for the clock source to be
+ * disabled.
+ */
+void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks);
+
 /**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *               This is only valid once the clock source has been enabled.
@@ -313,6 +409,19 @@ unsigned long clk_get_rate(struct clk *clk);
  */
 void clk_put(struct clk *clk);
 
+/**
+ * clk_bulk_put        - "free" the clock source
+ * @num_clks: the number of clk_bulk_data
+ * @clks: the clk_bulk_data table of consumer
+ *
+ * Note: drivers must ensure that all clk_bulk_enable calls made on this
+ * clock source are balanced by clk_bulk_disable calls prior to calling
+ * this function.
+ *
+ * clk_bulk_put should not be called from within interrupt context.
+ */
+void clk_bulk_put(int num_clks, struct clk_bulk_data *clks);
+
 /**
  * devm_clk_put        - "free" a managed clock source
  * @dev: device used to acquire the clock
@@ -445,11 +554,23 @@ static inline struct clk *clk_get(struct device *dev, const char *id)
        return NULL;
 }
 
+static inline int clk_bulk_get(struct device *dev, int num_clks,
+                              struct clk_bulk_data *clks)
+{
+       return 0;
+}
+
 static inline struct clk *devm_clk_get(struct device *dev, const char *id)
 {
        return NULL;
 }
 
+static inline int devm_clk_bulk_get(struct device *dev, int num_clks,
+                                   struct clk_bulk_data *clks)
+{
+       return 0;
+}
+
 static inline struct clk *devm_get_clk_from_child(struct device *dev,
                                struct device_node *np, const char *con_id)
 {
@@ -458,6 +579,8 @@ static inline struct clk *devm_get_clk_from_child(struct device *dev,
 
 static inline void clk_put(struct clk *clk) {}
 
+static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {}
+
 static inline void devm_clk_put(struct device *dev, struct clk *clk) {}
 
 static inline int clk_enable(struct clk *clk)
@@ -465,8 +588,17 @@ static inline int clk_enable(struct clk *clk)
        return 0;
 }
 
+static inline int clk_bulk_enable(int num_clks, struct clk_bulk_data *clks)
+{
+       return 0;
+}
+
 static inline void clk_disable(struct clk *clk) {}
 
+
+static inline void clk_bulk_disable(int num_clks,
+                                   struct clk_bulk_data *clks) {}
+
 static inline unsigned long clk_get_rate(struct clk *clk)
 {
        return 0;
@@ -539,6 +671,10 @@ static inline struct clk *of_clk_get_by_name(struct device_node *np,
 {
        return ERR_PTR(-ENOENT);
 }
+static inline struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
+{
+       return ERR_PTR(-ENOENT);
+}
 #endif
 
 #endif
diff --git a/include/linux/platform_data/clk-realview.h b/include/linux/platform_data/clk-realview.h
deleted file mode 100644 (file)
index 2e426a7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-void realview_clk_init(void __iomem *sysbase, bool is_pb1176);