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),