Merge tag 'clk-v4.9-samsung' of git://linuxtv.org/snawrocki/samsung into clk-next
authorStephen Boyd <sboyd@codeaurora.org>
Wed, 14 Sep 2016 18:06:47 +0000 (11:06 -0700)
committerStephen Boyd <sboyd@codeaurora.org>
Wed, 14 Sep 2016 18:06:47 +0000 (11:06 -0700)
Pull samsung clk driver updates from Sylwester Nawrocki:

In addition to a few clean up and code consolidation patches this
includes:
- addition of sound subsystem related clocks for Exynos5410 SoC
  (EPLL, PDMA) and support for "samsung,exynos5410-audss-clock"
  compatible in the clk-exynos-audss driver,
- addition of DRAM controller related clocks for exynos5420,
- MAINTAINERS update adding Chanwoo Choi as the Samsung SoC
  clock drivers co-maintainer.

* tag 'clk-v4.9-samsung' of git://linuxtv.org/snawrocki/samsung:
  clk: samsung: Add support for EPLL on exynos5410
  clk: samsung: clk-exynos-audss: Whitespace and debug trace cleanup
  clk: samsung: clk-exynos-audss: Add exynos5410 compatible
  clk: samsung: clk-exynos-audss: controller variant handling rework
  clk: samsung: Use common registration function for pll2550x
  clk: samsung: exynos5410: Expose the peripheral DMA gate clocks
  clk: samsung: exynos5420: Add clocks for CMU_CDREX domain
  clk: samsung: exynos5410: Use samsung_cmu_register_one() to simplify code
  clk: samsung: exynos5260: Move struct samsung_cmu_info to init section
  MAINTAINERS: Add myself as Samsung SoC clock drivers co-maintainer
  clk: samsung: exynos5410: Add clock IDs for PDMA and EPLL clocks
  clk: samsung: Add clock IDs for the CMU_CDREX (DRAM Express Controller)

136 files changed:
Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/arm-syscon-icst.txt
Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/maxim,max77686.txt
Documentation/devicetree/bindings/clock/maxim,max77802.txt [deleted file]
Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Documentation/devicetree/bindings/clock/qcom,lcc.txt
MAINTAINERS
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/axis/clk-artpec6.c
drivers/clk/bcm/clk-bcm2835.c
drivers/clk/bcm/clk-kona-setup.c
drivers/clk/bcm/clk-kona.c
drivers/clk/bcm/clk-kona.h
drivers/clk/berlin/berlin2-avpll.c
drivers/clk/berlin/berlin2-avpll.h
drivers/clk/berlin/berlin2-div.c
drivers/clk/berlin/berlin2-div.h
drivers/clk/berlin/berlin2-pll.c
drivers/clk/berlin/berlin2-pll.h
drivers/clk/berlin/bg2.c
drivers/clk/berlin/bg2q.c
drivers/clk/clk-asm9260.c
drivers/clk/clk-axi-clkgen.c
drivers/clk/clk-axm5516.c
drivers/clk/clk-cdce706.c
drivers/clk/clk-cdce925.c
drivers/clk/clk-clps711x.c
drivers/clk/clk-cs2000-cp.c
drivers/clk/clk-divider.c
drivers/clk/clk-efm32gg.c
drivers/clk/clk-fixed-factor.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-ls1x.c
drivers/clk/clk-max-gen.c [deleted file]
drivers/clk/clk-max-gen.h [deleted file]
drivers/clk/clk-max77686.c
drivers/clk/clk-max77802.c [deleted file]
drivers/clk/clk-mb86s7x.c
drivers/clk/clk-moxart.c
drivers/clk/clk-nspire.c
drivers/clk/clk-palmas.c
drivers/clk/clk-pwm.c
drivers/clk/clk-qoriq.c
drivers/clk/clk-rk808.c
drivers/clk/clk-scpi.c
drivers/clk/clk-si514.c
drivers/clk/clk-si5351.c
drivers/clk/clk-si570.c
drivers/clk/clk-twl6040.c
drivers/clk/clk-vt8500.c
drivers/clk/clk-wm831x.c
drivers/clk/clk.c
drivers/clk/h8300/clk-div.c
drivers/clk/h8300/clk-h8s2678.c
drivers/clk/imx/clk-imx7d.c
drivers/clk/imx/clk.h
drivers/clk/mediatek/Kconfig [new file with mode: 0644]
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-pll.c
drivers/clk/meson/Makefile
drivers/clk/meson/clkc.h
drivers/clk/meson/gxbb-aoclk.c [new file with mode: 0644]
drivers/clk/meson/gxbb.c
drivers/clk/meson/gxbb.h
drivers/clk/meson/meson8b-clkc.c [deleted file]
drivers/clk/meson/meson8b.c [new file with mode: 0644]
drivers/clk/meson/meson8b.h [new file with mode: 0644]
drivers/clk/microchip/clk-core.c
drivers/clk/microchip/clk-pic32mzda.c
drivers/clk/mvebu/Kconfig
drivers/clk/mvebu/Makefile
drivers/clk/mvebu/armada-37xx-periph.c [new file with mode: 0644]
drivers/clk/mvebu/armada-37xx-tbg.c [new file with mode: 0644]
drivers/clk/mvebu/armada-37xx-xtal.c [new file with mode: 0644]
drivers/clk/mvebu/armada-39x.c
drivers/clk/nxp/clk-lpc18xx-creg.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/clk-regmap.c
drivers/clk/qcom/clk-regmap.h
drivers/clk/qcom/common.c
drivers/clk/qcom/gcc-ipq4019.c
drivers/clk/qcom/gcc-mdm9615.c [new file with mode: 0644]
drivers/clk/qcom/gcc-msm8996.c
drivers/clk/qcom/lcc-mdm9615.c [new file with mode: 0644]
drivers/clk/qcom/mmcc-msm8996.c
drivers/clk/renesas/r8a7795-cpg-mssr.c
drivers/clk/renesas/r8a7796-cpg-mssr.c
drivers/clk/rockchip/Makefile
drivers/clk/rockchip/clk-ddr.c [new file with mode: 0644]
drivers/clk/rockchip/clk-pll.c
drivers/clk/rockchip/clk-rk3399.c
drivers/clk/rockchip/clk-rockchip.c
drivers/clk/rockchip/clk.c
drivers/clk/rockchip/clk.h
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
drivers/clk/sunxi-ng/ccu_common.c
drivers/clk/sunxi-ng/ccu_nk.c
drivers/clk/sunxi/clk-a10-pll2.c
drivers/clk/sunxi/clk-mod0.c
drivers/clk/sunxi/clk-sun8i-apb0.c
drivers/clk/sunxi/clk-sun8i-mbus.c
drivers/clk/tegra/clk-tegra114.c
drivers/clk/versatile/clk-icst.c
include/dt-bindings/clock/gxbb-aoclkc.h [new file with mode: 0644]
include/dt-bindings/clock/gxbb-clkc.h
include/dt-bindings/clock/maxim,max77620.h [new file with mode: 0644]
include/dt-bindings/clock/meson8b-clkc.h
include/dt-bindings/clock/mt2701-clk.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-mdm9615.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-msm8996.h
include/dt-bindings/clock/qcom,lcc-mdm9615.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,mmcc-msm8996.h
include/dt-bindings/clock/rk3399-cru.h
include/dt-bindings/reset/gxbb-aoclkc.h [new file with mode: 0644]
include/dt-bindings/reset/mt2701-resets.h [new file with mode: 0644]
include/dt-bindings/reset/qcom,gcc-mdm9615.h [new file with mode: 0644]
include/linux/clk-provider.h
include/soc/rockchip/rockchip_sip.h [new file with mode: 0644]

index 936166f..cb0054a 100644 (file)
@@ -5,7 +5,8 @@ The Mediatek apmixedsys controller provides the PLLs to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-apmixedsys"
        - "mediatek,mt8135-apmixedsys"
        - "mediatek,mt8173-apmixedsys"
 - #clock-cells: Must be 1
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt
new file mode 100644 (file)
index 0000000..4137196
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek bdpsys controller
+============================
+
+The Mediatek bdpsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt2701-bdpsys", "syscon"
+- #clock-cells: Must be 1
+
+The bdpsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+bdpsys: clock-controller@1c000000 {
+       compatible = "mediatek,mt2701-bdpsys", "syscon";
+       reg = <0 0x1c000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
new file mode 100644 (file)
index 0000000..768f3a5
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek ethsys controller
+============================
+
+The Mediatek ethsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt2701-ethsys", "syscon"
+- #clock-cells: Must be 1
+
+The ethsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+ethsys: clock-controller@1b000000 {
+       compatible = "mediatek,mt2701-ethsys", "syscon";
+       reg = <0 0x1b000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt
new file mode 100644 (file)
index 0000000..beed7b5
--- /dev/null
@@ -0,0 +1,24 @@
+Mediatek hifsys controller
+============================
+
+The Mediatek hifsys controller provides various clocks and reset
+outputs to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt2701-hifsys", "syscon"
+- #clock-cells: Must be 1
+
+The hifsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+hifsys: clock-controller@1a000000 {
+       compatible = "mediatek,mt2701-hifsys", "syscon";
+       reg = <0 0x1a000000 0 0x1000>;
+       #clock-cells = <1>;
+       #reset-cells = <1>;
+};
index b1f2ce1..f6a9166 100644 (file)
@@ -5,7 +5,8 @@ The Mediatek imgsys controller provides various clocks to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-imgsys", "syscon"
        - "mediatek,mt8173-imgsys", "syscon"
 - #clock-cells: Must be 1
 
index aaf8d14..1620ec2 100644 (file)
@@ -6,7 +6,8 @@ outputs to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-infracfg", "syscon"
        - "mediatek,mt8135-infracfg", "syscon"
        - "mediatek,mt8173-infracfg", "syscon"
 - #clock-cells: Must be 1
index 4385946..67dd2e4 100644 (file)
@@ -5,7 +5,8 @@ The Mediatek mmsys controller provides various clocks to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-mmsys", "syscon"
        - "mediatek,mt8173-mmsys", "syscon"
 - #clock-cells: Must be 1
 
index 2f6ff86..e494366 100644 (file)
@@ -6,7 +6,8 @@ outputs to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-pericfg", "syscon"
        - "mediatek,mt8135-pericfg", "syscon"
        - "mediatek,mt8173-pericfg", "syscon"
 - #clock-cells: Must be 1
index f9e9179..9f2fe78 100644 (file)
@@ -5,7 +5,8 @@ The Mediatek topckgen controller provides various clocks to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-topckgen"
        - "mediatek,mt8135-topckgen"
        - "mediatek,mt8173-topckgen"
 - #clock-cells: Must be 1
index 1faacf1..2440f73 100644 (file)
@@ -5,7 +5,8 @@ The Mediatek vdecsys controller provides various clocks to the system.
 
 Required Properties:
 
-- compatible: Should be:
+- compatible: Should be one of:
+       - "mediatek,mt2701-vdecsys", "syscon"
        - "mediatek,mt8173-vdecsys", "syscon"
 - #clock-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
new file mode 100644 (file)
index 0000000..a55d31b
--- /dev/null
@@ -0,0 +1,45 @@
+* Amlogic GXBB AO Clock and Reset Unit
+
+The Amlogic GXBB AO clock controller generates and supplies clock to various
+controllers within the Always-On part of the SoC.
+
+Required Properties:
+
+- compatible: should be "amlogic,gxbb-aoclkc"
+- reg: physical base address of the clock controller and length of memory
+       mapped region.
+
+- #clock-cells: should be 1.
+
+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/gxbb-aoclkc.h header and can be
+used in device tree sources.
+
+- #reset-cells: should be 1.
+
+Each reset is assigned an identifier and client nodes can use this identifier
+to specify the reset which they consume. All available resets are defined as
+preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be
+used in device tree sources.
+
+Example: AO Clock controller node:
+
+       clkc_AO: clock-controller@040 {
+               compatible = "amlogic,gxbb-aoclkc";
+               reg = <0x0 0x040 0x0 0x4>;
+               #clock-cells = <1>;
+               #reset-cells = <1>;
+       };
+
+Example: UART controller node that consumes the clock and reset generated
+  by the clock controller:
+
+       uart_AO: serial@4c0 {
+               compatible = "amlogic,meson-uart";
+               reg = <0x4c0 0x14>;
+               interrupts = <0 90 1>;
+               clocks = <&clkc_AO CLKID_AO_UART1>;
+               resets = <&clkc_AO RESET_AO_UART1>;
+               status = "disabled";
+       };
index 8b7177c..2746811 100644 (file)
@@ -5,20 +5,50 @@ Technology (IDT). ARM integrated these oscillators deeply into their
 reference designs by adding special control registers that manage such
 oscillators to their system controllers.
 
-The ARM system controller contains logic to serialize and initialize
+The various ARM system controllers contain logic to serialize and initialize
 an ICST clock request after a write to the 32 bit register at an offset
 into the system controller. Furthermore, to even be able to alter one of
 these frequencies, the system controller must first be unlocked by
 writing a special token to another offset in the system controller.
 
+Some ARM hardware contain special versions of the serial interface that only
+connects the low 8 bits of the VDW (missing one bit), hardwires RDW to
+different values and sometimes also hardwire the output divider. They
+therefore have special compatible strings as per this table (the OD value is
+the value on the pins, not the resulting output divider):
+
+Hardware variant:        RDW     OD          VDW
+
+Integrator/AP            22      1           Bit 8 0, rest variable
+integratorap-cm
+
+Integrator/AP            46      3           Bit 8 0, rest variable
+integratorap-sys
+
+Integrator/AP            22 or   1           17 or (33 or 25 MHz)
+integratorap-pci         14      1           14
+
+Integrator/CP            22      variable    Bit 8 0, rest variable
+integratorcp-cm-core
+
+Integrator/CP            22      variable    Bit 8 0, rest variable
+integratorcp-cm-mem
+
 The ICST oscillator must be provided inside a system controller node.
 
 Required properties:
+- compatible: must be one of
+  "arm,syscon-icst525"
+  "arm,syscon-icst307"
+  "arm,syscon-icst525-integratorap-cm"
+  "arm,syscon-icst525-integratorap-sys"
+  "arm,syscon-icst525-integratorap-pci"
+  "arm,syscon-icst525-integratorcp-cm-core"
+  "arm,syscon-icst525-integratorcp-cm-mem"
 - lock-offset: the offset address into the system controller where the
   unlocking register is located
 - vco-offset: the offset address into the system controller where the
   ICST control register is located (even 32 bit address)
-- compatible: must be one of "arm,syscon-icst525" or "arm,syscon-icst307"
 - #clock-cells: must be <0>
 - clocks: parent clock, since the ICST needs a parent clock to derive its
   frequency from, this attribute is compulsory.
diff --git a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt
new file mode 100644 (file)
index 0000000..1e3370b
--- /dev/null
@@ -0,0 +1,70 @@
+* Peripheral Clock bindings for Marvell Armada 37xx SoCs
+
+Marvell Armada 37xx SoCs provide peripheral clocks which are
+used as clock source for the peripheral of the SoC.
+
+There are two different blocks associated to north bridge and south
+bridge.
+
+The peripheral clock consumer should specify the desired clock by
+having the clock ID in its "clocks" phandle cell.
+
+The following is a list of provided IDs for Armada 370 North bridge clocks:
+ID     Clock name      Description
+-----------------------------------
+0      mmc             MMC controller
+1      sata_host       Sata Host
+2      sec_at          Security AT
+3      sac_dap         Security DAP
+4      tsecm           Security Engine
+5      setm_tmx        Serial Embedded Trace Module
+6      avs             Adaptive Voltage Scaling
+7      sqf             SPI
+8      pwm             PWM
+9      i2c_2           I2C 2
+10     i2c_1           I2C 1
+11     ddr_phy         DDR PHY
+12     ddr_fclk        DDR F clock
+13     trace           Trace
+14     counter         Counter
+15     eip97           EIP 97
+16     cpu             CPU
+
+The following is a list of provided IDs for Armada 370 South bridge clocks:
+ID     Clock name      Description
+-----------------------------------
+0      gbe-50          50 MHz parent clock for Gigabit Ethernet
+1      gbe-core        parent clock for Gigabit Ethernet core
+2      gbe-125         125 MHz parent clock for Gigabit Ethernet
+3      gbe1-50         50 MHz clock for Gigabit Ethernet port 1
+4      gbe0-50         50 MHz clock for Gigabit Ethernet port 0
+5      gbe1-125        125 MHz clock for Gigabit Ethernet port 1
+6      gbe0-125        125 MHz clock for Gigabit Ethernet port 0
+7      gbe1-core       Gigabit Ethernet core port 1
+8      gbe0-core       Gigabit Ethernet core port 0
+9      gbe-bm          Gigabit Ethernet Buffer Manager
+10     sdio            SDIO
+11     usb32-sub2-sys  USB 2 clock
+12     usb32-ss-sys    USB 3 clock
+
+Required properties:
+
+- compatible : shall be "marvell,armada-3700-periph-clock-nb" for the
+  north bridge block, or
+  "marvell,armada-3700-periph-clock-sb" for the south bridge block
+- reg : must be the register address of North/South Bridge Clock register
+- #clock-cells : from common clock binding; shall be set to 1
+
+- clocks : list of the parent clock phandle in the following order:
+  TBG-A P, TBG-B P, TBG-A S, TBG-B S and finally the xtal clock.
+
+
+Example:
+
+nb_perih_clk: nb-periph-clk@13000{
+       compatible = "marvell,armada-3700-periph-clock-nb";
+       reg = <0x13000 0x1000>;
+       clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>,
+       <&tbg 3>, <&xtalclk>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt
new file mode 100644 (file)
index 0000000..0ba1d83
--- /dev/null
@@ -0,0 +1,27 @@
+* Time Base Generator Clock bindings for Marvell Armada 37xx SoCs
+
+Marvell Armada 37xx SoCs provde Time Base Generator clocks which are
+used as parent clocks for the peripheral clocks.
+
+The TBG clock consumer should specify the desired clock by having the
+clock ID in its "clocks" phandle cell.
+
+The following is a list of provided IDs and clock names on Armada 3700:
+ 0 = TBG A P
+ 1 = TBG B P
+ 2 = TBG A S
+ 3 = TBG B S
+
+Required properties:
+- compatible : shall be "marvell,armada-3700-tbg-clock"
+- reg : must be the register address of North Bridge PLL register
+- #clock-cells : from common clock binding; shall be set to 1
+
+Example:
+
+tbg: tbg@13200 {
+       compatible = "marvell,armada-3700-tbg-clock";
+       reg = <0x13200 0x1000>;
+       clocks = <&xtalclk>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt
new file mode 100644 (file)
index 0000000..a88f1f0
--- /dev/null
@@ -0,0 +1,28 @@
+* Xtal Clock bindings for Marvell Armada 37xx SoCs
+
+Marvell Armada 37xx SoCs allow to determine the xtal clock frequencies by
+reading the gpio latch register.
+
+This node must be a subnode of the node exposing the register address
+of the GPIO block where the gpio latch is located.
+
+Required properties:
+- compatible : shall be one of the following:
+       "marvell,armada-3700-xtal-clock"
+- #clock-cells : from common clock binding; shall be set to 0
+
+Optional properties:
+- clock-output-names : from common clock binding; allows overwrite default clock
+       output names ("xtal")
+
+Example:
+gpio1: gpio@13800 {
+       compatible = "marvell,armada-3700-gpio", "syscon", "simple-mfd";
+       reg = <0x13800 0x1000>;
+
+       xtalclk: xtal-clk {
+               compatible = "marvell,armada-3700-xtal-clock";
+               clock-output-names = "xtal";
+               #clock-cells = <0>;
+       };
+};
index 9c40739..8398a3a 100644 (file)
@@ -1,10 +1,24 @@
-Binding for Maxim MAX77686 32k clock generator block
+Binding for Maxim MAX77686/MAX77802/MAX77620 32k clock generator block
 
-This is a part of device tree bindings of MAX77686 multi-function device.
-More information can be found in bindings/mfd/max77686.txt file.
+This is a part of device tree bindings of MAX77686/MAX77802/MAX77620
+multi-function device. More information can be found in MFD DT binding
+doc as follows:
+       bindings/mfd/max77686.txt for MAX77686 and
+       bindings/mfd/max77802.txt for MAX77802 and
+       bindings/mfd/max77620.txt for MAX77620.
 
 The MAX77686 contains three 32.768khz clock outputs that can be controlled
-(gated/ungated) over I2C.
+(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
+dt-bindings/clock/maxim,max77686.h.
+
+
+The MAX77802 contains two 32.768khz clock outputs that can be controlled
+(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
+dt-bindings/clock/maxim,max77802.h.
+
+The MAX77686 contains one 32.768khz clock outputs that can be controlled
+(gated/ungated) over I2C. Clocks are defined as preprocessor macros in
+dt-bindings/clock/maxim,max77620.h.
 
 Following properties should be presend in main device node of the MFD chip.
 
@@ -17,30 +31,84 @@ Optional properties:
 
 Each clock is assigned an identifier and client nodes can use this identifier
 to specify the clock which they consume. Following indices are allowed:
-    - 0: 32khz_ap clock,
-    - 1: 32khz_cp clock,
-    - 2: 32khz_pmic clock.
+    - 0: 32khz_ap clock (max77686, max77802), 32khz_out0 (max77620)
+    - 1: 32khz_cp clock (max77686, max77802),
+    - 2: 32khz_pmic clock (max77686).
+
+Clocks are defined as preprocessor macros in above dt-binding header for
+respective chips.
+
+Example:
+
+1. With MAX77686:
+
+#include <dt-bindings/clock/maxim,max77686.h>
+/* ... */
+
+       Node of the MFD chip
+               max77686: max77686@09 {
+                       compatible = "maxim,max77686";
+                       interrupt-parent = <&wakeup_eint>;
+                       interrupts = <26 0>;
+                       reg = <0x09>;
+                       #clock-cells = <1>;
+
+                       /* ... */
+               };
+
+       Clock consumer node
+
+               foo@0 {
+                       compatible = "bar,foo";
+                       /* ... */
+                       clock-names = "my-clock";
+                       clocks = <&max77686 MAX77686_CLK_PMIC>;
+               };
+
+2. With MAX77802:
+
+#include <dt-bindings/clock/maxim,max77802.h>
+/* ... */
+
+       Node of the MFD chip
+               max77802: max77802@09 {
+                       compatible = "maxim,max77802";
+                       interrupt-parent = <&wakeup_eint>;
+                       interrupts = <26 0>;
+                       reg = <0x09>;
+                       #clock-cells = <1>;
+
+                       /* ... */
+               };
+
+       Clock consumer node
+
+               foo@0 {
+                       compatible = "bar,foo";
+                       /* ... */
+                       clock-names = "my-clock";
+                       clocks = <&max77802 MAX77802_CLK_32K_AP>;
+               };
 
-Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77686.h
-header and can be used in device tree sources.
 
-Example: Node of the MFD chip
+3. With MAX77620:
 
-       max77686: max77686@09 {
-               compatible = "maxim,max77686";
-               interrupt-parent = <&wakeup_eint>;
-               interrupts = <26 0>;
-               reg = <0x09>;
-               #clock-cells = <1>;
+#include <dt-bindings/clock/maxim,max77620.h>
+/* ... */
 
-               /* ... */
-       };
+       Node of the MFD chip
+               max77620: max77620@3c {
+                       compatible = "maxim,max77620";
+                       reg = <0x3c>;
+                       #clock-cells = <1>;
+                       /* ... */
+               };
 
-Example: Clock consumer node
+       Clock consumer node
 
-       foo@0 {
-               compatible = "bar,foo";
-               /* ... */
-               clock-names = "my-clock";
-               clocks = <&max77686 MAX77686_CLK_PMIC>;
-       };
+               foo@0 {
+                       compatible = "bar,foo";
+                       /* ... */
+                       clock-names = "my-clock";
+                       clocks = <&max77620 MAX77620_CLK_32K_OUT0>;
+               };
diff --git a/Documentation/devicetree/bindings/clock/maxim,max77802.txt b/Documentation/devicetree/bindings/clock/maxim,max77802.txt
deleted file mode 100644 (file)
index c6dc783..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-Binding for Maxim MAX77802 32k clock generator block
-
-This is a part of device tree bindings of MAX77802 multi-function device.
-More information can be found in bindings/mfd/max77802.txt file.
-
-The MAX77802 contains two 32.768khz clock outputs that can be controlled
-(gated/ungated) over I2C.
-
-Following properties should be present in main device node of the MFD chip.
-
-Required properties:
-- #clock-cells: From common clock binding; shall be set to 1.
-
-Optional properties:
-- clock-output-names: From common clock binding.
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume. Following indices are allowed:
-     - 0: 32khz_ap clock,
-     - 1: 32khz_cp clock.
-
-Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77802.h
-header and can be used in device tree sources.
-
-Example: Node of the MFD chip
-
-       max77802: max77802@09 {
-               compatible = "maxim,max77802";
-               interrupt-parent = <&wakeup_eint>;
-               interrupts = <26 0>;
-               reg = <0x09>;
-               #clock-cells = <1>;
-
-               /* ... */
-       };
-
-Example: Clock consumer node
-
-       foo@0 {
-               compatible = "bar,foo";
-               /* ... */
-               clock-names = "my-clock";
-               clocks = <&max77802 MAX77802_CLK_32K_AP>;
-       };
index 660e649..cb8542d 100644 (file)
@@ -86,6 +86,8 @@ ID    Clock           Peripheral
 7      pex3            PCIe 3
 8      pex0            PCIe 0
 9      usb3h0          USB3 Host 0
+10     usb3h1          USB3 Host 1
+15     sata0           SATA 0
 17     sdio            SDIO
 22     xor0            XOR 0
 28     xor1            XOR 1
index 9a60fde..869a2f0 100644 (file)
@@ -15,6 +15,7 @@ Required properties :
                        "qcom,gcc-msm8974pro"
                        "qcom,gcc-msm8974pro-ac"
                        "qcom,gcc-msm8996"
+                       "qcom,gcc-mdm9615"
 
 - reg : shall contain base register location and length
 - #clock-cells : shall contain 1
index dd755be..a3c78aa 100644 (file)
@@ -7,6 +7,7 @@ Required properties :
                        "qcom,lcc-msm8960"
                        "qcom,lcc-apq8064"
                        "qcom,lcc-ipq8064"
+                       "qcom,lcc-mdm9615"
 
 - reg : shall contain base register location and length
 - #clock-cells : shall contain 1
index 442d6f5..d695e65 100644 (file)
@@ -3150,6 +3150,7 @@ COMMON CLK FRAMEWORK
 M:     Michael Turquette <mturquette@baylibre.com>
 M:     Stephen Boyd <sboyd@codeaurora.org>
 L:     linux-clk@vger.kernel.org
+Q:     http://patchwork.kernel.org/project/linux-clk/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
 S:     Maintained
 F:     Documentation/devicetree/bindings/clock/
@@ -9891,6 +9892,12 @@ F:       drivers/rpmsg/
 F:     Documentation/rpmsg.txt
 F:     include/linux/rpmsg.h
 
+RENESAS CLOCK DRIVERS
+M:     Geert Uytterhoeven <geert+renesas@glider.be>
+L:     linux-renesas-soc@vger.kernel.org
+S:     Supported
+F:     drivers/clk/renesas/
+
 RENESAS ETHERNET DRIVERS
 R:     Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
 L:     netdev@vger.kernel.org
index e2d9bd7..bf7d540 100644 (file)
@@ -31,22 +31,12 @@ config COMMON_CLK_WM831X
 
 source "drivers/clk/versatile/Kconfig"
 
-config COMMON_CLK_MAX_GEN
-        bool
-
 config COMMON_CLK_MAX77686
-       tristate "Clock driver for Maxim 77686 MFD"
-       depends on MFD_MAX77686
-       select COMMON_CLK_MAX_GEN
-       ---help---
-         This driver supports Maxim 77686 crystal oscillator clock. 
-
-config COMMON_CLK_MAX77802
-       tristate "Clock driver for Maxim 77802 PMIC"
-       depends on MFD_MAX77686
-       select COMMON_CLK_MAX_GEN
+       tristate "Clock driver for Maxim 77620/77686/77802 MFD"
+       depends on MFD_MAX77686 || MFD_MAX77620
        ---help---
-         This driver supports Maxim 77802 crystal oscillator clock.
+         This driver supports Maxim 77620/77686/77802 crystal oscillator
+         clock.
 
 config COMMON_CLK_RK808
        tristate "Clock driver for RK808/RK818"
@@ -210,6 +200,7 @@ config COMMON_CLK_OXNAS
 
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
+source "drivers/clk/mediatek/Kconfig"
 source "drivers/clk/meson/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
index 3b6f9cf..e775a83 100644 (file)
@@ -27,9 +27,7 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP)    += clk-cs2000-cp.o
 obj-$(CONFIG_ARCH_EFM32)               += clk-efm32gg.o
 obj-$(CONFIG_ARCH_HIGHBANK)            += clk-highbank.o
 obj-$(CONFIG_MACH_LOONGSON32)          += clk-ls1x.o
-obj-$(CONFIG_COMMON_CLK_MAX_GEN)       += clk-max-gen.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)      += clk-max77686.o
-obj-$(CONFIG_COMMON_CLK_MAX77802)      += clk-max77802.o
 obj-$(CONFIG_ARCH_MB86S7X)             += clk-mb86s7x.o
 obj-$(CONFIG_ARCH_MOXART)              += clk-moxart.o
 obj-$(CONFIG_ARCH_NOMADIK)             += clk-nomadik.o
index ffc988b..da1a073 100644 (file)
@@ -113,8 +113,8 @@ static void of_artpec6_clkctrl_setup(struct device_node *np)
        of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data);
 }
 
-CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl",
-              of_artpec6_clkctrl_setup);
+CLK_OF_DECLARE_DRIVER(artpec6_clkctrl, "axis,artpec6-clkctrl",
+                     of_artpec6_clkctrl_setup);
 
 static int artpec6_clkctrl_probe(struct platform_device *pdev)
 {
index 7a79708..e8a9646 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/clk.h>
 #include <linux/clk/bcm2835.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
@@ -443,6 +444,8 @@ struct bcm2835_clock_data {
        /* Number of fractional bits in the divider */
        u32 frac_bits;
 
+       u32 flags;
+
        bool is_vpu_clock;
        bool is_mash_clock;
 };
@@ -1006,16 +1009,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
        return 0;
 }
 
+static bool
+bcm2835_clk_is_pllc(struct clk_hw *hw)
+{
+       if (!hw)
+               return false;
+
+       return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
+}
+
 static int bcm2835_clock_determine_rate(struct clk_hw *hw,
                                        struct clk_rate_request *req)
 {
        struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
        struct clk_hw *parent, *best_parent = NULL;
+       bool current_parent_is_pllc;
        unsigned long rate, best_rate = 0;
        unsigned long prate, best_prate = 0;
        size_t i;
        u32 div;
 
+       current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
+
        /*
         * Select parent clock that results in the closest but lower rate
         */
@@ -1023,6 +1038,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
                parent = clk_hw_get_parent_by_index(hw, i);
                if (!parent)
                        continue;
+
+               /*
+                * Don't choose a PLLC-derived clock as our parent
+                * unless it had been manually set that way.  PLLC's
+                * frequency gets adjusted by the firmware due to
+                * over-temp or under-voltage conditions, without
+                * prior notification to our clock consumer.
+                */
+               if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
+                       continue;
+
                prate = clk_hw_get_rate(parent);
                div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
                rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
@@ -1230,13 +1256,19 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman,
        init.parent_names = parents;
        init.num_parents = data->num_mux_parents;
        init.name = data->name;
-       init.flags = CLK_IGNORE_UNUSED;
+       init.flags = data->flags | CLK_IGNORE_UNUSED;
 
        if (data->is_vpu_clock) {
                init.ops = &bcm2835_vpu_clock_clk_ops;
        } else {
                init.ops = &bcm2835_clock_clk_ops;
                init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+               /* If the clock wasn't actually enabled at boot, it's not
+                * critical.
+                */
+               if (!(cprman_read(cprman, data->ctl_reg) & CM_ENABLE))
+                       init.flags &= ~CLK_IS_CRITICAL;
        }
 
        clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL);
@@ -1649,6 +1681,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
                .div_reg = CM_VPUDIV,
                .int_bits = 12,
                .frac_bits = 8,
+               .flags = CLK_IS_CRITICAL,
                .is_vpu_clock = true),
 
        /* clocks with per parent mux */
@@ -1705,13 +1738,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
                .div_reg = CM_GP1DIV,
                .int_bits = 12,
                .frac_bits = 12,
+               .flags = CLK_IS_CRITICAL,
                .is_mash_clock = true),
        [BCM2835_CLOCK_GP2]     = REGISTER_PER_CLK(
                .name = "gp2",
                .ctl_reg = CM_GP2CTL,
                .div_reg = CM_GP2DIV,
                .int_bits = 12,
-               .frac_bits = 12),
+               .frac_bits = 12,
+               .flags = CLK_IS_CRITICAL),
 
        /* HDMI state machine */
        [BCM2835_CLOCK_HSM]     = REGISTER_PER_CLK(
@@ -1790,6 +1825,25 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
                .ctl_reg = CM_PERIICTL),
 };
 
+/*
+ * Permanently take a reference on the parent of the SDRAM clock.
+ *
+ * While the SDRAM is being driven by its dedicated PLL most of the
+ * time, there is a little loop running in the firmware that
+ * periodically switches the SDRAM to using our CM clock to do PVT
+ * recalibration, with the assumption that the previously configured
+ * SDRAM parent is still enabled and running.
+ */
+static int bcm2835_mark_sdc_parent_critical(struct clk *sdc)
+{
+       struct clk *parent = clk_get_parent(sdc);
+
+       if (IS_ERR(parent))
+               return PTR_ERR(parent);
+
+       return clk_prepare_enable(parent);
+}
+
 static int bcm2835_clk_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -1799,6 +1853,7 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
        const struct bcm2835_clk_desc *desc;
        const size_t asize = ARRAY_SIZE(clk_desc_array);
        size_t i;
+       int ret;
 
        cprman = devm_kzalloc(dev,
                              sizeof(*cprman) + asize * sizeof(*clks),
@@ -1829,6 +1884,10 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
                        clks[i] = desc->clk_register(cprman, desc->data);
        }
 
+       ret = bcm2835_mark_sdc_parent_critical(clks[BCM2835_CLOCK_SDRAM]);
+       if (ret)
+               return ret;
+
        return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
                                   &cprman->onecell);
 }
index 526b0b0..f2359b3 100644 (file)
@@ -696,77 +696,69 @@ static void bcm_clk_teardown(struct kona_clk *bcm_clk)
        bcm_clk->type = bcm_clk_none;
 }
 
-static void kona_clk_teardown(struct clk *clk)
+static void kona_clk_teardown(struct clk_hw *hw)
 {
-       struct clk_hw *hw;
        struct kona_clk *bcm_clk;
 
-       if (!clk)
+       if (!hw)
                return;
 
-       hw = __clk_get_hw(clk);
-       if (!hw) {
-               pr_err("%s: clk %p has null hw pointer\n", __func__, clk);
-               return;
-       }
-       clk_unregister(clk);
+       clk_hw_unregister(hw);
 
        bcm_clk = to_kona_clk(hw);
        bcm_clk_teardown(bcm_clk);
 }
 
-struct clk *kona_clk_setup(struct kona_clk *bcm_clk)
+static int kona_clk_setup(struct kona_clk *bcm_clk)
 {
+       int ret;
        struct clk_init_data *init_data = &bcm_clk->init_data;
-       struct clk *clk = NULL;
 
        switch (bcm_clk->type) {
        case bcm_clk_peri:
-               if (peri_clk_setup(bcm_clk->u.data, init_data))
-                       return NULL;
+               ret = peri_clk_setup(bcm_clk->u.data, init_data);
+               if (ret)
+                       return ret;
                break;
        default:
                pr_err("%s: clock type %d invalid for %s\n", __func__,
                        (int)bcm_clk->type, init_data->name);
-               return NULL;
+               return -EINVAL;
        }
 
        /* Make sure everything makes sense before we set it up */
        if (!kona_clk_valid(bcm_clk)) {
                pr_err("%s: clock data invalid for %s\n", __func__,
                        init_data->name);
+               ret = -EINVAL;
                goto out_teardown;
        }
 
        bcm_clk->hw.init = init_data;
-       clk = clk_register(NULL, &bcm_clk->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: error registering clock %s (%ld)\n", __func__,
-                       init_data->name, PTR_ERR(clk));
+       ret = clk_hw_register(NULL, &bcm_clk->hw);
+       if (ret) {
+               pr_err("%s: error registering clock %s (%d)\n", __func__,
+                       init_data->name, ret);
                goto out_teardown;
        }
-       BUG_ON(!clk);
 
-       return clk;
+       return 0;
 out_teardown:
        bcm_clk_teardown(bcm_clk);
 
-       return NULL;
+       return ret;
 }
 
 static void ccu_clks_teardown(struct ccu_data *ccu)
 {
        u32 i;
 
-       for (i = 0; i < ccu->clk_data.clk_num; i++)
-               kona_clk_teardown(ccu->clk_data.clks[i]);
-       kfree(ccu->clk_data.clks);
+       for (i = 0; i < ccu->clk_num; i++)
+               kona_clk_teardown(&ccu->kona_clks[i].hw);
 }
 
 static void kona_ccu_teardown(struct ccu_data *ccu)
 {
-       kfree(ccu->clk_data.clks);
-       ccu->clk_data.clks = NULL;
        if (!ccu->base)
                return;
 
@@ -793,6 +785,20 @@ static bool ccu_data_valid(struct ccu_data *ccu)
        return true;
 }
 
+static struct clk_hw *
+of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct ccu_data *ccu = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= ccu->clk_num) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return &ccu->kona_clks[idx].hw;
+}
+
 /*
  * Set up a CCU.  Call the provided ccu_clks_setup callback to
  * initialize the array of clocks provided by the CCU.
@@ -805,18 +811,6 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
        unsigned int i;
        int ret;
 
-       if (ccu->clk_data.clk_num) {
-               size_t size;
-
-               size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks);
-               ccu->clk_data.clks = kzalloc(size, GFP_KERNEL);
-               if (!ccu->clk_data.clks) {
-                       pr_err("%s: unable to allocate %u clocks for %s\n",
-                               __func__, ccu->clk_data.clk_num, node->name);
-                       return;
-               }
-       }
-
        ret = of_address_to_resource(node, 0, &res);
        if (ret) {
                pr_err("%s: no valid CCU registers found for %s\n", __func__,
@@ -851,13 +845,13 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu,
         * the clock framework clock array (in ccu->data).  Then
         * register as a provider for these clocks.
         */
-       for (i = 0; i < ccu->clk_data.clk_num; i++) {
+       for (i = 0; i < ccu->clk_num; i++) {
                if (!ccu->kona_clks[i].ccu)
                        continue;
-               ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]);
+               kona_clk_setup(&ccu->kona_clks[i]);
        }
 
-       ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data);
+       ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu);
        if (ret) {
                pr_err("%s: error adding ccu %s as provider (%d)\n", __func__,
                                node->name, ret);
index 3a15347..eee64b9 100644 (file)
@@ -1256,19 +1256,18 @@ bool __init kona_ccu_init(struct ccu_data *ccu)
 {
        unsigned long flags;
        unsigned int which;
-       struct clk **clks = ccu->clk_data.clks;
        struct kona_clk *kona_clks = ccu->kona_clks;
        bool success = true;
 
        flags = ccu_lock(ccu);
        __ccu_write_enable(ccu);
 
-       for (which = 0; which < ccu->clk_data.clk_num; which++) {
-               struct kona_clk *bcm_clk;
+       for (which = 0; which < ccu->clk_num; which++) {
+               struct kona_clk *bcm_clk = &kona_clks[which];
 
-               if (!clks[which])
+               if (!bcm_clk->ccu)
                        continue;
-               bcm_clk = &kona_clks[which];
+
                success &= __kona_clk_init(bcm_clk);
        }
 
index 906576e..f4b39bb 100644 (file)
@@ -481,7 +481,7 @@ struct ccu_data {
        bool write_enabled;     /* write access is currently enabled */
        struct ccu_policy policy;
        struct device_node *node;
-       struct clk_onecell_data clk_data;
+       size_t clk_num;
        const char *name;
        u32 range;              /* byte range of address space */
        struct kona_clk kona_clks[];    /* must be last */
@@ -491,9 +491,7 @@ struct ccu_data {
 #define KONA_CCU_COMMON(_prefix, _name, _ccuname)                          \
        .name           = #_name "_ccu",                                    \
        .lock           = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock),    \
-       .clk_data       = {                                                 \
-               .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT,    \
-       }
+       .clk_num        = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT
 
 /* Exported globals */
 
@@ -505,7 +503,6 @@ extern u64 scaled_div_max(struct bcm_clk_div *div);
 extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
                                u32 billionths);
 
-extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk);
 extern void __init kona_dt_ccu_setup(struct ccu_data *ccu,
                                struct device_node *node);
 extern bool __init kona_ccu_init(struct ccu_data *ccu);
index fd0f26c..cfcae46 100644 (file)
@@ -188,7 +188,7 @@ static const struct clk_ops berlin2_avpll_vco_ops = {
        .recalc_rate    = berlin2_avpll_vco_recalc_rate,
 };
 
-struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
+int __init berlin2_avpll_vco_register(void __iomem *base,
                               const char *name, const char *parent_name,
                               u8 vco_flags, unsigned long flags)
 {
@@ -197,7 +197,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
 
        vco = kzalloc(sizeof(*vco), GFP_KERNEL);
        if (!vco)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        vco->base = base;
        vco->flags = vco_flags;
@@ -208,7 +208,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base,
        init.num_parents = 1;
        init.flags = flags;
 
-       return clk_register(NULL, &vco->hw);
+       return clk_hw_register(NULL, &vco->hw);
 }
 
 struct berlin2_avpll_channel {
@@ -364,7 +364,7 @@ static const struct clk_ops berlin2_avpll_channel_ops = {
  */
 static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 };
 
-struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
+int __init berlin2_avpll_channel_register(void __iomem *base,
                           const char *name, u8 index, const char *parent_name,
                           u8 ch_flags, unsigned long flags)
 {
@@ -373,7 +373,7 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
 
        ch = kzalloc(sizeof(*ch), GFP_KERNEL);
        if (!ch)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        ch->base = base;
        if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK)
@@ -389,5 +389,5 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base,
        init.num_parents = 1;
        init.flags = flags;
 
-       return clk_register(NULL, &ch->hw);
+       return clk_hw_register(NULL, &ch->hw);
 }
index a37f506..17e3111 100644 (file)
 #ifndef __BERLIN2_AVPLL_H
 #define __BERLIN2_AVPLL_H
 
-struct clk;
-
 #define BERLIN2_AVPLL_BIT_QUIRK                BIT(0)
 #define BERLIN2_AVPLL_SCRAMBLE_QUIRK   BIT(1)
 
-struct clk * __init
-berlin2_avpll_vco_register(void __iomem *base, const char *name,
+int berlin2_avpll_vco_register(void __iomem *base, const char *name,
           const char *parent_name, u8 vco_flags, unsigned long flags);
 
-struct clk * __init
-berlin2_avpll_channel_register(void __iomem *base, const char *name,
+int berlin2_avpll_channel_register(void __iomem *base, const char *name,
                       u8 index, const char *parent_name, u8 ch_flags,
                       unsigned long flags);
 
index 81ff97f..41ab2d3 100644 (file)
@@ -234,7 +234,7 @@ static const struct clk_ops berlin2_div_mux_ops = {
        .get_parent     = berlin2_div_get_parent,
 };
 
-struct clk * __init
+struct clk_hw * __init
 berlin2_div_register(const struct berlin2_div_map *map,
                     void __iomem *base, const char *name, u8 div_flags,
                     const char **parent_names, int num_parents,
@@ -259,7 +259,7 @@ berlin2_div_register(const struct berlin2_div_map *map,
        if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0)
                mux_ops = NULL;
 
-       return clk_register_composite(NULL, name, parent_names, num_parents,
+       return clk_hw_register_composite(NULL, name, parent_names, num_parents,
                                      &div->hw, mux_ops, &div->hw, rate_ops,
                                      &div->hw, gate_ops, flags);
 }
index 15e3384..e835ddf 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef __BERLIN2_DIV_H
 #define __BERLIN2_DIV_H
 
-struct clk;
+struct clk_hw;
 
 #define BERLIN2_DIV_HAS_GATE           BIT(0)
 #define BERLIN2_DIV_HAS_MUX            BIT(1)
@@ -80,7 +80,7 @@ struct berlin2_div_data {
        u8 div_flags;
 };
 
-struct clk * __init
+struct clk_hw *
 berlin2_div_register(const struct berlin2_div_map *map,
             void __iomem *base,  const char *name, u8 div_flags,
             const char **parent_names, int num_parents,
index 1c2294d..4ffbe80 100644 (file)
@@ -84,7 +84,7 @@ static const struct clk_ops berlin2_pll_ops = {
        .recalc_rate    = berlin2_pll_recalc_rate,
 };
 
-struct clk * __init
+int __init
 berlin2_pll_register(const struct berlin2_pll_map *map,
                     void __iomem *base, const char *name,
                     const char *parent_name, unsigned long flags)
@@ -94,7 +94,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
        if (!pll)
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
 
        /* copy pll_map to allow __initconst */
        memcpy(&pll->map, map, sizeof(*map));
@@ -106,5 +106,5 @@ berlin2_pll_register(const struct berlin2_pll_map *map,
        init.num_parents = 1;
        init.flags = flags;
 
-       return clk_register(NULL, &pll->hw);
+       return clk_hw_register(NULL, &pll->hw);
 }
index 8831ce2..583e024 100644 (file)
@@ -19,8 +19,6 @@
 #ifndef __BERLIN2_PLL_H
 #define __BERLIN2_PLL_H
 
-struct clk;
-
 struct berlin2_pll_map {
        const u8 vcodiv[16];
        u8 mult;
@@ -29,9 +27,8 @@ struct berlin2_pll_map {
        u8 divsel_shift;
 };
 
-struct clk * __init
-berlin2_pll_register(const struct berlin2_pll_map *map,
-                    void __iomem *base, const char *name,
-                    const char *parent_name, unsigned long flags);
+int berlin2_pll_register(const struct berlin2_pll_map *map,
+                        void __iomem *base, const char *name,
+                        const char *parent_name, unsigned long flags);
 
 #endif /* __BERLIN2_PLL_H */
index 23e0e3b..edf3b96 100644 (file)
@@ -92,8 +92,7 @@
  */
 
 #define        MAX_CLKS 41
-static struct clk *clks[MAX_CLKS];
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_data;
 static DEFINE_SPINLOCK(lock);
 static void __iomem *gbase;
 
@@ -505,8 +504,17 @@ static void __init berlin2_clock_setup(struct device_node *np)
        struct device_node *parent_np = of_get_parent(np);
        const char *parent_names[9];
        struct clk *clk;
+       struct clk_hw *hw;
+       struct clk_hw **hws;
        u8 avpll_flags = 0;
-       int n;
+       int n, ret;
+
+       clk_data = kzalloc(sizeof(*clk_data) +
+                          sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
+       if (!clk_data)
+               return;
+       clk_data->num = MAX_CLKS;
+       hws = clk_data->hws;
 
        gbase = of_iomap(parent_np, 0);
        if (!gbase)
@@ -526,118 +534,118 @@ static void __init berlin2_clock_setup(struct device_node *np)
        }
 
        /* simple register PLLs */
-       clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
+       ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0,
                                   clk_names[SYSPLL], clk_names[REFCLK], 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2_fail;
 
-       clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
+       ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0,
                                   clk_names[MEMPLL], clk_names[REFCLK], 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2_fail;
 
-       clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
+       ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0,
                                   clk_names[CPUPLL], clk_names[REFCLK], 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2_fail;
 
        if (of_device_is_compatible(np, "marvell,berlin2-global-register"))
                avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK;
 
        /* audio/video VCOs */
-       clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
+       ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA",
                         clk_names[REFCLK], avpll_flags, 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2_fail;
 
        for (n = 0; n < 8; n++) {
-               clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
+               ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0,
                             clk_names[AVPLL_A1 + n], n, "avpll_vcoA",
                             avpll_flags, 0);
-               if (IS_ERR(clk))
+               if (ret)
                        goto bg2_fail;
        }
 
-       clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
+       ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB",
                                 clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK |
                                 avpll_flags, 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2_fail;
 
        for (n = 0; n < 8; n++) {
-               clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
+               ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31,
                             clk_names[AVPLL_B1 + n], n, "avpll_vcoB",
                             BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0);
-               if (IS_ERR(clk))
+               if (ret)
                        goto bg2_fail;
        }
 
        /* reference clock bypass switches */
        parent_names[0] = clk_names[SYSPLL];
        parent_names[1] = clk_names[REFCLK];
-       clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2,
+       hw = clk_hw_register_mux(NULL, "syspll_byp", parent_names, 2,
                               0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
-       clk_names[SYSPLL] = __clk_get_name(clk);
+       clk_names[SYSPLL] = clk_hw_get_name(hw);
 
        parent_names[0] = clk_names[MEMPLL];
        parent_names[1] = clk_names[REFCLK];
-       clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2,
+       hw = clk_hw_register_mux(NULL, "mempll_byp", parent_names, 2,
                               0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
-       clk_names[MEMPLL] = __clk_get_name(clk);
+       clk_names[MEMPLL] = clk_hw_get_name(hw);
 
        parent_names[0] = clk_names[CPUPLL];
        parent_names[1] = clk_names[REFCLK];
-       clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2,
+       hw = clk_hw_register_mux(NULL, "cpupll_byp", parent_names, 2,
                               0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
-       clk_names[CPUPLL] = __clk_get_name(clk);
+       clk_names[CPUPLL] = clk_hw_get_name(hw);
 
        /* clock muxes */
        parent_names[0] = clk_names[AVPLL_B3];
        parent_names[1] = clk_names[AVPLL_A3];
-       clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
+       hw = clk_hw_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2,
                               0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
 
        parent_names[0] = clk_names[VIDEO0_PLL];
        parent_names[1] = clk_names[VIDEO_EXT0];
-       clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
+       hw = clk_hw_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2,
                               0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
 
        parent_names[0] = clk_names[VIDEO1_PLL];
        parent_names[1] = clk_names[VIDEO_EXT0];
-       clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
+       hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2,
                               0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
 
        parent_names[0] = clk_names[AVPLL_A2];
        parent_names[1] = clk_names[AVPLL_B2];
-       clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
+       hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2,
                               0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
 
        parent_names[0] = clk_names[VIDEO2_PLL];
        parent_names[1] = clk_names[VIDEO_EXT0];
-       clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
+       hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2,
                               0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
 
        parent_names[0] = clk_names[AVPLL_B1];
        parent_names[1] = clk_names[AVPLL_A5];
-       clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
+       hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2,
                               0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock);
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                goto bg2_fail;
 
        /* clock divider cells */
@@ -648,7 +656,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
                for (k = 0; k < dd->num_parents; k++)
                        parent_names[k] = clk_names[dd->parent_ids[k]];
 
-               clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
+               hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
                                dd->name, dd->div_flags, parent_names,
                                dd->num_parents, dd->flags, &lock);
        }
@@ -657,18 +665,18 @@ static void __init berlin2_clock_setup(struct device_node *np)
        for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) {
                const struct berlin2_gate_data *gd = &bg2_gates[n];
 
-               clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name,
+               hws[CLKID_GETH0 + n] = clk_hw_register_gate(NULL, gd->name,
                            gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
                            gd->bit_idx, 0, &lock);
        }
 
        /* twdclk is derived from cpu/3 */
-       clks[CLKID_TWD] =
-               clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
+       hws[CLKID_TWD] =
+               clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
 
        /* check for errors on leaf clocks */
        for (n = 0; n < MAX_CLKS; n++) {
-               if (!IS_ERR(clks[n]))
+               if (!IS_ERR(hws[n]))
                        continue;
 
                pr_err("%s: Unable to register leaf clock %d\n",
@@ -677,9 +685,7 @@ static void __init berlin2_clock_setup(struct device_node *np)
        }
 
        /* register clk-provider */
-       clk_data.clks = clks;
-       clk_data.clk_num = MAX_CLKS;
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
 
        return;
 
index f144547..0718e83 100644 (file)
@@ -46,8 +46,7 @@
 #define REG_SDIO1XIN_CLKCTL    0x015c
 
 #define        MAX_CLKS 28
-static struct clk *clks[MAX_CLKS];
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_data;
 static DEFINE_SPINLOCK(lock);
 static void __iomem *gbase;
 static void __iomem *cpupll_base;
@@ -293,7 +292,15 @@ static void __init berlin2q_clock_setup(struct device_node *np)
        struct device_node *parent_np = of_get_parent(np);
        const char *parent_names[9];
        struct clk *clk;
-       int n;
+       struct clk_hw **hws;
+       int n, ret;
+
+       clk_data = kzalloc(sizeof(*clk_data) +
+                          sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
+       if (!clk_data)
+               return;
+       clk_data->num = MAX_CLKS;
+       hws = clk_data->hws;
 
        gbase = of_iomap(parent_np, 0);
        if (!gbase) {
@@ -317,14 +324,14 @@ static void __init berlin2q_clock_setup(struct device_node *np)
        }
 
        /* simple register PLLs */
-       clk = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0,
+       ret = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0,
                                   clk_names[SYSPLL], clk_names[REFCLK], 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2q_fail;
 
-       clk = berlin2_pll_register(&bg2q_pll_map, cpupll_base,
+       ret = berlin2_pll_register(&bg2q_pll_map, cpupll_base,
                                   clk_names[CPUPLL], clk_names[REFCLK], 0);
-       if (IS_ERR(clk))
+       if (ret)
                goto bg2q_fail;
 
        /* TODO: add BG2Q AVPLL */
@@ -342,7 +349,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
                for (k = 0; k < dd->num_parents; k++)
                        parent_names[k] = clk_names[dd->parent_ids[k]];
 
-               clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
+               hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase,
                                dd->name, dd->div_flags, parent_names,
                                dd->num_parents, dd->flags, &lock);
        }
@@ -351,22 +358,22 @@ static void __init berlin2q_clock_setup(struct device_node *np)
        for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) {
                const struct berlin2_gate_data *gd = &bg2q_gates[n];
 
-               clks[CLKID_GFX2DAXI + n] = clk_register_gate(NULL, gd->name,
+               hws[CLKID_GFX2DAXI + n] = clk_hw_register_gate(NULL, gd->name,
                            gd->parent_name, gd->flags, gbase + REG_CLKENABLE,
                            gd->bit_idx, 0, &lock);
        }
 
        /* cpuclk divider is fixed to 1 */
-       clks[CLKID_CPU] =
-               clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
+       hws[CLKID_CPU] =
+               clk_hw_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
                                          0, 1, 1);
        /* twdclk is derived from cpu/3 */
-       clks[CLKID_TWD] =
-               clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
+       hws[CLKID_TWD] =
+               clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
 
        /* check for errors on leaf clocks */
        for (n = 0; n < MAX_CLKS; n++) {
-               if (!IS_ERR(clks[n]))
+               if (!IS_ERR(hws[n]))
                        continue;
 
                pr_err("%s: Unable to register leaf clock %d\n",
@@ -375,9 +382,7 @@ static void __init berlin2q_clock_setup(struct device_node *np)
        }
 
        /* register clk-provider */
-       clk_data.clks = clks;
-       clk_data.clk_num = MAX_CLKS;
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
 
        return;
 
index 90897af..ea85685 100644 (file)
@@ -68,8 +68,7 @@
 #define HW_LCDCLKDIV           0x01fc
 #define HW_ADCANACLKDIV                0x0200
 
-static struct clk *clks[MAX_CLKS];
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_data;
 static DEFINE_SPINLOCK(asm9260_clk_lock);
 
 struct asm9260_div_clk {
@@ -267,12 +266,20 @@ static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
 
 static void __init asm9260_acc_init(struct device_node *np)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
+       struct clk_hw **hws;
        const char *ref_clk, *pll_clk = "pll";
        u32 rate;
        int n;
        u32 accuracy = 0;
 
+       clk_data = kzalloc(sizeof(*clk_data) +
+                          sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL);
+       if (!clk_data)
+               return;
+       clk_data->num = MAX_CLKS;
+       hws = clk_data->hws;
+
        base = of_io_request_and_map(np, 0, np->name);
        if (IS_ERR(base))
                panic("%s: unable to map resource", np->name);
@@ -282,10 +289,10 @@ static void __init asm9260_acc_init(struct device_node *np)
 
        ref_clk = of_clk_get_parent_name(np, 0);
        accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
-       clk = clk_register_fixed_rate_with_accuracy(NULL, pll_clk,
+       hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk,
                        ref_clk, 0, rate, accuracy);
 
-       if (IS_ERR(clk))
+       if (IS_ERR(hw))
                panic("%s: can't register REFCLK. Check DT!", np->name);
 
        for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
@@ -293,7 +300,7 @@ static void __init asm9260_acc_init(struct device_node *np)
 
                mc->parent_names[0] = ref_clk;
                mc->parent_names[1] = pll_clk;
-               clk = clk_register_mux_table(NULL, mc->name, mc->parent_names,
+               hw = clk_hw_register_mux_table(NULL, mc->name, mc->parent_names,
                                mc->num_parents, mc->flags, base + mc->offset,
                                0, mc->mask, 0, mc->table, &asm9260_clk_lock);
        }
@@ -302,7 +309,7 @@ static void __init asm9260_acc_init(struct device_node *np)
        for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
                const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
 
-               clk = clk_register_gate(NULL, gd->name,
+               hw = clk_hw_register_gate(NULL, gd->name,
                        gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
                        base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
        }
@@ -311,7 +318,7 @@ static void __init asm9260_acc_init(struct device_node *np)
        for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) {
                const struct asm9260_div_clk *dc = &asm9260_div_clks[n];
 
-               clks[dc->idx] = clk_register_divider(NULL, dc->name,
+               hws[dc->idx] = clk_hw_register_divider(NULL, dc->name,
                                dc->parent_name, CLK_SET_RATE_PARENT,
                                base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED,
                                &asm9260_clk_lock);
@@ -321,14 +328,14 @@ static void __init asm9260_acc_init(struct device_node *np)
        for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) {
                const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n];
 
-               clks[gd->idx] = clk_register_gate(NULL, gd->name,
+               hws[gd->idx] = clk_hw_register_gate(NULL, gd->name,
                                gd->parent_name, gd->flags, base + gd->reg,
                                gd->bit_idx, 0, &asm9260_clk_lock);
        }
 
        /* check for errors on leaf clocks */
        for (n = 0; n < MAX_CLKS; n++) {
-               if (!IS_ERR(clks[n]))
+               if (!IS_ERR(hws[n]))
                        continue;
 
                pr_err("%s: Unable to register leaf clock %d\n",
@@ -337,9 +344,7 @@ static void __init asm9260_acc_init(struct device_node *np)
        }
 
        /* register clk-provider */
-       clk_data.clks = clks;
-       clk_data.clk_num = MAX_CLKS;
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
        return;
 fail:
        iounmap(base);
index 3294db3..5e918e7 100644 (file)
@@ -392,8 +392,8 @@ static int axi_clkgen_probe(struct platform_device *pdev)
        const char *parent_names[2];
        const char *clk_name;
        struct resource *mem;
-       struct clk *clk;
        unsigned int i;
+       int ret;
 
        if (!pdev->dev.of_node)
                return -ENODEV;
@@ -433,12 +433,12 @@ static int axi_clkgen_probe(struct platform_device *pdev)
        axi_clkgen_mmcm_enable(axi_clkgen, false);
 
        axi_clkgen->clk_hw.init = &init;
-       clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       ret = devm_clk_hw_register(&pdev->dev, &axi_clkgen->clk_hw);
+       if (ret)
+               return ret;
 
-       return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get,
-                                   clk);
+       return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get,
+                                     &axi_clkgen->clk_hw);
 }
 
 static int axi_clkgen_remove(struct platform_device *pdev)
index c7c91a5..5d7ae33 100644 (file)
@@ -516,6 +516,19 @@ static struct axxia_clk *axmclk_clocks[] = {
        [AXXIA_CLK_MMC]      = &clk_mmc_mux.aclk,
 };
 
+static struct clk_hw *
+of_clk_axmclk_get(struct of_phandle_args *clkspec, void *unused)
+{
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= ARRAY_SIZE(axmclk_clocks)) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return &axmclk_clocks[idx]->hw;
+}
+
 static const struct regmap_config axmclk_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
@@ -530,21 +543,14 @@ static const struct of_device_id axmclk_match_table[] = {
 };
 MODULE_DEVICE_TABLE(of, axmclk_match_table);
 
-struct axmclk_priv {
-       struct clk_onecell_data onecell;
-       struct clk *clks[];
-};
-
 static int axmclk_probe(struct platform_device *pdev)
 {
        void __iomem *base;
        struct resource *res;
        int i, ret;
        struct device *dev = &pdev->dev;
-       struct clk *clk;
        struct regmap *regmap;
        size_t num_clks;
-       struct axmclk_priv *priv;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        base = devm_ioremap_resource(dev, res);
@@ -557,29 +563,18 @@ static int axmclk_probe(struct platform_device *pdev)
 
        num_clks = ARRAY_SIZE(axmclk_clocks);
        pr_info("axmclk: supporting %zu clocks\n", num_clks);
-       priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks,
-                           GFP_KERNEL);
-       if (!priv)
-               return -ENOMEM;
-
-       priv->onecell.clks = priv->clks;
-       priv->onecell.clk_num = num_clks;
 
        /* Update each entry with the allocated regmap and register the clock
         * with the common clock framework
         */
        for (i = 0; i < num_clks; i++) {
                axmclk_clocks[i]->regmap = regmap;
-               clk = devm_clk_register(dev, &axmclk_clocks[i]->hw);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
-               priv->clks[i] = clk;
+               ret = devm_clk_hw_register(dev, &axmclk_clocks[i]->hw);
+               if (ret)
+                       return ret;
        }
 
-       ret = of_clk_add_provider(dev->of_node,
-                                 of_clk_src_onecell_get, &priv->onecell);
-
-       return ret;
+       return of_clk_add_hw_provider(dev->of_node, of_clk_axmclk_get, NULL);
 }
 
 static int axmclk_remove(struct platform_device *pdev)
index 01877f6..f21d909 100644 (file)
@@ -71,7 +71,6 @@ struct cdce706_hw_data {
        struct cdce706_dev_data *dev_data;
        unsigned idx;
        unsigned parent;
-       struct clk *clk;
        struct clk_hw hw;
        unsigned div;
        unsigned mul;
@@ -81,8 +80,6 @@ struct cdce706_hw_data {
 struct cdce706_dev_data {
        struct i2c_client *client;
        struct regmap *regmap;
-       struct clk_onecell_data onecell;
-       struct clk *clks[6];
        struct clk *clkin_clk[2];
        const char *clkin_name[2];
        struct cdce706_hw_data clkin[1];
@@ -455,18 +452,19 @@ static int cdce706_register_hw(struct cdce706_dev_data *cdce,
                               struct clk_init_data *init)
 {
        unsigned i;
+       int ret;
 
        for (i = 0; i < num_hw; ++i, ++hw) {
                init->name = clk_names[i];
                hw->dev_data = cdce;
                hw->idx = i;
                hw->hw.init = init;
-               hw->clk = devm_clk_register(&cdce->client->dev,
+               ret = devm_clk_hw_register(&cdce->client->dev,
                                            &hw->hw);
-               if (IS_ERR(hw->clk)) {
+               if (ret) {
                        dev_err(&cdce->client->dev, "Failed to register %s\n",
                                clk_names[i]);
-                       return PTR_ERR(hw->clk);
+                       return ret;
                }
        }
        return 0;
@@ -613,13 +611,23 @@ static int cdce706_register_clkouts(struct cdce706_dev_data *cdce)
                        cdce->clkout[i].parent);
        }
 
-       ret = cdce706_register_hw(cdce, cdce->clkout,
-                                 ARRAY_SIZE(cdce->clkout),
-                                 cdce706_clkout_name, &init);
-       for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i)
-               cdce->clks[i] = cdce->clkout[i].clk;
+       return cdce706_register_hw(cdce, cdce->clkout,
+                                  ARRAY_SIZE(cdce->clkout),
+                                  cdce706_clkout_name, &init);
+}
 
-       return ret;
+static struct clk_hw *
+of_clk_cdce_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct cdce706_dev_data *cdce = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= ARRAY_SIZE(cdce->clkout)) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return &cdce->clkout[idx].hw;
 }
 
 static int cdce706_probe(struct i2c_client *client,
@@ -657,12 +665,8 @@ static int cdce706_probe(struct i2c_client *client,
        ret = cdce706_register_clkouts(cdce);
        if (ret < 0)
                return ret;
-       cdce->onecell.clks = cdce->clks;
-       cdce->onecell.clk_num = ARRAY_SIZE(cdce->clks);
-       ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
-                                 &cdce->onecell);
-
-       return ret;
+       return of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce_get,
+                                     cdce);
 }
 
 static int cdce706_remove(struct i2c_client *client)
index 089bf88..b8459c1 100644 (file)
@@ -62,8 +62,6 @@ struct clk_cdce925_chip {
        struct i2c_client *i2c_client;
        struct clk_cdce925_pll pll[NUMBER_OF_PLLS];
        struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS];
-       struct clk *dt_clk[NUMBER_OF_OUTPUTS];
-       struct clk_onecell_data onecell;
 };
 
 /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
@@ -557,6 +555,20 @@ static int cdce925_regmap_i2c_read(void *context,
                return -EIO;
 }
 
+static struct clk_hw *
+of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
+{
+       struct clk_cdce925_chip *data = _data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= ARRAY_SIZE(data->clk)) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return &data->clk[idx].hw;
+}
+
 /* The CDCE925 uses a funky way to read/write registers. Bulk mode is
  * just weird, so just use the single byte mode exclusively. */
 static struct regmap_bus regmap_cdce925_bus = {
@@ -572,7 +584,6 @@ static int cdce925_probe(struct i2c_client *client,
        const char *parent_name;
        const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,};
        struct clk_init_data init;
-       struct clk *clk;
        u32 value;
        int i;
        int err;
@@ -622,10 +633,9 @@ static int cdce925_probe(struct i2c_client *client,
                data->pll[i].chip = data;
                data->pll[i].hw.init = &init;
                data->pll[i].index = i;
-               clk = devm_clk_register(&client->dev, &data->pll[i].hw);
-               if (IS_ERR(clk)) {
+               err = devm_clk_hw_register(&client->dev, &data->pll[i].hw);
+               if (err) {
                        dev_err(&client->dev, "Failed register PLL %d\n", i);
-                       err = PTR_ERR(clk);
                        goto error;
                }
                sprintf(child_name, "PLL%d", i+1);
@@ -634,7 +644,7 @@ static int cdce925_probe(struct i2c_client *client,
                        continue;
                if (!of_property_read_u32(np_output,
                        "clock-frequency", &value)) {
-                       err = clk_set_rate(clk, value);
+                       err = clk_set_rate(data->pll[i].hw.clk, value);
                        if (err)
                                dev_err(&client->dev,
                                        "unable to set PLL frequency %ud\n",
@@ -663,14 +673,12 @@ static int cdce925_probe(struct i2c_client *client,
        data->clk[0].hw.init = &init;
        data->clk[0].index = 0;
        data->clk[0].pdiv = 1;
-       clk = devm_clk_register(&client->dev, &data->clk[0].hw);
+       err = devm_clk_hw_register(&client->dev, &data->clk[0].hw);
        kfree(init.name); /* clock framework made a copy of the name */
-       if (IS_ERR(clk)) {
+       if (err) {
                dev_err(&client->dev, "clock registration Y1 failed\n");
-               err = PTR_ERR(clk);
                goto error;
        }
-       data->dt_clk[0] = clk;
 
        /* Register output clocks Y2 .. Y5*/
        init.ops = &cdce925_clk_ops;
@@ -695,21 +703,17 @@ static int cdce925_probe(struct i2c_client *client,
                        init.parent_names = &pll_clk_name[1];
                        break;
                }
-               clk = devm_clk_register(&client->dev, &data->clk[i].hw);
+               err = devm_clk_hw_register(&client->dev, &data->clk[i].hw);
                kfree(init.name); /* clock framework made a copy of the name */
-               if (IS_ERR(clk)) {
+               if (err) {
                        dev_err(&client->dev, "clock registration failed\n");
-                       err = PTR_ERR(clk);
                        goto error;
                }
-               data->dt_clk[i] = clk;
        }
 
        /* Register the output clocks */
-       data->onecell.clk_num = NUMBER_OF_OUTPUTS;
-       data->onecell.clks = data->dt_clk;
-       err = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
-               &data->onecell);
+       err = of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce925_get,
+                                 data);
        if (err)
                dev_err(&client->dev, "unable to add OF clock provider\n");
 
index adaf109..9193f64 100644 (file)
@@ -40,9 +40,8 @@ static const struct clk_div_table timer_div_table[] = {
 };
 
 struct clps711x_clk {
-       struct clk_onecell_data clk_data;
-       spinlock_t              lock;
-       struct clk              *clks[CLPS711X_CLK_MAX];
+       spinlock_t                      lock;
+       struct clk_hw_onecell_data      clk_data;
 };
 
 static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
@@ -55,7 +54,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
        if (!base)
                return ERR_PTR(-ENOMEM);
 
-       clps711x_clk = kzalloc(sizeof(*clps711x_clk), GFP_KERNEL);
+       clps711x_clk = kzalloc(sizeof(*clps711x_clk) +
+                       sizeof(*clps711x_clk->clk_data.hws) * CLPS711X_CLK_MAX,
+                       GFP_KERNEL);
        if (!clps711x_clk)
                return ERR_PTR(-ENOMEM);
 
@@ -106,40 +107,40 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base,
        tmp |= SYSCON1_TC2M | SYSCON1_TC2S;
        writel(tmp, base + CLPS711X_SYSCON1);
 
-       clps711x_clk->clks[CLPS711X_CLK_DUMMY] =
-               clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
-       clps711x_clk->clks[CLPS711X_CLK_CPU] =
-               clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
-       clps711x_clk->clks[CLPS711X_CLK_BUS] =
-               clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
-       clps711x_clk->clks[CLPS711X_CLK_PLL] =
-               clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
-       clps711x_clk->clks[CLPS711X_CLK_TIMERREF] =
-               clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
-       clps711x_clk->clks[CLPS711X_CLK_TIMER1] =
-               clk_register_divider_table(NULL, "timer1", "timer_ref", 0,
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_DUMMY] =
+               clk_hw_register_fixed_rate(NULL, "dummy", NULL, 0, 0);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_CPU] =
+               clk_hw_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_BUS] =
+               clk_hw_register_fixed_rate(NULL, "bus", NULL, 0, f_bus);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_PLL] =
+               clk_hw_register_fixed_rate(NULL, "pll", NULL, 0, f_pll);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMERREF] =
+               clk_hw_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1] =
+               clk_hw_register_divider_table(NULL, "timer1", "timer_ref", 0,
                                           base + CLPS711X_SYSCON1, 5, 1, 0,
                                           timer_div_table, &clps711x_clk->lock);
-       clps711x_clk->clks[CLPS711X_CLK_TIMER2] =
-               clk_register_divider_table(NULL, "timer2", "timer_ref", 0,
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2] =
+               clk_hw_register_divider_table(NULL, "timer2", "timer_ref", 0,
                                           base + CLPS711X_SYSCON1, 7, 1, 0,
                                           timer_div_table, &clps711x_clk->lock);
-       clps711x_clk->clks[CLPS711X_CLK_PWM] =
-               clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
-       clps711x_clk->clks[CLPS711X_CLK_SPIREF] =
-               clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
-       clps711x_clk->clks[CLPS711X_CLK_SPI] =
-               clk_register_divider_table(NULL, "spi", "spi_ref", 0,
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM] =
+               clk_hw_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_SPIREF] =
+               clk_hw_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_SPI] =
+               clk_hw_register_divider_table(NULL, "spi", "spi_ref", 0,
                                           base + CLPS711X_SYSCON1, 16, 2, 0,
                                           spi_div_table, &clps711x_clk->lock);
-       clps711x_clk->clks[CLPS711X_CLK_UART] =
-               clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
-       clps711x_clk->clks[CLPS711X_CLK_TICK] =
-               clk_register_fixed_rate(NULL, "tick", NULL, 0, 64);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_UART] =
+               clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10);
+       clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] =
+               clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64);
        for (i = 0; i < CLPS711X_CLK_MAX; i++)
-               if (IS_ERR(clps711x_clk->clks[i]))
+               if (IS_ERR(clps711x_clk->clk_data.hws[i]))
                        pr_err("clk %i: register failed with %ld\n",
-                              i, PTR_ERR(clps711x_clk->clks[i]));
+                              i, PTR_ERR(clps711x_clk->clk_data.hws[i]));
 
        return clps711x_clk;
 }
@@ -153,17 +154,17 @@ void __init clps711x_clk_init(void __iomem *base)
        BUG_ON(IS_ERR(clps711x_clk));
 
        /* Clocksource */
-       clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER1],
+       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1],
                            NULL, "clps711x-timer.0");
-       clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER2],
+       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2],
                            NULL, "clps711x-timer.1");
 
        /* Drivers */
-       clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_PWM],
+       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM],
                            NULL, "clps711x-pwm");
-       clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART],
+       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
                            NULL, "clps711x-uart.0");
-       clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART],
+       clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART],
                            NULL, "clps711x-uart.1");
 }
 
@@ -179,10 +180,9 @@ static void __init clps711x_clk_init_dt(struct device_node *np)
        clps711x_clk = _clps711x_clk_init(base, fref);
        BUG_ON(IS_ERR(clps711x_clk));
 
-       clps711x_clk->clk_data.clks = clps711x_clk->clks;
-       clps711x_clk->clk_data.clk_num = CLPS711X_CLK_MAX;
-       of_clk_add_provider(np, of_clk_src_onecell_get,
-                           &clps711x_clk->clk_data);
+       clps711x_clk->clk_data.num = CLPS711X_CLK_MAX;
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
+                              &clps711x_clk->clk_data);
 }
 CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt);
 #endif
index 7379de8..021f3da 100644 (file)
@@ -59,7 +59,6 @@ struct cs2000_priv {
        struct i2c_client *client;
        struct clk *clk_in;
        struct clk *ref_clk;
-       struct clk *clk_out;
 };
 
 static const struct of_device_id cs2000_of_match[] = {
@@ -371,7 +370,6 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
        struct device_node *np = dev->of_node;
        struct clk_init_data init;
        const char *name = np->name;
-       struct clk *clk;
        static const char *parent_names[CLK_MAX];
        int ch = 0; /* it uses ch0 only at this point */
        int rate;
@@ -400,18 +398,16 @@ static int cs2000_clk_register(struct cs2000_priv *priv)
 
        priv->hw.init = &init;
 
-       clk = clk_register(dev, &priv->hw);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       ret = clk_hw_register(dev, &priv->hw);
+       if (ret)
+               return ret;
 
-       ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+       ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
        if (ret < 0) {
-               clk_unregister(clk);
+               clk_hw_unregister(&priv->hw);
                return ret;
        }
 
-       priv->clk_out = clk;
-
        return 0;
 }
 
@@ -454,7 +450,7 @@ static int cs2000_remove(struct i2c_client *client)
 
        of_clk_del_provider(np);
 
-       clk_unregister(priv->clk_out);
+       clk_hw_unregister(&priv->hw);
 
        return 0;
 }
index a0f55bc..96386ff 100644 (file)
@@ -352,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
 
        /* if read only, just return current value */
        if (divider->flags & CLK_DIVIDER_READ_ONLY) {
-               bestdiv = readl(divider->reg) >> divider->shift;
+               bestdiv = clk_readl(divider->reg) >> divider->shift;
                bestdiv &= div_mask(divider->width);
                bestdiv = _get_div(divider->table, bestdiv, divider->flags,
                        divider->width);
index 22e4c65..8802a2d 100644 (file)
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/slab.h>
 
 #include <dt-bindings/clock/efm32-cmu.h>
 
 #define CMU_HFPERCLKEN0                0x44
+#define CMU_MAX_CLKS           37
 
-static struct clk *clk[37];
-static struct clk_onecell_data clk_data = {
-       .clks = clk,
-       .clk_num = ARRAY_SIZE(clk),
-};
+static struct clk_hw_onecell_data *clk_data;
 
 static void __init efm32gg_cmu_init(struct device_node *np)
 {
        int i;
        void __iomem *base;
+       struct clk_hw **hws;
 
-       for (i = 0; i < ARRAY_SIZE(clk); ++i)
-               clk[i] = ERR_PTR(-ENOENT);
+       clk_data = kzalloc(sizeof(*clk_data) +
+                          sizeof(*clk_data->hws) * CMU_MAX_CLKS, GFP_KERNEL);
+
+       if (!clk_data)
+               return;
+
+       hws = clk_data->hws;
+
+       for (i = 0; i < CMU_MAX_CLKS; ++i)
+               hws[i] = ERR_PTR(-ENOENT);
 
        base = of_iomap(np, 0);
        if (!base) {
@@ -35,46 +42,46 @@ static void __init efm32gg_cmu_init(struct device_node *np)
                return;
        }
 
-       clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL,
-                       0, 48000000);
+       hws[clk_HFXO] = clk_hw_register_fixed_rate(NULL, "HFXO", NULL, 0,
+                                                  48000000);
 
-       clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0",
+       hws[clk_HFPERCLKUSART0] = clk_hw_register_gate(NULL, "HFPERCLK.USART0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
-       clk[clk_HFPERCLKUSART1] = clk_register_gate(NULL, "HFPERCLK.USART1",
+       hws[clk_HFPERCLKUSART1] = clk_hw_register_gate(NULL, "HFPERCLK.USART1",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL);
-       clk[clk_HFPERCLKUSART2] = clk_register_gate(NULL, "HFPERCLK.USART2",
+       hws[clk_HFPERCLKUSART2] = clk_hw_register_gate(NULL, "HFPERCLK.USART2",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL);
-       clk[clk_HFPERCLKUART0] = clk_register_gate(NULL, "HFPERCLK.UART0",
+       hws[clk_HFPERCLKUART0] = clk_hw_register_gate(NULL, "HFPERCLK.UART0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL);
-       clk[clk_HFPERCLKUART1] = clk_register_gate(NULL, "HFPERCLK.UART1",
+       hws[clk_HFPERCLKUART1] = clk_hw_register_gate(NULL, "HFPERCLK.UART1",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL);
-       clk[clk_HFPERCLKTIMER0] = clk_register_gate(NULL, "HFPERCLK.TIMER0",
+       hws[clk_HFPERCLKTIMER0] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL);
-       clk[clk_HFPERCLKTIMER1] = clk_register_gate(NULL, "HFPERCLK.TIMER1",
+       hws[clk_HFPERCLKTIMER1] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER1",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL);
-       clk[clk_HFPERCLKTIMER2] = clk_register_gate(NULL, "HFPERCLK.TIMER2",
+       hws[clk_HFPERCLKTIMER2] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER2",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL);
-       clk[clk_HFPERCLKTIMER3] = clk_register_gate(NULL, "HFPERCLK.TIMER3",
+       hws[clk_HFPERCLKTIMER3] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER3",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL);
-       clk[clk_HFPERCLKACMP0] = clk_register_gate(NULL, "HFPERCLK.ACMP0",
+       hws[clk_HFPERCLKACMP0] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL);
-       clk[clk_HFPERCLKACMP1] = clk_register_gate(NULL, "HFPERCLK.ACMP1",
+       hws[clk_HFPERCLKACMP1] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP1",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL);
-       clk[clk_HFPERCLKI2C0] = clk_register_gate(NULL, "HFPERCLK.I2C0",
+       hws[clk_HFPERCLKI2C0] = clk_hw_register_gate(NULL, "HFPERCLK.I2C0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL);
-       clk[clk_HFPERCLKI2C1] = clk_register_gate(NULL, "HFPERCLK.I2C1",
+       hws[clk_HFPERCLKI2C1] = clk_hw_register_gate(NULL, "HFPERCLK.I2C1",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL);
-       clk[clk_HFPERCLKGPIO] = clk_register_gate(NULL, "HFPERCLK.GPIO",
+       hws[clk_HFPERCLKGPIO] = clk_hw_register_gate(NULL, "HFPERCLK.GPIO",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL);
-       clk[clk_HFPERCLKVCMP] = clk_register_gate(NULL, "HFPERCLK.VCMP",
+       hws[clk_HFPERCLKVCMP] = clk_hw_register_gate(NULL, "HFPERCLK.VCMP",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL);
-       clk[clk_HFPERCLKPRS] = clk_register_gate(NULL, "HFPERCLK.PRS",
+       hws[clk_HFPERCLKPRS] = clk_hw_register_gate(NULL, "HFPERCLK.PRS",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL);
-       clk[clk_HFPERCLKADC0] = clk_register_gate(NULL, "HFPERCLK.ADC0",
+       hws[clk_HFPERCLKADC0] = clk_hw_register_gate(NULL, "HFPERCLK.ADC0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL);
-       clk[clk_HFPERCLKDAC0] = clk_register_gate(NULL, "HFPERCLK.DAC0",
+       hws[clk_HFPERCLKDAC0] = clk_hw_register_gate(NULL, "HFPERCLK.DAC0",
                        "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL);
 
-       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data);
 }
 CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init);
index 4db3be2..a5d402d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 
 /*
  * DOC: basic fixed multiplier and divider clock that cannot gate
@@ -147,27 +148,25 @@ static const struct of_device_id set_rate_parent_matches[] = {
        { /* Sentinel */ },
 };
 
-/**
- * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
- */
-void __init of_fixed_factor_clk_setup(struct device_node *node)
+static struct clk *_of_fixed_factor_clk_setup(struct device_node *node)
 {
        struct clk *clk;
        const char *clk_name = node->name;
        const char *parent_name;
        unsigned long flags = 0;
        u32 div, mult;
+       int ret;
 
        if (of_property_read_u32(node, "clock-div", &div)) {
                pr_err("%s Fixed factor clock <%s> must have a clock-div property\n",
                        __func__, node->name);
-               return;
+               return ERR_PTR(-EIO);
        }
 
        if (of_property_read_u32(node, "clock-mult", &mult)) {
                pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n",
                        __func__, node->name);
-               return;
+               return ERR_PTR(-EIO);
        }
 
        of_property_read_string(node, "clock-output-names", &clk_name);
@@ -178,10 +177,67 @@ void __init of_fixed_factor_clk_setup(struct device_node *node)
 
        clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags,
                                        mult, div);
-       if (!IS_ERR(clk))
-               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (IS_ERR(clk))
+               return clk;
+
+       ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (ret) {
+               clk_unregister(clk);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+/**
+ * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
+ */
+void __init of_fixed_factor_clk_setup(struct device_node *node)
+{
+       _of_fixed_factor_clk_setup(node);
 }
-EXPORT_SYMBOL_GPL(of_fixed_factor_clk_setup);
 CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock",
                of_fixed_factor_clk_setup);
+
+static int of_fixed_factor_clk_remove(struct platform_device *pdev)
+{
+       struct clk *clk = platform_get_drvdata(pdev);
+
+       clk_unregister_fixed_factor(clk);
+
+       return 0;
+}
+
+static int of_fixed_factor_clk_probe(struct platform_device *pdev)
+{
+       struct clk *clk;
+
+       /*
+        * This function is not executed when of_fixed_factor_clk_setup
+        * succeeded.
+        */
+       clk = _of_fixed_factor_clk_setup(pdev->dev.of_node);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       platform_set_drvdata(pdev, clk);
+
+       return 0;
+}
+
+static const struct of_device_id of_fixed_factor_clk_ids[] = {
+       { .compatible = "fixed-factor-clock" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, of_fixed_factor_clk_ids);
+
+static struct platform_driver of_fixed_factor_clk_driver = {
+       .driver = {
+               .name = "of_fixed_factor_clk",
+               .of_match_table = of_fixed_factor_clk_ids,
+       },
+       .probe = of_fixed_factor_clk_probe,
+       .remove = of_fixed_factor_clk_remove,
+};
+builtin_platform_driver(of_fixed_factor_clk_driver);
 #endif
index 2edb393..b5c46b3 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 
 /*
  * DOC: basic fixed-rate clock that cannot gate
@@ -157,18 +158,16 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
 EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
 
 #ifdef CONFIG_OF
-/**
- * of_fixed_clk_setup() - Setup function for simple fixed rate clock
- */
-void of_fixed_clk_setup(struct device_node *node)
+static struct clk *_of_fixed_clk_setup(struct device_node *node)
 {
        struct clk *clk;
        const char *clk_name = node->name;
        u32 rate;
        u32 accuracy = 0;
+       int ret;
 
        if (of_property_read_u32(node, "clock-frequency", &rate))
-               return;
+               return ERR_PTR(-EIO);
 
        of_property_read_u32(node, "clock-accuracy", &accuracy);
 
@@ -176,9 +175,66 @@ void of_fixed_clk_setup(struct device_node *node)
 
        clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
                                                    0, rate, accuracy);
-       if (!IS_ERR(clk))
-               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (IS_ERR(clk))
+               return clk;
+
+       ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (ret) {
+               clk_unregister(clk);
+               return ERR_PTR(ret);
+       }
+
+       return clk;
+}
+
+/**
+ * of_fixed_clk_setup() - Setup function for simple fixed rate clock
+ */
+void __init of_fixed_clk_setup(struct device_node *node)
+{
+       _of_fixed_clk_setup(node);
 }
-EXPORT_SYMBOL_GPL(of_fixed_clk_setup);
 CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
+
+static int of_fixed_clk_remove(struct platform_device *pdev)
+{
+       struct clk *clk = platform_get_drvdata(pdev);
+
+       clk_unregister_fixed_rate(clk);
+
+       return 0;
+}
+
+static int of_fixed_clk_probe(struct platform_device *pdev)
+{
+       struct clk *clk;
+
+       /*
+        * This function is not executed when of_fixed_clk_setup
+        * succeeded.
+        */
+       clk = _of_fixed_clk_setup(pdev->dev.of_node);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       platform_set_drvdata(pdev, clk);
+
+       return 0;
+}
+
+static const struct of_device_id of_fixed_clk_ids[] = {
+       { .compatible = "fixed-clock" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, of_fixed_clk_ids);
+
+static struct platform_driver of_fixed_clk_driver = {
+       .driver = {
+               .name = "of_fixed_clk",
+               .of_match_table = of_fixed_clk_ids,
+       },
+       .probe = of_fixed_clk_probe,
+       .remove = of_fixed_clk_remove,
+};
+builtin_platform_driver(of_fixed_clk_driver);
 #endif
index 5097831..8430e45 100644 (file)
@@ -48,13 +48,13 @@ static const struct clk_ops ls1x_pll_clk_ops = {
        .recalc_rate = ls1x_pll_recalc_rate,
 };
 
-static struct clk *__init clk_register_pll(struct device *dev,
-                                          const char *name,
-                                          const char *parent_name,
-                                          unsigned long flags)
+static struct clk_hw *__init clk_hw_register_pll(struct device *dev,
+                                                const char *name,
+                                                const char *parent_name,
+                                                unsigned long flags)
 {
+       int ret;
        struct clk_hw *hw;
-       struct clk *clk;
        struct clk_init_data init;
 
        /* allocate the divider */
@@ -72,12 +72,13 @@ static struct clk *__init clk_register_pll(struct device *dev,
        hw->init = &init;
 
        /* register the clock */
-       clk = clk_register(dev, hw);
-
-       if (IS_ERR(clk))
+       ret = clk_hw_register(dev, hw);
+       if (ret) {
                kfree(hw);
+               hw = ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
 
 static const char * const cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", };
@@ -86,14 +87,14 @@ static const char * const dc_parents[] = { "dc_clk_div", "osc_33m_clk", };
 
 void __init ls1x_clk_init(void)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
 
-       clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC);
-       clk_register_clkdev(clk, "osc_33m_clk", NULL);
+       hw = clk_hw_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC);
+       clk_hw_register_clkdev(hw, "osc_33m_clk", NULL);
 
        /* clock derived from 33 MHz OSC clk */
-       clk = clk_register_pll(NULL, "pll_clk", "osc_33m_clk", 0);
-       clk_register_clkdev(clk, "pll_clk", NULL);
+       hw = clk_hw_register_pll(NULL, "pll_clk", "osc_33m_clk", 0);
+       clk_hw_register_clkdev(hw, "pll_clk", NULL);
 
        /* clock derived from PLL clk */
        /*                                 _____
@@ -102,17 +103,17 @@ void __init ls1x_clk_init(void)
         *        \___ PLL ___ CPU DIV ___|     |
         *                                |_____|
         */
-       clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk",
+       hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk",
                                   CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV,
                                   DIV_CPU_SHIFT, DIV_CPU_WIDTH,
                                   CLK_DIVIDER_ONE_BASED |
                                   CLK_DIVIDER_ROUND_CLOSEST, &_lock);
-       clk_register_clkdev(clk, "cpu_clk_div", NULL);
-       clk = clk_register_mux(NULL, "cpu_clk", cpu_parents,
+       clk_hw_register_clkdev(hw, "cpu_clk_div", NULL);
+       hw = clk_hw_register_mux(NULL, "cpu_clk", cpu_parents,
                               ARRAY_SIZE(cpu_parents),
                               CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
                               BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock);
-       clk_register_clkdev(clk, "cpu_clk", NULL);
+       clk_hw_register_clkdev(hw, "cpu_clk", NULL);
 
        /*                                 _____
         *         _______________________|     |
@@ -120,15 +121,15 @@ void __init ls1x_clk_init(void)
         *        \___ PLL ___ DC  DIV ___|     |
         *                                |_____|
         */
-       clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk",
+       hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk",
                                   0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT,
                                   DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock);
-       clk_register_clkdev(clk, "dc_clk_div", NULL);
-       clk = clk_register_mux(NULL, "dc_clk", dc_parents,
+       clk_hw_register_clkdev(hw, "dc_clk_div", NULL);
+       hw = clk_hw_register_mux(NULL, "dc_clk", dc_parents,
                               ARRAY_SIZE(dc_parents),
                               CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
                               BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock);
-       clk_register_clkdev(clk, "dc_clk", NULL);
+       clk_hw_register_clkdev(hw, "dc_clk", NULL);
 
        /*                                 _____
         *         _______________________|     |
@@ -136,26 +137,26 @@ void __init ls1x_clk_init(void)
         *        \___ PLL ___ DDR DIV ___|     |
         *                                |_____|
         */
-       clk = clk_register_divider(NULL, "ahb_clk_div", "pll_clk",
+       hw = clk_hw_register_divider(NULL, "ahb_clk_div", "pll_clk",
                                   0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT,
                                   DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED,
                                   &_lock);
-       clk_register_clkdev(clk, "ahb_clk_div", NULL);
-       clk = clk_register_mux(NULL, "ahb_clk", ahb_parents,
+       clk_hw_register_clkdev(hw, "ahb_clk_div", NULL);
+       hw = clk_hw_register_mux(NULL, "ahb_clk", ahb_parents,
                               ARRAY_SIZE(ahb_parents),
                               CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV,
                               BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock);
-       clk_register_clkdev(clk, "ahb_clk", NULL);
-       clk_register_clkdev(clk, "stmmaceth", NULL);
+       clk_hw_register_clkdev(hw, "ahb_clk", NULL);
+       clk_hw_register_clkdev(hw, "stmmaceth", NULL);
 
        /* clock derived from AHB clk */
        /* APB clk is always half of the AHB clk */
-       clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
+       hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1,
                                        DIV_APB);
-       clk_register_clkdev(clk, "apb_clk", NULL);
-       clk_register_clkdev(clk, "ls1x_i2c", NULL);
-       clk_register_clkdev(clk, "ls1x_pwmtimer", NULL);
-       clk_register_clkdev(clk, "ls1x_spi", NULL);
-       clk_register_clkdev(clk, "ls1x_wdt", NULL);
-       clk_register_clkdev(clk, "serial8250", NULL);
+       clk_hw_register_clkdev(hw, "apb_clk", NULL);
+       clk_hw_register_clkdev(hw, "ls1x_i2c", NULL);
+       clk_hw_register_clkdev(hw, "ls1x_pwmtimer", NULL);
+       clk_hw_register_clkdev(hw, "ls1x_spi", NULL);
+       clk_hw_register_clkdev(hw, "ls1x_wdt", NULL);
+       clk_hw_register_clkdev(hw, "serial8250", NULL);
 }
diff --git a/drivers/clk/clk-max-gen.c b/drivers/clk/clk-max-gen.c
deleted file mode 100644 (file)
index 35af9cb..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * clk-max-gen.c - Generic clock driver for Maxim PMICs clocks
- *
- * Copyright (C) 2014 Google, Inc
- *
- * Copyright (C) 2012 Samsung Electornics
- * Jonghwa Lee <jonghwa3.lee@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * This driver is based on clk-max77686.c
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/regmap.h>
-#include <linux/platform_device.h>
-#include <linux/clk-provider.h>
-#include <linux/mutex.h>
-#include <linux/clkdev.h>
-#include <linux/of.h>
-#include <linux/export.h>
-
-#include "clk-max-gen.h"
-
-struct max_gen_clk {
-       struct regmap *regmap;
-       u32 mask;
-       u32 reg;
-       struct clk_hw hw;
-};
-
-static struct max_gen_clk *to_max_gen_clk(struct clk_hw *hw)
-{
-       return container_of(hw, struct max_gen_clk, hw);
-}
-
-static int max_gen_clk_prepare(struct clk_hw *hw)
-{
-       struct max_gen_clk *max_gen = to_max_gen_clk(hw);
-
-       return regmap_update_bits(max_gen->regmap, max_gen->reg,
-                                 max_gen->mask, max_gen->mask);
-}
-
-static void max_gen_clk_unprepare(struct clk_hw *hw)
-{
-       struct max_gen_clk *max_gen = to_max_gen_clk(hw);
-
-       regmap_update_bits(max_gen->regmap, max_gen->reg,
-                          max_gen->mask, ~max_gen->mask);
-}
-
-static int max_gen_clk_is_prepared(struct clk_hw *hw)
-{
-       struct max_gen_clk *max_gen = to_max_gen_clk(hw);
-       int ret;
-       u32 val;
-
-       ret = regmap_read(max_gen->regmap, max_gen->reg, &val);
-
-       if (ret < 0)
-               return -EINVAL;
-
-       return val & max_gen->mask;
-}
-
-static unsigned long max_gen_recalc_rate(struct clk_hw *hw,
-                                        unsigned long parent_rate)
-{
-       return 32768;
-}
-
-struct clk_ops max_gen_clk_ops = {
-       .prepare        = max_gen_clk_prepare,
-       .unprepare      = max_gen_clk_unprepare,
-       .is_prepared    = max_gen_clk_is_prepared,
-       .recalc_rate    = max_gen_recalc_rate,
-};
-EXPORT_SYMBOL_GPL(max_gen_clk_ops);
-
-static struct clk *max_gen_clk_register(struct device *dev,
-                                       struct max_gen_clk *max_gen)
-{
-       struct clk *clk;
-       struct clk_hw *hw = &max_gen->hw;
-       int ret;
-
-       clk = devm_clk_register(dev, hw);
-       if (IS_ERR(clk))
-               return clk;
-
-       ret = clk_register_clkdev(clk, hw->init->name, NULL);
-
-       if (ret)
-               return ERR_PTR(ret);
-
-       return clk;
-}
-
-int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap,
-                     u32 reg, struct clk_init_data *clks_init, int num_init)
-{
-       int i, ret;
-       struct max_gen_clk *max_gen_clks;
-       struct clk **clocks;
-       struct device *dev = pdev->dev.parent;
-       const char *clk_name;
-       struct clk_init_data *init;
-
-       clocks = devm_kzalloc(dev, sizeof(struct clk *) * num_init, GFP_KERNEL);
-       if (!clocks)
-               return -ENOMEM;
-
-       max_gen_clks = devm_kzalloc(dev, sizeof(struct max_gen_clk)
-                                   * num_init, GFP_KERNEL);
-       if (!max_gen_clks)
-               return -ENOMEM;
-
-       for (i = 0; i < num_init; i++) {
-               max_gen_clks[i].regmap = regmap;
-               max_gen_clks[i].mask = 1 << i;
-               max_gen_clks[i].reg = reg;
-
-               init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL);
-               if (!init)
-                       return -ENOMEM;
-
-               if (dev->of_node &&
-                   !of_property_read_string_index(dev->of_node,
-                                                  "clock-output-names",
-                                                  i, &clk_name))
-                       init->name = clk_name;
-               else
-                       init->name = clks_init[i].name;
-
-               init->ops = clks_init[i].ops;
-               init->flags = clks_init[i].flags;
-
-               max_gen_clks[i].hw.init = init;
-
-               clocks[i] = max_gen_clk_register(dev, &max_gen_clks[i]);
-               if (IS_ERR(clocks[i])) {
-                       ret = PTR_ERR(clocks[i]);
-                       dev_err(dev, "failed to register %s\n",
-                               max_gen_clks[i].hw.init->name);
-                       return ret;
-               }
-       }
-
-       platform_set_drvdata(pdev, clocks);
-
-       if (dev->of_node) {
-               struct clk_onecell_data *of_data;
-
-               of_data = devm_kzalloc(dev, sizeof(*of_data), GFP_KERNEL);
-               if (!of_data)
-                       return -ENOMEM;
-
-               of_data->clks = clocks;
-               of_data->clk_num = num_init;
-               ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
-                                         of_data);
-
-               if (ret) {
-                       dev_err(dev, "failed to register OF clock provider\n");
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(max_gen_clk_probe);
-
-int max_gen_clk_remove(struct platform_device *pdev, int num_init)
-{
-       struct device *dev = pdev->dev.parent;
-
-       if (dev->of_node)
-               of_clk_del_provider(dev->of_node);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(max_gen_clk_remove);
diff --git a/drivers/clk/clk-max-gen.h b/drivers/clk/clk-max-gen.h
deleted file mode 100644 (file)
index 997e86f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * clk-max-gen.h - Generic clock driver for Maxim PMICs clocks
- *
- * Copyright (C) 2014 Google, Inc
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef __CLK_MAX_GEN_H__
-#define __CLK_MAX_GEN_H__
-
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/clkdev.h>
-#include <linux/regmap.h>
-#include <linux/platform_device.h>
-
-int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap,
-                     u32 reg, struct clk_init_data *clks_init, int num_init);
-int max_gen_clk_remove(struct platform_device *pdev, int num_init);
-extern struct clk_ops max_gen_clk_ops;
-
-#endif /* __CLK_MAX_GEN_H__ */
index 9b6f277..b637f59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * clk-max77686.c - Clock driver for Maxim 77686
+ * clk-max77686.c - Clock driver for Maxim 77686/MAX77802
  *
  * Copyright (C) 2012 Samsung Electornics
  * Jonghwa Lee <jonghwa3.lee@samsung.com>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/max77620.h>
 #include <linux/mfd/max77686.h>
 #include <linux/mfd/max77686-private.h>
 #include <linux/clk-provider.h>
 #include <linux/mutex.h>
 #include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
 
 #include <dt-bindings/clock/maxim,max77686.h>
-#include "clk-max-gen.h"
+#include <dt-bindings/clock/maxim,max77802.h>
+#include <dt-bindings/clock/maxim,max77620.h>
 
-static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
+#define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3
+
+enum max77686_chip_name {
+       CHIP_MAX77686,
+       CHIP_MAX77802,
+       CHIP_MAX77620,
+};
+
+struct max77686_hw_clk_info {
+       const char *name;
+       u32 clk_reg;
+       u32 clk_enable_mask;
+       u32 flags;
+};
+
+struct max77686_clk_init_data {
+       struct regmap *regmap;
+       struct clk_hw hw;
+       struct clk_init_data clk_idata;
+       const struct max77686_hw_clk_info *clk_info;
+};
+
+struct max77686_clk_driver_data {
+       enum max77686_chip_name chip;
+       struct max77686_clk_init_data *max_clk_data;
+       size_t num_clks;
+};
+
+static const struct
+max77686_hw_clk_info max77686_hw_clks_info[MAX77686_CLKS_NUM] = {
        [MAX77686_CLK_AP] = {
                .name = "32khz_ap",
-               .ops = &max_gen_clk_ops,
+               .clk_reg = MAX77686_REG_32KHZ,
+               .clk_enable_mask = BIT(MAX77686_CLK_AP),
        },
        [MAX77686_CLK_CP] = {
                .name = "32khz_cp",
-               .ops = &max_gen_clk_ops,
+               .clk_reg = MAX77686_REG_32KHZ,
+               .clk_enable_mask = BIT(MAX77686_CLK_CP),
        },
        [MAX77686_CLK_PMIC] = {
                .name = "32khz_pmic",
-               .ops = &max_gen_clk_ops,
+               .clk_reg = MAX77686_REG_32KHZ,
+               .clk_enable_mask = BIT(MAX77686_CLK_PMIC),
+       },
+};
+
+static const struct
+max77686_hw_clk_info max77802_hw_clks_info[MAX77802_CLKS_NUM] = {
+       [MAX77802_CLK_32K_AP] = {
+               .name = "32khz_ap",
+               .clk_reg = MAX77802_REG_32KHZ,
+               .clk_enable_mask = BIT(MAX77802_CLK_32K_AP),
+       },
+       [MAX77802_CLK_32K_CP] = {
+               .name = "32khz_cp",
+               .clk_reg = MAX77802_REG_32KHZ,
+               .clk_enable_mask = BIT(MAX77802_CLK_32K_CP),
+       },
+};
+
+static const struct
+max77686_hw_clk_info max77620_hw_clks_info[MAX77620_CLKS_NUM] = {
+       [MAX77620_CLK_32K_OUT0] = {
+               .name = "32khz_out0",
+               .clk_reg = MAX77620_REG_CNFG1_32K,
+               .clk_enable_mask = MAX77620_CNFG1_32K_OUT0_EN,
        },
 };
 
+static struct max77686_clk_init_data *to_max77686_clk_init_data(
+                               struct clk_hw *hw)
+{
+       return container_of(hw, struct max77686_clk_init_data, hw);
+}
+
+static int max77686_clk_prepare(struct clk_hw *hw)
+{
+       struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw);
+
+       return regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg,
+                                 max77686->clk_info->clk_enable_mask,
+                                 max77686->clk_info->clk_enable_mask);
+}
+
+static void max77686_clk_unprepare(struct clk_hw *hw)
+{
+       struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw);
+
+       regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg,
+                          max77686->clk_info->clk_enable_mask,
+                          ~max77686->clk_info->clk_enable_mask);
+}
+
+static int max77686_clk_is_prepared(struct clk_hw *hw)
+{
+       struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw);
+       int ret;
+       u32 val;
+
+       ret = regmap_read(max77686->regmap, max77686->clk_info->clk_reg, &val);
+
+       if (ret < 0)
+               return -EINVAL;
+
+       return val & max77686->clk_info->clk_enable_mask;
+}
+
+static unsigned long max77686_recalc_rate(struct clk_hw *hw,
+                                         unsigned long parent_rate)
+{
+       return 32768;
+}
+
+static struct clk_ops max77686_clk_ops = {
+       .prepare        = max77686_clk_prepare,
+       .unprepare      = max77686_clk_unprepare,
+       .is_prepared    = max77686_clk_is_prepared,
+       .recalc_rate    = max77686_recalc_rate,
+};
+
+static struct clk_hw *
+of_clk_max77686_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct max77686_clk_driver_data *drv_data = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= drv_data->num_clks) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return &drv_data->max_clk_data[idx].hw;
+}
+
 static int max77686_clk_probe(struct platform_device *pdev)
 {
-       struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+       struct device *dev = &pdev->dev;
+       struct device *parent = dev->parent;
+       const struct platform_device_id *id = platform_get_device_id(pdev);
+       struct max77686_clk_driver_data *drv_data;
+       const struct max77686_hw_clk_info *hw_clks;
+       struct regmap *regmap;
+       int i, ret, num_clks;
+
+       drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL);
+       if (!drv_data)
+               return -ENOMEM;
+
+       regmap = dev_get_regmap(parent, NULL);
+       if (!regmap) {
+               dev_err(dev, "Failed to get rtc regmap\n");
+               return -ENODEV;
+       }
+
+       drv_data->chip = id->driver_data;
+
+       switch (drv_data->chip) {
+       case CHIP_MAX77686:
+               num_clks = MAX77686_CLKS_NUM;
+               hw_clks = max77686_hw_clks_info;
+               break;
+
+       case CHIP_MAX77802:
+               num_clks = MAX77802_CLKS_NUM;
+               hw_clks = max77802_hw_clks_info;
+               break;
+
+       case CHIP_MAX77620:
+               num_clks = MAX77620_CLKS_NUM;
+               hw_clks = max77620_hw_clks_info;
+               break;
 
-       return max_gen_clk_probe(pdev, iodev->regmap, MAX77686_REG_32KHZ,
-                                max77686_clks_init, MAX77686_CLKS_NUM);
+       default:
+               dev_err(dev, "Unknown Chip ID\n");
+               return -EINVAL;
+       }
+
+       drv_data->max_clk_data = devm_kcalloc(dev, num_clks,
+                                             sizeof(*drv_data->max_clk_data),
+                                             GFP_KERNEL);
+       if (!drv_data->max_clk_data)
+               return -ENOMEM;
+
+       for (i = 0; i < num_clks; i++) {
+               struct max77686_clk_init_data *max_clk_data;
+               const char *clk_name;
+
+               max_clk_data = &drv_data->max_clk_data[i];
+
+               max_clk_data->regmap = regmap;
+               max_clk_data->clk_info = &hw_clks[i];
+               max_clk_data->clk_idata.flags = hw_clks[i].flags;
+               max_clk_data->clk_idata.ops = &max77686_clk_ops;
+
+               if (parent->of_node &&
+                   !of_property_read_string_index(parent->of_node,
+                                                  "clock-output-names",
+                                                  i, &clk_name))
+                       max_clk_data->clk_idata.name = clk_name;
+               else
+                       max_clk_data->clk_idata.name = hw_clks[i].name;
+
+               max_clk_data->hw.init = &max_clk_data->clk_idata;
+
+               ret = devm_clk_hw_register(dev, &max_clk_data->hw);
+               if (ret) {
+                       dev_err(dev, "Failed to clock register: %d\n", ret);
+                       return ret;
+               }
+
+               ret = clk_hw_register_clkdev(&max_clk_data->hw,
+                                            max_clk_data->clk_idata.name, NULL);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to clkdev register: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (parent->of_node) {
+               ret = of_clk_add_hw_provider(parent->of_node, of_clk_max77686_get,
+                                            drv_data);
+
+               if (ret < 0) {
+                       dev_err(dev, "Failed to register OF clock provider: %d\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       /* MAX77802: Enable low-jitter mode on the 32khz clocks. */
+       if (drv_data->chip == CHIP_MAX77802) {
+               ret = regmap_update_bits(regmap, MAX77802_REG_32KHZ,
+                                        1 << MAX77802_CLOCK_LOW_JITTER_SHIFT,
+                                        1 << MAX77802_CLOCK_LOW_JITTER_SHIFT);
+               if (ret < 0) {
+                       dev_err(dev, "Failed to config low-jitter: %d\n", ret);
+                       goto remove_of_clk_provider;
+               }
+       }
+
+       return 0;
+
+remove_of_clk_provider:
+       if (parent->of_node)
+               of_clk_del_provider(parent->of_node);
+
+       return ret;
 }
 
 static int max77686_clk_remove(struct platform_device *pdev)
 {
-       return max_gen_clk_remove(pdev, MAX77686_CLKS_NUM);
+       struct device *parent = pdev->dev.parent;
+
+       if (parent->of_node)
+               of_clk_del_provider(parent->of_node);
+
+       return 0;
 }
 
 static const struct platform_device_id max77686_clk_id[] = {
-       { "max77686-clk", 0},
-       { },
+       { "max77686-clk", .driver_data = CHIP_MAX77686, },
+       { "max77802-clk", .driver_data = CHIP_MAX77802, },
+       { "max77620-clock", .driver_data = CHIP_MAX77620, },
+       {},
 };
 MODULE_DEVICE_TABLE(platform, max77686_clk_id);
 
diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c
deleted file mode 100644 (file)
index 355dd2e..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * clk-max77802.c - Clock driver for Maxim 77802
- *
- * Copyright (C) 2014 Google, Inc
- *
- * Copyright (C) 2012 Samsung Electornics
- * Jonghwa Lee <jonghwa3.lee@samsung.com>
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * This driver is based on clk-max77686.c
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/max77686-private.h>
-#include <linux/clk-provider.h>
-#include <linux/mutex.h>
-#include <linux/clkdev.h>
-
-#include <dt-bindings/clock/maxim,max77802.h>
-#include "clk-max-gen.h"
-
-#define MAX77802_CLOCK_OPMODE_MASK     0x1
-#define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3
-
-static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = {
-       [MAX77802_CLK_32K_AP] = {
-               .name = "32khz_ap",
-               .ops = &max_gen_clk_ops,
-       },
-       [MAX77802_CLK_32K_CP] = {
-               .name = "32khz_cp",
-               .ops = &max_gen_clk_ops,
-       },
-};
-
-static int max77802_clk_probe(struct platform_device *pdev)
-{
-       struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
-       int ret;
-
-       ret = max_gen_clk_probe(pdev, iodev->regmap, MAX77802_REG_32KHZ,
-                               max77802_clks_init, MAX77802_CLKS_NUM);
-
-       if (ret) {
-               dev_err(&pdev->dev, "generic probe failed %d\n", ret);
-               return ret;
-       }
-
-       /* Enable low-jitter mode on the 32khz clocks. */
-       ret = regmap_update_bits(iodev->regmap, MAX77802_REG_32KHZ,
-                                1 << MAX77802_CLOCK_LOW_JITTER_SHIFT,
-                                1 << MAX77802_CLOCK_LOW_JITTER_SHIFT);
-       if (ret < 0)
-               dev_err(&pdev->dev, "failed to enable low-jitter mode\n");
-
-       return ret;
-}
-
-static int max77802_clk_remove(struct platform_device *pdev)
-{
-       return max_gen_clk_remove(pdev, MAX77802_CLKS_NUM);
-}
-
-static const struct platform_device_id max77802_clk_id[] = {
-       { "max77802-clk", 0},
-       { },
-};
-MODULE_DEVICE_TABLE(platform, max77802_clk_id);
-
-static struct platform_driver max77802_clk_driver = {
-       .driver = {
-               .name  = "max77802-clk",
-       },
-       .probe = max77802_clk_probe,
-       .remove = max77802_clk_remove,
-       .id_table = max77802_clk_id,
-};
-
-module_platform_driver(max77802_clk_driver);
-
-MODULE_DESCRIPTION("MAXIM 77802 Clock Driver");
-MODULE_AUTHOR("Javier Martinez Canillas <javier@osg.samsung.com");
-MODULE_LICENSE("GPL");
index e081775..2a83a3f 100644 (file)
@@ -327,10 +327,11 @@ static struct clk_ops clk_clc_ops = {
        .set_rate = clc_set_rate,
 };
 
-struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
+static struct clk_hw *mb86s7x_clclk_register(struct device *cpu_dev)
 {
        struct clk_init_data init;
        struct cl_clk *clc;
+       int ret;
 
        clc = kzalloc(sizeof(*clc), GFP_KERNEL);
        if (!clc)
@@ -344,14 +345,17 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
        init.flags = CLK_GET_RATE_NOCACHE;
        init.num_parents = 0;
 
-       return devm_clk_register(cpu_dev, &clc->hw);
+       ret = devm_clk_hw_register(cpu_dev, &clc->hw);
+       if (ret)
+               return ERR_PTR(ret);
+       return &clc->hw;
 }
 
 static int mb86s7x_clclk_of_init(void)
 {
        int cpu, ret = -ENODEV;
        struct device_node *np;
-       struct clk *clk;
+       struct clk_hw *hw;
 
        np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
        if (!np || !of_device_is_available(np))
@@ -365,12 +369,12 @@ static int mb86s7x_clclk_of_init(void)
                        continue;
                }
 
-               clk = mb86s7x_clclk_register(cpu_dev);
-               if (IS_ERR(clk)) {
+               hw = mb86s7x_clclk_register(cpu_dev);
+               if (IS_ERR(hw)) {
                        pr_err("failed to register cpu%d clock\n", cpu);
                        continue;
                }
-               if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+               if (clk_hw_register_clkdev(hw, NULL, dev_name(cpu_dev))) {
                        pr_err("failed to register cpu%d clock lookup\n", cpu);
                        continue;
                }
index f37f719..b86dac8 100644 (file)
@@ -19,7 +19,8 @@
 static void __init moxart_of_pll_clk_init(struct device_node *node)
 {
        static void __iomem *base;
-       struct clk *clk, *ref_clk;
+       struct clk_hw *hw;
+       struct clk *ref_clk;
        unsigned int mul;
        const char *name = node->name;
        const char *parent_name;
@@ -42,14 +43,14 @@ static void __init moxart_of_pll_clk_init(struct device_node *node)
                return;
        }
 
-       clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
-       if (IS_ERR(clk)) {
+       hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
+       if (IS_ERR(hw)) {
                pr_err("%s: failed to register clock\n", node->full_name);
                return;
        }
 
-       clk_register_clkdev(clk, NULL, name);
-       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       clk_hw_register_clkdev(hw, NULL, name);
+       of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
               moxart_of_pll_clk_init);
@@ -57,7 +58,8 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
 static void __init moxart_of_apb_clk_init(struct device_node *node)
 {
        static void __iomem *base;
-       struct clk *clk, *pll_clk;
+       struct clk_hw *hw;
+       struct clk *pll_clk;
        unsigned int div, val;
        unsigned int div_idx[] = { 2, 3, 4, 6, 8};
        const char *name = node->name;
@@ -85,14 +87,14 @@ static void __init moxart_of_apb_clk_init(struct device_node *node)
                return;
        }
 
-       clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
-       if (IS_ERR(clk)) {
+       hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
+       if (IS_ERR(hw)) {
                pr_err("%s: failed to register clock\n", node->full_name);
                return;
        }
 
-       clk_register_clkdev(clk, NULL, name);
-       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       clk_hw_register_clkdev(hw, NULL, name);
+       of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
 }
 CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
               moxart_of_apb_clk_init);
index 64f196a..f861011 100644 (file)
@@ -69,7 +69,7 @@ static void __init nspire_ahbdiv_setup(struct device_node *node,
 {
        u32 val;
        void __iomem *io;
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *clk_name = node->name;
        const char *parent_name;
        struct nspire_clk_info info;
@@ -85,10 +85,10 @@ static void __init nspire_ahbdiv_setup(struct device_node *node,
        of_property_read_string(node, "clock-output-names", &clk_name);
        parent_name = of_clk_get_parent_name(node, 0);
 
-       clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0,
-                                       1, info.base_ahb_ratio);
-       if (!IS_ERR(clk))
-               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       hw = clk_hw_register_fixed_factor(NULL, clk_name, parent_name, 0,
+                                         1, info.base_ahb_ratio);
+       if (!IS_ERR(hw))
+               of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
 }
 
 static void __init nspire_ahbdiv_setup_cx(struct device_node *node)
@@ -111,7 +111,7 @@ static void __init nspire_clk_setup(struct device_node *node,
 {
        u32 val;
        void __iomem *io;
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *clk_name = node->name;
        struct nspire_clk_info info;
 
@@ -125,9 +125,10 @@ static void __init nspire_clk_setup(struct device_node *node,
 
        of_property_read_string(node, "clock-output-names", &clk_name);
 
-       clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, info.base_clock);
-       if (!IS_ERR(clk))
-               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       hw = clk_hw_register_fixed_rate(NULL, clk_name, NULL, 0,
+                                       info.base_clock);
+       if (!IS_ERR(hw))
+               of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
        else
                return;
 
index 8328863..31f590c 100644 (file)
@@ -41,7 +41,6 @@ struct palmas_clk32k_desc {
 
 struct palmas_clock_info {
        struct device *dev;
-       struct clk *clk;
        struct clk_hw hw;
        struct palmas *palmas;
        const struct palmas_clk32k_desc *clk_desc;
@@ -218,7 +217,7 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
        }
 
        if (cinfo->ext_control_pin) {
-               ret = clk_prepare(cinfo->clk);
+               ret = clk_prepare(cinfo->hw.clk);
                if (ret < 0) {
                        dev_err(cinfo->dev, "Clock prep failed, %d\n", ret);
                        return ret;
@@ -242,7 +241,6 @@ static int palmas_clks_probe(struct platform_device *pdev)
        struct device_node *node = pdev->dev.of_node;
        const struct palmas_clks_of_match_data *match_data;
        struct palmas_clock_info *cinfo;
-       struct clk *clk;
        int ret;
 
        match_data = of_device_get_match_data(&pdev->dev);
@@ -261,22 +259,20 @@ static int palmas_clks_probe(struct platform_device *pdev)
 
        cinfo->clk_desc = &match_data->desc;
        cinfo->hw.init = &match_data->init;
-       clk = devm_clk_register(&pdev->dev, &cinfo->hw);
-       if (IS_ERR(clk)) {
-               ret = PTR_ERR(clk);
+       ret = devm_clk_hw_register(&pdev->dev, &cinfo->hw);
+       if (ret) {
                dev_err(&pdev->dev, "Fail to register clock %s, %d\n",
                        match_data->desc.clk_name, ret);
                return ret;
        }
 
-       cinfo->clk = clk;
        ret = palmas_clks_init_configure(cinfo);
        if (ret < 0) {
                dev_err(&pdev->dev, "Clock config failed, %d\n", ret);
                return ret;
        }
 
-       ret = of_clk_add_provider(node, of_clk_src_simple_get, cinfo->clk);
+       ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &cinfo->hw);
        if (ret < 0)
                dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret);
        return ret;
index 1630a1f..8cb9d11 100644 (file)
@@ -61,7 +61,6 @@ static int clk_pwm_probe(struct platform_device *pdev)
        struct pwm_device *pwm;
        struct pwm_args pargs;
        const char *clk_name;
-       struct clk *clk;
        int ret;
 
        clk_pwm = devm_kzalloc(&pdev->dev, sizeof(*clk_pwm), GFP_KERNEL);
@@ -107,11 +106,11 @@ static int clk_pwm_probe(struct platform_device *pdev)
 
        clk_pwm->pwm = pwm;
        clk_pwm->hw.init = &init;
-       clk = devm_clk_register(&pdev->dev, &clk_pwm->hw);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       ret = devm_clk_hw_register(&pdev->dev, &clk_pwm->hw);
+       if (ret)
+               return ret;
 
-       return of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       return of_clk_add_hw_provider(node, of_clk_hw_simple_get, &clk_pwm->hw);
 }
 
 static int clk_pwm_remove(struct platform_device *pdev)
index 58566a1..20b1055 100644 (file)
@@ -766,7 +766,11 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
        if (!hwc)
                return NULL;
 
-       hwc->reg = cg->regs + 0x20 * idx;
+       if (cg->info.flags & CG_VER3)
+               hwc->reg = cg->regs + 0x70000 + 0x20 * idx;
+       else
+               hwc->reg = cg->regs + 0x20 * idx;
+
        hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]];
 
        /*
index 7438303..6461f28 100644 (file)
 #include <linux/mfd/rk808.h>
 #include <linux/i2c.h>
 
-#define RK808_NR_OUTPUT 2
-
 struct rk808_clkout {
        struct rk808 *rk808;
-       struct clk_onecell_data clk_data;
        struct clk_hw           clkout1_hw;
        struct clk_hw           clkout2_hw;
 };
@@ -85,14 +82,28 @@ static const struct clk_ops rk808_clkout2_ops = {
        .recalc_rate = rk808_clkout_recalc_rate,
 };
 
+static struct clk_hw *
+of_clk_rk808_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct rk808_clkout *rk808_clkout = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= 2) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return idx ? &rk808_clkout->clkout2_hw : &rk808_clkout->clkout1_hw;
+}
+
 static int rk808_clkout_probe(struct platform_device *pdev)
 {
        struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
        struct i2c_client *client = rk808->i2c;
        struct device_node *node = client->dev.of_node;
        struct clk_init_data init = {};
-       struct clk **clk_table;
        struct rk808_clkout *rk808_clkout;
+       int ret;
 
        rk808_clkout = devm_kzalloc(&client->dev,
                                    sizeof(*rk808_clkout), GFP_KERNEL);
@@ -101,11 +112,6 @@ static int rk808_clkout_probe(struct platform_device *pdev)
 
        rk808_clkout->rk808 = rk808;
 
-       clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT,
-                                sizeof(struct clk *), GFP_KERNEL);
-       if (!clk_table)
-               return -ENOMEM;
-
        init.parent_names = NULL;
        init.num_parents = 0;
        init.name = "rk808-clkout1";
@@ -116,10 +122,9 @@ static int rk808_clkout_probe(struct platform_device *pdev)
        of_property_read_string_index(node, "clock-output-names",
                                      0, &init.name);
 
-       clk_table[0] = devm_clk_register(&client->dev,
-                                        &rk808_clkout->clkout1_hw);
-       if (IS_ERR(clk_table[0]))
-               return PTR_ERR(clk_table[0]);
+       ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw);
+       if (ret)
+               return ret;
 
        init.name = "rk808-clkout2";
        init.ops = &rk808_clkout2_ops;
@@ -129,16 +134,11 @@ static int rk808_clkout_probe(struct platform_device *pdev)
        of_property_read_string_index(node, "clock-output-names",
                                      1, &init.name);
 
-       clk_table[1] = devm_clk_register(&client->dev,
-                                        &rk808_clkout->clkout2_hw);
-       if (IS_ERR(clk_table[1]))
-               return PTR_ERR(clk_table[1]);
-
-       rk808_clkout->clk_data.clks = clk_table;
-       rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT;
+       ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw);
+       if (ret)
+               return ret;
 
-       return of_clk_add_provider(node, of_clk_src_onecell_get,
-                                  &rk808_clkout->clk_data);
+       return of_clk_add_hw_provider(node, of_clk_rk808_get, rk808_clkout);
 }
 
 static int rk808_clkout_remove(struct platform_device *pdev)
index 6962ee5..2a3e9d8 100644 (file)
@@ -146,13 +146,13 @@ static const struct of_device_id scpi_clk_match[] = {
        {}
 };
 
-static struct clk *
+static int
 scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
                  struct scpi_clk *sclk, const char *name)
 {
        struct clk_init_data init;
-       struct clk *clk;
        unsigned long min = 0, max = 0;
+       int ret;
 
        init.name = name;
        init.flags = 0;
@@ -164,18 +164,18 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
        if (init.ops == &scpi_dvfs_ops) {
                sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id);
                if (IS_ERR(sclk->info))
-                       return NULL;
+                       return PTR_ERR(sclk->info);
        } else if (init.ops == &scpi_clk_ops) {
                if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max)
-                       return NULL;
+                       return -EINVAL;
        } else {
-               return NULL;
+               return -EINVAL;
        }
 
-       clk = devm_clk_register(dev, &sclk->hw);
-       if (!IS_ERR(clk) && max)
+       ret = devm_clk_hw_register(dev, &sclk->hw);
+       if (!ret && max)
                clk_hw_set_rate_range(&sclk->hw, min, max);
-       return clk;
+       return ret;
 }
 
 struct scpi_clk_data {
@@ -183,7 +183,7 @@ struct scpi_clk_data {
        unsigned int clk_num;
 };
 
-static struct clk *
+static struct clk_hw *
 scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
 {
        struct scpi_clk *sclk;
@@ -193,7 +193,7 @@ scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
        for (count = 0; count < clk_data->clk_num; count++) {
                sclk = clk_data->clk[count];
                if (idx == sclk->id)
-                       return sclk->hw.clk;
+                       return &sclk->hw;
        }
 
        return ERR_PTR(-EINVAL);
@@ -202,8 +202,7 @@ scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data)
 static int scpi_clk_add(struct device *dev, struct device_node *np,
                        const struct of_device_id *match)
 {
-       struct clk **clks;
-       int idx, count;
+       int idx, count, err;
        struct scpi_clk_data *clk_data;
 
        count = of_property_count_strings(np, "clock-output-names");
@@ -222,10 +221,6 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
        if (!clk_data->clk)
                return -ENOMEM;
 
-       clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL);
-       if (!clks)
-               return -ENOMEM;
-
        for (idx = 0; idx < count; idx++) {
                struct scpi_clk *sclk;
                const char *name;
@@ -249,15 +244,15 @@ static int scpi_clk_add(struct device *dev, struct device_node *np,
 
                sclk->id = val;
 
-               clks[idx] = scpi_clk_ops_init(dev, match, sclk, name);
-               if (IS_ERR_OR_NULL(clks[idx]))
+               err = scpi_clk_ops_init(dev, match, sclk, name);
+               if (err)
                        dev_err(dev, "failed to register clock '%s'\n", name);
                else
                        dev_dbg(dev, "Registered clock '%s'\n", name);
                clk_data->clk[idx] = sclk;
        }
 
-       return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data);
+       return of_clk_add_hw_provider(np, scpi_of_clk_src_get, clk_data);
 }
 
 static int scpi_clocks_remove(struct platform_device *pdev)
index ceef25b..09b6718 100644 (file)
@@ -305,7 +305,6 @@ static int si514_probe(struct i2c_client *client,
 {
        struct clk_si514 *data;
        struct clk_init_data init;
-       struct clk *clk;
        int err;
 
        data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
@@ -330,13 +329,13 @@ static int si514_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, data);
 
-       clk = devm_clk_register(&client->dev, &data->hw);
-       if (IS_ERR(clk)) {
+       err = devm_clk_hw_register(&client->dev, &data->hw);
+       if (err) {
                dev_err(&client->dev, "clock registration failed\n");
-               return PTR_ERR(clk);
+               return err;
        }
-       err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get,
-                       clk);
+       err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
+                                    &data->hw);
        if (err) {
                dev_err(&client->dev, "unable to add clk provider\n");
                return err;
index b1bc12c..b051db4 100644 (file)
@@ -54,7 +54,6 @@ struct si5351_driver_data {
        enum si5351_variant     variant;
        struct i2c_client       *client;
        struct regmap           *regmap;
-       struct clk_onecell_data onecell;
 
        struct clk              *pxtal;
        const char              *pxtal_name;
@@ -66,6 +65,7 @@ struct si5351_driver_data {
        struct si5351_hw_data   pll[2];
        struct si5351_hw_data   *msynth;
        struct si5351_hw_data   *clkout;
+       size_t                  num_clkout;
 };
 
 static const char * const si5351_input_names[] = {
@@ -1307,11 +1307,31 @@ put_child:
        of_node_put(child);
        return -EINVAL;
 }
+
+static struct clk_hw *
+si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+       struct si5351_driver_data *drvdata = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= drvdata->num_clkout) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return &drvdata->clkout[idx].hw;
+}
 #else
 static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant)
 {
        return 0;
 }
+
+static struct clk_hw *
+si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+       return NULL;
+}
 #endif /* CONFIG_OF */
 
 static int si5351_i2c_probe(struct i2c_client *client,
@@ -1321,7 +1341,6 @@ static int si5351_i2c_probe(struct i2c_client *client,
        struct si5351_platform_data *pdata;
        struct si5351_driver_data *drvdata;
        struct clk_init_data init;
-       struct clk *clk;
        const char *parent_names[4];
        u8 num_parents, num_clocks;
        int ret, n;
@@ -1438,10 +1457,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
                init.num_parents = 1;
        }
        drvdata->xtal.init = &init;
-       clk = devm_clk_register(&client->dev, &drvdata->xtal);
-       if (IS_ERR(clk)) {
+       ret = devm_clk_hw_register(&client->dev, &drvdata->xtal);
+       if (ret) {
                dev_err(&client->dev, "unable to register %s\n", init.name);
-               ret = PTR_ERR(clk);
                goto err_clk;
        }
 
@@ -1456,11 +1474,10 @@ static int si5351_i2c_probe(struct i2c_client *client,
                        init.num_parents = 1;
                }
                drvdata->clkin.init = &init;
-               clk = devm_clk_register(&client->dev, &drvdata->clkin);
-               if (IS_ERR(clk)) {
+               ret = devm_clk_hw_register(&client->dev, &drvdata->clkin);
+               if (ret) {
                        dev_err(&client->dev, "unable to register %s\n",
                                init.name);
-                       ret = PTR_ERR(clk);
                        goto err_clk;
                }
        }
@@ -1480,10 +1497,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
        init.flags = 0;
        init.parent_names = parent_names;
        init.num_parents = num_parents;
-       clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
-       if (IS_ERR(clk)) {
+       ret = devm_clk_hw_register(&client->dev, &drvdata->pll[0].hw);
+       if (ret) {
                dev_err(&client->dev, "unable to register %s\n", init.name);
-               ret = PTR_ERR(clk);
                goto err_clk;
        }
 
@@ -1505,10 +1521,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
                init.parent_names = parent_names;
                init.num_parents = num_parents;
        }
-       clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
-       if (IS_ERR(clk)) {
+       ret = devm_clk_hw_register(&client->dev, &drvdata->pll[1].hw);
+       if (ret) {
                dev_err(&client->dev, "unable to register %s\n", init.name);
-               ret = PTR_ERR(clk);
                goto err_clk;
        }
 
@@ -1524,13 +1539,9 @@ static int si5351_i2c_probe(struct i2c_client *client,
                                       sizeof(*drvdata->msynth), GFP_KERNEL);
        drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
                                       sizeof(*drvdata->clkout), GFP_KERNEL);
+       drvdata->num_clkout = num_clocks;
 
-       drvdata->onecell.clk_num = num_clocks;
-       drvdata->onecell.clks = devm_kzalloc(&client->dev,
-               num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
-
-       if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
-                   !drvdata->onecell.clks)) {
+       if (WARN_ON(!drvdata->msynth || !drvdata->clkout)) {
                ret = -ENOMEM;
                goto err_clk;
        }
@@ -1547,11 +1558,11 @@ static int si5351_i2c_probe(struct i2c_client *client,
                        init.flags |= CLK_SET_RATE_PARENT;
                init.parent_names = parent_names;
                init.num_parents = 2;
-               clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
-               if (IS_ERR(clk)) {
+               ret = devm_clk_hw_register(&client->dev,
+                                          &drvdata->msynth[n].hw);
+               if (ret) {
                        dev_err(&client->dev, "unable to register %s\n",
                                init.name);
-                       ret = PTR_ERR(clk);
                        goto err_clk;
                }
        }
@@ -1575,19 +1586,19 @@ static int si5351_i2c_probe(struct i2c_client *client,
                        init.flags |= CLK_SET_RATE_PARENT;
                init.parent_names = parent_names;
                init.num_parents = num_parents;
-               clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
-               if (IS_ERR(clk)) {
+               ret = devm_clk_hw_register(&client->dev,
+                                          &drvdata->clkout[n].hw);
+               if (ret) {
                        dev_err(&client->dev, "unable to register %s\n",
                                init.name);
-                       ret = PTR_ERR(clk);
                        goto err_clk;
                }
-               drvdata->onecell.clks[n] = clk;
 
                /* set initial clkout rate */
                if (pdata->clkout[n].rate != 0) {
                        int ret;
-                       ret = clk_set_rate(clk, pdata->clkout[n].rate);
+                       ret = clk_set_rate(drvdata->clkout[n].hw.clk,
+                                          pdata->clkout[n].rate);
                        if (ret != 0) {
                                dev_err(&client->dev, "Cannot set rate : %d\n",
                                        ret);
@@ -1595,8 +1606,8 @@ static int si5351_i2c_probe(struct i2c_client *client,
                }
        }
 
-       ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
-                                 &drvdata->onecell);
+       ret = of_clk_add_hw_provider(client->dev.of_node, si53351_of_clk_get,
+                                    drvdata);
        if (ret) {
                dev_err(&client->dev, "unable to add clk provider\n");
                goto err_clk;
index d566485..646af1d 100644 (file)
@@ -408,7 +408,6 @@ static int si570_probe(struct i2c_client *client,
 {
        struct clk_si570 *data;
        struct clk_init_data init;
-       struct clk *clk;
        u32 initial_fout, factory_fout, stability;
        int err;
        enum clk_si570_variant variant = id->driver_data;
@@ -462,13 +461,13 @@ static int si570_probe(struct i2c_client *client,
        if (err)
                return err;
 
-       clk = devm_clk_register(&client->dev, &data->hw);
-       if (IS_ERR(clk)) {
+       err = devm_clk_hw_register(&client->dev, &data->hw);
+       if (err) {
                dev_err(&client->dev, "clock registration failed\n");
-               return PTR_ERR(clk);
+               return err;
        }
-       err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get,
-                       clk);
+       err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get,
+                                    &data->hw);
        if (err) {
                dev_err(&client->dev, "unable to add clk provider\n");
                return err;
@@ -477,7 +476,7 @@ static int si570_probe(struct i2c_client *client,
        /* Read the requested initial output frequency from device tree */
        if (!of_property_read_u32(client->dev.of_node, "clock-frequency",
                                &initial_fout)) {
-               err = clk_set_rate(clk, initial_fout);
+               err = clk_set_rate(data->hw.clk, initial_fout);
                if (err) {
                        of_clk_del_provider(client->dev.of_node);
                        return err;
index 697c667..7b222a5 100644 (file)
 #include <linux/mfd/twl6040.h>
 #include <linux/clk-provider.h>
 
-struct twl6040_clk {
+struct twl6040_pdmclk {
        struct twl6040 *twl6040;
        struct device *dev;
-       struct clk_hw mcpdm_fclk;
-       struct clk *clk;
+       struct clk_hw pdmclk_hw;
        int enabled;
 };
 
-static int twl6040_bitclk_is_enabled(struct clk_hw *hw)
+static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
 {
-       struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
-                                                      mcpdm_fclk);
-       return twl6040_clk->enabled;
+       struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
+                                                    pdmclk_hw);
+
+       return pdmclk->enabled;
 }
 
-static int twl6040_bitclk_prepare(struct clk_hw *hw)
+static int twl6040_pdmclk_prepare(struct clk_hw *hw)
 {
-       struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
-                                                      mcpdm_fclk);
+       struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
+                                                    pdmclk_hw);
        int ret;
 
-       ret = twl6040_power(twl6040_clk->twl6040, 1);
+       ret = twl6040_power(pdmclk->twl6040, 1);
        if (!ret)
-               twl6040_clk->enabled = 1;
+               pdmclk->enabled = 1;
 
        return ret;
 }
 
-static void twl6040_bitclk_unprepare(struct clk_hw *hw)
+static void twl6040_pdmclk_unprepare(struct clk_hw *hw)
 {
-       struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk,
-                                                      mcpdm_fclk);
+       struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
+                                                    pdmclk_hw);
        int ret;
 
-       ret = twl6040_power(twl6040_clk->twl6040, 0);
+       ret = twl6040_power(pdmclk->twl6040, 0);
        if (!ret)
-               twl6040_clk->enabled = 0;
+               pdmclk->enabled = 0;
+
 }
 
-static const struct clk_ops twl6040_mcpdm_ops = {
-       .is_enabled = twl6040_bitclk_is_enabled,
-       .prepare = twl6040_bitclk_prepare,
-       .unprepare = twl6040_bitclk_unprepare,
+static unsigned long twl6040_pdmclk_recalc_rate(struct clk_hw *hw,
+                                               unsigned long parent_rate)
+{
+       struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
+                                                    pdmclk_hw);
+
+       return twl6040_get_sysclk(pdmclk->twl6040);
+}
+
+static const struct clk_ops twl6040_pdmclk_ops = {
+       .is_prepared = twl6040_pdmclk_is_prepared,
+       .prepare = twl6040_pdmclk_prepare,
+       .unprepare = twl6040_pdmclk_unprepare,
+       .recalc_rate = twl6040_pdmclk_recalc_rate,
 };
 
-static struct clk_init_data wm831x_clkout_init = {
-       .name = "mcpdm_fclk",
-       .ops = &twl6040_mcpdm_ops,
+static struct clk_init_data twl6040_pdmclk_init = {
+       .name = "pdmclk",
+       .ops = &twl6040_pdmclk_ops,
+       .flags = CLK_GET_RATE_NOCACHE,
 };
 
-static int twl6040_clk_probe(struct platform_device *pdev)
+static int twl6040_pdmclk_probe(struct platform_device *pdev)
 {
        struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent);
-       struct twl6040_clk *clkdata;
+       struct twl6040_pdmclk *clkdata;
+       int ret;
 
        clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
        if (!clkdata)
@@ -88,26 +101,28 @@ static int twl6040_clk_probe(struct platform_device *pdev)
        clkdata->dev = &pdev->dev;
        clkdata->twl6040 = twl6040;
 
-       clkdata->mcpdm_fclk.init = &wm831x_clkout_init;
-       clkdata->clk = devm_clk_register(&pdev->dev, &clkdata->mcpdm_fclk);
-       if (IS_ERR(clkdata->clk))
-               return PTR_ERR(clkdata->clk);
+       clkdata->pdmclk_hw.init = &twl6040_pdmclk_init;
+       ret = devm_clk_hw_register(&pdev->dev, &clkdata->pdmclk_hw);
+       if (ret)
+               return ret;
 
        platform_set_drvdata(pdev, clkdata);
 
-       return 0;
+       return of_clk_add_hw_provider(pdev->dev.parent->of_node,
+                                     of_clk_hw_simple_get,
+                                     &clkdata->pdmclk_hw);
 }
 
-static struct platform_driver twl6040_clk_driver = {
+static struct platform_driver twl6040_pdmclk_driver = {
        .driver = {
-               .name = "twl6040-clk",
+               .name = "twl6040-pdmclk",
        },
-       .probe = twl6040_clk_probe,
+       .probe = twl6040_pdmclk_probe,
 };
 
-module_platform_driver(twl6040_clk_driver);
+module_platform_driver(twl6040_pdmclk_driver);
 
 MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock");
 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
-MODULE_ALIAS("platform:twl6040-clk");
+MODULE_ALIAS("platform:twl6040-pdmclk");
 MODULE_LICENSE("GPL");
index 37368a3..4161a6f 100644 (file)
@@ -232,7 +232,7 @@ static const struct clk_ops vt8500_gated_divisor_clk_ops = {
 static __init void vtwm_device_clk_init(struct device_node *node)
 {
        u32 en_reg, div_reg;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_device *dev_clk;
        const char *clk_name = node->name;
        const char *parent_name;
@@ -301,13 +301,14 @@ static __init void vtwm_device_clk_init(struct device_node *node)
 
        dev_clk->hw.init = &init;
 
-       clk = clk_register(NULL, &dev_clk->hw);
-       if (WARN_ON(IS_ERR(clk))) {
+       hw = &dev_clk->hw;
+       rc = clk_hw_register(NULL, hw);
+       if (WARN_ON(rc)) {
                kfree(dev_clk);
                return;
        }
-       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
-       clk_register_clkdev(clk, clk_name, NULL);
+       rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
+       clk_hw_register_clkdev(hw, clk_name, NULL);
 }
 CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init);
 
@@ -681,7 +682,7 @@ static const struct clk_ops vtwm_pll_ops = {
 static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
 {
        u32 reg;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_pll *pll_clk;
        const char *clk_name = node->name;
        const char *parent_name;
@@ -714,13 +715,14 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type)
 
        pll_clk->hw.init = &init;
 
-       clk = clk_register(NULL, &pll_clk->hw);
-       if (WARN_ON(IS_ERR(clk))) {
+       hw = &pll_clk->hw;
+       rc = clk_hw_register(NULL, &pll_clk->hw);
+       if (WARN_ON(rc)) {
                kfree(pll_clk);
                return;
        }
-       rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
-       clk_register_clkdev(clk, clk_name, NULL);
+       rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
+       clk_hw_register_clkdev(hw, clk_name, NULL);
 }
 
 
index 88def4b..f4fdac5 100644 (file)
@@ -24,9 +24,6 @@ struct wm831x_clk {
        struct clk_hw xtal_hw;
        struct clk_hw fll_hw;
        struct clk_hw clkout_hw;
-       struct clk *xtal;
-       struct clk *fll;
-       struct clk *clkout;
        bool xtal_ena;
 };
 
@@ -370,19 +367,19 @@ static int wm831x_clk_probe(struct platform_device *pdev)
        clkdata->xtal_ena = ret & WM831X_XTAL_ENA;
 
        clkdata->xtal_hw.init = &wm831x_xtal_init;
-       clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw);
-       if (IS_ERR(clkdata->xtal))
-               return PTR_ERR(clkdata->xtal);
+       ret = devm_clk_hw_register(&pdev->dev, &clkdata->xtal_hw);
+       if (ret)
+               return ret;
 
        clkdata->fll_hw.init = &wm831x_fll_init;
-       clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw);
-       if (IS_ERR(clkdata->fll))
-               return PTR_ERR(clkdata->fll);
+       ret = devm_clk_hw_register(&pdev->dev, &clkdata->fll_hw);
+       if (ret)
+               return ret;
 
        clkdata->clkout_hw.init = &wm831x_clkout_init;
-       clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw);
-       if (IS_ERR(clkdata->clkout))
-               return PTR_ERR(clkdata->clkout);
+       ret = devm_clk_hw_register(&pdev->dev, &clkdata->clkout_hw);
+       if (ret)
+               return ret;
 
        platform_set_drvdata(pdev, clkdata);
 
index 820a939..0fb39fe 100644 (file)
@@ -1908,10 +1908,6 @@ int clk_set_phase(struct clk *clk, int degrees)
 
        clk_prepare_lock();
 
-       /* bail early if nothing to do */
-       if (degrees == clk->core->phase)
-               goto out;
-
        trace_clk_set_phase(clk->core, degrees);
 
        if (clk->core->ops->set_phase)
@@ -1922,7 +1918,6 @@ int clk_set_phase(struct clk *clk, int degrees)
        if (!ret)
                clk->core->phase = degrees;
 
-out:
        clk_prepare_unlock();
 
        return ret;
@@ -2449,8 +2444,16 @@ static int __clk_core_init(struct clk_core *core)
        hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
                struct clk_core *parent = __clk_init_parent(orphan);
 
-               if (parent)
-                       clk_core_reparent(orphan, parent);
+               /*
+                * we could call __clk_set_parent, but that would result in a
+                * redundant call to the .set_rate op, if it exists
+                */
+               if (parent) {
+                       __clk_set_parent_before(orphan, parent);
+                       __clk_set_parent_after(orphan, parent, NULL);
+                       __clk_recalc_accuracies(orphan);
+                       __clk_recalc_rates(orphan, 0);
+               }
        }
 
        /*
@@ -2491,7 +2494,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
 
        /* This is to allow this function to be chained to others */
        if (IS_ERR_OR_NULL(hw))
-               return (struct clk *) hw;
+               return ERR_CAST(hw);
 
        clk = kzalloc(sizeof(*clk), GFP_KERNEL);
        if (!clk)
@@ -3166,19 +3169,14 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider,
                              struct of_phandle_args *clkspec)
 {
        struct clk *clk;
-       struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
 
-       if (provider->get_hw) {
-               hw = provider->get_hw(clkspec, provider->data);
-       } else if (provider->get) {
-               clk = provider->get(clkspec, provider->data);
-               if (!IS_ERR(clk))
-                       hw = __clk_get_hw(clk);
-               else
-                       hw = ERR_CAST(clk);
-       }
+       if (provider->get_hw)
+               return provider->get_hw(clkspec, provider->data);
 
-       return hw;
+       clk = provider->get(clkspec, provider->data);
+       if (IS_ERR(clk))
+               return ERR_CAST(clk);
+       return __clk_get_hw(clk);
 }
 
 struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
@@ -3186,7 +3184,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
 {
        struct of_clk_provider *provider;
        struct clk *clk = ERR_PTR(-EPROBE_DEFER);
-       struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
+       struct clk_hw *hw;
 
        if (!clkspec)
                return ERR_PTR(-EINVAL);
@@ -3194,12 +3192,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
        /* Check if we have such a provider in our array */
        mutex_lock(&of_clk_mutex);
        list_for_each_entry(provider, &of_clk_providers, link) {
-               if (provider->node == clkspec->np)
+               if (provider->node == clkspec->np) {
                        hw = __of_clk_get_hw_from_provider(provider, clkspec);
-               if (!IS_ERR(hw)) {
                        clk = __clk_create_clk(hw, dev_id, con_id);
+               }
 
-                       if (!IS_ERR(clk) && !__clk_get(clk)) {
+               if (!IS_ERR(clk)) {
+                       if (!__clk_get(clk)) {
                                __clk_free_clk(clk);
                                clk = ERR_PTR(-ENOENT);
                        }
@@ -3451,6 +3450,10 @@ void __init of_clk_init(const struct of_device_id *matches)
                                        &clk_provider_list, node) {
                        if (force || parent_ready(clk_provider->np)) {
 
+                               /* Don't populate platform devices */
+                               of_node_set_flag(clk_provider->np,
+                                                OF_POPULATED);
+
                                clk_provider->clk_init_cb(clk_provider->np);
                                of_clk_set_defaults(clk_provider->np, true);
 
index 4bf44a2..715b882 100644 (file)
@@ -14,7 +14,7 @@ static DEFINE_SPINLOCK(clklock);
 static void __init h8300_div_clk_setup(struct device_node *node)
 {
        unsigned int num_parents;
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *clk_name = node->name;
        const char *parent_name;
        void __iomem *divcr = NULL;
@@ -38,15 +38,15 @@ static void __init h8300_div_clk_setup(struct device_node *node)
 
        parent_name = of_clk_get_parent_name(node, 0);
        of_property_read_u32(node, "renesas,width", &width);
-       clk = clk_register_divider(NULL, clk_name, parent_name,
+       hw = clk_hw_register_divider(NULL, clk_name, parent_name,
                                   CLK_SET_RATE_GATE, divcr, offset, width,
                                   CLK_DIVIDER_POWER_OF_TWO, &clklock);
-       if (!IS_ERR(clk)) {
-               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       if (!IS_ERR(hw)) {
+               of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
                return;
        }
        pr_err("%s: failed to register %s div clock (%ld)\n",
-              __func__, clk_name, PTR_ERR(clk));
+              __func__, clk_name, PTR_ERR(hw));
 error:
        if (divcr)
                iounmap(divcr);
index c9c2fd5..a263124 100644 (file)
@@ -84,11 +84,11 @@ static const struct clk_ops pll_ops = {
 static void __init h8s2678_pll_clk_setup(struct device_node *node)
 {
        unsigned int num_parents;
-       struct clk *clk;
        const char *clk_name = node->name;
        const char *parent_name;
        struct pll_clock *pll_clock;
        struct clk_init_data init;
+       int ret;
 
        num_parents = of_clk_get_parent_count(node);
        if (!num_parents) {
@@ -121,14 +121,14 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node)
        init.num_parents = 1;
        pll_clock->hw.init = &init;
 
-       clk = clk_register(NULL, &pll_clock->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: failed to register %s div clock (%ld)\n",
-                      __func__, clk_name, PTR_ERR(clk));
+       ret = clk_hw_register(NULL, &pll_clock->hw);
+       if (ret) {
+               pr_err("%s: failed to register %s div clock (%d)\n",
+                      __func__, clk_name, ret);
                goto unmap_pllcr;
        }
 
-       of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clock->hw);
        return;
 
 unmap_pllcr:
index 6ed4f8f..e7c7353 100644 (file)
 
 #include "clk.h"
 
+static u32 share_count_sai1;
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+
+static struct clk_div_table test_div_table[] = {
+       { .val = 3, .div = 1, },
+       { .val = 2, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 0, .div = 4, },
+       { }
+};
+
+static struct clk_div_table post_div_table[] = {
+       { .val = 3, .div = 4, },
+       { .val = 2, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 0, .div = 1, },
+       { }
+};
+
 static struct clk *clks[IMX7D_CLK_END];
 static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk",
        "pll_enet_500m_clk", "pll_dram_main_clk",
-       "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk",
+       "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_post_div",
        "pll_usb_main_clk", };
 
 static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
        "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk",
-       "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_usb_main_clk", };
 
 static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
        "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
-       "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_usb_main_clk", };
 
 static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
        "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", };
+       "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd7_clk", };
 
 static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
        "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk",
-       "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", };
+       "pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_main_clk", };
 
 static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
        "pll_dram_533m_clk", "pll_enet_250m_clk",
-       "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_sys_pfd4_clk", };
 
 static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
        "pll_dram_533m_clk", "pll_sys_main_240m_clk",
        "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk",
-       "pll_audio_main_clk", };
+       "pll_audio_post_div", };
 
 static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
        "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
-       "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk",
+       "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_post_div",
        "pll_video_main_clk", };
 
 static const char *dram_phym_sel[] = { "pll_dram_main_clk",
@@ -69,13 +89,13 @@ static const char *dram_sel[] = { "pll_dram_main_clk",
 
 static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
        "pll_sys_main_clk", "pll_enet_500m_clk",
-       "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk",
+       "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_post_div",
        "pll_video_main_clk", };
 
 static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk",
        "pll_sys_main_clk", "pll_enet_500m_clk",
        "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk",
-       "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", };
+       "pll_audio_post_div", "pll_sys_pfd2_270m_clk", };
 
 static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk",
        "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
@@ -101,53 +121,53 @@ static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk",
 
 static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk",
        "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
-       "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", };
+       "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", };
 
 static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk",
        "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk",
-       "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", };
+       "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", };
 
 static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk",
        "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2",
        "pll_video_main_clk", "ext_clk_3", };
 
 static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
-       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
        "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
 
 static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
-       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
        "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
 
 static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
-       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
        "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", };
 
 static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
-       "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk",
+       "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk",
        "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", };
 
 static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk",
        "pll_enet_50m_clk", "pll_enet_25m_clk",
-       "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "ext_clk_4", };
 
 static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
+       "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
        "ext_clk_4", "pll_video_main_clk", };
 
 static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk",
        "pll_enet_50m_clk", "pll_enet_25m_clk",
-       "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "ext_clk_4", };
 
 static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
+       "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
        "ext_clk_4", "pll_video_main_clk", };
 
 static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk",
        "pll_enet_50m_clk", "pll_enet_125m_clk",
-       "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_sys_pfd3_clk", };
 
 static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
@@ -188,22 +208,22 @@ static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk",
 
 static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk",
        "pll_enet_50m_clk", "pll_dram_533m_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
        "pll_sys_pfd2_135m_clk", };
 
 static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk",
        "pll_enet_50m_clk", "pll_dram_533m_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
        "pll_sys_pfd2_135m_clk", };
 
 static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk",
        "pll_enet_50m_clk", "pll_dram_533m_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
        "pll_sys_pfd2_135m_clk", };
 
 static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk",
        "pll_enet_50m_clk", "pll_dram_533m_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk",
+       "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk",
        "pll_sys_pfd2_135m_clk", };
 
 static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk",
@@ -262,32 +282,32 @@ static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk",
        "pll_usb_main_clk", };
 
 static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
        "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
 
 static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
        "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", };
 
 static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
        "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
 
 static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
        "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", };
 
 static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
        "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
 
 static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk",
-       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk",
+       "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
        "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", };
 
 static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
        "pll_sys_main_120m_clk", "pll_dram_533m_clk",
-       "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk",
+       "pll_usb_main_clk", "pll_audio_post_div", "pll_enet_125m_clk",
        "pll_sys_pfd7_clk", };
 
 static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
@@ -297,19 +317,19 @@ static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
 
 static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk",
        "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
-       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", };
+       "ref_1m_clk", "pll_audio_post_div", "ext_clk_1", };
 
 static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk",
        "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
-       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", };
+       "ref_1m_clk", "pll_audio_post_div", "ext_clk_2", };
 
 static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk",
        "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
-       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", };
+       "ref_1m_clk", "pll_audio_post_div", "ext_clk_3", };
 
 static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk",
        "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk",
-       "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", };
+       "ref_1m_clk", "pll_audio_post_div", "ext_clk_4", };
 
 static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
        "pll_sys_main_120m_clk", "pll_dram_533m_clk",
@@ -323,12 +343,12 @@ static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
 
 static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
        "pll_sys_main_120m_clk", "pll_dram_533m_clk",
-       "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_usb_main_clk", };
 
 static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
        "pll_sys_main_120m_clk", "pll_dram_533m_clk",
-       "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk",
+       "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk",
        "pll_usb_main_clk", };
 
 static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk",
@@ -342,13 +362,13 @@ static const char *clko1_sel[] = { "osc", "pll_sys_main_clk",
 
 static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
        "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "ckil", };
+       "pll_audio_post_div", "pll_video_main_clk", "ckil", };
 
 static const char *lvds1_sel[] = { "pll_arm_main_clk",
        "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
        "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
        "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk",
-       "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk",
+       "pll_audio_post_div", "pll_video_main_clk", "pll_enet_500m_clk",
        "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk",
        "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk",
        "pll_dram_main_clk", };
@@ -430,6 +450,11 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13);
        clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13);
 
+       clks[IMX7D_PLL_AUDIO_TEST_DIV]  = clk_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_clk",
+                               CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 19, 2, 0, test_div_table, &imx_ccm_lock);
+       clks[IMX7D_PLL_AUDIO_POST_DIV] = clk_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_test_div",
+                               CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 22, 2, 0, post_div_table, &imx_ccm_lock);
+
        clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0);
        clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1);
        clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2);
@@ -779,6 +804,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
        clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
        clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
+       clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
        clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
        clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
        clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
@@ -786,9 +812,12 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
        clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
        clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
-       clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate4("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0);
-       clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate4("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0);
-       clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate4("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0);
+       clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
+       clks[IMX7D_SAI1_IPG_CLK]  = imx_clk_gate2_shared2("sai1_ipg_clk",  "ipg_root_clk",  base + 0x48c0, 0, &share_count_sai1);
+       clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2);
+       clks[IMX7D_SAI2_IPG_CLK]  = imx_clk_gate2_shared2("sai2_ipg_clk",  "ipg_root_clk",  base + 0x48d0, 0, &share_count_sai2);
+       clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
+       clks[IMX7D_SAI3_IPG_CLK]  = imx_clk_gate2_shared2("sai3_ipg_clk",  "ipg_root_clk",  base + 0x48e0, 0, &share_count_sai3);
        clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
        clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
        clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
@@ -860,8 +889,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
        /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
        clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
 
-       clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]);
-
        /* set uart module clock's parent clock source that must be great then 80MHz */
        clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
 
index a81c038..3799ff8 100644 (file)
@@ -134,6 +134,15 @@ static inline struct clk *imx_clk_gate2_shared(const char *name,
                        shift, 0x3, 0, &imx_ccm_lock, share_count);
 }
 
+static inline struct clk *imx_clk_gate2_shared2(const char *name,
+               const char *parent, void __iomem *reg, u8 shift,
+               unsigned int *share_count)
+{
+       return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
+                                 CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0,
+                                 &imx_ccm_lock, share_count);
+}
+
 static inline struct clk *imx_clk_gate2_cgr(const char *name,
                const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
 {
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
new file mode 100644 (file)
index 0000000..380c372
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# MediaTek SoC drivers
+#
+config COMMON_CLK_MEDIATEK
+       bool
+       ---help---
+         Mediatek SoCs' clock support.
+
+config COMMON_CLK_MT8135
+       bool "Clock driver for Mediatek MT8135"
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       ---help---
+         This driver supports Mediatek MT8135 clocks.
+
+config COMMON_CLK_MT8173
+       bool "Clock driver for Mediatek MT8173"
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK
+       ---help---
+         This driver supports Mediatek MT8173 clocks.
index 95fdfac..32e7222 100644 (file)
@@ -1,4 +1,4 @@
-obj-y += 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
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
-obj-y += clk-mt8135.o
-obj-y += clk-mt8173.o
+obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
+obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
index 2a76901..d8787bf 100644 (file)
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
        .disable        = mtk_cg_disable_inv,
 };
 
-struct clk * __init mtk_clk_register_gate(
+struct clk *mtk_clk_register_gate(
                const char *name,
                const char *parent_name,
                struct regmap *regmap,
index 5ada644..bb30f70 100644 (file)
@@ -24,7 +24,7 @@
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num)
+struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
 {
        int i;
        struct clk_onecell_data *clk_data;
@@ -49,7 +49,7 @@ err_out:
        return NULL;
 }
 
-void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
                int num, struct clk_onecell_data *clk_data)
 {
        int i;
@@ -72,7 +72,7 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
        }
 }
 
-void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
                int num, struct clk_onecell_data *clk_data)
 {
        int i;
@@ -95,7 +95,7 @@ void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
        }
 }
 
-int __init mtk_clk_register_gates(struct device_node *node,
+int mtk_clk_register_gates(struct device_node *node,
                const struct mtk_gate *clks,
                int num, struct clk_onecell_data *clk_data)
 {
@@ -135,7 +135,7 @@ int __init mtk_clk_register_gates(struct device_node *node,
        return 0;
 }
 
-struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc,
+struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
                void __iomem *base, spinlock_t *lock)
 {
        struct clk *clk;
@@ -222,7 +222,7 @@ err_out:
        return ERR_PTR(ret);
 }
 
-void __init mtk_clk_register_composites(const struct mtk_composite *mcs,
+void mtk_clk_register_composites(const struct mtk_composite *mcs,
                int num, void __iomem *base, spinlock_t *lock,
                struct clk_onecell_data *clk_data)
 {
index 966cab1..0c2deac 100644 (file)
@@ -313,7 +313,7 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
        return clk;
 }
 
-void __init mtk_clk_register_plls(struct device_node *node,
+void mtk_clk_register_plls(struct device_node *node,
                const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
 {
        void __iomem *base;
index 197e401..3495834 100644 (file)
@@ -3,5 +3,5 @@
 #
 
 obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o
-obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b-clkc.o
-obj-$(CONFIG_COMMON_CLK_GXBB)   += gxbb.o
+obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
+obj-$(CONFIG_COMMON_CLK_GXBB)   += gxbb.o gxbb-aoclk.o
index 53326c3..9bb70e7 100644 (file)
@@ -98,7 +98,7 @@ struct meson_clk_mpll {
 };
 
 #define MESON_GATE(_name, _reg, _bit)                                  \
-struct clk_gate gxbb_##_name = {                                               \
+struct clk_gate _name = {                                              \
        .reg = (void __iomem *) _reg,                                   \
        .bit_idx = (_bit),                                              \
        .lock = &clk_lock,                                              \
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
new file mode 100644 (file)
index 0000000..b45c5fb
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/init.h>
+#include <dt-bindings/clock/gxbb-aoclkc.h>
+#include <dt-bindings/reset/gxbb-aoclkc.h>
+
+static DEFINE_SPINLOCK(gxbb_aoclk_lock);
+
+struct gxbb_aoclk_reset_controller {
+       struct reset_controller_dev reset;
+       unsigned int *data;
+       void __iomem *base;
+};
+
+static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev,
+                              unsigned long id)
+{
+       struct gxbb_aoclk_reset_controller *reset =
+               container_of(rcdev, struct gxbb_aoclk_reset_controller, reset);
+
+       writel(BIT(reset->data[id]), reset->base);
+
+       return 0;
+}
+
+static const struct reset_control_ops gxbb_aoclk_reset_ops = {
+       .reset = gxbb_aoclk_do_reset,
+};
+
+#define GXBB_AO_GATE(_name, _bit)                                      \
+static struct clk_gate _name##_ao = {                                  \
+       .reg = (void __iomem *)0,                                       \
+       .bit_idx = (_bit),                                              \
+       .lock = &gxbb_aoclk_lock,                                       \
+       .hw.init = &(struct clk_init_data) {                            \
+               .name = #_name "_ao",                                   \
+               .ops = &clk_gate_ops,                                   \
+               .parent_names = (const char *[]){ "clk81" },            \
+               .num_parents = 1,                                       \
+               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),     \
+       },                                                              \
+}
+
+GXBB_AO_GATE(remote, 0);
+GXBB_AO_GATE(i2c_master, 1);
+GXBB_AO_GATE(i2c_slave, 2);
+GXBB_AO_GATE(uart1, 3);
+GXBB_AO_GATE(uart2, 5);
+GXBB_AO_GATE(ir_blaster, 6);
+
+static unsigned int gxbb_aoclk_reset[] = {
+       [RESET_AO_REMOTE] = 16,
+       [RESET_AO_I2C_MASTER] = 18,
+       [RESET_AO_I2C_SLAVE] = 19,
+       [RESET_AO_UART1] = 17,
+       [RESET_AO_UART2] = 22,
+       [RESET_AO_IR_BLASTER] = 23,
+};
+
+static struct clk_gate *gxbb_aoclk_gate[] = {
+       [CLKID_AO_REMOTE] = &remote_ao,
+       [CLKID_AO_I2C_MASTER] = &i2c_master_ao,
+       [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao,
+       [CLKID_AO_UART1] = &uart1_ao,
+       [CLKID_AO_UART2] = &uart2_ao,
+       [CLKID_AO_IR_BLASTER] = &ir_blaster_ao,
+};
+
+static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
+       .hws = {
+               [CLKID_AO_REMOTE] = &remote_ao.hw,
+               [CLKID_AO_I2C_MASTER] = &i2c_master_ao.hw,
+               [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao.hw,
+               [CLKID_AO_UART1] = &uart1_ao.hw,
+               [CLKID_AO_UART2] = &uart2_ao.hw,
+               [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw,
+       },
+       .num = ARRAY_SIZE(gxbb_aoclk_gate),
+};
+
+static int gxbb_aoclkc_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       void __iomem *base;
+       int ret, clkid;
+       struct device *dev = &pdev->dev;
+       struct gxbb_aoclk_reset_controller *rstc;
+
+       rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL);
+       if (!rstc)
+               return -ENOMEM;
+
+       /* Generic clocks */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       /* Reset Controller */
+       rstc->base = base;
+       rstc->data = gxbb_aoclk_reset;
+       rstc->reset.ops = &gxbb_aoclk_reset_ops;
+       rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset);
+       rstc->reset.of_node = dev->of_node;
+       ret = devm_reset_controller_register(dev, &rstc->reset);
+
+       /*
+        * Populate base address and register all clks
+        */
+       for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) {
+               gxbb_aoclk_gate[clkid]->reg = base;
+
+               ret = devm_clk_hw_register(dev,
+                                       gxbb_aoclk_onecell_data.hws[clkid]);
+               if (ret)
+                       return ret;
+       }
+
+       return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
+                       &gxbb_aoclk_onecell_data);
+}
+
+static const struct of_device_id gxbb_aoclkc_match_table[] = {
+       { .compatible = "amlogic,gxbb-aoclkc" },
+       { }
+};
+
+static struct platform_driver gxbb_aoclkc_driver = {
+       .probe          = gxbb_aoclkc_probe,
+       .driver         = {
+               .name   = "gxbb-aoclkc",
+               .of_match_table = gxbb_aoclkc_match_table,
+       },
+};
+builtin_platform_driver(gxbb_aoclkc_driver);
index a4c6684..9d9af44 100644 (file)
@@ -565,90 +565,93 @@ static struct clk_gate gxbb_clk81 = {
 };
 
 /* Everything Else (EE) domain gates */
-static MESON_GATE(ddr, HHI_GCLK_MPEG0, 0);
-static MESON_GATE(dos, HHI_GCLK_MPEG0, 1);
-static MESON_GATE(isa, HHI_GCLK_MPEG0, 5);
-static MESON_GATE(pl301, HHI_GCLK_MPEG0, 6);
-static MESON_GATE(periphs, HHI_GCLK_MPEG0, 7);
-static MESON_GATE(spicc, HHI_GCLK_MPEG0, 8);
-static MESON_GATE(i2c, HHI_GCLK_MPEG0, 9);
-static MESON_GATE(sar_adc, HHI_GCLK_MPEG0, 10);
-static MESON_GATE(smart_card, HHI_GCLK_MPEG0, 11);
-static MESON_GATE(rng0, HHI_GCLK_MPEG0, 12);
-static MESON_GATE(uart0, HHI_GCLK_MPEG0, 13);
-static MESON_GATE(sdhc, HHI_GCLK_MPEG0, 14);
-static MESON_GATE(stream, HHI_GCLK_MPEG0, 15);
-static MESON_GATE(async_fifo, HHI_GCLK_MPEG0, 16);
-static MESON_GATE(sdio, HHI_GCLK_MPEG0, 17);
-static MESON_GATE(abuf, HHI_GCLK_MPEG0, 18);
-static MESON_GATE(hiu_iface, HHI_GCLK_MPEG0, 19);
-static MESON_GATE(assist_misc, HHI_GCLK_MPEG0, 23);
-static MESON_GATE(spi, HHI_GCLK_MPEG0, 30);
-
-static MESON_GATE(i2s_spdif, HHI_GCLK_MPEG1, 2);
-static MESON_GATE(eth, HHI_GCLK_MPEG1, 3);
-static MESON_GATE(demux, HHI_GCLK_MPEG1, 4);
-static MESON_GATE(aiu_glue, HHI_GCLK_MPEG1, 6);
-static MESON_GATE(iec958, HHI_GCLK_MPEG1, 7);
-static MESON_GATE(i2s_out, HHI_GCLK_MPEG1, 8);
-static MESON_GATE(amclk, HHI_GCLK_MPEG1, 9);
-static MESON_GATE(aififo2, HHI_GCLK_MPEG1, 10);
-static MESON_GATE(mixer, HHI_GCLK_MPEG1, 11);
-static MESON_GATE(mixer_iface, HHI_GCLK_MPEG1, 12);
-static MESON_GATE(adc, HHI_GCLK_MPEG1, 13);
-static MESON_GATE(blkmv, HHI_GCLK_MPEG1, 14);
-static MESON_GATE(aiu, HHI_GCLK_MPEG1, 15);
-static MESON_GATE(uart1, HHI_GCLK_MPEG1, 16);
-static MESON_GATE(g2d, HHI_GCLK_MPEG1, 20);
-static MESON_GATE(usb0, HHI_GCLK_MPEG1, 21);
-static MESON_GATE(usb1, HHI_GCLK_MPEG1, 22);
-static MESON_GATE(reset, HHI_GCLK_MPEG1, 23);
-static MESON_GATE(nand, HHI_GCLK_MPEG1, 24);
-static MESON_GATE(dos_parser, HHI_GCLK_MPEG1, 25);
-static MESON_GATE(usb, HHI_GCLK_MPEG1, 26);
-static MESON_GATE(vdin1, HHI_GCLK_MPEG1, 28);
-static MESON_GATE(ahb_arb0, HHI_GCLK_MPEG1, 29);
-static MESON_GATE(efuse, HHI_GCLK_MPEG1, 30);
-static MESON_GATE(boot_rom, HHI_GCLK_MPEG1, 31);
-
-static MESON_GATE(ahb_data_bus, HHI_GCLK_MPEG2, 1);
-static MESON_GATE(ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
-static MESON_GATE(hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
-static MESON_GATE(hdmi_pclk, HHI_GCLK_MPEG2, 4);
-static MESON_GATE(usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
-static MESON_GATE(usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
-static MESON_GATE(mmc_pclk, HHI_GCLK_MPEG2, 11);
-static MESON_GATE(dvin, HHI_GCLK_MPEG2, 12);
-static MESON_GATE(uart2, HHI_GCLK_MPEG2, 15);
-static MESON_GATE(sana, HHI_GCLK_MPEG2, 22);
-static MESON_GATE(vpu_intr, HHI_GCLK_MPEG2, 25);
-static MESON_GATE(sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
-static MESON_GATE(clk81_a53, HHI_GCLK_MPEG2, 29);
-
-static MESON_GATE(vclk2_venci0, HHI_GCLK_OTHER, 1);
-static MESON_GATE(vclk2_venci1, HHI_GCLK_OTHER, 2);
-static MESON_GATE(vclk2_vencp0, HHI_GCLK_OTHER, 3);
-static MESON_GATE(vclk2_vencp1, HHI_GCLK_OTHER, 4);
-static MESON_GATE(gclk_venci_int0, HHI_GCLK_OTHER, 8);
-static MESON_GATE(gclk_vencp_int, HHI_GCLK_OTHER, 9);
-static MESON_GATE(dac_clk, HHI_GCLK_OTHER, 10);
-static MESON_GATE(aoclk_gate, HHI_GCLK_OTHER, 14);
-static MESON_GATE(iec958_gate, HHI_GCLK_OTHER, 16);
-static MESON_GATE(enc480p, HHI_GCLK_OTHER, 20);
-static MESON_GATE(rng1, HHI_GCLK_OTHER, 21);
-static MESON_GATE(gclk_venci_int1, HHI_GCLK_OTHER, 22);
-static MESON_GATE(vclk2_venclmcc, HHI_GCLK_OTHER, 24);
-static MESON_GATE(vclk2_vencl, HHI_GCLK_OTHER, 25);
-static MESON_GATE(vclk_other, HHI_GCLK_OTHER, 26);
-static MESON_GATE(edp, HHI_GCLK_OTHER, 31);
+static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
+static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
+static MESON_GATE(gxbb_isa, HHI_GCLK_MPEG0, 5);
+static MESON_GATE(gxbb_pl301, HHI_GCLK_MPEG0, 6);
+static MESON_GATE(gxbb_periphs, HHI_GCLK_MPEG0, 7);
+static MESON_GATE(gxbb_spicc, HHI_GCLK_MPEG0, 8);
+static MESON_GATE(gxbb_i2c, HHI_GCLK_MPEG0, 9);
+static MESON_GATE(gxbb_sar_adc, HHI_GCLK_MPEG0, 10);
+static MESON_GATE(gxbb_smart_card, HHI_GCLK_MPEG0, 11);
+static MESON_GATE(gxbb_rng0, HHI_GCLK_MPEG0, 12);
+static MESON_GATE(gxbb_uart0, HHI_GCLK_MPEG0, 13);
+static MESON_GATE(gxbb_sdhc, HHI_GCLK_MPEG0, 14);
+static MESON_GATE(gxbb_stream, HHI_GCLK_MPEG0, 15);
+static MESON_GATE(gxbb_async_fifo, HHI_GCLK_MPEG0, 16);
+static MESON_GATE(gxbb_sdio, HHI_GCLK_MPEG0, 17);
+static MESON_GATE(gxbb_abuf, HHI_GCLK_MPEG0, 18);
+static MESON_GATE(gxbb_hiu_iface, HHI_GCLK_MPEG0, 19);
+static MESON_GATE(gxbb_assist_misc, HHI_GCLK_MPEG0, 23);
+static MESON_GATE(gxbb_emmc_a, HHI_GCLK_MPEG0, 24);
+static MESON_GATE(gxbb_emmc_b, HHI_GCLK_MPEG0, 25);
+static MESON_GATE(gxbb_emmc_c, HHI_GCLK_MPEG0, 26);
+static MESON_GATE(gxbb_spi, HHI_GCLK_MPEG0, 30);
+
+static MESON_GATE(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2);
+static MESON_GATE(gxbb_eth, HHI_GCLK_MPEG1, 3);
+static MESON_GATE(gxbb_demux, HHI_GCLK_MPEG1, 4);
+static MESON_GATE(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6);
+static MESON_GATE(gxbb_iec958, HHI_GCLK_MPEG1, 7);
+static MESON_GATE(gxbb_i2s_out, HHI_GCLK_MPEG1, 8);
+static MESON_GATE(gxbb_amclk, HHI_GCLK_MPEG1, 9);
+static MESON_GATE(gxbb_aififo2, HHI_GCLK_MPEG1, 10);
+static MESON_GATE(gxbb_mixer, HHI_GCLK_MPEG1, 11);
+static MESON_GATE(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12);
+static MESON_GATE(gxbb_adc, HHI_GCLK_MPEG1, 13);
+static MESON_GATE(gxbb_blkmv, HHI_GCLK_MPEG1, 14);
+static MESON_GATE(gxbb_aiu, HHI_GCLK_MPEG1, 15);
+static MESON_GATE(gxbb_uart1, HHI_GCLK_MPEG1, 16);
+static MESON_GATE(gxbb_g2d, HHI_GCLK_MPEG1, 20);
+static MESON_GATE(gxbb_usb0, HHI_GCLK_MPEG1, 21);
+static MESON_GATE(gxbb_usb1, HHI_GCLK_MPEG1, 22);
+static MESON_GATE(gxbb_reset, HHI_GCLK_MPEG1, 23);
+static MESON_GATE(gxbb_nand, HHI_GCLK_MPEG1, 24);
+static MESON_GATE(gxbb_dos_parser, HHI_GCLK_MPEG1, 25);
+static MESON_GATE(gxbb_usb, HHI_GCLK_MPEG1, 26);
+static MESON_GATE(gxbb_vdin1, HHI_GCLK_MPEG1, 28);
+static MESON_GATE(gxbb_ahb_arb0, HHI_GCLK_MPEG1, 29);
+static MESON_GATE(gxbb_efuse, HHI_GCLK_MPEG1, 30);
+static MESON_GATE(gxbb_boot_rom, HHI_GCLK_MPEG1, 31);
+
+static MESON_GATE(gxbb_ahb_data_bus, HHI_GCLK_MPEG2, 1);
+static MESON_GATE(gxbb_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
+static MESON_GATE(gxbb_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
+static MESON_GATE(gxbb_hdmi_pclk, HHI_GCLK_MPEG2, 4);
+static MESON_GATE(gxbb_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
+static MESON_GATE(gxbb_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
+static MESON_GATE(gxbb_mmc_pclk, HHI_GCLK_MPEG2, 11);
+static MESON_GATE(gxbb_dvin, HHI_GCLK_MPEG2, 12);
+static MESON_GATE(gxbb_uart2, HHI_GCLK_MPEG2, 15);
+static MESON_GATE(gxbb_sana, HHI_GCLK_MPEG2, 22);
+static MESON_GATE(gxbb_vpu_intr, HHI_GCLK_MPEG2, 25);
+static MESON_GATE(gxbb_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
+static MESON_GATE(gxbb_clk81_a53, HHI_GCLK_MPEG2, 29);
+
+static MESON_GATE(gxbb_vclk2_venci0, HHI_GCLK_OTHER, 1);
+static MESON_GATE(gxbb_vclk2_venci1, HHI_GCLK_OTHER, 2);
+static MESON_GATE(gxbb_vclk2_vencp0, HHI_GCLK_OTHER, 3);
+static MESON_GATE(gxbb_vclk2_vencp1, HHI_GCLK_OTHER, 4);
+static MESON_GATE(gxbb_gclk_venci_int0, HHI_GCLK_OTHER, 8);
+static MESON_GATE(gxbb_gclk_vencp_int, HHI_GCLK_OTHER, 9);
+static MESON_GATE(gxbb_dac_clk, HHI_GCLK_OTHER, 10);
+static MESON_GATE(gxbb_aoclk_gate, HHI_GCLK_OTHER, 14);
+static MESON_GATE(gxbb_iec958_gate, HHI_GCLK_OTHER, 16);
+static MESON_GATE(gxbb_enc480p, HHI_GCLK_OTHER, 20);
+static MESON_GATE(gxbb_rng1, HHI_GCLK_OTHER, 21);
+static MESON_GATE(gxbb_gclk_venci_int1, HHI_GCLK_OTHER, 22);
+static MESON_GATE(gxbb_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
+static MESON_GATE(gxbb_vclk2_vencl, HHI_GCLK_OTHER, 25);
+static MESON_GATE(gxbb_vclk_other, HHI_GCLK_OTHER, 26);
+static MESON_GATE(gxbb_edp, HHI_GCLK_OTHER, 31);
 
 /* Always On (AO) domain gates */
 
-static MESON_GATE(ao_media_cpu, HHI_GCLK_AO, 0);
-static MESON_GATE(ao_ahb_sram, HHI_GCLK_AO, 1);
-static MESON_GATE(ao_ahb_bus, HHI_GCLK_AO, 2);
-static MESON_GATE(ao_iface, HHI_GCLK_AO, 3);
-static MESON_GATE(ao_i2c, HHI_GCLK_AO, 4);
+static MESON_GATE(gxbb_ao_media_cpu, HHI_GCLK_AO, 0);
+static MESON_GATE(gxbb_ao_ahb_sram, HHI_GCLK_AO, 1);
+static MESON_GATE(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2);
+static MESON_GATE(gxbb_ao_iface, HHI_GCLK_AO, 3);
+static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4);
 
 /* Array of all clocks provided by this provider */
 
@@ -748,6 +751,9 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
                [CLKID_AO_AHB_BUS]          = &gxbb_ao_ahb_bus.hw,
                [CLKID_AO_IFACE]            = &gxbb_ao_iface.hw,
                [CLKID_AO_I2C]              = &gxbb_ao_i2c.hw,
+               [CLKID_SD_EMMC_A]           = &gxbb_emmc_a.hw,
+               [CLKID_SD_EMMC_B]           = &gxbb_emmc_b.hw,
+               [CLKID_SD_EMMC_C]           = &gxbb_emmc_c.hw,
        },
        .num = NR_CLKS,
 };
@@ -847,6 +853,9 @@ static struct clk_gate *gxbb_clk_gates[] = {
        &gxbb_ao_ahb_bus,
        &gxbb_ao_iface,
        &gxbb_ao_i2c,
+       &gxbb_emmc_a,
+       &gxbb_emmc_b,
+       &gxbb_emmc_c,
 };
 
 static int gxbb_clkc_probe(struct platform_device *pdev)
@@ -937,8 +946,4 @@ static struct platform_driver gxbb_driver = {
        },
 };
 
-static int __init gxbb_clkc_init(void)
-{
-       return platform_driver_register(&gxbb_driver);
-}
-device_initcall(gxbb_clkc_init);
+builtin_platform_driver(gxbb_driver);
index a2adf34..ae461b1 100644 (file)
  */
 #define CLKID_SYS_PLL            0
 /* CLKID_CPUCLK */
-#define CLKID_HDMI_PLL           2
+/* CLKID_HDMI_PLL */
 #define CLKID_FIXED_PLL                  3
-#define CLKID_FCLK_DIV2                  4
-#define CLKID_FCLK_DIV3                  5
-#define CLKID_FCLK_DIV4                  6
+/* CLKID_FCLK_DIV2 */
+/* CLKID_FCLK_DIV3 */
+/* CLKID_FCLK_DIV4 */
 #define CLKID_FCLK_DIV5                  7
 #define CLKID_FCLK_DIV7                  8
 #define CLKID_GP0_PLL            9
 #define CLKID_AO_AHB_BUS         91
 #define CLKID_AO_IFACE           92
 #define CLKID_AO_I2C             93
+/* CLKID_SD_EMMC_A */
+/* CLKID_SD_EMMC_B */
+/* CLKID_SD_EMMC_C */
 
-#define NR_CLKS                          94
+#define NR_CLKS                          97
 
 /* include the CLKIDs that have been made part of the stable DT binding */
 #include <dt-bindings/clock/gxbb-clkc.h>
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
deleted file mode 100644 (file)
index 4c9413c..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * AmLogic S805 / Meson8b Clock Controller Driver
- *
- * Copyright (c) 2015 Endless Mobile, Inc.
- * Author: Carlo Caione <carlo@endlessm.com>
- *
- * Copyright (c) 2016 BayLibre, Inc.
- * Michael Turquette <mturquette@baylibre.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/clk-provider.h>
-#include <linux/of_address.h>
-#include <dt-bindings/clock/meson8b-clkc.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-
-#include "clkc.h"
-
-/*
- * Clock controller register offsets
- *
- * Register offsets from the HardKernel[0] data sheet are listed in comment
- * blocks below. Those offsets must be multiplied by 4 before adding them to
- * the base address to get the right value
- *
- * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
- */
-#define MESON8B_REG_SYS_CPU_CNTL1      0x015c /* 0x57 offset in data sheet */
-#define MESON8B_REG_HHI_MPEG           0x0174 /* 0x5d offset in data sheet */
-#define MESON8B_REG_MALI               0x01b0 /* 0x6c offset in data sheet */
-#define MESON8B_REG_PLL_FIXED          0x0280
-#define MESON8B_REG_PLL_SYS            0x0300
-#define MESON8B_REG_PLL_VID            0x0320
-
-static DEFINE_SPINLOCK(clk_lock);
-
-static const struct pll_rate_table sys_pll_rate_table[] = {
-       PLL_RATE(312000000, 52, 1, 2),
-       PLL_RATE(336000000, 56, 1, 2),
-       PLL_RATE(360000000, 60, 1, 2),
-       PLL_RATE(384000000, 64, 1, 2),
-       PLL_RATE(408000000, 68, 1, 2),
-       PLL_RATE(432000000, 72, 1, 2),
-       PLL_RATE(456000000, 76, 1, 2),
-       PLL_RATE(480000000, 80, 1, 2),
-       PLL_RATE(504000000, 84, 1, 2),
-       PLL_RATE(528000000, 88, 1, 2),
-       PLL_RATE(552000000, 92, 1, 2),
-       PLL_RATE(576000000, 96, 1, 2),
-       PLL_RATE(600000000, 50, 1, 1),
-       PLL_RATE(624000000, 52, 1, 1),
-       PLL_RATE(648000000, 54, 1, 1),
-       PLL_RATE(672000000, 56, 1, 1),
-       PLL_RATE(696000000, 58, 1, 1),
-       PLL_RATE(720000000, 60, 1, 1),
-       PLL_RATE(744000000, 62, 1, 1),
-       PLL_RATE(768000000, 64, 1, 1),
-       PLL_RATE(792000000, 66, 1, 1),
-       PLL_RATE(816000000, 68, 1, 1),
-       PLL_RATE(840000000, 70, 1, 1),
-       PLL_RATE(864000000, 72, 1, 1),
-       PLL_RATE(888000000, 74, 1, 1),
-       PLL_RATE(912000000, 76, 1, 1),
-       PLL_RATE(936000000, 78, 1, 1),
-       PLL_RATE(960000000, 80, 1, 1),
-       PLL_RATE(984000000, 82, 1, 1),
-       PLL_RATE(1008000000, 84, 1, 1),
-       PLL_RATE(1032000000, 86, 1, 1),
-       PLL_RATE(1056000000, 88, 1, 1),
-       PLL_RATE(1080000000, 90, 1, 1),
-       PLL_RATE(1104000000, 92, 1, 1),
-       PLL_RATE(1128000000, 94, 1, 1),
-       PLL_RATE(1152000000, 96, 1, 1),
-       PLL_RATE(1176000000, 98, 1, 1),
-       PLL_RATE(1200000000, 50, 1, 0),
-       PLL_RATE(1224000000, 51, 1, 0),
-       PLL_RATE(1248000000, 52, 1, 0),
-       PLL_RATE(1272000000, 53, 1, 0),
-       PLL_RATE(1296000000, 54, 1, 0),
-       PLL_RATE(1320000000, 55, 1, 0),
-       PLL_RATE(1344000000, 56, 1, 0),
-       PLL_RATE(1368000000, 57, 1, 0),
-       PLL_RATE(1392000000, 58, 1, 0),
-       PLL_RATE(1416000000, 59, 1, 0),
-       PLL_RATE(1440000000, 60, 1, 0),
-       PLL_RATE(1464000000, 61, 1, 0),
-       PLL_RATE(1488000000, 62, 1, 0),
-       PLL_RATE(1512000000, 63, 1, 0),
-       PLL_RATE(1536000000, 64, 1, 0),
-       { /* 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 clk_fixed_rate meson8b_xtal = {
-       .fixed_rate = 24000000,
-       .hw.init = &(struct clk_init_data){
-               .name = "xtal",
-               .num_parents = 0,
-               .ops = &clk_fixed_rate_ops,
-       },
-};
-
-static struct meson_clk_pll meson8b_fixed_pll = {
-       .m = {
-               .reg_off = MESON8B_REG_PLL_FIXED,
-               .shift   = 0,
-               .width   = 9,
-       },
-       .n = {
-               .reg_off = MESON8B_REG_PLL_FIXED,
-               .shift   = 9,
-               .width   = 5,
-       },
-       .od = {
-               .reg_off = MESON8B_REG_PLL_FIXED,
-               .shift   = 16,
-               .width   = 2,
-       },
-       .lock = &clk_lock,
-       .hw.init = &(struct clk_init_data){
-               .name = "fixed_pll",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
-               .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
-       },
-};
-
-static struct meson_clk_pll meson8b_vid_pll = {
-       .m = {
-               .reg_off = MESON8B_REG_PLL_VID,
-               .shift   = 0,
-               .width   = 9,
-       },
-       .n = {
-               .reg_off = MESON8B_REG_PLL_VID,
-               .shift   = 9,
-               .width   = 5,
-       },
-       .od = {
-               .reg_off = MESON8B_REG_PLL_VID,
-               .shift   = 16,
-               .width   = 2,
-       },
-       .lock = &clk_lock,
-       .hw.init = &(struct clk_init_data){
-               .name = "vid_pll",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
-               .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
-       },
-};
-
-static struct meson_clk_pll meson8b_sys_pll = {
-       .m = {
-               .reg_off = MESON8B_REG_PLL_SYS,
-               .shift   = 0,
-               .width   = 9,
-       },
-       .n = {
-               .reg_off = MESON8B_REG_PLL_SYS,
-               .shift   = 9,
-               .width   = 5,
-       },
-       .od = {
-               .reg_off = MESON8B_REG_PLL_SYS,
-               .shift   = 16,
-               .width   = 2,
-       },
-       .rate_table = sys_pll_rate_table,
-       .rate_count = ARRAY_SIZE(sys_pll_rate_table),
-       .lock = &clk_lock,
-       .hw.init = &(struct clk_init_data){
-               .name = "sys_pll",
-               .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ "xtal" },
-               .num_parents = 1,
-               .flags = CLK_GET_RATE_NOCACHE,
-       },
-};
-
-static struct clk_fixed_factor meson8b_fclk_div2 = {
-       .mult = 1,
-       .div = 2,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div2",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_fixed_factor meson8b_fclk_div3 = {
-       .mult = 1,
-       .div = 3,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div3",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_fixed_factor meson8b_fclk_div4 = {
-       .mult = 1,
-       .div = 4,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div4",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_fixed_factor meson8b_fclk_div5 = {
-       .mult = 1,
-       .div = 5,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div5",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_fixed_factor meson8b_fclk_div7 = {
-       .mult = 1,
-       .div = 7,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div7",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-/*
- * 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
- */
-static struct meson_clk_cpu meson8b_cpu_clk = {
-       .reg_off = MESON8B_REG_SYS_CPU_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 };
-
-struct clk_mux meson8b_mpeg_clk_sel = {
-       .reg = (void *)MESON8B_REG_HHI_MPEG,
-       .mask = 0x7,
-       .shift = 12,
-       .flags = CLK_MUX_READ_ONLY,
-       .table = mux_table_clk81,
-       .lock = &clk_lock,
-       .hw.init = &(struct clk_init_data){
-               .name = "mpeg_clk_sel",
-               .ops = &clk_mux_ro_ops,
-               /*
-                * FIXME 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,
-               .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
-       },
-};
-
-struct clk_divider meson8b_mpeg_clk_div = {
-       .reg = (void *)MESON8B_REG_HHI_MPEG,
-       .shift = 0,
-       .width = 7,
-       .lock = &clk_lock,
-       .hw.init = &(struct clk_init_data){
-               .name = "mpeg_clk_div",
-               .ops = &clk_divider_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
-               .num_parents = 1,
-               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
-       },
-};
-
-struct clk_gate meson8b_clk81 = {
-       .reg = (void *)MESON8B_REG_HHI_MPEG,
-       .bit_idx = 7,
-       .lock = &clk_lock,
-       .hw.init = &(struct clk_init_data){
-               .name = "clk81",
-               .ops = &clk_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
-               .num_parents = 1,
-               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
-       },
-};
-
-static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
-       .hws = {
-               [CLKID_XTAL] = &meson8b_xtal.hw,
-               [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
-               [CLKID_PLL_VID] = &meson8b_vid_pll.hw,
-               [CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
-               [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
-               [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
-               [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
-               [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
-               [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
-               [CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
-               [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
-               [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
-               [CLKID_CLK81] = &meson8b_clk81.hw,
-       },
-       .num = CLK_NR_CLKS,
-};
-
-static struct meson_clk_pll *const meson8b_clk_plls[] = {
-       &meson8b_fixed_pll,
-       &meson8b_vid_pll,
-       &meson8b_sys_pll,
-};
-
-static int meson8b_clkc_probe(struct platform_device *pdev)
-{
-       void __iomem *clk_base;
-       int ret, clkid, i;
-       struct clk_hw *parent_hw;
-       struct clk *parent_clk;
-       struct device *dev = &pdev->dev;
-
-       /*  Generic clocks and PLLs */
-       clk_base = of_iomap(dev->of_node, 1);
-       if (!clk_base) {
-               pr_err("%s: Unable to map clk base\n", __func__);
-               return -ENXIO;
-       }
-
-       /* Populate base address for PLLs */
-       for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
-               meson8b_clk_plls[i]->base = clk_base;
-
-       /* Populate the base address for CPU clk */
-       meson8b_cpu_clk.base = clk_base;
-
-       /* Populate the base address for the MPEG clks */
-       meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
-       meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
-       meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
-
-       /*
-        * register all clks
-        * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
-        */
-       for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) {
-               /* array might be sparse */
-               if (!meson8b_hw_onecell_data.hws[clkid])
-                       continue;
-
-               /* FIXME convert to devm_clk_register */
-               ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
-               if (ret)
-                       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(&meson8b_cpu_clk.hw);
-       parent_clk = parent_hw->clk;
-       ret = clk_notifier_register(parent_clk, &meson8b_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,
-                       &meson8b_hw_onecell_data);
-
-iounmap:
-       iounmap(clk_base);
-       return ret;
-}
-
-static const struct of_device_id meson8b_clkc_match_table[] = {
-       { .compatible = "amlogic,meson8b-clkc" },
-       { }
-};
-
-static struct platform_driver meson8b_driver = {
-       .probe          = meson8b_clkc_probe,
-       .driver         = {
-               .name   = "meson8b-clkc",
-               .of_match_table = meson8b_clkc_match_table,
-       },
-};
-
-static int __init meson8b_clkc_init(void)
-{
-       return platform_driver_register(&meson8b_driver);
-}
-device_initcall(meson8b_clkc_init);
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
new file mode 100644 (file)
index 0000000..e1d4aa1
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * AmLogic S805 / Meson8b Clock Controller Driver
+ *
+ * Copyright (c) 2015 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ *
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Michael Turquette <mturquette@baylibre.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/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+#include "clkc.h"
+#include "meson8b.h"
+
+static DEFINE_SPINLOCK(clk_lock);
+
+static const struct pll_rate_table sys_pll_rate_table[] = {
+       PLL_RATE(312000000, 52, 1, 2),
+       PLL_RATE(336000000, 56, 1, 2),
+       PLL_RATE(360000000, 60, 1, 2),
+       PLL_RATE(384000000, 64, 1, 2),
+       PLL_RATE(408000000, 68, 1, 2),
+       PLL_RATE(432000000, 72, 1, 2),
+       PLL_RATE(456000000, 76, 1, 2),
+       PLL_RATE(480000000, 80, 1, 2),
+       PLL_RATE(504000000, 84, 1, 2),
+       PLL_RATE(528000000, 88, 1, 2),
+       PLL_RATE(552000000, 92, 1, 2),
+       PLL_RATE(576000000, 96, 1, 2),
+       PLL_RATE(600000000, 50, 1, 1),
+       PLL_RATE(624000000, 52, 1, 1),
+       PLL_RATE(648000000, 54, 1, 1),
+       PLL_RATE(672000000, 56, 1, 1),
+       PLL_RATE(696000000, 58, 1, 1),
+       PLL_RATE(720000000, 60, 1, 1),
+       PLL_RATE(744000000, 62, 1, 1),
+       PLL_RATE(768000000, 64, 1, 1),
+       PLL_RATE(792000000, 66, 1, 1),
+       PLL_RATE(816000000, 68, 1, 1),
+       PLL_RATE(840000000, 70, 1, 1),
+       PLL_RATE(864000000, 72, 1, 1),
+       PLL_RATE(888000000, 74, 1, 1),
+       PLL_RATE(912000000, 76, 1, 1),
+       PLL_RATE(936000000, 78, 1, 1),
+       PLL_RATE(960000000, 80, 1, 1),
+       PLL_RATE(984000000, 82, 1, 1),
+       PLL_RATE(1008000000, 84, 1, 1),
+       PLL_RATE(1032000000, 86, 1, 1),
+       PLL_RATE(1056000000, 88, 1, 1),
+       PLL_RATE(1080000000, 90, 1, 1),
+       PLL_RATE(1104000000, 92, 1, 1),
+       PLL_RATE(1128000000, 94, 1, 1),
+       PLL_RATE(1152000000, 96, 1, 1),
+       PLL_RATE(1176000000, 98, 1, 1),
+       PLL_RATE(1200000000, 50, 1, 0),
+       PLL_RATE(1224000000, 51, 1, 0),
+       PLL_RATE(1248000000, 52, 1, 0),
+       PLL_RATE(1272000000, 53, 1, 0),
+       PLL_RATE(1296000000, 54, 1, 0),
+       PLL_RATE(1320000000, 55, 1, 0),
+       PLL_RATE(1344000000, 56, 1, 0),
+       PLL_RATE(1368000000, 57, 1, 0),
+       PLL_RATE(1392000000, 58, 1, 0),
+       PLL_RATE(1416000000, 59, 1, 0),
+       PLL_RATE(1440000000, 60, 1, 0),
+       PLL_RATE(1464000000, 61, 1, 0),
+       PLL_RATE(1488000000, 62, 1, 0),
+       PLL_RATE(1512000000, 63, 1, 0),
+       PLL_RATE(1536000000, 64, 1, 0),
+       { /* 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 clk_fixed_rate meson8b_xtal = {
+       .fixed_rate = 24000000,
+       .hw.init = &(struct clk_init_data){
+               .name = "xtal",
+               .num_parents = 0,
+               .ops = &clk_fixed_rate_ops,
+       },
+};
+
+static struct meson_clk_pll meson8b_fixed_pll = {
+       .m = {
+               .reg_off = HHI_MPLL_CNTL,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_MPLL_CNTL,
+               .shift   = 9,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_MPLL_CNTL,
+               .shift   = 16,
+               .width   = 2,
+       },
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "fixed_pll",
+               .ops = &meson_clk_pll_ro_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_pll meson8b_vid_pll = {
+       .m = {
+               .reg_off = HHI_VID_PLL_CNTL,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_VID_PLL_CNTL,
+               .shift   = 9,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_VID_PLL_CNTL,
+               .shift   = 16,
+               .width   = 2,
+       },
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "vid_pll",
+               .ops = &meson_clk_pll_ro_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct meson_clk_pll meson8b_sys_pll = {
+       .m = {
+               .reg_off = HHI_SYS_PLL_CNTL,
+               .shift   = 0,
+               .width   = 9,
+       },
+       .n = {
+               .reg_off = HHI_SYS_PLL_CNTL,
+               .shift   = 9,
+               .width   = 5,
+       },
+       .od = {
+               .reg_off = HHI_SYS_PLL_CNTL,
+               .shift   = 16,
+               .width   = 2,
+       },
+       .rate_table = sys_pll_rate_table,
+       .rate_count = ARRAY_SIZE(sys_pll_rate_table),
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "sys_pll",
+               .ops = &meson_clk_pll_ops,
+               .parent_names = (const char *[]){ "xtal" },
+               .num_parents = 1,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_fixed_factor meson8b_fclk_div2 = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_fclk_div3 = {
+       .mult = 1,
+       .div = 3,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div3",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_fclk_div4 = {
+       .mult = 1,
+       .div = 4,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div4",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_fclk_div5 = {
+       .mult = 1,
+       .div = 5,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div5",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor meson8b_fclk_div7 = {
+       .mult = 1,
+       .div = 7,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div7",
+               .ops = &clk_fixed_factor_ops,
+               .parent_names = (const char *[]){ "fixed_pll" },
+               .num_parents = 1,
+       },
+};
+
+/*
+ * 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
+ */
+static struct meson_clk_cpu meson8b_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 };
+
+struct clk_mux meson8b_mpeg_clk_sel = {
+       .reg = (void *)HHI_MPEG_CLK_CNTL,
+       .mask = 0x7,
+       .shift = 12,
+       .flags = CLK_MUX_READ_ONLY,
+       .table = mux_table_clk81,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpeg_clk_sel",
+               .ops = &clk_mux_ro_ops,
+               /*
+                * FIXME 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,
+               .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
+       },
+};
+
+struct clk_divider meson8b_mpeg_clk_div = {
+       .reg = (void *)HHI_MPEG_CLK_CNTL,
+       .shift = 0,
+       .width = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "mpeg_clk_div",
+               .ops = &clk_divider_ops,
+               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .num_parents = 1,
+               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+       },
+};
+
+struct clk_gate meson8b_clk81 = {
+       .reg = (void *)HHI_MPEG_CLK_CNTL,
+       .bit_idx = 7,
+       .lock = &clk_lock,
+       .hw.init = &(struct clk_init_data){
+               .name = "clk81",
+               .ops = &clk_gate_ops,
+               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .num_parents = 1,
+               .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
+       },
+};
+
+/* Everything Else (EE) domain gates */
+
+static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
+static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
+static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
+static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
+static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
+static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
+static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
+static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
+static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
+static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
+static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
+static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
+static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
+static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
+static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
+static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
+static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
+static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
+static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
+
+static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
+static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
+static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
+static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
+static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
+static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
+static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
+static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
+static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
+static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
+static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
+static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
+static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
+static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
+static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
+static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
+static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
+static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
+static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
+static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
+static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
+static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
+static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
+static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
+static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
+
+static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
+static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
+static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
+static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
+static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
+static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
+static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
+static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
+static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
+static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
+static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
+static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
+static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
+
+static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
+static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
+static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
+static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
+static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
+static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
+static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
+static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
+static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
+static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
+static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
+static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
+static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
+static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
+static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
+static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
+
+/* Always On (AO) domain gates */
+
+static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
+static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
+static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
+static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
+
+static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
+       .hws = {
+               [CLKID_XTAL] = &meson8b_xtal.hw,
+               [CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
+               [CLKID_PLL_VID] = &meson8b_vid_pll.hw,
+               [CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
+               [CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
+               [CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
+               [CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
+               [CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
+               [CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
+               [CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
+               [CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
+               [CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
+               [CLKID_CLK81] = &meson8b_clk81.hw,
+               [CLKID_DDR]                 = &meson8b_ddr.hw,
+               [CLKID_DOS]                 = &meson8b_dos.hw,
+               [CLKID_ISA]                 = &meson8b_isa.hw,
+               [CLKID_PL301]               = &meson8b_pl301.hw,
+               [CLKID_PERIPHS]             = &meson8b_periphs.hw,
+               [CLKID_SPICC]               = &meson8b_spicc.hw,
+               [CLKID_I2C]                 = &meson8b_i2c.hw,
+               [CLKID_SAR_ADC]             = &meson8b_sar_adc.hw,
+               [CLKID_SMART_CARD]          = &meson8b_smart_card.hw,
+               [CLKID_RNG0]                = &meson8b_rng0.hw,
+               [CLKID_UART0]               = &meson8b_uart0.hw,
+               [CLKID_SDHC]                = &meson8b_sdhc.hw,
+               [CLKID_STREAM]              = &meson8b_stream.hw,
+               [CLKID_ASYNC_FIFO]          = &meson8b_async_fifo.hw,
+               [CLKID_SDIO]                = &meson8b_sdio.hw,
+               [CLKID_ABUF]                = &meson8b_abuf.hw,
+               [CLKID_HIU_IFACE]           = &meson8b_hiu_iface.hw,
+               [CLKID_ASSIST_MISC]         = &meson8b_assist_misc.hw,
+               [CLKID_SPI]                 = &meson8b_spi.hw,
+               [CLKID_I2S_SPDIF]           = &meson8b_i2s_spdif.hw,
+               [CLKID_ETH]                 = &meson8b_eth.hw,
+               [CLKID_DEMUX]               = &meson8b_demux.hw,
+               [CLKID_AIU_GLUE]            = &meson8b_aiu_glue.hw,
+               [CLKID_IEC958]              = &meson8b_iec958.hw,
+               [CLKID_I2S_OUT]             = &meson8b_i2s_out.hw,
+               [CLKID_AMCLK]               = &meson8b_amclk.hw,
+               [CLKID_AIFIFO2]             = &meson8b_aififo2.hw,
+               [CLKID_MIXER]               = &meson8b_mixer.hw,
+               [CLKID_MIXER_IFACE]         = &meson8b_mixer_iface.hw,
+               [CLKID_ADC]                 = &meson8b_adc.hw,
+               [CLKID_BLKMV]               = &meson8b_blkmv.hw,
+               [CLKID_AIU]                 = &meson8b_aiu.hw,
+               [CLKID_UART1]               = &meson8b_uart1.hw,
+               [CLKID_G2D]                 = &meson8b_g2d.hw,
+               [CLKID_USB0]                = &meson8b_usb0.hw,
+               [CLKID_USB1]                = &meson8b_usb1.hw,
+               [CLKID_RESET]               = &meson8b_reset.hw,
+               [CLKID_NAND]                = &meson8b_nand.hw,
+               [CLKID_DOS_PARSER]          = &meson8b_dos_parser.hw,
+               [CLKID_USB]                 = &meson8b_usb.hw,
+               [CLKID_VDIN1]               = &meson8b_vdin1.hw,
+               [CLKID_AHB_ARB0]            = &meson8b_ahb_arb0.hw,
+               [CLKID_EFUSE]               = &meson8b_efuse.hw,
+               [CLKID_BOOT_ROM]            = &meson8b_boot_rom.hw,
+               [CLKID_AHB_DATA_BUS]        = &meson8b_ahb_data_bus.hw,
+               [CLKID_AHB_CTRL_BUS]        = &meson8b_ahb_ctrl_bus.hw,
+               [CLKID_HDMI_INTR_SYNC]      = &meson8b_hdmi_intr_sync.hw,
+               [CLKID_HDMI_PCLK]           = &meson8b_hdmi_pclk.hw,
+               [CLKID_USB1_DDR_BRIDGE]     = &meson8b_usb1_ddr_bridge.hw,
+               [CLKID_USB0_DDR_BRIDGE]     = &meson8b_usb0_ddr_bridge.hw,
+               [CLKID_MMC_PCLK]            = &meson8b_mmc_pclk.hw,
+               [CLKID_DVIN]                = &meson8b_dvin.hw,
+               [CLKID_UART2]               = &meson8b_uart2.hw,
+               [CLKID_SANA]                = &meson8b_sana.hw,
+               [CLKID_VPU_INTR]            = &meson8b_vpu_intr.hw,
+               [CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
+               [CLKID_CLK81_A9]            = &meson8b_clk81_a9.hw,
+               [CLKID_VCLK2_VENCI0]        = &meson8b_vclk2_venci0.hw,
+               [CLKID_VCLK2_VENCI1]        = &meson8b_vclk2_venci1.hw,
+               [CLKID_VCLK2_VENCP0]        = &meson8b_vclk2_vencp0.hw,
+               [CLKID_VCLK2_VENCP1]        = &meson8b_vclk2_vencp1.hw,
+               [CLKID_GCLK_VENCI_INT]      = &meson8b_gclk_venci_int.hw,
+               [CLKID_GCLK_VENCI_INT]      = &meson8b_gclk_vencp_int.hw,
+               [CLKID_DAC_CLK]             = &meson8b_dac_clk.hw,
+               [CLKID_AOCLK_GATE]          = &meson8b_aoclk_gate.hw,
+               [CLKID_IEC958_GATE]         = &meson8b_iec958_gate.hw,
+               [CLKID_ENC480P]             = &meson8b_enc480p.hw,
+               [CLKID_RNG1]                = &meson8b_rng1.hw,
+               [CLKID_GCLK_VENCL_INT]      = &meson8b_gclk_vencl_int.hw,
+               [CLKID_VCLK2_VENCLMCC]      = &meson8b_vclk2_venclmcc.hw,
+               [CLKID_VCLK2_VENCL]         = &meson8b_vclk2_vencl.hw,
+               [CLKID_VCLK2_OTHER]         = &meson8b_vclk2_other.hw,
+               [CLKID_EDP]                 = &meson8b_edp.hw,
+               [CLKID_AO_MEDIA_CPU]        = &meson8b_ao_media_cpu.hw,
+               [CLKID_AO_AHB_SRAM]         = &meson8b_ao_ahb_sram.hw,
+               [CLKID_AO_AHB_BUS]          = &meson8b_ao_ahb_bus.hw,
+               [CLKID_AO_IFACE]            = &meson8b_ao_iface.hw,
+       },
+       .num = CLK_NR_CLKS,
+};
+
+static struct meson_clk_pll *const meson8b_clk_plls[] = {
+       &meson8b_fixed_pll,
+       &meson8b_vid_pll,
+       &meson8b_sys_pll,
+};
+
+static struct clk_gate *meson8b_clk_gates[] = {
+       &meson8b_clk81,
+       &meson8b_ddr,
+       &meson8b_dos,
+       &meson8b_isa,
+       &meson8b_pl301,
+       &meson8b_periphs,
+       &meson8b_spicc,
+       &meson8b_i2c,
+       &meson8b_sar_adc,
+       &meson8b_smart_card,
+       &meson8b_rng0,
+       &meson8b_uart0,
+       &meson8b_sdhc,
+       &meson8b_stream,
+       &meson8b_async_fifo,
+       &meson8b_sdio,
+       &meson8b_abuf,
+       &meson8b_hiu_iface,
+       &meson8b_assist_misc,
+       &meson8b_spi,
+       &meson8b_i2s_spdif,
+       &meson8b_eth,
+       &meson8b_demux,
+       &meson8b_aiu_glue,
+       &meson8b_iec958,
+       &meson8b_i2s_out,
+       &meson8b_amclk,
+       &meson8b_aififo2,
+       &meson8b_mixer,
+       &meson8b_mixer_iface,
+       &meson8b_adc,
+       &meson8b_blkmv,
+       &meson8b_aiu,
+       &meson8b_uart1,
+       &meson8b_g2d,
+       &meson8b_usb0,
+       &meson8b_usb1,
+       &meson8b_reset,
+       &meson8b_nand,
+       &meson8b_dos_parser,
+       &meson8b_usb,
+       &meson8b_vdin1,
+       &meson8b_ahb_arb0,
+       &meson8b_efuse,
+       &meson8b_boot_rom,
+       &meson8b_ahb_data_bus,
+       &meson8b_ahb_ctrl_bus,
+       &meson8b_hdmi_intr_sync,
+       &meson8b_hdmi_pclk,
+       &meson8b_usb1_ddr_bridge,
+       &meson8b_usb0_ddr_bridge,
+       &meson8b_mmc_pclk,
+       &meson8b_dvin,
+       &meson8b_uart2,
+       &meson8b_sana,
+       &meson8b_vpu_intr,
+       &meson8b_sec_ahb_ahb3_bridge,
+       &meson8b_clk81_a9,
+       &meson8b_vclk2_venci0,
+       &meson8b_vclk2_venci1,
+       &meson8b_vclk2_vencp0,
+       &meson8b_vclk2_vencp1,
+       &meson8b_gclk_venci_int,
+       &meson8b_gclk_vencp_int,
+       &meson8b_dac_clk,
+       &meson8b_aoclk_gate,
+       &meson8b_iec958_gate,
+       &meson8b_enc480p,
+       &meson8b_rng1,
+       &meson8b_gclk_vencl_int,
+       &meson8b_vclk2_venclmcc,
+       &meson8b_vclk2_vencl,
+       &meson8b_vclk2_other,
+       &meson8b_edp,
+       &meson8b_ao_media_cpu,
+       &meson8b_ao_ahb_sram,
+       &meson8b_ao_ahb_bus,
+       &meson8b_ao_iface,
+};
+
+static int meson8b_clkc_probe(struct platform_device *pdev)
+{
+       void __iomem *clk_base;
+       int ret, clkid, i;
+       struct clk_hw *parent_hw;
+       struct clk *parent_clk;
+       struct device *dev = &pdev->dev;
+
+       /*  Generic clocks and PLLs */
+       clk_base = of_iomap(dev->of_node, 1);
+       if (!clk_base) {
+               pr_err("%s: Unable to map clk base\n", __func__);
+               return -ENXIO;
+       }
+
+       /* Populate base address for PLLs */
+       for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
+               meson8b_clk_plls[i]->base = clk_base;
+
+       /* Populate the base address for CPU clk */
+       meson8b_cpu_clk.base = clk_base;
+
+       /* Populate the base address for the MPEG clks */
+       meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
+       meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
+       meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
+
+       /* Populate base address for gates */
+       for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
+               meson8b_clk_gates[i]->reg = clk_base +
+                       (u32)meson8b_clk_gates[i]->reg;
+
+       /*
+        * register all clks
+        * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
+        */
+       for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) {
+               /* array might be sparse */
+               if (!meson8b_hw_onecell_data.hws[clkid])
+                       continue;
+
+               /* FIXME convert to devm_clk_register */
+               ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
+               if (ret)
+                       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(&meson8b_cpu_clk.hw);
+       parent_clk = parent_hw->clk;
+       ret = clk_notifier_register(parent_clk, &meson8b_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,
+                       &meson8b_hw_onecell_data);
+
+iounmap:
+       iounmap(clk_base);
+       return ret;
+}
+
+static const struct of_device_id meson8b_clkc_match_table[] = {
+       { .compatible = "amlogic,meson8b-clkc" },
+       { }
+};
+
+static struct platform_driver meson8b_driver = {
+       .probe          = meson8b_clkc_probe,
+       .driver         = {
+               .name   = "meson8b-clkc",
+               .of_match_table = meson8b_clkc_match_table,
+       },
+};
+
+static int __init meson8b_clkc_init(void)
+{
+       return platform_driver_register(&meson8b_driver);
+}
+device_initcall(meson8b_clkc_init);
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h
new file mode 100644 (file)
index 0000000..010e958
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2015 Endless Mobile, Inc.
+ * Author: Carlo Caione <carlo@endlessm.com>
+ *
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Michael Turquette <mturquette@baylibre.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/>.
+ */
+
+#ifndef __MESON8B_H
+#define __MESON8B_H
+
+/*
+ * Clock controller register offsets
+ *
+ * Register offsets from the HardKernel[0] data sheet are listed in comment
+ * blocks below. Those offsets must be multiplied by 4 before adding them to
+ * the base address to get the right value
+ *
+ * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
+ */
+#define HHI_GCLK_MPEG0                 0x140 /* 0x50 offset in data sheet */
+#define HHI_GCLK_MPEG1                 0x144 /* 0x51 offset in data sheet */
+#define HHI_GCLK_MPEG2                 0x148 /* 0x52 offset in data sheet */
+#define HHI_GCLK_OTHER                 0x150 /* 0x54 offset in data sheet */
+#define HHI_GCLK_AO                    0x154 /* 0x55 offset in data sheet */
+#define HHI_SYS_CPU_CLK_CNTL1          0x15c /* 0x57 offset in data sheet */
+#define HHI_MPEG_CLK_CNTL              0x174 /* 0x5d offset in data sheet */
+#define HHI_MPLL_CNTL                  0x280 /* 0xa0 offset in data sheet */
+#define HHI_SYS_PLL_CNTL               0x300 /* 0xc0 offset in data sheet */
+#define HHI_VID_PLL_CNTL               0x320 /* 0xc8 offset in data sheet */
+
+/*
+ * CLKID index values
+ *
+ * These indices are entirely contrived and do not map onto the hardware.
+ * Migrate them out of this header and into the DT header file when they need
+ * to be exposed to client nodes in DT: include/dt-bindings/clock/meson8b-clkc.h
+ */
+
+/* CLKID_UNUSED */
+/* CLKID_XTAL */
+/* CLKID_PLL_FIXED */
+/* CLKID_PLL_VID */
+/* CLKID_PLL_SYS */
+/* CLKID_FCLK_DIV2 */
+/* CLKID_FCLK_DIV3 */
+/* CLKID_FCLK_DIV4 */
+/* CLKID_FCLK_DIV5 */
+/* CLKID_FCLK_DIV7 */
+/* CLKID_CLK81 */
+/* CLKID_MALI */
+/* CLKID_CPUCLK */
+/* CLKID_ZERO */
+/* CLKID_MPEG_SEL */
+/* CLKID_MPEG_DIV */
+#define CLKID_DDR              16
+#define CLKID_DOS              17
+#define CLKID_ISA              18
+#define CLKID_PL301            19
+#define CLKID_PERIPHS          20
+#define CLKID_SPICC            21
+#define CLKID_I2C              22
+#define CLKID_SAR_ADC          23
+#define CLKID_SMART_CARD       24
+#define CLKID_RNG0             25
+#define CLKID_UART0            26
+#define CLKID_SDHC             27
+#define CLKID_STREAM           28
+#define CLKID_ASYNC_FIFO       29
+#define CLKID_SDIO             30
+#define CLKID_ABUF             31
+#define CLKID_HIU_IFACE                32
+#define CLKID_ASSIST_MISC      33
+#define CLKID_SPI              34
+#define CLKID_I2S_SPDIF                35
+#define CLKID_ETH              36
+#define CLKID_DEMUX            37
+#define CLKID_AIU_GLUE         38
+#define CLKID_IEC958           39
+#define CLKID_I2S_OUT          40
+#define CLKID_AMCLK            41
+#define CLKID_AIFIFO2          42
+#define CLKID_MIXER            43
+#define CLKID_MIXER_IFACE      44
+#define CLKID_ADC              45
+#define CLKID_BLKMV            46
+#define CLKID_AIU              47
+#define CLKID_UART1            48
+#define CLKID_G2D              49
+#define CLKID_USB0             50
+#define CLKID_USB1             51
+#define CLKID_RESET            52
+#define CLKID_NAND             53
+#define CLKID_DOS_PARSER       54
+#define CLKID_USB              55
+#define CLKID_VDIN1            56
+#define CLKID_AHB_ARB0         57
+#define CLKID_EFUSE            58
+#define CLKID_BOOT_ROM         59
+#define CLKID_AHB_DATA_BUS     60
+#define CLKID_AHB_CTRL_BUS     61
+#define CLKID_HDMI_INTR_SYNC   62
+#define CLKID_HDMI_PCLK                63
+#define CLKID_USB1_DDR_BRIDGE  64
+#define CLKID_USB0_DDR_BRIDGE  65
+#define CLKID_MMC_PCLK         66
+#define CLKID_DVIN             67
+#define CLKID_UART2            68
+#define CLKID_SANA             69
+#define CLKID_VPU_INTR         70
+#define CLKID_SEC_AHB_AHB3_BRIDGE      71
+#define CLKID_CLK81_A9         72
+#define CLKID_VCLK2_VENCI0     73
+#define CLKID_VCLK2_VENCI1     74
+#define CLKID_VCLK2_VENCP0     75
+#define CLKID_VCLK2_VENCP1     76
+#define CLKID_GCLK_VENCI_INT   77
+#define CLKID_GCLK_VENCP_INT   78
+#define CLKID_DAC_CLK          79
+#define CLKID_AOCLK_GATE       80
+#define CLKID_IEC958_GATE      81
+#define CLKID_ENC480P          82
+#define CLKID_RNG1             83
+#define CLKID_GCLK_VENCL_INT   84
+#define CLKID_VCLK2_VENCLMCC   85
+#define CLKID_VCLK2_VENCL      86
+#define CLKID_VCLK2_OTHER      87
+#define CLKID_EDP              88
+#define CLKID_AO_MEDIA_CPU     89
+#define CLKID_AO_AHB_SRAM      90
+#define CLKID_AO_AHB_BUS       91
+#define CLKID_AO_IFACE         92
+
+#define CLK_NR_CLKS            93
+
+/* include the CLKIDs that have been made part of the stable DT binding */
+#include <dt-bindings/clock/meson8b-clkc.h>
+
+#endif /* __MESON8B_H */
index ca85cea..c3b3014 100644 (file)
@@ -199,9 +199,9 @@ static int pbclk_set_rate(struct clk_hw *hw, unsigned long rate,
 
        spin_unlock_irqrestore(&pb->core->reg_lock, flags);
 
-       /* wait again, for pbdivready */
-       err = readl_poll_timeout_atomic(pb->ctrl_reg, v, v & PB_DIV_READY,
-                                       1, LOCK_TIMEOUT_US);
+       /* wait again for DIV_READY */
+       err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY,
+                                1, LOCK_TIMEOUT_US);
        if (err)
                return err;
 
index 51f5438..9f73477 100644 (file)
@@ -118,6 +118,7 @@ static const struct pic32_sec_osc_data sosc_clk = {
        .status_reg = 0x1d0,
        .enable_mask = BIT(1),
        .status_mask = BIT(4),
+       .fixed_rate = 32768,
        .init_data = {
                .name = "sosc_clk",
                .parent_names = NULL,
index 3165da7..fddc8ac 100644 (file)
@@ -24,6 +24,9 @@ config ARMADA_39X_CLK
        bool
        select MVEBU_CLK_COMMON
 
+config ARMADA_37XX_CLK
+       bool
+
 config ARMADA_XP_CLK
        bool
        select MVEBU_CLK_COMMON
index 7172ef6..d9ae97f 100644 (file)
@@ -6,6 +6,9 @@ obj-$(CONFIG_ARMADA_370_CLK)    += armada-370.o
 obj-$(CONFIG_ARMADA_375_CLK)   += armada-375.o
 obj-$(CONFIG_ARMADA_38X_CLK)   += armada-38x.o
 obj-$(CONFIG_ARMADA_39X_CLK)   += armada-39x.o
+obj-$(CONFIG_ARMADA_37XX_CLK)  += armada-37xx-xtal.o
+obj-$(CONFIG_ARMADA_37XX_CLK)  += armada-37xx-tbg.o
+obj-$(CONFIG_ARMADA_37XX_CLK)  += armada-37xx-periph.o
 obj-$(CONFIG_ARMADA_XP_CLK)    += armada-xp.o
 obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
 obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
new file mode 100644 (file)
index 0000000..45905fc
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Marvell Armada 37xx SoC Peripheral clocks
+ *
+ * Copyright (C) 2016 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2 or later. This program is licensed "as is"
+ * without any warranty of any kind, whether express or implied.
+ *
+ * Most of the peripheral clocks can be modelled like this:
+ *             _____    _______    _______
+ * TBG-A-P  --|     |  |       |  |       |   ______
+ * TBG-B-P  --| Mux |--| /div1 |--| /div2 |--| Gate |--> perip_clk
+ * TBG-A-S  --|     |  |       |  |       |  |______|
+ * TBG-B-S  --|_____|  |_______|  |_______|
+ *
+ * However some clocks may use only one or two block or and use the
+ * xtal clock as parent.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define TBG_SEL                0x0
+#define DIV_SEL0       0x4
+#define DIV_SEL1       0x8
+#define DIV_SEL2       0xC
+#define CLK_SEL                0x10
+#define CLK_DIS                0x14
+
+struct clk_periph_driver_data {
+       struct clk_hw_onecell_data *hw_data;
+       spinlock_t lock;
+};
+
+struct clk_double_div {
+       struct clk_hw hw;
+       void __iomem *reg1;
+       u8 shift1;
+       void __iomem *reg2;
+       u8 shift2;
+};
+
+#define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw)
+
+struct clk_periph_data {
+       const char *name;
+       const char * const *parent_names;
+       int num_parents;
+       struct clk_hw *mux_hw;
+       struct clk_hw *rate_hw;
+       struct clk_hw *gate_hw;
+       bool is_double_div;
+};
+
+static const struct clk_div_table clk_table6[] = {
+       { .val = 1, .div = 1, },
+       { .val = 2, .div = 2, },
+       { .val = 3, .div = 3, },
+       { .val = 4, .div = 4, },
+       { .val = 5, .div = 5, },
+       { .val = 6, .div = 6, },
+       { .val = 0, .div = 0, }, /* last entry */
+};
+
+static const struct clk_div_table clk_table1[] = {
+       { .val = 0, .div = 1, },
+       { .val = 1, .div = 2, },
+       { .val = 0, .div = 0, }, /* last entry */
+};
+
+static const struct clk_div_table clk_table2[] = {
+       { .val = 0, .div = 2, },
+       { .val = 1, .div = 4, },
+       { .val = 0, .div = 0, }, /* last entry */
+};
+static const struct clk_ops clk_double_div_ops;
+
+#define PERIPH_GATE(_name, _bit)               \
+struct clk_gate gate_##_name = {               \
+       .reg = (void *)CLK_DIS,                 \
+       .bit_idx = _bit,                        \
+       .hw.init = &(struct clk_init_data){     \
+               .ops =  &clk_gate_ops,          \
+       }                                       \
+};
+
+#define PERIPH_MUX(_name, _shift)              \
+struct clk_mux mux_##_name = {                 \
+       .reg = (void *)TBG_SEL,                 \
+       .shift = _shift,                        \
+       .mask = 3,                              \
+       .hw.init = &(struct clk_init_data){     \
+               .ops =  &clk_mux_ro_ops,        \
+       }                                       \
+};
+
+#define PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2)        \
+struct clk_double_div rate_##_name = {         \
+       .reg1 = (void *)_reg1,                  \
+       .reg2 = (void *)_reg2,                  \
+       .shift1 = _shift1,                      \
+       .shift2 = _shift2,                      \
+       .hw.init = &(struct clk_init_data){     \
+               .ops =  &clk_double_div_ops,    \
+       }                                       \
+};
+
+#define PERIPH_DIV(_name, _reg, _shift, _table)        \
+struct clk_divider rate_##_name = {            \
+       .reg = (void *)_reg,                    \
+       .table = _table,                        \
+       .shift = _shift,                        \
+       .hw.init = &(struct clk_init_data){     \
+               .ops =  &clk_divider_ro_ops,    \
+       }                                       \
+};
+
+#define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\
+static PERIPH_GATE(_name, _bit);                           \
+static PERIPH_MUX(_name, _shift);                          \
+static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
+
+#define PERIPH_CLK_FULL(_name, _bit, _shift, _reg, _shift1, _table)    \
+static PERIPH_GATE(_name, _bit);                           \
+static PERIPH_MUX(_name, _shift);                          \
+static PERIPH_DIV(_name, _reg, _shift1, _table);
+
+#define PERIPH_CLK_GATE_DIV(_name, _bit,  _reg, _shift, _table)        \
+static PERIPH_GATE(_name, _bit);                       \
+static PERIPH_DIV(_name, _reg, _shift, _table);
+
+#define PERIPH_CLK_MUX_DIV(_name, _shift,  _reg, _shift_div, _table)   \
+static PERIPH_MUX(_name, _shift);                          \
+static PERIPH_DIV(_name, _reg, _shift_div, _table);
+
+#define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\
+static PERIPH_MUX(_name, _shift);                          \
+static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
+
+#define REF_CLK_FULL(_name)                            \
+       { .name = #_name,                               \
+         .parent_names = (const char *[]){ "TBG-A-P",  \
+             "TBG-B-P", "TBG-A-S", "TBG-B-S"},         \
+         .num_parents = 4,                             \
+         .mux_hw = &mux_##_name.hw,                    \
+         .gate_hw = &gate_##_name.hw,                  \
+         .rate_hw = &rate_##_name.hw,                  \
+       }
+
+#define REF_CLK_FULL_DD(_name)                         \
+       { .name = #_name,                               \
+         .parent_names = (const char *[]){ "TBG-A-P",  \
+             "TBG-B-P", "TBG-A-S", "TBG-B-S"},         \
+         .num_parents = 4,                             \
+         .mux_hw = &mux_##_name.hw,                    \
+         .gate_hw = &gate_##_name.hw,                  \
+         .rate_hw = &rate_##_name.hw,                  \
+         .is_double_div = true,                        \
+       }
+
+#define REF_CLK_GATE(_name, _parent_name)                      \
+       { .name = #_name,                                       \
+         .parent_names = (const char *[]){ _parent_name},      \
+         .num_parents = 1,                                     \
+         .gate_hw = &gate_##_name.hw,                          \
+       }
+
+#define REF_CLK_GATE_DIV(_name, _parent_name)                  \
+       { .name = #_name,                                       \
+         .parent_names = (const char *[]){ _parent_name},      \
+         .num_parents = 1,                                     \
+         .gate_hw = &gate_##_name.hw,                          \
+         .rate_hw = &rate_##_name.hw,                          \
+       }
+
+#define REF_CLK_MUX_DIV(_name)                         \
+       { .name = #_name,                               \
+         .parent_names = (const char *[]){ "TBG-A-P",  \
+             "TBG-B-P", "TBG-A-S", "TBG-B-S"},         \
+         .num_parents = 4,                             \
+         .mux_hw = &mux_##_name.hw,                    \
+         .rate_hw = &rate_##_name.hw,                  \
+       }
+
+#define REF_CLK_MUX_DD(_name)                          \
+       { .name = #_name,                               \
+         .parent_names = (const char *[]){ "TBG-A-P",  \
+             "TBG-B-P", "TBG-A-S", "TBG-B-S"},         \
+         .num_parents = 4,                             \
+         .mux_hw = &mux_##_name.hw,                    \
+         .rate_hw = &rate_##_name.hw,                  \
+         .is_double_div = true,                        \
+       }
+
+/* NB periph clocks */
+PERIPH_CLK_FULL_DD(mmc, 2, 0, DIV_SEL2, DIV_SEL2, 16, 13);
+PERIPH_CLK_FULL_DD(sata_host, 3, 2, DIV_SEL2, DIV_SEL2, 10, 7);
+PERIPH_CLK_FULL_DD(sec_at, 6, 4, DIV_SEL1, DIV_SEL1, 3, 0);
+PERIPH_CLK_FULL_DD(sec_dap, 7, 6, DIV_SEL1, DIV_SEL1, 9, 6);
+PERIPH_CLK_FULL_DD(tscem, 8, 8, DIV_SEL1, DIV_SEL1, 15, 12);
+PERIPH_CLK_FULL(tscem_tmx, 10, 10, DIV_SEL1, 18, clk_table6);
+static PERIPH_GATE(avs, 11);
+PERIPH_CLK_FULL_DD(pwm, 13, 14, DIV_SEL0, DIV_SEL0, 3, 0);
+PERIPH_CLK_FULL_DD(sqf, 12, 12, DIV_SEL1, DIV_SEL1, 27, 24);
+static PERIPH_GATE(i2c_2, 16);
+static PERIPH_GATE(i2c_1, 17);
+PERIPH_CLK_GATE_DIV(ddr_phy, 19, DIV_SEL0, 18, clk_table2);
+PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV_SEL0, DIV_SEL0, 15, 12);
+PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6);
+PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6);
+PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19);
+PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6);
+
+static struct clk_periph_data data_nb[] ={
+       REF_CLK_FULL_DD(mmc),
+       REF_CLK_FULL_DD(sata_host),
+       REF_CLK_FULL_DD(sec_at),
+       REF_CLK_FULL_DD(sec_dap),
+       REF_CLK_FULL_DD(tscem),
+       REF_CLK_FULL(tscem_tmx),
+       REF_CLK_GATE(avs, "xtal"),
+       REF_CLK_FULL_DD(sqf),
+       REF_CLK_FULL_DD(pwm),
+       REF_CLK_GATE(i2c_2, "xtal"),
+       REF_CLK_GATE(i2c_1, "xtal"),
+       REF_CLK_GATE_DIV(ddr_phy, "TBG-A-S"),
+       REF_CLK_FULL_DD(ddr_fclk),
+       REF_CLK_FULL(trace),
+       REF_CLK_FULL(counter),
+       REF_CLK_FULL_DD(eip97),
+       REF_CLK_MUX_DIV(cpu),
+       { },
+};
+
+/* SB periph clocks */
+PERIPH_CLK_MUX_DD(gbe_50, 6, DIV_SEL2, DIV_SEL2, 6, 9);
+PERIPH_CLK_MUX_DD(gbe_core, 8, DIV_SEL1, DIV_SEL1, 18, 21);
+PERIPH_CLK_MUX_DD(gbe_125, 10, DIV_SEL1, DIV_SEL1, 6, 9);
+static PERIPH_GATE(gbe1_50, 0);
+static PERIPH_GATE(gbe0_50, 1);
+static PERIPH_GATE(gbe1_125, 2);
+static PERIPH_GATE(gbe0_125, 3);
+PERIPH_CLK_GATE_DIV(gbe1_core, 4, DIV_SEL1, 13, clk_table1);
+PERIPH_CLK_GATE_DIV(gbe0_core, 5, DIV_SEL1, 14, clk_table1);
+PERIPH_CLK_GATE_DIV(gbe_bm, 12, DIV_SEL1, 0, clk_table1);
+PERIPH_CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6);
+PERIPH_CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12);
+PERIPH_CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18);
+
+static struct clk_periph_data data_sb[] = {
+       REF_CLK_MUX_DD(gbe_50),
+       REF_CLK_MUX_DD(gbe_core),
+       REF_CLK_MUX_DD(gbe_125),
+       REF_CLK_GATE(gbe1_50, "gbe_50"),
+       REF_CLK_GATE(gbe0_50, "gbe_50"),
+       REF_CLK_GATE(gbe1_125, "gbe_125"),
+       REF_CLK_GATE(gbe0_125, "gbe_125"),
+       REF_CLK_GATE_DIV(gbe1_core, "gbe_core"),
+       REF_CLK_GATE_DIV(gbe0_core, "gbe_core"),
+       REF_CLK_GATE_DIV(gbe_bm, "gbe_core"),
+       REF_CLK_FULL_DD(sdio),
+       REF_CLK_FULL_DD(usb32_usb2_sys),
+       REF_CLK_FULL_DD(usb32_ss_sys),
+       { },
+};
+
+static unsigned int get_div(void __iomem *reg, int shift)
+{
+       u32 val;
+
+       val = (readl(reg) >> shift) & 0x7;
+       if (val > 6)
+               return 0;
+       return val;
+}
+
+static unsigned long clk_double_div_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_double_div *double_div = to_clk_double_div(hw);
+       unsigned int div;
+
+       div = get_div(double_div->reg1, double_div->shift1);
+       div *= get_div(double_div->reg2, double_div->shift2);
+
+       return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+}
+
+static const struct clk_ops clk_double_div_ops = {
+       .recalc_rate = clk_double_div_recalc_rate,
+};
+
+static const struct of_device_id armada_3700_periph_clock_of_match[] = {
+       { .compatible = "marvell,armada-3700-periph-clock-nb",
+         .data = data_nb, },
+       { .compatible = "marvell,armada-3700-periph-clock-sb",
+       .data = data_sb, },
+       { }
+};
+static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
+                                        void __iomem *reg, spinlock_t *lock,
+                                        struct device *dev, struct clk_hw *hw)
+{
+       const struct clk_ops *mux_ops = NULL, *gate_ops = NULL,
+               *rate_ops = NULL;
+       struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *rate_hw = NULL;
+
+       if (data->mux_hw) {
+               struct clk_mux *mux;
+
+               mux_hw = data->mux_hw;
+               mux = to_clk_mux(mux_hw);
+               mux->lock = lock;
+               mux_ops = mux_hw->init->ops;
+               mux->reg = reg + (u64)mux->reg;
+       }
+
+       if (data->gate_hw) {
+               struct clk_gate *gate;
+
+               gate_hw = data->gate_hw;
+               gate = to_clk_gate(gate_hw);
+               gate->lock = lock;
+               gate_ops = gate_hw->init->ops;
+               gate->reg = reg + (u64)gate->reg;
+       }
+
+       if (data->rate_hw) {
+               rate_hw = data->rate_hw;
+               rate_ops = rate_hw->init->ops;
+               if (data->is_double_div) {
+                       struct clk_double_div *rate;
+
+                       rate =  to_clk_double_div(rate_hw);
+                       rate->reg1 = reg + (u64)rate->reg1;
+                       rate->reg2 = reg + (u64)rate->reg2;
+               } else {
+                       struct clk_divider *rate = to_clk_divider(rate_hw);
+                       const struct clk_div_table *clkt;
+                       int table_size = 0;
+
+                       rate->reg = reg + (u64)rate->reg;
+                       for (clkt = rate->table; clkt->div; clkt++)
+                               table_size++;
+                       rate->width = order_base_2(table_size);
+                       rate->lock = lock;
+               }
+       }
+
+       hw = clk_hw_register_composite(dev, data->name, data->parent_names,
+                                      data->num_parents, mux_hw,
+                                      mux_ops, rate_hw, rate_ops,
+                                      gate_hw, gate_ops, CLK_IGNORE_UNUSED);
+
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       return 0;
+}
+
+static int armada_3700_periph_clock_probe(struct platform_device *pdev)
+{
+       struct clk_periph_driver_data *driver_data;
+       struct device_node *np = pdev->dev.of_node;
+       const struct clk_periph_data *data;
+       struct device *dev = &pdev->dev;
+       int num_periph = 0, i, ret;
+       struct resource *res;
+       void __iomem *reg;
+
+       data = of_device_get_match_data(dev);
+       if (!data)
+               return -ENODEV;
+
+       while (data[num_periph].name)
+               num_periph++;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg = devm_ioremap_resource(dev, res);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
+       if (!driver_data)
+               return -ENOMEM;
+
+       driver_data->hw_data = devm_kzalloc(dev, sizeof(*driver_data->hw_data) +
+                           sizeof(*driver_data->hw_data->hws) * num_periph,
+                           GFP_KERNEL);
+       if (!driver_data->hw_data)
+               return -ENOMEM;
+       driver_data->hw_data->num = num_periph;
+
+       spin_lock_init(&driver_data->lock);
+
+       for (i = 0; i < num_periph; i++) {
+               struct clk_hw *hw = driver_data->hw_data->hws[i];
+
+               if (armada_3700_add_composite_clk(&data[i], reg,
+                                                 &driver_data->lock, dev, hw))
+                       dev_err(dev, "Can't register periph clock %s\n",
+                              data[i].name);
+
+       }
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get,
+                                 driver_data->hw_data);
+       if (ret) {
+               for (i = 0; i < num_periph; i++)
+                       clk_hw_unregister(driver_data->hw_data->hws[i]);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, driver_data);
+       return 0;
+}
+
+static int armada_3700_periph_clock_remove(struct platform_device *pdev)
+{
+       struct clk_periph_driver_data *data = platform_get_drvdata(pdev);
+       struct clk_hw_onecell_data *hw_data = data->hw_data;
+       int i;
+
+       of_clk_del_provider(pdev->dev.of_node);
+
+       for (i = 0; i < hw_data->num; i++)
+               clk_hw_unregister(hw_data->hws[i]);
+
+       return 0;
+}
+
+static struct platform_driver armada_3700_periph_clock_driver = {
+       .probe = armada_3700_periph_clock_probe,
+       .remove = armada_3700_periph_clock_remove,
+       .driver         = {
+               .name   = "marvell-armada-3700-periph-clock",
+               .of_match_table = armada_3700_periph_clock_of_match,
+       },
+};
+
+builtin_platform_driver(armada_3700_periph_clock_driver);
diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c
new file mode 100644 (file)
index 0000000..aa80db1
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Marvell Armada 37xx SoC Time Base Generator clocks
+ *
+ * Copyright (C) 2016 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2 or later. This program is licensed "as is"
+ * without any warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define NUM_TBG            4
+
+#define TBG_CTRL0              0x4
+#define TBG_CTRL1              0x8
+#define TBG_CTRL7              0x20
+#define TBG_CTRL8              0x30
+
+#define TBG_DIV_MASK           0x1FF
+
+#define TBG_A_REFDIV           0
+#define TBG_B_REFDIV           16
+
+#define TBG_A_FBDIV            2
+#define TBG_B_FBDIV            18
+
+#define TBG_A_VCODIV_SE                0
+#define TBG_B_VCODIV_SE                16
+
+#define TBG_A_VCODIV_DIFF      1
+#define TBG_B_VCODIV_DIFF      17
+
+struct tbg_def {
+       char *name;
+       u32 refdiv_offset;
+       u32 fbdiv_offset;
+       u32 vcodiv_reg;
+       u32 vcodiv_offset;
+};
+
+static const struct tbg_def tbg[NUM_TBG] = {
+       {"TBG-A-P", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL8, TBG_A_VCODIV_DIFF},
+       {"TBG-B-P", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL8, TBG_B_VCODIV_DIFF},
+       {"TBG-A-S", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL1, TBG_A_VCODIV_SE},
+       {"TBG-B-S", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL1, TBG_B_VCODIV_SE},
+};
+
+static unsigned int tbg_get_mult(void __iomem *reg, const struct tbg_def *ptbg)
+{
+       u32 val;
+
+       val = readl(reg + TBG_CTRL0);
+
+       return ((val >> ptbg->fbdiv_offset) & TBG_DIV_MASK) << 2;
+}
+
+static unsigned int tbg_get_div(void __iomem *reg, const struct tbg_def *ptbg)
+{
+       u32 val;
+       unsigned int div;
+
+       val = readl(reg + TBG_CTRL7);
+
+       div = (val >> ptbg->refdiv_offset) & TBG_DIV_MASK;
+       if (div == 0)
+               div = 1;
+       val = readl(reg + ptbg->vcodiv_reg);
+
+       div *= 1 << ((val >>  ptbg->vcodiv_offset) & TBG_DIV_MASK);
+
+       return div;
+}
+
+
+static int armada_3700_tbg_clock_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct clk_hw_onecell_data *hw_tbg_data;
+       struct device *dev = &pdev->dev;
+       const char *parent_name;
+       struct resource *res;
+       struct clk *parent;
+       void __iomem *reg;
+       int i, ret;
+
+       hw_tbg_data = devm_kzalloc(&pdev->dev, sizeof(*hw_tbg_data)
+                                  + sizeof(*hw_tbg_data->hws) * NUM_TBG,
+                                  GFP_KERNEL);
+       if (!hw_tbg_data)
+               return -ENOMEM;
+       hw_tbg_data->num = NUM_TBG;
+       platform_set_drvdata(pdev, hw_tbg_data);
+
+       parent = devm_clk_get(dev, NULL);
+       if (IS_ERR(parent)) {
+               dev_err(dev, "Could get the clock parent\n");
+               return -EINVAL;
+       }
+       parent_name = __clk_get_name(parent);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       reg = devm_ioremap_resource(dev, res);
+       if (IS_ERR(reg))
+               return PTR_ERR(reg);
+
+       for (i = 0; i < NUM_TBG; i++) {
+               const char *name;
+               unsigned int mult, div;
+
+               name = tbg[i].name;
+               mult = tbg_get_mult(reg, &tbg[i]);
+               div = tbg_get_div(reg, &tbg[i]);
+               hw_tbg_data->hws[i] = clk_hw_register_fixed_factor(NULL, name,
+                                               parent_name, 0, mult, div);
+               if (IS_ERR(hw_tbg_data->hws[i]))
+                       dev_err(dev, "Can't register TBG clock %s\n", name);
+       }
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_tbg_data);
+
+       return ret;
+}
+
+static int armada_3700_tbg_clock_remove(struct platform_device *pdev)
+{
+       int i;
+       struct clk_hw_onecell_data *hw_tbg_data = platform_get_drvdata(pdev);
+
+       of_clk_del_provider(pdev->dev.of_node);
+       for (i = 0; i < hw_tbg_data->num; i++)
+               clk_hw_unregister_fixed_factor(hw_tbg_data->hws[i]);
+
+       return 0;
+}
+
+static const struct of_device_id armada_3700_tbg_clock_of_match[] = {
+       { .compatible = "marvell,armada-3700-tbg-clock", },
+       { }
+};
+
+static struct platform_driver armada_3700_tbg_clock_driver = {
+       .probe = armada_3700_tbg_clock_probe,
+       .remove = armada_3700_tbg_clock_remove,
+       .driver         = {
+               .name   = "marvell-armada-3700-tbg-clock",
+               .of_match_table = armada_3700_tbg_clock_of_match,
+       },
+};
+
+builtin_platform_driver(armada_3700_tbg_clock_driver);
diff --git a/drivers/clk/mvebu/armada-37xx-xtal.c b/drivers/clk/mvebu/armada-37xx-xtal.c
new file mode 100644 (file)
index 0000000..612d65e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Marvell Armada 37xx SoC xtal clocks
+ *
+ * Copyright (C) 2016 Marvell
+ *
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define NB_GPIO1_LATCH 0xC
+#define XTAL_MODE          BIT(31)
+
+static int armada_3700_xtal_clock_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const char *xtal_name = "xtal";
+       struct device_node *parent;
+       struct regmap *regmap;
+       struct clk_hw *xtal_hw;
+       unsigned int rate;
+       u32 reg;
+       int ret;
+
+       xtal_hw = devm_kzalloc(&pdev->dev, sizeof(*xtal_hw), GFP_KERNEL);
+       if (!xtal_hw)
+               return -ENOMEM;
+
+       platform_set_drvdata(pdev, xtal_hw);
+
+       parent = np->parent;
+       if (!parent) {
+               dev_err(&pdev->dev, "no parent\n");
+               return -ENODEV;
+       }
+
+       regmap = syscon_node_to_regmap(parent);
+       if (IS_ERR(regmap)) {
+               dev_err(&pdev->dev, "cannot get regmap\n");
+               return PTR_ERR(regmap);
+       }
+
+       ret = regmap_read(regmap, NB_GPIO1_LATCH, &reg);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot read from regmap\n");
+               return ret;
+       }
+
+       if (reg & XTAL_MODE)
+               rate = 40000000;
+       else
+               rate = 25000000;
+
+       of_property_read_string_index(np, "clock-output-names", 0, &xtal_name);
+       xtal_hw = clk_hw_register_fixed_rate(NULL, xtal_name, NULL, 0, rate);
+       if (IS_ERR(xtal_hw))
+               return PTR_ERR(xtal_hw);
+       ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, xtal_hw);
+
+       return ret;
+}
+
+static int armada_3700_xtal_clock_remove(struct platform_device *pdev)
+{
+       of_clk_del_provider(pdev->dev.of_node);
+
+       return 0;
+}
+
+static const struct of_device_id armada_3700_xtal_clock_of_match[] = {
+       { .compatible = "marvell,armada-3700-xtal-clock", },
+       { }
+};
+
+static struct platform_driver armada_3700_xtal_clock_driver = {
+       .probe = armada_3700_xtal_clock_probe,
+       .remove = armada_3700_xtal_clock_remove,
+       .driver         = {
+               .name   = "marvell-armada-3700-xtal-clock",
+               .of_match_table = armada_3700_xtal_clock_of_match,
+       },
+};
+
+builtin_platform_driver(armada_3700_xtal_clock_driver);
index efb974d..4fdfd32 100644 (file)
@@ -142,6 +142,8 @@ static const struct clk_gating_soc_desc armada_39x_gating_desc[] __initconst = {
        { "pex3", NULL, 7 },
        { "pex0", NULL, 8 },
        { "usb3h0", NULL, 9 },
+       { "usb3h1", NULL, 10 },
+       { "sata0", NULL, 15 },
        { "sdio", NULL, 17 },
        { "xor0", NULL, 22 },
        { "xor1", NULL, 28 },
index 9e35749..c6e802e 100644 (file)
@@ -184,7 +184,8 @@ static void __init lpc18xx_creg_clk_init(struct device_node *np)
 
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data);
 }
-CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init);
+CLK_OF_DECLARE_DRIVER(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk",
+                     lpc18xx_creg_clk_init);
 
 static struct clk *clk_creg[CREG_CLK_MAX];
 static struct clk_onecell_data clk_creg_data = {
index 95e3b3e..0146d3c 100644 (file)
@@ -87,6 +87,23 @@ config MSM_LCC_8960
          Say Y if you want to use audio devices such as i2s, pcm,
          SLIMBus, etc.
 
+config MDM_GCC_9615
+       tristate "MDM9615 Global Clock Controller"
+       depends on COMMON_CLK_QCOM
+       help
+         Support for the global clock controller on mdm9615 devices.
+         Say Y if you want to use peripheral devices such as UART, SPI,
+         i2c, USB, SD/eMMC, etc.
+
+config MDM_LCC_9615
+       tristate "MDM9615 LPASS Clock Controller"
+       select MDM_GCC_9615
+       depends on COMMON_CLK_QCOM
+       help
+         Support for the LPASS clock controller on mdm9615 devices.
+         Say Y if you want to use audio devices such as i2s, pcm,
+         SLIMBus, etc.
+
 config MSM_MMCC_8960
        tristate "MSM8960 Multimedia Clock Controller"
        select MSM_GCC_8960
@@ -117,6 +134,7 @@ config MSM_MMCC_8974
 
 config MSM_GCC_8996
        tristate "MSM8996 Global Clock Controller"
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the global clock controller on msm8996 devices.
@@ -126,6 +144,7 @@ config MSM_GCC_8996
 config MSM_MMCC_8996
        tristate "MSM8996 Multimedia Clock Controller"
        select MSM_GCC_8996
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the multimedia clock controller on msm8996 devices.
index 2a25f4e..1fb1f54 100644 (file)
@@ -12,17 +12,20 @@ clk-qcom-y += clk-regmap-mux.o
 clk-qcom-y += reset.o
 clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 
+# Keep alphabetically sorted by config
 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_LCC_806X) += lcc-ipq806x.o
+obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
+obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
-obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
 obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
 obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
+obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
index a58ba39..1c856d3 100644 (file)
@@ -101,14 +101,13 @@ EXPORT_SYMBOL_GPL(clk_disable_regmap);
  * clk_regmap struct via this function so that the regmap is initialized
  * and so that the clock is registered with the common clock framework.
  */
-struct clk *devm_clk_register_regmap(struct device *dev,
-                                    struct clk_regmap *rclk)
+int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk)
 {
        if (dev && dev_get_regmap(dev, NULL))
                rclk->regmap = dev_get_regmap(dev, NULL);
        else if (dev && dev->parent)
                rclk->regmap = dev_get_regmap(dev->parent, NULL);
 
-       return devm_clk_register(dev, &rclk->hw);
+       return devm_clk_hw_register(dev, &rclk->hw);
 }
 EXPORT_SYMBOL_GPL(devm_clk_register_regmap);
index 491a63d..90d95cd 100644 (file)
@@ -39,7 +39,6 @@ struct clk_regmap {
 int clk_is_enabled_regmap(struct clk_hw *hw);
 int clk_enable_regmap(struct clk_hw *hw);
 void clk_disable_regmap(struct clk_hw *hw);
-struct clk *
-devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
+int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
 
 #endif
index f7c226a..fffcbaf 100644 (file)
@@ -27,8 +27,8 @@
 
 struct qcom_cc {
        struct qcom_reset_controller reset;
-       struct clk_onecell_data data;
-       struct clk *clks[];
+       struct clk_regmap **rclks;
+       size_t num_rclks;
 };
 
 const
@@ -102,8 +102,8 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
        struct device_node *clocks_node;
        struct clk_fixed_factor *factor;
        struct clk_fixed_rate *fixed;
-       struct clk *clk;
        struct clk_init_data init_data = { };
+       int ret;
 
        clocks_node = of_find_node_by_path("/clocks");
        if (clocks_node)
@@ -121,9 +121,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
                init_data.name = path;
                init_data.ops = &clk_fixed_rate_ops;
 
-               clk = devm_clk_register(dev, &fixed->hw);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
+               ret = devm_clk_hw_register(dev, &fixed->hw);
+               if (ret)
+                       return ret;
        }
        of_node_put(node);
 
@@ -141,9 +141,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path,
                init_data.flags = 0;
                init_data.ops = &clk_fixed_factor_ops;
 
-               clk = devm_clk_register(dev, &factor->hw);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
+               ret = devm_clk_hw_register(dev, &factor->hw);
+               if (ret)
+                       return ret;
        }
 
        return 0;
@@ -174,42 +174,48 @@ int qcom_cc_register_sleep_clk(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk);
 
+static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
+                                        void *data)
+{
+       struct qcom_cc *cc = data;
+       unsigned int idx = clkspec->args[0];
+
+       if (idx >= cc->num_rclks) {
+               pr_err("%s: invalid index %u\n", __func__, idx);
+               return ERR_PTR(-EINVAL);
+       }
+
+       return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT);
+}
+
 int qcom_cc_really_probe(struct platform_device *pdev,
                         const struct qcom_cc_desc *desc, struct regmap *regmap)
 {
        int i, ret;
        struct device *dev = &pdev->dev;
-       struct clk *clk;
-       struct clk_onecell_data *data;
-       struct clk **clks;
        struct qcom_reset_controller *reset;
        struct qcom_cc *cc;
        struct gdsc_desc *scd;
        size_t num_clks = desc->num_clks;
        struct clk_regmap **rclks = desc->clks;
 
-       cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks,
-                         GFP_KERNEL);
+       cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL);
        if (!cc)
                return -ENOMEM;
 
-       clks = cc->clks;
-       data = &cc->data;
-       data->clks = clks;
-       data->clk_num = num_clks;
+       cc->rclks = rclks;
+       cc->num_rclks = num_clks;
 
        for (i = 0; i < num_clks; i++) {
-               if (!rclks[i]) {
-                       clks[i] = ERR_PTR(-ENOENT);
+               if (!rclks[i])
                        continue;
-               }
-               clk = devm_clk_register_regmap(dev, rclks[i]);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
-               clks[i] = clk;
+
+               ret = devm_clk_register_regmap(dev, rclks[i]);
+               if (ret)
+                       return ret;
        }
 
-       ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data);
+       ret = of_clk_add_hw_provider(dev->of_node, qcom_cc_clk_hw_get, cc);
        if (ret)
                return ret;
 
index 3cd1af0..b593065 100644 (file)
@@ -1332,7 +1332,6 @@ static struct platform_driver gcc_ipq4019_driver = {
        .probe          = gcc_ipq4019_probe,
        .driver         = {
                .name   = "qcom,gcc-ipq4019",
-               .owner  = THIS_MODULE,
                .of_match_table = gcc_ipq4019_match_table,
        },
 };
diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c
new file mode 100644 (file)
index 0000000..581a17f
--- /dev/null
@@ -0,0 +1,1727 @@
+/*
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * 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/bitops.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 <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,gcc-mdm9615.h>
+#include <dt-bindings/reset/qcom,gcc-mdm9615.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+
+static struct clk_fixed_factor cxo = {
+       .mult = 1,
+       .div = 1,
+       .hw.init = &(struct clk_init_data){
+               .name = "cxo",
+               .parent_names = (const char *[]){ "cxo_board" },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static struct clk_pll pll0 = {
+       .l_reg = 0x30c4,
+       .m_reg = 0x30c8,
+       .n_reg = 0x30cc,
+       .config_reg = 0x30d4,
+       .mode_reg = 0x30c0,
+       .status_reg = 0x30d8,
+       .status_bit = 16,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pll0",
+               .parent_names = (const char *[]){ "cxo" },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap pll0_vote = {
+       .enable_reg = 0x34c0,
+       .enable_mask = BIT(0),
+       .hw.init = &(struct clk_init_data){
+               .name = "pll0_vote",
+               .parent_names = (const char *[]){ "pll8" },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_regmap pll4_vote = {
+       .enable_reg = 0x34c0,
+       .enable_mask = BIT(4),
+       .hw.init = &(struct clk_init_data){
+               .name = "pll4_vote",
+               .parent_names = (const char *[]){ "pll4" },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll pll8 = {
+       .l_reg = 0x3144,
+       .m_reg = 0x3148,
+       .n_reg = 0x314c,
+       .config_reg = 0x3154,
+       .mode_reg = 0x3140,
+       .status_reg = 0x3158,
+       .status_bit = 16,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pll8",
+               .parent_names = (const char *[]){ "cxo" },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap pll8_vote = {
+       .enable_reg = 0x34c0,
+       .enable_mask = BIT(8),
+       .hw.init = &(struct clk_init_data){
+               .name = "pll8_vote",
+               .parent_names = (const char *[]){ "pll8" },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+static struct clk_pll pll14 = {
+       .l_reg = 0x31c4,
+       .m_reg = 0x31c8,
+       .n_reg = 0x31cc,
+       .config_reg = 0x31d4,
+       .mode_reg = 0x31c0,
+       .status_reg = 0x31d8,
+       .status_bit = 16,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pll14",
+               .parent_names = (const char *[]){ "cxo" },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+static struct clk_regmap pll14_vote = {
+       .enable_reg = 0x34c0,
+       .enable_mask = BIT(11),
+       .hw.init = &(struct clk_init_data){
+               .name = "pll14_vote",
+               .parent_names = (const char *[]){ "pll14" },
+               .num_parents = 1,
+               .ops = &clk_pll_vote_ops,
+       },
+};
+
+enum {
+       P_CXO,
+       P_PLL8,
+       P_PLL14,
+};
+
+static const struct parent_map gcc_cxo_pll8_map[] = {
+       { P_CXO, 0 },
+       { P_PLL8, 3 }
+};
+
+static const char * const gcc_cxo_pll8[] = {
+       "cxo",
+       "pll8_vote",
+};
+
+static const struct parent_map gcc_cxo_pll14_map[] = {
+       { P_CXO, 0 },
+       { P_PLL14, 4 }
+};
+
+static const char * const gcc_cxo_pll14[] = {
+       "cxo",
+       "pll14_vote",
+};
+
+static const struct parent_map gcc_cxo_map[] = {
+       { P_CXO, 0 },
+};
+
+static const char * const gcc_cxo[] = {
+       "cxo",
+};
+
+static struct freq_tbl clk_tbl_gsbi_uart[] = {
+       {  1843200, P_PLL8, 2,  6, 625 },
+       {  3686400, P_PLL8, 2, 12, 625 },
+       {  7372800, P_PLL8, 2, 24, 625 },
+       { 14745600, P_PLL8, 2, 48, 625 },
+       { 16000000, P_PLL8, 4,  1,   6 },
+       { 24000000, P_PLL8, 4,  1,   4 },
+       { 32000000, P_PLL8, 4,  1,   3 },
+       { 40000000, P_PLL8, 1,  5,  48 },
+       { 46400000, P_PLL8, 1, 29, 240 },
+       { 48000000, P_PLL8, 4,  1,   2 },
+       { 51200000, P_PLL8, 1,  2,  15 },
+       { 56000000, P_PLL8, 1,  7,  48 },
+       { 58982400, P_PLL8, 1, 96, 625 },
+       { 64000000, P_PLL8, 2,  1,   3 },
+       { }
+};
+
+static struct clk_rcg gsbi1_uart_src = {
+       .ns_reg = 0x29d4,
+       .md_reg = 0x29d0,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 16,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_uart,
+       .clkr = {
+               .enable_reg = 0x29d4,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi1_uart_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi1_uart_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 10,
+       .clkr = {
+               .enable_reg = 0x29d4,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi1_uart_clk",
+                       .parent_names = (const char *[]){
+                               "gsbi1_uart_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi2_uart_src = {
+       .ns_reg = 0x29f4,
+       .md_reg = 0x29f0,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 16,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_uart,
+       .clkr = {
+               .enable_reg = 0x29f4,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi2_uart_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi2_uart_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 6,
+       .clkr = {
+               .enable_reg = 0x29f4,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi2_uart_clk",
+                       .parent_names = (const char *[]){
+                               "gsbi2_uart_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi3_uart_src = {
+       .ns_reg = 0x2a14,
+       .md_reg = 0x2a10,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 16,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_uart,
+       .clkr = {
+               .enable_reg = 0x2a14,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi3_uart_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi3_uart_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 2,
+       .clkr = {
+               .enable_reg = 0x2a14,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi3_uart_clk",
+                       .parent_names = (const char *[]){
+                               "gsbi3_uart_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi4_uart_src = {
+       .ns_reg = 0x2a34,
+       .md_reg = 0x2a30,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 16,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_uart,
+       .clkr = {
+               .enable_reg = 0x2a34,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi4_uart_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi4_uart_clk = {
+       .halt_reg = 0x2fd0,
+       .halt_bit = 26,
+       .clkr = {
+               .enable_reg = 0x2a34,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi4_uart_clk",
+                       .parent_names = (const char *[]){
+                               "gsbi4_uart_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi5_uart_src = {
+       .ns_reg = 0x2a54,
+       .md_reg = 0x2a50,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 16,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_uart,
+       .clkr = {
+               .enable_reg = 0x2a54,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi5_uart_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi5_uart_clk = {
+       .halt_reg = 0x2fd0,
+       .halt_bit = 22,
+       .clkr = {
+               .enable_reg = 0x2a54,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi5_uart_clk",
+                       .parent_names = (const char *[]){
+                               "gsbi5_uart_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct freq_tbl clk_tbl_gsbi_qup[] = {
+       {   960000, P_CXO,  4, 1,  5 },
+       {  4800000, P_CXO,  4, 0,  1 },
+       {  9600000, P_CXO,  2, 0,  1 },
+       { 15060000, P_PLL8, 1, 2, 51 },
+       { 24000000, P_PLL8, 4, 1,  4 },
+       { 25600000, P_PLL8, 1, 1, 15 },
+       { 48000000, P_PLL8, 4, 1,  2 },
+       { 51200000, P_PLL8, 1, 2, 15 },
+       { }
+};
+
+static struct clk_rcg gsbi1_qup_src = {
+       .ns_reg = 0x29cc,
+       .md_reg = 0x29c8,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_qup,
+       .clkr = {
+               .enable_reg = 0x29cc,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi1_qup_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi1_qup_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 9,
+       .clkr = {
+               .enable_reg = 0x29cc,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi1_qup_clk",
+                       .parent_names = (const char *[]){ "gsbi1_qup_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi2_qup_src = {
+       .ns_reg = 0x29ec,
+       .md_reg = 0x29e8,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_qup,
+       .clkr = {
+               .enable_reg = 0x29ec,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi2_qup_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi2_qup_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 4,
+       .clkr = {
+               .enable_reg = 0x29ec,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi2_qup_clk",
+                       .parent_names = (const char *[]){ "gsbi2_qup_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi3_qup_src = {
+       .ns_reg = 0x2a0c,
+       .md_reg = 0x2a08,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_qup,
+       .clkr = {
+               .enable_reg = 0x2a0c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi3_qup_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi3_qup_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 0,
+       .clkr = {
+               .enable_reg = 0x2a0c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi3_qup_clk",
+                       .parent_names = (const char *[]){ "gsbi3_qup_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi4_qup_src = {
+       .ns_reg = 0x2a2c,
+       .md_reg = 0x2a28,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_qup,
+       .clkr = {
+               .enable_reg = 0x2a2c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi4_qup_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi4_qup_clk = {
+       .halt_reg = 0x2fd0,
+       .halt_bit = 24,
+       .clkr = {
+               .enable_reg = 0x2a2c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi4_qup_clk",
+                       .parent_names = (const char *[]){ "gsbi4_qup_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gsbi5_qup_src = {
+       .ns_reg = 0x2a4c,
+       .md_reg = 0x2a48,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_gsbi_qup,
+       .clkr = {
+               .enable_reg = 0x2a4c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi5_qup_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       },
+};
+
+static struct clk_branch gsbi5_qup_clk = {
+       .halt_reg = 0x2fd0,
+       .halt_bit = 20,
+       .clkr = {
+               .enable_reg = 0x2a4c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi5_qup_clk",
+                       .parent_names = (const char *[]){ "gsbi5_qup_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl clk_tbl_gp[] = {
+       { 9600000, P_CXO,  2, 0, 0 },
+       { 19200000, P_CXO,  1, 0, 0 },
+       { }
+};
+
+static struct clk_rcg gp0_src = {
+       .ns_reg = 0x2d24,
+       .md_reg = 0x2d00,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_map,
+       },
+       .freq_tbl = clk_tbl_gp,
+       .clkr = {
+               .enable_reg = 0x2d24,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gp0_src",
+                       .parent_names = gcc_cxo,
+                       .num_parents = 1,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_PARENT_GATE,
+               },
+       }
+};
+
+static struct clk_branch gp0_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_bit = 7,
+       .clkr = {
+               .enable_reg = 0x2d24,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gp0_clk",
+                       .parent_names = (const char *[]){ "gp0_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gp1_src = {
+       .ns_reg = 0x2d44,
+       .md_reg = 0x2d40,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_map,
+       },
+       .freq_tbl = clk_tbl_gp,
+       .clkr = {
+               .enable_reg = 0x2d44,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gp1_src",
+                       .parent_names = gcc_cxo,
+                       .num_parents = 1,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch gp1_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_bit = 6,
+       .clkr = {
+               .enable_reg = 0x2d44,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gp1_clk",
+                       .parent_names = (const char *[]){ "gp1_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg gp2_src = {
+       .ns_reg = 0x2d64,
+       .md_reg = 0x2d60,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_map,
+       },
+       .freq_tbl = clk_tbl_gp,
+       .clkr = {
+               .enable_reg = 0x2d64,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gp2_src",
+                       .parent_names = gcc_cxo,
+                       .num_parents = 1,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch gp2_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_bit = 5,
+       .clkr = {
+               .enable_reg = 0x2d64,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gp2_clk",
+                       .parent_names = (const char *[]){ "gp2_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch pmem_clk = {
+       .hwcg_reg = 0x25a0,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fc8,
+       .halt_bit = 20,
+       .clkr = {
+               .enable_reg = 0x25a0,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "pmem_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_rcg prng_src = {
+       .ns_reg = 0x2e80,
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "prng_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+               },
+       },
+};
+
+static struct clk_branch prng_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 10,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "prng_clk",
+                       .parent_names = (const char *[]){ "prng_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static const struct freq_tbl clk_tbl_sdc[] = {
+       {    144000, P_CXO,   1, 1, 133 },
+       {    400000, P_PLL8,  4, 1, 240 },
+       {  16000000, P_PLL8,  4, 1,   6 },
+       {  17070000, P_PLL8,  1, 2,  45 },
+       {  20210000, P_PLL8,  1, 1,  19 },
+       {  24000000, P_PLL8,  4, 1,   4 },
+       {  38400000, P_PLL8,  2, 1,   5 },
+       {  48000000, P_PLL8,  4, 1,   2 },
+       {  64000000, P_PLL8,  3, 1,   2 },
+       {  76800000, P_PLL8,  1, 1,   5 },
+       { }
+};
+
+static struct clk_rcg sdc1_src = {
+       .ns_reg = 0x282c,
+       .md_reg = 0x2828,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_sdc,
+       .clkr = {
+               .enable_reg = 0x282c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sdc1_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch sdc1_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 6,
+       .clkr = {
+               .enable_reg = 0x282c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sdc1_clk",
+                       .parent_names = (const char *[]){ "sdc1_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg sdc2_src = {
+       .ns_reg = 0x284c,
+       .md_reg = 0x2848,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_sdc,
+       .clkr = {
+               .enable_reg = 0x284c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sdc2_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch sdc2_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 5,
+       .clkr = {
+               .enable_reg = 0x284c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sdc2_clk",
+                       .parent_names = (const char *[]){ "sdc2_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl clk_tbl_usb[] = {
+       { 60000000, P_PLL8, 1, 5, 32 },
+       { }
+};
+
+static struct clk_rcg usb_hs1_xcvr_src = {
+       .ns_reg = 0x290c,
+       .md_reg = 0x2908,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_usb,
+       .clkr = {
+               .enable_reg = 0x290c,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hs1_xcvr_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch usb_hs1_xcvr_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 0,
+       .clkr = {
+               .enable_reg = 0x290c,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hs1_xcvr_clk",
+                       .parent_names = (const char *[]){ "usb_hs1_xcvr_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg usb_hsic_xcvr_fs_src = {
+       .ns_reg = 0x2928,
+       .md_reg = 0x2924,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_usb,
+       .clkr = {
+               .enable_reg = 0x2928,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hsic_xcvr_fs_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch usb_hsic_xcvr_fs_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 9,
+       .clkr = {
+               .enable_reg = 0x2928,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hsic_xcvr_fs_clk",
+                       .parent_names =
+                               (const char *[]){ "usb_hsic_xcvr_fs_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl clk_tbl_usb_hs1_system[] = {
+       { 60000000, P_PLL8, 1, 5, 32 },
+       { }
+};
+
+static struct clk_rcg usb_hs1_system_src = {
+       .ns_reg = 0x36a4,
+       .md_reg = 0x36a0,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_usb_hs1_system,
+       .clkr = {
+               .enable_reg = 0x36a4,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hs1_system_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch usb_hs1_system_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 4,
+       .clkr = {
+               .enable_reg = 0x36a4,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .parent_names =
+                               (const char *[]){ "usb_hs1_system_src" },
+                       .num_parents = 1,
+                       .name = "usb_hs1_system_clk",
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+               },
+       },
+};
+
+static const struct freq_tbl clk_tbl_usb_hsic_system[] = {
+       { 64000000, P_PLL8, 1, 1, 6 },
+       { }
+};
+
+static struct clk_rcg usb_hsic_system_src = {
+       .ns_reg = 0x2b58,
+       .md_reg = 0x2b54,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll8_map,
+       },
+       .freq_tbl = clk_tbl_usb_hsic_system,
+       .clkr = {
+               .enable_reg = 0x2b58,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hsic_system_src",
+                       .parent_names = gcc_cxo_pll8,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch usb_hsic_system_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 7,
+       .clkr = {
+               .enable_reg = 0x2b58,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .parent_names =
+                               (const char *[]){ "usb_hsic_system_src" },
+                       .num_parents = 1,
+                       .name = "usb_hsic_system_clk",
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl clk_tbl_usb_hsic_hsic[] = {
+       { 48000000, P_PLL14, 1, 0, 0 },
+       { }
+};
+
+static struct clk_rcg usb_hsic_hsic_src = {
+       .ns_reg = 0x2b50,
+       .md_reg = 0x2b4c,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = gcc_cxo_pll14_map,
+       },
+       .freq_tbl = clk_tbl_usb_hsic_hsic,
+       .clkr = {
+               .enable_reg = 0x2b50,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hsic_hsic_src",
+                       .parent_names = gcc_cxo_pll14,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       }
+};
+
+static struct clk_branch usb_hsic_hsic_clk = {
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x2b50,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .parent_names = (const char *[]){ "usb_hsic_hsic_src" },
+                       .num_parents = 1,
+                       .name = "usb_hsic_hsic_clk",
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch usb_hsic_hsio_cal_clk = {
+       .halt_reg = 0x2fc8,
+       .halt_bit = 8,
+       .clkr = {
+               .enable_reg = 0x2b48,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .parent_names = (const char *[]){ "cxo" },
+                       .num_parents = 1,
+                       .name = "usb_hsic_hsio_cal_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch ce1_core_clk = {
+       .hwcg_reg = 0x2724,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fd4,
+       .halt_bit = 27,
+       .clkr = {
+               .enable_reg = 0x2724,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "ce1_core_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch ce1_h_clk = {
+       .halt_reg = 0x2fd4,
+       .halt_bit = 1,
+       .clkr = {
+               .enable_reg = 0x2720,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "ce1_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch dma_bam_h_clk = {
+       .hwcg_reg = 0x25c0,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fc8,
+       .halt_bit = 12,
+       .clkr = {
+               .enable_reg = 0x25c0,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dma_bam_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch gsbi1_h_clk = {
+       .hwcg_reg = 0x29c0,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fcc,
+       .halt_bit = 11,
+       .clkr = {
+               .enable_reg = 0x29c0,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi1_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch gsbi2_h_clk = {
+       .hwcg_reg = 0x29e0,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fcc,
+       .halt_bit = 7,
+       .clkr = {
+               .enable_reg = 0x29e0,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi2_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch gsbi3_h_clk = {
+       .hwcg_reg = 0x2a00,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fcc,
+       .halt_bit = 3,
+       .clkr = {
+               .enable_reg = 0x2a00,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi3_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch gsbi4_h_clk = {
+       .hwcg_reg = 0x2a20,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fd0,
+       .halt_bit = 27,
+       .clkr = {
+               .enable_reg = 0x2a20,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi4_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch gsbi5_h_clk = {
+       .hwcg_reg = 0x2a40,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fd0,
+       .halt_bit = 23,
+       .clkr = {
+               .enable_reg = 0x2a40,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gsbi5_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch usb_hs1_h_clk = {
+       .hwcg_reg = 0x2900,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fc8,
+       .halt_bit = 1,
+       .clkr = {
+               .enable_reg = 0x2900,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hs1_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch usb_hsic_h_clk = {
+       .halt_reg = 0x2fcc,
+       .halt_bit = 28,
+       .clkr = {
+               .enable_reg = 0x2920,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb_hsic_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch sdc1_h_clk = {
+       .hwcg_reg = 0x2820,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fc8,
+       .halt_bit = 11,
+       .clkr = {
+               .enable_reg = 0x2820,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sdc1_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch sdc2_h_clk = {
+       .hwcg_reg = 0x2840,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fc8,
+       .halt_bit = 10,
+       .clkr = {
+               .enable_reg = 0x2840,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sdc2_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch adm0_clk = {
+       .halt_reg = 0x2fdc,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 14,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "adm0_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch adm0_pbus_clk = {
+       .hwcg_reg = 0x2208,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fdc,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 13,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(3),
+               .hw.init = &(struct clk_init_data){
+                       .name = "adm0_pbus_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch pmic_arb0_h_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 22,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "pmic_arb0_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch pmic_arb1_h_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 21,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "pmic_arb1_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch pmic_ssbi2_clk = {
+       .halt_reg = 0x2fd8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 23,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "pmic_ssbi2_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_branch rpm_msg_ram_h_clk = {
+       .hwcg_reg = 0x27e0,
+       .hwcg_bit = 6,
+       .halt_reg = 0x2fd8,
+       .halt_check = BRANCH_HALT_VOTED,
+       .halt_bit = 12,
+       .clkr = {
+               .enable_reg = 0x3080,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "rpm_msg_ram_h_clk",
+                       .ops = &clk_branch_ops,
+               },
+       },
+};
+
+static struct clk_hw *gcc_mdm9615_hws[] = {
+       &cxo.hw,
+};
+
+static struct clk_regmap *gcc_mdm9615_clks[] = {
+       [PLL0] = &pll0.clkr,
+       [PLL0_VOTE] = &pll0_vote,
+       [PLL4_VOTE] = &pll4_vote,
+       [PLL8] = &pll8.clkr,
+       [PLL8_VOTE] = &pll8_vote,
+       [PLL14] = &pll14.clkr,
+       [PLL14_VOTE] = &pll14_vote,
+       [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
+       [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
+       [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
+       [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr,
+       [GSBI3_UART_SRC] = &gsbi3_uart_src.clkr,
+       [GSBI3_UART_CLK] = &gsbi3_uart_clk.clkr,
+       [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr,
+       [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr,
+       [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr,
+       [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr,
+       [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr,
+       [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr,
+       [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr,
+       [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr,
+       [GSBI3_QUP_SRC] = &gsbi3_qup_src.clkr,
+       [GSBI3_QUP_CLK] = &gsbi3_qup_clk.clkr,
+       [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr,
+       [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr,
+       [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr,
+       [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr,
+       [GP0_SRC] = &gp0_src.clkr,
+       [GP0_CLK] = &gp0_clk.clkr,
+       [GP1_SRC] = &gp1_src.clkr,
+       [GP1_CLK] = &gp1_clk.clkr,
+       [GP2_SRC] = &gp2_src.clkr,
+       [GP2_CLK] = &gp2_clk.clkr,
+       [PMEM_A_CLK] = &pmem_clk.clkr,
+       [PRNG_SRC] = &prng_src.clkr,
+       [PRNG_CLK] = &prng_clk.clkr,
+       [SDC1_SRC] = &sdc1_src.clkr,
+       [SDC1_CLK] = &sdc1_clk.clkr,
+       [SDC2_SRC] = &sdc2_src.clkr,
+       [SDC2_CLK] = &sdc2_clk.clkr,
+       [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_src.clkr,
+       [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr,
+       [USB_HS1_SYSTEM_CLK_SRC] = &usb_hs1_system_src.clkr,
+       [USB_HS1_SYSTEM_CLK] = &usb_hs1_system_clk.clkr,
+       [USB_HSIC_XCVR_FS_SRC] = &usb_hsic_xcvr_fs_src.clkr,
+       [USB_HSIC_XCVR_FS_CLK] = &usb_hsic_xcvr_fs_clk.clkr,
+       [USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_src.clkr,
+       [USB_HSIC_SYSTEM_CLK] = &usb_hsic_system_clk.clkr,
+       [USB_HSIC_HSIC_CLK_SRC] = &usb_hsic_hsic_src.clkr,
+       [USB_HSIC_HSIC_CLK] = &usb_hsic_hsic_clk.clkr,
+       [USB_HSIC_HSIO_CAL_CLK] = &usb_hsic_hsio_cal_clk.clkr,
+       [CE1_CORE_CLK] = &ce1_core_clk.clkr,
+       [CE1_H_CLK] = &ce1_h_clk.clkr,
+       [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr,
+       [GSBI1_H_CLK] = &gsbi1_h_clk.clkr,
+       [GSBI2_H_CLK] = &gsbi2_h_clk.clkr,
+       [GSBI3_H_CLK] = &gsbi3_h_clk.clkr,
+       [GSBI4_H_CLK] = &gsbi4_h_clk.clkr,
+       [GSBI5_H_CLK] = &gsbi5_h_clk.clkr,
+       [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr,
+       [USB_HSIC_H_CLK] = &usb_hsic_h_clk.clkr,
+       [SDC1_H_CLK] = &sdc1_h_clk.clkr,
+       [SDC2_H_CLK] = &sdc2_h_clk.clkr,
+       [ADM0_CLK] = &adm0_clk.clkr,
+       [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
+       [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr,
+       [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
+       [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
+       [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
+};
+
+static const struct qcom_reset_map gcc_mdm9615_resets[] = {
+       [DMA_BAM_RESET] = { 0x25c0, 7 },
+       [CE1_H_RESET] = { 0x2720, 7 },
+       [CE1_CORE_RESET] = { 0x2724, 7 },
+       [SDC1_RESET] = { 0x2830 },
+       [SDC2_RESET] = { 0x2850 },
+       [ADM0_C2_RESET] = { 0x220c, 4 },
+       [ADM0_C1_RESET] = { 0x220c, 3 },
+       [ADM0_C0_RESET] = { 0x220c, 2 },
+       [ADM0_PBUS_RESET] = { 0x220c, 1 },
+       [ADM0_RESET] = { 0x220c },
+       [USB_HS1_RESET] = { 0x2910 },
+       [USB_HSIC_RESET] = { 0x2934 },
+       [GSBI1_RESET] = { 0x29dc },
+       [GSBI2_RESET] = { 0x29fc },
+       [GSBI3_RESET] = { 0x2a1c },
+       [GSBI4_RESET] = { 0x2a3c },
+       [GSBI5_RESET] = { 0x2a5c },
+       [PDM_RESET] = { 0x2CC0, 12 },
+};
+
+static const struct regmap_config gcc_mdm9615_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x3660,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_mdm9615_desc = {
+       .config = &gcc_mdm9615_regmap_config,
+       .clks = gcc_mdm9615_clks,
+       .num_clks = ARRAY_SIZE(gcc_mdm9615_clks),
+       .resets = gcc_mdm9615_resets,
+       .num_resets = ARRAY_SIZE(gcc_mdm9615_resets),
+};
+
+static const struct of_device_id gcc_mdm9615_match_table[] = {
+       { .compatible = "qcom,gcc-mdm9615" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_mdm9615_match_table);
+
+static int gcc_mdm9615_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct regmap *regmap;
+       int ret;
+       int i;
+
+       regmap = qcom_cc_map(pdev, &gcc_mdm9615_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       for (i = 0; i < ARRAY_SIZE(gcc_mdm9615_hws); i++) {
+               ret = devm_clk_hw_register(dev, gcc_mdm9615_hws[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap);
+}
+
+static struct platform_driver gcc_mdm9615_driver = {
+       .probe          = gcc_mdm9615_probe,
+       .driver         = {
+               .name   = "gcc-mdm9615",
+               .of_match_table = gcc_mdm9615_match_table,
+       },
+};
+
+static int __init gcc_mdm9615_init(void)
+{
+       return platform_driver_register(&gcc_mdm9615_driver);
+}
+core_initcall(gcc_mdm9615_init);
+
+static void __exit gcc_mdm9615_exit(void)
+{
+       platform_driver_unregister(&gcc_mdm9615_driver);
+}
+module_exit(gcc_mdm9615_exit);
+
+MODULE_DESCRIPTION("QCOM GCC MDM9615 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:gcc-mdm9615");
index bbf732b..ebe5d18 100644 (file)
@@ -2592,9 +2592,9 @@ static struct clk_branch gcc_pcie_2_aux_clk = {
 };
 
 static struct clk_branch gcc_pcie_2_pipe_clk = {
-       .halt_reg = 0x6e108,
+       .halt_reg = 0x6e018,
        .clkr = {
-               .enable_reg = 0x6e108,
+               .enable_reg = 0x6e018,
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_2_pipe_clk",
@@ -3404,6 +3404,8 @@ static const struct qcom_reset_map gcc_msm8996_resets[] = {
        [GCC_PCIE_2_BCR] = { 0x6e000 },
        [GCC_PCIE_2_PHY_BCR] = { 0x6e038 },
        [GCC_PCIE_PHY_BCR] = { 0x6f000 },
+       [GCC_PCIE_PHY_COM_BCR] = { 0x6f014 },
+       [GCC_PCIE_PHY_COM_NOCSR_BCR] = { 0x6f00c },
        [GCC_DCD_BCR] = { 0x70000 },
        [GCC_OBT_ODT_BCR] = { 0x73000 },
        [GCC_UFS_BCR] = { 0x75000 },
@@ -3447,9 +3449,8 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table);
 
 static int gcc_msm8996_probe(struct platform_device *pdev)
 {
-       struct clk *clk;
        struct device *dev = &pdev->dev;
-       int i;
+       int i, ret;
        struct regmap *regmap;
 
        regmap = qcom_cc_map(pdev, &gcc_msm8996_desc);
@@ -3463,9 +3464,9 @@ static int gcc_msm8996_probe(struct platform_device *pdev)
        regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
 
        for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) {
-               clk = devm_clk_register(dev, gcc_msm8996_hws[i]);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
+               ret = devm_clk_hw_register(dev, gcc_msm8996_hws[i]);
+               if (ret)
+                       return ret;
        }
 
        return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
diff --git a/drivers/clk/qcom/lcc-mdm9615.c b/drivers/clk/qcom/lcc-mdm9615.c
new file mode 100644 (file)
index 0000000..3237ef4
--- /dev/null
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * 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/bitops.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,lcc-mdm9615.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+
+static struct clk_pll pll4 = {
+       .l_reg = 0x4,
+       .m_reg = 0x8,
+       .n_reg = 0xc,
+       .config_reg = 0x14,
+       .mode_reg = 0x0,
+       .status_reg = 0x18,
+       .status_bit = 16,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pll4",
+               .parent_names = (const char *[]){ "cxo" },
+               .num_parents = 1,
+               .ops = &clk_pll_ops,
+       },
+};
+
+enum {
+       P_CXO,
+       P_PLL4,
+};
+
+static const struct parent_map lcc_cxo_pll4_map[] = {
+       { P_CXO, 0 },
+       { P_PLL4, 2 }
+};
+
+static const char * const lcc_cxo_pll4[] = {
+       "cxo",
+       "pll4_vote",
+};
+
+static struct freq_tbl clk_tbl_aif_osr_492[] = {
+       {   512000, P_PLL4, 4, 1, 240 },
+       {   768000, P_PLL4, 4, 1, 160 },
+       {  1024000, P_PLL4, 4, 1, 120 },
+       {  1536000, P_PLL4, 4, 1,  80 },
+       {  2048000, P_PLL4, 4, 1,  60 },
+       {  3072000, P_PLL4, 4, 1,  40 },
+       {  4096000, P_PLL4, 4, 1,  30 },
+       {  6144000, P_PLL4, 4, 1,  20 },
+       {  8192000, P_PLL4, 4, 1,  15 },
+       { 12288000, P_PLL4, 4, 1,  10 },
+       { 24576000, P_PLL4, 4, 1,   5 },
+       { 27000000, P_CXO,  1, 0,   0 },
+       { }
+};
+
+static struct freq_tbl clk_tbl_aif_osr_393[] = {
+       {   512000, P_PLL4, 4, 1, 192 },
+       {   768000, P_PLL4, 4, 1, 128 },
+       {  1024000, P_PLL4, 4, 1,  96 },
+       {  1536000, P_PLL4, 4, 1,  64 },
+       {  2048000, P_PLL4, 4, 1,  48 },
+       {  3072000, P_PLL4, 4, 1,  32 },
+       {  4096000, P_PLL4, 4, 1,  24 },
+       {  6144000, P_PLL4, 4, 1,  16 },
+       {  8192000, P_PLL4, 4, 1,  12 },
+       { 12288000, P_PLL4, 4, 1,   8 },
+       { 24576000, P_PLL4, 4, 1,   4 },
+       { 27000000, P_CXO,  1, 0,   0 },
+       { }
+};
+
+static struct clk_rcg mi2s_osr_src = {
+       .ns_reg = 0x48,
+       .md_reg = 0x4c,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 24,
+               .m_val_shift = 8,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = lcc_cxo_pll4_map,
+       },
+       .freq_tbl = clk_tbl_aif_osr_393,
+       .clkr = {
+               .enable_reg = 0x48,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mi2s_osr_src",
+                       .parent_names = lcc_cxo_pll4,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       },
+};
+
+static const char * const lcc_mi2s_parents[] = {
+       "mi2s_osr_src",
+};
+
+static struct clk_branch mi2s_osr_clk = {
+       .halt_reg = 0x50,
+       .halt_bit = 1,
+       .halt_check = BRANCH_HALT_ENABLE,
+       .clkr = {
+               .enable_reg = 0x48,
+               .enable_mask = BIT(17),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mi2s_osr_clk",
+                       .parent_names = lcc_mi2s_parents,
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div mi2s_div_clk = {
+       .reg = 0x48,
+       .shift = 10,
+       .width = 4,
+       .clkr = {
+               .enable_reg = 0x48,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mi2s_div_clk",
+                       .parent_names = lcc_mi2s_parents,
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+               },
+       },
+};
+
+static struct clk_branch mi2s_bit_div_clk = {
+       .halt_reg = 0x50,
+       .halt_bit = 0,
+       .halt_check = BRANCH_HALT_ENABLE,
+       .clkr = {
+               .enable_reg = 0x48,
+               .enable_mask = BIT(15),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mi2s_bit_div_clk",
+                       .parent_names = (const char *[]){ "mi2s_div_clk" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_mux mi2s_bit_clk = {
+       .reg = 0x48,
+       .shift = 14,
+       .width = 1,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "mi2s_bit_clk",
+                       .parent_names = (const char *[]){
+                               "mi2s_bit_div_clk",
+                               "mi2s_codec_clk",
+                       },
+                       .num_parents = 2,
+                       .ops = &clk_regmap_mux_closest_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)                  \
+static struct clk_rcg prefix##_osr_src = {                     \
+       .ns_reg = _ns,                                          \
+       .md_reg = _md,                                          \
+       .mn = {                                                 \
+               .mnctr_en_bit = 8,                              \
+               .mnctr_reset_bit = 7,                           \
+               .mnctr_mode_shift = 5,                          \
+               .n_val_shift = 24,                              \
+               .m_val_shift = 8,                               \
+               .width = 8,                                     \
+       },                                                      \
+       .p = {                                                  \
+               .pre_div_shift = 3,                             \
+               .pre_div_width = 2,                             \
+       },                                                      \
+       .s = {                                                  \
+               .src_sel_shift = 0,                             \
+               .parent_map = lcc_cxo_pll4_map,                 \
+       },                                                      \
+       .freq_tbl = clk_tbl_aif_osr_393,                        \
+       .clkr = {                                               \
+               .enable_reg = _ns,                              \
+               .enable_mask = BIT(9),                          \
+               .hw.init = &(struct clk_init_data){             \
+                       .name = #prefix "_osr_src",             \
+                       .parent_names = lcc_cxo_pll4,           \
+                       .num_parents = 2,                       \
+                       .ops = &clk_rcg_ops,                    \
+                       .flags = CLK_SET_RATE_GATE,             \
+               },                                              \
+       },                                                      \
+};                                                             \
+                                                               \
+static const char * const lcc_##prefix##_parents[] = {         \
+       #prefix "_osr_src",                                     \
+};                                                             \
+                                                               \
+static struct clk_branch prefix##_osr_clk = {                  \
+       .halt_reg = hr,                                         \
+       .halt_bit = 1,                                          \
+       .halt_check = BRANCH_HALT_ENABLE,                       \
+       .clkr = {                                               \
+               .enable_reg = _ns,                              \
+               .enable_mask = BIT(21),                         \
+               .hw.init = &(struct clk_init_data){             \
+                       .name = #prefix "_osr_clk",             \
+                       .parent_names = lcc_##prefix##_parents, \
+                       .num_parents = 1,                       \
+                       .ops = &clk_branch_ops,                 \
+                       .flags = CLK_SET_RATE_PARENT,           \
+               },                                              \
+       },                                                      \
+};                                                             \
+                                                               \
+static struct clk_regmap_div prefix##_div_clk = {              \
+       .reg = _ns,                                             \
+       .shift = 10,                                            \
+       .width = 8,                                             \
+       .clkr = {                                               \
+               .hw.init = &(struct clk_init_data){             \
+                       .name = #prefix "_div_clk",             \
+                       .parent_names = lcc_##prefix##_parents, \
+                       .num_parents = 1,                       \
+                       .ops = &clk_regmap_div_ops,             \
+               },                                              \
+       },                                                      \
+};                                                             \
+                                                               \
+static struct clk_branch prefix##_bit_div_clk = {              \
+       .halt_reg = hr,                                         \
+       .halt_bit = 0,                                          \
+       .halt_check = BRANCH_HALT_ENABLE,                       \
+       .clkr = {                                               \
+               .enable_reg = _ns,                              \
+               .enable_mask = BIT(19),                         \
+               .hw.init = &(struct clk_init_data){             \
+                       .name = #prefix "_bit_div_clk",         \
+                       .parent_names = (const char *[]){       \
+                               #prefix "_div_clk"              \
+                       },                                      \
+                       .num_parents = 1,                       \
+                       .ops = &clk_branch_ops,                 \
+                       .flags = CLK_SET_RATE_PARENT,           \
+               },                                              \
+       },                                                      \
+};                                                             \
+                                                               \
+static struct clk_regmap_mux prefix##_bit_clk = {              \
+       .reg = _ns,                                             \
+       .shift = 18,                                            \
+       .width = 1,                                             \
+       .clkr = {                                               \
+               .hw.init = &(struct clk_init_data){             \
+                       .name = #prefix "_bit_clk",             \
+                       .parent_names = (const char *[]){       \
+                               #prefix "_bit_div_clk",         \
+                               #prefix "_codec_clk",           \
+                       },                                      \
+                       .num_parents = 2,                       \
+                       .ops = &clk_regmap_mux_closest_ops,     \
+                       .flags = CLK_SET_RATE_PARENT,           \
+               },                                              \
+       },                                                      \
+}
+
+CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
+CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
+CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74);
+CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c);
+
+static struct freq_tbl clk_tbl_pcm_492[] = {
+       {   256000, P_PLL4, 4, 1, 480 },
+       {   512000, P_PLL4, 4, 1, 240 },
+       {   768000, P_PLL4, 4, 1, 160 },
+       {  1024000, P_PLL4, 4, 1, 120 },
+       {  1536000, P_PLL4, 4, 1,  80 },
+       {  2048000, P_PLL4, 4, 1,  60 },
+       {  3072000, P_PLL4, 4, 1,  40 },
+       {  4096000, P_PLL4, 4, 1,  30 },
+       {  6144000, P_PLL4, 4, 1,  20 },
+       {  8192000, P_PLL4, 4, 1,  15 },
+       { 12288000, P_PLL4, 4, 1,  10 },
+       { 24576000, P_PLL4, 4, 1,   5 },
+       { 27000000, P_CXO,  1, 0,   0 },
+       { }
+};
+
+static struct freq_tbl clk_tbl_pcm_393[] = {
+       {   256000, P_PLL4, 4, 1, 384 },
+       {   512000, P_PLL4, 4, 1, 192 },
+       {   768000, P_PLL4, 4, 1, 128 },
+       {  1024000, P_PLL4, 4, 1,  96 },
+       {  1536000, P_PLL4, 4, 1,  64 },
+       {  2048000, P_PLL4, 4, 1,  48 },
+       {  3072000, P_PLL4, 4, 1,  32 },
+       {  4096000, P_PLL4, 4, 1,  24 },
+       {  6144000, P_PLL4, 4, 1,  16 },
+       {  8192000, P_PLL4, 4, 1,  12 },
+       { 12288000, P_PLL4, 4, 1,   8 },
+       { 24576000, P_PLL4, 4, 1,   4 },
+       { 27000000, P_CXO,  1, 0,   0 },
+       { }
+};
+
+static struct clk_rcg pcm_src = {
+       .ns_reg = 0x54,
+       .md_reg = 0x58,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 16,
+               .m_val_shift = 16,
+               .width = 16,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = lcc_cxo_pll4_map,
+       },
+       .freq_tbl = clk_tbl_pcm_393,
+       .clkr = {
+               .enable_reg = 0x54,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "pcm_src",
+                       .parent_names = lcc_cxo_pll4,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       },
+};
+
+static struct clk_branch pcm_clk_out = {
+       .halt_reg = 0x5c,
+       .halt_bit = 0,
+       .halt_check = BRANCH_HALT_ENABLE,
+       .clkr = {
+               .enable_reg = 0x54,
+               .enable_mask = BIT(11),
+               .hw.init = &(struct clk_init_data){
+                       .name = "pcm_clk_out",
+                       .parent_names = (const char *[]){ "pcm_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_mux pcm_clk = {
+       .reg = 0x54,
+       .shift = 10,
+       .width = 1,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "pcm_clk",
+                       .parent_names = (const char *[]){
+                               "pcm_clk_out",
+                               "pcm_codec_clk",
+                       },
+                       .num_parents = 2,
+                       .ops = &clk_regmap_mux_closest_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg slimbus_src = {
+       .ns_reg = 0xcc,
+       .md_reg = 0xd0,
+       .mn = {
+               .mnctr_en_bit = 8,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 5,
+               .n_val_shift = 24,
+               .m_val_shift = 8,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 3,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = lcc_cxo_pll4_map,
+       },
+       .freq_tbl = clk_tbl_aif_osr_393,
+       .clkr = {
+               .enable_reg = 0xcc,
+               .enable_mask = BIT(9),
+               .hw.init = &(struct clk_init_data){
+                       .name = "slimbus_src",
+                       .parent_names = lcc_cxo_pll4,
+                       .num_parents = 2,
+                       .ops = &clk_rcg_ops,
+                       .flags = CLK_SET_RATE_GATE,
+               },
+       },
+};
+
+static const char * const lcc_slimbus_parents[] = {
+       "slimbus_src",
+};
+
+static struct clk_branch audio_slimbus_clk = {
+       .halt_reg = 0xd4,
+       .halt_bit = 0,
+       .halt_check = BRANCH_HALT_ENABLE,
+       .clkr = {
+               .enable_reg = 0xcc,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "audio_slimbus_clk",
+                       .parent_names = lcc_slimbus_parents,
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch sps_slimbus_clk = {
+       .halt_reg = 0xd4,
+       .halt_bit = 1,
+       .halt_check = BRANCH_HALT_ENABLE,
+       .clkr = {
+               .enable_reg = 0xcc,
+               .enable_mask = BIT(12),
+               .hw.init = &(struct clk_init_data){
+                       .name = "sps_slimbus_clk",
+                       .parent_names = lcc_slimbus_parents,
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap *lcc_mdm9615_clks[] = {
+       [PLL4] = &pll4.clkr,
+       [MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
+       [MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
+       [MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
+       [MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
+       [MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
+       [PCM_SRC] = &pcm_src.clkr,
+       [PCM_CLK_OUT] = &pcm_clk_out.clkr,
+       [PCM_CLK] = &pcm_clk.clkr,
+       [SLIMBUS_SRC] = &slimbus_src.clkr,
+       [AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr,
+       [SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr,
+       [CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr,
+       [CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr,
+       [CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr,
+       [CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr,
+       [CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr,
+       [SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr,
+       [SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr,
+       [SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr,
+       [SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr,
+       [SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr,
+       [CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr,
+       [CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr,
+       [CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr,
+       [CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr,
+       [CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr,
+       [SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr,
+       [SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr,
+       [SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr,
+       [SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr,
+       [SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr,
+};
+
+static const struct regmap_config lcc_mdm9615_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0xfc,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc lcc_mdm9615_desc = {
+       .config = &lcc_mdm9615_regmap_config,
+       .clks = lcc_mdm9615_clks,
+       .num_clks = ARRAY_SIZE(lcc_mdm9615_clks),
+};
+
+static const struct of_device_id lcc_mdm9615_match_table[] = {
+       { .compatible = "qcom,lcc-mdm9615" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, lcc_mdm9615_match_table);
+
+static int lcc_mdm9615_probe(struct platform_device *pdev)
+{
+       u32 val;
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &lcc_mdm9615_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* Use the correct frequency plan depending on speed of PLL4 */
+       regmap_read(regmap, 0x4, &val);
+       if (val == 0x12) {
+               slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
+               mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+               codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+               spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+               codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+               spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
+               pcm_src.freq_tbl = clk_tbl_pcm_492;
+       }
+       /* Enable PLL4 source on the LPASS Primary PLL Mux */
+       regmap_write(regmap, 0xc4, 0x1);
+
+       return qcom_cc_really_probe(pdev, &lcc_mdm9615_desc, regmap);
+}
+
+static struct platform_driver lcc_mdm9615_driver = {
+       .probe          = lcc_mdm9615_probe,
+       .driver         = {
+               .name   = "lcc-mdm9615",
+               .of_match_table = lcc_mdm9615_match_table,
+       },
+};
+module_platform_driver(lcc_mdm9615_driver);
+
+MODULE_DESCRIPTION("QCOM LCC MDM9615 Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:lcc-mdm9615");
index 847dd9d..ca97e11 100644 (file)
@@ -2888,6 +2888,14 @@ static struct clk_hw *mmcc_msm8996_hws[] = {
        &gpll0_div.hw,
 };
 
+static struct gdsc mmagic_bimc_gdsc = {
+       .gdscr = 0x529c,
+       .pd = {
+               .name = "mmagic_bimc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct gdsc mmagic_video_gdsc = {
        .gdscr = 0x119c,
        .gds_hw_ctrl = 0x120c,
@@ -3201,6 +3209,7 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = {
 };
 
 static struct gdsc *mmcc_msm8996_gdscs[] = {
+       [MMAGIC_BIMC_GDSC] = &mmagic_bimc_gdsc,
        [MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc,
        [MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc,
        [MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc,
@@ -3305,9 +3314,8 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8996_match_table);
 
 static int mmcc_msm8996_probe(struct platform_device *pdev)
 {
-       struct clk *clk;
        struct device *dev = &pdev->dev;
-       int i;
+       int i, ret;
        struct regmap *regmap;
 
        regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc);
@@ -3320,9 +3328,9 @@ static int mmcc_msm8996_probe(struct platform_device *pdev)
        regmap_update_bits(regmap, 0x5054, BIT(15), 0);
 
        for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) {
-               clk = devm_clk_register(dev, mmcc_msm8996_hws[i]);
-               if (IS_ERR(clk))
-                       return PTR_ERR(clk);
+               ret = devm_clk_hw_register(dev, mmcc_msm8996_hws[i]);
+               if (ret)
+                       return ret;
        }
 
        return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap);
index d359c92..e38bf60 100644 (file)
@@ -69,6 +69,7 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
        DEF_FIXED(".s1",        CLK_S1,            CLK_PLL1_DIV2,  3, 1),
        DEF_FIXED(".s2",        CLK_S2,            CLK_PLL1_DIV2,  4, 1),
        DEF_FIXED(".s3",        CLK_S3,            CLK_PLL1_DIV2,  6, 1),
+       DEF_FIXED(".sdsrc",     CLK_SDSRC,         CLK_PLL1_DIV2,  2, 1),
 
        /* Core Clock Outputs */
        DEF_FIXED("ztr",        R8A7795_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
@@ -87,10 +88,10 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A7795_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A7795_CLK_S3D4,  CLK_S3,         4, 1),
 
-       DEF_GEN3_SD("sd0",      R8A7795_CLK_SD0,   CLK_PLL1_DIV2, 0x0074),
-       DEF_GEN3_SD("sd1",      R8A7795_CLK_SD1,   CLK_PLL1_DIV2, 0x0078),
-       DEF_GEN3_SD("sd2",      R8A7795_CLK_SD2,   CLK_PLL1_DIV2, 0x0268),
-       DEF_GEN3_SD("sd3",      R8A7795_CLK_SD3,   CLK_PLL1_DIV2, 0x026c),
+       DEF_GEN3_SD("sd0",      R8A7795_CLK_SD0,   CLK_SDSRC,     0x0074),
+       DEF_GEN3_SD("sd1",      R8A7795_CLK_SD1,   CLK_SDSRC,     0x0078),
+       DEF_GEN3_SD("sd2",      R8A7795_CLK_SD2,   CLK_SDSRC,     0x0268),
+       DEF_GEN3_SD("sd3",      R8A7795_CLK_SD3,   CLK_SDSRC,     0x026c),
 
        DEF_FIXED("cl",         R8A7795_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A7795_CLK_CP,    CLK_EXTAL,      2, 1),
index c84b549..891b353 100644 (file)
@@ -45,6 +45,7 @@ enum clk_ids {
        CLK_S3,
        CLK_SDSRC,
        CLK_SSPSRC,
+       CLK_RINT,
 
        /* Module Clocks */
        MOD_CLK_BASE
@@ -69,6 +70,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
        DEF_FIXED(".s1",        CLK_S1,            CLK_PLL1_DIV2,  3, 1),
        DEF_FIXED(".s2",        CLK_S2,            CLK_PLL1_DIV2,  4, 1),
        DEF_FIXED(".s3",        CLK_S3,            CLK_PLL1_DIV2,  6, 1),
+       DEF_FIXED(".sdsrc",     CLK_SDSRC,         CLK_PLL1_DIV2,  2, 1),
 
        /* Core Clock Outputs */
        DEF_FIXED("ztr",        R8A7796_CLK_ZTR,   CLK_PLL1_DIV2,  6, 1),
@@ -92,13 +94,36 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
        DEF_FIXED("s3d2",       R8A7796_CLK_S3D2,  CLK_S3,         2, 1),
        DEF_FIXED("s3d4",       R8A7796_CLK_S3D4,  CLK_S3,         4, 1),
 
+       DEF_GEN3_SD("sd0",      R8A7796_CLK_SD0,   CLK_SDSRC,    0x0074),
+       DEF_GEN3_SD("sd1",      R8A7796_CLK_SD1,   CLK_SDSRC,    0x0078),
+       DEF_GEN3_SD("sd2",      R8A7796_CLK_SD2,   CLK_SDSRC,    0x0268),
+       DEF_GEN3_SD("sd3",      R8A7796_CLK_SD3,   CLK_SDSRC,    0x026c),
+
        DEF_FIXED("cl",         R8A7796_CLK_CL,    CLK_PLL1_DIV2, 48, 1),
        DEF_FIXED("cp",         R8A7796_CLK_CP,    CLK_EXTAL,      2, 1),
+
+       DEF_DIV6_RO("osc",      R8A7796_CLK_OSC,   CLK_EXTAL, CPG_RCKCR,  8),
+       DEF_DIV6_RO("r_int",    CLK_RINT,          CLK_EXTAL, CPG_RCKCR, 32),
+
+       DEF_BASE("r",           R8A7796_CLK_R,     CLK_TYPE_GEN3_R, CLK_RINT),
 };
 
 static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
        DEF_MOD("scif2",                 310,   R8A7796_CLK_S3D4),
+       DEF_MOD("sdif3",                 311,   R8A7796_CLK_SD3),
+       DEF_MOD("sdif2",                 312,   R8A7796_CLK_SD2),
+       DEF_MOD("sdif1",                 313,   R8A7796_CLK_SD1),
+       DEF_MOD("sdif0",                 314,   R8A7796_CLK_SD0),
+       DEF_MOD("rwdt0",                 402,   R8A7796_CLK_R),
        DEF_MOD("intc-ap",               408,   R8A7796_CLK_S3D1),
+       DEF_MOD("gpio7",                 905,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio6",                 906,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio5",                 907,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio4",                 908,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio3",                 909,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio2",                 910,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio1",                 911,   R8A7796_CLK_S3D4),
+       DEF_MOD("gpio0",                 912,   R8A7796_CLK_S3D4),
 };
 
 static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
index f47a2fa..b5f2c8e 100644 (file)
@@ -8,6 +8,7 @@ obj-y   += clk-pll.o
 obj-y  += clk-cpu.o
 obj-y  += clk-inverter.o
 obj-y  += clk-mmc-phase.o
+obj-y  += clk-ddr.o
 obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
 
 obj-y  += clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644 (file)
index 0000000..8feba93
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang <hl@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <soc/rockchip/rockchip_sip.h>
+#include "clk.h"
+
+struct rockchip_ddrclk {
+       struct clk_hw   hw;
+       void __iomem    *reg_base;
+       int             mux_offset;
+       int             mux_shift;
+       int             mux_width;
+       int             div_shift;
+       int             div_width;
+       int             ddr_flag;
+       spinlock_t      *lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
+
+static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
+                                       unsigned long prate)
+{
+       struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+       unsigned long flags;
+       struct arm_smccc_res res;
+
+       spin_lock_irqsave(ddrclk->lock, flags);
+       arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
+                     ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
+                     0, 0, 0, 0, &res);
+       spin_unlock_irqrestore(ddrclk->lock, flags);
+
+       return res.a0;
+}
+
+static unsigned long
+rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
+                     ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
+                     0, 0, 0, 0, &res);
+
+       return res.a0;
+}
+
+static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
+                                          unsigned long rate,
+                                          unsigned long *prate)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0,
+                     ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
+                     0, 0, 0, 0, &res);
+
+       return res.a0;
+}
+
+static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
+{
+       struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+       int num_parents = clk_hw_get_num_parents(hw);
+       u32 val;
+
+       val = clk_readl(ddrclk->reg_base +
+                       ddrclk->mux_offset) >> ddrclk->mux_shift;
+       val &= GENMASK(ddrclk->mux_width - 1, 0);
+
+       if (val >= num_parents)
+               return -EINVAL;
+
+       return val;
+}
+
+static const struct clk_ops rockchip_ddrclk_sip_ops = {
+       .recalc_rate = rockchip_ddrclk_sip_recalc_rate,
+       .set_rate = rockchip_ddrclk_sip_set_rate,
+       .round_rate = rockchip_ddrclk_sip_round_rate,
+       .get_parent = rockchip_ddrclk_get_parent,
+};
+
+struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
+                                        const char *const *parent_names,
+                                        u8 num_parents, int mux_offset,
+                                        int mux_shift, int mux_width,
+                                        int div_shift, int div_width,
+                                        int ddr_flag, void __iomem *reg_base,
+                                        spinlock_t *lock)
+{
+       struct rockchip_ddrclk *ddrclk;
+       struct clk_init_data init;
+       struct clk *clk;
+
+       ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
+       if (!ddrclk)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+
+       init.flags = flags;
+       init.flags |= CLK_SET_RATE_NO_REPARENT;
+
+       switch (ddr_flag) {
+       case ROCKCHIP_DDRCLK_SIP:
+               init.ops = &rockchip_ddrclk_sip_ops;
+               break;
+       default:
+               pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
+               kfree(ddrclk);
+               return ERR_PTR(-EINVAL);
+       }
+
+       ddrclk->reg_base = reg_base;
+       ddrclk->lock = lock;
+       ddrclk->hw.init = &init;
+       ddrclk->mux_offset = mux_offset;
+       ddrclk->mux_shift = mux_shift;
+       ddrclk->mux_width = mux_width;
+       ddrclk->div_shift = div_shift;
+       ddrclk->div_width = div_width;
+       ddrclk->ddr_flag = ddr_flag;
+
+       clk = clk_register(NULL, &ddrclk->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: could not register ddrclk %s\n", __func__,  name);
+               kfree(ddrclk);
+               return NULL;
+       }
+
+       return clk;
+}
index db81e45..9c1373e 100644 (file)
@@ -837,7 +837,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
                u8 num_parents, int con_offset, int grf_lock_offset,
                int lock_shift, int mode_offset, int mode_shift,
                struct rockchip_pll_rate_table *rate_table,
-               u8 clk_pll_flags)
+               unsigned long flags, u8 clk_pll_flags)
 {
        const char *pll_parents[3];
        struct clk_init_data init;
@@ -892,7 +892,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
        init.name = pll_name;
 
        /* keep all plls untouched for now */
-       init.flags = CLK_IGNORE_UNUSED;
+       init.flags = flags | CLK_IGNORE_UNUSED;
 
        init.parent_names = &parent_names[0];
        init.num_parents = 1;
index c109d80..8387c7a 100644 (file)
@@ -100,8 +100,10 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
        RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0),
        RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
        RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0),
+       RK3036_PLL_RATE( 106500000, 1, 71, 4, 4, 1, 0),
        RK3036_PLL_RATE(  96000000, 1, 64, 4, 4, 1, 0),
        RK3036_PLL_RATE(  74250000, 2, 99, 4, 4, 1, 0),
+       RK3036_PLL_RATE(  65000000, 1, 65, 6, 4, 1, 0),
        RK3036_PLL_RATE(  54000000, 1, 54, 6, 4, 1, 0),
        RK3036_PLL_RATE(  27000000, 1, 27, 6, 4, 1, 0),
        { /* sentinel */ },
@@ -118,6 +120,10 @@ PNAME(mux_armclkb_p)                               = { "clk_core_b_lpll_src",
                                                    "clk_core_b_bpll_src",
                                                    "clk_core_b_dpll_src",
                                                    "clk_core_b_gpll_src" };
+PNAME(mux_ddrclk_p)                            = { "clk_ddrc_lpll_src",
+                                                   "clk_ddrc_bpll_src",
+                                                   "clk_ddrc_dpll_src",
+                                                   "clk_ddrc_gpll_src" };
 PNAME(mux_aclk_cci_p)                          = { "cpll_aclk_cci_src",
                                                    "gpll_aclk_cci_src",
                                                    "npll_aclk_cci_src",
@@ -373,6 +379,7 @@ static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = {
        RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11),
        RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10),
        RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10),
+       RK3399_CPUCLKB_RATE(2016000000, 1, 9, 9),
        RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9),
        RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9),
        RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8),
@@ -578,7 +585,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
                        RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(8), 13, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0,
                        RK3399_CLKSEL_CON(99), 0,
                        RK3399_CLKGATE_CON(8), 14, GFLAGS,
                        &rk3399_spdif_fracmux),
@@ -592,7 +599,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
                        RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(8), 3, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0,
                        RK3399_CLKSEL_CON(96), 0,
                        RK3399_CLKGATE_CON(8), 4, GFLAGS,
                        &rk3399_i2s0_fracmux),
@@ -602,7 +609,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
                        RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(8), 6, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0,
                        RK3399_CLKSEL_CON(97), 0,
                        RK3399_CLKGATE_CON(8), 7, GFLAGS,
                        &rk3399_i2s1_fracmux),
@@ -612,7 +619,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
                        RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(8), 9, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0,
                        RK3399_CLKSEL_CON(98), 0,
                        RK3399_CLKGATE_CON(8), 10, GFLAGS,
                        &rk3399_i2s2_fracmux),
@@ -631,7 +638,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0,
                        RK3399_CLKSEL_CON(33), 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(9), 0, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0,
                        RK3399_CLKSEL_CON(100), 0,
                        RK3399_CLKGATE_CON(9), 1, GFLAGS,
                        &rk3399_uart0_fracmux),
@@ -641,7 +648,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0,
                        RK3399_CLKSEL_CON(34), 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(9), 2, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0,
                        RK3399_CLKSEL_CON(101), 0,
                        RK3399_CLKGATE_CON(9), 3, GFLAGS,
                        &rk3399_uart1_fracmux),
@@ -649,7 +656,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0,
                        RK3399_CLKSEL_CON(35), 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(9), 4, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0,
                        RK3399_CLKSEL_CON(102), 0,
                        RK3399_CLKGATE_CON(9), 5, GFLAGS,
                        &rk3399_uart2_fracmux),
@@ -657,7 +664,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0,
                        RK3399_CLKSEL_CON(36), 0, 7, DFLAGS,
                        RK3399_CLKGATE_CON(9), 6, GFLAGS),
-       COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0,
                        RK3399_CLKSEL_CON(103), 0,
                        RK3399_CLKGATE_CON(9), 7, GFLAGS,
                        &rk3399_uart3_fracmux),
@@ -833,9 +840,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
 
        /* perihp */
        GATE(0, "cpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED,
-                       RK3399_CLKGATE_CON(5), 0, GFLAGS),
-       GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED,
                        RK3399_CLKGATE_CON(5), 1, GFLAGS),
+       GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(5), 0, GFLAGS),
        COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED,
                        RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS,
                        RK3399_CLKGATE_CON(5), 2, GFLAGS),
@@ -846,9 +853,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
                        RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
                        RK3399_CLKGATE_CON(5), 4, GFLAGS),
 
-       GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED,
+       GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", 0,
                        RK3399_CLKGATE_CON(20), 2, GFLAGS),
-       GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED,
+       GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", 0,
                        RK3399_CLKGATE_CON(20), 10, GFLAGS),
        GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
                        RK3399_CLKGATE_CON(20), 12, GFLAGS),
@@ -923,9 +930,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
                        RK3399_CLKGATE_CON(6), 14, GFLAGS),
 
        GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED,
-                       RK3399_CLKGATE_CON(6), 12, GFLAGS),
-       GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED,
                        RK3399_CLKGATE_CON(6), 13, GFLAGS),
+       GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED,
+                       RK3399_CLKGATE_CON(6), 12, GFLAGS),
        COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED,
                        RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS),
        GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED,
@@ -1071,7 +1078,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        /* vio */
        COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED,
                        RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS,
-                       RK3399_CLKGATE_CON(11), 10, GFLAGS),
+                       RK3399_CLKGATE_CON(11), 0, GFLAGS),
        COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0,
                        RK3399_CLKSEL_CON(43), 0, 5, DFLAGS,
                        RK3399_CLKGATE_CON(11), 1, GFLAGS),
@@ -1161,7 +1168,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
                        RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS,
                        RK3399_CLKGATE_CON(10), 12, GFLAGS),
 
-       COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0,
                        RK3399_CLKSEL_CON(106), 0,
                        &rk3399_dclk_vop0_fracmux),
 
@@ -1191,7 +1198,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
                        RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS,
                        RK3399_CLKGATE_CON(10), 13, GFLAGS),
 
-       COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX_NOGATE(DCLK_VOP1_FRAC, "dclk_vop1_frac", "dclk_vop1_div", 0,
                        RK3399_CLKSEL_CON(107), 0,
                        &rk3399_dclk_vop1_fracmux),
 
@@ -1305,7 +1312,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        /* testout */
        MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT,
                        RK3399_CLKSEL_CON(58), 7, 1, MFLAGS),
-       COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", 0,
                        RK3399_CLKSEL_CON(105), 0,
                        RK3399_CLKGATE_CON(13), 9, GFLAGS),
 
@@ -1377,6 +1384,18 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
                        RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
                        RK3368_CLKGATE_CON(13), 11, GFLAGS),
+
+       /* ddrc */
+       GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
+            0, GFLAGS),
+       GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
+            1, GFLAGS),
+       GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
+            2, GFLAGS),
+       GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
+            3, GFLAGS),
+       COMPOSITE_DDRCLK(SCLK_DDRC, "sclk_ddrc", mux_ddrclk_p, 0,
+                      RK3399_CLKSEL_CON(6), 4, 2, 0, 0, ROCKCHIP_DDRCLK_SIP),
 };
 
 static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
@@ -1398,7 +1417,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
                        RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
                        RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS),
 
-       COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0,
                        RK3399_PMU_CLKSEL_CON(7), 0,
                        &rk3399_pmuclk_wifi_fracmux),
 
@@ -1426,7 +1445,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
                        RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
                        RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS),
 
-       COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT,
+       COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0,
                        RK3399_PMU_CLKSEL_CON(6), 0,
                        RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS,
                        &rk3399_uart4_pmu_fracmux),
@@ -1468,6 +1487,9 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = {
        "aclk_cci_pre",
        "aclk_gic",
        "aclk_gic_noc",
+       "aclk_hdcp_noc",
+       "hclk_hdcp_noc",
+       "pclk_hdcp_noc",
        "pclk_perilp0",
        "pclk_perilp0",
        "hclk_perilp0",
@@ -1484,9 +1506,14 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = {
        "hclk_perilp1",
        "hclk_perilp1_noc",
        "aclk_dmac0_perilp",
+       "aclk_emmc_noc",
        "gpll_hclk_perilp1_src",
        "gpll_aclk_perilp0_src",
        "gpll_aclk_perihp_src",
+       "aclk_vio_noc",
+
+       /* ddrc */
+       "sclk_ddrc"
 };
 
 static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
index 4cf838d..2c9bb81 100644 (file)
@@ -49,14 +49,19 @@ static void __init rk2928_gate_clk_init(struct device_node *node)
        }
 
        reg = of_iomap(node, 0);
+       if (!reg)
+               return;
 
        clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
-       if (!clk_data)
+       if (!clk_data) {
+               iounmap(reg);
                return;
+       }
 
        clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL);
        if (!clk_data->clks) {
                kfree(clk_data);
+               iounmap(reg);
                return;
        }
 
index 7ffd134..b886be3 100644 (file)
@@ -385,7 +385,7 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
                                list->con_offset, grf_lock_offset,
                                list->lock_shift, list->mode_offset,
                                list->mode_shift, list->rate_table,
-                               list->pll_flags);
+                               list->flags, list->pll_flags);
                if (IS_ERR(clk)) {
                        pr_err("%s: failed to register clock %s\n", __func__,
                                list->name);
@@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches(
                                list->gate_offset, list->gate_shift,
                                list->gate_flags, flags, &ctx->lock);
                        break;
+               case branch_ddrclk:
+                       clk = rockchip_clk_register_ddrclk(
+                               list->name, list->flags,
+                               list->parent_names, list->num_parents,
+                               list->muxdiv_offset, list->mux_shift,
+                               list->mux_width, list->div_shift,
+                               list->div_width, list->div_flags,
+                               ctx->reg_base, &ctx->lock);
+                       break;
                }
 
                /* none of the cases above matched */
index 2194ffa..1653edd 100644 (file)
@@ -238,7 +238,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
                u8 num_parents, int con_offset, int grf_lock_offset,
                int lock_shift, int mode_offset, int mode_shift,
                struct rockchip_pll_rate_table *rate_table,
-               u8 clk_pll_flags);
+               unsigned long flags, u8 clk_pll_flags);
 
 struct rockchip_cpuclk_clksel {
        int reg;
@@ -281,6 +281,20 @@ struct clk *rockchip_clk_register_mmc(const char *name,
                                const char *const *parent_names, u8 num_parents,
                                void __iomem *reg, int shift);
 
+/*
+ * DDRCLK flags, including method of setting the rate
+ * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
+ */
+#define ROCKCHIP_DDRCLK_SIP            BIT(0)
+
+struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
+                                        const char *const *parent_names,
+                                        u8 num_parents, int mux_offset,
+                                        int mux_shift, int mux_width,
+                                        int div_shift, int div_width,
+                                        int ddr_flags, void __iomem *reg_base,
+                                        spinlock_t *lock);
+
 #define ROCKCHIP_INVERTER_HIWORD_MASK  BIT(0)
 
 struct clk *rockchip_clk_register_inverter(const char *name,
@@ -299,6 +313,7 @@ enum rockchip_clk_branch_type {
        branch_mmc,
        branch_inverter,
        branch_factor,
+       branch_ddrclk,
 };
 
 struct rockchip_clk_branch {
@@ -488,6 +503,24 @@ struct rockchip_clk_branch {
                .child          = ch,                           \
        }
 
+#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw,    \
+                        ds, dw, df)                            \
+       {                                                       \
+               .id             = _id,                          \
+               .branch_type    = branch_ddrclk,                \
+               .name           = cname,                        \
+               .parent_names   = pnames,                       \
+               .num_parents    = ARRAY_SIZE(pnames),           \
+               .flags          = f,                            \
+               .muxdiv_offset  = mo,                           \
+               .mux_shift      = ms,                           \
+               .mux_width      = mw,                           \
+               .div_shift      = ds,                           \
+               .div_width      = dw,                           \
+               .div_flags      = df,                           \
+               .gate_offset    = -1,                           \
+       }
+
 #define MUX(_id, cname, pnames, f, o, s, w, mf)                        \
        {                                                       \
                .id             = _id,                          \
index 9af3595..267f995 100644 (file)
@@ -783,14 +783,14 @@ static struct ccu_reset_map sun8i_h3_ccu_resets[] = {
        [RST_BUS_I2S1]          =  { 0x2d0, BIT(13) },
        [RST_BUS_I2S2]          =  { 0x2d0, BIT(14) },
 
-       [RST_BUS_I2C0]          =  { 0x2d4, BIT(0) },
-       [RST_BUS_I2C1]          =  { 0x2d4, BIT(1) },
-       [RST_BUS_I2C2]          =  { 0x2d4, BIT(2) },
-       [RST_BUS_UART0]         =  { 0x2d4, BIT(16) },
-       [RST_BUS_UART1]         =  { 0x2d4, BIT(17) },
-       [RST_BUS_UART2]         =  { 0x2d4, BIT(18) },
-       [RST_BUS_UART3]         =  { 0x2d4, BIT(19) },
-       [RST_BUS_SCR]           =  { 0x2d4, BIT(20) },
+       [RST_BUS_I2C0]          =  { 0x2d8, BIT(0) },
+       [RST_BUS_I2C1]          =  { 0x2d8, BIT(1) },
+       [RST_BUS_I2C2]          =  { 0x2d8, BIT(2) },
+       [RST_BUS_UART0]         =  { 0x2d8, BIT(16) },
+       [RST_BUS_UART1]         =  { 0x2d8, BIT(17) },
+       [RST_BUS_UART2]         =  { 0x2d8, BIT(18) },
+       [RST_BUS_UART3]         =  { 0x2d8, BIT(19) },
+       [RST_BUS_SCR]           =  { 0x2d8, BIT(20) },
 };
 
 static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = {
index fc17b52..51d4bac 100644 (file)
@@ -31,7 +31,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
                return;
 
        WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg,
-                                          !(reg & lock), 100, 70000));
+                                          reg & lock, 100, 70000));
 }
 
 int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
index 4470ffc..d6fafb3 100644 (file)
@@ -14,9 +14,9 @@
 #include "ccu_gate.h"
 #include "ccu_nk.h"
 
-void ccu_nk_find_best(unsigned long parent, unsigned long rate,
-                     unsigned int max_n, unsigned int max_k,
-                     unsigned int *n, unsigned int *k)
+static void ccu_nk_find_best(unsigned long parent, unsigned long rate,
+                            unsigned int max_n, unsigned int max_k,
+                            unsigned int *n, unsigned int *k)
 {
        unsigned long best_rate = 0;
        unsigned int best_k = 0, best_n = 0;
index 0ee1f36..d8eab90 100644 (file)
@@ -73,7 +73,7 @@ static void __init sun4i_pll2_setup(struct device_node *node,
                                          SUN4I_PLL2_PRE_DIV_WIDTH,
                                          CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
                                          &sun4i_a10_pll2_lock);
-       if (!prediv_clk) {
+       if (IS_ERR(prediv_clk)) {
                pr_err("Couldn't register the prediv clock\n");
                goto err_free_array;
        }
@@ -106,7 +106,7 @@ static void __init sun4i_pll2_setup(struct device_node *node,
                                          &mult->hw, &clk_multiplier_ops,
                                          &gate->hw, &clk_gate_ops,
                                          CLK_SET_RATE_PARENT);
-       if (!base_clk) {
+       if (IS_ERR(base_clk)) {
                pr_err("Couldn't register the base multiplier clock\n");
                goto err_free_multiplier;
        }
index b38d71c..e54266c 100644 (file)
@@ -91,7 +91,8 @@ static void __init sun4i_a10_mod0_setup(struct device_node *node)
        sunxi_factors_register(node, &sun4i_a10_mod0_data,
                               &sun4i_a10_mod0_lock, reg);
 }
-CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup);
+CLK_OF_DECLARE_DRIVER(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk",
+                     sun4i_a10_mod0_setup);
 
 static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev)
 {
index a5666e1..ea1eed2 100644 (file)
@@ -82,8 +82,8 @@ err_unmap:
        of_address_to_resource(node, 0, &res);
        release_mem_region(res.start, resource_size(&res));
 }
-CLK_OF_DECLARE(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk",
-              sun8i_a23_apb0_setup);
+CLK_OF_DECLARE_DRIVER(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk",
+                     sun8i_a23_apb0_setup);
 
 static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
 {
index 411d303..b200ebf 100644 (file)
@@ -48,7 +48,7 @@ static void __init sun8i_a23_mbus_setup(struct device_node *node)
                return;
 
        reg = of_io_request_and_map(node, 0, of_node_full_name(node));
-       if (!reg) {
+       if (IS_ERR(reg)) {
                pr_err("Could not get registers for sun8i-mbus-clk\n");
                goto err_free_parents;
        }
index 64da7b7..933b5dd 100644 (file)
@@ -428,7 +428,7 @@ static struct tegra_clk_pll_params pll_d_params = {
        .div_nmp = &pllp_nmp,
        .freq_table = pll_d_freq_table,
        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
-                TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
+                TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
 static struct tegra_clk_pll_params pll_d2_params = {
@@ -446,7 +446,7 @@ static struct tegra_clk_pll_params pll_d2_params = {
        .div_nmp = &pllp_nmp,
        .freq_table = pll_d_freq_table,
        .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
-                TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
+                TEGRA_PLL_HAS_LOCK_ENABLE,
 };
 
 static const struct pdiv_map pllu_p[] = {
index 5e9b652..4faa944 100644 (file)
 /* Magic unlocking token used on all Versatile boards */
 #define VERSATILE_LOCK_VAL     0xA05F
 
+#define VERSATILE_AUX_OSC_BITS 0x7FFFF
+#define INTEGRATOR_AP_CM_BITS 0xFF
+#define INTEGRATOR_AP_SYS_BITS 0xFF
+#define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
+#define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000
+
+#define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8)
+
+/**
+ * enum icst_control_type - the type of ICST control register
+ */
+enum icst_control_type {
+       ICST_VERSATILE, /* The standard type, all control bits available */
+       ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */
+       ICST_INTEGRATOR_AP_SYS, /* Only 8 bits of VDW available */
+       ICST_INTEGRATOR_AP_PCI, /* Odd bit pattern storage */
+       ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */
+       ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */
+};
+
 /**
  * struct clk_icst - ICST VCO clock wrapper
  * @hw: corresponding clock hardware entry
@@ -34,6 +54,7 @@
  * @lockreg: VCO lock register address
  * @params: parameters for this ICST instance
  * @rate: current rate
+ * @ctype: the type of control register for the ICST
  */
 struct clk_icst {
        struct clk_hw hw;
@@ -42,6 +63,7 @@ struct clk_icst {
        u32 lockreg_off;
        struct icst_params *params;
        unsigned long rate;
+       enum icst_control_type ctype;
 };
 
 #define to_icst(_hw) container_of(_hw, struct clk_icst, hw)
@@ -59,6 +81,76 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
        ret = regmap_read(icst->map, icst->vcoreg_off, &val);
        if (ret)
                return ret;
+
+       /*
+        * The Integrator/AP core clock can only access the low eight
+        * bits of the v PLL divider. Bit 8 is tied low and always zero,
+        * r is hardwired to 22 and output divider s is hardwired to 1
+        * (divide by 2) according to the document
+        * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
+        * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14.
+        */
+       if (icst->ctype == ICST_INTEGRATOR_AP_CM) {
+               vco->v = val & INTEGRATOR_AP_CM_BITS;
+               vco->r = 22;
+               vco->s = 1;
+               return 0;
+       }
+
+       /*
+        * The Integrator/AP system clock on the base board can only
+        * access the low eight bits of the v PLL divider. Bit 8 is tied low
+        * and always zero, r is hardwired to 46, and the output divider is
+        * hardwired to 3 (divide by 4) according to the document
+        * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B,
+        * page 3-16.
+        */
+       if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
+               vco->v = val & INTEGRATOR_AP_SYS_BITS;
+               vco->r = 46;
+               vco->s = 3;
+               return 0;
+       }
+
+       /*
+        * The Integrator/AP PCI clock is using an odd pattern to create
+        * the child clock, basically a single bit called DIVX/Y is used
+        * to select between two different hardwired values: setting the
+        * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the
+        * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies
+        * 33 or 25 MHz respectively.
+        */
+       if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
+               bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ);
+
+               vco->v = divxy ? 17 : 14;
+               vco->r = divxy ? 22 : 14;
+               vco->s = 1;
+               return 0;
+       }
+
+       /*
+        * The Integrator/CP core clock can access the low eight bits
+        * of the v PLL divider. Bit 8 is tied low and always zero,
+        * r is hardwired to 22 and the output divider s is accessible
+        * in bits 8 thru 10 according to the document
+        * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide"
+        * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10.
+        */
+       if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
+               vco->v = val & 0xFF;
+               vco->r = 22;
+               vco->s = (val >> 8) & 7;
+               return 0;
+       }
+
+       if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
+               vco->v = (val >> 12) & 0xFF;
+               vco->r = 22;
+               vco->s = (val >> 20) & 7;
+               return 0;
+       }
+
        vco->v = val & 0x1ff;
        vco->r = (val >> 9) & 0x7f;
        vco->s = (val >> 16) & 03;
@@ -72,22 +164,62 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
  */
 static int vco_set(struct clk_icst *icst, struct icst_vco vco)
 {
+       u32 mask;
        u32 val;
        int ret;
 
-       ret = regmap_read(icst->map, icst->vcoreg_off, &val);
-       if (ret)
-               return ret;
+       /* Mask the bits used by the VCO */
+       switch (icst->ctype) {
+       case ICST_INTEGRATOR_AP_CM:
+               mask = INTEGRATOR_AP_CM_BITS;
+               val = vco.v & 0xFF;
+               if (vco.v & 0x100)
+                       pr_err("ICST error: tried to set bit 8 of VDW\n");
+               if (vco.s != 1)
+                       pr_err("ICST error: tried to use VOD != 1\n");
+               if (vco.r != 22)
+                       pr_err("ICST error: tried to use RDW != 22\n");
+               break;
+       case ICST_INTEGRATOR_AP_SYS:
+               mask = INTEGRATOR_AP_SYS_BITS;
+               val = vco.v & 0xFF;
+               if (vco.v & 0x100)
+                       pr_err("ICST error: tried to set bit 8 of VDW\n");
+               if (vco.s != 3)
+                       pr_err("ICST error: tried to use VOD != 1\n");
+               if (vco.r != 46)
+                       pr_err("ICST error: tried to use RDW != 22\n");
+               break;
+       case ICST_INTEGRATOR_CP_CM_CORE:
+               mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
+               val = (vco.v & 0xFF) | vco.s << 8;
+               if (vco.v & 0x100)
+                       pr_err("ICST error: tried to set bit 8 of VDW\n");
+               if (vco.r != 22)
+                       pr_err("ICST error: tried to use RDW != 22\n");
+               break;
+       case ICST_INTEGRATOR_CP_CM_MEM:
+               mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */
+               val = ((vco.v & 0xFF) << 12) | (vco.s << 20);
+               if (vco.v & 0x100)
+                       pr_err("ICST error: tried to set bit 8 of VDW\n");
+               if (vco.r != 22)
+                       pr_err("ICST error: tried to use RDW != 22\n");
+               break;
+       default:
+               /* Regular auxilary oscillator */
+               mask = VERSATILE_AUX_OSC_BITS;
+               val = vco.v | (vco.r << 9) | (vco.s << 16);
+               break;
+       }
 
-       /* Mask the 18 bits used by the VCO */
-       val &= ~0x7ffff;
-       val |= vco.v | (vco.r << 9) | (vco.s << 16);
+       pr_debug("ICST: new val = 0x%08x\n", val);
 
        /* This magic unlocks the VCO so it can be controlled */
        ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL);
        if (ret)
                return ret;
-       ret = regmap_write(icst->map, icst->vcoreg_off, val);
+       ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val);
        if (ret)
                return ret;
        /* This locks the VCO again */
@@ -121,6 +253,46 @@ static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_icst *icst = to_icst(hw);
        struct icst_vco vco;
 
+       if (icst->ctype == ICST_INTEGRATOR_AP_CM ||
+           icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
+               if (rate <= 12000000)
+                       return 12000000;
+               if (rate >= 160000000)
+                       return 160000000;
+               /* Slam to closest megahertz */
+               return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000;
+       }
+
+       if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
+               if (rate <= 6000000)
+                       return 6000000;
+               if (rate >= 66000000)
+                       return 66000000;
+               /* Slam to closest 0.5 megahertz */
+               return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
+       }
+
+       if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
+               /* Divides between 3 and 50 MHz in steps of 0.25 MHz */
+               if (rate <= 3000000)
+                       return 3000000;
+               if (rate >= 50000000)
+                       return 5000000;
+               /* Slam to closest 0.25 MHz */
+               return DIV_ROUND_CLOSEST(rate, 250000) * 250000;
+       }
+
+       if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
+               /*
+                * If we're below or less than halfway from 25 to 33 MHz
+                * select 25 MHz
+                */
+               if (rate <= 25000000 || rate < 29000000)
+                       return 25000000;
+               /* Else just return the default frequency */
+               return 33000000;
+       }
+
        vco = icst_hz_to_vco(icst->params, rate);
        return icst_hz(icst->params, vco);
 }
@@ -131,6 +303,36 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_icst *icst = to_icst(hw);
        struct icst_vco vco;
 
+       if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
+               /* This clock is especially primitive */
+               unsigned int val;
+               int ret;
+
+               if (rate == 25000000) {
+                       val = 0;
+               } else if (rate == 33000000) {
+                       val = INTEGRATOR_AP_PCI_25_33_MHZ;
+               } else {
+                       pr_err("ICST: cannot set PCI frequency %lu\n",
+                              rate);
+                       return -EINVAL;
+               }
+               ret = regmap_write(icst->map, icst->lockreg_off,
+                                  VERSATILE_LOCK_VAL);
+               if (ret)
+                       return ret;
+               ret = regmap_update_bits(icst->map, icst->vcoreg_off,
+                                        INTEGRATOR_AP_PCI_25_33_MHZ,
+                                        val);
+               if (ret)
+                       return ret;
+               /* This locks the VCO again */
+               ret = regmap_write(icst->map, icst->lockreg_off, 0);
+               if (ret)
+                       return ret;
+               return 0;
+       }
+
        if (parent_rate)
                icst->params->ref = parent_rate;
        vco = icst_hz_to_vco(icst->params, rate);
@@ -148,7 +350,8 @@ static struct clk *icst_clk_setup(struct device *dev,
                                  const struct clk_icst_desc *desc,
                                  const char *name,
                                  const char *parent_name,
-                                 struct regmap *map)
+                                 struct regmap *map,
+                                 enum icst_control_type ctype)
 {
        struct clk *clk;
        struct clk_icst *icst;
@@ -178,6 +381,7 @@ static struct clk *icst_clk_setup(struct device *dev,
        icst->params = pclone;
        icst->vcoreg_off = desc->vco_offset;
        icst->lockreg_off = desc->lock_offset;
+       icst->ctype = ctype;
 
        clk = clk_register(dev, &icst->hw);
        if (IS_ERR(clk)) {
@@ -206,7 +410,8 @@ struct clk *icst_clk_register(struct device *dev,
                pr_err("could not initialize ICST regmap\n");
                return ERR_CAST(map);
        }
-       return icst_clk_setup(dev, desc, name, parent_name, map);
+       return icst_clk_setup(dev, desc, name, parent_name, map,
+                             ICST_VERSATILE);
 }
 EXPORT_SYMBOL_GPL(icst_clk_register);
 
@@ -239,6 +444,56 @@ static const struct icst_params icst307_params = {
        .idx2s          = icst307_idx2s,
 };
 
+/**
+ * The core modules on the Integrator/AP and Integrator/CP have
+ * especially crippled ICST525 control.
+ */
+static const struct icst_params icst525_apcp_cm_params = {
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
+       /* Minimum 12 MHz, VDW = 4 */
+       .vd_min         = 12,
+       /*
+        * Maximum 160 MHz, VDW = 152 for all core modules, but
+        * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually
+        * go to 200 MHz (max VDW = 192).
+        */
+       .vd_max         = 192,
+       /* r is hardcoded to 22 and this is the actual divisor, +2 */
+       .rd_min         = 24,
+       .rd_max         = 24,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
+};
+
+static const struct icst_params icst525_ap_sys_params = {
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
+       /* Minimum 3 MHz, VDW = 4 */
+       .vd_min         = 3,
+       /* Maximum 50 MHz, VDW = 192 */
+       .vd_max         = 50,
+       /* r is hardcoded to 46 and this is the actual divisor, +2 */
+       .rd_min         = 48,
+       .rd_max         = 48,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
+};
+
+static const struct icst_params icst525_ap_pci_params = {
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
+       /* Minimum 25 MHz */
+       .vd_min         = 25,
+       /* Maximum 33 MHz */
+       .vd_max         = 33,
+       /* r is hardcoded to 14 or 22 and this is the actual divisors +2 */
+       .rd_min         = 16,
+       .rd_max         = 24,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
+};
+
 static void __init of_syscon_icst_setup(struct device_node *np)
 {
        struct device_node *parent;
@@ -247,6 +502,7 @@ static void __init of_syscon_icst_setup(struct device_node *np)
        const char *name = np->name;
        const char *parent_name;
        struct clk *regclk;
+       enum icst_control_type ctype;
 
        /* We do not release this reference, we are using it perpetually */
        parent = of_get_parent(np);
@@ -269,11 +525,28 @@ static void __init of_syscon_icst_setup(struct device_node *np)
                return;
        }
 
-       if (of_device_is_compatible(np, "arm,syscon-icst525"))
+       if (of_device_is_compatible(np, "arm,syscon-icst525")) {
                icst_desc.params = &icst525_params;
-       else if (of_device_is_compatible(np, "arm,syscon-icst307"))
+               ctype = ICST_VERSATILE;
+       } else if (of_device_is_compatible(np, "arm,syscon-icst307")) {
                icst_desc.params = &icst307_params;
-       else {
+               ctype = ICST_VERSATILE;
+       } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) {
+               icst_desc.params = &icst525_apcp_cm_params;
+               ctype = ICST_INTEGRATOR_AP_CM;
+       } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) {
+               icst_desc.params = &icst525_ap_sys_params;
+               ctype = ICST_INTEGRATOR_AP_SYS;
+       } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) {
+               icst_desc.params = &icst525_ap_pci_params;
+               ctype = ICST_INTEGRATOR_AP_PCI;
+       } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) {
+               icst_desc.params = &icst525_apcp_cm_params;
+               ctype = ICST_INTEGRATOR_CP_CM_CORE;
+       } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) {
+               icst_desc.params = &icst525_apcp_cm_params;
+               ctype = ICST_INTEGRATOR_CP_CM_MEM;
+       } else {
                pr_err("unknown ICST clock %s\n", name);
                return;
        }
@@ -281,7 +554,7 @@ static void __init of_syscon_icst_setup(struct device_node *np)
        /* Parent clock name is not the same as node parent */
        parent_name = of_clk_get_parent_name(np, 0);
 
-       regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map);
+       regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype);
        if (IS_ERR(regclk)) {
                pr_err("error setting up syscon ICST clock %s\n", name);
                return;
@@ -294,5 +567,14 @@ CLK_OF_DECLARE(arm_syscon_icst525_clk,
               "arm,syscon-icst525", of_syscon_icst_setup);
 CLK_OF_DECLARE(arm_syscon_icst307_clk,
               "arm,syscon-icst307", of_syscon_icst_setup);
-
+CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk,
+              "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorap_sys_clk,
+              "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorap_pci_clk,
+              "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk,
+              "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
+CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk,
+              "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup);
 #endif
diff --git a/include/dt-bindings/clock/gxbb-aoclkc.h b/include/dt-bindings/clock/gxbb-aoclkc.h
new file mode 100644 (file)
index 0000000..3175148
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_GXBB_AOCLK
+#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_GXBB_AOCLK
+
+#define CLKID_AO_REMOTE                0
+#define CLKID_AO_I2C_MASTER    1
+#define CLKID_AO_I2C_SLAVE     2
+#define CLKID_AO_UART1         3
+#define CLKID_AO_UART2         4
+#define CLKID_AO_IR_BLASTER    5
+
+#endif
index f889d80..ce4ad63 100644 (file)
@@ -6,7 +6,14 @@
 #define __GXBB_CLKC_H
 
 #define CLKID_CPUCLK           1
+#define CLKID_HDMI_PLL         2
+#define CLKID_FCLK_DIV2                4
+#define CLKID_FCLK_DIV3                5
+#define CLKID_FCLK_DIV4                6
 #define CLKID_CLK81            12
 #define CLKID_ETH              36
+#define CLKID_SD_EMMC_A                94
+#define CLKID_SD_EMMC_B                95
+#define CLKID_SD_EMMC_C                96
 
 #endif /* __GXBB_CLKC_H */
diff --git a/include/dt-bindings/clock/maxim,max77620.h b/include/dt-bindings/clock/maxim,max77620.h
new file mode 100644 (file)
index 0000000..82aba28
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ *
+ * Device Tree binding constants clocks for the Maxim 77620 PMIC.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H
+#define _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H
+
+/* Fixed rate clocks. */
+
+#define MAX77620_CLK_32K_OUT0          0
+
+/* Total number of clocks. */
+#define MAX77620_CLKS_NUM              (MAX77620_CLK_32K_OUT0 + 1)
+
+#endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H */
index 595a58d..a55ff8c 100644 (file)
@@ -22,6 +22,4 @@
 #define CLKID_MPEG_SEL         14
 #define CLKID_MPEG_DIV         15
 
-#define CLK_NR_CLKS            (CLKID_MPEG_DIV + 1)
-
 #endif /* __MESON8B_CLKC_H */
diff --git a/include/dt-bindings/clock/mt2701-clk.h b/include/dt-bindings/clock/mt2701-clk.h
new file mode 100644 (file)
index 0000000..2062c67
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: Shunli Wang <shunli.wang@mediatek.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 in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT2701_H
+#define _DT_BINDINGS_CLK_MT2701_H
+
+/* TOPCKGEN */
+#define CLK_TOP_SYSPLL                         1
+#define CLK_TOP_SYSPLL_D2                      2
+#define CLK_TOP_SYSPLL_D3                      3
+#define CLK_TOP_SYSPLL_D5                      4
+#define CLK_TOP_SYSPLL_D7                      5
+#define CLK_TOP_SYSPLL1_D2                     6
+#define CLK_TOP_SYSPLL1_D4                     7
+#define CLK_TOP_SYSPLL1_D8                     8
+#define CLK_TOP_SYSPLL1_D16                    9
+#define CLK_TOP_SYSPLL2_D2                     10
+#define CLK_TOP_SYSPLL2_D4                     11
+#define CLK_TOP_SYSPLL2_D8                     12
+#define CLK_TOP_SYSPLL3_D2                     13
+#define CLK_TOP_SYSPLL3_D4                     14
+#define CLK_TOP_SYSPLL4_D2                     15
+#define CLK_TOP_SYSPLL4_D4                     16
+#define CLK_TOP_UNIVPLL                                17
+#define CLK_TOP_UNIVPLL_D2                     18
+#define CLK_TOP_UNIVPLL_D3                     19
+#define CLK_TOP_UNIVPLL_D5                     20
+#define CLK_TOP_UNIVPLL_D7                     21
+#define CLK_TOP_UNIVPLL_D26                    22
+#define CLK_TOP_UNIVPLL_D52                    23
+#define CLK_TOP_UNIVPLL_D108                   24
+#define CLK_TOP_USB_PHY48M                     25
+#define CLK_TOP_UNIVPLL1_D2                    26
+#define CLK_TOP_UNIVPLL1_D4                    27
+#define CLK_TOP_UNIVPLL1_D8                    28
+#define CLK_TOP_UNIVPLL2_D2                    29
+#define CLK_TOP_UNIVPLL2_D4                    30
+#define CLK_TOP_UNIVPLL2_D8                    31
+#define CLK_TOP_UNIVPLL2_D16                   32
+#define CLK_TOP_UNIVPLL2_D32                   33
+#define CLK_TOP_UNIVPLL3_D2                    34
+#define CLK_TOP_UNIVPLL3_D4                    35
+#define CLK_TOP_UNIVPLL3_D8                    36
+#define CLK_TOP_MSDCPLL                                37
+#define CLK_TOP_MSDCPLL_D2                     38
+#define CLK_TOP_MSDCPLL_D4                     39
+#define CLK_TOP_MSDCPLL_D8                     40
+#define CLK_TOP_MMPLL                          41
+#define CLK_TOP_MMPLL_D2                       42
+#define CLK_TOP_DMPLL                          43
+#define CLK_TOP_DMPLL_D2                       44
+#define CLK_TOP_DMPLL_D4                       45
+#define CLK_TOP_DMPLL_X2                       46
+#define CLK_TOP_TVDPLL                         47
+#define CLK_TOP_TVDPLL_D2                      48
+#define CLK_TOP_TVDPLL_D4                      49
+#define CLK_TOP_TVD2PLL                                50
+#define CLK_TOP_TVD2PLL_D2                     51
+#define CLK_TOP_HADDS2PLL_98M                  52
+#define CLK_TOP_HADDS2PLL_294M                 53
+#define CLK_TOP_HADDS2_FB                      54
+#define CLK_TOP_MIPIPLL_D2                     55
+#define CLK_TOP_MIPIPLL_D4                     56
+#define CLK_TOP_HDMIPLL                                57
+#define CLK_TOP_HDMIPLL_D2                     58
+#define CLK_TOP_HDMIPLL_D3                     59
+#define CLK_TOP_HDMI_SCL_RX                    60
+#define CLK_TOP_HDMI_0_PIX340M                 61
+#define CLK_TOP_HDMI_0_DEEP340M                        62
+#define CLK_TOP_HDMI_0_PLL340M                 63
+#define CLK_TOP_AUD1PLL_98M                    64
+#define CLK_TOP_AUD2PLL_90M                    65
+#define CLK_TOP_AUDPLL                         66
+#define CLK_TOP_AUDPLL_D4                      67
+#define CLK_TOP_AUDPLL_D8                      68
+#define CLK_TOP_AUDPLL_D16                     69
+#define CLK_TOP_AUDPLL_D24                     70
+#define CLK_TOP_ETHPLL_500M                    71
+#define CLK_TOP_VDECPLL                                72
+#define CLK_TOP_VENCPLL                                73
+#define CLK_TOP_MIPIPLL                                74
+#define CLK_TOP_ARMPLL_1P3G                    75
+
+#define CLK_TOP_MM_SEL                         76
+#define CLK_TOP_DDRPHYCFG_SEL                  77
+#define CLK_TOP_MEM_SEL                                78
+#define CLK_TOP_AXI_SEL                                79
+#define CLK_TOP_CAMTG_SEL                      80
+#define CLK_TOP_MFG_SEL                                81
+#define CLK_TOP_VDEC_SEL                       82
+#define CLK_TOP_PWM_SEL                                83
+#define CLK_TOP_MSDC30_0_SEL                   84
+#define CLK_TOP_USB20_SEL                      85
+#define CLK_TOP_SPI0_SEL                       86
+#define CLK_TOP_UART_SEL                       87
+#define CLK_TOP_AUDINTBUS_SEL                  88
+#define CLK_TOP_AUDIO_SEL                      89
+#define CLK_TOP_MSDC30_2_SEL                   90
+#define CLK_TOP_MSDC30_1_SEL                   91
+#define CLK_TOP_DPI1_SEL                       92
+#define CLK_TOP_DPI0_SEL                       93
+#define CLK_TOP_SCP_SEL                                94
+#define CLK_TOP_PMICSPI_SEL                    95
+#define CLK_TOP_APLL_SEL                       96
+#define CLK_TOP_HDMI_SEL                       97
+#define CLK_TOP_TVE_SEL                                98
+#define CLK_TOP_EMMC_HCLK_SEL                  99
+#define CLK_TOP_NFI2X_SEL                      100
+#define CLK_TOP_RTC_SEL                                101
+#define CLK_TOP_OSD_SEL                                102
+#define CLK_TOP_NR_SEL                         103
+#define CLK_TOP_DI_SEL                         104
+#define CLK_TOP_FLASH_SEL                      105
+#define CLK_TOP_ASM_M_SEL                      106
+#define CLK_TOP_ASM_I_SEL                      107
+#define CLK_TOP_INTDIR_SEL                     108
+#define CLK_TOP_HDMIRX_BIST_SEL                        109
+#define CLK_TOP_ETHIF_SEL                      110
+#define CLK_TOP_MS_CARD_SEL                    111
+#define CLK_TOP_ASM_H_SEL                      112
+#define CLK_TOP_SPI1_SEL                       113
+#define CLK_TOP_CMSYS_SEL                      114
+#define CLK_TOP_MSDC30_3_SEL                   115
+#define CLK_TOP_HDMIRX26_24_SEL                        116
+#define CLK_TOP_AUD2DVD_SEL                    117
+#define CLK_TOP_8BDAC_SEL                      118
+#define CLK_TOP_SPI2_SEL                       119
+#define CLK_TOP_AUD_MUX1_SEL                   120
+#define CLK_TOP_AUD_MUX2_SEL                   121
+#define CLK_TOP_AUDPLL_MUX_SEL                 122
+#define CLK_TOP_AUD_K1_SRC_SEL                 123
+#define CLK_TOP_AUD_K2_SRC_SEL                 124
+#define CLK_TOP_AUD_K3_SRC_SEL                 125
+#define CLK_TOP_AUD_K4_SRC_SEL                 126
+#define CLK_TOP_AUD_K5_SRC_SEL                 127
+#define CLK_TOP_AUD_K6_SRC_SEL                 128
+#define CLK_TOP_PADMCLK_SEL                    129
+#define CLK_TOP_AUD_EXTCK1_DIV                 130
+#define CLK_TOP_AUD_EXTCK2_DIV                 131
+#define CLK_TOP_AUD_MUX1_DIV                   132
+#define CLK_TOP_AUD_MUX2_DIV                   133
+#define CLK_TOP_AUD_K1_SRC_DIV                 134
+#define CLK_TOP_AUD_K2_SRC_DIV                 135
+#define CLK_TOP_AUD_K3_SRC_DIV                 136
+#define CLK_TOP_AUD_K4_SRC_DIV                 137
+#define CLK_TOP_AUD_K5_SRC_DIV                 138
+#define CLK_TOP_AUD_K6_SRC_DIV                 139
+#define CLK_TOP_AUD_I2S1_MCLK                  140
+#define CLK_TOP_AUD_I2S2_MCLK                  141
+#define CLK_TOP_AUD_I2S3_MCLK                  142
+#define CLK_TOP_AUD_I2S4_MCLK                  143
+#define CLK_TOP_AUD_I2S5_MCLK                  144
+#define CLK_TOP_AUD_I2S6_MCLK                  145
+#define CLK_TOP_AUD_48K_TIMING                 146
+#define CLK_TOP_AUD_44K_TIMING                 147
+
+#define CLK_TOP_32K_INTERNAL                   148
+#define CLK_TOP_32K_EXTERNAL                   149
+#define CLK_TOP_CLK26M_D8                      150
+#define CLK_TOP_8BDAC                          151
+#define CLK_TOP_WBG_DIG_416M                   152
+#define CLK_TOP_DPI                            153
+#define CLK_TOP_HDMITX_CLKDIG_CTS              154
+#define CLK_TOP_DSI0_LNTC_DSI                  155
+#define CLK_TOP_AUD_EXT1                       156
+#define CLK_TOP_AUD_EXT2                       157
+#define CLK_TOP_NFI1X_PAD                      158
+#define CLK_TOP_NR                             159
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL                     1
+#define CLK_APMIXED_MAINPLL                    2
+#define CLK_APMIXED_UNIVPLL                    3
+#define CLK_APMIXED_MMPLL                      4
+#define CLK_APMIXED_MSDCPLL                    5
+#define CLK_APMIXED_TVDPLL                     6
+#define CLK_APMIXED_AUD1PLL                    7
+#define CLK_APMIXED_TRGPLL                     8
+#define CLK_APMIXED_ETHPLL                     9
+#define CLK_APMIXED_VDECPLL                    10
+#define CLK_APMIXED_HADDS2PLL                  11
+#define CLK_APMIXED_AUD2PLL                    12
+#define CLK_APMIXED_TVD2PLL                    13
+#define CLK_APMIXED_NR                         14
+
+/* DDRPHY */
+
+#define CLK_DDRPHY_VENCPLL                     1
+#define CLK_DDRPHY_NR                          2
+
+/* INFRACFG */
+
+#define CLK_INFRA_DBG                          1
+#define CLK_INFRA_SMI                          2
+#define CLK_INFRA_QAXI_CM4                     3
+#define CLK_INFRA_AUD_SPLIN_B                  4
+#define CLK_INFRA_AUDIO                                5
+#define CLK_INFRA_EFUSE                                6
+#define CLK_INFRA_L2C_SRAM                     7
+#define CLK_INFRA_M4U                          8
+#define CLK_INFRA_CONNMCU                      9
+#define CLK_INFRA_TRNG                         10
+#define CLK_INFRA_RAMBUFIF                     11
+#define CLK_INFRA_CPUM                         12
+#define CLK_INFRA_KP                           13
+#define CLK_INFRA_CEC                          14
+#define CLK_INFRA_IRRX                         15
+#define CLK_INFRA_PMICSPI                      16
+#define CLK_INFRA_PMICWRAP                     17
+#define CLK_INFRA_DDCCI                                18
+#define CLK_INFRA_CLK_13M                      19
+#define CLK_INFRA_NR                           20
+
+/* PERICFG */
+
+#define CLK_PERI_NFI                           1
+#define CLK_PERI_THERM                         2
+#define CLK_PERI_PWM1                          3
+#define CLK_PERI_PWM2                          4
+#define CLK_PERI_PWM3                          5
+#define CLK_PERI_PWM4                          6
+#define CLK_PERI_PWM5                          7
+#define CLK_PERI_PWM6                          8
+#define CLK_PERI_PWM7                          9
+#define CLK_PERI_PWM                           10
+#define CLK_PERI_USB0                          11
+#define CLK_PERI_USB1                          12
+#define CLK_PERI_AP_DMA                                13
+#define CLK_PERI_MSDC30_0                      14
+#define CLK_PERI_MSDC30_1                      15
+#define CLK_PERI_MSDC30_2                      16
+#define CLK_PERI_MSDC30_3                      17
+#define CLK_PERI_MSDC50_3                      18
+#define CLK_PERI_NLI                           19
+#define CLK_PERI_UART0                         20
+#define CLK_PERI_UART1                         21
+#define CLK_PERI_UART2                         22
+#define CLK_PERI_UART3                         23
+#define CLK_PERI_BTIF                          24
+#define CLK_PERI_I2C0                          25
+#define CLK_PERI_I2C1                          26
+#define CLK_PERI_I2C2                          27
+#define CLK_PERI_I2C3                          28
+#define CLK_PERI_AUXADC                                29
+#define CLK_PERI_SPI0                          30
+#define CLK_PERI_ETH                           31
+#define CLK_PERI_USB0_MCU                      32
+
+#define CLK_PERI_USB1_MCU                      33
+#define CLK_PERI_USB_SLV                       34
+#define CLK_PERI_GCPU                          35
+#define CLK_PERI_NFI_ECC                       36
+#define CLK_PERI_NFI_PAD                       37
+#define CLK_PERI_FLASH                         38
+#define CLK_PERI_HOST89_INT                    39
+#define CLK_PERI_HOST89_SPI                    40
+#define CLK_PERI_HOST89_DVD                    41
+#define CLK_PERI_SPI1                          42
+#define CLK_PERI_SPI2                          43
+#define CLK_PERI_FCI                           44
+
+#define CLK_PERI_UART0_SEL                     45
+#define CLK_PERI_UART1_SEL                     46
+#define CLK_PERI_UART2_SEL                     47
+#define CLK_PERI_UART3_SEL                     48
+#define CLK_PERI_NR                            49
+
+/* AUDIO */
+
+#define CLK_AUD_AFE                            1
+#define CLK_AUD_LRCK_DETECT                    2
+#define CLK_AUD_I2S                            3
+#define CLK_AUD_APLL_TUNER                     4
+#define CLK_AUD_HDMI                           5
+#define CLK_AUD_SPDF                           6
+#define CLK_AUD_SPDF2                          7
+#define CLK_AUD_APLL                           8
+#define CLK_AUD_TML                            9
+#define CLK_AUD_AHB_IDLE_EXT                   10
+#define CLK_AUD_AHB_IDLE_INT                   11
+
+#define CLK_AUD_I2SIN1                         12
+#define CLK_AUD_I2SIN2                         13
+#define CLK_AUD_I2SIN3                         14
+#define CLK_AUD_I2SIN4                         15
+#define CLK_AUD_I2SIN5                         16
+#define CLK_AUD_I2SIN6                         17
+#define CLK_AUD_I2SO1                          18
+#define CLK_AUD_I2SO2                          19
+#define CLK_AUD_I2SO3                          20
+#define CLK_AUD_I2SO4                          21
+#define CLK_AUD_I2SO5                          22
+#define CLK_AUD_I2SO6                          23
+#define CLK_AUD_ASRCI1                         24
+#define CLK_AUD_ASRCI2                         25
+#define CLK_AUD_ASRCO1                         26
+#define CLK_AUD_ASRCO2                         27
+#define CLK_AUD_ASRC11                         28
+#define CLK_AUD_ASRC12                         29
+#define CLK_AUD_HDMIRX                         30
+#define CLK_AUD_INTDIR                         31
+#define CLK_AUD_A1SYS                          32
+#define CLK_AUD_A2SYS                          33
+#define CLK_AUD_AFE_CONN                       34
+#define CLK_AUD_AFE_PCMIF                      35
+#define CLK_AUD_AFE_MRGIF                      36
+
+#define CLK_AUD_MMIF_UL1                       37
+#define CLK_AUD_MMIF_UL2                       38
+#define CLK_AUD_MMIF_UL3                       39
+#define CLK_AUD_MMIF_UL4                       40
+#define CLK_AUD_MMIF_UL5                       41
+#define CLK_AUD_MMIF_UL6                       42
+#define CLK_AUD_MMIF_DL1                       43
+#define CLK_AUD_MMIF_DL2                       44
+#define CLK_AUD_MMIF_DL3                       45
+#define CLK_AUD_MMIF_DL4                       46
+#define CLK_AUD_MMIF_DL5                       47
+#define CLK_AUD_MMIF_DL6                       48
+#define CLK_AUD_MMIF_DLMCH                     49
+#define CLK_AUD_MMIF_ARB1                      50
+#define CLK_AUD_MMIF_AWB1                      51
+#define CLK_AUD_MMIF_AWB2                      52
+#define CLK_AUD_MMIF_DAI                       53
+
+#define CLK_AUD_DMIC1                          54
+#define CLK_AUD_DMIC2                          55
+#define CLK_AUD_ASRCI3                         56
+#define CLK_AUD_ASRCI4                         57
+#define CLK_AUD_ASRCI5                         58
+#define CLK_AUD_ASRCI6                         59
+#define CLK_AUD_ASRCO3                         60
+#define CLK_AUD_ASRCO4                         61
+#define CLK_AUD_ASRCO5                         62
+#define CLK_AUD_ASRCO6                         63
+#define CLK_AUD_MEM_ASRC1                      64
+#define CLK_AUD_MEM_ASRC2                      65
+#define CLK_AUD_MEM_ASRC3                      66
+#define CLK_AUD_MEM_ASRC4                      67
+#define CLK_AUD_MEM_ASRC5                      68
+#define CLK_AUD_DSD_ENC                                69
+#define CLK_AUD_ASRC_BRG                       70
+#define CLK_AUD_NR                             71
+
+/* MMSYS */
+
+#define CLK_MM_SMI_COMMON                      1
+#define CLK_MM_SMI_LARB0                       2
+#define CLK_MM_CMDQ                            3
+#define CLK_MM_MUTEX                           4
+#define CLK_MM_DISP_COLOR                      5
+#define CLK_MM_DISP_BLS                                6
+#define CLK_MM_DISP_WDMA                       7
+#define CLK_MM_DISP_RDMA                       8
+#define CLK_MM_DISP_OVL                                9
+#define CLK_MM_MDP_TDSHP                       10
+#define CLK_MM_MDP_WROT                                11
+#define CLK_MM_MDP_WDMA                                12
+#define CLK_MM_MDP_RSZ1                                13
+#define CLK_MM_MDP_RSZ0                                14
+#define CLK_MM_MDP_RDMA                                15
+#define CLK_MM_MDP_BLS_26M                     16
+#define CLK_MM_CAM_MDP                         17
+#define CLK_MM_FAKE_ENG                                18
+#define CLK_MM_MUTEX_32K                       19
+#define CLK_MM_DISP_RDMA1                      20
+#define CLK_MM_DISP_UFOE                       21
+
+#define CLK_MM_DSI_ENGINE                      22
+#define CLK_MM_DSI_DIG                         23
+#define CLK_MM_DPI_DIGL                                24
+#define CLK_MM_DPI_ENGINE                      25
+#define CLK_MM_DPI1_DIGL                       26
+#define CLK_MM_DPI1_ENGINE                     27
+#define CLK_MM_TVE_OUTPUT                      28
+#define CLK_MM_TVE_INPUT                       29
+#define CLK_MM_HDMI_PIXEL                      30
+#define CLK_MM_HDMI_PLL                                31
+#define CLK_MM_HDMI_AUDIO                      32
+#define CLK_MM_HDMI_SPDIF                      33
+#define CLK_MM_TVE_FMM                         34
+#define CLK_MM_NR                              35
+
+/* IMGSYS */
+
+#define CLK_IMG_SMI_COMM                       1
+#define CLK_IMG_RESZ                           2
+#define CLK_IMG_JPGDEC_SMI                     3
+#define CLK_IMG_JPGDEC                         4
+#define CLK_IMG_VENC_LT                                5
+#define CLK_IMG_VENC                           6
+#define CLK_IMG_NR                             7
+
+/* VDEC */
+
+#define CLK_VDEC_CKGEN                         1
+#define CLK_VDEC_LARB                          2
+#define CLK_VDEC_NR                            3
+
+/* HIFSYS */
+
+#define CLK_HIFSYS_USB0PHY                     1
+#define CLK_HIFSYS_USB1PHY                     2
+#define CLK_HIFSYS_PCIE0                       3
+#define CLK_HIFSYS_PCIE1                       4
+#define CLK_HIFSYS_PCIE2                       5
+#define CLK_HIFSYS_NR                          6
+
+/* ETHSYS */
+#define CLK_ETHSYS_HSDMA                       1
+#define CLK_ETHSYS_ESW                         2
+#define CLK_ETHSYS_GP2                         3
+#define CLK_ETHSYS_GP1                         4
+#define CLK_ETHSYS_PCM                         5
+#define CLK_ETHSYS_GDMA                                6
+#define CLK_ETHSYS_I2S                         7
+#define CLK_ETHSYS_CRYPTO                      8
+#define CLK_ETHSYS_NR                          9
+
+/* BDP */
+
+#define CLK_BDP_BRG_BA                         1
+#define CLK_BDP_BRG_DRAM                       2
+#define CLK_BDP_LARB_DRAM                      3
+#define CLK_BDP_WR_VDI_PXL                     4
+#define CLK_BDP_WR_VDI_DRAM                    5
+#define CLK_BDP_WR_B                           6
+#define CLK_BDP_DGI_IN                         7
+#define CLK_BDP_DGI_OUT                                8
+#define CLK_BDP_FMT_MAST_27                    9
+#define CLK_BDP_FMT_B                          10
+#define CLK_BDP_OSD_B                          11
+#define CLK_BDP_OSD_DRAM                       12
+#define CLK_BDP_OSD_AGENT                      13
+#define CLK_BDP_OSD_PXL                                14
+#define CLK_BDP_RLE_B                          15
+#define CLK_BDP_RLE_AGENT                      16
+#define CLK_BDP_RLE_DRAM                       17
+#define CLK_BDP_F27M                           18
+#define CLK_BDP_F27M_VDOUT                     19
+#define CLK_BDP_F27_74_74                      20
+#define CLK_BDP_F2FS                           21
+#define CLK_BDP_F2FS74_148                     22
+#define CLK_BDP_FB                             23
+#define CLK_BDP_VDO_DRAM                       24
+#define CLK_BDP_VDO_2FS                                25
+#define CLK_BDP_VDO_B                          26
+#define CLK_BDP_WR_DI_PXL                      27
+#define CLK_BDP_WR_DI_DRAM                     28
+#define CLK_BDP_WR_DI_B                                29
+#define CLK_BDP_NR_PXL                         30
+#define CLK_BDP_NR_DRAM                                31
+#define CLK_BDP_NR_B                           32
+
+#define CLK_BDP_RX_F                           33
+#define CLK_BDP_RX_X                           34
+#define CLK_BDP_RXPDT                          35
+#define CLK_BDP_RX_CSCL_N                      36
+#define CLK_BDP_RX_CSCL                                37
+#define CLK_BDP_RX_DDCSCL_N                    38
+#define CLK_BDP_RX_DDCSCL                      39
+#define CLK_BDP_RX_VCO                         40
+#define CLK_BDP_RX_DP                          41
+#define CLK_BDP_RX_P                           42
+#define CLK_BDP_RX_M                           43
+#define CLK_BDP_RX_PLL                         44
+#define CLK_BDP_BRG_RT_B                       45
+#define CLK_BDP_BRG_RT_DRAM                    46
+#define CLK_BDP_LARBRT_DRAM                    47
+#define CLK_BDP_TMDS_SYN                       48
+#define CLK_BDP_HDMI_MON                       49
+#define CLK_BDP_NR                             50
+
+#endif /* _DT_BINDINGS_CLK_MT2701_H */
diff --git a/include/dt-bindings/clock/qcom,gcc-mdm9615.h b/include/dt-bindings/clock/qcom,gcc-mdm9615.h
new file mode 100644 (file)
index 0000000..9ab2c40
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MDM_GCC_9615_H
+#define _DT_BINDINGS_CLK_MDM_GCC_9615_H
+
+#define AFAB_CLK_SRC                           0
+#define AFAB_CORE_CLK                          1
+#define SFAB_MSS_Q6_SW_A_CLK                   2
+#define SFAB_MSS_Q6_FW_A_CLK                   3
+#define QDSS_STM_CLK                           4
+#define SCSS_A_CLK                             5
+#define SCSS_H_CLK                             6
+#define SCSS_XO_SRC_CLK                                7
+#define AFAB_EBI1_CH0_A_CLK                    8
+#define AFAB_EBI1_CH1_A_CLK                    9
+#define AFAB_AXI_S0_FCLK                       10
+#define AFAB_AXI_S1_FCLK                       11
+#define AFAB_AXI_S2_FCLK                       12
+#define AFAB_AXI_S3_FCLK                       13
+#define AFAB_AXI_S4_FCLK                       14
+#define SFAB_CORE_CLK                          15
+#define SFAB_AXI_S0_FCLK                       16
+#define SFAB_AXI_S1_FCLK                       17
+#define SFAB_AXI_S2_FCLK                       18
+#define SFAB_AXI_S3_FCLK                       19
+#define SFAB_AXI_S4_FCLK                       20
+#define SFAB_AHB_S0_FCLK                       21
+#define SFAB_AHB_S1_FCLK                       22
+#define SFAB_AHB_S2_FCLK                       23
+#define SFAB_AHB_S3_FCLK                       24
+#define SFAB_AHB_S4_FCLK                       25
+#define SFAB_AHB_S5_FCLK                       26
+#define SFAB_AHB_S6_FCLK                       27
+#define SFAB_AHB_S7_FCLK                       28
+#define QDSS_AT_CLK_SRC                                29
+#define QDSS_AT_CLK                            30
+#define QDSS_TRACECLKIN_CLK_SRC                        31
+#define QDSS_TRACECLKIN_CLK                    32
+#define QDSS_TSCTR_CLK_SRC                     33
+#define QDSS_TSCTR_CLK                         34
+#define SFAB_ADM0_M0_A_CLK                     35
+#define SFAB_ADM0_M1_A_CLK                     36
+#define SFAB_ADM0_M2_H_CLK                     37
+#define ADM0_CLK                               38
+#define ADM0_PBUS_CLK                          39
+#define MSS_XPU_CLK                            40
+#define IMEM0_A_CLK                            41
+#define QDSS_H_CLK                             42
+#define PCIE_A_CLK                             43
+#define PCIE_AUX_CLK                           44
+#define PCIE_PHY_REF_CLK                       45
+#define PCIE_H_CLK                             46
+#define SFAB_CLK_SRC                           47
+#define MAHB0_CLK                              48
+#define Q6SW_CLK_SRC                           49
+#define Q6SW_CLK                               50
+#define Q6FW_CLK_SRC                           51
+#define Q6FW_CLK                               52
+#define SFAB_MSS_M_A_CLK                       53
+#define SFAB_USB3_M_A_CLK                      54
+#define SFAB_LPASS_Q6_A_CLK                    55
+#define SFAB_AFAB_M_A_CLK                      56
+#define AFAB_SFAB_M0_A_CLK                     57
+#define AFAB_SFAB_M1_A_CLK                     58
+#define SFAB_SATA_S_H_CLK                      59
+#define DFAB_CLK_SRC                           60
+#define DFAB_CLK                               61
+#define SFAB_DFAB_M_A_CLK                      62
+#define DFAB_SFAB_M_A_CLK                      63
+#define DFAB_SWAY0_H_CLK                       64
+#define DFAB_SWAY1_H_CLK                       65
+#define DFAB_ARB0_H_CLK                                66
+#define DFAB_ARB1_H_CLK                                67
+#define PPSS_H_CLK                             68
+#define PPSS_PROC_CLK                          69
+#define PPSS_TIMER0_CLK                                70
+#define PPSS_TIMER1_CLK                                71
+#define PMEM_A_CLK                             72
+#define DMA_BAM_H_CLK                          73
+#define SIC_H_CLK                              74
+#define SPS_TIC_H_CLK                          75
+#define SLIMBUS_H_CLK                          76
+#define SLIMBUS_XO_SRC_CLK                     77
+#define CFPB_2X_CLK_SRC                                78
+#define CFPB_CLK                               79
+#define CFPB0_H_CLK                            80
+#define CFPB1_H_CLK                            81
+#define CFPB2_H_CLK                            82
+#define SFAB_CFPB_M_H_CLK                      83
+#define CFPB_MASTER_H_CLK                      84
+#define SFAB_CFPB_S_H_CLK                      85
+#define CFPB_SPLITTER_H_CLK                    86
+#define TSIF_H_CLK                             87
+#define TSIF_INACTIVITY_TIMERS_CLK             88
+#define TSIF_REF_SRC                           89
+#define TSIF_REF_CLK                           90
+#define CE1_H_CLK                              91
+#define CE1_CORE_CLK                           92
+#define CE1_SLEEP_CLK                          93
+#define CE2_H_CLK                              94
+#define CE2_CORE_CLK                           95
+#define SFPB_H_CLK_SRC                         97
+#define SFPB_H_CLK                             98
+#define SFAB_SFPB_M_H_CLK                      99
+#define SFAB_SFPB_S_H_CLK                      100
+#define RPM_PROC_CLK                           101
+#define RPM_BUS_H_CLK                          102
+#define RPM_SLEEP_CLK                          103
+#define RPM_TIMER_CLK                          104
+#define RPM_MSG_RAM_H_CLK                      105
+#define PMIC_ARB0_H_CLK                                106
+#define PMIC_ARB1_H_CLK                                107
+#define PMIC_SSBI2_SRC                         108
+#define PMIC_SSBI2_CLK                         109
+#define SDC1_H_CLK                             110
+#define SDC2_H_CLK                             111
+#define SDC3_H_CLK                             112
+#define SDC4_H_CLK                             113
+#define SDC5_H_CLK                             114
+#define SDC1_SRC                               115
+#define SDC2_SRC                               116
+#define SDC3_SRC                               117
+#define SDC4_SRC                               118
+#define SDC5_SRC                               119
+#define SDC1_CLK                               120
+#define SDC2_CLK                               121
+#define SDC3_CLK                               122
+#define SDC4_CLK                               123
+#define SDC5_CLK                               124
+#define DFAB_A2_H_CLK                          125
+#define USB_HS1_H_CLK                          126
+#define USB_HS1_XCVR_SRC                       127
+#define USB_HS1_XCVR_CLK                       128
+#define USB_HSIC_H_CLK                         129
+#define USB_HSIC_XCVR_FS_SRC                   130
+#define USB_HSIC_XCVR_FS_CLK                   131
+#define USB_HSIC_SYSTEM_CLK_SRC                        132
+#define USB_HSIC_SYSTEM_CLK                    133
+#define CFPB0_C0_H_CLK                         134
+#define CFPB0_C1_H_CLK                         135
+#define CFPB0_D0_H_CLK                         136
+#define CFPB0_D1_H_CLK                         137
+#define USB_FS1_H_CLK                          138
+#define USB_FS1_XCVR_FS_SRC                    139
+#define USB_FS1_XCVR_FS_CLK                    140
+#define USB_FS1_SYSTEM_CLK                     141
+#define USB_FS2_H_CLK                          142
+#define USB_FS2_XCVR_FS_SRC                    143
+#define USB_FS2_XCVR_FS_CLK                    144
+#define USB_FS2_SYSTEM_CLK                     145
+#define GSBI_COMMON_SIM_SRC                    146
+#define GSBI1_H_CLK                            147
+#define GSBI2_H_CLK                            148
+#define GSBI3_H_CLK                            149
+#define GSBI4_H_CLK                            150
+#define GSBI5_H_CLK                            151
+#define GSBI6_H_CLK                            152
+#define GSBI7_H_CLK                            153
+#define GSBI8_H_CLK                            154
+#define GSBI9_H_CLK                            155
+#define GSBI10_H_CLK                           156
+#define GSBI11_H_CLK                           157
+#define GSBI12_H_CLK                           158
+#define GSBI1_UART_SRC                         159
+#define GSBI1_UART_CLK                         160
+#define GSBI2_UART_SRC                         161
+#define GSBI2_UART_CLK                         162
+#define GSBI3_UART_SRC                         163
+#define GSBI3_UART_CLK                         164
+#define GSBI4_UART_SRC                         165
+#define GSBI4_UART_CLK                         166
+#define GSBI5_UART_SRC                         167
+#define GSBI5_UART_CLK                         168
+#define GSBI6_UART_SRC                         169
+#define GSBI6_UART_CLK                         170
+#define GSBI7_UART_SRC                         171
+#define GSBI7_UART_CLK                         172
+#define GSBI8_UART_SRC                         173
+#define GSBI8_UART_CLK                         174
+#define GSBI9_UART_SRC                         175
+#define GSBI9_UART_CLK                         176
+#define GSBI10_UART_SRC                                177
+#define GSBI10_UART_CLK                                178
+#define GSBI11_UART_SRC                                179
+#define GSBI11_UART_CLK                                180
+#define GSBI12_UART_SRC                                181
+#define GSBI12_UART_CLK                                182
+#define GSBI1_QUP_SRC                          183
+#define GSBI1_QUP_CLK                          184
+#define GSBI2_QUP_SRC                          185
+#define GSBI2_QUP_CLK                          186
+#define GSBI3_QUP_SRC                          187
+#define GSBI3_QUP_CLK                          188
+#define GSBI4_QUP_SRC                          189
+#define GSBI4_QUP_CLK                          190
+#define GSBI5_QUP_SRC                          191
+#define GSBI5_QUP_CLK                          192
+#define GSBI6_QUP_SRC                          193
+#define GSBI6_QUP_CLK                          194
+#define GSBI7_QUP_SRC                          195
+#define GSBI7_QUP_CLK                          196
+#define GSBI8_QUP_SRC                          197
+#define GSBI8_QUP_CLK                          198
+#define GSBI9_QUP_SRC                          199
+#define GSBI9_QUP_CLK                          200
+#define GSBI10_QUP_SRC                         201
+#define GSBI10_QUP_CLK                         202
+#define GSBI11_QUP_SRC                         203
+#define GSBI11_QUP_CLK                         204
+#define GSBI12_QUP_SRC                         205
+#define GSBI12_QUP_CLK                         206
+#define GSBI1_SIM_CLK                          207
+#define GSBI2_SIM_CLK                          208
+#define GSBI3_SIM_CLK                          209
+#define GSBI4_SIM_CLK                          210
+#define GSBI5_SIM_CLK                          211
+#define GSBI6_SIM_CLK                          212
+#define GSBI7_SIM_CLK                          213
+#define GSBI8_SIM_CLK                          214
+#define GSBI9_SIM_CLK                          215
+#define GSBI10_SIM_CLK                         216
+#define GSBI11_SIM_CLK                         217
+#define GSBI12_SIM_CLK                         218
+#define USB_HSIC_HSIC_CLK_SRC                  219
+#define USB_HSIC_HSIC_CLK                      220
+#define USB_HSIC_HSIO_CAL_CLK                  221
+#define SPDM_CFG_H_CLK                         222
+#define SPDM_MSTR_H_CLK                                223
+#define SPDM_FF_CLK_SRC                                224
+#define SPDM_FF_CLK                            225
+#define SEC_CTRL_CLK                           226
+#define SEC_CTRL_ACC_CLK_SRC                   227
+#define SEC_CTRL_ACC_CLK                       228
+#define TLMM_H_CLK                             229
+#define TLMM_CLK                               230
+#define SFAB_MSS_S_H_CLK                       231
+#define MSS_SLP_CLK                            232
+#define MSS_Q6SW_JTAG_CLK                      233
+#define MSS_Q6FW_JTAG_CLK                      234
+#define MSS_S_H_CLK                            235
+#define MSS_CXO_SRC_CLK                                236
+#define SATA_H_CLK                             237
+#define SATA_CLK_SRC                           238
+#define SATA_RXOOB_CLK                         239
+#define SATA_PMALIVE_CLK                       240
+#define SATA_PHY_REF_CLK                       241
+#define TSSC_CLK_SRC                           242
+#define TSSC_CLK                               243
+#define PDM_SRC                                        244
+#define PDM_CLK                                        245
+#define GP0_SRC                                        246
+#define GP0_CLK                                        247
+#define GP1_SRC                                        248
+#define GP1_CLK                                        249
+#define GP2_SRC                                        250
+#define GP2_CLK                                        251
+#define MPM_CLK                                        252
+#define EBI1_CLK_SRC                           253
+#define EBI1_CH0_CLK                           254
+#define EBI1_CH1_CLK                           255
+#define EBI1_2X_CLK                            256
+#define EBI1_CH0_DQ_CLK                                257
+#define EBI1_CH1_DQ_CLK                                258
+#define EBI1_CH0_CA_CLK                                259
+#define EBI1_CH1_CA_CLK                                260
+#define EBI1_XO_CLK                            261
+#define SFAB_SMPSS_S_H_CLK                     262
+#define PRNG_SRC                               263
+#define PRNG_CLK                               264
+#define PXO_SRC                                        265
+#define LPASS_CXO_CLK                          266
+#define LPASS_PXO_CLK                          267
+#define SPDM_CY_PORT0_CLK                      268
+#define SPDM_CY_PORT1_CLK                      269
+#define SPDM_CY_PORT2_CLK                      270
+#define SPDM_CY_PORT3_CLK                      271
+#define SPDM_CY_PORT4_CLK                      272
+#define SPDM_CY_PORT5_CLK                      273
+#define SPDM_CY_PORT6_CLK                      274
+#define SPDM_CY_PORT7_CLK                      275
+#define PLL0                                   276
+#define PLL0_VOTE                              277
+#define PLL3                                   278
+#define PLL3_VOTE                              279
+#define PLL4_VOTE                              280
+#define PLL5                                   281
+#define PLL5_VOTE                              282
+#define PLL6                                   283
+#define PLL6_VOTE                              284
+#define PLL7_VOTE                              285
+#define PLL8                                   286
+#define PLL8_VOTE                              287
+#define PLL9                                   288
+#define PLL10                                  289
+#define PLL11                                  290
+#define PLL12                                  291
+#define PLL13                                  292
+#define PLL14                                  293
+#define PLL14_VOTE                             294
+#define USB_HS3_H_CLK                          295
+#define USB_HS3_XCVR_SRC                       296
+#define USB_HS3_XCVR_CLK                       297
+#define USB_HS4_H_CLK                          298
+#define USB_HS4_XCVR_SRC                       299
+#define USB_HS4_XCVR_CLK                       300
+#define SATA_PHY_CFG_CLK                       301
+#define SATA_A_CLK                             302
+#define CE3_SRC                                        303
+#define CE3_CORE_CLK                           304
+#define CE3_H_CLK                              305
+#define USB_HS1_SYSTEM_CLK_SRC                 306
+#define USB_HS1_SYSTEM_CLK                     307
+
+#endif
index 6f814db..b7ea1e8 100644 (file)
 #define GCC_MSMPU_BCR                                          98
 #define GCC_MSS_Q6_BCR                                         99
 #define GCC_QREFS_VBG_CAL_BCR                                  100
+#define GCC_PCIE_PHY_COM_BCR                                   101
+#define GCC_PCIE_PHY_COM_NOCSR_BCR                             102
+
 
 /* Indexes for GDSCs */
 #define AGGRE0_NOC_GDSC                        0
diff --git a/include/dt-bindings/clock/qcom,lcc-mdm9615.h b/include/dt-bindings/clock/qcom,lcc-mdm9615.h
new file mode 100644 (file)
index 0000000..cac963a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_CLK_LCC_MDM9615_H
+#define _DT_BINDINGS_CLK_LCC_MDM9615_H
+
+#define PLL4                           0
+#define MI2S_OSR_SRC                   1
+#define MI2S_OSR_CLK                   2
+#define MI2S_DIV_CLK                   3
+#define MI2S_BIT_DIV_CLK               4
+#define MI2S_BIT_CLK                   5
+#define PCM_SRC                                6
+#define PCM_CLK_OUT                    7
+#define PCM_CLK                                8
+#define SLIMBUS_SRC                    9
+#define AUDIO_SLIMBUS_CLK              10
+#define SPS_SLIMBUS_CLK                        11
+#define CODEC_I2S_MIC_OSR_SRC          12
+#define CODEC_I2S_MIC_OSR_CLK          13
+#define CODEC_I2S_MIC_DIV_CLK          14
+#define CODEC_I2S_MIC_BIT_DIV_CLK      15
+#define CODEC_I2S_MIC_BIT_CLK          16
+#define SPARE_I2S_MIC_OSR_SRC          17
+#define SPARE_I2S_MIC_OSR_CLK          18
+#define SPARE_I2S_MIC_DIV_CLK          19
+#define SPARE_I2S_MIC_BIT_DIV_CLK      20
+#define SPARE_I2S_MIC_BIT_CLK          21
+#define CODEC_I2S_SPKR_OSR_SRC         22
+#define CODEC_I2S_SPKR_OSR_CLK         23
+#define CODEC_I2S_SPKR_DIV_CLK         24
+#define CODEC_I2S_SPKR_BIT_DIV_CLK     25
+#define CODEC_I2S_SPKR_BIT_CLK         26
+#define SPARE_I2S_SPKR_OSR_SRC         27
+#define SPARE_I2S_SPKR_OSR_CLK         28
+#define SPARE_I2S_SPKR_DIV_CLK         29
+#define SPARE_I2S_SPKR_BIT_DIV_CLK     30
+#define SPARE_I2S_SPKR_BIT_CLK         31
+
+#endif
index 7d3a7fa..5abc445 100644 (file)
 #define FD_GDSC                        12
 #define MDSS_GDSC              13
 #define GPU_GX_GDSC            14
+#define MMAGIC_BIMC_GDSC       15
 
 #endif
index 50a44cf..220a60f 100644 (file)
 #define SCLK_DPHY_RX0_CFG              165
 #define SCLK_RMII_SRC                  166
 #define SCLK_PCIEPHY_REF100M           167
+#define SCLK_DDRC                      168
 
 #define DCLK_VOP0                      180
 #define DCLK_VOP1                      181
 #define DCLK_VOP0_DIV                  182
 #define DCLK_VOP1_DIV                  183
 #define DCLK_M0_PERILP                 184
+#define DCLK_VOP0_FRAC                 185
+#define DCLK_VOP1_FRAC                 186
 
 #define FCLK_CM0S                      190
 
diff --git a/include/dt-bindings/reset/gxbb-aoclkc.h b/include/dt-bindings/reset/gxbb-aoclkc.h
new file mode 100644 (file)
index 0000000..9e3fd60
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * The full GNU General Public License is included in this distribution
+ * in the file called COPYING.
+ *
+ * BSD LICENSE
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_GXBB_AOCLK
+#define DT_BINDINGS_RESET_AMLOGIC_MESON_GXBB_AOCLK
+
+#define RESET_AO_REMOTE                0
+#define RESET_AO_I2C_MASTER    1
+#define RESET_AO_I2C_SLAVE     2
+#define RESET_AO_UART1         3
+#define RESET_AO_UART2         4
+#define RESET_AO_IR_BLASTER    5
+
+#endif
diff --git a/include/dt-bindings/reset/mt2701-resets.h b/include/dt-bindings/reset/mt2701-resets.h
new file mode 100644 (file)
index 0000000..aaf0305
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015 MediaTek, Shunli Wang <shunli.wang@mediatek.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 in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2701
+#define _DT_BINDINGS_RESET_CONTROLLER_MT2701
+
+/* INFRACFG resets */
+#define MT2701_INFRA_EMI_REG_RST               0
+#define MT2701_INFRA_DRAMC0_A0_RST             1
+#define MT2701_INFRA_FHCTL_RST                 2
+#define MT2701_INFRA_APCIRQ_EINT_RST           3
+#define MT2701_INFRA_APXGPT_RST                        4
+#define MT2701_INFRA_SCPSYS_RST                        5
+#define MT2701_INFRA_KP_RST                    6
+#define MT2701_INFRA_PMIC_WRAP_RST             7
+#define MT2701_INFRA_MIPI_RST                  8
+#define MT2701_INFRA_IRRX_RST                  9
+#define MT2701_INFRA_CEC_RST                   10
+#define MT2701_INFRA_EMI_RST                   32
+#define MT2701_INFRA_DRAMC0_RST                        34
+#define MT2701_INFRA_TRNG_RST                  37
+#define MT2701_INFRA_SYSIRQ_RST                        38
+
+/*  PERICFG resets */
+#define MT2701_PERI_UART0_SW_RST               0
+#define MT2701_PERI_UART1_SW_RST               1
+#define MT2701_PERI_UART2_SW_RST               2
+#define MT2701_PERI_UART3_SW_RST               3
+#define MT2701_PERI_GCPU_SW_RST                        5
+#define MT2701_PERI_BTIF_SW_RST                        6
+#define MT2701_PERI_PWM_SW_RST                 8
+#define MT2701_PERI_AUXADC_SW_RST              10
+#define MT2701_PERI_DMA_SW_RST                 11
+#define MT2701_PERI_NFI_SW_RST                 14
+#define MT2701_PERI_NLI_SW_RST                 15
+#define MT2701_PERI_THERM_SW_RST               16
+#define MT2701_PERI_MSDC2_SW_RST               17
+#define MT2701_PERI_MSDC0_SW_RST               19
+#define MT2701_PERI_MSDC1_SW_RST               20
+#define MT2701_PERI_I2C0_SW_RST                        22
+#define MT2701_PERI_I2C1_SW_RST                        23
+#define MT2701_PERI_I2C2_SW_RST                        24
+#define MT2701_PERI_I2C3_SW_RST                        25
+#define MT2701_PERI_USB_SW_RST                 28
+#define MT2701_PERI_ETH_SW_RST                 29
+#define MT2701_PERI_SPI0_SW_RST                        33
+
+/* TOPRGU resets */
+#define MT2701_TOPRGU_INFRA_RST                        0
+#define MT2701_TOPRGU_MM_RST                   1
+#define MT2701_TOPRGU_MFG_RST                  2
+#define MT2701_TOPRGU_ETHDMA_RST               3
+#define MT2701_TOPRGU_VDEC_RST                 4
+#define MT2701_TOPRGU_VENC_IMG_RST             5
+#define MT2701_TOPRGU_DDRPHY_RST               6
+#define MT2701_TOPRGU_MD_RST                   7
+#define MT2701_TOPRGU_INFRA_AO_RST             8
+#define MT2701_TOPRGU_CONN_RST                 9
+#define MT2701_TOPRGU_APMIXED_RST              10
+#define MT2701_TOPRGU_HIFSYS_RST               11
+#define MT2701_TOPRGU_CONN_MCU_RST             12
+#define MT2701_TOPRGU_BDP_DISP_RST             13
+
+/* HIFSYS resets */
+#define MT2701_HIFSYS_UHOST0_RST               3
+#define MT2701_HIFSYS_UHOST1_RST               4
+#define MT2701_HIFSYS_UPHY0_RST                        21
+#define MT2701_HIFSYS_UPHY1_RST                        22
+#define MT2701_HIFSYS_PCIE0_RST                        24
+#define MT2701_HIFSYS_PCIE1_RST                        25
+#define MT2701_HIFSYS_PCIE2_RST                        26
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */
diff --git a/include/dt-bindings/reset/qcom,gcc-mdm9615.h b/include/dt-bindings/reset/qcom,gcc-mdm9615.h
new file mode 100644 (file)
index 0000000..7f86e9a
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) BayLibre, SAS.
+ * Author : Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_RESET_GCC_MDM9615_H
+#define _DT_BINDINGS_RESET_GCC_MDM9615_H
+
+#define SFAB_MSS_Q6_SW_RESET                           0
+#define SFAB_MSS_Q6_FW_RESET                           1
+#define QDSS_STM_RESET                                 2
+#define AFAB_SMPSS_S_RESET                             3
+#define AFAB_SMPSS_M1_RESET                            4
+#define AFAB_SMPSS_M0_RESET                            5
+#define AFAB_EBI1_CH0_RESET                            6
+#define AFAB_EBI1_CH1_RESET                            7
+#define SFAB_ADM0_M0_RESET                             8
+#define SFAB_ADM0_M1_RESET                             9
+#define SFAB_ADM0_M2_RESET                             10
+#define ADM0_C2_RESET                                  11
+#define ADM0_C1_RESET                                  12
+#define ADM0_C0_RESET                                  13
+#define ADM0_PBUS_RESET                                        14
+#define ADM0_RESET                                     15
+#define QDSS_CLKS_SW_RESET                             16
+#define QDSS_POR_RESET                                 17
+#define QDSS_TSCTR_RESET                               18
+#define QDSS_HRESET_RESET                              19
+#define QDSS_AXI_RESET                                 20
+#define QDSS_DBG_RESET                                 21
+#define PCIE_A_RESET                                   22
+#define PCIE_AUX_RESET                                 23
+#define PCIE_H_RESET                                   24
+#define SFAB_PCIE_M_RESET                              25
+#define SFAB_PCIE_S_RESET                              26
+#define SFAB_MSS_M_RESET                               27
+#define SFAB_USB3_M_RESET                              28
+#define SFAB_RIVA_M_RESET                              29
+#define SFAB_LPASS_RESET                               30
+#define SFAB_AFAB_M_RESET                              31
+#define AFAB_SFAB_M0_RESET                             32
+#define AFAB_SFAB_M1_RESET                             33
+#define SFAB_SATA_S_RESET                              34
+#define SFAB_DFAB_M_RESET                              35
+#define DFAB_SFAB_M_RESET                              36
+#define DFAB_SWAY0_RESET                               37
+#define DFAB_SWAY1_RESET                               38
+#define DFAB_ARB0_RESET                                        39
+#define DFAB_ARB1_RESET                                        40
+#define PPSS_PROC_RESET                                        41
+#define PPSS_RESET                                     42
+#define DMA_BAM_RESET                                  43
+#define SPS_TIC_H_RESET                                        44
+#define SLIMBUS_H_RESET                                        45
+#define SFAB_CFPB_M_RESET                              46
+#define SFAB_CFPB_S_RESET                              47
+#define TSIF_H_RESET                                   48
+#define CE1_H_RESET                                    49
+#define CE1_CORE_RESET                                 50
+#define CE1_SLEEP_RESET                                        51
+#define CE2_H_RESET                                    52
+#define CE2_CORE_RESET                                 53
+#define SFAB_SFPB_M_RESET                              54
+#define SFAB_SFPB_S_RESET                              55
+#define RPM_PROC_RESET                                 56
+#define PMIC_SSBI2_RESET                               57
+#define SDC1_RESET                                     58
+#define SDC2_RESET                                     59
+#define SDC3_RESET                                     60
+#define SDC4_RESET                                     61
+#define SDC5_RESET                                     62
+#define DFAB_A2_RESET                                  63
+#define USB_HS1_RESET                                  64
+#define USB_HSIC_RESET                                 65
+#define USB_FS1_XCVR_RESET                             66
+#define USB_FS1_RESET                                  67
+#define USB_FS2_XCVR_RESET                             68
+#define USB_FS2_RESET                                  69
+#define GSBI1_RESET                                    70
+#define GSBI2_RESET                                    71
+#define GSBI3_RESET                                    72
+#define GSBI4_RESET                                    73
+#define GSBI5_RESET                                    74
+#define GSBI6_RESET                                    75
+#define GSBI7_RESET                                    76
+#define GSBI8_RESET                                    77
+#define GSBI9_RESET                                    78
+#define GSBI10_RESET                                   79
+#define GSBI11_RESET                                   80
+#define GSBI12_RESET                                   81
+#define SPDM_RESET                                     82
+#define TLMM_H_RESET                                   83
+#define SFAB_MSS_S_RESET                               84
+#define MSS_SLP_RESET                                  85
+#define MSS_Q6SW_JTAG_RESET                            86
+#define MSS_Q6FW_JTAG_RESET                            87
+#define MSS_RESET                                      88
+#define SATA_H_RESET                                   89
+#define SATA_RXOOB_RESE                                        90
+#define SATA_PMALIVE_RESET                             91
+#define SATA_SFAB_M_RESET                              92
+#define TSSC_RESET                                     93
+#define PDM_RESET                                      94
+#define MPM_H_RESET                                    95
+#define MPM_RESET                                      96
+#define SFAB_SMPSS_S_RESET                             97
+#define PRNG_RESET                                     98
+#define RIVA_RESET                                     99
+#define USB_HS3_RESET                                  100
+#define USB_HS4_RESET                                  101
+#define CE3_RESET                                      102
+#define PCIE_EXT_PCI_RESET                             103
+#define PCIE_PHY_RESET                                 104
+#define PCIE_PCI_RESET                                 105
+#define PCIE_POR_RESET                                 106
+#define PCIE_HCLK_RESET                                        107
+#define PCIE_ACLK_RESET                                        108
+#define CE3_H_RESET                                    109
+#define SFAB_CE3_M_RESET                               110
+#define SFAB_CE3_S_RESET                               111
+#define SATA_RESET                                     112
+#define CE3_SLEEP_RESET                                        113
+#define GSS_SLP_RESET                                  114
+#define GSS_RESET                                      115
+
+#endif
index a39c0c5..37b8fdc 100644 (file)
@@ -780,6 +780,18 @@ extern struct of_device_id __clk_of_table;
 
 #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn)
 
+/*
+ * Use this macro when you have a driver that requires two initialization
+ * routines, one at of_clk_init(), and one at platform device probe
+ */
+#define CLK_OF_DECLARE_DRIVER(name, compat, fn) \
+       static void name##_of_clk_init_driver(struct device_node *np)   \
+       {                                                               \
+               of_node_clear_flag(np, OF_POPULATED);                   \
+               fn(np);                                                 \
+       }                                                               \
+       OF_DECLARE_1(clk, name, compat, name##_of_clk_init_driver)
+
 #ifdef CONFIG_OF
 int of_clk_add_provider(struct device_node *np,
                        struct clk *(*clk_src_get)(struct of_phandle_args *args,
@@ -842,7 +854,7 @@ of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data)
 {
        return ERR_PTR(-ENOENT);
 }
-static inline int of_clk_get_parent_count(struct device_node *np)
+static inline unsigned int of_clk_get_parent_count(struct device_node *np)
 {
        return 0;
 }
diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
new file mode 100644 (file)
index 0000000..7e28092
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang <hl@rock-chips.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.
+ */
+#ifndef __SOC_ROCKCHIP_SIP_H
+#define __SOC_ROCKCHIP_SIP_H
+
+#define ROCKCHIP_SIP_DRAM_FREQ                 0x82000008
+#define ROCKCHIP_SIP_CONFIG_DRAM_INIT          0x00
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE      0x01
+#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE    0x02
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR     0x03
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW                0x04
+#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE      0x05
+#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ       0x06
+#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM     0x07
+
+#endif