Merge branch 'clk-next-shmobile' into clk-next
authorMichael Turquette <mturquette@linaro.org>
Tue, 18 Nov 2014 23:11:52 +0000 (15:11 -0800)
committerMichael Turquette <mturquette@linaro.org>
Wed, 19 Nov 2014 19:41:19 +0000 (11:41 -0800)
41 files changed:
Documentation/devicetree/bindings/clock/marvell,mmp2.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/marvell,pxa168.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/marvell,pxa910.txt [new file with mode: 0644]
MAINTAINERS
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/mmp2-brownstone.dts
arch/arm/boot/dts/mmp2.dtsi
arch/arm/boot/dts/pxa168-aspenite.dts
arch/arm/boot/dts/pxa168.dtsi
arch/arm/boot/dts/pxa910-dkb.dts
arch/arm/boot/dts/pxa910.dtsi
arch/arm/mach-mmp/Kconfig
arch/arm/mach-mmp/mmp-dt.c
arch/arm/mach-mmp/mmp2-dt.c
drivers/clk/clk.c
drivers/clk/mmp/Makefile
drivers/clk/mmp/clk-frac.c
drivers/clk/mmp/clk-gate.c [new file with mode: 0644]
drivers/clk/mmp/clk-mix.c [new file with mode: 0644]
drivers/clk/mmp/clk-mmp2.c
drivers/clk/mmp/clk-of-mmp2.c [new file with mode: 0644]
drivers/clk/mmp/clk-of-pxa168.c [new file with mode: 0644]
drivers/clk/mmp/clk-of-pxa910.c [new file with mode: 0644]
drivers/clk/mmp/clk-pxa168.c
drivers/clk/mmp/clk-pxa910.c
drivers/clk/mmp/clk.c [new file with mode: 0644]
drivers/clk/mmp/clk.h
drivers/clk/mmp/reset.c [new file with mode: 0644]
drivers/clk/mmp/reset.h [new file with mode: 0644]
drivers/clk/pxa/Makefile
drivers/clk/pxa/clk-pxa.c
drivers/clk/pxa/clk-pxa.h
drivers/clk/pxa/clk-pxa25x.c [new file with mode: 0644]
drivers/clk/pxa/clk-pxa27x.c
drivers/clk/rockchip/clk-rk3188.c
drivers/clk/rockchip/clk-rk3288.c
drivers/clk/rockchip/clk.c
drivers/clk/rockchip/clk.h
include/dt-bindings/clock/marvell,mmp2.h [new file with mode: 0644]
include/dt-bindings/clock/marvell,pxa168.h [new file with mode: 0644]
include/dt-bindings/clock/marvell,pxa910.h [new file with mode: 0644]

diff --git a/Documentation/devicetree/bindings/clock/marvell,mmp2.txt b/Documentation/devicetree/bindings/clock/marvell,mmp2.txt
new file mode 100644 (file)
index 0000000..af376a0
--- /dev/null
@@ -0,0 +1,21 @@
+* Marvell MMP2 Clock Controller
+
+The MMP2 clock subsystem generates and supplies clock to various
+controllers within the MMP2 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,mmp2-clock" - controller compatible with MMP2 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc". So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in <dt-bindings/clock/marvell-mmp2.h>.
diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa168.txt b/Documentation/devicetree/bindings/clock/marvell,pxa168.txt
new file mode 100644 (file)
index 0000000..c62eb1d
--- /dev/null
@@ -0,0 +1,21 @@
+* Marvell PXA168 Clock Controller
+
+The PXA168 clock subsystem generates and supplies clock to various
+controllers within the PXA168 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,pxa168-clock" - controller compatible with PXA168 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 3 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc". So three reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in <dt-bindings/clock/marvell,pxa168.h>.
diff --git a/Documentation/devicetree/bindings/clock/marvell,pxa910.txt b/Documentation/devicetree/bindings/clock/marvell,pxa910.txt
new file mode 100644 (file)
index 0000000..d9f41f3
--- /dev/null
@@ -0,0 +1,21 @@
+* Marvell PXA910 Clock Controller
+
+The PXA910 clock subsystem generates and supplies clock to various
+controllers within the PXA910 SoC.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "marvell,pxa910-clock" - controller compatible with PXA910 SoC.
+
+- reg: physical base address of the clock subsystem and length of memory mapped
+  region. There are 4 places in SOC has clock control logic:
+  "mpmu", "apmu", "apbc", "apbcp". So four reg spaces need to be defined.
+
+- #clock-cells: should be 1.
+- #reset-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in <dt-bindings/clock/marvell-pxa910.h>.
index ea4d0058fd1b68b7d5e11f5228a4867aa0b96eea..924499202dac89afab39ebd93005daa53fcb6ab5 100644 (file)
@@ -2491,8 +2491,9 @@ F:        include/uapi/linux/coda*.h
 
 COMMON CLK FRAMEWORK
 M:     Mike Turquette <mturquette@linaro.org>
+M:     Stephen Boyd <sboyd@codeaurora.org>
 L:     linux-kernel@vger.kernel.org
-T:     git git://git.linaro.org/people/mturquette/linux.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
 S:     Maintained
 F:     drivers/clk/
 X:     drivers/clk/clkdev.c
index 38c89cafa1ab8ea3ee682b8ccb0c02af8739f785..5b31c3f6d8e57803c4858323636364c67f37188c 100644 (file)
@@ -164,6 +164,9 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
 dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
 dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
 dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
+dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
+       pxa910-dkb.dtb \
+       mmp2-brownstone.dtb
 dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb
 dtb-$(CONFIG_ARCH_MXC) += \
        imx1-ads.dtb \
index 7f70a39459f649d7051b5423c754e356686762db..350208c5e1ed2f6d27d192d1c256ab58db5ecb27 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "mmp2.dtsi"
+#include "mmp2.dtsi"
 
 / {
        model = "Marvell MMP2 Brownstone Development Board";
index 4e8b08c628c7ee405efd864f743cbadc8a617321..766bbb8495b60d796ccd857c4965ab4f8d09721c 100644 (file)
@@ -7,7 +7,8 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/marvell,mmp2.h>
 
 / {
        aliases {
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4030000 0x1000>;
                                interrupts = <27>;
+                               clocks = <&soc_clocks MMP2_CLK_UART0>;
+                               resets = <&soc_clocks MMP2_CLK_UART0>;
                                status = "disabled";
                        };
 
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4017000 0x1000>;
                                interrupts = <28>;
+                               clocks = <&soc_clocks MMP2_CLK_UART1>;
+                               resets = <&soc_clocks MMP2_CLK_UART1>;
                                status = "disabled";
                        };
 
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4018000 0x1000>;
                                interrupts = <24>;
+                               clocks = <&soc_clocks MMP2_CLK_UART2>;
+                               resets = <&soc_clocks MMP2_CLK_UART2>;
                                status = "disabled";
                        };
 
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4016000 0x1000>;
                                interrupts = <46>;
+                               clocks = <&soc_clocks MMP2_CLK_UART3>;
+                               resets = <&soc_clocks MMP2_CLK_UART3>;
                                status = "disabled";
                        };
 
                                #gpio-cells = <2>;
                                interrupts = <49>;
                                interrupt-names = "gpio_mux";
+                               clocks = <&soc_clocks MMP2_CLK_GPIO>;
+                               resets = <&soc_clocks MMP2_CLK_GPIO>;
                                interrupt-controller;
                                #interrupt-cells = <1>;
                                ranges;
                                compatible = "mrvl,mmp-twsi";
                                reg = <0xd4011000 0x1000>;
                                interrupts = <7>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI0>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI0>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                mrvl,i2c-fast-mode;
                                compatible = "mrvl,mmp-twsi";
                                reg = <0xd4025000 0x1000>;
                                interrupts = <58>;
+                               clocks = <&soc_clocks MMP2_CLK_TWSI1>;
+                               resets = <&soc_clocks MMP2_CLK_TWSI1>;
                                status = "disabled";
                        };
 
                                interrupts = <1 0>;
                                interrupt-names = "rtc 1Hz", "rtc alarm";
                                interrupt-parent = <&intcmux5>;
+                               clocks = <&soc_clocks MMP2_CLK_RTC>;
+                               resets = <&soc_clocks MMP2_CLK_RTC>;
                                status = "disabled";
                        };
                };
+
+               soc_clocks: clocks{
+                       compatible = "marvell,mmp2-clock";
+                       reg = <0xd4050000 0x1000>,
+                             <0xd4282800 0x400>,
+                             <0xd4015000 0x1000>;
+                       reg-names = "mpmu", "apmu", "apbc";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
        };
 };
index e762facb3fa434473e2a1b53ca0a3c68f323c20a..0a988b3fb248ee46658bf1d65780f3f01b4582be 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "pxa168.dtsi"
+#include "pxa168.dtsi"
 
 / {
        model = "Marvell PXA168 Aspenite Development Board";
index 975dad21ac3890d4b81bb23a0d1bf2962a831e09..b899e25cbb1be973c60dc8a8d8c220c02cf3c039 100644 (file)
@@ -7,7 +7,8 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/marvell,pxa168.h>
 
 / {
        aliases {
@@ -59,6 +60,8 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4017000 0x1000>;
                                interrupts = <27>;
+                               clocks = <&soc_clocks PXA168_CLK_UART0>;
+                               resets = <&soc_clocks PXA168_CLK_UART0>;
                                status = "disabled";
                        };
 
@@ -66,6 +69,8 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4018000 0x1000>;
                                interrupts = <28>;
+                               clocks = <&soc_clocks PXA168_CLK_UART1>;
+                               resets = <&soc_clocks PXA168_CLK_UART1>;
                                status = "disabled";
                        };
 
@@ -73,6 +78,8 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4026000 0x1000>;
                                interrupts = <29>;
+                               clocks = <&soc_clocks PXA168_CLK_UART2>;
+                               resets = <&soc_clocks PXA168_CLK_UART2>;
                                status = "disabled";
                        };
 
@@ -84,6 +91,8 @@
                                gpio-controller;
                                #gpio-cells = <2>;
                                interrupts = <49>;
+                               clocks = <&soc_clocks PXA168_CLK_GPIO>;
+                               resets = <&soc_clocks PXA168_CLK_GPIO>;
                                interrupt-names = "gpio_mux";
                                interrupt-controller;
                                #interrupt-cells = <1>;
                                compatible = "mrvl,mmp-twsi";
                                reg = <0xd4011000 0x1000>;
                                interrupts = <7>;
+                               clocks = <&soc_clocks PXA168_CLK_TWSI0>;
+                               resets = <&soc_clocks PXA168_CLK_TWSI0>;
                                mrvl,i2c-fast-mode;
                                status = "disabled";
                        };
                                compatible = "mrvl,mmp-twsi";
                                reg = <0xd4025000 0x1000>;
                                interrupts = <58>;
+                               clocks = <&soc_clocks PXA168_CLK_TWSI1>;
+                               resets = <&soc_clocks PXA168_CLK_TWSI1>;
                                status = "disabled";
                        };
 
                                reg = <0xd4010000 0x1000>;
                                interrupts = <5 6>;
                                interrupt-names = "rtc 1Hz", "rtc alarm";
+                               clocks = <&soc_clocks PXA168_CLK_RTC>;
+                               resets = <&soc_clocks PXA168_CLK_RTC>;
                                status = "disabled";
                        };
                };
+
+               soc_clocks: clocks{
+                       compatible = "marvell,pxa168-clock";
+                       reg = <0xd4050000 0x1000>,
+                             <0xd4282800 0x400>,
+                             <0xd4015000 0x1000>;
+                       reg-names = "mpmu", "apmu", "apbc";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
        };
 };
index 595492aa505372047aab605aff58b043f16896f6..c82f2810ec73c2274b9c9f4a996cf5a31e530379 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 /dts-v1/;
-/include/ "pxa910.dtsi"
+#include "pxa910.dtsi"
 
 / {
        model = "Marvell PXA910 DKB Development Board";
index 0247c622f580728f77f31dbb36d555d310f524d0..0868f6729be1eaf60fc6df14887f449e92f750c6 100644 (file)
@@ -7,7 +7,8 @@
  *  publishhed by the Free Software Foundation.
  */
 
-/include/ "skeleton.dtsi"
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/marvell,pxa910.h>
 
 / {
        aliases {
@@ -71,6 +72,8 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4017000 0x1000>;
                                interrupts = <27>;
+                               clocks = <&soc_clocks PXA910_CLK_UART0>;
+                               resets = <&soc_clocks PXA910_CLK_UART0>;
                                status = "disabled";
                        };
 
@@ -78,6 +81,8 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4018000 0x1000>;
                                interrupts = <28>;
+                               clocks = <&soc_clocks PXA910_CLK_UART1>;
+                               resets = <&soc_clocks PXA910_CLK_UART1>;
                                status = "disabled";
                        };
 
@@ -85,6 +90,8 @@
                                compatible = "mrvl,mmp-uart";
                                reg = <0xd4036000 0x1000>;
                                interrupts = <59>;
+                               clocks = <&soc_clocks PXA910_CLK_UART2>;
+                               resets = <&soc_clocks PXA910_CLK_UART2>;
                                status = "disabled";
                        };
 
                                #gpio-cells = <2>;
                                interrupts = <49>;
                                interrupt-names = "gpio_mux";
+                               clocks = <&soc_clocks PXA910_CLK_GPIO>;
+                               resets = <&soc_clocks PXA910_CLK_GPIO>;
                                interrupt-controller;
                                #interrupt-cells = <1>;
                                ranges;
                                #size-cells = <0>;
                                reg = <0xd4011000 0x1000>;
                                interrupts = <7>;
+                               clocks = <&soc_clocks PXA910_CLK_TWSI0>;
+                               resets = <&soc_clocks PXA910_CLK_TWSI0>;
                                mrvl,i2c-fast-mode;
                                status = "disabled";
                        };
                                #size-cells = <0>;
                                reg = <0xd4037000 0x1000>;
                                interrupts = <54>;
+                               clocks = <&soc_clocks PXA910_CLK_TWSI1>;
+                               resets = <&soc_clocks PXA910_CLK_TWSI1>;
                                status = "disabled";
                        };
 
                                reg = <0xd4010000 0x1000>;
                                interrupts = <5 6>;
                                interrupt-names = "rtc 1Hz", "rtc alarm";
+                               clocks = <&soc_clocks PXA910_CLK_RTC>;
+                               resets = <&soc_clocks PXA910_CLK_RTC>;
                                status = "disabled";
                        };
                };
+
+               soc_clocks: clocks{
+                       compatible = "marvell,pxa910-clock";
+                       reg = <0xd4050000 0x1000>,
+                             <0xd4282800 0x400>,
+                             <0xd4015000 0x1000>,
+                             <0xd403b000 0x1000>;
+                       reg-names = "mpmu", "apmu", "apbc", "apbcp";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
        };
 };
index ebdba87b96711a4a2a3970bcd824253ea9273327..fdbfadf00c84b492bb032f3ca47cf94f78f9c0d7 100644 (file)
@@ -86,11 +86,12 @@ config MACH_GPLUGD
 
 config MACH_MMP_DT
        bool "Support MMP (ARMv5) platforms from device tree"
-       select CPU_PXA168
-       select CPU_PXA910
        select USE_OF
        select PINCTRL
        select PINCTRL_SINGLE
+       select COMMON_CLK
+       select ARCH_HAS_RESET_CONTROLLER
+       select CPU_MOHAWK
        help
          Include support for Marvell MMP2 based platforms using
          the device tree. Needn't select any other machine while
@@ -99,10 +100,12 @@ config MACH_MMP_DT
 config MACH_MMP2_DT
        bool "Support MMP2 (ARMv7) platforms from device tree"
        depends on !CPU_MOHAWK
-       select CPU_MMP2
        select USE_OF
        select PINCTRL
        select PINCTRL_SINGLE
+       select COMMON_CLK
+       select ARCH_HAS_RESET_CONTROLLER
+       select CPU_PJ4
        help
          Include support for Marvell MMP2 based platforms using
          the device tree.
@@ -111,21 +114,18 @@ endmenu
 
 config CPU_PXA168
        bool
-       select COMMON_CLK
        select CPU_MOHAWK
        help
          Select code specific to PXA168
 
 config CPU_PXA910
        bool
-       select COMMON_CLK
        select CPU_MOHAWK
        help
          Select code specific to PXA910
 
 config CPU_MMP2
        bool
-       select COMMON_CLK
        select CPU_PJ4
        help
          Select code specific to MMP2. MMP2 is ARMv7 compatible.
index cca529ceecb758101f0120faa547c2790b004e80..b2296c9309b87659566992548a2a177888f1cf03 100644 (file)
 
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
+#include <linux/clk-provider.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
+#include <asm/hardware/cache-tauros2.h>
 
 #include "common.h"
 
 extern void __init mmp_dt_init_timer(void);
 
-static const struct of_dev_auxdata pxa168_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4026000, "pxa2xx-uart.2", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
-       OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp-gpio", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
-       {}
+static const char *pxa168_dt_board_compat[] __initdata = {
+       "mrvl,pxa168-aspenite",
+       NULL,
 };
 
-static const struct of_dev_auxdata pxa910_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.0", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.1", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4036000, "pxa2xx-uart.2", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4037000, "pxa2xx-i2c.1", NULL),
-       OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp-gpio", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
-       {}
+static const char *pxa910_dt_board_compat[] __initdata = {
+       "mrvl,pxa910-dkb",
+       NULL,
 };
 
-static void __init pxa168_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table,
-                            pxa168_auxdata_lookup, NULL);
-}
-
-static void __init pxa910_dt_init(void)
+static void __init mmp_init_time(void)
 {
-       of_platform_populate(NULL, of_default_bus_match_table,
-                            pxa910_auxdata_lookup, NULL);
+#ifdef CONFIG_CACHE_TAUROS2
+       tauros2_init(0);
+#endif
+       mmp_dt_init_timer();
+       of_clk_init(NULL);
 }
 
-static const char *mmp_dt_board_compat[] __initdata = {
-       "mrvl,pxa168-aspenite",
-       "mrvl,pxa910-dkb",
-       NULL,
-};
-
 DT_MACHINE_START(PXA168_DT, "Marvell PXA168 (Device Tree Support)")
        .map_io         = mmp_map_io,
-       .init_time      = mmp_dt_init_timer,
-       .init_machine   = pxa168_dt_init,
-       .dt_compat      = mmp_dt_board_compat,
+       .init_time      = mmp_init_time,
+       .dt_compat      = pxa168_dt_board_compat,
 MACHINE_END
 
 DT_MACHINE_START(PXA910_DT, "Marvell PXA910 (Device Tree Support)")
        .map_io         = mmp_map_io,
-       .init_time      = mmp_dt_init_timer,
-       .init_machine   = pxa910_dt_init,
-       .dt_compat      = mmp_dt_board_compat,
+       .init_time      = mmp_init_time,
+       .dt_compat      = pxa910_dt_board_compat,
 MACHINE_END
index 023cb453f157ff621110d6c17b6f0cc185b8d8ba..998c0f533abc842659b7f4bcb0d05e2a873a9b58 100644 (file)
 #include <linux/io.h>
 #include <linux/irqchip.h>
 #include <linux/of_platform.h>
+#include <linux/clk-provider.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
+#include <asm/hardware/cache-tauros2.h>
 
 #include "common.h"
 
 extern void __init mmp_dt_init_timer(void);
 
-static const struct of_dev_auxdata mmp2_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4030000, "pxa2xx-uart.0", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4017000, "pxa2xx-uart.1", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4018000, "pxa2xx-uart.2", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-uart", 0xd4016000, "pxa2xx-uart.3", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4011000, "pxa2xx-i2c.0", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-twsi", 0xd4025000, "pxa2xx-i2c.1", NULL),
-       OF_DEV_AUXDATA("marvell,mmp-gpio", 0xd4019000, "mmp2-gpio", NULL),
-       OF_DEV_AUXDATA("mrvl,mmp-rtc", 0xd4010000, "sa1100-rtc", NULL),
-       {}
-};
-
-static void __init mmp2_dt_init(void)
+static void __init mmp_init_time(void)
 {
-       of_platform_populate(NULL, of_default_bus_match_table,
-                            mmp2_auxdata_lookup, NULL);
+#ifdef CONFIG_CACHE_TAUROS2
+       tauros2_init(0);
+#endif
+       mmp_dt_init_timer();
+       of_clk_init(NULL);
 }
 
 static const char *mmp2_dt_board_compat[] __initdata = {
@@ -44,7 +37,6 @@ static const char *mmp2_dt_board_compat[] __initdata = {
 
 DT_MACHINE_START(MMP2_DT, "Marvell MMP2 (Device Tree Support)")
        .map_io         = mmp_map_io,
-       .init_time      = mmp_dt_init_timer,
-       .init_machine   = mmp2_dt_init,
+       .init_time      = mmp_init_time,
        .dt_compat      = mmp2_dt_board_compat,
 MACHINE_END
index 4896ae9e23da0c23ed52872cf1992f95609e1b59..5307225684eb351c49463b1332fdf9eb6e4f9755 100644 (file)
@@ -1614,7 +1614,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
 
        if (clk->num_parents == 1) {
                if (IS_ERR_OR_NULL(clk->parent))
-                       ret = clk->parent = __clk_lookup(clk->parent_names[0]);
+                       clk->parent = __clk_lookup(clk->parent_names[0]);
                ret = clk->parent;
                goto out;
        }
index 392d78044ce3748903ad1614ffc4589a7cdb168c..3caaf7cc169c684559973f105317dea76bbd1d54 100644 (file)
@@ -2,7 +2,12 @@
 # Makefile for mmp specific clk
 #
 
-obj-y += clk-apbc.o clk-apmu.o clk-frac.o
+obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
+
+obj-$(CONFIG_RESET_CONTROLLER) += reset.o
+
+obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
+obj-$(CONFIG_MACH_MMP2_DT) += clk-of-mmp2.o
 
 obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
 obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
index 23a56f561812decc149624fe72b803a7bbb726ab..eeba52c2def6df56d25bf8d641d7fa38e261db6d 100644 (file)
  * numerator/denominator = Fin / (Fout * factor)
  */
 
-#define to_clk_factor(hw) container_of(hw, struct clk_factor, hw)
-struct clk_factor {
-       struct clk_hw           hw;
-       void __iomem            *base;
-       struct clk_factor_masks *masks;
-       struct clk_factor_tbl   *ftbl;
-       unsigned int            ftbl_cnt;
-};
+#define to_clk_factor(hw) container_of(hw, struct mmp_clk_factor, hw)
 
 static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
                unsigned long *prate)
 {
-       struct clk_factor *factor = to_clk_factor(hw);
+       struct mmp_clk_factor *factor = to_clk_factor(hw);
        unsigned long rate = 0, prev_rate;
        int i;
 
@@ -58,8 +51,8 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
 static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
-       struct clk_factor *factor = to_clk_factor(hw);
-       struct clk_factor_masks *masks = factor->masks;
+       struct mmp_clk_factor *factor = to_clk_factor(hw);
+       struct mmp_clk_factor_masks *masks = factor->masks;
        unsigned int val, num, den;
 
        val = readl_relaxed(factor->base);
@@ -81,11 +74,12 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
 static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
                                unsigned long prate)
 {
-       struct clk_factor *factor = to_clk_factor(hw);
-       struct clk_factor_masks *masks = factor->masks;
+       struct mmp_clk_factor *factor = to_clk_factor(hw);
+       struct mmp_clk_factor_masks *masks = factor->masks;
        int i;
        unsigned long val;
        unsigned long prev_rate, rate = 0;
+       unsigned long flags = 0;
 
        for (i = 0; i < factor->ftbl_cnt; i++) {
                prev_rate = rate;
@@ -97,6 +91,9 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
        if (i > 0)
                i--;
 
+       if (factor->lock)
+               spin_lock_irqsave(factor->lock, flags);
+
        val = readl_relaxed(factor->base);
 
        val &= ~(masks->num_mask << masks->num_shift);
@@ -107,21 +104,65 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
 
        writel_relaxed(val, factor->base);
 
+       if (factor->lock)
+               spin_unlock_irqrestore(factor->lock, flags);
+
        return 0;
 }
 
+void clk_factor_init(struct clk_hw *hw)
+{
+       struct mmp_clk_factor *factor = to_clk_factor(hw);
+       struct mmp_clk_factor_masks *masks = factor->masks;
+       u32 val, num, den;
+       int i;
+       unsigned long flags = 0;
+
+       if (factor->lock)
+               spin_lock_irqsave(factor->lock, flags);
+
+       val = readl(factor->base);
+
+       /* calculate numerator */
+       num = (val >> masks->num_shift) & masks->num_mask;
+
+       /* calculate denominator */
+       den = (val >> masks->den_shift) & masks->den_mask;
+
+       for (i = 0; i < factor->ftbl_cnt; i++)
+               if (den == factor->ftbl[i].den && num == factor->ftbl[i].num)
+                       break;
+
+       if (i >= factor->ftbl_cnt) {
+               val &= ~(masks->num_mask << masks->num_shift);
+               val |= (factor->ftbl[0].num & masks->num_mask) <<
+                       masks->num_shift;
+
+               val &= ~(masks->den_mask << masks->den_shift);
+               val |= (factor->ftbl[0].den & masks->den_mask) <<
+                       masks->den_shift;
+
+               writel(val, factor->base);
+       }
+
+       if (factor->lock)
+               spin_unlock_irqrestore(factor->lock, flags);
+}
+
 static struct clk_ops clk_factor_ops = {
        .recalc_rate = clk_factor_recalc_rate,
        .round_rate = clk_factor_round_rate,
        .set_rate = clk_factor_set_rate,
+       .init = clk_factor_init,
 };
 
 struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
                unsigned long flags, void __iomem *base,
-               struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl,
-               unsigned int ftbl_cnt)
+               struct mmp_clk_factor_masks *masks,
+               struct mmp_clk_factor_tbl *ftbl,
+               unsigned int ftbl_cnt, spinlock_t *lock)
 {
-       struct clk_factor *factor;
+       struct mmp_clk_factor *factor;
        struct clk_init_data init;
        struct clk *clk;
 
@@ -142,6 +183,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,
        factor->ftbl = ftbl;
        factor->ftbl_cnt = ftbl_cnt;
        factor->hw.init = &init;
+       factor->lock = lock;
 
        init.name = name;
        init.ops = &clk_factor_ops;
diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c
new file mode 100644 (file)
index 0000000..adbd9d6
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * mmp gate clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie <chao.xie@marvell.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/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include "clk.h"
+
+/*
+ * Some clocks will have mutiple bits to enable the clocks, and
+ * the bits to disable the clock is not same as enabling bits.
+ */
+
+#define to_clk_mmp_gate(hw)    container_of(hw, struct mmp_clk_gate, hw)
+
+static int mmp_clk_gate_enable(struct clk_hw *hw)
+{
+       struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+       struct clk *clk = hw->clk;
+       unsigned long flags = 0;
+       unsigned long rate;
+       u32 tmp;
+
+       if (gate->lock)
+               spin_lock_irqsave(gate->lock, flags);
+
+       tmp = readl(gate->reg);
+       tmp &= ~gate->mask;
+       tmp |= gate->val_enable;
+       writel(tmp, gate->reg);
+
+       if (gate->lock)
+               spin_unlock_irqrestore(gate->lock, flags);
+
+       if (gate->flags & MMP_CLK_GATE_NEED_DELAY) {
+               rate = __clk_get_rate(clk);
+               /* Need delay 2 cycles. */
+               udelay(2000000/rate);
+       }
+
+       return 0;
+}
+
+static void mmp_clk_gate_disable(struct clk_hw *hw)
+{
+       struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+       unsigned long flags = 0;
+       u32 tmp;
+
+       if (gate->lock)
+               spin_lock_irqsave(gate->lock, flags);
+
+       tmp = readl(gate->reg);
+       tmp &= ~gate->mask;
+       tmp |= gate->val_disable;
+       writel(tmp, gate->reg);
+
+       if (gate->lock)
+               spin_unlock_irqrestore(gate->lock, flags);
+}
+
+static int mmp_clk_gate_is_enabled(struct clk_hw *hw)
+{
+       struct mmp_clk_gate *gate = to_clk_mmp_gate(hw);
+       unsigned long flags = 0;
+       u32 tmp;
+
+       if (gate->lock)
+               spin_lock_irqsave(gate->lock, flags);
+
+       tmp = readl(gate->reg);
+
+       if (gate->lock)
+               spin_unlock_irqrestore(gate->lock, flags);
+
+       return (tmp & gate->mask) == gate->val_enable;
+}
+
+const struct clk_ops mmp_clk_gate_ops = {
+       .enable = mmp_clk_gate_enable,
+       .disable = mmp_clk_gate_disable,
+       .is_enabled = mmp_clk_gate_is_enabled,
+};
+
+struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *reg, u32 mask, u32 val_enable, u32 val_disable,
+               unsigned int gate_flags, spinlock_t *lock)
+{
+       struct mmp_clk_gate *gate;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       /* allocate the gate */
+       gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+       if (!gate) {
+               pr_err("%s:%s could not allocate gate clk\n", __func__, name);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = name;
+       init.ops = &mmp_clk_gate_ops;
+       init.flags = flags | CLK_IS_BASIC;
+       init.parent_names = (parent_name ? &parent_name : NULL);
+       init.num_parents = (parent_name ? 1 : 0);
+
+       /* struct clk_gate assignments */
+       gate->reg = reg;
+       gate->mask = mask;
+       gate->val_enable = val_enable;
+       gate->val_disable = val_disable;
+       gate->flags = gate_flags;
+       gate->lock = lock;
+       gate->hw.init = &init;
+
+       clk = clk_register(dev, &gate->hw);
+
+       if (IS_ERR(clk))
+               kfree(gate);
+
+       return clk;
+}
diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c
new file mode 100644 (file)
index 0000000..b79742c
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ * mmp mix(div and mux) clock operation source file
+ *
+ * Copyright (C) 2014 Marvell
+ * Chao Xie <chao.xie@marvell.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/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include "clk.h"
+
+/*
+ * The mix clock is a clock combined mux and div type clock.
+ * Because the div field and mux field need to be set at same
+ * time, we can not divide it into 2 types of clock
+ */
+
+#define to_clk_mix(hw) container_of(hw, struct mmp_clk_mix, hw)
+
+static unsigned int _get_maxdiv(struct mmp_clk_mix *mix)
+{
+       unsigned int div_mask = (1 << mix->reg_info.width_div) - 1;
+       unsigned int maxdiv = 0;
+       struct clk_div_table *clkt;
+
+       if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+               return div_mask;
+       if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+               return 1 << div_mask;
+       if (mix->div_table) {
+               for (clkt = mix->div_table; clkt->div; clkt++)
+                       if (clkt->div > maxdiv)
+                               maxdiv = clkt->div;
+               return maxdiv;
+       }
+       return div_mask + 1;
+}
+
+static unsigned int _get_div(struct mmp_clk_mix *mix, unsigned int val)
+{
+       struct clk_div_table *clkt;
+
+       if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+               return val;
+       if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+               return 1 << val;
+       if (mix->div_table) {
+               for (clkt = mix->div_table; clkt->div; clkt++)
+                       if (clkt->val == val)
+                               return clkt->div;
+               if (clkt->div == 0)
+                       return 0;
+       }
+       return val + 1;
+}
+
+static unsigned int _get_mux(struct mmp_clk_mix *mix, unsigned int val)
+{
+       int num_parents = __clk_get_num_parents(mix->hw.clk);
+       int i;
+
+       if (mix->mux_flags & CLK_MUX_INDEX_BIT)
+               return ffs(val) - 1;
+       if (mix->mux_flags & CLK_MUX_INDEX_ONE)
+               return val - 1;
+       if (mix->mux_table) {
+               for (i = 0; i < num_parents; i++)
+                       if (mix->mux_table[i] == val)
+                               return i;
+               if (i == num_parents)
+                       return 0;
+       }
+
+       return val;
+}
+static unsigned int _get_div_val(struct mmp_clk_mix *mix, unsigned int div)
+{
+       struct clk_div_table *clkt;
+
+       if (mix->div_flags & CLK_DIVIDER_ONE_BASED)
+               return div;
+       if (mix->div_flags & CLK_DIVIDER_POWER_OF_TWO)
+               return __ffs(div);
+       if (mix->div_table) {
+               for (clkt = mix->div_table; clkt->div; clkt++)
+                       if (clkt->div == div)
+                               return clkt->val;
+               if (clkt->div == 0)
+                       return 0;
+       }
+
+       return div - 1;
+}
+
+static unsigned int _get_mux_val(struct mmp_clk_mix *mix, unsigned int mux)
+{
+       if (mix->mux_table)
+               return mix->mux_table[mux];
+
+       return mux;
+}
+
+static void _filter_clk_table(struct mmp_clk_mix *mix,
+                               struct mmp_clk_mix_clk_table *table,
+                               unsigned int table_size)
+{
+       int i;
+       struct mmp_clk_mix_clk_table *item;
+       struct clk *parent, *clk;
+       unsigned long parent_rate;
+
+       clk = mix->hw.clk;
+
+       for (i = 0; i < table_size; i++) {
+               item = &table[i];
+               parent = clk_get_parent_by_index(clk, item->parent_index);
+               parent_rate = __clk_get_rate(parent);
+               if (parent_rate % item->rate) {
+                       item->valid = 0;
+               } else {
+                       item->divisor = parent_rate / item->rate;
+                       item->valid = 1;
+               }
+       }
+}
+
+static int _set_rate(struct mmp_clk_mix *mix, u32 mux_val, u32 div_val,
+                       unsigned int change_mux, unsigned int change_div)
+{
+       struct mmp_clk_mix_reg_info *ri = &mix->reg_info;
+       u8 width, shift;
+       u32 mux_div, fc_req;
+       int ret, timeout = 50;
+       unsigned long flags = 0;
+
+       if (!change_mux && !change_div)
+               return -EINVAL;
+
+       if (mix->lock)
+               spin_lock_irqsave(mix->lock, flags);
+
+       if (mix->type == MMP_CLK_MIX_TYPE_V1
+               || mix->type == MMP_CLK_MIX_TYPE_V2)
+               mux_div = readl(ri->reg_clk_ctrl);
+       else
+               mux_div = readl(ri->reg_clk_sel);
+
+       if (change_div) {
+               width = ri->width_div;
+               shift = ri->shift_div;
+               mux_div &= ~MMP_CLK_BITS_MASK(width, shift);
+               mux_div |= MMP_CLK_BITS_SET_VAL(div_val, width, shift);
+       }
+
+       if (change_mux) {
+               width = ri->width_mux;
+               shift = ri->shift_mux;
+               mux_div &= ~MMP_CLK_BITS_MASK(width, shift);
+               mux_div |= MMP_CLK_BITS_SET_VAL(mux_val, width, shift);
+       }
+
+       if (mix->type == MMP_CLK_MIX_TYPE_V1) {
+               writel(mux_div, ri->reg_clk_ctrl);
+       } else if (mix->type == MMP_CLK_MIX_TYPE_V2) {
+               mux_div |= (1 << ri->bit_fc);
+               writel(mux_div, ri->reg_clk_ctrl);
+
+               do {
+                       fc_req = readl(ri->reg_clk_ctrl);
+                       timeout--;
+                       if (!(fc_req & (1 << ri->bit_fc)))
+                               break;
+               } while (timeout);
+
+               if (timeout == 0) {
+                       pr_err("%s:%s cannot do frequency change\n",
+                               __func__, __clk_get_name(mix->hw.clk));
+                       ret = -EBUSY;
+                       goto error;
+               }
+       } else {
+               fc_req = readl(ri->reg_clk_ctrl);
+               fc_req |= 1 << ri->bit_fc;
+               writel(fc_req, ri->reg_clk_ctrl);
+               writel(mux_div, ri->reg_clk_sel);
+               fc_req &= ~(1 << ri->bit_fc);
+       }
+
+       ret = 0;
+error:
+       if (mix->lock)
+               spin_unlock_irqrestore(mix->lock, flags);
+
+       return ret;
+}
+
+static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate,
+                                       unsigned long *best_parent_rate,
+                                       struct clk **best_parent_clk)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+       struct mmp_clk_mix_clk_table *item;
+       struct clk *parent, *parent_best, *mix_clk;
+       unsigned long parent_rate, mix_rate, mix_rate_best, parent_rate_best;
+       unsigned long gap, gap_best;
+       u32 div_val_max;
+       unsigned int div;
+       int i, j;
+
+       mix_clk = hw->clk;
+
+       parent = NULL;
+       mix_rate_best = 0;
+       parent_rate_best = 0;
+       gap_best = rate;
+       parent_best = NULL;
+
+       if (mix->table) {
+               for (i = 0; i < mix->table_size; i++) {
+                       item = &mix->table[i];
+                       if (item->valid == 0)
+                               continue;
+                       parent = clk_get_parent_by_index(mix_clk,
+                                                       item->parent_index);
+                       parent_rate = __clk_get_rate(parent);
+                       mix_rate = parent_rate / item->divisor;
+                       gap = abs(mix_rate - rate);
+                       if (parent_best == NULL || gap < gap_best) {
+                               parent_best = parent;
+                               parent_rate_best = parent_rate;
+                               mix_rate_best = mix_rate;
+                               gap_best = gap;
+                               if (gap_best == 0)
+                                       goto found;
+                       }
+               }
+       } else {
+               for (i = 0; i < __clk_get_num_parents(mix_clk); i++) {
+                       parent = clk_get_parent_by_index(mix_clk, i);
+                       parent_rate = __clk_get_rate(parent);
+                       div_val_max = _get_maxdiv(mix);
+                       for (j = 0; j < div_val_max; j++) {
+                               div = _get_div(mix, j);
+                               mix_rate = parent_rate / div;
+                               gap = abs(mix_rate - rate);
+                               if (parent_best == NULL || gap < gap_best) {
+                                       parent_best = parent;
+                                       parent_rate_best = parent_rate;
+                                       mix_rate_best = mix_rate;
+                                       gap_best = gap;
+                                       if (gap_best == 0)
+                                               goto found;
+                               }
+                       }
+               }
+       }
+
+found:
+       *best_parent_rate = parent_rate_best;
+       *best_parent_clk = parent_best;
+
+       return mix_rate_best;
+}
+
+static int mmp_clk_mix_set_rate_and_parent(struct clk_hw *hw,
+                                               unsigned long rate,
+                                               unsigned long parent_rate,
+                                               u8 index)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+       unsigned int div;
+       u32 div_val, mux_val;
+
+       div = parent_rate / rate;
+       div_val = _get_div_val(mix, div);
+       mux_val = _get_mux_val(mix, index);
+
+       return _set_rate(mix, mux_val, div_val, 1, 1);
+}
+
+static u8 mmp_clk_mix_get_parent(struct clk_hw *hw)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+       struct mmp_clk_mix_reg_info *ri = &mix->reg_info;
+       unsigned long flags = 0;
+       u32 mux_div = 0;
+       u8 width, shift;
+       u32 mux_val;
+
+       if (mix->lock)
+               spin_lock_irqsave(mix->lock, flags);
+
+       if (mix->type == MMP_CLK_MIX_TYPE_V1
+               || mix->type == MMP_CLK_MIX_TYPE_V2)
+               mux_div = readl(ri->reg_clk_ctrl);
+       else
+               mux_div = readl(ri->reg_clk_sel);
+
+       if (mix->lock)
+               spin_unlock_irqrestore(mix->lock, flags);
+
+       width = mix->reg_info.width_mux;
+       shift = mix->reg_info.shift_mux;
+
+       mux_val = MMP_CLK_BITS_GET_VAL(mux_div, width, shift);
+
+       return _get_mux(mix, mux_val);
+}
+
+static unsigned long mmp_clk_mix_recalc_rate(struct clk_hw *hw,
+                                       unsigned long parent_rate)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+       struct mmp_clk_mix_reg_info *ri = &mix->reg_info;
+       unsigned long flags = 0;
+       u32 mux_div = 0;
+       u8 width, shift;
+       unsigned int div;
+
+       if (mix->lock)
+               spin_lock_irqsave(mix->lock, flags);
+
+       if (mix->type == MMP_CLK_MIX_TYPE_V1
+               || mix->type == MMP_CLK_MIX_TYPE_V2)
+               mux_div = readl(ri->reg_clk_ctrl);
+       else
+               mux_div = readl(ri->reg_clk_sel);
+
+       if (mix->lock)
+               spin_unlock_irqrestore(mix->lock, flags);
+
+       width = mix->reg_info.width_div;
+       shift = mix->reg_info.shift_div;
+
+       div = _get_div(mix, MMP_CLK_BITS_GET_VAL(mux_div, width, shift));
+
+       return parent_rate / div;
+}
+
+static int mmp_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+       struct mmp_clk_mix_clk_table *item;
+       int i;
+       u32 div_val, mux_val;
+
+       if (mix->table) {
+               for (i = 0; i < mix->table_size; i++) {
+                       item = &mix->table[i];
+                       if (item->valid == 0)
+                               continue;
+                       if (item->parent_index == index)
+                               break;
+               }
+               if (i < mix->table_size) {
+                       div_val = _get_div_val(mix, item->divisor);
+                       mux_val = _get_mux_val(mix, item->parent_index);
+               } else
+                       return -EINVAL;
+       } else {
+               mux_val = _get_mux_val(mix, index);
+               div_val = 0;
+       }
+
+       return _set_rate(mix, mux_val, div_val, 1, div_val ? 1 : 0);
+}
+
+static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long best_parent_rate)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+       struct mmp_clk_mix_clk_table *item;
+       unsigned long parent_rate;
+       unsigned int best_divisor;
+       struct clk *mix_clk, *parent;
+       int i;
+
+       best_divisor = best_parent_rate / rate;
+
+       mix_clk = hw->clk;
+       if (mix->table) {
+               for (i = 0; i < mix->table_size; i++) {
+                       item = &mix->table[i];
+                       if (item->valid == 0)
+                               continue;
+                       parent = clk_get_parent_by_index(mix_clk,
+                                                       item->parent_index);
+                       parent_rate = __clk_get_rate(parent);
+                       if (parent_rate == best_parent_rate
+                               && item->divisor == best_divisor)
+                               break;
+               }
+               if (i < mix->table_size)
+                       return _set_rate(mix,
+                                       _get_mux_val(mix, item->parent_index),
+                                       _get_div_val(mix, item->divisor),
+                                       1, 1);
+               else
+                       return -EINVAL;
+       } else {
+               for (i = 0; i < __clk_get_num_parents(mix_clk); i++) {
+                       parent = clk_get_parent_by_index(mix_clk, i);
+                       parent_rate = __clk_get_rate(parent);
+                       if (parent_rate == best_parent_rate)
+                               break;
+               }
+               if (i < __clk_get_num_parents(mix_clk))
+                       return _set_rate(mix, _get_mux_val(mix, i),
+                                       _get_div_val(mix, best_divisor), 1, 1);
+               else
+                       return -EINVAL;
+       }
+}
+
+static void mmp_clk_mix_init(struct clk_hw *hw)
+{
+       struct mmp_clk_mix *mix = to_clk_mix(hw);
+
+       if (mix->table)
+               _filter_clk_table(mix, mix->table, mix->table_size);
+}
+
+const struct clk_ops mmp_clk_mix_ops = {
+       .determine_rate = mmp_clk_mix_determine_rate,
+       .set_rate_and_parent = mmp_clk_mix_set_rate_and_parent,
+       .set_rate = mmp_clk_set_rate,
+       .set_parent = mmp_clk_set_parent,
+       .get_parent = mmp_clk_mix_get_parent,
+       .recalc_rate = mmp_clk_mix_recalc_rate,
+       .init = mmp_clk_mix_init,
+};
+
+struct clk *mmp_clk_register_mix(struct device *dev,
+                                       const char *name,
+                                       const char **parent_names,
+                                       u8 num_parents,
+                                       unsigned long flags,
+                                       struct mmp_clk_mix_config *config,
+                                       spinlock_t *lock)
+{
+       struct mmp_clk_mix *mix;
+       struct clk *clk;
+       struct clk_init_data init;
+       size_t table_bytes;
+
+       mix = kzalloc(sizeof(*mix), GFP_KERNEL);
+       if (!mix) {
+               pr_err("%s:%s: could not allocate mmp mix clk\n",
+                       __func__, name);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = name;
+       init.flags = flags | CLK_GET_RATE_NOCACHE;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+       init.ops = &mmp_clk_mix_ops;
+
+       memcpy(&mix->reg_info, &config->reg_info, sizeof(config->reg_info));
+       if (config->table) {
+               table_bytes = sizeof(*config->table) * config->table_size;
+               mix->table = kzalloc(table_bytes, GFP_KERNEL);
+               if (!mix->table) {
+                       pr_err("%s:%s: could not allocate mmp mix table\n",
+                               __func__, name);
+                       kfree(mix);
+                       return ERR_PTR(-ENOMEM);
+               }
+               memcpy(mix->table, config->table, table_bytes);
+               mix->table_size = config->table_size;
+       }
+
+       if (config->mux_table) {
+               table_bytes = sizeof(u32) * num_parents;
+               mix->mux_table = kzalloc(table_bytes, GFP_KERNEL);
+               if (!mix->mux_table) {
+                       pr_err("%s:%s: could not allocate mmp mix mux-table\n",
+                               __func__, name);
+                       kfree(mix->table);
+                       kfree(mix);
+                       return ERR_PTR(-ENOMEM);
+               }
+               memcpy(mix->mux_table, config->mux_table, table_bytes);
+       }
+
+       mix->div_flags = config->div_flags;
+       mix->mux_flags = config->mux_flags;
+       mix->lock = lock;
+       mix->hw.init = &init;
+
+       if (config->reg_info.bit_fc >= 32)
+               mix->type = MMP_CLK_MIX_TYPE_V1;
+       else if (config->reg_info.reg_clk_sel)
+               mix->type = MMP_CLK_MIX_TYPE_V3;
+       else
+               mix->type = MMP_CLK_MIX_TYPE_V2;
+       clk = clk_register(dev, &mix->hw);
+
+       if (IS_ERR(clk)) {
+               kfree(mix->mux_table);
+               kfree(mix->table);
+               kfree(mix);
+       }
+
+       return clk;
+}
index b2721cae257adcca4a106cee4e9a9e443bf5d808..5c90a4230fa3d3f2718c7ed6452c32c51df70b24 100644 (file)
@@ -54,7 +54,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
        .factor = 2,
        .num_mask = 0x1fff,
        .den_mask = 0x1fff,
@@ -62,7 +62,7 @@ static struct clk_factor_masks uart_factor_masks = {
        .den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
        {.num = 14634, .den = 2165},    /*14.745MHZ */
        {.num = 3521, .den = 689},      /*19.23MHZ */
        {.num = 9679, .den = 5728},     /*58.9824MHZ */
@@ -191,7 +191,7 @@ void __init mmp2_clk_init(void)
        clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
                                mpmu_base + MPMU_UART_PLL,
                                &uart_factor_masks, uart_factor_tbl,
-                               ARRAY_SIZE(uart_factor_tbl));
+                               ARRAY_SIZE(uart_factor_tbl), &clk_lock);
        clk_set_rate(clk, 14745600);
        clk_register_clkdev(clk, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
new file mode 100644 (file)
index 0000000..2cbc2b4
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * mmp2 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie <xiechao.mail@gmail.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/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/marvell,mmp2.h>
+
+#include "clk.h"
+#include "reset.h"
+
+#define APBC_RTC       0x0
+#define APBC_TWSI0     0x4
+#define APBC_TWSI1     0x8
+#define APBC_TWSI2     0xc
+#define APBC_TWSI3     0x10
+#define APBC_TWSI4     0x7c
+#define APBC_TWSI5     0x80
+#define APBC_KPC       0x18
+#define APBC_UART0     0x2c
+#define APBC_UART1     0x30
+#define APBC_UART2     0x34
+#define APBC_UART3     0x88
+#define APBC_GPIO      0x38
+#define APBC_PWM0      0x3c
+#define APBC_PWM1      0x40
+#define APBC_PWM2      0x44
+#define APBC_PWM3      0x48
+#define APBC_SSP0      0x50
+#define APBC_SSP1      0x54
+#define APBC_SSP2      0x58
+#define APBC_SSP3      0x5c
+#define APMU_SDH0      0x54
+#define APMU_SDH1      0x58
+#define APMU_SDH2      0xe8
+#define APMU_SDH3      0xec
+#define APMU_USB       0x5c
+#define APMU_DISP0     0x4c
+#define APMU_DISP1     0x110
+#define APMU_CCIC0     0x50
+#define APMU_CCIC1     0xf4
+#define MPMU_UART_PLL  0x14
+
+struct mmp2_clk_unit {
+       struct mmp_clk_unit unit;
+       void __iomem *mpmu_base;
+       void __iomem *apmu_base;
+       void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+       {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+       {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
+       {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 800000000},
+       {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 960000000},
+       {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+       {MMP2_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+       {MMP2_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+       {MMP2_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+       {MMP2_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+       {MMP2_CLK_PLL1_20, "pll1_20", "pll1_4", 1, 5, 0},
+       {MMP2_CLK_PLL1_3, "pll1_3", "pll1", 1, 3, 0},
+       {MMP2_CLK_PLL1_6, "pll1_6", "pll1_3", 1, 2, 0},
+       {MMP2_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+       {MMP2_CLK_PLL2_2, "pll2_2", "pll2", 1, 2, 0},
+       {MMP2_CLK_PLL2_4, "pll2_4", "pll2_2", 1, 2, 0},
+       {MMP2_CLK_PLL2_8, "pll2_8", "pll2_4", 1, 2, 0},
+       {MMP2_CLK_PLL2_16, "pll2_16", "pll2_8", 1, 2, 0},
+       {MMP2_CLK_PLL2_3, "pll2_3", "pll2", 1, 3, 0},
+       {MMP2_CLK_PLL2_6, "pll2_6", "pll2_3", 1, 2, 0},
+       {MMP2_CLK_PLL2_12, "pll2_12", "pll2_6", 1, 2, 0},
+       {MMP2_CLK_VCTCXO_2, "vctcxo_2", "vctcxo", 1, 2, 0},
+       {MMP2_CLK_VCTCXO_4, "vctcxo_4", "vctcxo_2", 1, 2, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+       .factor = 2,
+       .num_mask = 0x1fff,
+       .den_mask = 0x1fff,
+       .num_shift = 16,
+       .den_shift = 0,
+};
+
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
+       {.num = 14634, .den = 2165},    /*14.745MHZ */
+       {.num = 3521, .den = 689},      /*19.23MHZ */
+       {.num = 9679, .den = 5728},     /*58.9824MHZ */
+       {.num = 15850, .den = 9451},    /*59.429MHZ */
+};
+
+static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
+{
+       struct clk *clk;
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
+                                       ARRAY_SIZE(fixed_rate_clks));
+
+       mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
+                                       ARRAY_SIZE(fixed_factor_clks));
+
+       clk = mmp_clk_register_factor("uart_pll", "pll1_4",
+                               CLK_SET_RATE_PARENT,
+                               pxa_unit->mpmu_base + MPMU_UART_PLL,
+                               &uart_factor_masks, uart_factor_tbl,
+                               ARRAY_SIZE(uart_factor_tbl), NULL);
+       mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk);
+}
+
+static DEFINE_SPINLOCK(uart0_lock);
+static DEFINE_SPINLOCK(uart1_lock);
+static DEFINE_SPINLOCK(uart2_lock);
+static const char *uart_parent_names[] = {"uart_pll", "vctcxo"};
+
+static DEFINE_SPINLOCK(ssp0_lock);
+static DEFINE_SPINLOCK(ssp1_lock);
+static DEFINE_SPINLOCK(ssp2_lock);
+static DEFINE_SPINLOCK(ssp3_lock);
+static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"};
+
+static DEFINE_SPINLOCK(reset_lock);
+
+static struct mmp_param_mux_clk apbc_mux_clks[] = {
+       {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
+       {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
+       {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock},
+       {0, "uart3_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART3, 4, 3, 0, &uart2_lock},
+       {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
+       {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
+       {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock},
+       {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock},
+};
+
+static struct mmp_param_gate_clk apbc_gate_clks[] = {
+       {MMP2_CLK_TWSI0, "twsi0_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_TWSI1, "twsi1_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_TWSI2, "twsi2_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI2, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_TWSI3, "twsi3_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI3, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_TWSI4, "twsi4_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI4, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_TWSI5, "twsi5_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_TWSI5, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x7, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock},
+       {MMP2_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x87, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, &reset_lock},
+       {MMP2_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x7, 0x3, 0x0, 0, &reset_lock},
+       {MMP2_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x7, 0x3, 0x0, 0, &reset_lock},
+       /* The gate clocks has mux parent. */
+       {MMP2_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x7, 0x3, 0x0, 0, &uart0_lock},
+       {MMP2_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x7, 0x3, 0x0, 0, &uart1_lock},
+       {MMP2_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x7, 0x3, 0x0, 0, &uart2_lock},
+       {MMP2_CLK_UART3, "uart3_clk", "uart3_mux", CLK_SET_RATE_PARENT, APBC_UART3, 0x7, 0x3, 0x0, 0, &uart2_lock},
+       {MMP2_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x7, 0x3, 0x0, 0, &ssp0_lock},
+       {MMP2_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x7, 0x3, 0x0, 0, &ssp1_lock},
+       {MMP2_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x7, 0x3, 0x0, 0, &ssp2_lock},
+       {MMP2_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x7, 0x3, 0x0, 0, &ssp3_lock},
+};
+
+static void mmp2_apb_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
+{
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
+                               ARRAY_SIZE(apbc_mux_clks));
+
+       mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
+                               ARRAY_SIZE(apbc_gate_clks));
+}
+
+static DEFINE_SPINLOCK(sdh_lock);
+static const char *sdh_parent_names[] = {"pll1_4", "pll2", "usb_pll", "pll1"};
+static struct mmp_clk_mix_config sdh_mix_config = {
+       .reg_info = DEFINE_MIX_REG_INFO(4, 10, 2, 8, 32),
+};
+
+static DEFINE_SPINLOCK(usb_lock);
+
+static DEFINE_SPINLOCK(disp0_lock);
+static DEFINE_SPINLOCK(disp1_lock);
+static const char *disp_parent_names[] = {"pll1", "pll1_16", "pll2", "vctcxo"};
+
+static DEFINE_SPINLOCK(ccic0_lock);
+static DEFINE_SPINLOCK(ccic1_lock);
+static const char *ccic_parent_names[] = {"pll1_2", "pll1_16", "vctcxo"};
+static struct mmp_clk_mix_config ccic0_mix_config = {
+       .reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32),
+};
+static struct mmp_clk_mix_config ccic1_mix_config = {
+       .reg_info = DEFINE_MIX_REG_INFO(4, 16, 2, 6, 32),
+};
+
+static struct mmp_param_mux_clk apmu_mux_clks[] = {
+       {MMP2_CLK_DISP0_MUX, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 2, 0, &disp0_lock},
+       {MMP2_CLK_DISP1_MUX, "disp1_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP1, 6, 2, 0, &disp1_lock},
+};
+
+static struct mmp_param_div_clk apmu_div_clks[] = {
+       {0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock},
+       {0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock},
+       {0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock},
+       {0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
+       {0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock},
+};
+
+static struct mmp_param_gate_clk apmu_gate_clks[] = {
+       {MMP2_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
+       /* The gate clocks has mux parent. */
+       {MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
+       {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
+       {MMP2_CLK_SDH1, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
+       {MMP2_CLK_SDH1, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
+       {MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
+       {MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
+       {MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock},
+       {MMP2_CLK_CCIC_ARBITER, "ccic_arbiter", "vctcxo", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1800, 0x1800, 0x0, 0, &ccic0_lock},
+       {MMP2_CLK_CCIC0, "ccic0_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
+       {MMP2_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
+       {MMP2_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock},
+       {MMP2_CLK_CCIC1, "ccic1_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x1b, 0x1b, 0x0, 0, &ccic1_lock},
+       {MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
+       {MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
+};
+
+static void mmp2_axi_periph_clk_init(struct mmp2_clk_unit *pxa_unit)
+{
+       struct clk *clk;
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       sdh_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_SDH0;
+       clk = mmp_clk_register_mix(NULL, "sdh_mix_clk", sdh_parent_names,
+                                       ARRAY_SIZE(sdh_parent_names),
+                                       CLK_SET_RATE_PARENT,
+                                       &sdh_mix_config, &sdh_lock);
+
+       ccic0_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC0;
+       clk = mmp_clk_register_mix(NULL, "ccic0_mix_clk", ccic_parent_names,
+                                       ARRAY_SIZE(ccic_parent_names),
+                                       CLK_SET_RATE_PARENT,
+                                       &ccic0_mix_config, &ccic0_lock);
+       mmp_clk_add(unit, MMP2_CLK_CCIC0_MIX, clk);
+
+       ccic1_mix_config.reg_info.reg_clk_ctrl = pxa_unit->apmu_base + APMU_CCIC1;
+       clk = mmp_clk_register_mix(NULL, "ccic1_mix_clk", ccic_parent_names,
+                                       ARRAY_SIZE(ccic_parent_names),
+                                       CLK_SET_RATE_PARENT,
+                                       &ccic1_mix_config, &ccic1_lock);
+       mmp_clk_add(unit, MMP2_CLK_CCIC1_MIX, clk);
+
+       mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_mux_clks));
+
+       mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_div_clks));
+
+       mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_gate_clks));
+}
+
+static void mmp2_clk_reset_init(struct device_node *np,
+                               struct mmp2_clk_unit *pxa_unit)
+{
+       struct mmp_clk_reset_cell *cells;
+       int i, nr_resets;
+
+       nr_resets = ARRAY_SIZE(apbc_gate_clks);
+       cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
+       if (!cells)
+               return;
+
+       for (i = 0; i < nr_resets; i++) {
+               cells[i].clk_id = apbc_gate_clks[i].id;
+               cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset;
+               cells[i].flags = 0;
+               cells[i].lock = apbc_gate_clks[i].lock;
+               cells[i].bits = 0x4;
+       }
+
+       mmp_clk_reset_register(np, cells, nr_resets);
+}
+
+static void __init mmp2_clk_init(struct device_node *np)
+{
+       struct mmp2_clk_unit *pxa_unit;
+
+       pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
+       if (!pxa_unit)
+               return;
+
+       pxa_unit->mpmu_base = of_iomap(np, 0);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map mpmu registers\n");
+               return;
+       }
+
+       pxa_unit->apmu_base = of_iomap(np, 1);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map apmu registers\n");
+               return;
+       }
+
+       pxa_unit->apbc_base = of_iomap(np, 2);
+       if (!pxa_unit->apbc_base) {
+               pr_err("failed to map apbc registers\n");
+               return;
+       }
+
+       mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
+
+       mmp2_pll_init(pxa_unit);
+
+       mmp2_apb_periph_clk_init(pxa_unit);
+
+       mmp2_axi_periph_clk_init(pxa_unit);
+
+       mmp2_clk_reset_init(np, pxa_unit);
+}
+
+CLK_OF_DECLARE(mmp2_clk, "marvell,mmp2-clock", mmp2_clk_init);
diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
new file mode 100644 (file)
index 0000000..5b1810d
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * pxa168 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie <xiechao.mail@gmail.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/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/marvell,pxa168.h>
+
+#include "clk.h"
+#include "reset.h"
+
+#define APBC_RTC       0x28
+#define APBC_TWSI0     0x2c
+#define APBC_KPC       0x30
+#define APBC_UART0     0x0
+#define APBC_UART1     0x4
+#define APBC_GPIO      0x8
+#define APBC_PWM0      0xc
+#define APBC_PWM1      0x10
+#define APBC_PWM2      0x14
+#define APBC_PWM3      0x18
+#define APBC_SSP0      0x81c
+#define APBC_SSP1      0x820
+#define APBC_SSP2      0x84c
+#define APBC_SSP3      0x858
+#define APBC_SSP4      0x85c
+#define APBC_TWSI1     0x6c
+#define APBC_UART2     0x70
+#define APMU_SDH0      0x54
+#define APMU_SDH1      0x58
+#define APMU_USB       0x5c
+#define APMU_DISP0     0x4c
+#define APMU_CCIC0     0x50
+#define APMU_DFC       0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa168_clk_unit {
+       struct mmp_clk_unit unit;
+       void __iomem *mpmu_base;
+       void __iomem *apmu_base;
+       void __iomem *apbc_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+       {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+       {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
+       {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+       {PXA168_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+       {PXA168_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+       {PXA168_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+       {PXA168_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+       {PXA168_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
+       {PXA168_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+       {PXA168_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
+       {PXA168_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
+       {PXA168_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+       {PXA168_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
+       {PXA168_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
+       {PXA168_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+       {PXA168_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+       .factor = 2,
+       .num_mask = 0x1fff,
+       .den_mask = 0x1fff,
+       .num_shift = 16,
+       .den_shift = 0,
+};
+
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
+       {.num = 8125, .den = 1536},     /*14.745MHZ */
+};
+
+static void pxa168_pll_init(struct pxa168_clk_unit *pxa_unit)
+{
+       struct clk *clk;
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
+                                       ARRAY_SIZE(fixed_rate_clks));
+
+       mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
+                                       ARRAY_SIZE(fixed_factor_clks));
+
+       clk = mmp_clk_register_factor("uart_pll", "pll1_4",
+                               CLK_SET_RATE_PARENT,
+                               pxa_unit->mpmu_base + MPMU_UART_PLL,
+                               &uart_factor_masks, uart_factor_tbl,
+                               ARRAY_SIZE(uart_factor_tbl), NULL);
+       mmp_clk_add(unit, PXA168_CLK_UART_PLL, clk);
+}
+
+static DEFINE_SPINLOCK(uart0_lock);
+static DEFINE_SPINLOCK(uart1_lock);
+static DEFINE_SPINLOCK(uart2_lock);
+static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"};
+
+static DEFINE_SPINLOCK(ssp0_lock);
+static DEFINE_SPINLOCK(ssp1_lock);
+static DEFINE_SPINLOCK(ssp2_lock);
+static DEFINE_SPINLOCK(ssp3_lock);
+static DEFINE_SPINLOCK(ssp4_lock);
+static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
+
+static DEFINE_SPINLOCK(reset_lock);
+
+static struct mmp_param_mux_clk apbc_mux_clks[] = {
+       {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
+       {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
+       {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART2, 4, 3, 0, &uart2_lock},
+       {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
+       {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
+       {0, "ssp2_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP2, 4, 3, 0, &ssp2_lock},
+       {0, "ssp3_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP3, 4, 3, 0, &ssp3_lock},
+       {0, "ssp4_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP4, 4, 3, 0, &ssp4_lock},
+};
+
+static struct mmp_param_gate_clk apbc_gate_clks[] = {
+       {PXA168_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA168_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA168_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA168_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
+       {PXA168_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
+       {PXA168_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA168_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA168_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA168_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock},
+       /* The gate clocks has mux parent. */
+       {PXA168_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock},
+       {PXA168_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock},
+       {PXA168_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBC_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock},
+       {PXA168_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock},
+       {PXA168_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock},
+       {PXA168_CLK_SSP2, "ssp2_clk", "ssp2_mux", CLK_SET_RATE_PARENT, APBC_SSP2, 0x3, 0x3, 0x0, 0, &ssp2_lock},
+       {PXA168_CLK_SSP3, "ssp3_clk", "ssp3_mux", CLK_SET_RATE_PARENT, APBC_SSP3, 0x3, 0x3, 0x0, 0, &ssp3_lock},
+       {PXA168_CLK_SSP4, "ssp4_clk", "ssp4_mux", CLK_SET_RATE_PARENT, APBC_SSP4, 0x3, 0x3, 0x0, 0, &ssp4_lock},
+};
+
+static void pxa168_apb_periph_clk_init(struct pxa168_clk_unit *pxa_unit)
+{
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
+                               ARRAY_SIZE(apbc_mux_clks));
+
+       mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
+                               ARRAY_SIZE(apbc_gate_clks));
+
+}
+
+static DEFINE_SPINLOCK(sdh0_lock);
+static DEFINE_SPINLOCK(sdh1_lock);
+static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"};
+
+static DEFINE_SPINLOCK(usb_lock);
+
+static DEFINE_SPINLOCK(disp0_lock);
+static const char *disp_parent_names[] = {"pll1_2", "pll1_12"};
+
+static DEFINE_SPINLOCK(ccic0_lock);
+static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"};
+static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"};
+
+static struct mmp_param_mux_clk apmu_mux_clks[] = {
+       {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock},
+       {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock},
+       {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock},
+       {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock},
+       {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock},
+};
+
+static struct mmp_param_div_clk apmu_div_clks[] = {
+       {0, "ccic0_sphy_div", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
+};
+
+static struct mmp_param_gate_clk apmu_gate_clks[] = {
+       {PXA168_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL},
+       {PXA168_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
+       {PXA168_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock},
+       /* The gate clocks has mux parent. */
+       {PXA168_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock},
+       {PXA168_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock},
+       {PXA168_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
+       {PXA168_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
+       {PXA168_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
+       {PXA168_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock},
+};
+
+static void pxa168_axi_periph_clk_init(struct pxa168_clk_unit *pxa_unit)
+{
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_mux_clks));
+
+       mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_div_clks));
+
+       mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_gate_clks));
+}
+
+static void pxa168_clk_reset_init(struct device_node *np,
+                               struct pxa168_clk_unit *pxa_unit)
+{
+       struct mmp_clk_reset_cell *cells;
+       int i, nr_resets;
+
+       nr_resets = ARRAY_SIZE(apbc_gate_clks);
+       cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
+       if (!cells)
+               return;
+
+       for (i = 0; i < nr_resets; i++) {
+               cells[i].clk_id = apbc_gate_clks[i].id;
+               cells[i].reg = pxa_unit->apbc_base + apbc_gate_clks[i].offset;
+               cells[i].flags = 0;
+               cells[i].lock = apbc_gate_clks[i].lock;
+               cells[i].bits = 0x4;
+       }
+
+       mmp_clk_reset_register(np, cells, nr_resets);
+}
+
+static void __init pxa168_clk_init(struct device_node *np)
+{
+       struct pxa168_clk_unit *pxa_unit;
+
+       pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
+       if (!pxa_unit)
+               return;
+
+       pxa_unit->mpmu_base = of_iomap(np, 0);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map mpmu registers\n");
+               return;
+       }
+
+       pxa_unit->apmu_base = of_iomap(np, 1);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map apmu registers\n");
+               return;
+       }
+
+       pxa_unit->apbc_base = of_iomap(np, 2);
+       if (!pxa_unit->apbc_base) {
+               pr_err("failed to map apbc registers\n");
+               return;
+       }
+
+       mmp_clk_init(np, &pxa_unit->unit, PXA168_NR_CLKS);
+
+       pxa168_pll_init(pxa_unit);
+
+       pxa168_apb_periph_clk_init(pxa_unit);
+
+       pxa168_axi_periph_clk_init(pxa_unit);
+
+       pxa168_clk_reset_init(np, pxa_unit);
+}
+
+CLK_OF_DECLARE(pxa168_clk, "marvell,pxa168-clock", pxa168_clk_init);
diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
new file mode 100644 (file)
index 0000000..5e3c80d
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * pxa910 clock framework source file
+ *
+ * Copyright (C) 2012 Marvell
+ * Chao Xie <xiechao.mail@gmail.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/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/marvell,pxa910.h>
+
+#include "clk.h"
+#include "reset.h"
+
+#define APBC_RTC       0x28
+#define APBC_TWSI0     0x2c
+#define APBC_KPC       0x18
+#define APBC_UART0     0x0
+#define APBC_UART1     0x4
+#define APBC_GPIO      0x8
+#define APBC_PWM0      0xc
+#define APBC_PWM1      0x10
+#define APBC_PWM2      0x14
+#define APBC_PWM3      0x18
+#define APBC_SSP0      0x1c
+#define APBC_SSP1      0x20
+#define APBC_SSP2      0x4c
+#define APBCP_TWSI1    0x28
+#define APBCP_UART2    0x1c
+#define APMU_SDH0      0x54
+#define APMU_SDH1      0x58
+#define APMU_USB       0x5c
+#define APMU_DISP0     0x4c
+#define APMU_CCIC0     0x50
+#define APMU_DFC       0x60
+#define MPMU_UART_PLL  0x14
+
+struct pxa910_clk_unit {
+       struct mmp_clk_unit unit;
+       void __iomem *mpmu_base;
+       void __iomem *apmu_base;
+       void __iomem *apbc_base;
+       void __iomem *apbcp_base;
+};
+
+static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
+       {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768},
+       {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000},
+       {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000},
+};
+
+static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+       {PXA910_CLK_PLL1_2, "pll1_2", "pll1", 1, 2, 0},
+       {PXA910_CLK_PLL1_4, "pll1_4", "pll1_2", 1, 2, 0},
+       {PXA910_CLK_PLL1_8, "pll1_8", "pll1_4", 1, 2, 0},
+       {PXA910_CLK_PLL1_16, "pll1_16", "pll1_8", 1, 2, 0},
+       {PXA910_CLK_PLL1_6, "pll1_6", "pll1_2", 1, 3, 0},
+       {PXA910_CLK_PLL1_12, "pll1_12", "pll1_6", 1, 2, 0},
+       {PXA910_CLK_PLL1_24, "pll1_24", "pll1_12", 1, 2, 0},
+       {PXA910_CLK_PLL1_48, "pll1_48", "pll1_24", 1, 2, 0},
+       {PXA910_CLK_PLL1_96, "pll1_96", "pll1_48", 1, 2, 0},
+       {PXA910_CLK_PLL1_13, "pll1_13", "pll1", 1, 13, 0},
+       {PXA910_CLK_PLL1_13_1_5, "pll1_13_1_5", "pll1_13", 2, 3, 0},
+       {PXA910_CLK_PLL1_2_1_5, "pll1_2_1_5", "pll1_2", 2, 3, 0},
+       {PXA910_CLK_PLL1_3_16, "pll1_3_16", "pll1", 3, 16, 0},
+};
+
+static struct mmp_clk_factor_masks uart_factor_masks = {
+       .factor = 2,
+       .num_mask = 0x1fff,
+       .den_mask = 0x1fff,
+       .num_shift = 16,
+       .den_shift = 0,
+};
+
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
+       {.num = 8125, .den = 1536},     /*14.745MHZ */
+};
+
+static void pxa910_pll_init(struct pxa910_clk_unit *pxa_unit)
+{
+       struct clk *clk;
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
+                                       ARRAY_SIZE(fixed_rate_clks));
+
+       mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
+                                       ARRAY_SIZE(fixed_factor_clks));
+
+       clk = mmp_clk_register_factor("uart_pll", "pll1_4",
+                               CLK_SET_RATE_PARENT,
+                               pxa_unit->mpmu_base + MPMU_UART_PLL,
+                               &uart_factor_masks, uart_factor_tbl,
+                               ARRAY_SIZE(uart_factor_tbl), NULL);
+       mmp_clk_add(unit, PXA910_CLK_UART_PLL, clk);
+}
+
+static DEFINE_SPINLOCK(uart0_lock);
+static DEFINE_SPINLOCK(uart1_lock);
+static DEFINE_SPINLOCK(uart2_lock);
+static const char *uart_parent_names[] = {"pll1_3_16", "uart_pll"};
+
+static DEFINE_SPINLOCK(ssp0_lock);
+static DEFINE_SPINLOCK(ssp1_lock);
+static const char *ssp_parent_names[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"};
+
+static DEFINE_SPINLOCK(reset_lock);
+
+static struct mmp_param_mux_clk apbc_mux_clks[] = {
+       {0, "uart0_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART0, 4, 3, 0, &uart0_lock},
+       {0, "uart1_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBC_UART1, 4, 3, 0, &uart1_lock},
+       {0, "ssp0_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP0, 4, 3, 0, &ssp0_lock},
+       {0, "ssp1_mux", ssp_parent_names, ARRAY_SIZE(ssp_parent_names), CLK_SET_RATE_PARENT, APBC_SSP1, 4, 3, 0, &ssp1_lock},
+};
+
+static struct mmp_param_mux_clk apbcp_mux_clks[] = {
+       {0, "uart2_mux", uart_parent_names, ARRAY_SIZE(uart_parent_names), CLK_SET_RATE_PARENT, APBCP_UART2, 4, 3, 0, &uart2_lock},
+};
+
+static struct mmp_param_gate_clk apbc_gate_clks[] = {
+       {PXA910_CLK_TWSI0, "twsi0_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBC_TWSI0, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA910_CLK_GPIO, "gpio_clk", "vctcxo", CLK_SET_RATE_PARENT, APBC_GPIO, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA910_CLK_KPC, "kpc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_KPC, 0x3, 0x3, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
+       {PXA910_CLK_RTC, "rtc_clk", "clk32", CLK_SET_RATE_PARENT, APBC_RTC, 0x83, 0x83, 0x0, MMP_CLK_GATE_NEED_DELAY, NULL},
+       {PXA910_CLK_PWM0, "pwm0_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM0, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA910_CLK_PWM1, "pwm1_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM1, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA910_CLK_PWM2, "pwm2_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM2, 0x3, 0x3, 0x0, 0, &reset_lock},
+       {PXA910_CLK_PWM3, "pwm3_clk", "pll1_48", CLK_SET_RATE_PARENT, APBC_PWM3, 0x3, 0x3, 0x0, 0, &reset_lock},
+       /* The gate clocks has mux parent. */
+       {PXA910_CLK_UART0, "uart0_clk", "uart0_mux", CLK_SET_RATE_PARENT, APBC_UART0, 0x3, 0x3, 0x0, 0, &uart0_lock},
+       {PXA910_CLK_UART1, "uart1_clk", "uart1_mux", CLK_SET_RATE_PARENT, APBC_UART1, 0x3, 0x3, 0x0, 0, &uart1_lock},
+       {PXA910_CLK_SSP0, "ssp0_clk", "ssp0_mux", CLK_SET_RATE_PARENT, APBC_SSP0, 0x3, 0x3, 0x0, 0, &ssp0_lock},
+       {PXA910_CLK_SSP1, "ssp1_clk", "ssp1_mux", CLK_SET_RATE_PARENT, APBC_SSP1, 0x3, 0x3, 0x0, 0, &ssp1_lock},
+};
+
+static struct mmp_param_gate_clk apbcp_gate_clks[] = {
+       {PXA910_CLK_TWSI1, "twsi1_clk", "pll1_13_1_5", CLK_SET_RATE_PARENT, APBCP_TWSI1, 0x3, 0x3, 0x0, 0, &reset_lock},
+       /* The gate clocks has mux parent. */
+       {PXA910_CLK_UART2, "uart2_clk", "uart2_mux", CLK_SET_RATE_PARENT, APBCP_UART2, 0x3, 0x3, 0x0, 0, &uart2_lock},
+};
+
+static void pxa910_apb_periph_clk_init(struct pxa910_clk_unit *pxa_unit)
+{
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_mux_clks(unit, apbc_mux_clks, pxa_unit->apbc_base,
+                               ARRAY_SIZE(apbc_mux_clks));
+
+       mmp_register_mux_clks(unit, apbcp_mux_clks, pxa_unit->apbcp_base,
+                               ARRAY_SIZE(apbcp_mux_clks));
+
+       mmp_register_gate_clks(unit, apbc_gate_clks, pxa_unit->apbc_base,
+                               ARRAY_SIZE(apbc_gate_clks));
+
+       mmp_register_gate_clks(unit, apbcp_gate_clks, pxa_unit->apbcp_base,
+                               ARRAY_SIZE(apbcp_gate_clks));
+}
+
+static DEFINE_SPINLOCK(sdh0_lock);
+static DEFINE_SPINLOCK(sdh1_lock);
+static const char *sdh_parent_names[] = {"pll1_12", "pll1_13"};
+
+static DEFINE_SPINLOCK(usb_lock);
+
+static DEFINE_SPINLOCK(disp0_lock);
+static const char *disp_parent_names[] = {"pll1_2", "pll1_12"};
+
+static DEFINE_SPINLOCK(ccic0_lock);
+static const char *ccic_parent_names[] = {"pll1_2", "pll1_12"};
+static const char *ccic_phy_parent_names[] = {"pll1_6", "pll1_12"};
+
+static struct mmp_param_mux_clk apmu_mux_clks[] = {
+       {0, "sdh0_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH0, 6, 1, 0, &sdh0_lock},
+       {0, "sdh1_mux", sdh_parent_names, ARRAY_SIZE(sdh_parent_names), CLK_SET_RATE_PARENT, APMU_SDH1, 6, 1, 0, &sdh1_lock},
+       {0, "disp0_mux", disp_parent_names, ARRAY_SIZE(disp_parent_names), CLK_SET_RATE_PARENT, APMU_DISP0, 6, 1, 0, &disp0_lock},
+       {0, "ccic0_mux", ccic_parent_names, ARRAY_SIZE(ccic_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 6, 1, 0, &ccic0_lock},
+       {0, "ccic0_phy_mux", ccic_phy_parent_names, ARRAY_SIZE(ccic_phy_parent_names), CLK_SET_RATE_PARENT, APMU_CCIC0, 7, 1, 0, &ccic0_lock},
+};
+
+static struct mmp_param_div_clk apmu_div_clks[] = {
+       {0, "ccic0_sphy_div", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
+};
+
+static struct mmp_param_gate_clk apmu_gate_clks[] = {
+       {PXA910_CLK_DFC, "dfc_clk", "pll1_4", CLK_SET_RATE_PARENT, APMU_DFC, 0x19b, 0x19b, 0x0, 0, NULL},
+       {PXA910_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
+       {PXA910_CLK_SPH, "sph_clk", "usb_pll", 0, APMU_USB, 0x12, 0x12, 0x0, 0, &usb_lock},
+       /* The gate clocks has mux parent. */
+       {PXA910_CLK_SDH0, "sdh0_clk", "sdh0_mux", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh0_lock},
+       {PXA910_CLK_SDH1, "sdh1_clk", "sdh1_mux", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh1_lock},
+       {PXA910_CLK_DISP0, "disp0_clk", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
+       {PXA910_CLK_CCIC0, "ccic0_clk", "ccic0_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x1b, 0x1b, 0x0, 0, &ccic0_lock},
+       {PXA910_CLK_CCIC0_PHY, "ccic0_phy_clk", "ccic0_phy_mux", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x24, 0x24, 0x0, 0, &ccic0_lock},
+       {PXA910_CLK_CCIC0_SPHY, "ccic0_sphy_clk", "ccic0_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC0, 0x300, 0x300, 0x0, 0, &ccic0_lock},
+};
+
+static void pxa910_axi_periph_clk_init(struct pxa910_clk_unit *pxa_unit)
+{
+       struct mmp_clk_unit *unit = &pxa_unit->unit;
+
+       mmp_register_mux_clks(unit, apmu_mux_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_mux_clks));
+
+       mmp_register_div_clks(unit, apmu_div_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_div_clks));
+
+       mmp_register_gate_clks(unit, apmu_gate_clks, pxa_unit->apmu_base,
+                               ARRAY_SIZE(apmu_gate_clks));
+}
+
+static void pxa910_clk_reset_init(struct device_node *np,
+                               struct pxa910_clk_unit *pxa_unit)
+{
+       struct mmp_clk_reset_cell *cells;
+       int i, base, nr_resets_apbc, nr_resets_apbcp, nr_resets;
+
+       nr_resets_apbc = ARRAY_SIZE(apbc_gate_clks);
+       nr_resets_apbcp = ARRAY_SIZE(apbcp_gate_clks);
+       nr_resets = nr_resets_apbc + nr_resets_apbcp;
+       cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL);
+       if (!cells)
+               return;
+
+       base = 0;
+       for (i = 0; i < nr_resets_apbc; i++) {
+               cells[base + i].clk_id = apbc_gate_clks[i].id;
+               cells[base + i].reg =
+                       pxa_unit->apbc_base + apbc_gate_clks[i].offset;
+               cells[base + i].flags = 0;
+               cells[base + i].lock = apbc_gate_clks[i].lock;
+               cells[base + i].bits = 0x4;
+       }
+
+       base = nr_resets_apbc;
+       for (i = 0; i < nr_resets_apbcp; i++) {
+               cells[base + i].clk_id = apbcp_gate_clks[i].id;
+               cells[base + i].reg =
+                       pxa_unit->apbc_base + apbc_gate_clks[i].offset;
+               cells[base + i].flags = 0;
+               cells[base + i].lock = apbc_gate_clks[i].lock;
+               cells[base + i].bits = 0x4;
+       }
+
+       mmp_clk_reset_register(np, cells, nr_resets);
+}
+
+static void __init pxa910_clk_init(struct device_node *np)
+{
+       struct pxa910_clk_unit *pxa_unit;
+
+       pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL);
+       if (!pxa_unit)
+               return;
+
+       pxa_unit->mpmu_base = of_iomap(np, 0);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map mpmu registers\n");
+               return;
+       }
+
+       pxa_unit->apmu_base = of_iomap(np, 1);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map apmu registers\n");
+               return;
+       }
+
+       pxa_unit->apbc_base = of_iomap(np, 2);
+       if (!pxa_unit->apbc_base) {
+               pr_err("failed to map apbc registers\n");
+               return;
+       }
+
+       pxa_unit->apbcp_base = of_iomap(np, 3);
+       if (!pxa_unit->mpmu_base) {
+               pr_err("failed to map apbcp registers\n");
+               return;
+       }
+
+       mmp_clk_init(np, &pxa_unit->unit, PXA910_NR_CLKS);
+
+       pxa910_pll_init(pxa_unit);
+
+       pxa910_apb_periph_clk_init(pxa_unit);
+
+       pxa910_axi_periph_clk_init(pxa_unit);
+
+       pxa910_clk_reset_init(np, pxa_unit);
+}
+
+CLK_OF_DECLARE(pxa910_clk, "marvell,pxa910-clock", pxa910_clk_init);
index 014396b028a2c8c137723ccf2063f2dba6404f02..93e967c0f972f954ef1f7af9bb2f90e0c3241cae 100644 (file)
@@ -47,7 +47,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
        .factor = 2,
        .num_mask = 0x1fff,
        .den_mask = 0x1fff,
@@ -55,7 +55,7 @@ static struct clk_factor_masks uart_factor_masks = {
        .den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
        {.num = 8125, .den = 1536},     /*14.745MHZ */
 };
 
@@ -158,7 +158,7 @@ void __init pxa168_clk_init(void)
        uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0,
                                mpmu_base + MPMU_UART_PLL,
                                &uart_factor_masks, uart_factor_tbl,
-                               ARRAY_SIZE(uart_factor_tbl));
+                               ARRAY_SIZE(uart_factor_tbl), &clk_lock);
        clk_set_rate(uart_pll, 14745600);
        clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
index 9efc6a47535d3bf07747e3373078daef8162794a..993abcdb32cce825fdb1d2ea835cb69f3ecf94fc 100644 (file)
@@ -45,7 +45,7 @@
 
 static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk_factor_masks uart_factor_masks = {
+static struct mmp_clk_factor_masks uart_factor_masks = {
        .factor = 2,
        .num_mask = 0x1fff,
        .den_mask = 0x1fff,
@@ -53,7 +53,7 @@ static struct clk_factor_masks uart_factor_masks = {
        .den_shift = 0,
 };
 
-static struct clk_factor_tbl uart_factor_tbl[] = {
+static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
        {.num = 8125, .den = 1536},     /*14.745MHZ */
 };
 
@@ -163,7 +163,7 @@ void __init pxa910_clk_init(void)
        uart_pll =  mmp_clk_register_factor("uart_pll", "pll1_4", 0,
                                mpmu_base + MPMU_UART_PLL,
                                &uart_factor_masks, uart_factor_tbl,
-                               ARRAY_SIZE(uart_factor_tbl));
+                               ARRAY_SIZE(uart_factor_tbl), &clk_lock);
        clk_set_rate(uart_pll, 14745600);
        clk_register_clkdev(uart_pll, "uart_pll", NULL);
 
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c
new file mode 100644 (file)
index 0000000..cf038ef
--- /dev/null
@@ -0,0 +1,192 @@
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk.h"
+
+void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
+               int nr_clks)
+{
+       static struct clk **clk_table;
+
+       clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL);
+       if (!clk_table)
+               return;
+
+       unit->clk_table = clk_table;
+       unit->nr_clks = nr_clks;
+       unit->clk_data.clks = clk_table;
+       unit->clk_data.clk_num = nr_clks;
+       of_clk_add_provider(np, of_clk_src_onecell_get, &unit->clk_data);
+}
+
+void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
+                               struct mmp_param_fixed_rate_clk *clks,
+                               int size)
+{
+       int i;
+       struct clk *clk;
+
+       for (i = 0; i < size; i++) {
+               clk = clk_register_fixed_rate(NULL, clks[i].name,
+                                       clks[i].parent_name,
+                                       clks[i].flags,
+                                       clks[i].fixed_rate);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               if (clks[i].id)
+                       unit->clk_table[clks[i].id] = clk;
+       }
+}
+
+void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
+                               struct mmp_param_fixed_factor_clk *clks,
+                               int size)
+{
+       struct clk *clk;
+       int i;
+
+       for (i = 0; i < size; i++) {
+               clk = clk_register_fixed_factor(NULL, clks[i].name,
+                                               clks[i].parent_name,
+                                               clks[i].flags, clks[i].mult,
+                                               clks[i].div);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               if (clks[i].id)
+                       unit->clk_table[clks[i].id] = clk;
+       }
+}
+
+void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
+                               struct mmp_param_general_gate_clk *clks,
+                               void __iomem *base, int size)
+{
+       struct clk *clk;
+       int i;
+
+       for (i = 0; i < size; i++) {
+               clk = clk_register_gate(NULL, clks[i].name,
+                                       clks[i].parent_name,
+                                       clks[i].flags,
+                                       base + clks[i].offset,
+                                       clks[i].bit_idx,
+                                       clks[i].gate_flags,
+                                       clks[i].lock);
+
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               if (clks[i].id)
+                       unit->clk_table[clks[i].id] = clk;
+       }
+}
+
+void mmp_register_gate_clks(struct mmp_clk_unit *unit,
+                       struct mmp_param_gate_clk *clks,
+                       void __iomem *base, int size)
+{
+       struct clk *clk;
+       int i;
+
+       for (i = 0; i < size; i++) {
+               clk = mmp_clk_register_gate(NULL, clks[i].name,
+                                       clks[i].parent_name,
+                                       clks[i].flags,
+                                       base + clks[i].offset,
+                                       clks[i].mask,
+                                       clks[i].val_enable,
+                                       clks[i].val_disable,
+                                       clks[i].gate_flags,
+                                       clks[i].lock);
+
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               if (clks[i].id)
+                       unit->clk_table[clks[i].id] = clk;
+       }
+}
+
+void mmp_register_mux_clks(struct mmp_clk_unit *unit,
+                       struct mmp_param_mux_clk *clks,
+                       void __iomem *base, int size)
+{
+       struct clk *clk;
+       int i;
+
+       for (i = 0; i < size; i++) {
+               clk = clk_register_mux(NULL, clks[i].name,
+                                       clks[i].parent_name,
+                                       clks[i].num_parents,
+                                       clks[i].flags,
+                                       base + clks[i].offset,
+                                       clks[i].shift,
+                                       clks[i].width,
+                                       clks[i].mux_flags,
+                                       clks[i].lock);
+
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               if (clks[i].id)
+                       unit->clk_table[clks[i].id] = clk;
+       }
+}
+
+void mmp_register_div_clks(struct mmp_clk_unit *unit,
+                       struct mmp_param_div_clk *clks,
+                       void __iomem *base, int size)
+{
+       struct clk *clk;
+       int i;
+
+       for (i = 0; i < size; i++) {
+               clk = clk_register_divider(NULL, clks[i].name,
+                                       clks[i].parent_name,
+                                       clks[i].flags,
+                                       base + clks[i].offset,
+                                       clks[i].shift,
+                                       clks[i].width,
+                                       clks[i].div_flags,
+                                       clks[i].lock);
+
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n",
+                              __func__, clks[i].name);
+                       continue;
+               }
+               if (clks[i].id)
+                       unit->clk_table[clks[i].id] = clk;
+       }
+}
+
+void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
+                       struct clk *clk)
+{
+       if (IS_ERR_OR_NULL(clk)) {
+               pr_err("CLK %d has invalid pointer %p\n", id, clk);
+               return;
+       }
+       if (id > unit->nr_clks) {
+               pr_err("CLK %d is invalid\n", id);
+               return;
+       }
+
+       unit->clk_table[id] = clk;
+}
index ab86dd4a416a5fa6b75aa74d7588894e7b8c4c2e..adf9b711b03702e61c989b315124b66aafa6c07a 100644 (file)
 #define APBC_NO_BUS_CTRL       BIT(0)
 #define APBC_POWER_CTRL                BIT(1)
 
-struct clk_factor_masks {
-       unsigned int    factor;
-       unsigned int    num_mask;
-       unsigned int    den_mask;
-       unsigned int    num_shift;
-       unsigned int    den_shift;
+
+/* Clock type "factor" */
+struct mmp_clk_factor_masks {
+       unsigned int factor;
+       unsigned int num_mask;
+       unsigned int den_mask;
+       unsigned int num_shift;
+       unsigned int den_shift;
 };
 
-struct clk_factor_tbl {
+struct mmp_clk_factor_tbl {
        unsigned int num;
        unsigned int den;
 };
 
+struct mmp_clk_factor {
+       struct clk_hw hw;
+       void __iomem *base;
+       struct mmp_clk_factor_masks *masks;
+       struct mmp_clk_factor_tbl *ftbl;
+       unsigned int ftbl_cnt;
+       spinlock_t *lock;
+};
+
+extern struct clk *mmp_clk_register_factor(const char *name,
+               const char *parent_name, unsigned long flags,
+               void __iomem *base, struct mmp_clk_factor_masks *masks,
+               struct mmp_clk_factor_tbl *ftbl, unsigned int ftbl_cnt,
+               spinlock_t *lock);
+
+/* Clock type "mix" */
+#define MMP_CLK_BITS_MASK(width, shift)                        \
+               (((1 << (width)) - 1) << (shift))
+#define MMP_CLK_BITS_GET_VAL(data, width, shift)       \
+               ((data & MMP_CLK_BITS_MASK(width, shift)) >> (shift))
+#define MMP_CLK_BITS_SET_VAL(val, width, shift)                \
+               (((val) << (shift)) & MMP_CLK_BITS_MASK(width, shift))
+
+enum {
+       MMP_CLK_MIX_TYPE_V1,
+       MMP_CLK_MIX_TYPE_V2,
+       MMP_CLK_MIX_TYPE_V3,
+};
+
+/* The register layout */
+struct mmp_clk_mix_reg_info {
+       void __iomem *reg_clk_ctrl;
+       void __iomem *reg_clk_sel;
+       u8 width_div;
+       u8 shift_div;
+       u8 width_mux;
+       u8 shift_mux;
+       u8 bit_fc;
+};
+
+/* The suggested clock table from user. */
+struct mmp_clk_mix_clk_table {
+       unsigned long rate;
+       u8 parent_index;
+       unsigned int divisor;
+       unsigned int valid;
+};
+
+struct mmp_clk_mix_config {
+       struct mmp_clk_mix_reg_info reg_info;
+       struct mmp_clk_mix_clk_table *table;
+       unsigned int table_size;
+       u32 *mux_table;
+       struct clk_div_table *div_table;
+       u8 div_flags;
+       u8 mux_flags;
+};
+
+struct mmp_clk_mix {
+       struct clk_hw hw;
+       struct mmp_clk_mix_reg_info reg_info;
+       struct mmp_clk_mix_clk_table *table;
+       u32 *mux_table;
+       struct clk_div_table *div_table;
+       unsigned int table_size;
+       u8 div_flags;
+       u8 mux_flags;
+       unsigned int type;
+       spinlock_t *lock;
+};
+
+extern const struct clk_ops mmp_clk_mix_ops;
+extern struct clk *mmp_clk_register_mix(struct device *dev,
+                                       const char *name,
+                                       const char **parent_names,
+                                       u8 num_parents,
+                                       unsigned long flags,
+                                       struct mmp_clk_mix_config *config,
+                                       spinlock_t *lock);
+
+
+/* Clock type "gate". MMP private gate */
+#define MMP_CLK_GATE_NEED_DELAY                BIT(0)
+
+struct mmp_clk_gate {
+       struct clk_hw hw;
+       void __iomem *reg;
+       u32 mask;
+       u32 val_enable;
+       u32 val_disable;
+       unsigned int flags;
+       spinlock_t *lock;
+};
+
+extern const struct clk_ops mmp_clk_gate_ops;
+extern struct clk *mmp_clk_register_gate(struct device *dev, const char *name,
+                       const char *parent_name, unsigned long flags,
+                       void __iomem *reg, u32 mask, u32 val_enable,
+                       u32 val_disable, unsigned int gate_flags,
+                       spinlock_t *lock);
+
+
 extern struct clk *mmp_clk_register_pll2(const char *name,
                const char *parent_name, unsigned long flags);
 extern struct clk *mmp_clk_register_apbc(const char *name,
@@ -28,8 +132,108 @@ extern struct clk *mmp_clk_register_apbc(const char *name,
 extern struct clk *mmp_clk_register_apmu(const char *name,
                const char *parent_name, void __iomem *base, u32 enable_mask,
                spinlock_t *lock);
-extern struct clk *mmp_clk_register_factor(const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *base, struct clk_factor_masks *masks,
-               struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt);
+
+struct mmp_clk_unit {
+       unsigned int nr_clks;
+       struct clk **clk_table;
+       struct clk_onecell_data clk_data;
+};
+
+struct mmp_param_fixed_rate_clk {
+       unsigned int id;
+       char *name;
+       const char *parent_name;
+       unsigned long flags;
+       unsigned long fixed_rate;
+};
+void mmp_register_fixed_rate_clks(struct mmp_clk_unit *unit,
+                               struct mmp_param_fixed_rate_clk *clks,
+                               int size);
+
+struct mmp_param_fixed_factor_clk {
+       unsigned int id;
+       char *name;
+       const char *parent_name;
+       unsigned long mult;
+       unsigned long div;
+       unsigned long flags;
+};
+void mmp_register_fixed_factor_clks(struct mmp_clk_unit *unit,
+                               struct mmp_param_fixed_factor_clk *clks,
+                               int size);
+
+struct mmp_param_general_gate_clk {
+       unsigned int id;
+       const char *name;
+       const char *parent_name;
+       unsigned long flags;
+       unsigned long offset;
+       u8 bit_idx;
+       u8 gate_flags;
+       spinlock_t *lock;
+};
+void mmp_register_general_gate_clks(struct mmp_clk_unit *unit,
+                               struct mmp_param_general_gate_clk *clks,
+                               void __iomem *base, int size);
+
+struct mmp_param_gate_clk {
+       unsigned int id;
+       char *name;
+       const char *parent_name;
+       unsigned long flags;
+       unsigned long offset;
+       u32 mask;
+       u32 val_enable;
+       u32 val_disable;
+       unsigned int gate_flags;
+       spinlock_t *lock;
+};
+void mmp_register_gate_clks(struct mmp_clk_unit *unit,
+                       struct mmp_param_gate_clk *clks,
+                       void __iomem *base, int size);
+
+struct mmp_param_mux_clk {
+       unsigned int id;
+       char *name;
+       const char **parent_name;
+       u8 num_parents;
+       unsigned long flags;
+       unsigned long offset;
+       u8 shift;
+       u8 width;
+       u8 mux_flags;
+       spinlock_t *lock;
+};
+void mmp_register_mux_clks(struct mmp_clk_unit *unit,
+                       struct mmp_param_mux_clk *clks,
+                       void __iomem *base, int size);
+
+struct mmp_param_div_clk {
+       unsigned int id;
+       char *name;
+       const char *parent_name;
+       unsigned long flags;
+       unsigned long offset;
+       u8 shift;
+       u8 width;
+       u8 div_flags;
+       spinlock_t *lock;
+};
+void mmp_register_div_clks(struct mmp_clk_unit *unit,
+                       struct mmp_param_div_clk *clks,
+                       void __iomem *base, int size);
+
+#define DEFINE_MIX_REG_INFO(w_d, s_d, w_m, s_m, fc)    \
+{                                                      \
+       .width_div = (w_d),                             \
+       .shift_div = (s_d),                             \
+       .width_mux = (w_m),                             \
+       .shift_mux = (s_m),                             \
+       .bit_fc = (fc),                                 \
+}
+
+void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
+               int nr_clks);
+void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
+               struct clk *clk);
 #endif
diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c
new file mode 100644 (file)
index 0000000..b54da1f
--- /dev/null
@@ -0,0 +1,99 @@
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/reset-controller.h>
+
+#include "reset.h"
+
+#define rcdev_to_unit(rcdev) container_of(rcdev, struct mmp_clk_reset_unit, rcdev)
+
+static int mmp_of_reset_xlate(struct reset_controller_dev *rcdev,
+                         const struct of_phandle_args *reset_spec)
+{
+       struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+       struct mmp_clk_reset_cell *cell;
+       int i;
+
+       if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells))
+               return -EINVAL;
+
+       for (i = 0; i < rcdev->nr_resets; i++) {
+               cell = &unit->cells[i];
+               if (cell->clk_id == reset_spec->args[0])
+                       break;
+       }
+
+       if (i == rcdev->nr_resets)
+               return -EINVAL;
+
+       return i;
+}
+
+static int mmp_clk_reset_assert(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+       struct mmp_clk_reset_cell *cell;
+       unsigned long flags = 0;
+       u32 val;
+
+       cell = &unit->cells[id];
+       if (cell->lock)
+               spin_lock_irqsave(cell->lock, flags);
+
+       val = readl(cell->reg);
+       val |= cell->bits;
+       writel(val, cell->reg);
+
+       if (cell->lock)
+               spin_unlock_irqrestore(cell->lock, flags);
+
+       return 0;
+}
+
+static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev,
+                               unsigned long id)
+{
+       struct mmp_clk_reset_unit *unit = rcdev_to_unit(rcdev);
+       struct mmp_clk_reset_cell *cell;
+       unsigned long flags = 0;
+       u32 val;
+
+       cell = &unit->cells[id];
+       if (cell->lock)
+               spin_lock_irqsave(cell->lock, flags);
+
+       val = readl(cell->reg);
+       val &= ~cell->bits;
+       writel(val, cell->reg);
+
+       if (cell->lock)
+               spin_unlock_irqrestore(cell->lock, flags);
+
+       return 0;
+}
+
+static struct reset_control_ops mmp_clk_reset_ops = {
+       .assert         = mmp_clk_reset_assert,
+       .deassert       = mmp_clk_reset_deassert,
+};
+
+void mmp_clk_reset_register(struct device_node *np,
+                       struct mmp_clk_reset_cell *cells, int nr_resets)
+{
+       struct mmp_clk_reset_unit *unit;
+
+       unit = kzalloc(sizeof(*unit), GFP_KERNEL);
+       if (!unit)
+               return;
+
+       unit->cells = cells;
+       unit->rcdev.of_reset_n_cells = 1;
+       unit->rcdev.nr_resets = nr_resets;
+       unit->rcdev.ops = &mmp_clk_reset_ops;
+       unit->rcdev.of_node = np;
+       unit->rcdev.of_xlate = mmp_of_reset_xlate;
+
+       reset_controller_register(&unit->rcdev);
+}
diff --git a/drivers/clk/mmp/reset.h b/drivers/clk/mmp/reset.h
new file mode 100644 (file)
index 0000000..be8b1a7
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __MACH_MMP_CLK_RESET_H
+#define __MACH_MMP_CLK_RESET_H
+
+#include <linux/reset-controller.h>
+
+#define MMP_RESET_INVERT       1
+
+struct mmp_clk_reset_cell {
+       unsigned int clk_id;
+       void __iomem *reg;
+       u32 bits;
+       unsigned int flags;
+       spinlock_t *lock;
+};
+
+struct mmp_clk_reset_unit {
+       struct reset_controller_dev rcdev;
+       struct mmp_clk_reset_cell *cells;
+};
+
+#ifdef CONFIG_RESET_CONTROLLER
+void mmp_clk_reset_register(struct device_node *np,
+                       struct mmp_clk_reset_cell *cells, int nr_resets);
+#else
+static inline void mmp_clk_reset_register(struct device_node *np,
+                       struct mmp_clk_reset_cell *cells, int nr_resets)
+{
+}
+#endif
+
+#endif
index 4ff2abcd500b8e2109241b56152eeef6dd46f0e0..38e9153446059a1fb0c0728c841517cf99747f40 100644 (file)
@@ -1,2 +1,3 @@
 obj-y                          += clk-pxa.o
+obj-$(CONFIG_PXA25x)           += clk-pxa25x.o
 obj-$(CONFIG_PXA27x)           += clk-pxa27x.o
index ef3c05389c0aeb4704a6f2c2e23720eda6311a83..4e834753ab094500677811702c37ad005503929b 100644 (file)
@@ -26,12 +26,20 @@ static struct clk_onecell_data onecell_data = {
        .clk_num = CLK_MAX,
 };
 
-#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk_cken, hw)
+struct pxa_clk {
+       struct clk_hw hw;
+       struct clk_fixed_factor lp;
+       struct clk_fixed_factor hp;
+       struct clk_gate gate;
+       bool (*is_in_low_power)(void);
+};
+
+#define to_pxa_clk(_hw) container_of(_hw, struct pxa_clk, hw)
 
 static unsigned long cken_recalc_rate(struct clk_hw *hw,
                                      unsigned long parent_rate)
 {
-       struct pxa_clk_cken *pclk = to_pxa_clk(hw);
+       struct pxa_clk *pclk = to_pxa_clk(hw);
        struct clk_fixed_factor *fix;
 
        if (!pclk->is_in_low_power || pclk->is_in_low_power())
@@ -48,7 +56,7 @@ static struct clk_ops cken_rate_ops = {
 
 static u8 cken_get_parent(struct clk_hw *hw)
 {
-       struct pxa_clk_cken *pclk = to_pxa_clk(hw);
+       struct pxa_clk *pclk = to_pxa_clk(hw);
 
        if (!pclk->is_in_low_power)
                return 0;
@@ -69,29 +77,32 @@ void __init clkdev_pxa_register(int ckid, const char *con_id,
                clk_register_clkdev(clk, con_id, dev_id);
 }
 
-int __init clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks)
+int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks)
 {
        int i;
-       struct pxa_clk_cken *pclk;
+       struct pxa_clk *pxa_clk;
        struct clk *clk;
 
        for (i = 0; i < nb_clks; i++) {
-               pclk = clks + i;
-               pclk->gate.lock = &lock;
-               clk = clk_register_composite(NULL, pclk->name,
-                                            pclk->parent_names, 2,
-                                            &pclk->hw, &cken_mux_ops,
-                                            &pclk->hw, &cken_rate_ops,
-                                            &pclk->gate.hw, &clk_gate_ops,
-                                            pclk->flags);
-               clkdev_pxa_register(pclk->ckid, pclk->con_id, pclk->dev_id,
-                                   clk);
+               pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL);
+               pxa_clk->is_in_low_power = clks[i].is_in_low_power;
+               pxa_clk->lp = clks[i].lp;
+               pxa_clk->hp = clks[i].hp;
+               pxa_clk->gate = clks[i].gate;
+               pxa_clk->gate.lock = &lock;
+               clk = clk_register_composite(NULL, clks[i].name,
+                                            clks[i].parent_names, 2,
+                                            &pxa_clk->hw, &cken_mux_ops,
+                                            &pxa_clk->hw, &cken_rate_ops,
+                                            &pxa_clk->gate.hw, &clk_gate_ops,
+                                            clks[i].flags);
+               clkdev_pxa_register(clks[i].ckid, clks[i].con_id,
+                                   clks[i].dev_id, clk);
        }
        return 0;
 }
 
-static void __init pxa_dt_clocks_init(struct device_node *np)
+void __init clk_pxa_dt_common_init(struct device_node *np)
 {
        of_clk_add_provider(np, of_clk_src_onecell_get, &onecell_data);
 }
-CLK_OF_DECLARE(pxa_clks, "marvell,pxa-clocks", pxa_dt_clocks_init);
index 5fe219d06b490c49a7203dd547fe65b537089c73..323965430111943b33dad32b3e8d5a889c7dead2 100644 (file)
@@ -25,7 +25,7 @@
        static struct clk_ops name ## _rate_ops = {             \
                .recalc_rate = name ## _get_rate,               \
        };                                                      \
-       static struct clk *clk_register_ ## name(void)          \
+       static struct clk * __init clk_register_ ## name(void)  \
        {                                                       \
                return clk_register_composite(NULL, clk_name,   \
                        name ## _parents,                       \
@@ -40,7 +40,7 @@
        static struct clk_ops name ## _rate_ops = {             \
                .recalc_rate = name ## _get_rate,               \
        };                                                      \
-       static struct clk *clk_register_ ## name(void)          \
+       static struct clk * __init clk_register_ ## name(void)  \
        {                                                       \
                return clk_register_composite(NULL, clk_name,   \
                        name ## _parents,                       \
@@ -66,7 +66,7 @@
  *  |    Clock   | --- | / div_hp  |
  *  +------------+     +-----------+
  */
-struct pxa_clk_cken {
+struct desc_clk_cken {
        struct clk_hw hw;
        int ckid;
        const char *name;
@@ -102,6 +102,7 @@ static int dummy_clk_set_parent(struct clk_hw *hw, u8 index)
 
 extern void clkdev_pxa_register(int ckid, const char *con_id,
                                const char *dev_id, struct clk *clk);
-extern int clk_pxa_cken_init(struct pxa_clk_cken *clks, int nb_clks);
+extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks);
+void clk_pxa_dt_common_init(struct device_node *np);
 
 #endif
diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c
new file mode 100644 (file)
index 0000000..6cd88d9
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Marvell PXA25x family clocks
+ *
+ * Copyright (C) 2014 Robert Jarzmik
+ *
+ * Heavily inspired from former arch/arm/mach-pxa/pxa25x.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * For non-devicetree platforms. Once pxa is fully converted to devicetree, this
+ * should go away.
+ */
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <mach/pxa25x.h>
+#include <mach/pxa2xx-regs.h>
+
+#include <dt-bindings/clock/pxa-clock.h>
+#include "clk-pxa.h"
+
+#define KHz 1000
+#define MHz (1000 * 1000)
+
+enum {
+       PXA_CORE_RUN = 0,
+       PXA_CORE_TURBO,
+};
+
+/*
+ * Various clock factors driven by the CCCR register.
+ */
+
+/* Crystal Frequency to Memory Frequency Multiplier (L) */
+static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
+
+/* Memory Frequency to Run Mode Frequency Multiplier (M) */
+static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
+
+/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
+/* Note: we store the value N * 2 here. */
+static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
+
+static const char * const get_freq_khz[] = {
+       "core", "run", "cpll", "memory"
+};
+
+/*
+ * Get the clock frequency as reflected by CCCR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa25x_get_clk_frequency_khz(int info)
+{
+       struct clk *clk;
+       unsigned long clks[5];
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(get_freq_khz); i++) {
+               clk = clk_get(NULL, get_freq_khz[i]);
+               if (IS_ERR(clk)) {
+                       clks[i] = 0;
+               } else {
+                       clks[i] = clk_get_rate(clk);
+                       clk_put(clk);
+               }
+       }
+
+       if (info) {
+               pr_info("Run Mode clock: %ld.%02ldMHz\n",
+                       clks[1] / 1000000, (clks[1] % 1000000) / 10000);
+               pr_info("Turbo Mode clock: %ld.%02ldMHz\n",
+                       clks[2] / 1000000, (clks[2] % 1000000) / 10000);
+               pr_info("Memory clock: %ld.%02ldMHz\n",
+                       clks[3] / 1000000, (clks[3] % 1000000) / 10000);
+       }
+
+       return (unsigned int)clks[0];
+}
+
+static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw,
+                                               unsigned long parent_rate)
+{
+       unsigned long cccr = CCCR;
+       unsigned int m = M_clk_mult[(cccr >> 5) & 0x03];
+
+       return parent_rate / m;
+}
+PARENTS(clk_pxa25x_memory) = { "run" };
+RATE_RO_OPS(clk_pxa25x_memory, "memory");
+
+PARENTS(pxa25x_pbus95) = { "ppll_95_85mhz", "ppll_95_85mhz" };
+PARENTS(pxa25x_pbus147) = { "ppll_147_46mhz", "ppll_147_46mhz" };
+PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" };
+
+#define PXA25X_CKEN(dev_id, con_id, parents, mult, div,                        \
+                   bit, is_lp, flags)                                  \
+       PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div,    \
+                is_lp,  &CKEN, CKEN_ ## bit, flags)
+#define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)        \
+       PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp,     \
+                   div_hp, bit, NULL, 0)
+#define PXA25X_PBUS147_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)\
+       PXA25X_CKEN(dev_id, con_id, pxa25x_pbus147_parents, mult_hp,    \
+                   div_hp, bit, NULL, 0)
+#define PXA25X_OSC3_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay)  \
+       PXA25X_CKEN(dev_id, con_id, pxa25x_osc3_parents, mult_hp,       \
+                   div_hp, bit, NULL, 0)
+
+#define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay)         \
+       PXA_CKEN_1RATE(dev_id, con_id, bit, parents,                    \
+                      &CKEN, CKEN_ ## bit, 0)
+#define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay)      \
+       PXA_CKEN_1RATE(dev_id, con_id, bit, parents,                    \
+                      &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
+
+static struct desc_clk_cken pxa25x_clocks[] __initdata = {
+       PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0),
+       PXA25X_PBUS95_CKEN("pxa2xx-i2c.0", NULL, I2C, 1, 3, 0),
+       PXA25X_PBUS95_CKEN("pxa2xx-ir", "FICPCLK", FICP, 1, 2, 0),
+       PXA25X_PBUS95_CKEN("pxa25x-udc", NULL, USB, 1, 2, 5),
+       PXA25X_PBUS147_CKEN("pxa2xx-uart.0", NULL, FFUART, 1, 10, 1),
+       PXA25X_PBUS147_CKEN("pxa2xx-uart.1", NULL, BTUART, 1, 10, 1),
+       PXA25X_PBUS147_CKEN("pxa2xx-uart.2", NULL, STUART, 1, 10, 1),
+       PXA25X_PBUS147_CKEN("pxa2xx-uart.3", NULL, HWUART, 1, 10, 1),
+       PXA25X_PBUS147_CKEN("pxa2xx-i2s", NULL, I2S, 1, 10, 0),
+       PXA25X_PBUS147_CKEN(NULL, "AC97CLK", AC97, 1, 12, 0),
+       PXA25X_OSC3_CKEN("pxa25x-ssp.0", NULL, SSP, 1, 1, 0),
+       PXA25X_OSC3_CKEN("pxa25x-nssp.1", NULL, NSSP, 1, 1, 0),
+       PXA25X_OSC3_CKEN("pxa25x-nssp.2", NULL, ASSP, 1, 1, 0),
+       PXA25X_OSC3_CKEN("pxa25x-pwm.0", NULL, PWM0, 1, 1, 0),
+       PXA25X_OSC3_CKEN("pxa25x-pwm.1", NULL, PWM1, 1, 1, 0),
+
+       PXA25X_CKEN_1RATE("pxa2xx-fb", NULL, LCD, clk_pxa25x_memory_parents, 0),
+       PXA25X_CKEN_1RATE_AO("pxa2xx-pcmcia", NULL, MEMC,
+                            clk_pxa25x_memory_parents, 0),
+};
+
+static u8 clk_pxa25x_core_get_parent(struct clk_hw *hw)
+{
+       unsigned long clkcfg;
+       unsigned int t;
+
+       asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
+       t  = clkcfg & (1 << 0);
+       if (t)
+               return PXA_CORE_TURBO;
+       return PXA_CORE_RUN;
+}
+
+static unsigned long clk_pxa25x_core_get_rate(struct clk_hw *hw,
+                                             unsigned long parent_rate)
+{
+       return parent_rate;
+}
+PARENTS(clk_pxa25x_core) = { "run", "cpll" };
+MUX_RO_RATE_RO_OPS(clk_pxa25x_core, "core");
+
+static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw,
+                                            unsigned long parent_rate)
+{
+       unsigned long cccr = CCCR;
+       unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07];
+
+       return (parent_rate / n2) * 2;
+}
+PARENTS(clk_pxa25x_run) = { "cpll" };
+RATE_RO_OPS(clk_pxa25x_run, "run");
+
+static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw,
+       unsigned long parent_rate)
+{
+       unsigned long clkcfg, cccr = CCCR;
+       unsigned int l, m, n2, t;
+
+       asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg));
+       t = clkcfg & (1 << 0);
+       l  =  L_clk_mult[(cccr >> 0) & 0x1f];
+       m = M_clk_mult[(cccr >> 5) & 0x03];
+       n2 = N2_clk_mult[(cccr >> 7) & 0x07];
+
+       if (t)
+               return m * l * n2 * parent_rate / 2;
+       return m * l * parent_rate;
+}
+PARENTS(clk_pxa25x_cpll) = { "osc_3_6864mhz" };
+RATE_RO_OPS(clk_pxa25x_cpll, "cpll");
+
+static void __init pxa25x_register_core(void)
+{
+       clk_register_clk_pxa25x_cpll();
+       clk_register_clk_pxa25x_run();
+       clkdev_pxa_register(CLK_CORE, "core", NULL,
+                           clk_register_clk_pxa25x_core());
+}
+
+static void __init pxa25x_register_plls(void)
+{
+       clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL,
+                               CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
+                               3686400);
+       clk_register_fixed_rate(NULL, "osc_32_768khz", NULL,
+                               CLK_GET_RATE_NOCACHE | CLK_IS_ROOT,
+                               32768);
+       clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0);
+       clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz",
+                                 0, 26, 1);
+       clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz",
+                                 0, 40, 1);
+}
+
+static void __init pxa25x_base_clocks_init(void)
+{
+       pxa25x_register_plls();
+       pxa25x_register_core();
+       clk_register_clk_pxa25x_memory();
+}
+
+#define DUMMY_CLK(_con_id, _dev_id, _parent) \
+       { .con_id = _con_id, .dev_id = _dev_id, .parent = _parent }
+struct dummy_clk {
+       const char *con_id;
+       const char *dev_id;
+       const char *parent;
+};
+static struct dummy_clk dummy_clks[] __initdata = {
+       DUMMY_CLK(NULL, "pxa25x-gpio", "osc_32_768khz"),
+       DUMMY_CLK(NULL, "pxa26x-gpio", "osc_32_768khz"),
+       DUMMY_CLK("GPIO11_CLK", NULL, "osc_3_6864mhz"),
+       DUMMY_CLK("GPIO12_CLK", NULL, "osc_32_768khz"),
+       DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"),
+       DUMMY_CLK("OSTIMER0", NULL, "osc_32_768khz"),
+       DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"),
+};
+
+static void __init pxa25x_dummy_clocks_init(void)
+{
+       struct clk *clk;
+       struct dummy_clk *d;
+       const char *name;
+       int i;
+
+       /*
+        * All pinctrl logic has been wiped out of the clock driver, especially
+        * for gpio11 and gpio12 outputs. Machine code should ensure proper pin
+        * control (ie. pxa2xx_mfp_config() invocation).
+        */
+       for (i = 0; i < ARRAY_SIZE(dummy_clks); i++) {
+               d = &dummy_clks[i];
+               name = d->dev_id ? d->dev_id : d->con_id;
+               clk = clk_register_fixed_factor(NULL, name, d->parent, 0, 1, 1);
+               clk_register_clkdev(clk, d->con_id, d->dev_id);
+       }
+}
+
+int __init pxa25x_clocks_init(void)
+{
+       pxa25x_base_clocks_init();
+       pxa25x_dummy_clocks_init();
+       return clk_pxa_cken_init(pxa25x_clocks, ARRAY_SIZE(pxa25x_clocks));
+}
+
+static void __init pxa25x_dt_clocks_init(struct device_node *np)
+{
+       pxa25x_clocks_init();
+       clk_pxa_dt_common_init(np);
+}
+CLK_OF_DECLARE(pxa25x_clks, "marvell,pxa250-core-clocks",
+              pxa25x_dt_clocks_init);
index b345cc791e5defdeeb57d0b8df4d566bd41aef2c..bb8dfbc747bae16a1dee294edc7419ef4ad0c307 100644 (file)
@@ -111,7 +111,7 @@ PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" };
        PXA_CKEN_1RATE(dev_id, con_id, bit, parents,                    \
                       &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED)
 
-static struct pxa_clk_cken pxa27x_clocks[] = {
+static struct desc_clk_cken pxa27x_clocks[] __initdata = {
        PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1),
        PXA27X_PBUS_CKEN("pxa2xx-uart.1", NULL, BTUART, 2, 42, 1),
        PXA27X_PBUS_CKEN("pxa2xx-uart.2", NULL, STUART, 2, 42, 1),
@@ -368,3 +368,10 @@ static int __init pxa27x_clocks_init(void)
        return clk_pxa_cken_init(pxa27x_clocks, ARRAY_SIZE(pxa27x_clocks));
 }
 postcore_initcall(pxa27x_clocks_init);
+
+static void __init pxa27x_dt_clocks_init(struct device_node *np)
+{
+       pxa27x_clocks_init();
+       clk_pxa_dt_common_init(np);
+}
+CLK_OF_DECLARE(pxa_clks, "marvell,pxa270-clocks", pxa27x_dt_clocks_init);
index beed49c79126bb1412cf7b217586aa8c0b6e532d..f88eb7dacd9730028f881f03825897b3ad807318 100644 (file)
@@ -257,9 +257,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
        GATE(0, "hclk_vdpu", "aclk_vdpu", 0,
                        RK2928_CLKGATE_CON(3), 12, GFLAGS),
 
-       GATE(0, "gpll_ddr", "gpll", 0,
+       GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(1), 7, GFLAGS),
-       COMPOSITE(0, "ddrphy", mux_ddrphy_p, 0,
+       COMPOSITE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED,
                        RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
                        RK2928_CLKGATE_CON(0), 2, GFLAGS),
 
@@ -270,10 +270,10 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
                        RK2928_CLKGATE_CON(0), 6, GFLAGS),
        GATE(0, "pclk_cpu", "pclk_cpu_pre", 0,
                        RK2928_CLKGATE_CON(0), 5, GFLAGS),
-       GATE(0, "hclk_cpu", "hclk_cpu_pre", 0,
+       GATE(0, "hclk_cpu", "hclk_cpu_pre", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(0), 4, GFLAGS),
 
-       COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, 0,
+       COMPOSITE(0, "aclk_lcdc0_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
                        RK2928_CLKSEL_CON(31), 7, 1, MFLAGS, 0, 5, DFLAGS,
                        RK2928_CLKGATE_CON(3), 0, GFLAGS),
        COMPOSITE(0, "aclk_lcdc1_pre", mux_pll_src_cpll_gpll_p, 0,
@@ -304,9 +304,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
         * the 480m are generated inside the usb block from these clocks,
         * but they are also a source for the hsicphy clock.
         */
-       GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0,
+       GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(1), 5, GFLAGS),
-       GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0,
+       GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(1), 6, GFLAGS),
 
        COMPOSITE(0, "mac_src", mux_mac_p, 0,
@@ -320,9 +320,9 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
        COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0,
                        RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS,
                        RK2928_CLKGATE_CON(2), 6, GFLAGS),
-       COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src",
+       COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0,
                        RK2928_CLKSEL_CON(23), 0,
-                       RK2928_CLKGATE_CON(2), 7, 0, GFLAGS),
+                       RK2928_CLKGATE_CON(2), 7, GFLAGS),
        MUX(SCLK_HSADC, "sclk_hsadc", mux_sclk_hsadc_p, 0,
                        RK2928_CLKSEL_CON(22), 4, 2, MFLAGS),
 
@@ -399,8 +399,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 
        /* aclk_cpu gates */
        GATE(ACLK_DMA1, "aclk_dma1", "aclk_cpu", 0, RK2928_CLKGATE_CON(5), 0, GFLAGS),
-       GATE(0, "aclk_intmem", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 12, GFLAGS),
-       GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK2928_CLKGATE_CON(4), 10, GFLAGS),
+       GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS),
+       GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS),
 
        /* hclk_cpu gates */
        GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS),
@@ -416,8 +416,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
        GATE(HCLK_RGA, "hclk_rga", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 10, GFLAGS),
 
        /* hclk_peri gates */
-       GATE(0, "hclk_peri_axi_matrix", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 0, GFLAGS),
-       GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 6, GFLAGS),
+       GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
+       GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS),
        GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS),
        GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
        GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
@@ -457,18 +457,18 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
        GATE(0, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
        GATE(0, "pclk_ddrpubl", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS),
        GATE(0, "pclk_dbg", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 1, GFLAGS),
-       GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS),
-       GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 5, GFLAGS),
+       GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS),
+       GATE(PCLK_PMU, "pclk_pmu", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 5, GFLAGS),
 
        /* aclk_peri */
        GATE(ACLK_DMA2, "aclk_dma2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
        GATE(ACLK_SMC, "aclk_smc", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 8, GFLAGS),
-       GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 4, GFLAGS),
-       GATE(0, "aclk_cpu_peri", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 2, GFLAGS),
-       GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK2928_CLKGATE_CON(4), 3, GFLAGS),
+       GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 4, GFLAGS),
+       GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
+       GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS),
 
        /* pclk_peri gates */
-       GATE(0, "pclk_peri_axi_matrix", "pclk_peri", 0, RK2928_CLKGATE_CON(4), 1, GFLAGS),
+       GATE(0, "pclk_peri_axi_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
        GATE(PCLK_PWM23, "pclk_pwm23", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 11, GFLAGS),
        GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
        GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
@@ -511,7 +511,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
                                                            | CLK_DIVIDER_READ_ONLY,
                        RK2928_CLKGATE_CON(4), 9, GFLAGS),
 
-       GATE(CORE_L2C, "core_l2c", "aclk_cpu", 0,
+       GATE(CORE_L2C, "core_l2c", "aclk_cpu", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(9), 4, GFLAGS),
 
        COMPOSITE(0, "aclk_peri_pre", mux_pll_src_gpll_cpll_p, 0,
@@ -618,7 +618,7 @@ PNAME(mux_hsicphy_p)                = { "sclk_otgphy0", "sclk_otgphy1",
                                    "gpll", "cpll" };
 
 static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
-       COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", 0,
+       COMPOSITE_NOMUX_DIVTBL(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED,
                        RK2928_CLKSEL_CON(1), 3, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        div_rk3188_aclk_core_t, RK2928_CLKGATE_CON(0), 7, GFLAGS),
 
@@ -633,7 +633,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
                        RK2928_CLKSEL_CON(1), 14, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
                        RK2928_CLKGATE_CON(4), 9, GFLAGS),
 
-       GATE(CORE_L2C, "core_l2c", "armclk", 0,
+       GATE(CORE_L2C, "core_l2c", "armclk", CLK_IGNORE_UNUSED,
                        RK2928_CLKGATE_CON(9), 4, GFLAGS),
 
        COMPOSITE(0, "aclk_peri_pre", mux_pll_src_cpll_gpll_p, 0,
index 23278291da448de806a9a8929fe300c6952aafec..174589c95e33fcb5de8eb78689bbd2bb4895cea6 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/syscore_ops.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include "clk.h"
 
@@ -83,11 +84,13 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = {
        RK3066_PLL_RATE( 742500000, 8, 495, 2),
        RK3066_PLL_RATE( 696000000, 1, 58, 2),
        RK3066_PLL_RATE( 600000000, 1, 50, 2),
-       RK3066_PLL_RATE( 594000000, 2, 198, 4),
+       RK3066_PLL_RATE_BWADJ(594000000, 1, 198, 8, 1),
        RK3066_PLL_RATE( 552000000, 1, 46, 2),
        RK3066_PLL_RATE( 504000000, 1, 84, 4),
+       RK3066_PLL_RATE( 500000000, 3, 125, 2),
        RK3066_PLL_RATE( 456000000, 1, 76, 4),
        RK3066_PLL_RATE( 408000000, 1, 68, 4),
+       RK3066_PLL_RATE( 400000000, 3, 100, 2),
        RK3066_PLL_RATE( 384000000, 2, 128, 4),
        RK3066_PLL_RATE( 360000000, 1, 60, 4),
        RK3066_PLL_RATE( 312000000, 1, 52, 4),
@@ -173,14 +176,14 @@ PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu" };
 PNAME(mux_pll_src_cpll_gpll_p)         = { "cpll", "gpll" };
 PNAME(mux_pll_src_npll_cpll_gpll_p)    = { "npll", "cpll", "gpll" };
 PNAME(mux_pll_src_cpll_gpll_npll_p)    = { "cpll", "gpll", "npll" };
-PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usb480m" };
+PNAME(mux_pll_src_cpll_gpll_usb480m_p) = { "cpll", "gpll", "usbphy480m_src" };
+PNAME(mux_pll_src_cpll_gll_usb_npll_p) = { "cpll", "gpll", "usbphy480m_src", "npll" };
 
 PNAME(mux_mmc_src_p)   = { "cpll", "gpll", "xin24m", "xin24m" };
 PNAME(mux_i2s_pre_p)   = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
 PNAME(mux_i2s_clkout_p)        = { "i2s_pre", "xin12m" };
 PNAME(mux_spdif_p)     = { "spdif_pre", "spdif_frac", "xin12m" };
 PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "xin12m" };
-PNAME(mux_uart0_pll_p) = { "cpll", "gpll", "usbphy_480m_src", "npll" };
 PNAME(mux_uart0_p)     = { "uart0_src", "uart0_frac", "xin24m" };
 PNAME(mux_uart1_p)     = { "uart1_src", "uart1_frac", "xin24m" };
 PNAME(mux_uart2_p)     = { "uart2_src", "uart2_frac", "xin24m" };
@@ -192,8 +195,8 @@ PNAME(mux_hsadcout_p)       = { "hsadc_src", "ext_hsadc" };
 PNAME(mux_edp_24m_p)   = { "ext_edp_24m", "xin24m" };
 PNAME(mux_tspout_p)    = { "cpll", "gpll", "npll", "xin27m" };
 
-PNAME(mux_usbphy480m_p)                = { "sclk_otgphy0", "sclk_otgphy1",
-                                   "sclk_otgphy2" };
+PNAME(mux_usbphy480m_p)                = { "sclk_otgphy1", "sclk_otgphy2",
+                                   "sclk_otgphy0" };
 PNAME(mux_hsicphy480m_p)       = { "cpll", "gpll", "usbphy480m_src" };
 PNAME(mux_hsicphy12m_p)                = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" };
 
@@ -226,67 +229,67 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
         * Clock-Architecture Diagram 1
         */
 
-       GATE(0, "apll_core", "apll", 0,
+       GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 1, GFLAGS),
-       GATE(0, "gpll_core", "gpll", 0,
+       GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 2, GFLAGS),
 
-       COMPOSITE_NOMUX(0, "armcore0", "armclk", 0,
+       COMPOSITE_NOMUX(0, "armcore0", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(36), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 0, GFLAGS),
-       COMPOSITE_NOMUX(0, "armcore1", "armclk", 0,
+       COMPOSITE_NOMUX(0, "armcore1", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(36), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 1, GFLAGS),
-       COMPOSITE_NOMUX(0, "armcore2", "armclk", 0,
+       COMPOSITE_NOMUX(0, "armcore2", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(36), 8, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 2, GFLAGS),
-       COMPOSITE_NOMUX(0, "armcore3", "armclk", 0,
+       COMPOSITE_NOMUX(0, "armcore3", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(36), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 3, GFLAGS),
-       COMPOSITE_NOMUX(0, "l2ram", "armclk", 0,
+       COMPOSITE_NOMUX(0, "l2ram", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(37), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 4, GFLAGS),
-       COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", 0,
+       COMPOSITE_NOMUX(0, "aclk_core_m0", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(0), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 5, GFLAGS),
-       COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", 0,
+       COMPOSITE_NOMUX(0, "aclk_core_mp", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(0), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 6, GFLAGS),
        COMPOSITE_NOMUX(0, "atclk", "armclk", 0,
                        RK3288_CLKSEL_CON(37), 4, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 7, GFLAGS),
-       COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", 0,
+       COMPOSITE_NOMUX(0, "pclk_dbg_pre", "armclk", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(37), 9, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
                        RK3288_CLKGATE_CON(12), 8, GFLAGS),
        GATE(0, "pclk_dbg", "pclk_dbg_pre", 0,
                        RK3288_CLKGATE_CON(12), 9, GFLAGS),
-       GATE(0, "cs_dbg", "pclk_dbg_pre", 0,
+       GATE(0, "cs_dbg", "pclk_dbg_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(12), 10, GFLAGS),
        GATE(0, "pclk_core_niu", "pclk_dbg_pre", 0,
                        RK3288_CLKGATE_CON(12), 11, GFLAGS),
 
-       GATE(0, "dpll_ddr", "dpll", 0,
+       GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 8, GFLAGS),
        GATE(0, "gpll_ddr", "gpll", 0,
                        RK3288_CLKGATE_CON(0), 9, GFLAGS),
-       COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, 0,
+       COMPOSITE_NOGATE(0, "ddrphy", mux_ddrphy_p, CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(26), 2, 1, MFLAGS, 0, 2,
                                        DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
 
-       GATE(0, "gpll_aclk_cpu", "gpll", 0,
+       GATE(0, "gpll_aclk_cpu", "gpll", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 10, GFLAGS),
-       GATE(0, "cpll_aclk_cpu", "cpll", 0,
+       GATE(0, "cpll_aclk_cpu", "cpll", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 11, GFLAGS),
-       COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, 0,
+       COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_aclk_cpu_src_p, CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(1), 15, 1, MFLAGS, 3, 5, DFLAGS),
-       DIV(0, "aclk_cpu_pre", "aclk_cpu_src", 0,
+       DIV(0, "aclk_cpu_pre", "aclk_cpu_src", CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(1), 0, 3, DFLAGS),
-       GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", 0,
+       GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 3, GFLAGS),
-       COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", 0,
+       COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(1), 12, 3, DFLAGS,
                        RK3288_CLKGATE_CON(0), 5, GFLAGS),
-       COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", 0,
+       COMPOSITE_NOMUX_DIVTBL(HCLK_CPU, "hclk_cpu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(1), 8, 2, DFLAGS, div_hclk_cpu_t,
                        RK3288_CLKGATE_CON(0), 4, GFLAGS),
        GATE(0, "c2c_host", "aclk_cpu_src", 0,
@@ -294,7 +297,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0,
                        RK3288_CLKSEL_CON(26), 6, 2, DFLAGS,
                        RK3288_CLKGATE_CON(5), 4, GFLAGS),
-       GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", 0,
+       GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(0), 7, GFLAGS),
 
        COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0,
@@ -305,7 +308,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
                        RK3288_CLKGATE_CON(4), 2, GFLAGS),
        MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
                        RK3288_CLKSEL_CON(4), 8, 2, MFLAGS),
-       COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, CLK_SET_RATE_PARENT,
+       COMPOSITE_NODIV(0, "i2s0_clkout", mux_i2s_clkout_p, 0,
                        RK3288_CLKSEL_CON(4), 12, 1, MFLAGS,
                        RK3288_CLKGATE_CON(4), 0, GFLAGS),
        GATE(SCLK_I2S0, "sclk_i2s0", "i2s_pre", CLK_SET_RATE_PARENT,
@@ -325,7 +328,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0,
                        RK3288_CLKSEL_CON(40), 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(4), 7, GFLAGS),
-       COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", 0,
+       COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0,
                        RK3288_CLKSEL_CON(41), 0,
                        RK3288_CLKGATE_CON(4), 8, GFLAGS),
        COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0,
@@ -373,12 +376,12 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0,
                RK3288_CLKGATE_CON(9), 1, GFLAGS),
 
-       COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, 0,
+       COMPOSITE(0, "aclk_vio0", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(31), 6, 2, MFLAGS, 0, 5, DFLAGS,
                        RK3288_CLKGATE_CON(3), 0, GFLAGS),
        DIV(0, "hclk_vio", "aclk_vio0", 0,
                        RK3288_CLKSEL_CON(28), 8, 5, DFLAGS),
-       COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, 0,
+       COMPOSITE(0, "aclk_vio1", mux_pll_src_cpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
                        RK3288_CLKGATE_CON(3), 2, GFLAGS),
 
@@ -436,24 +439,24 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 
        DIV(0, "pclk_pd_alive", "gpll", 0,
                        RK3288_CLKSEL_CON(33), 8, 5, DFLAGS),
-       COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", 0,
+       COMPOSITE_NOMUX(0, "pclk_pd_pmu", "gpll", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(33), 0, 5, DFLAGS,
                        RK3288_CLKGATE_CON(5), 8, GFLAGS),
 
-       COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gpll_usb480m_p, 0,
+       COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_cpll_gll_usb_npll_p, 0,
                        RK3288_CLKSEL_CON(34), 6, 2, MFLAGS, 0, 5, DFLAGS,
                        RK3288_CLKGATE_CON(5), 7, GFLAGS),
 
-       COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, 0,
+       COMPOSITE(0, "aclk_peri_src", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(10), 15, 1, MFLAGS, 0, 5, DFLAGS,
                        RK3288_CLKGATE_CON(2), 0, GFLAGS),
        COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "aclk_peri_src", 0,
                        RK3288_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
                        RK3288_CLKGATE_CON(2), 3, GFLAGS),
-       COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", 0,
+       COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED,
                        RK3288_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
                        RK3288_CLKGATE_CON(2), 2, GFLAGS),
-       GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
+       GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(2), 1, GFLAGS),
 
        /*
@@ -490,13 +493,13 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
                        RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
                        RK3288_CLKGATE_CON(4), 10, GFLAGS),
 
-       GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", 0,
+       GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(13), 4, GFLAGS),
-       GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", 0,
+       GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(13), 5, GFLAGS),
-       GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", 0,
+       GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(13), 6, GFLAGS),
-       GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", 0,
+       GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED,
                        RK3288_CLKGATE_CON(13), 7, GFLAGS),
 
        COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin32k", 0,
@@ -517,7 +520,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
                        RK3288_CLKSEL_CON(38), 15, 1, MFLAGS, 8, 5, DFLAGS,
                        RK3288_CLKGATE_CON(5), 6, GFLAGS),
 
-       COMPOSITE(0, "uart0_src", mux_uart0_pll_p, 0,
+       COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
                        RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
                        RK3288_CLKGATE_CON(1), 8, GFLAGS),
        COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0,
@@ -585,7 +588,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 
        COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0,
                        RK3288_CLKSEL_CON(13), 11, 2, MFLAGS,
-                       RK3288_CLKGATE_CON(5), 15, GFLAGS),
+                       RK3288_CLKGATE_CON(5), 14, GFLAGS),
        COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
                        RK3288_CLKSEL_CON(29), 0, 2, MFLAGS,
                        RK3288_CLKGATE_CON(3), 6, GFLAGS),
@@ -601,19 +604,19 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
         */
 
        /* aclk_cpu gates */
-       GATE(0, "sclk_intmem0", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 5, GFLAGS),
-       GATE(0, "sclk_intmem1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 6, GFLAGS),
-       GATE(0, "sclk_intmem2", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 7, GFLAGS),
+       GATE(0, "sclk_intmem0", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 5, GFLAGS),
+       GATE(0, "sclk_intmem1", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 6, GFLAGS),
+       GATE(0, "sclk_intmem2", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 7, GFLAGS),
        GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 12, GFLAGS),
-       GATE(0, "aclk_strc_sys", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 13, GFLAGS),
-       GATE(0, "aclk_intmem", "aclk_cpu", 0, RK3288_CLKGATE_CON(10), 4, GFLAGS),
+       GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 13, GFLAGS),
+       GATE(0, "aclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 4, GFLAGS),
        GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 6, GFLAGS),
        GATE(0, "aclk_ccp", "aclk_cpu", 0, RK3288_CLKGATE_CON(11), 8, GFLAGS),
 
        /* hclk_cpu gates */
        GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK3288_CLKGATE_CON(11), 7, GFLAGS),
        GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 8, GFLAGS),
-       GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 9, GFLAGS),
+       GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(10), 9, GFLAGS),
        GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 10, GFLAGS),
        GATE(HCLK_SPDIF8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK3288_CLKGATE_CON(10), 11, GFLAGS),
 
@@ -630,34 +633,34 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        GATE(PCLK_TZPC, "pclk_tzpc", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 3, GFLAGS),
        GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 9, GFLAGS),
        GATE(0, "pclk_efuse_256", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 10, GFLAGS),
-       GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", 0, RK3288_CLKGATE_CON(11), 11, GFLAGS),
+       GATE(PCLK_RKPWM, "pclk_rkpwm", "pclk_cpu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 11, GFLAGS),
 
        /* ddrctrl [DDR Controller PHY clock] gates */
-       GATE(0, "nclk_ddrupctl0", "ddrphy", 0, RK3288_CLKGATE_CON(11), 4, GFLAGS),
-       GATE(0, "nclk_ddrupctl1", "ddrphy", 0, RK3288_CLKGATE_CON(11), 5, GFLAGS),
+       GATE(0, "nclk_ddrupctl0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 4, GFLAGS),
+       GATE(0, "nclk_ddrupctl1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(11), 5, GFLAGS),
 
        /* ddrphy gates */
-       GATE(0, "sclk_ddrphy0", "ddrphy", 0, RK3288_CLKGATE_CON(4), 12, GFLAGS),
-       GATE(0, "sclk_ddrphy1", "ddrphy", 0, RK3288_CLKGATE_CON(4), 13, GFLAGS),
+       GATE(0, "sclk_ddrphy0", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 12, GFLAGS),
+       GATE(0, "sclk_ddrphy1", "ddrphy", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(4), 13, GFLAGS),
 
        /* aclk_peri gates */
-       GATE(0, "aclk_peri_axi_matrix", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 2, GFLAGS),
+       GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 2, GFLAGS),
        GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK3288_CLKGATE_CON(6), 3, GFLAGS),
-       GATE(0, "aclk_peri_niu", "aclk_peri", 0, RK3288_CLKGATE_CON(7), 11, GFLAGS),
-       GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 12, GFLAGS),
+       GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 11, GFLAGS),
+       GATE(ACLK_MMU, "aclk_mmu", "aclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(8), 12, GFLAGS),
        GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 0, GFLAGS),
        GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK3288_CLKGATE_CON(8), 2, GFLAGS),
 
        /* hclk_peri gates */
-       GATE(0, "hclk_peri_matrix", "hclk_peri", 0, RK3288_CLKGATE_CON(6), 0, GFLAGS),
-       GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 4, GFLAGS),
+       GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 0, GFLAGS),
+       GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 4, GFLAGS),
        GATE(HCLK_USBHOST0, "hclk_host0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 6, GFLAGS),
-       GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 7, GFLAGS),
+       GATE(HCLK_USBHOST1, "hclk_host1", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 7, GFLAGS),
        GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 8, GFLAGS),
-       GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 9, GFLAGS),
-       GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 10, GFLAGS),
-       GATE(0, "hclk_emem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 12, GFLAGS),
-       GATE(0, "hclk_mem", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 13, GFLAGS),
+       GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 9, GFLAGS),
+       GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 10, GFLAGS),
+       GATE(0, "hclk_emem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 12, GFLAGS),
+       GATE(0, "hclk_mem", "hclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(7), 13, GFLAGS),
        GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 14, GFLAGS),
        GATE(HCLK_NANDC1, "hclk_nandc1", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 15, GFLAGS),
        GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK3288_CLKGATE_CON(8), 8, GFLAGS),
@@ -669,7 +672,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        GATE(0, "pmu_hclk_otg0", "hclk_peri", 0, RK3288_CLKGATE_CON(7), 5, GFLAGS),
 
        /* pclk_peri gates */
-       GATE(0, "pclk_peri_matrix", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 1, GFLAGS),
+       GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(6), 1, GFLAGS),
        GATE(PCLK_SPI0, "pclk_spi0", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 4, GFLAGS),
        GATE(PCLK_SPI1, "pclk_spi1", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 5, GFLAGS),
        GATE(PCLK_SPI2, "pclk_spi2", "pclk_peri", 0, RK3288_CLKGATE_CON(6), 6, GFLAGS),
@@ -705,48 +708,48 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
        GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 4, GFLAGS),
        GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 5, GFLAGS),
        GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 6, GFLAGS),
-       GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 11, GFLAGS),
-       GATE(0, "pclk_alive_niu", "pclk_pd_alive", 0, RK3288_CLKGATE_CON(14), 12, GFLAGS),
+       GATE(PCLK_GRF, "pclk_grf", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 11, GFLAGS),
+       GATE(0, "pclk_alive_niu", "pclk_pd_alive", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(14), 12, GFLAGS),
 
        /* pclk_pd_pmu gates */
-       GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 0, GFLAGS),
-       GATE(0, "pclk_intmem1", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 1, GFLAGS),
-       GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 2, GFLAGS),
-       GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 3, GFLAGS),
+       GATE(PCLK_PMU, "pclk_pmu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 0, GFLAGS),
+       GATE(0, "pclk_intmem1", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 1, GFLAGS),
+       GATE(0, "pclk_pmu_niu", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 2, GFLAGS),
+       GATE(PCLK_SGRF, "pclk_sgrf", "pclk_pd_pmu", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(17), 3, GFLAGS),
        GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pd_pmu", 0, RK3288_CLKGATE_CON(17), 4, GFLAGS),
 
        /* hclk_vio gates */
        GATE(HCLK_RGA, "hclk_rga", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 1, GFLAGS),
        GATE(HCLK_VOP0, "hclk_vop0", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 6, GFLAGS),
        GATE(HCLK_VOP1, "hclk_vop1", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 8, GFLAGS),
-       GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 9, GFLAGS),
-       GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 10, GFLAGS),
+       GATE(HCLK_VIO_AHB_ARBI, "hclk_vio_ahb_arbi", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 9, GFLAGS),
+       GATE(HCLK_VIO_NIU, "hclk_vio_niu", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 10, GFLAGS),
        GATE(HCLK_VIP, "hclk_vip", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 15, GFLAGS),
        GATE(HCLK_IEP, "hclk_iep", "hclk_vio", 0, RK3288_CLKGATE_CON(15), 3, GFLAGS),
        GATE(HCLK_ISP, "hclk_isp", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 1, GFLAGS),
-       GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 10, GFLAGS),
+       GATE(HCLK_VIO2_H2P, "hclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 10, GFLAGS),
        GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 4, GFLAGS),
        GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 5, GFLAGS),
        GATE(PCLK_MIPI_CSI, "pclk_mipi_csi", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 6, GFLAGS),
        GATE(PCLK_LVDS_PHY, "pclk_lvds_phy", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 7, GFLAGS),
-       GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 8, GFLAGS),
+       GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 8, GFLAGS),
        GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 9, GFLAGS),
-       GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", 0, RK3288_CLKGATE_CON(16), 11, GFLAGS),
+       GATE(PCLK_VIO2_H2P, "pclk_vio2_h2p", "hclk_vio", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(16), 11, GFLAGS),
 
        /* aclk_vio0 gates */
        GATE(ACLK_VOP0, "aclk_vop0", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 5, GFLAGS),
        GATE(ACLK_IEP, "aclk_iep", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 2, GFLAGS),
-       GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 11, GFLAGS),
+       GATE(ACLK_VIO0_NIU, "aclk_vio0_niu", "aclk_vio0", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 11, GFLAGS),
        GATE(ACLK_VIP, "aclk_vip", "aclk_vio0", 0, RK3288_CLKGATE_CON(15), 14, GFLAGS),
 
        /* aclk_vio1 gates */
        GATE(ACLK_VOP1, "aclk_vop1", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 7, GFLAGS),
        GATE(ACLK_ISP, "aclk_isp", "aclk_vio1", 0, RK3288_CLKGATE_CON(16), 2, GFLAGS),
-       GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", 0, RK3288_CLKGATE_CON(15), 12, GFLAGS),
+       GATE(ACLK_VIO1_NIU, "aclk_vio1_niu", "aclk_vio1", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 12, GFLAGS),
 
        /* aclk_rga_pre gates */
        GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 0, GFLAGS),
-       GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", 0, RK3288_CLKGATE_CON(15), 13, GFLAGS),
+       GATE(ACLK_RGA_NIU, "aclk_rga_niu", "aclk_rga_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(15), 13, GFLAGS),
 
        /*
         * Other ungrouped clocks.
@@ -762,6 +765,64 @@ static const char *rk3288_critical_clocks[] __initconst = {
        "hclk_peri",
 };
 
+#ifdef CONFIG_PM_SLEEP
+static void __iomem *rk3288_cru_base;
+
+/* Some CRU registers will be reset in maskrom when the system
+ * wakes up from fastboot.
+ * So save them before suspend, restore them after resume.
+ */
+static const int rk3288_saved_cru_reg_ids[] = {
+       RK3288_MODE_CON,
+       RK3288_CLKSEL_CON(0),
+       RK3288_CLKSEL_CON(1),
+       RK3288_CLKSEL_CON(10),
+       RK3288_CLKSEL_CON(33),
+       RK3288_CLKSEL_CON(37),
+};
+
+static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
+
+static int rk3288_clk_suspend(void)
+{
+       int i, reg_id;
+
+       for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) {
+               reg_id = rk3288_saved_cru_reg_ids[i];
+
+               rk3288_saved_cru_regs[i] =
+                               readl_relaxed(rk3288_cru_base + reg_id);
+       }
+       return 0;
+}
+
+static void rk3288_clk_resume(void)
+{
+       int i, reg_id;
+
+       for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) {
+               reg_id = rk3288_saved_cru_reg_ids[i];
+
+               writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000,
+                              rk3288_cru_base + reg_id);
+       }
+}
+
+static struct syscore_ops rk3288_clk_syscore_ops = {
+       .suspend = rk3288_clk_suspend,
+       .resume = rk3288_clk_resume,
+};
+
+static void rk3288_clk_sleep_init(void __iomem *reg_base)
+{
+       rk3288_cru_base = reg_base;
+       register_syscore_ops(&rk3288_clk_syscore_ops);
+}
+
+#else /* CONFIG_PM_SLEEP */
+static void rk3288_clk_sleep_init(void __iomem *reg_base) {}
+#endif
+
 static void __init rk3288_clk_init(struct device_node *np)
 {
        void __iomem *reg_base;
@@ -810,5 +871,6 @@ static void __init rk3288_clk_init(struct device_node *np)
                                  ROCKCHIP_SOFTRST_HIWORD_MASK);
 
        rockchip_register_restart_notifier(RK3288_GLB_SRST_FST);
+       rk3288_clk_sleep_init(reg_base);
 }
 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
index 1e68bff481b8e32ec440959002a2467287c269da..dec6f8d6dc13acbb655e9141ea250a2a91bca92d 100644 (file)
@@ -246,9 +246,6 @@ void __init rockchip_clk_register_branches(
                                        list->div_flags, &clk_lock);
                        break;
                case branch_fraction_divider:
-                       /* keep all gates untouched for now */
-                       flags |= CLK_IGNORE_UNUSED;
-
                        clk = rockchip_clk_register_frac_branch(list->name,
                                list->parent_names, list->num_parents,
                                reg_base, list->muxdiv_offset, list->div_flags,
@@ -258,18 +255,12 @@ void __init rockchip_clk_register_branches(
                case branch_gate:
                        flags |= CLK_SET_RATE_PARENT;
 
-                       /* keep all gates untouched for now */
-                       flags |= CLK_IGNORE_UNUSED;
-
                        clk = clk_register_gate(NULL, list->name,
                                list->parent_names[0], flags,
                                reg_base + list->gate_offset,
                                list->gate_shift, list->gate_flags, &clk_lock);
                        break;
                case branch_composite:
-                       /* keep all gates untouched for now */
-                       flags |= CLK_IGNORE_UNUSED;
-
                        clk = rockchip_clk_register_branch(list->name,
                                list->parent_names, list->num_parents,
                                reg_base, list->muxdiv_offset, list->mux_shift,
index ca009ab0a33a28ad507d83cf9cf0de183b33a09e..6baf6655b5c383598c4eae85f48de7c079f5c6c2 100644 (file)
@@ -62,6 +62,15 @@ enum rockchip_pll_type {
        .bwadj = (_nf >> 1),                    \
 }
 
+#define RK3066_PLL_RATE_BWADJ(_rate, _nr, _nf, _no, _bw)       \
+{                                                              \
+       .rate   = _rate##U,                                     \
+       .nr = _nr,                                              \
+       .nf = _nf,                                              \
+       .no = _no,                                              \
+       .bwadj = _bw,                                           \
+}
+
 struct rockchip_pll_rate_table {
        unsigned long rate;
        unsigned int nr;
diff --git a/include/dt-bindings/clock/marvell,mmp2.h b/include/dt-bindings/clock/marvell,mmp2.h
new file mode 100644 (file)
index 0000000..591f7fb
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __DTS_MARVELL_MMP2_CLOCK_H
+#define __DTS_MARVELL_MMP2_CLOCK_H
+
+/* fixed clocks and plls */
+#define MMP2_CLK_CLK32                 1
+#define MMP2_CLK_VCTCXO                        2
+#define MMP2_CLK_PLL1                  3
+#define MMP2_CLK_PLL1_2                        8
+#define MMP2_CLK_PLL1_4                        9
+#define MMP2_CLK_PLL1_8                        10
+#define MMP2_CLK_PLL1_16               11
+#define MMP2_CLK_PLL1_3                        12
+#define MMP2_CLK_PLL1_6                        13
+#define MMP2_CLK_PLL1_12               14
+#define MMP2_CLK_PLL1_20               15
+#define MMP2_CLK_PLL2                  16
+#define MMP2_CLK_PLL2_2                        17
+#define MMP2_CLK_PLL2_4                        18
+#define MMP2_CLK_PLL2_8                        19
+#define MMP2_CLK_PLL2_16               20
+#define MMP2_CLK_PLL2_3                        21
+#define MMP2_CLK_PLL2_6                        22
+#define MMP2_CLK_PLL2_12               23
+#define MMP2_CLK_VCTCXO_2              24
+#define MMP2_CLK_VCTCXO_4              25
+#define MMP2_CLK_UART_PLL              26
+#define MMP2_CLK_USB_PLL               27
+
+/* apb periphrals */
+#define MMP2_CLK_TWSI0                 60
+#define MMP2_CLK_TWSI1                 61
+#define MMP2_CLK_TWSI2                 62
+#define MMP2_CLK_TWSI3                 63
+#define MMP2_CLK_TWSI4                 64
+#define MMP2_CLK_TWSI5                 65
+#define MMP2_CLK_GPIO                  66
+#define MMP2_CLK_KPC                   67
+#define MMP2_CLK_RTC                   68
+#define MMP2_CLK_PWM0                  69
+#define MMP2_CLK_PWM1                  70
+#define MMP2_CLK_PWM2                  71
+#define MMP2_CLK_PWM3                  72
+#define MMP2_CLK_UART0                 73
+#define MMP2_CLK_UART1                 74
+#define MMP2_CLK_UART2                 75
+#define MMP2_CLK_UART3                 76
+#define MMP2_CLK_SSP0                  77
+#define MMP2_CLK_SSP1                  78
+#define MMP2_CLK_SSP2                  79
+#define MMP2_CLK_SSP3                  80
+
+/* axi periphrals */
+#define MMP2_CLK_SDH0                  101
+#define MMP2_CLK_SDH1                  102
+#define MMP2_CLK_SDH2                  103
+#define MMP2_CLK_SDH3                  104
+#define MMP2_CLK_USB                   105
+#define MMP2_CLK_DISP0                 106
+#define MMP2_CLK_DISP0_MUX             107
+#define MMP2_CLK_DISP0_SPHY            108
+#define MMP2_CLK_DISP1                 109
+#define MMP2_CLK_DISP1_MUX             110
+#define MMP2_CLK_CCIC_ARBITER          111
+#define MMP2_CLK_CCIC0                 112
+#define MMP2_CLK_CCIC0_MIX             113
+#define MMP2_CLK_CCIC0_PHY             114
+#define MMP2_CLK_CCIC0_SPHY            115
+#define MMP2_CLK_CCIC1                 116
+#define MMP2_CLK_CCIC1_MIX             117
+#define MMP2_CLK_CCIC1_PHY             118
+#define MMP2_CLK_CCIC1_SPHY            119
+
+#define MMP2_NR_CLKS                   200
+#endif
diff --git a/include/dt-bindings/clock/marvell,pxa168.h b/include/dt-bindings/clock/marvell,pxa168.h
new file mode 100644 (file)
index 0000000..79630b9
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __DTS_MARVELL_PXA168_CLOCK_H
+#define __DTS_MARVELL_PXA168_CLOCK_H
+
+/* fixed clocks and plls */
+#define PXA168_CLK_CLK32               1
+#define PXA168_CLK_VCTCXO              2
+#define PXA168_CLK_PLL1                        3
+#define PXA168_CLK_PLL1_2              8
+#define PXA168_CLK_PLL1_4              9
+#define PXA168_CLK_PLL1_8              10
+#define PXA168_CLK_PLL1_16             11
+#define PXA168_CLK_PLL1_6              12
+#define PXA168_CLK_PLL1_12             13
+#define PXA168_CLK_PLL1_24             14
+#define PXA168_CLK_PLL1_48             15
+#define PXA168_CLK_PLL1_96             16
+#define PXA168_CLK_PLL1_13             17
+#define PXA168_CLK_PLL1_13_1_5         18
+#define PXA168_CLK_PLL1_2_1_5          19
+#define PXA168_CLK_PLL1_3_16           20
+#define PXA168_CLK_UART_PLL            27
+
+/* apb periphrals */
+#define PXA168_CLK_TWSI0               60
+#define PXA168_CLK_TWSI1               61
+#define PXA168_CLK_TWSI2               62
+#define PXA168_CLK_TWSI3               63
+#define PXA168_CLK_GPIO                        64
+#define PXA168_CLK_KPC                 65
+#define PXA168_CLK_RTC                 66
+#define PXA168_CLK_PWM0                        67
+#define PXA168_CLK_PWM1                        68
+#define PXA168_CLK_PWM2                        69
+#define PXA168_CLK_PWM3                        70
+#define PXA168_CLK_UART0               71
+#define PXA168_CLK_UART1               72
+#define PXA168_CLK_UART2               73
+#define PXA168_CLK_SSP0                        74
+#define PXA168_CLK_SSP1                        75
+#define PXA168_CLK_SSP2                        76
+#define PXA168_CLK_SSP3                        77
+#define PXA168_CLK_SSP4                        78
+
+/* axi periphrals */
+#define PXA168_CLK_DFC                 100
+#define PXA168_CLK_SDH0                        101
+#define PXA168_CLK_SDH1                        102
+#define PXA168_CLK_SDH2                        103
+#define PXA168_CLK_USB                 104
+#define PXA168_CLK_SPH                 105
+#define PXA168_CLK_DISP0               106
+#define PXA168_CLK_CCIC0               107
+#define PXA168_CLK_CCIC0_PHY           108
+#define PXA168_CLK_CCIC0_SPHY          109
+
+#define PXA168_NR_CLKS                 200
+#endif
diff --git a/include/dt-bindings/clock/marvell,pxa910.h b/include/dt-bindings/clock/marvell,pxa910.h
new file mode 100644 (file)
index 0000000..719cffb
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __DTS_MARVELL_PXA910_CLOCK_H
+#define __DTS_MARVELL_PXA910_CLOCK_H
+
+/* fixed clocks and plls */
+#define PXA910_CLK_CLK32               1
+#define PXA910_CLK_VCTCXO              2
+#define PXA910_CLK_PLL1                        3
+#define PXA910_CLK_PLL1_2              8
+#define PXA910_CLK_PLL1_4              9
+#define PXA910_CLK_PLL1_8              10
+#define PXA910_CLK_PLL1_16             11
+#define PXA910_CLK_PLL1_6              12
+#define PXA910_CLK_PLL1_12             13
+#define PXA910_CLK_PLL1_24             14
+#define PXA910_CLK_PLL1_48             15
+#define PXA910_CLK_PLL1_96             16
+#define PXA910_CLK_PLL1_13             17
+#define PXA910_CLK_PLL1_13_1_5         18
+#define PXA910_CLK_PLL1_2_1_5          19
+#define PXA910_CLK_PLL1_3_16           20
+#define PXA910_CLK_UART_PLL            27
+
+/* apb periphrals */
+#define PXA910_CLK_TWSI0               60
+#define PXA910_CLK_TWSI1               61
+#define PXA910_CLK_TWSI2               62
+#define PXA910_CLK_TWSI3               63
+#define PXA910_CLK_GPIO                        64
+#define PXA910_CLK_KPC                 65
+#define PXA910_CLK_RTC                 66
+#define PXA910_CLK_PWM0                        67
+#define PXA910_CLK_PWM1                        68
+#define PXA910_CLK_PWM2                        69
+#define PXA910_CLK_PWM3                        70
+#define PXA910_CLK_UART0               71
+#define PXA910_CLK_UART1               72
+#define PXA910_CLK_UART2               73
+#define PXA910_CLK_SSP0                        74
+#define PXA910_CLK_SSP1                        75
+
+/* axi periphrals */
+#define PXA910_CLK_DFC                 100
+#define PXA910_CLK_SDH0                        101
+#define PXA910_CLK_SDH1                        102
+#define PXA910_CLK_SDH2                        103
+#define PXA910_CLK_USB                 104
+#define PXA910_CLK_SPH                 105
+#define PXA910_CLK_DISP0               106
+#define PXA910_CLK_CCIC0               107
+#define PXA910_CLK_CCIC0_PHY           108
+#define PXA910_CLK_CCIC0_SPHY          109
+
+#define PXA910_NR_CLKS                 200
+#endif