]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'clk/clk-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 04:21:42 +0000 (15:21 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 5 Nov 2015 04:21:42 +0000 (15:21 +1100)
111 files changed:
Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/at91-clock.txt
Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt
Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/silabs,si514.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
arch/arm/mach-at91/Kconfig
arch/arm/mach-bcm/Kconfig
drivers/base/power/domain.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/Makefile
drivers/clk/at91/clk-generated.c [new file with mode: 0644]
drivers/clk/at91/clk-peripheral.c
drivers/clk/at91/clk-system.c
drivers/clk/at91/clk-utmi.c
drivers/clk/at91/pmc.c
drivers/clk/at91/pmc.h
drivers/clk/bcm/Kconfig
drivers/clk/bcm/Makefile
drivers/clk/bcm/clk-cygnus.c
drivers/clk/bcm/clk-iproc-pll.c
drivers/clk/bcm/clk-iproc.h
drivers/clk/bcm/clk-ns2.c [new file with mode: 0644]
drivers/clk/bcm/clk-nsp.c [new file with mode: 0644]
drivers/clk/berlin/bg2.c
drivers/clk/berlin/bg2q.c
drivers/clk/clk-divider.c
drivers/clk/clk-fractional-divider.c
drivers/clk/clk-max77802.c
drivers/clk/clk-multiplier.c
drivers/clk/clk-si514.c [new file with mode: 0644]
drivers/clk/clk-si5351.c
drivers/clk/clk-xgene.c
drivers/clk/clk.c
drivers/clk/hisilicon/clk-hi6220-stub.c
drivers/clk/imx/clk-imx27.c
drivers/clk/imx/clk-imx31.c
drivers/clk/imx/clk-pllv2.c
drivers/clk/keystone/pll.c
drivers/clk/mediatek/Makefile
drivers/clk/mediatek/clk-apmixed.c [new file with mode: 0644]
drivers/clk/mediatek/clk-gate.c
drivers/clk/mediatek/clk-mt8173.c
drivers/clk/mediatek/clk-mtk.c
drivers/clk/mediatek/clk-mtk.h
drivers/clk/mediatek/clk-pll.c
drivers/clk/mvebu/clk-cpu.c
drivers/clk/mvebu/common.c
drivers/clk/mxs/clk-frac.c
drivers/clk/nxp/clk-lpc18xx-ccu.c
drivers/clk/nxp/clk-lpc18xx-cgu.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/clk-rcg.c
drivers/clk/qcom/clk-rcg.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/common.c
drivers/clk/qcom/common.h
drivers/clk/qcom/gcc-apq8084.c
drivers/clk/qcom/gcc-ipq806x.c
drivers/clk/qcom/gcc-msm8660.c
drivers/clk/qcom/gcc-msm8916.c
drivers/clk/qcom/gcc-msm8960.c
drivers/clk/qcom/gcc-msm8974.c
drivers/clk/qcom/gdsc.c [new file with mode: 0644]
drivers/clk/qcom/gdsc.h [new file with mode: 0644]
drivers/clk/qcom/lcc-ipq806x.c
drivers/clk/qcom/lcc-msm8960.c
drivers/clk/qcom/mmcc-apq8084.c
drivers/clk/qcom/mmcc-msm8960.c
drivers/clk/qcom/mmcc-msm8974.c
drivers/clk/rockchip/clk-mmc-phase.c
drivers/clk/rockchip/clk-pll.c
drivers/clk/rockchip/clk.c
drivers/clk/samsung/clk-exynos7.c
drivers/clk/shmobile/clk-mstp.c
drivers/clk/shmobile/clk-r8a7778.c
drivers/clk/sirf/clk-atlas7.c
drivers/clk/st/clk-flexgen.c
drivers/clk/st/clkgen-mux.c
drivers/clk/st/clkgen-pll.c
drivers/clk/st/clkgen.h
drivers/clk/sunxi/clk-sun6i-apb0-gates.c
drivers/clk/sunxi/clk-sun6i-apb0.c
drivers/clk/sunxi/clk-sun6i-ar100.c
drivers/clk/sunxi/clk-sun8i-apb0.c
drivers/clk/sunxi/clk-sun9i-mmc.c
drivers/clk/tegra/clk-emc.c
drivers/clk/versatile/Kconfig
drivers/clk/versatile/clk-icst.c
drivers/tty/serial/8250/8250_dw.c
include/dt-bindings/clock/at91.h
include/dt-bindings/clock/bcm-ns2.h [new file with mode: 0644]
include/dt-bindings/clock/bcm-nsp.h [new file with mode: 0644]
include/dt-bindings/clock/exynos7-clk.h
include/dt-bindings/clock/mt8173-clk.h
include/dt-bindings/clock/qcom,gcc-apq8084.h
include/dt-bindings/clock/qcom,gcc-msm8916.h
include/dt-bindings/clock/qcom,gcc-msm8974.h
include/dt-bindings/clock/qcom,mmcc-apq8084.h
include/dt-bindings/clock/qcom,mmcc-msm8974.h
include/dt-bindings/clock/r8a7795-cpg-mssr.h [new file with mode: 0644]
include/dt-bindings/clock/renesas-cpg-mssr.h [new file with mode: 0644]
include/linux/clk-provider.h
include/linux/clk/at91_pmc.h

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
new file mode 100644 (file)
index 0000000..b1f2ce1
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek imgsys controller
+============================
+
+The Mediatek imgsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt8173-imgsys", "syscon"
+- #clock-cells: Must be 1
+
+The imgsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+imgsys: clock-controller@15000000 {
+       compatible = "mediatek,mt8173-imgsys", "syscon";
+       reg = <0 0x15000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
new file mode 100644 (file)
index 0000000..4385946
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek mmsys controller
+============================
+
+The Mediatek mmsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt8173-mmsys", "syscon"
+- #clock-cells: Must be 1
+
+The mmsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+mmsys: clock-controller@14000000 {
+       compatible = "mediatek,mt8173-mmsys", "syscon";
+       reg = <0 0x14000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
new file mode 100644 (file)
index 0000000..1faacf1
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek vdecsys controller
+============================
+
+The Mediatek vdecsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt8173-vdecsys", "syscon"
+- #clock-cells: Must be 1
+
+The vdecsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vdecsys: clock-controller@16000000 {
+       compatible = "mediatek,mt8173-vdecsys", "syscon";
+       reg = <0 0x16000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
new file mode 100644 (file)
index 0000000..3cc299f
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek vencltsys controller
+============================
+
+The Mediatek vencltsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt8173-vencltsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencltsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vencltsys: clock-controller@19000000 {
+       compatible = "mediatek,mt8173-vencltsys", "syscon";
+       reg = <0 0x19000000 0 0x1000>;
+       #clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
new file mode 100644 (file)
index 0000000..5bb2866
--- /dev/null
@@ -0,0 +1,22 @@
+Mediatek vencsys controller
+============================
+
+The Mediatek vencsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+       - "mediatek,mt8173-vencsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vencsys: clock-controller@18000000 {
+       compatible = "mediatek,mt8173-vencsys", "syscon";
+       reg = <0 0x18000000 0 0x1000>;
+       #clock-cells = <1>;
+};
index 5ba6450693b9816dfc1dacef96570e14c22a111b..181bc8ac4e3a50a7fa430b61a16f10cf0675d8b9 100644 (file)
@@ -77,6 +77,9 @@ Required properties:
        "atmel,sama5d4-clk-h32mx":
                at91 h32mx clock
 
+       "atmel,sama5d2-clk-generated":
+               at91 generated clock
+
 Required properties for SCKC node:
 - reg : defines the IO memory reserved for the SCKC.
 - #size-cells : shall be 0 (reg is used to encode clk id).
@@ -461,3 +464,35 @@ For example:
                compatible = "atmel,sama5d4-clk-h32mx";
                clocks = <&mck>;
        };
+
+Required properties for generated clocks:
+- #size-cells : shall be 0 (reg is used to encode clk id).
+- #address-cells : shall be 1 (reg is used to encode clk id).
+- clocks : shall be the generated clock source phandles.
+       e.g. clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
+- name: device tree node describing a specific generated clock.
+       * #clock-cells : from common clock binding; shall be set to 0.
+       * reg: peripheral id. See Atmel's datasheets to get a full
+         list of peripheral ids.
+       * atmel,clk-output-range : minimum and maximum clock frequency
+         (two u32 fields).
+
+For example:
+       gck {
+               compatible = "atmel,sama5d2-clk-generated";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>;
+
+               tcb0_gclk: tcb0_gclk {
+                       #clock-cells = <0>;
+                       reg = <35>;
+                       atmel,clk-output-range = <0 83000000>;
+               };
+
+               pwm_gclk: pwm_gclk {
+                       #clock-cells = <0>;
+                       reg = <38>;
+                       atmel,clk-output-range = <0 83000000>;
+               };
+       };
index da8d9bb5751c0546386b6a62ba890b72d1cdbe71..ede65a55e21bc74c2afe9d254dd757bcc1d06a83 100644 (file)
@@ -130,3 +130,81 @@ These clock IDs are defined in:
     ch3_unused mipipll          4       BCM_CYGNUS_MIPIPLL_CH3_UNUSED
     ch4_unused mipipll          5       BCM_CYGNUS_MIPIPLL_CH4_UNUSED
     ch5_unused mipipll          6       BCM_CYGNUS_MIPIPLL_CH5_UNUSED
+
+Northstar and Northstar Plus
+------
+PLL and leaf clock compatible strings for Northstar and Northstar Plus are:
+ "brcm,nsp-armpll"
+ "brcm,nsp-genpll"
+ "brcm,nsp-lcpll0"
+
+The following table defines the set of PLL/clock index and ID for Northstar and
+Northstar Plus.  These clock IDs are defined in:
+    "include/dt-bindings/clock/bcm-nsp.h"
+
+    Clock      Source          Index   ID
+    ---                -----           -----   ---------
+    crystal    N/A             N/A     N/A
+
+    armpll     crystal         N/A     N/A
+
+    genpll     crystal         0       BCM_NSP_GENPLL
+    phy                genpll          1       BCM_NSP_GENPLL_PHY_CLK
+    ethernetclk        genpll          2       BCM_NSP_GENPLL_ENET_SW_CLK
+    usbclk     genpll          3       BCM_NSP_GENPLL_USB_PHY_REF_CLK
+    iprocfast  genpll          4       BCM_NSP_GENPLL_IPROCFAST_CLK
+    sata1      genpll          5       BCM_NSP_GENPLL_SATA1_CLK
+    sata2      genpll          6       BCM_NSP_GENPLL_SATA2_CLK
+
+    lcpll0     crystal         0       BCM_NSP_LCPLL0
+    pcie_phy   lcpll0          1       BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK
+    sdio       lcpll0          2       BCM_NSP_LCPLL0_SDIO_CLK
+    ddr_phy    lcpll0          3       BCM_NSP_LCPLL0_DDR_PHY_CLK
+
+Northstar 2
+-----------
+PLL and leaf clock compatible strings for Northstar 2 are:
+    "brcm,ns2-genpll-scr"
+    "brcm,ns2-genpll-sw"
+    "brcm,ns2-lcpll-ddr"
+    "brcm,ns2-lcpll-ports"
+
+The following table defines the set of PLL/clock index and ID for Northstar 2.
+These clock IDs are defined in:
+    "include/dt-bindings/clock/bcm-ns2.h"
+
+    Clock      Source          Index   ID
+    ---                -----           -----   ---------
+    crystal    N/A             N/A     N/A
+
+    genpll_scr crystal         0       BCM_NS2_GENPLL_SCR
+    scr                genpll_scr      1       BCM_NS2_GENPLL_SCR_SCR_CLK
+    fs         genpll_scr      2       BCM_NS2_GENPLL_SCR_FS_CLK
+    audio_ref  genpll_scr      3       BCM_NS2_GENPLL_SCR_AUDIO_CLK
+    ch3_unused genpll_scr      4       BCM_NS2_GENPLL_SCR_CH3_UNUSED
+    ch4_unused genpll_scr      5       BCM_NS2_GENPLL_SCR_CH4_UNUSED
+    ch5_unused genpll_scr      6       BCM_NS2_GENPLL_SCR_CH5_UNUSED
+
+    genpll_sw  crystal         0       BCM_NS2_GENPLL_SW
+    rpe                genpll_sw       1       BCM_NS2_GENPLL_SW_RPE_CLK
+    250                genpll_sw       2       BCM_NS2_GENPLL_SW_250_CLK
+    nic                genpll_sw       3       BCM_NS2_GENPLL_SW_NIC_CLK
+    chimp      genpll_sw       4       BCM_NS2_GENPLL_SW_CHIMP_CLK
+    port       genpll_sw       5       BCM_NS2_GENPLL_SW_PORT_CLK
+    sdio       genpll_sw       6       BCM_NS2_GENPLL_SW_SDIO_CLK
+
+    lcpll_ddr  crystal         0       BCM_NS2_LCPLL_DDR
+    pcie_sata_usb lcpll_ddr    1       BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK
+    ddr                lcpll_ddr       2       BCM_NS2_LCPLL_DDR_DDR_CLK
+    ch2_unused lcpll_ddr       3       BCM_NS2_LCPLL_DDR_CH2_UNUSED
+    ch3_unused lcpll_ddr       4       BCM_NS2_LCPLL_DDR_CH3_UNUSED
+    ch4_unused lcpll_ddr       5       BCM_NS2_LCPLL_DDR_CH4_UNUSED
+    ch5_unused lcpll_ddr       6       BCM_NS2_LCPLL_DDR_CH5_UNUSED
+
+    lcpll_ports        crystal         0       BCM_NS2_LCPLL_PORTS
+    wan                lcpll_ports     1       BCM_NS2_LCPLL_PORTS_WAN_CLK
+    rgmii      lcpll_ports     2       BCM_NS2_LCPLL_PORTS_RGMII_CLK
+    ch2_unused lcpll_ports     3       BCM_NS2_LCPLL_PORTS_CH2_UNUSED
+    ch3_unused lcpll_ports     4       BCM_NS2_LCPLL_PORTS_CH3_UNUSED
+    ch4_unused lcpll_ports     5       BCM_NS2_LCPLL_PORTS_CH4_UNUSED
+    ch5_unused lcpll_ports     6       BCM_NS2_LCPLL_PORTS_CH5_UNUSED
index 5ddb68418655d569e047ec91891d5c6b41bda49e..38dcf03701430e603e2b3b376e1239014501d62a 100644 (file)
@@ -1,7 +1,7 @@
 * Renesas CPG DIV6 Clock
 
 The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse
-Generator (CPG). They clock input is divided by a configurable factor from 1
+Generator (CPG). Their clock input is divided by a configurable factor from 1
 to 64.
 
 Required Properties:
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
new file mode 100644 (file)
index 0000000..59297d3
--- /dev/null
@@ -0,0 +1,69 @@
+* Renesas Clock Pulse Generator / Module Standby and Software Reset
+
+On Renesas ARM SoCs (SH/R-Mobile, R-Car, RZ), the CPG (Clock Pulse Generator)
+and MSSR (Module Standby and Software Reset) blocks are intimately connected,
+and share the same register block.
+
+They provide the following functionalities:
+  - The CPG block generates various core clocks,
+  - The MSSR block provides two functions:
+      1. Module Standby, providing a Clock Domain to control the clock supply
+        to individual SoC devices,
+      2. Reset Control, to perform a software reset of individual SoC devices.
+
+Required Properties:
+  - compatible: Must be one of:
+      - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC
+
+  - reg: Base address and length of the memory resource used by the CPG/MSSR
+    block
+
+  - clocks: References to external parent clocks, one entry for each entry in
+    clock-names
+  - clock-names: List of external parent clock names. Valid names are:
+      - "extal" (r8a7795)
+      - "extalr" (r8a7795)
+
+  - #clock-cells: Must be 2
+      - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
+       and a core clock reference, as defined in
+       <dt-bindings/clock/*-cpg-mssr.h>.
+      - For module clocks, the two clock specifier cells must be "CPG_MOD" and
+       a module number, as defined in the datasheet.
+
+  - #power-domain-cells: Must be 0
+      - SoC devices that are part of the CPG/MSSR Clock Domain and can be
+       power-managed through Module Standby should refer to the CPG device
+       node in their "power-domains" property, as documented by the generic PM
+       Domain bindings in
+       Documentation/devicetree/bindings/power/power_domain.txt.
+
+
+Examples
+--------
+
+  - CPG device node:
+
+       cpg: clock-controller@e6150000 {
+               compatible = "renesas,r8a7795-cpg-mssr";
+               reg = <0 0xe6150000 0 0x1000>;
+               clocks = <&extal_clk>, <&extalr_clk>;
+               clock-names = "extal", "extalr";
+               #clock-cells = <2>;
+               #power-domain-cells = <0>;
+       };
+
+
+  - CPG/MSSR Clock Domain member device node:
+
+       scif2: serial@e6e88000 {
+               compatible = "renesas,scif-r8a7795", "renesas,scif";
+               reg = <0 0xe6e88000 0 64>;
+               interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 310>;
+               clock-names = "sci_ick";
+               dmas = <&dmac1 0x13>, <&dmac1 0x12>;
+               dma-names = "tx", "rx";
+               power-domains = <&cpg>;
+               status = "disabled";
+       };
diff --git a/Documentation/devicetree/bindings/clock/silabs,si514.txt b/Documentation/devicetree/bindings/clock/silabs,si514.txt
new file mode 100644 (file)
index 0000000..ea1a9db
--- /dev/null
@@ -0,0 +1,24 @@
+Binding for Silicon Labs 514 programmable I2C clock generator.
+
+Reference
+This binding uses the common clock binding[1]. Details about the device can be
+found in the datasheet[2].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+[2] Si514 datasheet
+    http://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf
+
+Required properties:
+ - compatible: Shall be "silabs,si514"
+ - reg: I2C device address.
+ - #clock-cells: From common clock bindings: Shall be 0.
+
+Optional properties:
+ - clock-output-names: From common clock bindings. Recommended to be "si514".
+
+Example:
+       si514: clock-generator@55 {
+               reg = <0x55>;
+               #clock-cells = <0>;
+               compatible = "silabs,si514";
+       };
index d8b168ebd5f16d9ac351fe2ea856b28dc2c45437..844b3a0976bf54e0bd46569a326ca3bb6158480a 100644 (file)
@@ -23,6 +23,7 @@ Required properties:
        "st,stih407-plls-c32-a9",       "st,clkgen-plls-c32"
        "sst,plls-c32-cx_0",            "st,clkgen-plls-c32"
        "sst,plls-c32-cx_1",            "st,clkgen-plls-c32"
+       "st,stih418-plls-c28-a9",       "st,clkgen-plls-c32"
 
        "st,stih415-gpu-pll-c32",       "st,clkgengpu-pll-c32"
        "st,stih416-gpu-pll-c32",       "st,clkgengpu-pll-c32"
index 9e4067cfecbed3e37751e6c08b9dcbf6a6d9415f..ec7a0641fefb0c57d0ab2f417f1b87c5ef60a1ca 100644 (file)
@@ -103,6 +103,9 @@ config HAVE_AT91_SMD
 config HAVE_AT91_H32MX
        bool
 
+config HAVE_AT91_GENERATED_CLK
+       bool
+
 config SOC_SAM_V4_V5
        bool
 
index 0be09af9dec724aec2ed818959753cebf84f85fe..8c53c55be1feb318e84e2c2aba475b42646527c2 100644 (file)
@@ -14,7 +14,7 @@ config ARCH_BCM_IPROC
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select ARM_GLOBAL_TIMER
-
+       select COMMON_CLK_IPROC
        select CLKSRC_MMIO
        select ARCH_REQUIRE_GPIOLIB
        select ARM_AMBA
index a7dfdf9f15bada9112d38c6c5616abbd40f3762c..80e29887038830a7bac36fe79d8c53912b828d81 100644 (file)
@@ -1353,6 +1353,7 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain);
 
 /**
  * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
@@ -1400,6 +1401,7 @@ out:
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain);
 
 /* Default device callbacks for generic PM domains. */
 
index 67826167a0e0af6ebf5fcca662e04554ab89569d..c3e3a02f7f1f9b288ac93a524db3615f6abb72ae 100644 (file)
@@ -14,6 +14,7 @@ config COMMON_CLK
        select HAVE_CLK_PREPARE
        select CLKDEV_LOOKUP
        select SRCU
+       select RATIONAL
        ---help---
          The common clock framework is a single definition of struct
          clk, useful across many platforms, as well as an
@@ -78,6 +79,16 @@ config COMMON_CLK_SI5351
          This driver supports Silicon Labs 5351A/B/C programmable clock
          generators.
 
+config COMMON_CLK_SI514
+       tristate "Clock driver for SiLabs 514 devices"
+       depends on I2C
+       depends on OF
+       select REGMAP_I2C
+       help
+       ---help---
+         This driver supports the Silicon Labs 514 programmable clock
+         generator.
+
 config COMMON_CLK_SI570
        tristate "Clock driver for SiLabs 570 and compatible devices"
        depends on I2C
@@ -123,7 +134,7 @@ config CLK_TWL6040
 
 config COMMON_CLK_AXI_CLKGEN
        tristate "AXI clkgen driver"
-       depends on ARCH_ZYNQ || MICROBLAZE
+       depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
        help
        ---help---
          Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
@@ -131,7 +142,7 @@ config COMMON_CLK_AXI_CLKGEN
 
 config CLK_QORIQ
        bool "Clock driver for Freescale QorIQ platforms"
-       depends on (PPC_E500MC || ARM || ARM64) && OF
+       depends on (PPC_E500MC || ARM || ARM64 || COMPILE_TEST) && OF
        ---help---
          This adds the clock driver support for Freescale QorIQ platforms
          using common clock framework.
@@ -139,13 +150,13 @@ config CLK_QORIQ
 config COMMON_CLK_XGENE
        bool "Clock driver for APM XGene SoC"
        default y
-       depends on ARM64
+       depends on ARM64 || COMPILE_TEST
        ---help---
          Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
 
 config COMMON_CLK_KEYSTONE
        tristate "Clock drivers for Keystone based SOCs"
-       depends on ARCH_KEYSTONE && OF
+       depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF
        ---help---
           Supports clock drivers for Keystone based SOCs. These SOCs have local
          a power sleep control module that gate the clock to the IPs and PLLs.
index 1ec1ce1849a72c84e64446769452d22a54fd3ae5..820714c72d368e29fe211d1699c9a68202c98359 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_COMMON_CLK_RK808)                += clk-rk808.o
 obj-$(CONFIG_COMMON_CLK_S2MPS11)       += clk-s2mps11.o
 obj-$(CONFIG_COMMON_CLK_SCPI)           += clk-scpi.o
 obj-$(CONFIG_COMMON_CLK_SI5351)                += clk-si5351.o
+obj-$(CONFIG_COMMON_CLK_SI514)         += clk-si514.o
 obj-$(CONFIG_COMMON_CLK_SI570)         += clk-si570.o
 obj-$(CONFIG_COMMON_CLK_CDCE925)       += clk-cdce925.o
 obj-$(CONFIG_ARCH_STM32)               += clk-stm32f4.o
@@ -48,7 +49,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X)               += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE)         += clk-xgene.o
 obj-$(CONFIG_COMMON_CLK_PWM)           += clk-pwm.o
 obj-$(CONFIG_COMMON_CLK_AT91)          += at91/
-obj-$(CONFIG_ARCH_BCM)                 += bcm/
+obj-y                                  += bcm/
 obj-$(CONFIG_ARCH_BERLIN)              += berlin/
 obj-$(CONFIG_ARCH_HISI)                        += hisilicon/
 obj-$(CONFIG_ARCH_MXC)                 += imx/
index 89a48a7bd5df452b7ba9157249a2f18fc37ceb57..13e67bd35cff3c8c56eb86229a35a58f40bcf834 100644 (file)
@@ -10,3 +10,4 @@ obj-$(CONFIG_HAVE_AT91_UTMI)          += clk-utmi.o
 obj-$(CONFIG_HAVE_AT91_USB_CLK)                += clk-usb.o
 obj-$(CONFIG_HAVE_AT91_SMD)            += clk-smd.o
 obj-$(CONFIG_HAVE_AT91_H32MX)          += clk-h32mx.o
+obj-$(CONFIG_HAVE_AT91_GENERATED_CLK)  += clk-generated.o
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c
new file mode 100644 (file)
index 0000000..abc8094
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ *  Copyright (C) 2015 Atmel Corporation,
+ *                     Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/clk/at91_pmc.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+#include "pmc.h"
+
+#define PERIPHERAL_MAX         64
+#define PERIPHERAL_ID_MIN      2
+
+#define GENERATED_SOURCE_MAX   6
+#define GENERATED_MAX_DIV      255
+
+struct clk_generated {
+       struct clk_hw hw;
+       struct at91_pmc *pmc;
+       struct clk_range range;
+       u32 id;
+       u32 gckdiv;
+       u8 parent_id;
+};
+
+#define to_clk_generated(hw) \
+       container_of(hw, struct clk_generated, hw)
+
+static int clk_generated_enable(struct clk_hw *hw)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+       struct at91_pmc *pmc = gck->pmc;
+       u32 tmp;
+
+       pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n",
+                __func__, gck->gckdiv, gck->parent_id);
+
+       pmc_lock(pmc);
+       pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+       tmp = pmc_read(pmc, AT91_PMC_PCR) &
+                       ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK);
+       pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id)
+                                        | AT91_PMC_PCR_CMD
+                                        | AT91_PMC_PCR_GCKDIV(gck->gckdiv)
+                                        | AT91_PMC_PCR_GCKEN);
+       pmc_unlock(pmc);
+       return 0;
+}
+
+static void clk_generated_disable(struct clk_hw *hw)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+       struct at91_pmc *pmc = gck->pmc;
+       u32 tmp;
+
+       pmc_lock(pmc);
+       pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+       tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN;
+       pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+       pmc_unlock(pmc);
+}
+
+static int clk_generated_is_enabled(struct clk_hw *hw)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+       struct at91_pmc *pmc = gck->pmc;
+       int ret;
+
+       pmc_lock(pmc);
+       pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+       ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN);
+       pmc_unlock(pmc);
+
+       return ret;
+}
+
+static unsigned long
+clk_generated_recalc_rate(struct clk_hw *hw,
+                         unsigned long parent_rate)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+
+       return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1);
+}
+
+static int clk_generated_determine_rate(struct clk_hw *hw,
+                                       struct clk_rate_request *req)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+       struct clk_hw *parent = NULL;
+       long best_rate = -EINVAL;
+       unsigned long tmp_rate, min_rate;
+       int best_diff = -1;
+       int tmp_diff;
+       int i;
+
+       for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
+               u32 div;
+               unsigned long parent_rate;
+
+               parent = clk_hw_get_parent_by_index(hw, i);
+               if (!parent)
+                       continue;
+
+               parent_rate = clk_hw_get_rate(parent);
+               min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1);
+               if (!parent_rate ||
+                   (gck->range.max && min_rate > gck->range.max))
+                       continue;
+
+               for (div = 1; div < GENERATED_MAX_DIV + 2; div++) {
+                       tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div);
+                       tmp_diff = abs(req->rate - tmp_rate);
+
+                       if (best_diff < 0 || best_diff > tmp_diff) {
+                               best_rate = tmp_rate;
+                               best_diff = tmp_diff;
+                               req->best_parent_rate = parent_rate;
+                               req->best_parent_hw = parent;
+                       }
+
+                       if (!best_diff || tmp_rate < req->rate)
+                               break;
+               }
+
+               if (!best_diff)
+                       break;
+       }
+
+       pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
+                __func__, best_rate,
+                __clk_get_name((req->best_parent_hw)->clk),
+                req->best_parent_rate);
+
+       if (best_rate < 0)
+               return best_rate;
+
+       req->rate = best_rate;
+       return 0;
+}
+
+/* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */
+static int clk_generated_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+
+       if (index >= clk_hw_get_num_parents(hw))
+               return -EINVAL;
+
+       gck->parent_id = index;
+       return 0;
+}
+
+static u8 clk_generated_get_parent(struct clk_hw *hw)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+
+       return gck->parent_id;
+}
+
+/* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */
+static int clk_generated_set_rate(struct clk_hw *hw,
+                                 unsigned long rate,
+                                 unsigned long parent_rate)
+{
+       struct clk_generated *gck = to_clk_generated(hw);
+       u32 div;
+
+       if (!rate)
+               return -EINVAL;
+
+       if (gck->range.max && rate > gck->range.max)
+               return -EINVAL;
+
+       div = DIV_ROUND_CLOSEST(parent_rate, rate);
+       if (div > GENERATED_MAX_DIV + 1 || !div)
+               return -EINVAL;
+
+       gck->gckdiv = div - 1;
+       return 0;
+}
+
+static const struct clk_ops generated_ops = {
+       .enable = clk_generated_enable,
+       .disable = clk_generated_disable,
+       .is_enabled = clk_generated_is_enabled,
+       .recalc_rate = clk_generated_recalc_rate,
+       .determine_rate = clk_generated_determine_rate,
+       .get_parent = clk_generated_get_parent,
+       .set_parent = clk_generated_set_parent,
+       .set_rate = clk_generated_set_rate,
+};
+
+/**
+ * clk_generated_startup - Initialize a given clock to its default parent and
+ * divisor parameter.
+ *
+ * @gck:       Generated clock to set the startup parameters for.
+ *
+ * Take parameters from the hardware and update local clock configuration
+ * accordingly.
+ */
+static void clk_generated_startup(struct clk_generated *gck)
+{
+       struct at91_pmc *pmc = gck->pmc;
+       u32 tmp;
+
+       pmc_lock(pmc);
+       pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK));
+       tmp = pmc_read(pmc, AT91_PMC_PCR);
+       pmc_unlock(pmc);
+
+       gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK)
+                                       >> AT91_PMC_PCR_GCKCSS_OFFSET;
+       gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK)
+                                       >> AT91_PMC_PCR_GCKDIV_OFFSET;
+}
+
+static struct clk * __init
+at91_clk_register_generated(struct at91_pmc *pmc, const char *name,
+                           const char **parent_names, u8 num_parents,
+                           u8 id, const struct clk_range *range)
+{
+       struct clk_generated *gck;
+       struct clk *clk = NULL;
+       struct clk_init_data init;
+
+       gck = kzalloc(sizeof(*gck), GFP_KERNEL);
+       if (!gck)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &generated_ops;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+       init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+       gck->id = id;
+       gck->hw.init = &init;
+       gck->pmc = pmc;
+       gck->range = *range;
+
+       clk = clk_register(NULL, &gck->hw);
+       if (IS_ERR(clk))
+               kfree(gck);
+       else
+               clk_generated_startup(gck);
+
+       return clk;
+}
+
+void __init of_sama5d2_clk_generated_setup(struct device_node *np,
+                                          struct at91_pmc *pmc)
+{
+       int num;
+       u32 id;
+       const char *name;
+       struct clk *clk;
+       int num_parents;
+       const char *parent_names[GENERATED_SOURCE_MAX];
+       struct device_node *gcknp;
+       struct clk_range range = CLK_RANGE(0, 0);
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       num = of_get_child_count(np);
+       if (!num || num > PERIPHERAL_MAX)
+               return;
+
+       for_each_child_of_node(np, gcknp) {
+               if (of_property_read_u32(gcknp, "reg", &id))
+                       continue;
+
+               if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
+                       continue;
+
+               if (of_property_read_string(np, "clock-output-names", &name))
+                       name = gcknp->name;
+
+               of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
+                                     &range);
+
+               clk = at91_clk_register_generated(pmc, name, parent_names,
+                                                 num_parents, id, &range);
+               if (IS_ERR(clk))
+                       continue;
+
+               of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
+       }
+}
index e4d7b574f1ea33a198a454e0223818c9e539ebb9..58f3b568e9cb9024beaf0831c9ac3e0237a93d03 100644 (file)
@@ -161,14 +161,18 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw)
 {
        struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
        struct at91_pmc *pmc = periph->pmc;
+       u32 tmp;
 
        if (periph->id < PERIPHERAL_ID_MIN)
                return 0;
 
-       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) |
-                                    AT91_PMC_PCR_CMD |
-                                    AT91_PMC_PCR_DIV(periph->div) |
-                                    AT91_PMC_PCR_EN);
+       pmc_lock(pmc);
+       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+       tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK;
+       pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div)
+                                        | AT91_PMC_PCR_CMD
+                                        | AT91_PMC_PCR_EN);
+       pmc_unlock(pmc);
        return 0;
 }
 
@@ -176,12 +180,16 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw)
 {
        struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw);
        struct at91_pmc *pmc = periph->pmc;
+       u32 tmp;
 
        if (periph->id < PERIPHERAL_ID_MIN)
                return;
 
-       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) |
-                                    AT91_PMC_PCR_CMD);
+       pmc_lock(pmc);
+       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
+       tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN;
+       pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD);
+       pmc_unlock(pmc);
 }
 
 static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
@@ -194,7 +202,7 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw)
                return 1;
 
        pmc_lock(pmc);
-       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID));
+       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
        ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN);
        pmc_unlock(pmc);
 
@@ -213,7 +221,7 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw,
                return parent_rate;
 
        pmc_lock(pmc);
-       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID));
+       pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK));
        tmp = pmc_read(pmc, AT91_PMC_PCR);
        pmc_unlock(pmc);
 
index 58008b3e8bc175f8befb8126e99e5f55c57d2176..3f5314344286e3335ec77f9c02360cb75c19cb93 100644 (file)
@@ -138,7 +138,8 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
 
        clk = clk_register(NULL, &sys->hw);
        if (IS_ERR(clk)) {
-               free_irq(sys->irq, sys);
+               if (irq)
+                       free_irq(sys->irq, sys);
                kfree(sys);
        }
 
index 30dd697b1668bea6d437655d5c7fc825cda3f52a..ca561e90a60f48884d801bc1b81c61612a4954df 100644 (file)
@@ -47,7 +47,7 @@ static int clk_utmi_prepare(struct clk_hw *hw)
 {
        struct clk_utmi *utmi = to_clk_utmi(hw);
        struct at91_pmc *pmc = utmi->pmc;
-       u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
+       u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
                  AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;
 
        pmc_write(pmc, AT91_CKGR_UCKR, tmp);
@@ -73,7 +73,7 @@ static void clk_utmi_unprepare(struct clk_hw *hw)
 {
        struct clk_utmi *utmi = to_clk_utmi(hw);
        struct at91_pmc *pmc = utmi->pmc;
-       u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
+       u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;
 
        pmc_write(pmc, AT91_CKGR_UCKR, tmp);
 }
index d1844f1f37292a79bac681d9037141586b4ba203..8476b570779b2d2b04ce1b4283eec0688febd4d3 100644 (file)
@@ -206,6 +206,14 @@ static const struct at91_pmc_caps at91sam9x5_caps = {
                          AT91_PMC_MOSCRCS | AT91_PMC_CFDEV,
 };
 
+static const struct at91_pmc_caps sama5d2_caps = {
+       .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
+                         AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
+                         AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY |
+                         AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS |
+                         AT91_PMC_CFDEV | AT91_PMC_GCKRDY,
+};
+
 static const struct at91_pmc_caps sama5d3_caps = {
        .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY |
                          AT91_PMC_LOCKU | AT91_PMC_PCK0RDY |
@@ -368,6 +376,12 @@ static const struct of_device_id pmc_clk_ids[] __initconst = {
                .compatible = "atmel,sama5d4-clk-h32mx",
                .data = of_sama5d4_clk_h32mx_setup,
        },
+#endif
+#if defined(CONFIG_HAVE_AT91_GENERATED_CLK)
+       {
+               .compatible = "atmel,sama5d2-clk-generated",
+               .data = of_sama5d2_clk_generated_setup,
+       },
 #endif
        { /*sentinel*/ }
 };
@@ -436,6 +450,13 @@ static void __init of_at91sam9x5_pmc_setup(struct device_node *np)
 CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc",
               of_at91sam9x5_pmc_setup);
 
+static void __init of_sama5d2_pmc_setup(struct device_node *np)
+{
+       of_at91_pmc_setup(np, &sama5d2_caps);
+}
+CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc",
+              of_sama5d2_pmc_setup);
+
 static void __init of_sama5d3_pmc_setup(struct device_node *np)
 {
        of_at91_pmc_setup(np, &sama5d3_caps);
index 8b87771c69b2c4211597c879e01c6256655c4bc0..f65739272779d3677e74321d4c6ff89d31379adf 100644 (file)
@@ -118,4 +118,7 @@ void of_at91sam9x5_clk_smd_setup(struct device_node *np,
 void of_sama5d4_clk_h32mx_setup(struct device_node *np,
                                struct at91_pmc *pmc);
 
+void of_sama5d2_clk_generated_setup(struct device_node *np,
+                                   struct at91_pmc *pmc);
+
 #endif /* __PMC_H_ */
index 88febf53b276a9253bfaf4045799197901180687..85260fb96b36547659bda0cd0f8430c682d1d781 100644 (file)
@@ -1,6 +1,6 @@
 config CLK_BCM_KONA
        bool "Broadcom Kona CCU clock support"
-       depends on ARCH_BCM_MOBILE
+       depends on ARCH_BCM_MOBILE || COMPILE_TEST
        depends on COMMON_CLK
        default y
        help
@@ -9,10 +9,8 @@ config CLK_BCM_KONA
          in the BCM281xx and BCM21664 families.
 
 config COMMON_CLK_IPROC
-       bool "Broadcom iProc clock support"
-       depends on ARCH_BCM_IPROC
+       bool
        depends on COMMON_CLK
-       default ARCH_BCM_IPROC
        help
          Enable common clock framework support for Broadcom SoCs
          based on the iProc architecture
index ee2349bbe1f16855a3a0b2d4161d719aaacbc22c..3fc95060d875e8607696c61bece2020613f4fdb1 100644 (file)
@@ -4,4 +4,7 @@ obj-$(CONFIG_CLK_BCM_KONA)      += clk-bcm281xx.o
 obj-$(CONFIG_CLK_BCM_KONA)     += clk-bcm21664.o
 obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o
 obj-$(CONFIG_ARCH_BCM2835)     += clk-bcm2835.o
+obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o
 obj-$(CONFIG_ARCH_BCM_CYGNUS)  += clk-cygnus.o
+obj-$(CONFIG_ARCH_BCM_NSP)     += clk-nsp.o
+obj-$(CONFIG_ARCH_BCM_5301X)   += clk-nsp.o
index 316c603376619266378e42fc88b0ab2540defbb0..3a228b6d4feefe6466f29941e9f66fee0c532615 100644 (file)
 #include <dt-bindings/clock/bcm-cygnus.h>
 #include "clk-iproc.h"
 
-#define reg_val(o, s, w) { .offset = o, .shift = s, .width = w, }
+#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
 
-#define aon_val(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
+#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
        .pwr_shift = ps, .iso_shift = is }
 
-#define sw_ctrl_val(o, s) { .offset = o, .shift = s, }
+#define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
 
-#define asiu_div_val(o, es, hs, hw, ls, lw) \
+#define ASIU_DIV_VAL(o, es, hs, hw, ls, lw) \
                { .offset = o, .en_shift = es, .high_shift = hs, \
                .high_width = hw, .low_shift = ls, .low_width = lw }
 
-#define reset_val(o, rs, prs, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \
-       .reset_shift = rs, .p_reset_shift = prs, .ki_shift = kis, \
-       .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \
+#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
+       .p_reset_shift = prs }
+
+#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
+       .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas,    \
        .ka_width = kaw }
 
-#define vco_ctrl_val(uo, lo) { .u_offset = uo, .l_offset = lo }
+#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
 
-#define enable_val(o, es, hs, bs) { .offset = o, .enable_shift = es, \
+#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
        .hold_shift = hs, .bypass_shift = bs }
 
-#define asiu_gate_val(o, es) { .offset = o, .en_shift = es }
+#define ASIU_GATE_VAL(o, es) { .offset = o, .en_shift = es }
 
 static void __init cygnus_armpll_init(struct device_node *node)
 {
@@ -55,52 +57,53 @@ CLK_OF_DECLARE(cygnus_armpll, "brcm,cygnus-armpll", cygnus_armpll_init);
 static const struct iproc_pll_ctrl genpll = {
        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
                IPROC_CLK_PLL_NEEDS_SW_CFG,
-       .aon = aon_val(0x0, 2, 1, 0),
-       .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 3),
-       .sw_ctrl = sw_ctrl_val(0x10, 31),
-       .ndiv_int = reg_val(0x10, 20, 10),
-       .ndiv_frac = reg_val(0x10, 0, 20),
-       .pdiv = reg_val(0x14, 0, 4),
-       .vco_ctrl = vco_ctrl_val(0x18, 0x1c),
-       .status = reg_val(0x28, 12, 1),
+       .aon = AON_VAL(0x0, 2, 1, 0),
+       .reset = RESET_VAL(0x0, 11, 10),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
+       .sw_ctrl = SW_CTRL_VAL(0x10, 31),
+       .ndiv_int = REG_VAL(0x10, 20, 10),
+       .ndiv_frac = REG_VAL(0x10, 0, 20),
+       .pdiv = REG_VAL(0x14, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c),
+       .status = REG_VAL(0x28, 12, 1),
 };
 
 static const struct iproc_clk_ctrl genpll_clk[] = {
        [BCM_CYGNUS_GENPLL_AXI21_CLK] = {
                .channel = BCM_CYGNUS_GENPLL_AXI21_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x4, 6, 0, 12),
-               .mdiv = reg_val(0x20, 0, 8),
+               .enable = ENABLE_VAL(0x4, 6, 0, 12),
+               .mdiv = REG_VAL(0x20, 0, 8),
        },
        [BCM_CYGNUS_GENPLL_250MHZ_CLK] = {
                .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x4, 7, 1, 13),
-               .mdiv = reg_val(0x20, 10, 8),
+               .enable = ENABLE_VAL(0x4, 7, 1, 13),
+               .mdiv = REG_VAL(0x20, 10, 8),
        },
        [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = {
                .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x4, 8, 2, 14),
-               .mdiv = reg_val(0x20, 20, 8),
+               .enable = ENABLE_VAL(0x4, 8, 2, 14),
+               .mdiv = REG_VAL(0x20, 20, 8),
        },
        [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = {
                .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x4, 9, 3, 15),
-               .mdiv = reg_val(0x24, 0, 8),
+               .enable = ENABLE_VAL(0x4, 9, 3, 15),
+               .mdiv = REG_VAL(0x24, 0, 8),
        },
        [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = {
                .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x4, 10, 4, 16),
-               .mdiv = reg_val(0x24, 10, 8),
+               .enable = ENABLE_VAL(0x4, 10, 4, 16),
+               .mdiv = REG_VAL(0x24, 10, 8),
        },
        [BCM_CYGNUS_GENPLL_CAN_CLK] = {
                .channel = BCM_CYGNUS_GENPLL_CAN_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x4, 11, 5, 17),
-               .mdiv = reg_val(0x24, 20, 8),
+               .enable = ENABLE_VAL(0x4, 11, 5, 17),
+               .mdiv = REG_VAL(0x24, 20, 8),
        },
 };
 
@@ -113,51 +116,52 @@ CLK_OF_DECLARE(cygnus_genpll, "brcm,cygnus-genpll", cygnus_genpll_clk_init);
 
 static const struct iproc_pll_ctrl lcpll0 = {
        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
-       .aon = aon_val(0x0, 2, 5, 4),
-       .reset = reset_val(0x0, 31, 30, 27, 3, 23, 4, 19, 4),
-       .sw_ctrl = sw_ctrl_val(0x4, 31),
-       .ndiv_int = reg_val(0x4, 16, 10),
-       .pdiv = reg_val(0x4, 26, 4),
-       .vco_ctrl = vco_ctrl_val(0x10, 0x14),
-       .status = reg_val(0x18, 12, 1),
+       .aon = AON_VAL(0x0, 2, 5, 4),
+       .reset = RESET_VAL(0x0, 31, 30),
+       .dig_filter = DF_VAL(0x0, 27, 3, 23, 4, 19, 4),
+       .sw_ctrl = SW_CTRL_VAL(0x4, 31),
+       .ndiv_int = REG_VAL(0x4, 16, 10),
+       .pdiv = REG_VAL(0x4, 26, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x10, 0x14),
+       .status = REG_VAL(0x18, 12, 1),
 };
 
 static const struct iproc_clk_ctrl lcpll0_clk[] = {
        [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = {
                .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x0, 7, 1, 13),
-               .mdiv = reg_val(0x8, 0, 8),
+               .enable = ENABLE_VAL(0x0, 7, 1, 13),
+               .mdiv = REG_VAL(0x8, 0, 8),
        },
        [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = {
                .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x0, 8, 2, 14),
-               .mdiv = reg_val(0x8, 10, 8),
+               .enable = ENABLE_VAL(0x0, 8, 2, 14),
+               .mdiv = REG_VAL(0x8, 10, 8),
        },
        [BCM_CYGNUS_LCPLL0_SDIO_CLK] = {
                .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x0, 9, 3, 15),
-               .mdiv = reg_val(0x8, 20, 8),
+               .enable = ENABLE_VAL(0x0, 9, 3, 15),
+               .mdiv = REG_VAL(0x8, 20, 8),
        },
        [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = {
                .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x0, 10, 4, 16),
-               .mdiv = reg_val(0xc, 0, 8),
+               .enable = ENABLE_VAL(0x0, 10, 4, 16),
+               .mdiv = REG_VAL(0xc, 0, 8),
        },
        [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = {
                .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x0, 11, 5, 17),
-               .mdiv = reg_val(0xc, 10, 8),
+               .enable = ENABLE_VAL(0x0, 11, 5, 17),
+               .mdiv = REG_VAL(0xc, 10, 8),
        },
        [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = {
                .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED,
                .flags = IPROC_CLK_AON,
-               .enable = enable_val(0x0, 12, 6, 18),
-               .mdiv = reg_val(0xc, 20, 8),
+               .enable = ENABLE_VAL(0x0, 12, 6, 18),
+               .mdiv = REG_VAL(0xc, 20, 8),
        },
 };
 
@@ -189,52 +193,53 @@ static const struct iproc_pll_vco_param mipipll_vco_params[] = {
 static const struct iproc_pll_ctrl mipipll = {
        .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC |
                 IPROC_CLK_NEEDS_READ_BACK,
-       .aon = aon_val(0x0, 4, 17, 16),
-       .asiu = asiu_gate_val(0x0, 3),
-       .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 4),
-       .ndiv_int = reg_val(0x10, 20, 10),
-       .ndiv_frac = reg_val(0x10, 0, 20),
-       .pdiv = reg_val(0x14, 0, 4),
-       .vco_ctrl = vco_ctrl_val(0x18, 0x1c),
-       .status = reg_val(0x28, 12, 1),
+       .aon = AON_VAL(0x0, 4, 17, 16),
+       .asiu = ASIU_GATE_VAL(0x0, 3),
+       .reset = RESET_VAL(0x0, 11, 10),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 4),
+       .ndiv_int = REG_VAL(0x10, 20, 10),
+       .ndiv_frac = REG_VAL(0x10, 0, 20),
+       .pdiv = REG_VAL(0x14, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c),
+       .status = REG_VAL(0x28, 12, 1),
 };
 
 static const struct iproc_clk_ctrl mipipll_clk[] = {
        [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = {
                .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED,
                .flags = IPROC_CLK_NEEDS_READ_BACK,
-               .enable = enable_val(0x4, 12, 6, 18),
-               .mdiv = reg_val(0x20, 0, 8),
+               .enable = ENABLE_VAL(0x4, 12, 6, 18),
+               .mdiv = REG_VAL(0x20, 0, 8),
        },
        [BCM_CYGNUS_MIPIPLL_CH1_LCD] = {
                .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD,
                .flags = IPROC_CLK_NEEDS_READ_BACK,
-               .enable = enable_val(0x4, 13, 7, 19),
-               .mdiv = reg_val(0x20, 10, 8),
+               .enable = ENABLE_VAL(0x4, 13, 7, 19),
+               .mdiv = REG_VAL(0x20, 10, 8),
        },
        [BCM_CYGNUS_MIPIPLL_CH2_V3D] = {
                .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D,
                .flags = IPROC_CLK_NEEDS_READ_BACK,
-               .enable = enable_val(0x4, 14, 8, 20),
-               .mdiv = reg_val(0x20, 20, 8),
+               .enable = ENABLE_VAL(0x4, 14, 8, 20),
+               .mdiv = REG_VAL(0x20, 20, 8),
        },
        [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = {
                .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED,
                .flags = IPROC_CLK_NEEDS_READ_BACK,
-               .enable = enable_val(0x4, 15, 9, 21),
-               .mdiv = reg_val(0x24, 0, 8),
+               .enable = ENABLE_VAL(0x4, 15, 9, 21),
+               .mdiv = REG_VAL(0x24, 0, 8),
        },
        [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = {
                .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED,
                .flags = IPROC_CLK_NEEDS_READ_BACK,
-               .enable = enable_val(0x4, 16, 10, 22),
-               .mdiv = reg_val(0x24, 10, 8),
+               .enable = ENABLE_VAL(0x4, 16, 10, 22),
+               .mdiv = REG_VAL(0x24, 10, 8),
        },
        [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = {
                .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED,
                .flags = IPROC_CLK_NEEDS_READ_BACK,
-               .enable = enable_val(0x4, 17, 11, 23),
-               .mdiv = reg_val(0x24, 20, 8),
+               .enable = ENABLE_VAL(0x4, 17, 11, 23),
+               .mdiv = REG_VAL(0x24, 20, 8),
        },
 };
 
@@ -247,15 +252,15 @@ static void __init cygnus_mipipll_clk_init(struct device_node *node)
 CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init);
 
 static const struct iproc_asiu_div asiu_div[] = {
-       [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_div_val(0x0, 31, 16, 10, 0, 10),
-       [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_div_val(0x4, 31, 16, 10, 0, 10),
-       [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_div_val(0x8, 31, 16, 10, 0, 10),
+       [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_DIV_VAL(0x0, 31, 16, 10, 0, 10),
+       [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_DIV_VAL(0x4, 31, 16, 10, 0, 10),
+       [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_DIV_VAL(0x8, 31, 16, 10, 0, 10),
 };
 
 static const struct iproc_asiu_gate asiu_gate[] = {
-       [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_gate_val(0x0, 7),
-       [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_gate_val(0x0, 9),
-       [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_gate_val(IPROC_CLK_INVALID_OFFSET, 0),
+       [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_GATE_VAL(0x0, 7),
+       [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_GATE_VAL(0x0, 9),
+       [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_GATE_VAL(IPROC_CLK_INVALID_OFFSET, 0),
 };
 
 static void __init cygnus_asiu_init(struct device_node *node)
index 2dda4e8295a912a4ca28f091fc8a4af86f1c4662..afd5891ac9e6aafeb6f429e487d5e06cbfd2f4f1 100644 (file)
@@ -74,7 +74,8 @@ struct iproc_clk {
 };
 
 struct iproc_pll {
-       void __iomem *pll_base;
+       void __iomem *status_base;
+       void __iomem *control_base;
        void __iomem *pwr_base;
        void __iomem *asiu_base;
 
@@ -127,7 +128,7 @@ static int pll_wait_for_lock(struct iproc_pll *pll)
        const struct iproc_pll_ctrl *ctrl = pll->ctrl;
 
        for (i = 0; i < LOCK_DELAY; i++) {
-               u32 val = readl(pll->pll_base + ctrl->status.offset);
+               u32 val = readl(pll->status_base + ctrl->status.offset);
 
                if (val & (1 << ctrl->status.shift))
                        return 0;
@@ -137,6 +138,18 @@ static int pll_wait_for_lock(struct iproc_pll *pll)
        return -EIO;
 }
 
+static void iproc_pll_write(const struct iproc_pll *pll, void __iomem *base,
+                           const u32 offset, u32 val)
+{
+       const struct iproc_pll_ctrl *ctrl = pll->ctrl;
+
+       writel(val, base + offset);
+
+       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK &&
+                    (base == pll->status_base || base == pll->control_base)))
+               val = readl(base + offset);
+}
+
 static void __pll_disable(struct iproc_pll *pll)
 {
        const struct iproc_pll_ctrl *ctrl = pll->ctrl;
@@ -145,17 +158,25 @@ static void __pll_disable(struct iproc_pll *pll)
        if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
                val = readl(pll->asiu_base + ctrl->asiu.offset);
                val &= ~(1 << ctrl->asiu.en_shift);
-               writel(val, pll->asiu_base + ctrl->asiu.offset);
+               iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
+       }
+
+       if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
+               val = readl(pll->control_base + ctrl->aon.offset);
+               val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
+               iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
        }
 
-       /* latch input value so core power can be shut down */
-       val = readl(pll->pwr_base + ctrl->aon.offset);
-       val |= (1 << ctrl->aon.iso_shift);
-       writel(val, pll->pwr_base + ctrl->aon.offset);
+       if (pll->pwr_base) {
+               /* latch input value so core power can be shut down */
+               val = readl(pll->pwr_base + ctrl->aon.offset);
+               val |= 1 << ctrl->aon.iso_shift;
+               iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
 
-       /* power down the core */
-       val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
-       writel(val, pll->pwr_base + ctrl->aon.offset);
+               /* power down the core */
+               val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
+               iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
+       }
 }
 
 static int __pll_enable(struct iproc_pll *pll)
@@ -163,17 +184,25 @@ static int __pll_enable(struct iproc_pll *pll)
        const struct iproc_pll_ctrl *ctrl = pll->ctrl;
        u32 val;
 
-       /* power up the PLL and make sure it's not latched */
-       val = readl(pll->pwr_base + ctrl->aon.offset);
-       val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
-       val &= ~(1 << ctrl->aon.iso_shift);
-       writel(val, pll->pwr_base + ctrl->aon.offset);
+       if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) {
+               val = readl(pll->control_base + ctrl->aon.offset);
+               val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift);
+               iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val);
+       }
+
+       if (pll->pwr_base) {
+               /* power up the PLL and make sure it's not latched */
+               val = readl(pll->pwr_base + ctrl->aon.offset);
+               val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift;
+               val &= ~(1 << ctrl->aon.iso_shift);
+               iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val);
+       }
 
        /* certain PLLs also need to be ungated from the ASIU top level */
        if (ctrl->flags & IPROC_CLK_PLL_ASIU) {
                val = readl(pll->asiu_base + ctrl->asiu.offset);
                val |= (1 << ctrl->asiu.en_shift);
-               writel(val, pll->asiu_base + ctrl->asiu.offset);
+               iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val);
        }
 
        return 0;
@@ -185,11 +214,9 @@ static void __pll_put_in_reset(struct iproc_pll *pll)
        const struct iproc_pll_ctrl *ctrl = pll->ctrl;
        const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
 
-       val = readl(pll->pll_base + reset->offset);
+       val = readl(pll->control_base + reset->offset);
        val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift);
-       writel(val, pll->pll_base + reset->offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + reset->offset);
+       iproc_pll_write(pll, pll->control_base, reset->offset, val);
 }
 
 static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
@@ -198,17 +225,19 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp,
        u32 val;
        const struct iproc_pll_ctrl *ctrl = pll->ctrl;
        const struct iproc_pll_reset_ctrl *reset = &ctrl->reset;
+       const struct iproc_pll_dig_filter_ctrl *dig_filter = &ctrl->dig_filter;
+
+       val = readl(pll->control_base + dig_filter->offset);
+       val &= ~(bit_mask(dig_filter->ki_width) << dig_filter->ki_shift |
+               bit_mask(dig_filter->kp_width) << dig_filter->kp_shift |
+               bit_mask(dig_filter->ka_width) << dig_filter->ka_shift);
+       val |= ki << dig_filter->ki_shift | kp << dig_filter->kp_shift |
+              ka << dig_filter->ka_shift;
+       iproc_pll_write(pll, pll->control_base, dig_filter->offset, val);
 
-       val = readl(pll->pll_base + reset->offset);
-       val &= ~(bit_mask(reset->ki_width) << reset->ki_shift |
-                bit_mask(reset->kp_width) << reset->kp_shift |
-                bit_mask(reset->ka_width) << reset->ka_shift);
-       val |=  ki << reset->ki_shift | kp << reset->kp_shift |
-               ka << reset->ka_shift;
+       val = readl(pll->control_base + reset->offset);
        val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift;
-       writel(val, pll->pll_base + reset->offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + reset->offset);
+       iproc_pll_write(pll, pll->control_base, reset->offset, val);
 }
 
 static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
@@ -263,10 +292,9 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
        /* put PLL in reset */
        __pll_put_in_reset(pll);
 
-       writel(0, pll->pll_base + ctrl->vco_ctrl.u_offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->vco_ctrl.u_offset);
-       val = readl(pll->pll_base + ctrl->vco_ctrl.l_offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0);
+
+       val = readl(pll->control_base + ctrl->vco_ctrl.l_offset);
 
        if (rate >= VCO_LOW && rate < VCO_MID)
                val |= (1 << PLL_VCO_LOW_SHIFT);
@@ -276,36 +304,29 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index,
        else
                val |= (1 << PLL_VCO_HIGH_SHIFT);
 
-       writel(val, pll->pll_base + ctrl->vco_ctrl.l_offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->vco_ctrl.l_offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.l_offset, val);
 
        /* program integer part of NDIV */
-       val = readl(pll->pll_base + ctrl->ndiv_int.offset);
+       val = readl(pll->control_base + ctrl->ndiv_int.offset);
        val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift);
        val |= vco->ndiv_int << ctrl->ndiv_int.shift;
-       writel(val, pll->pll_base + ctrl->ndiv_int.offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->ndiv_int.offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->ndiv_int.offset, val);
 
        /* program fractional part of NDIV */
        if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
-               val = readl(pll->pll_base + ctrl->ndiv_frac.offset);
+               val = readl(pll->control_base + ctrl->ndiv_frac.offset);
                val &= ~(bit_mask(ctrl->ndiv_frac.width) <<
                         ctrl->ndiv_frac.shift);
                val |= vco->ndiv_frac << ctrl->ndiv_frac.shift;
-               writel(val, pll->pll_base + ctrl->ndiv_frac.offset);
-               if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-                       readl(pll->pll_base + ctrl->ndiv_frac.offset);
+               iproc_pll_write(pll, pll->control_base, ctrl->ndiv_frac.offset,
+                               val);
        }
 
        /* program PDIV */
-       val = readl(pll->pll_base + ctrl->pdiv.offset);
+       val = readl(pll->control_base + ctrl->pdiv.offset);
        val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift);
        val |= vco->pdiv << ctrl->pdiv.shift;
-       writel(val, pll->pll_base + ctrl->pdiv.offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->pdiv.offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->pdiv.offset, val);
 
        __pll_bring_out_reset(pll, kp, ka, ki);
 
@@ -345,14 +366,14 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
        struct iproc_pll *pll = clk->pll;
        const struct iproc_pll_ctrl *ctrl = pll->ctrl;
        u32 val;
-       u64 ndiv;
-       unsigned int ndiv_int, ndiv_frac, pdiv;
+       u64 ndiv, ndiv_int, ndiv_frac;
+       unsigned int pdiv;
 
        if (parent_rate == 0)
                return 0;
 
        /* PLL needs to be locked */
-       val = readl(pll->pll_base + ctrl->status.offset);
+       val = readl(pll->status_base + ctrl->status.offset);
        if ((val & (1 << ctrl->status.shift)) == 0) {
                clk->rate = 0;
                return 0;
@@ -363,25 +384,22 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw,
         *
         * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv)
         */
-       val = readl(pll->pll_base + ctrl->ndiv_int.offset);
+       val = readl(pll->control_base + ctrl->ndiv_int.offset);
        ndiv_int = (val >> ctrl->ndiv_int.shift) &
                bit_mask(ctrl->ndiv_int.width);
-       ndiv = (u64)ndiv_int << ctrl->ndiv_int.shift;
+       ndiv = ndiv_int << 20;
 
        if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) {
-               val = readl(pll->pll_base + ctrl->ndiv_frac.offset);
+               val = readl(pll->control_base + ctrl->ndiv_frac.offset);
                ndiv_frac = (val >> ctrl->ndiv_frac.shift) &
                        bit_mask(ctrl->ndiv_frac.width);
-
-               if (ndiv_frac != 0)
-                       ndiv = ((u64)ndiv_int << ctrl->ndiv_int.shift) |
-                               ndiv_frac;
+               ndiv += ndiv_frac;
        }
 
-       val = readl(pll->pll_base + ctrl->pdiv.offset);
+       val = readl(pll->control_base + ctrl->pdiv.offset);
        pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width);
 
-       clk->rate = (ndiv * parent_rate) >> ctrl->ndiv_int.shift;
+       clk->rate = (ndiv * parent_rate) >> 20;
 
        if (pdiv == 0)
                clk->rate *= 2;
@@ -443,16 +461,14 @@ static int iproc_clk_enable(struct clk_hw *hw)
        u32 val;
 
        /* channel enable is active low */
-       val = readl(pll->pll_base + ctrl->enable.offset);
+       val = readl(pll->control_base + ctrl->enable.offset);
        val &= ~(1 << ctrl->enable.enable_shift);
-       writel(val, pll->pll_base + ctrl->enable.offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
 
        /* also make sure channel is not held */
-       val = readl(pll->pll_base + ctrl->enable.offset);
+       val = readl(pll->control_base + ctrl->enable.offset);
        val &= ~(1 << ctrl->enable.hold_shift);
-       writel(val, pll->pll_base + ctrl->enable.offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->enable.offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
 
        return 0;
 }
@@ -467,11 +483,9 @@ static void iproc_clk_disable(struct clk_hw *hw)
        if (ctrl->flags & IPROC_CLK_AON)
                return;
 
-       val = readl(pll->pll_base + ctrl->enable.offset);
+       val = readl(pll->control_base + ctrl->enable.offset);
        val |= 1 << ctrl->enable.enable_shift;
-       writel(val, pll->pll_base + ctrl->enable.offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->enable.offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val);
 }
 
 static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
@@ -486,7 +500,7 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw,
        if (parent_rate == 0)
                return 0;
 
-       val = readl(pll->pll_base + ctrl->mdiv.offset);
+       val = readl(pll->control_base + ctrl->mdiv.offset);
        mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width);
        if (mdiv == 0)
                mdiv = 256;
@@ -533,16 +547,14 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        if (div > 256)
                return -EINVAL;
 
-       val = readl(pll->pll_base + ctrl->mdiv.offset);
+       val = readl(pll->control_base + ctrl->mdiv.offset);
        if (div == 256) {
                val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
        } else {
                val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift);
                val |= div << ctrl->mdiv.shift;
        }
-       writel(val, pll->pll_base + ctrl->mdiv.offset);
-       if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-               readl(pll->pll_base + ctrl->mdiv.offset);
+       iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val);
        clk->rate = parent_rate / div;
 
        return 0;
@@ -567,11 +579,10 @@ static void iproc_pll_sw_cfg(struct iproc_pll *pll)
        if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) {
                u32 val;
 
-               val = readl(pll->pll_base + ctrl->sw_ctrl.offset);
+               val = readl(pll->control_base + ctrl->sw_ctrl.offset);
                val |= BIT(ctrl->sw_ctrl.shift);
-               writel(val, pll->pll_base + ctrl->sw_ctrl.offset);
-               if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK))
-                       readl(pll->pll_base + ctrl->sw_ctrl.offset);
+               iproc_pll_write(pll, pll->control_base, ctrl->sw_ctrl.offset,
+                               val);
        }
 }
 
@@ -606,13 +617,12 @@ void __init iproc_pll_clk_setup(struct device_node *node,
        if (WARN_ON(!pll->clks))
                goto err_clks;
 
-       pll->pll_base = of_iomap(node, 0);
-       if (WARN_ON(!pll->pll_base))
+       pll->control_base = of_iomap(node, 0);
+       if (WARN_ON(!pll->control_base))
                goto err_pll_iomap;
 
+       /* Some SoCs do not require the pwr_base, thus failing is not fatal */
        pll->pwr_base = of_iomap(node, 1);
-       if (WARN_ON(!pll->pwr_base))
-               goto err_pwr_iomap;
 
        /* some PLLs require gating control at the top ASIU level */
        if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) {
@@ -621,6 +631,16 @@ void __init iproc_pll_clk_setup(struct device_node *node,
                        goto err_asiu_iomap;
        }
 
+       if (pll_ctrl->flags & IPROC_CLK_PLL_SPLIT_STAT_CTRL) {
+               /* Some SoCs have a split status/control.  If this does not
+                * exist, assume they are unified.
+                */
+               pll->status_base = of_iomap(node, 2);
+               if (!pll->status_base)
+                       goto err_status_iomap;
+       } else
+               pll->status_base = pll->control_base;
+
        /* initialize and register the PLL itself */
        pll->ctrl = pll_ctrl;
 
@@ -691,14 +711,18 @@ err_clk_register:
                clk_unregister(pll->clk_data.clks[i]);
 
 err_pll_register:
+       if (pll->status_base != pll->control_base)
+               iounmap(pll->status_base);
+
+err_status_iomap:
        if (pll->asiu_base)
                iounmap(pll->asiu_base);
 
 err_asiu_iomap:
-       iounmap(pll->pwr_base);
+       if (pll->pwr_base)
+               iounmap(pll->pwr_base);
 
-err_pwr_iomap:
-       iounmap(pll->pll_base);
+       iounmap(pll->control_base);
 
 err_pll_iomap:
        kfree(pll->clks);
index d834b7abd5c6a703b8ebf361d70a96c3361ecb3d..8988de70a98cc3fd38c4d72212443ce8250ffca3 100644 (file)
  */
 #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4)
 
+/*
+ * Some PLLs use a different way to control clock power, via the PWRDWN bit in
+ * the PLL control register
+ */
+#define IPROC_CLK_EMBED_PWRCTRL BIT(5)
+
+/*
+ * Some PLLs have separate registers for Status and Control.  Identify this to
+ * let the driver know if additional registers need to be used
+ */
+#define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6)
+
 /*
  * Parameters for VCO frequency configuration
  *
@@ -88,12 +100,19 @@ struct iproc_pll_aon_pwr_ctrl {
 };
 
 /*
- * Control of the PLL reset, with Ki, Kp, and Ka parameters
+ * Control of the PLL reset
  */
 struct iproc_pll_reset_ctrl {
        unsigned int offset;
        unsigned int reset_shift;
        unsigned int p_reset_shift;
+};
+
+/*
+ * Control of the Ki, Kp, and Ka parameters
+ */
+struct iproc_pll_dig_filter_ctrl {
+       unsigned int offset;
        unsigned int ki_shift;
        unsigned int ki_width;
        unsigned int kp_shift;
@@ -123,6 +142,7 @@ struct iproc_pll_ctrl {
        struct iproc_pll_aon_pwr_ctrl aon;
        struct iproc_asiu_gate asiu;
        struct iproc_pll_reset_ctrl reset;
+       struct iproc_pll_dig_filter_ctrl dig_filter;
        struct iproc_pll_sw_ctrl sw_ctrl;
        struct iproc_clk_reg_op ndiv_int;
        struct iproc_clk_reg_op ndiv_frac;
diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c
new file mode 100644 (file)
index 0000000..a564e92
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/bcm-ns2.h>
+#include "clk-iproc.h"
+
+#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
+
+#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
+       .pwr_shift = ps, .iso_shift = is }
+
+#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
+       .p_reset_shift = prs }
+
+#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
+       .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas,    \
+       .ka_width = kaw }
+
+#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
+
+#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
+       .hold_shift = hs, .bypass_shift = bs }
+
+static const struct iproc_pll_ctrl genpll_scr = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+       .aon = AON_VAL(0x0, 1, 15, 12),
+       .reset = RESET_VAL(0x4, 2, 1),
+       .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
+       .ndiv_int = REG_VAL(0x8, 4, 10),
+       .pdiv = REG_VAL(0x8, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+       .status = REG_VAL(0x0, 27, 1),
+};
+
+
+static const struct iproc_clk_ctrl genpll_scr_clk[] = {
+       /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+        * in NS2.  However, it doesn't appear to be used anywhere, so setting
+        * it to 0.
+        */
+       [BCM_NS2_GENPLL_SCR_SCR_CLK] = {
+               .channel = BCM_NS2_GENPLL_SCR_SCR_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 18, 12, 0),
+               .mdiv = REG_VAL(0x18, 0, 8),
+       },
+       [BCM_NS2_GENPLL_SCR_FS_CLK] = {
+               .channel = BCM_NS2_GENPLL_SCR_FS_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 19, 13, 0),
+               .mdiv = REG_VAL(0x18, 8, 8),
+       },
+       [BCM_NS2_GENPLL_SCR_AUDIO_CLK] = {
+               .channel = BCM_NS2_GENPLL_SCR_AUDIO_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 20, 14, 0),
+               .mdiv = REG_VAL(0x14, 0, 8),
+       },
+       [BCM_NS2_GENPLL_SCR_CH3_UNUSED] = {
+               .channel = BCM_NS2_GENPLL_SCR_CH3_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 21, 15, 0),
+               .mdiv = REG_VAL(0x14, 8, 8),
+       },
+       [BCM_NS2_GENPLL_SCR_CH4_UNUSED] = {
+               .channel = BCM_NS2_GENPLL_SCR_CH4_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 22, 16, 0),
+               .mdiv = REG_VAL(0x14, 16, 8),
+       },
+       [BCM_NS2_GENPLL_SCR_CH5_UNUSED] = {
+               .channel = BCM_NS2_GENPLL_SCR_CH5_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 23, 17, 0),
+               .mdiv = REG_VAL(0x14, 24, 8),
+       },
+};
+
+static void __init ns2_genpll_scr_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &genpll_scr, NULL, 0, genpll_scr_clk,
+                           ARRAY_SIZE(genpll_scr_clk));
+}
+CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr",
+              ns2_genpll_scr_clk_init);
+
+static const struct iproc_pll_ctrl genpll_sw = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+       .aon = AON_VAL(0x0, 2, 9, 8),
+       .reset = RESET_VAL(0x4, 2, 1),
+       .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3),
+       .ndiv_int = REG_VAL(0x8, 4, 10),
+       .pdiv = REG_VAL(0x8, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+       .status = REG_VAL(0x0, 13, 1),
+};
+
+static const struct iproc_clk_ctrl genpll_sw_clk[] = {
+       /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+        * in NS2.  However, it doesn't appear to be used anywhere, so setting
+        * it to 0.
+        */
+       [BCM_NS2_GENPLL_SW_RPE_CLK] = {
+               .channel = BCM_NS2_GENPLL_SW_RPE_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 18, 12, 0),
+               .mdiv = REG_VAL(0x18, 0, 8),
+       },
+       [BCM_NS2_GENPLL_SW_250_CLK] = {
+               .channel = BCM_NS2_GENPLL_SW_250_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 19, 13, 0),
+               .mdiv = REG_VAL(0x18, 8, 8),
+       },
+       [BCM_NS2_GENPLL_SW_NIC_CLK] = {
+               .channel = BCM_NS2_GENPLL_SW_NIC_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 20, 14, 0),
+               .mdiv = REG_VAL(0x14, 0, 8),
+       },
+       [BCM_NS2_GENPLL_SW_CHIMP_CLK] = {
+               .channel = BCM_NS2_GENPLL_SW_CHIMP_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 21, 15, 0),
+               .mdiv = REG_VAL(0x14, 8, 8),
+       },
+       [BCM_NS2_GENPLL_SW_PORT_CLK] = {
+               .channel = BCM_NS2_GENPLL_SW_PORT_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 22, 16, 0),
+               .mdiv = REG_VAL(0x14, 16, 8),
+       },
+       [BCM_NS2_GENPLL_SW_SDIO_CLK] = {
+               .channel = BCM_NS2_GENPLL_SW_SDIO_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 23, 17, 0),
+               .mdiv = REG_VAL(0x14, 24, 8),
+       },
+};
+
+static void __init ns2_genpll_sw_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &genpll_sw, NULL, 0, genpll_sw_clk,
+                           ARRAY_SIZE(genpll_sw_clk));
+}
+CLK_OF_DECLARE(ns2_genpll_sw_clk, "brcm,ns2-genpll-sw",
+              ns2_genpll_sw_clk_init);
+
+static const struct iproc_pll_ctrl lcpll_ddr = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+       .aon = AON_VAL(0x0, 2, 1, 0),
+       .reset = RESET_VAL(0x4, 2, 1),
+       .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4),
+       .ndiv_int = REG_VAL(0x8, 4, 10),
+       .pdiv = REG_VAL(0x8, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+       .status = REG_VAL(0x0, 0, 1),
+};
+
+static const struct iproc_clk_ctrl lcpll_ddr_clk[] = {
+       /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+        * in NS2.  However, it doesn't appear to be used anywhere, so setting
+        * it to 0.
+        */
+       [BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK] = {
+               .channel = BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 18, 12, 0),
+               .mdiv = REG_VAL(0x14, 0, 8),
+       },
+       [BCM_NS2_LCPLL_DDR_DDR_CLK] = {
+               .channel = BCM_NS2_LCPLL_DDR_DDR_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 19, 13, 0),
+               .mdiv = REG_VAL(0x14, 8, 8),
+       },
+       [BCM_NS2_LCPLL_DDR_CH2_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_DDR_CH2_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 20, 14, 0),
+               .mdiv = REG_VAL(0x10, 0, 8),
+       },
+       [BCM_NS2_LCPLL_DDR_CH3_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_DDR_CH3_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 21, 15, 0),
+               .mdiv = REG_VAL(0x10, 8, 8),
+       },
+       [BCM_NS2_LCPLL_DDR_CH4_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_DDR_CH4_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 22, 16, 0),
+               .mdiv = REG_VAL(0x10, 16, 8),
+       },
+       [BCM_NS2_LCPLL_DDR_CH5_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_DDR_CH5_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 23, 17, 0),
+               .mdiv = REG_VAL(0x10, 24, 8),
+       },
+};
+
+static void __init ns2_lcpll_ddr_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &lcpll_ddr, NULL, 0, lcpll_ddr_clk,
+                           ARRAY_SIZE(lcpll_ddr_clk));
+}
+CLK_OF_DECLARE(ns2_lcpll_ddr_clk, "brcm,ns2-lcpll-ddr",
+              ns2_lcpll_ddr_clk_init);
+
+static const struct iproc_pll_ctrl lcpll_ports = {
+       .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL,
+       .aon = AON_VAL(0x0, 2, 5, 4),
+       .reset = RESET_VAL(0x4, 2, 1),
+       .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4),
+       .ndiv_int = REG_VAL(0x8, 4, 10),
+       .pdiv = REG_VAL(0x8, 0, 4),
+       .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc),
+       .status = REG_VAL(0x0, 0, 1),
+};
+
+static const struct iproc_clk_ctrl lcpll_ports_clk[] = {
+       /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined
+        * in NS2.  However, it doesn't appear to be used anywhere, so setting
+        * it to 0.
+        */
+       [BCM_NS2_LCPLL_PORTS_WAN_CLK] = {
+               .channel = BCM_NS2_LCPLL_PORTS_WAN_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 18, 12, 0),
+               .mdiv = REG_VAL(0x14, 0, 8),
+       },
+       [BCM_NS2_LCPLL_PORTS_RGMII_CLK] = {
+               .channel = BCM_NS2_LCPLL_PORTS_RGMII_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 19, 13, 0),
+               .mdiv = REG_VAL(0x14, 8, 8),
+       },
+       [BCM_NS2_LCPLL_PORTS_CH2_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_PORTS_CH2_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 20, 14, 0),
+               .mdiv = REG_VAL(0x10, 0, 8),
+       },
+       [BCM_NS2_LCPLL_PORTS_CH3_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_PORTS_CH3_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 21, 15, 0),
+               .mdiv = REG_VAL(0x10, 8, 8),
+       },
+       [BCM_NS2_LCPLL_PORTS_CH4_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_PORTS_CH4_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 22, 16, 0),
+               .mdiv = REG_VAL(0x10, 16, 8),
+       },
+       [BCM_NS2_LCPLL_PORTS_CH5_UNUSED] = {
+               .channel = BCM_NS2_LCPLL_PORTS_CH5_UNUSED,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 23, 17, 0),
+               .mdiv = REG_VAL(0x10, 24, 8),
+       },
+};
+
+static void __init ns2_lcpll_ports_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &lcpll_ports, NULL, 0, lcpll_ports_clk,
+                           ARRAY_SIZE(lcpll_ports_clk));
+}
+CLK_OF_DECLARE(ns2_lcpll_ports_clk, "brcm,ns2-lcpll-ports",
+              ns2_lcpll_ports_clk_init);
diff --git a/drivers/clk/bcm/clk-nsp.c b/drivers/clk/bcm/clk-nsp.c
new file mode 100644 (file)
index 0000000..cf66f64
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/bcm-nsp.h>
+#include "clk-iproc.h"
+
+#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
+
+#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
+       .pwr_shift = ps, .iso_shift = is }
+
+#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
+       .p_reset_shift = prs }
+
+#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\
+       .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas,    \
+       .ka_width = kaw }
+
+#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
+       .hold_shift = hs, .bypass_shift = bs }
+
+static void __init nsp_armpll_init(struct device_node *node)
+{
+       iproc_armpll_setup(node);
+}
+CLK_OF_DECLARE(nsp_armpll, "brcm,nsp-armpll", nsp_armpll_init);
+
+static const struct iproc_pll_ctrl genpll = {
+       .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL,
+       .aon = AON_VAL(0x0, 1, 12, 0),
+       .reset = RESET_VAL(0x0, 11, 10),
+       .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
+       .ndiv_int = REG_VAL(0x14, 20, 10),
+       .ndiv_frac = REG_VAL(0x14, 0, 20),
+       .pdiv = REG_VAL(0x18, 24, 3),
+       .status = REG_VAL(0x20, 12, 1),
+};
+
+static const struct iproc_clk_ctrl genpll_clk[] = {
+       [BCM_NSP_GENPLL_PHY_CLK] = {
+               .channel = BCM_NSP_GENPLL_PHY_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 12, 6, 18),
+               .mdiv = REG_VAL(0x18, 16, 8),
+       },
+       [BCM_NSP_GENPLL_ENET_SW_CLK] = {
+               .channel = BCM_NSP_GENPLL_ENET_SW_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 13, 7, 19),
+               .mdiv = REG_VAL(0x18, 8, 8),
+       },
+       [BCM_NSP_GENPLL_USB_PHY_REF_CLK] = {
+               .channel = BCM_NSP_GENPLL_USB_PHY_REF_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 14, 8, 20),
+               .mdiv = REG_VAL(0x18, 0, 8),
+       },
+       [BCM_NSP_GENPLL_IPROCFAST_CLK] = {
+               .channel = BCM_NSP_GENPLL_IPROCFAST_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 15, 9, 21),
+               .mdiv = REG_VAL(0x1c, 16, 8),
+       },
+       [BCM_NSP_GENPLL_SATA1_CLK] = {
+               .channel = BCM_NSP_GENPLL_SATA1_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 16, 10, 22),
+               .mdiv = REG_VAL(0x1c, 8, 8),
+       },
+       [BCM_NSP_GENPLL_SATA2_CLK] = {
+               .channel = BCM_NSP_GENPLL_SATA2_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x4, 17, 11, 23),
+               .mdiv = REG_VAL(0x1c, 0, 8),
+       },
+};
+
+static void __init nsp_genpll_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &genpll, NULL, 0, genpll_clk,
+                           ARRAY_SIZE(genpll_clk));
+}
+CLK_OF_DECLARE(nsp_genpll_clk, "brcm,nsp-genpll", nsp_genpll_clk_init);
+
+static const struct iproc_pll_ctrl lcpll0 = {
+       .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL,
+       .aon = AON_VAL(0x0, 1, 24, 0),
+       .reset = RESET_VAL(0x0, 23, 22),
+       .dig_filter = DF_VAL(0x0, 16, 3, 12, 4, 19, 4),
+       .ndiv_int = REG_VAL(0x4, 20, 8),
+       .ndiv_frac = REG_VAL(0x4, 0, 20),
+       .pdiv = REG_VAL(0x4, 28, 3),
+       .status = REG_VAL(0x10, 12, 1),
+};
+
+static const struct iproc_clk_ctrl lcpll0_clk[] = {
+       [BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK] = {
+               .channel = BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 6, 3, 9),
+               .mdiv = REG_VAL(0x8, 24, 8),
+       },
+       [BCM_NSP_LCPLL0_SDIO_CLK] = {
+               .channel = BCM_NSP_LCPLL0_SDIO_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 7, 4, 10),
+               .mdiv = REG_VAL(0x8, 16, 8),
+       },
+       [BCM_NSP_LCPLL0_DDR_PHY_CLK] = {
+               .channel = BCM_NSP_LCPLL0_DDR_PHY_CLK,
+               .flags = IPROC_CLK_AON,
+               .enable = ENABLE_VAL(0x0, 8, 5, 11),
+               .mdiv = REG_VAL(0x8, 8, 8),
+       },
+};
+
+static void __init nsp_lcpll0_clk_init(struct device_node *node)
+{
+       iproc_pll_clk_setup(node, &lcpll0, NULL, 0, lcpll0_clk,
+                           ARRAY_SIZE(lcpll0_clk));
+}
+CLK_OF_DECLARE(nsp_lcpll0_clk, "brcm,nsp-lcpll0", nsp_lcpll0_clk_init);
index 73153fc45ee93067562732b66dd93da201a791b4..23e0e3be6c377e342cb19a6b84ff7c1be5cd4406 100644 (file)
@@ -490,8 +490,8 @@ static const struct berlin2_gate_data bg2_gates[] __initconst = {
        { "usb0",       "perif",        11 },
        { "usb1",       "perif",        12 },
        { "pbridge",    "perif",        13, CLK_IGNORE_UNUSED },
-       { "sdio0",      "perif",        14, CLK_IGNORE_UNUSED },
-       { "sdio1",      "perif",        15, CLK_IGNORE_UNUSED },
+       { "sdio0",      "perif",        14 },
+       { "sdio1",      "perif",        15 },
        { "nfc",        "perif",        17 },
        { "smemc",      "perif",        19 },
        { "audiohd",    "audiohd_pll",  26 },
index 72d2f3500db85ba5d27bf173af90d9689bc1b491..f144547cf76ca94767eac93de9e8d82a0b4d7c7d 100644 (file)
@@ -283,7 +283,7 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = {
        { "usb2",       "perif",        13 },
        { "usb3",       "perif",        14 },
        { "pbridge",    "perif",        15, CLK_IGNORE_UNUSED },
-       { "sdio",       "perif",        16, CLK_IGNORE_UNUSED },
+       { "sdio",       "perif",        16 },
        { "nfc",        "perif",        18 },
        { "pcie",       "perif",        22 },
 };
index f24d0a19ae70aa8cc2a1210ab03da617d048aff0..3ace102a2a0a4da1d3c0046181de2cca8b406d0e 100644 (file)
@@ -24,7 +24,7 @@
  * Traits of this clock:
  * prepare - clk_prepare only ensures that parents are prepared
  * enable - clk_enable only ensures that parents are enabled
- * rate - rate is adjustable.  clk->rate = DIV_ROUND_UP(parent->rate / divisor)
+ * rate - rate is adjustable.  clk->rate = ceiling(parent->rate / divisor)
  * parent - fixed parent.  No clk_set_parent support
  */
 
@@ -132,7 +132,7 @@ unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate,
                return parent_rate;
        }
 
-       return DIV_ROUND_UP(parent_rate, div);
+       return DIV_ROUND_UP_ULL((u64)parent_rate, div);
 }
 EXPORT_SYMBOL_GPL(divider_recalc_rate);
 
@@ -210,7 +210,7 @@ static int _div_round_up(const struct clk_div_table *table,
                         unsigned long parent_rate, unsigned long rate,
                         unsigned long flags)
 {
-       int div = DIV_ROUND_UP(parent_rate, rate);
+       int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
 
        if (flags & CLK_DIVIDER_POWER_OF_TWO)
                div = __roundup_pow_of_two(div);
@@ -227,7 +227,7 @@ static int _div_round_closest(const struct clk_div_table *table,
        int up, down;
        unsigned long up_rate, down_rate;
 
-       up = DIV_ROUND_UP(parent_rate, rate);
+       up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
        down = parent_rate / rate;
 
        if (flags & CLK_DIVIDER_POWER_OF_TWO) {
@@ -238,8 +238,8 @@ static int _div_round_closest(const struct clk_div_table *table,
                down = _round_down_table(table, down);
        }
 
-       up_rate = DIV_ROUND_UP(parent_rate, up);
-       down_rate = DIV_ROUND_UP(parent_rate, down);
+       up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
+       down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
 
        return (rate - up_rate) <= (down_rate - rate) ? up : down;
 }
@@ -318,7 +318,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
                }
                parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
                                               rate * i);
-               now = DIV_ROUND_UP(parent_rate, i);
+               now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
                if (_is_best_div(rate, now, best, flags)) {
                        bestdiv = i;
                        best = now;
@@ -342,7 +342,7 @@ long divider_round_rate(struct clk_hw *hw, unsigned long rate,
 
        div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
 
-       return DIV_ROUND_UP(*prate, div);
+       return DIV_ROUND_UP_ULL((u64)*prate, div);
 }
 EXPORT_SYMBOL_GPL(divider_round_rate);
 
@@ -358,7 +358,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
                bestdiv &= div_mask(divider->width);
                bestdiv = _get_div(divider->table, bestdiv, divider->flags,
                        divider->width);
-               return DIV_ROUND_UP(*prate, bestdiv);
+               return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
        }
 
        return divider_round_rate(hw, rate, prate, divider->table,
@@ -371,7 +371,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
 {
        unsigned int div, value;
 
-       div = DIV_ROUND_UP(parent_rate, rate);
+       div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
 
        if (!_is_valid_div(table, div, flags))
                return -EINVAL;
index e85f856b859219b1987dda9a403e07f4ded45769..5c4955e33f7a259711b960593941df38d526f2bb 100644 (file)
@@ -7,13 +7,14 @@
  *
  * Adjustable fractional divider clock implementation.
  * Output rate = (m / n) * parent_rate.
+ * Uses rational best approximation algorithm.
  */
 
 #include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/slab.h>
-#include <linux/gcd.h>
+#include <linux/rational.h>
 
 #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw)
 
@@ -22,7 +23,8 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
 {
        struct clk_fractional_divider *fd = to_clk_fd(hw);
        unsigned long flags = 0;
-       u32 val, m, n;
+       unsigned long m, n;
+       u32 val;
        u64 ret;
 
        if (fd->lock)
@@ -50,23 +52,33 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw,
 }
 
 static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
-                             unsigned long *prate)
+                             unsigned long *parent_rate)
 {
        struct clk_fractional_divider *fd = to_clk_fd(hw);
-       unsigned maxn = (fd->nmask >> fd->nshift) + 1;
-       unsigned div;
+       unsigned long scale;
+       unsigned long m, n;
+       u64 ret;
 
-       if (!rate || rate >= *prate)
-               return *prate;
+       if (!rate || rate >= *parent_rate)
+               return *parent_rate;
 
-       div = gcd(*prate, rate);
+       /*
+        * Get rate closer to *parent_rate to guarantee there is no overflow
+        * for m and n. In the result it will be the nearest rate left shifted
+        * by (scale - fd->nwidth) bits.
+        */
+       scale = fls_long(*parent_rate / rate - 1);
+       if (scale > fd->nwidth)
+               rate <<= scale - fd->nwidth;
 
-       while ((*prate / div) > maxn) {
-               div <<= 1;
-               rate <<= 1;
-       }
+       rational_best_approximation(rate, *parent_rate,
+                       GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+                       &m, &n);
 
-       return rate;
+       ret = (u64)*parent_rate * m;
+       do_div(ret, n);
+
+       return ret;
 }
 
 static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -74,13 +86,12 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct clk_fractional_divider *fd = to_clk_fd(hw);
        unsigned long flags = 0;
-       unsigned long div;
-       unsigned n, m;
+       unsigned long m, n;
        u32 val;
 
-       div = gcd(parent_rate, rate);
-       m = rate / div;
-       n = parent_rate / div;
+       rational_best_approximation(rate, parent_rate,
+                       GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
+                       &m, &n);
 
        if (fd->lock)
                spin_lock_irqsave(fd->lock, flags);
@@ -128,9 +139,11 @@ struct clk *clk_register_fractional_divider(struct device *dev,
 
        fd->reg = reg;
        fd->mshift = mshift;
-       fd->mmask = (BIT(mwidth) - 1) << mshift;
+       fd->mwidth = mwidth;
+       fd->mmask = GENMASK(mwidth - 1, 0) << mshift;
        fd->nshift = nshift;
-       fd->nmask = (BIT(nwidth) - 1) << nshift;
+       fd->nwidth = nwidth;
+       fd->nmask = GENMASK(nwidth - 1, 0) << nshift;
        fd->flags = clk_divider_flags;
        fd->lock = lock;
        fd->hw.init = &init;
index 74c49b93a6eba5c40f28342f7d4ab4225c477795..4a89f7979ba070c3a90b93d7fdd757d3fd76ab8b 100644 (file)
@@ -94,5 +94,5 @@ static struct platform_driver max77802_clk_driver = {
 module_platform_driver(max77802_clk_driver);
 
 MODULE_DESCRIPTION("MAXIM 77802 Clock Driver");
-MODULE_AUTHOR("Javier Martinez Canillas <javier.martinez@collabora.co.uk>");
+MODULE_AUTHOR("Javier Martinez Canillas <javier@osg.samsung.com");
 MODULE_LICENSE("GPL");
index 43ec269fcbffa2f17a64283b7f11d4ec16139538..fe7806506bf34e8a554a815cef99c5afba754b26 100644 (file)
@@ -128,54 +128,3 @@ const struct clk_ops clk_multiplier_ops = {
        .set_rate       = clk_multiplier_set_rate,
 };
 EXPORT_SYMBOL_GPL(clk_multiplier_ops);
-
-struct clk *clk_register_multiplier(struct device *dev, const char *name,
-                                   const char *parent_name,
-                                   unsigned long flags,
-                                   void __iomem *reg, u8 shift, u8 width,
-                                   u8 clk_mult_flags, spinlock_t *lock)
-{
-       struct clk_init_data init;
-       struct clk_multiplier *mult;
-       struct clk *clk;
-
-       mult = kmalloc(sizeof(*mult), GFP_KERNEL);
-       if (!mult)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.ops = &clk_multiplier_ops;
-       init.flags = flags | CLK_IS_BASIC;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-
-       mult->reg = reg;
-       mult->shift = shift;
-       mult->width = width;
-       mult->flags = clk_mult_flags;
-       mult->lock = lock;
-       mult->hw.init = &init;
-
-       clk = clk_register(dev, &mult->hw);
-       if (IS_ERR(clk))
-               kfree(mult);
-
-       return clk;
-}
-EXPORT_SYMBOL_GPL(clk_register_multiplier);
-
-void clk_unregister_multiplier(struct clk *clk)
-{
-       struct clk_multiplier *mult;
-       struct clk_hw *hw;
-
-       hw = __clk_get_hw(clk);
-       if (!hw)
-               return;
-
-       mult = to_clk_multiplier(hw);
-
-       clk_unregister(clk);
-       kfree(mult);
-}
-EXPORT_SYMBOL_GPL(clk_unregister_multiplier);
diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c
new file mode 100644 (file)
index 0000000..6af7dce
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * Driver for Silicon Labs Si514 Programmable Oscillator
+ *
+ * Copyright (C) 2015 Topic Embedded Products
+ *
+ * Author: Mike Looijmans <mike.looijmans@topic.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* I2C registers */
+#define SI514_REG_LP           0
+#define SI514_REG_M_FRAC1      5
+#define SI514_REG_M_FRAC2      6
+#define SI514_REG_M_FRAC3      7
+#define SI514_REG_M_INT_FRAC   8
+#define SI514_REG_M_INT                9
+#define SI514_REG_HS_DIV       10
+#define SI514_REG_LS_HS_DIV    11
+#define SI514_REG_OE_STATE     14
+#define SI514_REG_RESET                128
+#define SI514_REG_CONTROL      132
+
+/* Register values */
+#define SI514_RESET_RST                BIT(7)
+
+#define SI514_CONTROL_FCAL     BIT(0)
+#define SI514_CONTROL_OE       BIT(2)
+
+#define SI514_MIN_FREQ     100000U
+#define SI514_MAX_FREQ  250000000U
+
+#define FXO              31980000U
+
+#define FVCO_MIN       2080000000U
+#define FVCO_MAX       2500000000U
+
+#define HS_DIV_MAX     1022
+
+struct clk_si514 {
+       struct clk_hw hw;
+       struct regmap *regmap;
+       struct i2c_client *i2c_client;
+};
+#define to_clk_si514(_hw)      container_of(_hw, struct clk_si514, hw)
+
+/* Multiplier/divider settings */
+struct clk_si514_muldiv {
+       u32 m_frac;  /* 29-bit Fractional part of multiplier M */
+       u8 m_int; /* Integer part of multiplier M, 65..78 */
+       u8 ls_div_bits; /* 2nd divider, as 2^x */
+       u16 hs_div; /* 1st divider, must be even and 10<=x<=1022 */
+};
+
+/* Enables or disables the output driver */
+static int si514_enable_output(struct clk_si514 *data, bool enable)
+{
+       return regmap_update_bits(data->regmap, SI514_REG_CONTROL,
+               SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0);
+}
+
+/* Retrieve clock multiplier and dividers from hardware */
+static int si514_get_muldiv(struct clk_si514 *data,
+       struct clk_si514_muldiv *settings)
+{
+       int err;
+       u8 reg[7];
+
+       err = regmap_bulk_read(data->regmap, SI514_REG_M_FRAC1,
+                       reg, ARRAY_SIZE(reg));
+       if (err)
+               return err;
+
+       settings->m_frac = reg[0] | reg[1] << 8 | reg[2] << 16 |
+                          (reg[3] & 0x1F) << 24;
+       settings->m_int = (reg[4] & 0x3f) << 3 | reg[3] >> 5;
+       settings->ls_div_bits = (reg[6] >> 4) & 0x07;
+       settings->hs_div = (reg[6] & 0x03) << 8 | reg[5];
+       return 0;
+}
+
+static int si514_set_muldiv(struct clk_si514 *data,
+       struct clk_si514_muldiv *settings)
+{
+       u8 lp;
+       u8 reg[7];
+       int err;
+
+       /* Calculate LP1/LP2 according to table 13 in the datasheet */
+       /* 65.259980246 */
+       if (settings->m_int < 65 ||
+               (settings->m_int == 65 && settings->m_frac <= 139575831))
+               lp = 0x22;
+       /* 67.859763463 */
+       else if (settings->m_int < 67 ||
+               (settings->m_int == 67 && settings->m_frac <= 461581994))
+               lp = 0x23;
+       /* 72.937624981 */
+       else if (settings->m_int < 72 ||
+               (settings->m_int == 72 && settings->m_frac <= 503383578))
+               lp = 0x33;
+       /* 75.843265046 */
+       else if (settings->m_int < 75 ||
+               (settings->m_int == 75 && settings->m_frac <= 452724474))
+               lp = 0x34;
+       else
+               lp = 0x44;
+
+       err = regmap_write(data->regmap, SI514_REG_LP, lp);
+       if (err < 0)
+               return err;
+
+       reg[0] = settings->m_frac;
+       reg[1] = settings->m_frac >> 8;
+       reg[2] = settings->m_frac >> 16;
+       reg[3] = settings->m_frac >> 24 | settings->m_int << 5;
+       reg[4] = settings->m_int >> 3;
+       reg[5] = settings->hs_div;
+       reg[6] = (settings->hs_div >> 8) | (settings->ls_div_bits << 4);
+
+       err = regmap_bulk_write(data->regmap, SI514_REG_HS_DIV, reg + 5, 2);
+       if (err < 0)
+               return err;
+       /*
+        * Writing to SI514_REG_M_INT_FRAC triggers the clock change, so that
+        * must be written last
+        */
+       return regmap_bulk_write(data->regmap, SI514_REG_M_FRAC1, reg, 5);
+}
+
+/* Calculate divider settings for a given frequency */
+static int si514_calc_muldiv(struct clk_si514_muldiv *settings,
+       unsigned long frequency)
+{
+       u64 m;
+       u32 ls_freq;
+       u32 tmp;
+       u8 res;
+
+       if ((frequency < SI514_MIN_FREQ) || (frequency > SI514_MAX_FREQ))
+               return -EINVAL;
+
+       /* Determine the minimum value of LS_DIV and resulting target freq. */
+       ls_freq = frequency;
+       if (frequency >= (FVCO_MIN / HS_DIV_MAX))
+               settings->ls_div_bits = 0;
+       else {
+               res = 1;
+               tmp = 2 * HS_DIV_MAX;
+               while (tmp <= (HS_DIV_MAX * 32)) {
+                       if ((frequency * tmp) >= FVCO_MIN)
+                               break;
+                       ++res;
+                       tmp <<= 1;
+               }
+               settings->ls_div_bits = res;
+               ls_freq = frequency << res;
+       }
+
+       /* Determine minimum HS_DIV, round up to even number */
+       settings->hs_div = DIV_ROUND_UP(FVCO_MIN >> 1, ls_freq) << 1;
+
+       /* M = LS_DIV x HS_DIV x frequency / F_XO (in fixed-point) */
+       m = ((u64)(ls_freq * settings->hs_div) << 29) + (FXO / 2);
+       do_div(m, FXO);
+       settings->m_frac = (u32)m & (BIT(29) - 1);
+       settings->m_int = (u32)(m >> 29);
+
+       return 0;
+}
+
+/* Calculate resulting frequency given the register settings */
+static unsigned long si514_calc_rate(struct clk_si514_muldiv *settings)
+{
+       u64 m = settings->m_frac | ((u64)settings->m_int << 29);
+       u32 d = settings->hs_div * BIT(settings->ls_div_bits);
+
+       return ((u32)(((m * FXO) + (FXO / 2)) >> 29)) / d;
+}
+
+static unsigned long si514_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_si514 *data = to_clk_si514(hw);
+       struct clk_si514_muldiv settings;
+       int err;
+
+       err = si514_get_muldiv(data, &settings);
+       if (err) {
+               dev_err(&data->i2c_client->dev, "unable to retrieve settings\n");
+               return 0;
+       }
+
+       return si514_calc_rate(&settings);
+}
+
+static long si514_round_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long *parent_rate)
+{
+       struct clk_si514_muldiv settings;
+       int err;
+
+       if (!rate)
+               return 0;
+
+       err = si514_calc_muldiv(&settings, rate);
+       if (err)
+               return err;
+
+       return si514_calc_rate(&settings);
+}
+
+/*
+ * Update output frequency for big frequency changes (> 1000 ppm).
+ * The chip supports <1000ppm changes "on the fly", we haven't implemented
+ * that here.
+ */
+static int si514_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_si514 *data = to_clk_si514(hw);
+       struct clk_si514_muldiv settings;
+       int err;
+
+       err = si514_calc_muldiv(&settings, rate);
+       if (err)
+               return err;
+
+       si514_enable_output(data, false);
+
+       err = si514_set_muldiv(data, &settings);
+       if (err < 0)
+               return err; /* Undefined state now, best to leave disabled */
+
+       /* Trigger calibration */
+       err = regmap_write(data->regmap, SI514_REG_CONTROL, SI514_CONTROL_FCAL);
+       if (err < 0)
+               return err;
+
+       /* Applying a new frequency can take up to 10ms */
+       usleep_range(10000, 12000);
+
+       si514_enable_output(data, true);
+
+       return err;
+}
+
+static const struct clk_ops si514_clk_ops = {
+       .recalc_rate = si514_recalc_rate,
+       .round_rate = si514_round_rate,
+       .set_rate = si514_set_rate,
+};
+
+static bool si514_regmap_is_volatile(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case SI514_REG_CONTROL:
+       case SI514_REG_RESET:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool si514_regmap_is_writeable(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case SI514_REG_LP:
+       case SI514_REG_M_FRAC1 ... SI514_REG_LS_HS_DIV:
+       case SI514_REG_OE_STATE:
+       case SI514_REG_RESET:
+       case SI514_REG_CONTROL:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const struct regmap_config si514_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .cache_type = REGCACHE_RBTREE,
+       .max_register = SI514_REG_CONTROL,
+       .writeable_reg = si514_regmap_is_writeable,
+       .volatile_reg = si514_regmap_is_volatile,
+};
+
+static int si514_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+{
+       struct clk_si514 *data;
+       struct clk_init_data init;
+       struct clk *clk;
+       int err;
+
+       data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       init.ops = &si514_clk_ops;
+       init.flags = CLK_IS_ROOT;
+       init.num_parents = 0;
+       data->hw.init = &init;
+       data->i2c_client = client;
+
+       if (of_property_read_string(client->dev.of_node, "clock-output-names",
+                       &init.name))
+               init.name = client->dev.of_node->name;
+
+       data->regmap = devm_regmap_init_i2c(client, &si514_regmap_config);
+       if (IS_ERR(data->regmap)) {
+               dev_err(&client->dev, "failed to allocate register map\n");
+               return PTR_ERR(data->regmap);
+       }
+
+       i2c_set_clientdata(client, data);
+
+       clk = devm_clk_register(&client->dev, &data->hw);
+       if (IS_ERR(clk)) {
+               dev_err(&client->dev, "clock registration failed\n");
+               return PTR_ERR(clk);
+       }
+       err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get,
+                       clk);
+       if (err) {
+               dev_err(&client->dev, "unable to add clk provider\n");
+               return err;
+       }
+
+       return 0;
+}
+
+static int si514_remove(struct i2c_client *client)
+{
+       of_clk_del_provider(client->dev.of_node);
+       return 0;
+}
+
+static const struct i2c_device_id si514_id[] = {
+       { "si514", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, si514_id);
+
+static const struct of_device_id clk_si514_of_match[] = {
+       { .compatible = "silabs,si514" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, clk_si514_of_match);
+
+static struct i2c_driver si514_driver = {
+       .driver = {
+               .name = "si514",
+               .of_match_table = clk_si514_of_match,
+       },
+       .probe          = si514_probe,
+       .remove         = si514_remove,
+       .id_table       = si514_id,
+};
+module_i2c_driver(si514_driver);
+
+MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
+MODULE_DESCRIPTION("Si514 driver");
+MODULE_LICENSE("GPL");
index 5596c0aac22f8f4f1a639d6e3cf01ad92c7e0df4..e346b223199d5a5f742cd783f01fcb588b9f1b9f 100644 (file)
@@ -1183,13 +1183,13 @@ static int si5351_dt_parse(struct i2c_client *client,
                if (of_property_read_u32(child, "reg", &num)) {
                        dev_err(&client->dev, "missing reg property of %s\n",
                                child->name);
-                       return -EINVAL;
+                       goto put_child;
                }
 
                if (num >= 8 ||
                    (variant == SI5351_VARIANT_A3 && num >= 3)) {
                        dev_err(&client->dev, "invalid clkout %d\n", num);
-                       return -EINVAL;
+                       goto put_child;
                }
 
                if (!of_property_read_u32(child, "silabs,multisynth-source",
@@ -1207,7 +1207,7 @@ static int si5351_dt_parse(struct i2c_client *client,
                                dev_err(&client->dev,
                                        "invalid parent %d for multisynth %d\n",
                                        val, num);
-                               return -EINVAL;
+                               goto put_child;
                        }
                }
 
@@ -1230,7 +1230,7 @@ static int si5351_dt_parse(struct i2c_client *client,
                                        dev_err(&client->dev,
                                                "invalid parent %d for clkout %d\n",
                                                val, num);
-                                       return -EINVAL;
+                                       goto put_child;
                                }
                                pdata->clkout[num].clkout_src =
                                        SI5351_CLKOUT_SRC_CLKIN;
@@ -1239,7 +1239,7 @@ static int si5351_dt_parse(struct i2c_client *client,
                                dev_err(&client->dev,
                                        "invalid parent %d for clkout %d\n",
                                        val, num);
-                               return -EINVAL;
+                               goto put_child;
                        }
                }
 
@@ -1256,7 +1256,7 @@ static int si5351_dt_parse(struct i2c_client *client,
                                dev_err(&client->dev,
                                        "invalid drive strength %d for clkout %d\n",
                                        val, num);
-                               return -EINVAL;
+                               goto put_child;
                        }
                }
 
@@ -1283,7 +1283,7 @@ static int si5351_dt_parse(struct i2c_client *client,
                                dev_err(&client->dev,
                                        "invalid disable state %d for clkout %d\n",
                                        val, num);
-                               return -EINVAL;
+                               goto put_child;
                        }
                }
 
@@ -1296,6 +1296,9 @@ static int si5351_dt_parse(struct i2c_client *client,
        client->dev.platform_data = pdata;
 
        return 0;
+put_child:
+       of_node_put(child);
+       return -EINVAL;
 }
 #else
 static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant)
index 96a6190acac230844d7c3588754d4280dc6d8f0e..27c0da29eca3dc6c67496ac45de696911f732955 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
 #include <linux/of_address.h>
-#include <asm/setup.h>
 
 /* Register SCU_PCPPLL bit fields */
 #define N_DIV_RD(src)                  (((src) & 0x000001ff))
index 0ebcf449778abc18e9956733ebb55db2e5dc77f9..f13c3f4228d4d51d5649c3705fd565b4aac82913 100644 (file)
@@ -272,7 +272,7 @@ late_initcall_sync(clk_disable_unused);
 
 /***    helper functions   ***/
 
-const char *__clk_get_name(struct clk *clk)
+const char *__clk_get_name(const struct clk *clk)
 {
        return !clk ? NULL : clk->core->name;
 }
@@ -427,6 +427,11 @@ bool clk_hw_is_prepared(const struct clk_hw *hw)
        return clk_core_is_prepared(hw->core);
 }
 
+bool clk_hw_is_enabled(const struct clk_hw *hw)
+{
+       return clk_core_is_enabled(hw->core);
+}
+
 bool __clk_is_enabled(struct clk *clk)
 {
        if (!clk)
@@ -1685,7 +1690,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core)
                        "%s: multi-parent clocks must implement .get_parent\n",
                        __func__);
                goto out;
-       };
+       }
 
        /*
         * Do our best to cache parent clocks in core->parents.  This prevents
@@ -2932,7 +2937,7 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data)
        unsigned int idx = clkspec->args[0];
 
        if (idx >= clk_data->clk_num) {
-               pr_err("%s: invalid clock index %d\n", __func__, idx);
+               pr_err("%s: invalid clock index %u\n", __func__, idx);
                return ERR_PTR(-EINVAL);
        }
 
@@ -3055,6 +3060,7 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
        u32 pv;
        int rc;
        int count;
+       struct clk *clk;
 
        if (index < 0)
                return NULL;
@@ -3080,8 +3086,25 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
 
        if (of_property_read_string_index(clkspec.np, "clock-output-names",
                                          index,
-                                         &clk_name) < 0)
-               clk_name = clkspec.np->name;
+                                         &clk_name) < 0) {
+               /*
+                * Best effort to get the name if the clock has been
+                * registered with the framework. If the clock isn't
+                * registered, we return the node name as the name of
+                * the clock as long as #clock-cells = 0.
+                */
+               clk = of_clk_get_from_provider(&clkspec);
+               if (IS_ERR(clk)) {
+                       if (clkspec.args_count == 0)
+                               clk_name = clkspec.np->name;
+                       else
+                               clk_name = NULL;
+               } else {
+                       clk_name = __clk_get_name(clk);
+                       clk_put(clk);
+               }
+       }
+
 
        of_node_put(clkspec.np);
        return clk_name;
@@ -3179,13 +3202,15 @@ void __init of_clk_init(const struct of_device_id *matches)
                        list_for_each_entry_safe(clk_provider, next,
                                                 &clk_provider_list, node) {
                                list_del(&clk_provider->node);
+                               of_node_put(clk_provider->np);
                                kfree(clk_provider);
                        }
+                       of_node_put(np);
                        return;
                }
 
                parent->clk_init_cb = match->data;
-               parent->np = np;
+               parent->np = of_node_get(np);
                list_add_tail(&parent->node, &clk_provider_list);
        }
 
@@ -3199,6 +3224,7 @@ void __init of_clk_init(const struct of_device_id *matches)
                                of_clk_set_defaults(clk_provider->np, true);
 
                                list_del(&clk_provider->node);
+                               of_node_put(clk_provider->np);
                                kfree(clk_provider);
                                is_init_done = true;
                        }
index 2c4add11c1ca379bf594c8d8d2798cf8cdced2a6..8afb40ef40ce81f884de1b0b677b86fc5fb5ed7d 100644 (file)
@@ -230,7 +230,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev)
        if (IS_ERR(stub_clk->mbox)) {
                dev_err(dev, "failed get mailbox channel\n");
                return PTR_ERR(stub_clk->mbox);
-       };
+       }
 
        init.name = "acpu0";
        init.ops = &hi6220_stub_clk_ops;
index 0d7b8df04dfa8ed66463572f8d0d0a5b24cb3140..cf5cf75a484872ce516fe82f548cb629ea7726a7 100644 (file)
@@ -261,8 +261,10 @@ static void __init mx27_clocks_init_dt(struct device_node *np)
                if (!of_device_is_compatible(refnp, "fsl,imx-osc26m"))
                        continue;
 
-               if (!of_property_read_u32(refnp, "clock-frequency", &fref))
+               if (!of_property_read_u32(refnp, "clock-frequency", &fref)) {
+                       of_node_put(refnp);
                        break;
+               }
        }
 
        ccm = of_iomap(np, 0);
index f65b8b1a974ac4b3d91be2d5af87d904d13c3e70..6a964144a5b5df1d3d134e22bfcd8464f510e6a3 100644 (file)
@@ -233,8 +233,10 @@ int __init mx31_clocks_init_dt(void)
                if (!of_device_is_compatible(np, "fsl,imx-osc26m"))
                        continue;
 
-               if (!of_property_read_u32(np, "clock-frequency", &fref))
+               if (!of_property_read_u32(np, "clock-frequency", &fref)) {
+                       of_node_put(np);
                        break;
+               }
        }
 
        _mx31_clocks_init(fref);
index 20889d59b44d9230eabb3606e02f1024bc6b7188..b18f875eac6acadd7e0ae27644fe8af0df240af6 100644 (file)
@@ -77,7 +77,7 @@ struct clk_pllv2 {
 static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
                u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn)
 {
-       long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+       long mfi, mfn, mfd, pdf, ref_clk;
        unsigned long dbl;
        s64 temp;
 
@@ -87,19 +87,15 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate,
        mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
        mfi = (mfi <= 5) ? 5 : mfi;
        mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
-       mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
-       /* Sign extend to 32-bits */
-       if (mfn >= 0x04000000) {
-               mfn |= 0xFC000000;
-               mfn_abs = -mfn;
-       }
+       mfn = dp_mfn & MXC_PLL_DP_MFN_MASK;
+       mfn = sign_extend32(mfn, 26);
 
        ref_clk = 2 * parent_rate;
        if (dbl != 0)
                ref_clk *= 2;
 
        ref_clk /= (pdf + 1);
-       temp = (u64) ref_clk * mfn_abs;
+       temp = (u64) ref_clk * abs(mfn);
        do_div(temp, mfd + 1);
        if (mfn < 0)
                temp = -temp;
index 3f553d0ae0b5f885d3cee60c9f673870684f83fc..a26ba2184454a8654eca7d7ca3185b472e7ff46e 100644 (file)
@@ -157,7 +157,7 @@ out:
  * _of_clk_init - PLL initialisation via DT
  * @node: device tree node for this clock
  * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of
- *             pll controller, else it is in the control regsiter0(bit 11-6)
+ *             pll controller, else it is in the control register0(bit 11-6)
  */
 static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
 {
index 8e4b2a4635b96cb998951590dfb62d263c31b8e2..95fdfacb2ebf6828162c911da86a847804200599 100644 (file)
@@ -1,4 +1,4 @@
-obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 obj-y += clk-mt8135.o
 obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
new file mode 100644 (file)
index 0000000..5303c59
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+#define REF2USB_TX_EN          BIT(0)
+#define REF2USB_TX_LPF_EN      BIT(1)
+#define REF2USB_TX_OUT_EN      BIT(2)
+#define REF2USB_EN_MASK                (REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
+                                REF2USB_TX_OUT_EN)
+
+struct mtk_ref2usb_tx {
+       struct clk_hw   hw;
+       void __iomem    *base_addr;
+};
+
+static inline struct mtk_ref2usb_tx *to_mtk_ref2usb_tx(struct clk_hw *hw)
+{
+       return container_of(hw, struct mtk_ref2usb_tx, hw);
+}
+
+static int mtk_ref2usb_tx_is_prepared(struct clk_hw *hw)
+{
+       struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+
+       return (readl(tx->base_addr) & REF2USB_EN_MASK) == REF2USB_EN_MASK;
+}
+
+static int mtk_ref2usb_tx_prepare(struct clk_hw *hw)
+{
+       struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+       u32 val;
+
+       val = readl(tx->base_addr);
+
+       val |= REF2USB_TX_EN;
+       writel(val, tx->base_addr);
+       udelay(100);
+
+       val |= REF2USB_TX_LPF_EN;
+       writel(val, tx->base_addr);
+
+       val |= REF2USB_TX_OUT_EN;
+       writel(val, tx->base_addr);
+
+       return 0;
+}
+
+static void mtk_ref2usb_tx_unprepare(struct clk_hw *hw)
+{
+       struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+       u32 val;
+
+       val = readl(tx->base_addr);
+       val &= ~REF2USB_EN_MASK;
+       writel(val, tx->base_addr);
+}
+
+static const struct clk_ops mtk_ref2usb_tx_ops = {
+       .is_prepared    = mtk_ref2usb_tx_is_prepared,
+       .prepare        = mtk_ref2usb_tx_prepare,
+       .unprepare      = mtk_ref2usb_tx_unprepare,
+};
+
+struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
+                       const char *parent_name, void __iomem *reg)
+{
+       struct mtk_ref2usb_tx *tx;
+       struct clk_init_data init = {};
+       struct clk *clk;
+
+       tx = kzalloc(sizeof(*tx), GFP_KERNEL);
+       if (!tx)
+               return ERR_PTR(-ENOMEM);
+
+       tx->base_addr = reg;
+       tx->hw.init = &init;
+
+       init.name = name;
+       init.ops = &mtk_ref2usb_tx_ops;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       clk = clk_register(NULL, &tx->hw);
+
+       if (IS_ERR(clk)) {
+               pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk));
+               kfree(tx);
+       }
+
+       return clk;
+}
index 57020368a6934a490695fe174954c8485fdd2cc3..576bdb7c98b8c98f6ece22aea9ae80443ad2b887 100644 (file)
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
        .disable        = mtk_cg_disable_inv,
 };
 
-struct clk *mtk_clk_register_gate(
+struct clk * __init mtk_clk_register_gate(
                const char *name,
                const char *parent_name,
                struct regmap *regmap,
index 90eff85f4285ec10415509ba8013b63d623f94cb..227e356403d9558346a6ef0b99b24eac50a3fd4f 100644 (file)
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/slab.h>
-#include <linux/mfd/syscon.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
 #include <dt-bindings/clock/mt8173-clk.h>
 
+/*
+ * For some clocks, we don't care what their actual rates are. And these
+ * clocks may change their rate on different products or different scenarios.
+ * So we model these clocks' rate as 0, to denote it's not an actual rate.
+ */
+#define DUMMY_RATE             0
+
 static DEFINE_SPINLOCK(mt8173_clk_lock);
 
-static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
-       FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
-       FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1),
-       FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
-       FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
+static const struct mtk_fixed_clk fixed_clks[] __initconst = {
+       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE),
+       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
+       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", DUMMY_RATE),
+       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", DUMMY_RATE),
+       FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", DUMMY_RATE),
+       FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", DUMMY_RATE),
 };
 
 static const struct mtk_fixed_factor top_divs[] __initconst = {
@@ -54,6 +61,7 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
        FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
        FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1),
 
+       FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "tvdpll_445p5m", 1, 3),
        FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
        FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
 
@@ -590,7 +598,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
        MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
 };
 
-static const struct mtk_gate_regs infra_cg_regs = {
+static const struct mtk_gate_regs infra_cg_regs __initconst = {
        .set_ofs = 0x0040,
        .clr_ofs = 0x0044,
        .sta_ofs = 0x0048,
@@ -612,20 +620,24 @@ static const struct mtk_gate infra_clks[] __initconst = {
        GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
        GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
        GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
-       GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15),
+       GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15),
        GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
        GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18),
        GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
        GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
 };
 
-static const struct mtk_gate_regs peri0_cg_regs = {
+static const struct mtk_fixed_factor infra_divs[] __initconst = {
+       FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
+};
+
+static const struct mtk_gate_regs peri0_cg_regs __initconst = {
        .set_ofs = 0x0008,
        .clr_ofs = 0x0010,
        .sta_ofs = 0x0018,
 };
 
-static const struct mtk_gate_regs peri1_cg_regs = {
+static const struct mtk_gate_regs peri1_cg_regs __initconst = {
        .set_ofs = 0x000c,
        .clr_ofs = 0x0014,
        .sta_ofs = 0x001c,
@@ -701,6 +713,183 @@ static const struct mtk_composite peri_clks[] __initconst = {
        MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
 };
 
+static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = {
+       .set_ofs = 0x0004,
+       .clr_ofs = 0x0008,
+       .sta_ofs = 0x0000,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {                        \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &cg_regs_4_8_0,                         \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr,                \
+       }
+
+static const struct mtk_gate img_clks[] __initconst = {
+       GATE_IMG(CLK_IMG_LARB2_SMI, "img_larb2_smi", "mm_sel", 0),
+       GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "mm_sel", 5),
+       GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "mm_sel", 6),
+       GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "camtg_sel", 7),
+       GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "mm_sel", 8),
+       GATE_IMG(CLK_IMG_CAM_SV, "img_cam_sv", "mm_sel", 9),
+       GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
+};
+
+static const struct mtk_gate_regs mm0_cg_regs __initconst = {
+       .set_ofs = 0x0104,
+       .clr_ofs = 0x0108,
+       .sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs __initconst = {
+       .set_ofs = 0x0114,
+       .clr_ofs = 0x0118,
+       .sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {                        \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &mm0_cg_regs,                           \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr,                \
+       }
+
+#define GATE_MM1(_id, _name, _parent, _shift) {                        \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &mm1_cg_regs,                           \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr,                \
+       }
+
+static const struct mtk_gate mm_clks[] __initconst = {
+       /* MM0 */
+       GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+       GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+       GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
+       GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
+       GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
+       GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
+       GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
+       GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
+       GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
+       GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
+       GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+       GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+       GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+       GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+       GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15),
+       GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
+       GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
+       GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
+       GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
+       GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
+       GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+       GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+       GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
+       GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
+       GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+       GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+       GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
+       GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
+       GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
+       GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
+       GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
+       /* MM1 */
+       GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
+       GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
+       GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
+       GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
+       GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
+       GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
+       GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
+       GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
+       GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
+       GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
+       GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10),
+       GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
+       GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12),
+       GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13),
+       GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14),
+       GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15),
+       GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16),
+       GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17),
+       GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
+       GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19),
+       GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20),
+};
+
+static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
+       .set_ofs = 0x0000,
+       .clr_ofs = 0x0004,
+       .sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
+       .set_ofs = 0x0008,
+       .clr_ofs = 0x000c,
+       .sta_ofs = 0x0008,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) {              \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &vdec0_cg_regs,                         \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr_inv,            \
+       }
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) {              \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &vdec1_cg_regs,                         \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr_inv,            \
+       }
+
+static const struct mtk_gate vdec_clks[] __initconst = {
+       GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
+       GATE_VDEC1(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", 0),
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) {               \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &cg_regs_4_8_0,                         \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr_inv,            \
+       }
+
+static const struct mtk_gate venc_clks[] __initconst = {
+       GATE_VENC(CLK_VENC_CKE0, "venc_cke0", "mm_sel", 0),
+       GATE_VENC(CLK_VENC_CKE1, "venc_cke1", "venc_sel", 4),
+       GATE_VENC(CLK_VENC_CKE2, "venc_cke2", "venc_sel", 8),
+       GATE_VENC(CLK_VENC_CKE3, "venc_cke3", "venc_sel", 12),
+};
+
+#define GATE_VENCLT(_id, _name, _parent, _shift) {             \
+               .id = _id,                                      \
+               .name = _name,                                  \
+               .parent_name = _parent,                         \
+               .regs = &cg_regs_4_8_0,                         \
+               .shift = _shift,                                \
+               .ops = &mtk_clk_gate_ops_setclr_inv,            \
+       }
+
+static const struct mtk_gate venclt_clks[] __initconst = {
+       GATE_VENCLT(CLK_VENCLT_CKE0, "venclt_cke0", "mm_sel", 0),
+       GATE_VENCLT(CLK_VENCLT_CKE1, "venclt_cke1", "venclt_sel", 4),
+};
+
 static struct clk_onecell_data *mt8173_top_clk_data __initdata;
 static struct clk_onecell_data *mt8173_pll_clk_data __initdata;
 
@@ -731,7 +920,7 @@ static void __init mtk_topckgen_init(struct device_node *node)
 
        mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
 
-       mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+       mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
        mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
        mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
                        &mt8173_clk_lock, clk_data);
@@ -754,6 +943,7 @@ static void __init mtk_infrasys_init(struct device_node *node)
 
        mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
                                                clk_data);
+       mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
 
        r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
        if (r)
@@ -792,6 +982,24 @@ static void __init mtk_pericfg_init(struct device_node *node)
 }
 CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
 
+struct mtk_clk_usb {
+       int id;
+       const char *name;
+       const char *parent;
+       u32 reg_ofs;
+};
+
+#define APMIXED_USB(_id, _name, _parent, _reg_ofs) {                   \
+               .id = _id,                                              \
+               .name = _name,                                          \
+               .parent = _parent,                                      \
+               .reg_ofs = _reg_ofs,                                    \
+       }
+
+static const struct mtk_clk_usb apmixed_usb[] __initconst = {
+       APMIXED_USB(CLK_APMIXED_REF2USB_TX, "ref2usb_tx", "clk26m", 0x8),
+};
+
 #define MT8173_PLL_FMAX                (3000UL * MHZ)
 
 #define CON0_MT8173_RST_BAR    BIT(24)
@@ -852,6 +1060,15 @@ static const struct mtk_pll_data plls[] = {
 static void __init mtk_apmixedsys_init(struct device_node *node)
 {
        struct clk_onecell_data *clk_data;
+       void __iomem *base;
+       struct clk *clk;
+       int r, i;
+
+       base = of_iomap(node, 0);
+       if (!base) {
+               pr_err("%s(): ioremap failed\n", __func__);
+               return;
+       }
 
        mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
        if (!clk_data)
@@ -859,7 +1076,113 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
 
        mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 
+       for (i = 0; i < ARRAY_SIZE(apmixed_usb); i++) {
+               const struct mtk_clk_usb *cku = &apmixed_usb[i];
+
+               clk = mtk_clk_register_ref2usb_tx(cku->name, cku->parent,
+                                       base + cku->reg_ofs);
+
+               if (IS_ERR(clk)) {
+                       pr_err("Failed to register clk %s: %ld\n", cku->name,
+                                       PTR_ERR(clk));
+                       continue;
+               }
+
+               clk_data->clks[cku->id] = clk;
+       }
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+
        mtk_clk_enable_critical();
 }
 CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
                mtk_apmixedsys_init);
+
+static void __init mtk_imgsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+       mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+                                               clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
+
+static void __init mtk_mmsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+       mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+                                               clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
+
+static void __init mtk_vdecsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
+
+       mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+                                               clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
+
+static void __init mtk_vencsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
+
+       mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+                                               clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
+
+static void __init mtk_vencltsys_init(struct device_node *node)
+{
+       struct clk_onecell_data *clk_data;
+       int r;
+
+       clk_data = mtk_alloc_clk_data(CLK_VENCLT_NR_CLK);
+
+       mtk_clk_register_gates(node, venclt_clks, ARRAY_SIZE(venclt_clks),
+                                               clk_data);
+
+       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+       if (r)
+               pr_err("%s(): could not register clock provider: %d\n",
+                       __func__, r);
+}
+CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
index 18444aea63c93c1eb491d3a574fe351895768374..cf08db6c130c9887e6bc4ed40415aa683efd9b8d 100644 (file)
@@ -24,7 +24,7 @@
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num)
 {
        int i;
        struct clk_onecell_data *clk_data;
@@ -49,8 +49,31 @@ err_out:
        return NULL;
 }
 
-void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
-               struct clk_onecell_data *clk_data)
+void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+               int num, struct clk_onecell_data *clk_data)
+{
+       int i;
+       struct clk *clk;
+
+       for (i = 0; i < num; i++) {
+               const struct mtk_fixed_clk *rc = &clks[i];
+
+               clk = clk_register_fixed_rate(NULL, rc->name, rc->parent,
+                               rc->parent ? 0 : CLK_IS_ROOT, rc->rate);
+
+               if (IS_ERR(clk)) {
+                       pr_err("Failed to register clk %s: %ld\n",
+                                       rc->name, PTR_ERR(clk));
+                       continue;
+               }
+
+               if (clk_data)
+                       clk_data->clks[rc->id] = clk;
+       }
+}
+
+void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+               int num, struct clk_onecell_data *clk_data)
 {
        int i;
        struct clk *clk;
@@ -72,7 +95,8 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
        }
 }
 
-int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
+int __init mtk_clk_register_gates(struct device_node *node,
+               const struct mtk_gate *clks,
                int num, struct clk_onecell_data *clk_data)
 {
        int i;
@@ -111,7 +135,7 @@ int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks
        return 0;
 }
 
-struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
+struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc,
                void __iomem *base, spinlock_t *lock)
 {
        struct clk *clk;
@@ -196,7 +220,7 @@ err_out:
        return ERR_PTR(ret);
 }
 
-void mtk_clk_register_composites(const struct mtk_composite *mcs,
+void __init mtk_clk_register_composites(const struct mtk_composite *mcs,
                int num, void __iomem *base, spinlock_t *lock,
                struct clk_onecell_data *clk_data)
 {
index c5cbecb3d218c3d33e116db2d814819987067e8d..32d2e455eb3fbd0bb3e59434af25d4c0d26f0158 100644 (file)
@@ -26,6 +26,23 @@ struct clk;
 
 #define MHZ (1000 * 1000)
 
+struct mtk_fixed_clk {
+       int id;
+       const char *name;
+       const char *parent;
+       unsigned long rate;
+};
+
+#define FIXED_CLK(_id, _name, _parent, _rate) {                \
+               .id = _id,                              \
+               .name = _name,                          \
+               .parent = _parent,                      \
+               .rate = _rate,                          \
+       }
+
+void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+               int num, struct clk_onecell_data *clk_data);
+
 struct mtk_fixed_factor {
        int id;
        const char *name;
@@ -42,7 +59,7 @@ struct mtk_fixed_factor {
                .div = _div,                            \
        }
 
-extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
                int num, struct clk_onecell_data *clk_data);
 
 struct mtk_composite {
@@ -159,10 +176,13 @@ struct mtk_pll_data {
        const struct mtk_pll_div_table *div_table;
 };
 
-void __init mtk_clk_register_plls(struct device_node *node,
+void mtk_clk_register_plls(struct device_node *node,
                const struct mtk_pll_data *plls, int num_plls,
                struct clk_onecell_data *clk_data);
 
+struct clk *mtk_clk_register_ref2usb_tx(const char *name,
+                       const char *parent_name, void __iomem *reg);
+
 #ifdef CONFIG_RESET_CONTROLLER
 void mtk_register_reset_controller(struct device_node *np,
                        unsigned int num_regs, int regofs);
index 622e7b6c62b42893f1c4c98574a492eed361130e..966cab1348dad869f0de40b3699a770ec17ffe35 100644 (file)
@@ -317,7 +317,7 @@ void __init mtk_clk_register_plls(struct device_node *node,
                const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
 {
        void __iomem *base;
-       int r, i;
+       int i;
        struct clk *clk;
 
        base = of_iomap(node, 0);
@@ -339,9 +339,4 @@ void __init mtk_clk_register_plls(struct device_node *node,
 
                clk_data->clks[pll->id] = clk;
        }
-
-       r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-       if (r)
-               pr_err("%s(): could not register clock provider: %d\n",
-                       __func__, r);
 }
index 85da8b9832568b2e4daab35eea661d4d99a5ac26..5837eb8a212fbdcd8446ff9da77f393cc05c128a 100644 (file)
@@ -197,7 +197,6 @@ static void __init of_cpu_clk_setup(struct device_node *node)
        for_each_node_by_type(dn, "cpu") {
                struct clk_init_data init;
                struct clk *clk;
-               struct clk *parent_clk;
                char *clk_name = kzalloc(5, GFP_KERNEL);
                int cpu, err;
 
@@ -209,9 +208,8 @@ static void __init of_cpu_clk_setup(struct device_node *node)
                        goto bail_out;
 
                sprintf(clk_name, "cpu%d", cpu);
-               parent_clk = of_clk_get(node, 0);
 
-               cpuclk[cpu].parent_name = __clk_get_name(parent_clk);
+               cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0);
                cpuclk[cpu].clk_name = clk_name;
                cpuclk[cpu].cpu = cpu;
                cpuclk[cpu].reg_base = clock_complex_base;
index 4a22429cd7a23b4171f825062ac96abc0f34d311..28aac67e7b92b0c668fee1d2d7c637a708141cef 100644 (file)
@@ -165,7 +165,7 @@ void __init mvebu_coreclk_setup(struct device_node *np,
                clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
                                       cpuclk_name, 0, mult, div);
                WARN_ON(IS_ERR(clk_data.clks[2+n]));
-       };
+       }
 
        /* Register optional refclk */
        if (desc->get_refclk_freq) {
index 73f0240569ac0733d0312a3627d891d454f98ec5..f8dd10f6df3d47347ea245a5a2b8275ec738f9f4 100644 (file)
@@ -41,11 +41,13 @@ static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
 {
        struct clk_frac *frac = to_clk_frac(hw);
        u32 div;
+       u64 tmp_rate;
 
        div = readl_relaxed(frac->reg) >> frac->shift;
        div &= (1 << frac->width) - 1;
 
-       return (parent_rate >> frac->width) * div;
+       tmp_rate = (u64)parent_rate * div;
+       return tmp_rate >> frac->width;
 }
 
 static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -54,7 +56,7 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
        struct clk_frac *frac = to_clk_frac(hw);
        unsigned long parent_rate = *prate;
        u32 div;
-       u64 tmp;
+       u64 tmp, tmp_rate, result;
 
        if (rate > parent_rate)
                return -EINVAL;
@@ -67,7 +69,11 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
        if (!div)
                return -EINVAL;
 
-       return (parent_rate >> frac->width) * div;
+       tmp_rate = (u64)parent_rate * div;
+       result = tmp_rate >> frac->width;
+       if ((result << frac->width) < tmp_rate)
+               result += 1;
+       return result;
 }
 
 static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
index eeaee97da1105ad79cc0683964cee6fb87527f5b..13aabbb3acbec3ff91d1fd478f097cd3014bfd8d 100644 (file)
@@ -179,9 +179,22 @@ static void lpc18xx_ccu_gate_disable(struct clk_hw *hw)
 
 static int lpc18xx_ccu_gate_is_enabled(struct clk_hw *hw)
 {
-       struct clk_gate *gate = to_clk_gate(hw);
+       const struct clk_hw *parent;
+
+       /*
+        * The branch clock registers are only accessible
+        * if the base (parent) clock is enabled. Register
+        * access with a disabled base clock will hang the
+        * system.
+        */
+       parent = clk_hw_get_parent(hw);
+       if (!parent)
+               return 0;
+
+       if (!clk_hw_is_enabled(parent))
+               return 0;
 
-       return clk_readl(gate->reg) & LPC18XX_CCU_RUN;
+       return clk_gate_ops.is_enabled(hw);
 }
 
 static const struct clk_ops lpc18xx_ccu_gate_ops = {
index e0a3cb8970ab5b68e24dbb2fbcbb45f13d0ae0b3..c924572fc9bc1296b6c7353ff0b39d8ed92ead62 100644 (file)
@@ -480,6 +480,42 @@ static const struct clk_ops lpc18xx_pll1_ops = {
        .recalc_rate = lpc18xx_pll1_recalc_rate,
 };
 
+static int lpc18xx_cgu_gate_enable(struct clk_hw *hw)
+{
+       return clk_gate_ops.enable(hw);
+}
+
+static void lpc18xx_cgu_gate_disable(struct clk_hw *hw)
+{
+       clk_gate_ops.disable(hw);
+}
+
+static int lpc18xx_cgu_gate_is_enabled(struct clk_hw *hw)
+{
+       const struct clk_hw *parent;
+
+       /*
+        * The consumer of base clocks needs know if the
+        * base clock is really enabled before it can be
+        * accessed. It is therefore necessary to verify
+        * this all the way up.
+        */
+       parent = clk_hw_get_parent(hw);
+       if (!parent)
+               return 0;
+
+       if (!clk_hw_is_enabled(parent))
+               return 0;
+
+       return clk_gate_ops.is_enabled(hw);
+}
+
+static const struct clk_ops lpc18xx_gate_ops = {
+       .enable = lpc18xx_cgu_gate_enable,
+       .disable = lpc18xx_cgu_gate_disable,
+       .is_enabled = lpc18xx_cgu_gate_is_enabled,
+};
+
 static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = {
        LPC1XX_CGU_CLK_PLL(PLL0USB,     pll0_src_ids, pll0_ops),
        LPC1XX_CGU_CLK_PLL(PLL0AUDIO,   pll0_src_ids, pll0_ops),
@@ -510,7 +546,7 @@ static struct clk *lpc18xx_cgu_register_div(struct lpc18xx_cgu_src_clk_div *clk,
        return clk_register_composite(NULL, name, parents, clk->n_parents,
                                      &clk->mux.hw, &clk_mux_ops,
                                      &clk->div.hw, &clk_divider_ops,
-                                     &clk->gate.hw, &clk_gate_ops, 0);
+                                     &clk->gate.hw, &lpc18xx_gate_ops, 0);
 }
 
 
@@ -538,7 +574,7 @@ static struct clk *lpc18xx_register_base_clk(struct lpc18xx_cgu_base_clk *clk,
        return clk_register_composite(NULL, name, parents, clk->n_parents,
                                      &clk->mux.hw, &clk_mux_ops,
                                      NULL,  NULL,
-                                     &clk->gate.hw, &clk_gate_ops, 0);
+                                     &clk->gate.hw, &lpc18xx_gate_ops, 0);
 }
 
 
@@ -557,7 +593,7 @@ static struct clk *lpc18xx_cgu_register_pll(struct lpc18xx_cgu_pll_clk *clk,
        return clk_register_composite(NULL, name, parents, clk->n_parents,
                                      &clk->mux.hw, &clk_mux_ops,
                                      &clk->pll.hw, clk->pll_ops,
-                                     &clk->gate.hw, &clk_gate_ops, 0);
+                                     &clk->gate.hw, &lpc18xx_gate_ops, 0);
 }
 
 static void __init lpc18xx_cgu_register_source_clks(struct device_node *np,
index 59d16668bdf5e807ab1cdbf8bc4fd12c3b6fb179..ee4c83aab4f40daabe8fbe84c028fdeef8bf73ec 100644 (file)
@@ -1,3 +1,7 @@
+config QCOM_GDSC
+       bool
+       select PM_GENERIC_DOMAINS if PM
+
 config COMMON_CLK_QCOM
        tristate "Support for Qualcomm's clock controllers"
        depends on OF
@@ -7,6 +11,7 @@ config COMMON_CLK_QCOM
 
 config APQ_GCC_8084
        tristate "APQ8084 Global Clock Controller"
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the global clock controller on apq8084 devices.
@@ -16,6 +21,7 @@ config APQ_GCC_8084
 config APQ_MMCC_8084
        tristate "APQ8084 Multimedia Clock Controller"
        select APQ_GCC_8084
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the multimedia clock controller on apq8084 devices.
@@ -49,6 +55,7 @@ config MSM_GCC_8660
 
 config MSM_GCC_8916
        tristate "MSM8916 Global Clock Controller"
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the global clock controller on msm8916 devices.
@@ -83,6 +90,7 @@ config MSM_MMCC_8960
 
 config MSM_GCC_8974
        tristate "MSM8974 Global Clock Controller"
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the global clock controller on msm8974 devices.
@@ -92,6 +100,7 @@ config MSM_GCC_8974
 config MSM_MMCC_8974
        tristate "MSM8974 Multimedia Clock Controller"
        select MSM_GCC_8974
+       select QCOM_GDSC
        depends on COMMON_CLK_QCOM
        help
          Support for the multimedia clock controller on msm8974 devices.
index 50b337a24a87a08066823342a2ca9a452f825c90..fe6252349e55211c23e3b8dd6e4126bc5a6dc337 100644 (file)
@@ -9,6 +9,7 @@ clk-qcom-y += clk-branch.o
 clk-qcom-y += clk-regmap-divider.o
 clk-qcom-y += clk-regmap-mux.o
 clk-qcom-y += reset.o
+clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
index bccedc4b57568bda6edafa516933fc45f8cfa439..bfbb28f450c2ea0ad4c10dfd96e34c8f5a56cbbf 100644 (file)
@@ -542,6 +542,200 @@ static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
        return __clk_rcg_set_rate(rcg, rcg->freq_tbl);
 }
 
+static int clk_rcg_bypass2_determine_rate(struct clk_hw *hw,
+                               struct clk_rate_request *req)
+{
+       struct clk_hw *p;
+
+       p = req->best_parent_hw;
+       req->best_parent_rate = clk_hw_round_rate(p, req->rate);
+       req->rate = req->best_parent_rate;
+
+       return 0;
+}
+
+static int clk_rcg_bypass2_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct clk_rcg *rcg = to_clk_rcg(hw);
+       struct freq_tbl f = { 0 };
+       u32 ns, src;
+       int i, ret, num_parents = clk_hw_get_num_parents(hw);
+
+       ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
+       if (ret)
+               return ret;
+
+       src = ns_to_src(&rcg->s, ns);
+       f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1;
+
+       for (i = 0; i < num_parents; i++) {
+               if (src == rcg->s.parent_map[i].cfg) {
+                       f.src = rcg->s.parent_map[i].src;
+                       return __clk_rcg_set_rate(rcg, &f);
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int clk_rcg_bypass2_set_rate_and_parent(struct clk_hw *hw,
+               unsigned long rate, unsigned long parent_rate, u8 index)
+{
+       /* Read the hardware to determine parent during set_rate */
+       return clk_rcg_bypass2_set_rate(hw, rate, parent_rate);
+}
+
+struct frac_entry {
+       int num;
+       int den;
+};
+
+static const struct frac_entry pixel_table[] = {
+       { 1, 2 },
+       { 1, 3 },
+       { 3, 16 },
+       { }
+};
+
+static int clk_rcg_pixel_determine_rate(struct clk_hw *hw,
+               struct clk_rate_request *req)
+{
+       int delta = 100000;
+       const struct frac_entry *frac = pixel_table;
+       unsigned long request, src_rate;
+
+       for (; frac->num; frac++) {
+               request = (req->rate * frac->den) / frac->num;
+
+               src_rate = clk_hw_round_rate(req->best_parent_hw, request);
+
+               if ((src_rate < (request - delta)) ||
+                       (src_rate > (request + delta)))
+                       continue;
+
+               req->best_parent_rate = src_rate;
+               req->rate = (src_rate * frac->num) / frac->den;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct clk_rcg *rcg = to_clk_rcg(hw);
+       int delta = 100000;
+       const struct frac_entry *frac = pixel_table;
+       unsigned long request;
+       struct freq_tbl f = { 0 };
+       u32 ns, src;
+       int i, ret, num_parents = clk_hw_get_num_parents(hw);
+
+       ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
+       if (ret)
+               return ret;
+
+       src = ns_to_src(&rcg->s, ns);
+       f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1;
+
+       for (i = 0; i < num_parents; i++) {
+               if (src == rcg->s.parent_map[i].cfg) {
+                       f.src = rcg->s.parent_map[i].src;
+                       break;
+               }
+       }
+
+       /* let us find appropriate m/n values for this */
+       for (; frac->num; frac++) {
+               request = (rate * frac->den) / frac->num;
+
+               if ((parent_rate < (request - delta)) ||
+                       (parent_rate > (request + delta)))
+                       continue;
+
+               f.m = frac->num;
+               f.n = frac->den;
+
+               return __clk_rcg_set_rate(rcg, &f);
+       }
+
+       return -EINVAL;
+}
+
+static int clk_rcg_pixel_set_rate_and_parent(struct clk_hw *hw,
+               unsigned long rate, unsigned long parent_rate, u8 index)
+{
+       return clk_rcg_pixel_set_rate(hw, rate, parent_rate);
+}
+
+static int clk_rcg_esc_determine_rate(struct clk_hw *hw,
+               struct clk_rate_request *req)
+{
+       struct clk_rcg *rcg = to_clk_rcg(hw);
+       int pre_div_max = BIT(rcg->p.pre_div_width);
+       int div;
+       unsigned long src_rate;
+
+       if (req->rate == 0)
+               return -EINVAL;
+
+       src_rate = clk_hw_get_rate(req->best_parent_hw);
+
+       div = src_rate / req->rate;
+
+       if (div >= 1 && div <= pre_div_max) {
+               req->best_parent_rate = src_rate;
+               req->rate = src_rate / div;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+static int clk_rcg_esc_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct clk_rcg *rcg = to_clk_rcg(hw);
+       struct freq_tbl f = { 0 };
+       int pre_div_max = BIT(rcg->p.pre_div_width);
+       int div;
+       u32 ns;
+       int i, ret, num_parents = clk_hw_get_num_parents(hw);
+
+       if (rate == 0)
+               return -EINVAL;
+
+       ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
+       if (ret)
+               return ret;
+
+       ns = ns_to_src(&rcg->s, ns);
+
+       for (i = 0; i < num_parents; i++) {
+               if (ns == rcg->s.parent_map[i].cfg) {
+                       f.src = rcg->s.parent_map[i].src;
+                       break;
+               }
+       }
+
+       div = parent_rate / rate;
+
+       if (div >= 1 && div <= pre_div_max) {
+               f.pre_div = div;
+               return __clk_rcg_set_rate(rcg, &f);
+       }
+
+       return -EINVAL;
+}
+
+static int clk_rcg_esc_set_rate_and_parent(struct clk_hw *hw,
+               unsigned long rate, unsigned long parent_rate, u8 index)
+{
+       return clk_rcg_esc_set_rate(hw, rate, parent_rate);
+}
+
 /*
  * This type of clock has a glitch-free mux that switches between the output of
  * the M/N counter and an always on clock source (XO). When clk_set_rate() is
@@ -639,6 +833,42 @@ const struct clk_ops clk_rcg_bypass_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops);
 
+const struct clk_ops clk_rcg_bypass2_ops = {
+       .enable = clk_enable_regmap,
+       .disable = clk_disable_regmap,
+       .get_parent = clk_rcg_get_parent,
+       .set_parent = clk_rcg_set_parent,
+       .recalc_rate = clk_rcg_recalc_rate,
+       .determine_rate = clk_rcg_bypass2_determine_rate,
+       .set_rate = clk_rcg_bypass2_set_rate,
+       .set_rate_and_parent = clk_rcg_bypass2_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg_bypass2_ops);
+
+const struct clk_ops clk_rcg_pixel_ops = {
+       .enable = clk_enable_regmap,
+       .disable = clk_disable_regmap,
+       .get_parent = clk_rcg_get_parent,
+       .set_parent = clk_rcg_set_parent,
+       .recalc_rate = clk_rcg_recalc_rate,
+       .determine_rate = clk_rcg_pixel_determine_rate,
+       .set_rate = clk_rcg_pixel_set_rate,
+       .set_rate_and_parent = clk_rcg_pixel_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg_pixel_ops);
+
+const struct clk_ops clk_rcg_esc_ops = {
+       .enable = clk_enable_regmap,
+       .disable = clk_disable_regmap,
+       .get_parent = clk_rcg_get_parent,
+       .set_parent = clk_rcg_set_parent,
+       .recalc_rate = clk_rcg_recalc_rate,
+       .determine_rate = clk_rcg_esc_determine_rate,
+       .set_rate = clk_rcg_esc_set_rate,
+       .set_rate_and_parent = clk_rcg_esc_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg_esc_ops);
+
 const struct clk_ops clk_rcg_lcc_ops = {
        .enable = clk_rcg_lcc_enable,
        .disable = clk_rcg_lcc_disable,
index 56028bb31d8713f4a627a78027191df58b504bfb..4b1e94bdf29e2b3a585b4c1d64680ff51f71d467 100644 (file)
@@ -106,6 +106,9 @@ struct clk_rcg {
 
 extern const struct clk_ops clk_rcg_ops;
 extern const struct clk_ops clk_rcg_bypass_ops;
+extern const struct clk_ops clk_rcg_bypass2_ops;
+extern const struct clk_ops clk_rcg_pixel_ops;
+extern const struct clk_ops clk_rcg_esc_ops;
 extern const struct clk_ops clk_rcg_lcc_ops;
 
 #define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr)
@@ -153,8 +156,8 @@ extern const struct clk_ops clk_dyn_rcg_ops;
  * @hid_width: number of bits in half integer divider
  * @parent_map: map from software's parent index to hardware's src_sel field
  * @freq_tbl: frequency table
+ * @current_freq: last cached frequency when using branches with shared RCGs
  * @clkr: regmap clock handle
- * @lock: register lock
  *
  */
 struct clk_rcg2 {
@@ -163,14 +166,17 @@ struct clk_rcg2 {
        u8                      hid_width;
        const struct parent_map *parent_map;
        const struct freq_tbl   *freq_tbl;
+       unsigned long           current_freq;
        struct clk_regmap       clkr;
 };
 
 #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
 
 extern const struct clk_ops clk_rcg2_ops;
+extern const struct clk_ops clk_rcg2_shared_ops;
 extern const struct clk_ops clk_edp_pixel_ops;
 extern const struct clk_ops clk_byte_ops;
+extern const struct clk_ops clk_byte2_ops;
 extern const struct clk_ops clk_pixel_ops;
 
 #endif
index 9aec1761fd29e26c4c2ad0fbd7979e609c880db3..b544bb302f79894c0d3c6599858c7f0c8b113433 100644 (file)
@@ -300,6 +300,85 @@ const struct clk_ops clk_rcg2_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_ops);
 
+static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       const char *name = clk_hw_get_name(hw);
+       int ret, count;
+
+       /* force enable RCG */
+       ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
+                                CMD_ROOT_EN, CMD_ROOT_EN);
+       if (ret)
+               return ret;
+
+       /* wait for RCG to turn ON */
+       for (count = 500; count > 0; count--) {
+               ret = clk_rcg2_is_enabled(hw);
+               if (ret)
+                       break;
+               udelay(1);
+       }
+       if (!count)
+               pr_err("%s: RCG did not turn on\n", name);
+
+       /* set clock rate */
+       ret = __clk_rcg2_set_rate(hw, rate);
+       if (ret)
+               return ret;
+
+       /* clear force enable RCG */
+       return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
+                                CMD_ROOT_EN, 0);
+}
+
+static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+                                   unsigned long parent_rate)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+       /* cache the rate */
+       rcg->current_freq = rate;
+
+       if (!__clk_is_enabled(hw->clk))
+               return 0;
+
+       return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
+}
+
+static unsigned long
+clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+       return rcg->current_freq = clk_rcg2_recalc_rate(hw, parent_rate);
+}
+
+static int clk_rcg2_shared_enable(struct clk_hw *hw)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+       return clk_rcg2_shared_force_enable(hw, rcg->current_freq);
+}
+
+static void clk_rcg2_shared_disable(struct clk_hw *hw)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+       /* switch to XO, which is the lowest entry in the freq table */
+       clk_rcg2_shared_set_rate(hw, rcg->freq_tbl[0].freq, 0);
+}
+
+const struct clk_ops clk_rcg2_shared_ops = {
+       .enable = clk_rcg2_shared_enable,
+       .disable = clk_rcg2_shared_disable,
+       .get_parent = clk_rcg2_get_parent,
+       .recalc_rate = clk_rcg2_shared_recalc_rate,
+       .determine_rate = clk_rcg2_determine_rate,
+       .set_rate = clk_rcg2_shared_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
+
 struct frac_entry {
        int num;
        int den;
@@ -485,6 +564,76 @@ const struct clk_ops clk_byte_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_byte_ops);
 
+static int clk_byte2_determine_rate(struct clk_hw *hw,
+                                   struct clk_rate_request *req)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       unsigned long parent_rate, div;
+       u32 mask = BIT(rcg->hid_width) - 1;
+       struct clk_hw *p;
+       unsigned long rate = req->rate;
+
+       if (rate == 0)
+               return -EINVAL;
+
+       p = req->best_parent_hw;
+       req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate);
+
+       div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
+       div = min_t(u32, div, mask);
+
+       req->rate = calc_rate(parent_rate, 0, 0, 0, div);
+
+       return 0;
+}
+
+static int clk_byte2_set_rate(struct clk_hw *hw, unsigned long rate,
+                        unsigned long parent_rate)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       struct freq_tbl f = { 0 };
+       unsigned long div;
+       int i, num_parents = clk_hw_get_num_parents(hw);
+       u32 mask = BIT(rcg->hid_width) - 1;
+       u32 cfg;
+
+       div = DIV_ROUND_UP((2 * parent_rate), rate) - 1;
+       div = min_t(u32, div, mask);
+
+       f.pre_div = div;
+
+       regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
+       cfg &= CFG_SRC_SEL_MASK;
+       cfg >>= CFG_SRC_SEL_SHIFT;
+
+       for (i = 0; i < num_parents; i++) {
+               if (cfg == rcg->parent_map[i].cfg) {
+                       f.src = rcg->parent_map[i].src;
+                       return clk_rcg2_configure(rcg, &f);
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int clk_byte2_set_rate_and_parent(struct clk_hw *hw,
+               unsigned long rate, unsigned long parent_rate, u8 index)
+{
+       /* Read the hardware to determine parent during set_rate */
+       return clk_byte2_set_rate(hw, rate, parent_rate);
+}
+
+const struct clk_ops clk_byte2_ops = {
+       .is_enabled = clk_rcg2_is_enabled,
+       .get_parent = clk_rcg2_get_parent,
+       .set_parent = clk_rcg2_set_parent,
+       .recalc_rate = clk_rcg2_recalc_rate,
+       .set_rate = clk_byte2_set_rate,
+       .set_rate_and_parent = clk_byte2_set_rate_and_parent,
+       .determine_rate = clk_byte2_determine_rate,
+};
+EXPORT_SYMBOL_GPL(clk_byte2_ops);
+
 static const struct frac_entry frac_table_pixel[] = {
        { 3, 8 },
        { 2, 9 },
@@ -496,14 +645,9 @@ static const struct frac_entry frac_table_pixel[] = {
 static int clk_pixel_determine_rate(struct clk_hw *hw,
                                    struct clk_rate_request *req)
 {
-       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
        unsigned long request, src_rate;
        int delta = 100000;
-       const struct freq_tbl *f = rcg->freq_tbl;
        const struct frac_entry *frac = frac_table_pixel;
-       int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
-
-       req->best_parent_hw = clk_hw_get_parent_by_index(hw, index);
 
        for (; frac->num; frac++) {
                request = (req->rate * frac->den) / frac->num;
@@ -525,12 +669,23 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
                unsigned long parent_rate)
 {
        struct clk_rcg2 *rcg = to_clk_rcg2(hw);
-       struct freq_tbl f = *rcg->freq_tbl;
+       struct freq_tbl f = { 0 };
        const struct frac_entry *frac = frac_table_pixel;
        unsigned long request;
        int delta = 100000;
        u32 mask = BIT(rcg->hid_width) - 1;
-       u32 hid_div;
+       u32 hid_div, cfg;
+       int i, num_parents = clk_hw_get_num_parents(hw);
+
+       regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
+       cfg &= CFG_SRC_SEL_MASK;
+       cfg >>= CFG_SRC_SEL_SHIFT;
+
+       for (i = 0; i < num_parents; i++)
+               if (cfg == rcg->parent_map[i].cfg) {
+                       f.src = rcg->parent_map[i].src;
+                       break;
+               }
 
        for (; frac->num; frac++) {
                request = (rate * frac->den) / frac->num;
@@ -555,7 +710,6 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
 static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
                unsigned long parent_rate, u8 index)
 {
-       /* Parent index is set statically in frequency table */
        return clk_pixel_set_rate(hw, rate, parent_rate);
 }
 
index 2dedceefd21d84464f4733bdfa36fda1f3489a2b..8fa477293ae0ad1f21ab711d991dbc0898a4d34f 100644 (file)
@@ -22,6 +22,7 @@
 #include "clk-rcg.h"
 #include "clk-regmap.h"
 #include "reset.h"
+#include "gdsc.h"
 
 struct qcom_cc {
        struct qcom_reset_controller reset;
@@ -72,6 +73,21 @@ qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
 }
 EXPORT_SYMBOL_GPL(qcom_cc_map);
 
+static void qcom_cc_del_clk_provider(void *data)
+{
+       of_clk_del_provider(data);
+}
+
+static void qcom_cc_reset_unregister(void *data)
+{
+       reset_controller_unregister(data);
+}
+
+static void qcom_cc_gdsc_unregister(void *data)
+{
+       gdsc_unregister(data);
+}
+
 int qcom_cc_really_probe(struct platform_device *pdev,
                         const struct qcom_cc_desc *desc, struct regmap *regmap)
 {
@@ -110,6 +126,8 @@ int qcom_cc_really_probe(struct platform_device *pdev,
        if (ret)
                return ret;
 
+       devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node);
+
        reset = &cc->reset;
        reset->rcdev.of_node = dev->of_node;
        reset->rcdev.ops = &qcom_reset_ops;
@@ -117,13 +135,24 @@ int qcom_cc_really_probe(struct platform_device *pdev,
        reset->rcdev.nr_resets = desc->num_resets;
        reset->regmap = regmap;
        reset->reset_map = desc->resets;
-       platform_set_drvdata(pdev, &reset->rcdev);
 
        ret = reset_controller_register(&reset->rcdev);
        if (ret)
-               of_clk_del_provider(dev->of_node);
+               return ret;
+
+       devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev);
+
+       if (desc->gdscs && desc->num_gdscs) {
+               ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
+                                   &reset->rcdev, regmap);
+               if (ret)
+                       return ret;
+       }
+
+       devm_add_action(dev, qcom_cc_gdsc_unregister, dev);
 
-       return ret;
+
+       return 0;
 }
 EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
 
@@ -139,11 +168,4 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc)
 }
 EXPORT_SYMBOL_GPL(qcom_cc_probe);
 
-void qcom_cc_remove(struct platform_device *pdev)
-{
-       of_clk_del_provider(pdev->dev.of_node);
-       reset_controller_unregister(platform_get_drvdata(pdev));
-}
-EXPORT_SYMBOL_GPL(qcom_cc_remove);
-
 MODULE_LICENSE("GPL v2");
index 7a0e737130630228ef2b27ed4874b5709d0ea682..7c1fba3ebc038b5367b8dd8e659dc5c711b401ee 100644 (file)
@@ -28,6 +28,8 @@ struct qcom_cc_desc {
        size_t num_clks;
        const struct qcom_reset_map *resets;
        size_t num_resets;
+       struct gdsc **gdscs;
+       size_t num_gdscs;
 };
 
 extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
@@ -43,6 +45,4 @@ extern int qcom_cc_really_probe(struct platform_device *pdev,
 extern int qcom_cc_probe(struct platform_device *pdev,
                         const struct qcom_cc_desc *desc);
 
-extern void qcom_cc_remove(struct platform_device *pdev);
-
 #endif
index 3563019b8e3cefe1ac8347464297a2183ce69c34..1567c3a7953474af552fd71d6f92773ec23bc898 100644 (file)
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
        P_XO,
@@ -3254,6 +3255,38 @@ static struct clk_branch gcc_usb_hsic_system_clk = {
        },
 };
 
+static struct gdsc usb_hs_hsic_gdsc = {
+       .gdscr = 0x404,
+       .pd = {
+               .name = "usb_hs_hsic",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie0_gdsc = {
+       .gdscr = 0x1ac4,
+       .pd = {
+               .name = "pcie0",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie1_gdsc = {
+       .gdscr = 0x1b44,
+       .pd = {
+               .name = "pcie1",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb30_gdsc = {
+       .gdscr = 0x1e84,
+       .pd = {
+               .name = "usb30",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *gcc_apq8084_clocks[] = {
        [GPLL0] = &gpll0.clkr,
        [GPLL0_VOTE] = &gpll0_vote,
@@ -3447,6 +3480,13 @@ static struct clk_regmap *gcc_apq8084_clocks[] = {
        [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
 };
 
+static struct gdsc *gcc_apq8084_gdscs[] = {
+       [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
+       [PCIE0_GDSC] = &pcie0_gdsc,
+       [PCIE1_GDSC] = &pcie1_gdsc,
+       [USB30_GDSC] = &usb30_gdsc,
+};
+
 static const struct qcom_reset_map gcc_apq8084_resets[] = {
        [GCC_SYSTEM_NOC_BCR] = { 0x0100 },
        [GCC_CONFIG_NOC_BCR] = { 0x0140 },
@@ -3555,6 +3595,8 @@ static const struct qcom_cc_desc gcc_apq8084_desc = {
        .num_clks = ARRAY_SIZE(gcc_apq8084_clocks),
        .resets = gcc_apq8084_resets,
        .num_resets = ARRAY_SIZE(gcc_apq8084_resets),
+       .gdscs = gcc_apq8084_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_apq8084_gdscs),
 };
 
 static const struct of_device_id gcc_apq8084_match_table[] = {
@@ -3581,15 +3623,8 @@ static int gcc_apq8084_probe(struct platform_device *pdev)
        return qcom_cc_probe(pdev, &gcc_apq8084_desc);
 }
 
-static int gcc_apq8084_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver gcc_apq8084_driver = {
        .probe          = gcc_apq8084_probe,
-       .remove         = gcc_apq8084_remove,
        .driver         = {
                .name   = "gcc-apq8084",
                .of_match_table = gcc_apq8084_match_table,
index 40e480220cd3fb60206a5d8f5bbbf5aba10c3ac9..16fc64c082a5e1e351e5c957cfe7d1a44b1c8d22 100644 (file)
@@ -3058,15 +3058,8 @@ static int gcc_ipq806x_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int gcc_ipq806x_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver gcc_ipq806x_driver = {
        .probe          = gcc_ipq806x_probe,
-       .remove         = gcc_ipq806x_remove,
        .driver         = {
                .name   = "gcc-ipq806x",
                .of_match_table = gcc_ipq806x_match_table,
index b02826ed770a25f474e37922133c7e0ead56c8d0..f110bb5a1df3ea868c19f491c33ee2c86bab9fb0 100644 (file)
@@ -2735,15 +2735,8 @@ static int gcc_msm8660_probe(struct platform_device *pdev)
        return qcom_cc_probe(pdev, &gcc_msm8660_desc);
 }
 
-static int gcc_msm8660_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver gcc_msm8660_driver = {
        .probe          = gcc_msm8660_probe,
-       .remove         = gcc_msm8660_remove,
        .driver         = {
                .name   = "gcc-msm8660",
                .of_match_table = gcc_msm8660_match_table,
index 22a4e1e732c0a3cddc38bb20f1beeb97052ce733..d0a0313d6bef601f229b70782b930ffa7838e1f8 100644 (file)
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
        P_XO,
@@ -44,6 +45,9 @@ enum {
        P_SLEEP_CLK,
        P_DSI0_PHYPLL_BYTE,
        P_DSI0_PHYPLL_DSI,
+       P_EXT_PRI_I2S,
+       P_EXT_SEC_I2S,
+       P_EXT_MCLK,
 };
 
 static const struct parent_map gcc_xo_gpll0_map[] = {
@@ -190,6 +194,76 @@ static const char * const gcc_xo_gpll0a_gpll1_gpll2[] = {
        "gpll2_vote",
 };
 
+static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL1, 2 },
+       { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll0_gpll1_sleep[] = {
+       "xo",
+       "gpll0_vote",
+       "gpll1_vote",
+       "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = {
+       { P_XO, 0 },
+       { P_GPLL1, 1 },
+       { P_EXT_PRI_I2S, 2 },
+       { P_EXT_MCLK, 3 },
+       { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll1_epi2s_emclk_sleep[] = {
+       "xo",
+       "gpll1_vote",
+       "ext_pri_i2s",
+       "ext_mclk",
+       "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = {
+       { P_XO, 0 },
+       { P_GPLL1, 1 },
+       { P_EXT_SEC_I2S, 2 },
+       { P_EXT_MCLK, 3 },
+       { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll1_esi2s_emclk_sleep[] = {
+       "xo",
+       "gpll1_vote",
+       "ext_sec_i2s",
+       "ext_mclk",
+       "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_sleep_map[] = {
+       { P_XO, 0 },
+       { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_sleep[] = {
+       "xo",
+       "sleep_clk",
+};
+
+static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = {
+       { P_XO, 0 },
+       { P_GPLL1, 1 },
+       { P_EXT_MCLK, 2 },
+       { P_SLEEP_CLK, 6 }
+};
+
+static const char * const gcc_xo_gpll1_emclk_sleep[] = {
+       "xo",
+       "gpll1_vote",
+       "ext_mclk",
+       "sleep_clk",
+};
+
 #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
 
 static struct clk_pll gpll0 = {
@@ -906,21 +980,15 @@ static struct clk_rcg2 gp3_clk_src = {
        },
 };
 
-static struct freq_tbl ftbl_gcc_mdss_byte0_clk[] = {
-       { .src = P_DSI0_PHYPLL_BYTE },
-       { }
-};
-
 static struct clk_rcg2 byte0_clk_src = {
        .cmd_rcgr = 0x4d044,
        .hid_width = 5,
        .parent_map = gcc_xo_gpll0a_dsibyte_map,
-       .freq_tbl = ftbl_gcc_mdss_byte0_clk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "byte0_clk_src",
                .parent_names = gcc_xo_gpll0a_dsibyte,
                .num_parents = 3,
-               .ops = &clk_byte_ops,
+               .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -968,17 +1036,11 @@ static struct clk_rcg2 mdp_clk_src = {
        },
 };
 
-static struct freq_tbl ftbl_gcc_mdss_pclk[] = {
-       { .src = P_DSI0_PHYPLL_DSI },
-       { }
-};
-
 static struct clk_rcg2 pclk0_clk_src = {
        .cmd_rcgr = 0x4d000,
        .mnd_width = 8,
        .hid_width = 5,
        .parent_map = gcc_xo_gpll0a_dsiphy_map,
-       .freq_tbl = ftbl_gcc_mdss_pclk,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk0_clk_src",
                .parent_names = gcc_xo_gpll0a_dsiphy,
@@ -1094,6 +1156,30 @@ static struct clk_rcg2 apss_tcu_clk_src = {
        },
 };
 
+static const struct freq_tbl ftbl_gcc_bimc_gpu_clk[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266500000, P_BIMC, 4, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(533000000, P_BIMC, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 bimc_gpu_clk_src = {
+       .cmd_rcgr = 0x31028,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .freq_tbl = ftbl_gcc_bimc_gpu_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "bimc_gpu_clk_src",
+               .parent_names = gcc_xo_gpll0_bimc,
+               .num_parents = 3,
+               .flags = CLK_GET_RATE_NOCACHE,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
 static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = {
        F(80000000, P_GPLL0, 10, 0, 0),
        { }
@@ -1112,6 +1198,305 @@ static struct clk_rcg2 usb_hs_system_clk_src = {
        },
 };
 
+static const struct freq_tbl ftbl_gcc_ultaudio_ahb_clk[] = {
+       F(3200000, P_XO, 6, 0, 0),
+       F(6400000, P_XO, 3, 0, 0),
+       F(9600000, P_XO, 2, 0, 0),
+       F(19200000, P_XO, 1, 0, 0),
+       F(40000000, P_GPLL0, 10, 1, 2),
+       F(66670000, P_GPLL0, 12, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ultaudio_ahbfabric_clk_src = {
+       .cmd_rcgr = 0x1c010,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_xo_gpll0_gpll1_sleep_map,
+       .freq_tbl = ftbl_gcc_ultaudio_ahb_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ultaudio_ahbfabric_clk_src",
+               .parent_names = gcc_xo_gpll0_gpll1_sleep,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = {
+       .halt_reg = 0x1c028,
+       .clkr = {
+               .enable_reg = 0x1c028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_ahbfabric_ixfabric_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_ahbfabric_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = {
+       .halt_reg = 0x1c024,
+       .clkr = {
+               .enable_reg = 0x1c024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_ahbfabric_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_lpaif_i2s_clk[] = {
+       F(256000, P_XO, 5, 1, 15),
+       F(512000, P_XO, 5, 2, 15),
+       F(705600, P_GPLL1, 16, 1, 80),
+       F(768000, P_XO, 5, 1, 5),
+       F(800000, P_XO, 5, 5, 24),
+       F(1024000, P_GPLL1, 14, 1, 63),
+       F(1152000, P_XO, 1, 3, 50),
+       F(1411200, P_GPLL1, 16, 1, 40),
+       F(1536000, P_XO, 1, 2, 25),
+       F(1600000, P_XO, 12, 0, 0),
+       F(2048000, P_GPLL1, 9, 1, 49),
+       F(2400000, P_XO, 8, 0, 0),
+       F(2822400, P_GPLL1, 16, 1, 20),
+       F(3072000, P_GPLL1, 14, 1, 21),
+       F(4096000, P_GPLL1, 9, 2, 49),
+       F(4800000, P_XO, 4, 0, 0),
+       F(5644800, P_GPLL1, 16, 1, 10),
+       F(6144000, P_GPLL1, 7, 1, 21),
+       F(8192000, P_GPLL1, 9, 4, 49),
+       F(9600000, P_XO, 2, 0, 0),
+       F(11289600, P_GPLL1, 16, 1, 5),
+       F(12288000, P_GPLL1, 7, 2, 21),
+       { }
+};
+
+static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = {
+       .cmd_rcgr = 0x1c054,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_xo_gpll1_epi2s_emclk_sleep_map,
+       .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ultaudio_lpaif_pri_i2s_clk_src",
+               .parent_names = gcc_xo_gpll1_epi2s_emclk_sleep,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = {
+       .halt_reg = 0x1c068,
+       .clkr = {
+               .enable_reg = 0x1c068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_lpaif_pri_i2s_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_lpaif_pri_i2s_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = {
+       .cmd_rcgr = 0x1c06c,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_xo_gpll1_esi2s_emclk_sleep_map,
+       .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ultaudio_lpaif_sec_i2s_clk_src",
+               .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = {
+       .halt_reg = 0x1c080,
+       .clkr = {
+               .enable_reg = 0x1c080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_lpaif_sec_i2s_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_lpaif_sec_i2s_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = {
+       .cmd_rcgr = 0x1c084,
+       .hid_width = 5,
+       .mnd_width = 8,
+       .parent_map = gcc_xo_gpll1_emclk_sleep_map,
+       .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ultaudio_lpaif_aux_i2s_clk_src",
+               .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = {
+       .halt_reg = 0x1c098,
+       .clkr = {
+               .enable_reg = 0x1c098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_lpaif_aux_i2s_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_lpaif_aux_i2s_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_gcc_ultaudio_xo_clk[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ultaudio_xo_clk_src = {
+       .cmd_rcgr = 0x1c034,
+       .hid_width = 5,
+       .parent_map = gcc_xo_sleep_map,
+       .freq_tbl = ftbl_gcc_ultaudio_xo_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ultaudio_xo_clk_src",
+               .parent_names = gcc_xo_sleep,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_ultaudio_avsync_xo_clk = {
+       .halt_reg = 0x1c04c,
+       .clkr = {
+               .enable_reg = 0x1c04c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_avsync_xo_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_xo_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ultaudio_stc_xo_clk = {
+       .halt_reg = 0x1c050,
+       .clkr = {
+               .enable_reg = 0x1c050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_stc_xo_clk",
+                       .parent_names = (const char *[]){
+                               "ultaudio_xo_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_codec_clk[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(11289600, P_EXT_MCLK, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 codec_digcodec_clk_src = {
+       .cmd_rcgr = 0x1c09c,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll1_emclk_sleep_map,
+       .freq_tbl = ftbl_codec_clk,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "codec_digcodec_clk_src",
+               .parent_names = gcc_xo_gpll1_emclk_sleep,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_codec_digcodec_clk = {
+       .halt_reg = 0x1c0b0,
+       .clkr = {
+               .enable_reg = 0x1c0b0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_codec_digcodec_clk",
+                       .parent_names = (const char *[]){
+                               "codec_digcodec_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = {
+       .halt_reg = 0x1c000,
+       .clkr = {
+               .enable_reg = 0x1c000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_pcnoc_mport_clk",
+                       .parent_names = (const char *[]){
+                               "pcnoc_bfdcd_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = {
+       .halt_reg = 0x1c004,
+       .clkr = {
+               .enable_reg = 0x1c004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ultaudio_pcnoc_sway_clk",
+                       .parent_names = (const char *[]){
+                               "pcnoc_bfdcd_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = {
        F(100000000, P_GPLL0, 8, 0, 0),
        F(160000000, P_GPLL0, 5, 0, 0),
@@ -2358,6 +2743,51 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
        },
 };
 
+static struct clk_rcg2 bimc_ddr_clk_src = {
+       .cmd_rcgr = 0x32004,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_bimc_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "bimc_ddr_clk_src",
+               .parent_names = gcc_xo_gpll0_bimc,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_branch gcc_apss_tcu_clk = {
+       .halt_reg = 0x12018,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_tcu_clk",
+                       .parent_names = (const char *[]){
+                               "bimc_ddr_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gfx_tcu_clk = {
+       .halt_reg = 0x12020,
+       .clkr = {
+               .enable_reg = 0x4500c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gfx_tcu_clk",
+                       .parent_names = (const char *[]){
+                               "bimc_ddr_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_gtcu_ahb_clk = {
        .halt_reg = 0x12044,
        .clkr = {
@@ -2375,6 +2805,40 @@ static struct clk_branch gcc_gtcu_ahb_clk = {
        },
 };
 
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x31024,
+       .clkr = {
+               .enable_reg = 0x31024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gfx_clk",
+                       .parent_names = (const char *[]){
+                               "bimc_gpu_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_bimc_gpu_clk = {
+       .halt_reg = 0x31040,
+       .clkr = {
+               .enable_reg = 0x31040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gpu_clk",
+                       .parent_names = (const char *[]){
+                               "bimc_gpu_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_jpeg_tbu_clk = {
        .halt_reg = 0x12034,
        .clkr = {
@@ -2562,6 +3026,46 @@ static struct clk_branch gcc_venus0_vcodec0_clk = {
        },
 };
 
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x4c018,
+       .pd = {
+               .name = "venus",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x4d078,
+       .pd = {
+               .name = "mdss",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+       .gdscr = 0x5701c,
+       .pd = {
+               .name = "jpeg",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe_gdsc = {
+       .gdscr = 0x58034,
+       .pd = {
+               .name = "vfe",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+       .gdscr = 0x5901c,
+       .pd = {
+               .name = "oxili",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *gcc_msm8916_clocks[] = {
        [GPLL0] = &gpll0.clkr,
        [GPLL0_VOTE] = &gpll0_vote,
@@ -2701,6 +3205,36 @@ static struct clk_regmap *gcc_msm8916_clocks[] = {
        [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr,
        [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr,
        [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
+       [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr,
+       [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr,
+       [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr,
+       [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr,
+       [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
+       [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr,
+       [ULTAUDIO_AHBFABRIC_CLK_SRC] = &ultaudio_ahbfabric_clk_src.clkr,
+       [ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC] = &ultaudio_lpaif_pri_i2s_clk_src.clkr,
+       [ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC] = &ultaudio_lpaif_sec_i2s_clk_src.clkr,
+       [ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC] = &ultaudio_lpaif_aux_i2s_clk_src.clkr,
+       [ULTAUDIO_XO_CLK_SRC] = &ultaudio_xo_clk_src.clkr,
+       [CODEC_DIGCODEC_CLK_SRC] = &codec_digcodec_clk_src.clkr,
+       [GCC_ULTAUDIO_PCNOC_MPORT_CLK] = &gcc_ultaudio_pcnoc_mport_clk.clkr,
+       [GCC_ULTAUDIO_PCNOC_SWAY_CLK] = &gcc_ultaudio_pcnoc_sway_clk.clkr,
+       [GCC_ULTAUDIO_AVSYNC_XO_CLK] = &gcc_ultaudio_avsync_xo_clk.clkr,
+       [GCC_ULTAUDIO_STC_XO_CLK] = &gcc_ultaudio_stc_xo_clk.clkr,
+       [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_clk.clkr,
+       [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_lpm_clk.clkr,
+       [GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK] = &gcc_ultaudio_lpaif_pri_i2s_clk.clkr,
+       [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr,
+       [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr,
+       [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr,
+};
+
+static struct gdsc *gcc_msm8916_gdscs[] = {
+       [VENUS_GDSC] = &venus_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [JPEG_GDSC] = &jpeg_gdsc,
+       [VFE_GDSC] = &vfe_gdsc,
+       [OXILI_GDSC] = &oxili_gdsc,
 };
 
 static const struct qcom_reset_map gcc_msm8916_resets[] = {
@@ -2810,6 +3344,8 @@ static const struct qcom_cc_desc gcc_msm8916_desc = {
        .num_clks = ARRAY_SIZE(gcc_msm8916_clocks),
        .resets = gcc_msm8916_resets,
        .num_resets = ARRAY_SIZE(gcc_msm8916_resets),
+       .gdscs = gcc_msm8916_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_msm8916_gdscs),
 };
 
 static const struct of_device_id gcc_msm8916_match_table[] = {
@@ -2836,15 +3372,8 @@ static int gcc_msm8916_probe(struct platform_device *pdev)
        return qcom_cc_probe(pdev, &gcc_msm8916_desc);
 }
 
-static int gcc_msm8916_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver gcc_msm8916_driver = {
        .probe          = gcc_msm8916_probe,
-       .remove         = gcc_msm8916_remove,
        .driver         = {
                .name   = "gcc-msm8916",
                .of_match_table = gcc_msm8916_match_table,
index aa294b1bad343ccbef5b4daef38cda33fd6513f1..66c18bc97857d8d7cf75318fe91a153dcb3945d1 100644 (file)
@@ -3506,6 +3506,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
        struct clk *clk;
        struct device *dev = &pdev->dev;
        const struct of_device_id *match;
+       struct platform_device *tsens;
+       int ret;
 
        match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
        if (!match)
@@ -3520,12 +3522,26 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
-       return qcom_cc_probe(pdev, match->data);
+       ret = qcom_cc_probe(pdev, match->data);
+       if (ret)
+               return ret;
+
+       tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1,
+                                             NULL, 0);
+       if (IS_ERR(tsens))
+               return PTR_ERR(tsens);
+
+       platform_set_drvdata(pdev, tsens);
+
+       return 0;
 }
 
 static int gcc_msm8960_remove(struct platform_device *pdev)
 {
-       qcom_cc_remove(pdev);
+       struct platform_device *tsens = platform_get_drvdata(pdev);
+
+       platform_device_unregister(tsens);
+
        return 0;
 }
 
index 2bcf87538f9d7e34700d1a2e21b366e1618d4a5e..28abb8f8f293d1c3ad373139796d4725bd040e77 100644 (file)
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
        P_XO,
@@ -2432,6 +2433,14 @@ static struct clk_branch gcc_usb_hsic_system_clk = {
        },
 };
 
+static struct gdsc usb_hs_hsic_gdsc = {
+       .gdscr = 0x404,
+       .pd = {
+               .name = "usb_hs_hsic",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *gcc_msm8974_clocks[] = {
        [GPLL0] = &gpll0.clkr,
        [GPLL0_VOTE] = &gpll0_vote,
@@ -2661,6 +2670,10 @@ static const struct qcom_reset_map gcc_msm8974_resets[] = {
        [GCC_VENUS_RESTART] = { 0x1740 },
 };
 
+static struct gdsc *gcc_msm8974_gdscs[] = {
+       [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
+};
+
 static const struct regmap_config gcc_msm8974_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
@@ -2675,6 +2688,8 @@ static const struct qcom_cc_desc gcc_msm8974_desc = {
        .num_clks = ARRAY_SIZE(gcc_msm8974_clocks),
        .resets = gcc_msm8974_resets,
        .num_resets = ARRAY_SIZE(gcc_msm8974_resets),
+       .gdscs = gcc_msm8974_gdscs,
+       .num_gdscs = ARRAY_SIZE(gcc_msm8974_gdscs),
 };
 
 static const struct of_device_id gcc_msm8974_match_table[] = {
@@ -2729,15 +2744,8 @@ static int gcc_msm8974_probe(struct platform_device *pdev)
        return qcom_cc_probe(pdev, &gcc_msm8974_desc);
 }
 
-static int gcc_msm8974_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver gcc_msm8974_driver = {
        .probe          = gcc_msm8974_probe,
-       .remove         = gcc_msm8974_remove,
        .driver         = {
                .name   = "gcc-msm8974",
                .of_match_table = gcc_msm8974_match_table,
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644 (file)
index 0000000..da9fad8
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include "gdsc.h"
+
+#define PWR_ON_MASK            BIT(31)
+#define EN_REST_WAIT_MASK      GENMASK_ULL(23, 20)
+#define EN_FEW_WAIT_MASK       GENMASK_ULL(19, 16)
+#define CLK_DIS_WAIT_MASK      GENMASK_ULL(15, 12)
+#define SW_OVERRIDE_MASK       BIT(2)
+#define HW_CONTROL_MASK                BIT(1)
+#define SW_COLLAPSE_MASK       BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL       (0x2 << 20)
+#define EN_FEW_WAIT_VAL                (0x8 << 16)
+#define CLK_DIS_WAIT_VAL       (0x2 << 12)
+
+#define RETAIN_MEM             BIT(14)
+#define RETAIN_PERIPH          BIT(13)
+
+#define TIMEOUT_US             100
+
+#define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
+
+static int gdsc_is_enabled(struct gdsc *sc)
+{
+       u32 val;
+       int ret;
+
+       ret = regmap_read(sc->regmap, sc->gdscr, &val);
+       if (ret)
+               return ret;
+
+       return !!(val & PWR_ON_MASK);
+}
+
+static int gdsc_toggle_logic(struct gdsc *sc, bool en)
+{
+       int ret;
+       u32 val = en ? 0 : SW_COLLAPSE_MASK;
+       u32 check = en ? PWR_ON_MASK : 0;
+       unsigned long timeout;
+
+       ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
+       if (ret)
+               return ret;
+
+       timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+       do {
+               ret = regmap_read(sc->regmap, sc->gdscr, &val);
+               if (ret)
+                       return ret;
+
+               if ((val & PWR_ON_MASK) == check)
+                       return 0;
+       } while (time_before(jiffies, timeout));
+
+       ret = regmap_read(sc->regmap, sc->gdscr, &val);
+       if (ret)
+               return ret;
+
+       if ((val & PWR_ON_MASK) == check)
+               return 0;
+
+       return -ETIMEDOUT;
+}
+
+static inline int gdsc_deassert_reset(struct gdsc *sc)
+{
+       int i;
+
+       for (i = 0; i < sc->reset_count; i++)
+               sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
+       return 0;
+}
+
+static inline int gdsc_assert_reset(struct gdsc *sc)
+{
+       int i;
+
+       for (i = 0; i < sc->reset_count; i++)
+               sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
+       return 0;
+}
+
+static inline void gdsc_force_mem_on(struct gdsc *sc)
+{
+       int i;
+       u32 mask = RETAIN_MEM | RETAIN_PERIPH;
+
+       for (i = 0; i < sc->cxc_count; i++)
+               regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+}
+
+static inline void gdsc_clear_mem_on(struct gdsc *sc)
+{
+       int i;
+       u32 mask = RETAIN_MEM | RETAIN_PERIPH;
+
+       for (i = 0; i < sc->cxc_count; i++)
+               regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
+}
+
+static int gdsc_enable(struct generic_pm_domain *domain)
+{
+       struct gdsc *sc = domain_to_gdsc(domain);
+       int ret;
+
+       if (sc->pwrsts == PWRSTS_ON)
+               return gdsc_deassert_reset(sc);
+
+       ret = gdsc_toggle_logic(sc, true);
+       if (ret)
+               return ret;
+
+       if (sc->pwrsts & PWRSTS_OFF)
+               gdsc_force_mem_on(sc);
+
+       /*
+        * If clocks to this power domain were already on, they will take an
+        * additional 4 clock cycles to re-enable after the power domain is
+        * enabled. Delay to account for this. A delay is also needed to ensure
+        * clocks are not enabled within 400ns of enabling power to the
+        * memories.
+        */
+       udelay(1);
+
+       return 0;
+}
+
+static int gdsc_disable(struct generic_pm_domain *domain)
+{
+       struct gdsc *sc = domain_to_gdsc(domain);
+
+       if (sc->pwrsts == PWRSTS_ON)
+               return gdsc_assert_reset(sc);
+
+       if (sc->pwrsts & PWRSTS_OFF)
+               gdsc_clear_mem_on(sc);
+
+       return gdsc_toggle_logic(sc, false);
+}
+
+static int gdsc_init(struct gdsc *sc)
+{
+       u32 mask, val;
+       int on, ret;
+
+       /*
+        * Disable HW trigger: collapse/restore occur based on registers writes.
+        * Disable SW override: Use hardware state-machine for sequencing.
+        * Configure wait time between states.
+        */
+       mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+              EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+       val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+       ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+       if (ret)
+               return ret;
+
+       /* Force gdsc ON if only ON state is supported */
+       if (sc->pwrsts == PWRSTS_ON) {
+               ret = gdsc_toggle_logic(sc, true);
+               if (ret)
+                       return ret;
+       }
+
+       on = gdsc_is_enabled(sc);
+       if (on < 0)
+               return on;
+
+       if (on || (sc->pwrsts & PWRSTS_RET))
+               gdsc_force_mem_on(sc);
+       else
+               gdsc_clear_mem_on(sc);
+
+       sc->pd.power_off = gdsc_disable;
+       sc->pd.power_on = gdsc_enable;
+       pm_genpd_init(&sc->pd, NULL, !on);
+
+       return 0;
+}
+
+int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
+                 struct reset_controller_dev *rcdev, struct regmap *regmap)
+{
+       int i, ret;
+       struct genpd_onecell_data *data;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->domains = devm_kcalloc(dev, num, sizeof(*data->domains),
+                                    GFP_KERNEL);
+       if (!data->domains)
+               return -ENOMEM;
+
+       data->num_domains = num;
+       for (i = 0; i < num; i++) {
+               if (!scs[i])
+                       continue;
+               scs[i]->regmap = regmap;
+               scs[i]->rcdev = rcdev;
+               ret = gdsc_init(scs[i]);
+               if (ret)
+                       return ret;
+               data->domains[i] = &scs[i]->pd;
+       }
+
+       return of_genpd_add_provider_onecell(dev->of_node, data);
+}
+
+void gdsc_unregister(struct device *dev)
+{
+       of_genpd_del_provider(dev->of_node);
+}
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644 (file)
index 0000000..5ded268
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __QCOM_GDSC_H__
+#define __QCOM_GDSC_H__
+
+#include <linux/err.h>
+#include <linux/pm_domain.h>
+
+struct regmap;
+struct reset_controller_dev;
+
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_OFF             BIT(0)
+#define PWRSTS_RET             BIT(1)
+#define PWRSTS_ON              BIT(2)
+#define PWRSTS_OFF_ON          (PWRSTS_OFF | PWRSTS_ON)
+#define PWRSTS_RET_ON          (PWRSTS_RET | PWRSTS_ON)
+
+/**
+ * struct gdsc - Globally Distributed Switch Controller
+ * @pd: generic power domain
+ * @regmap: regmap for MMIO accesses
+ * @gdscr: gsdc control register
+ * @cxcs: offsets of branch registers to toggle mem/periph bits in
+ * @cxc_count: number of @cxcs
+ * @pwrsts: Possible powerdomain power states
+ * @resets: ids of resets associated with this gdsc
+ * @reset_count: number of @resets
+ * @rcdev: reset controller
+ */
+struct gdsc {
+       struct generic_pm_domain        pd;
+       struct regmap                   *regmap;
+       unsigned int                    gdscr;
+       unsigned int                    *cxcs;
+       unsigned int                    cxc_count;
+       const u8                        pwrsts;
+       struct reset_controller_dev     *rcdev;
+       unsigned int                    *resets;
+       unsigned int                    reset_count;
+};
+
+#ifdef CONFIG_QCOM_GDSC
+int gdsc_register(struct device *, struct gdsc **, size_t n,
+                 struct reset_controller_dev *, struct regmap *);
+void gdsc_unregister(struct device *);
+#else
+static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
+                               struct reset_controller_dev *rcdev,
+                               struct regmap *r)
+{
+       return -ENOSYS;
+}
+
+static inline void gdsc_unregister(struct device *d) {};
+#endif /* CONFIG_QCOM_GDSC */
+#endif /* __QCOM_GDSC_H__ */
index 93ad42b1436604be66fcbb8081932879929fd823..db3998e5e2d83d77a5b07f8d1e29490b2e532f6d 100644 (file)
@@ -452,15 +452,8 @@ static int lcc_ipq806x_probe(struct platform_device *pdev)
        return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap);
 }
 
-static int lcc_ipq806x_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver lcc_ipq806x_driver = {
        .probe          = lcc_ipq806x_probe,
-       .remove         = lcc_ipq806x_remove,
        .driver         = {
                .name   = "lcc-ipq806x",
                .of_match_table = lcc_ipq806x_match_table,
index ecb96c2846756e78185ad9b3be6b9d8d75218edc..4fcf9d1d233c0a0c64c2455efcdd11015da89b18 100644 (file)
@@ -565,15 +565,8 @@ static int lcc_msm8960_probe(struct platform_device *pdev)
        return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap);
 }
 
-static int lcc_msm8960_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver lcc_msm8960_driver = {
        .probe          = lcc_msm8960_probe,
-       .remove         = lcc_msm8960_remove,
        .driver         = {
                .name   = "lcc-msm8960",
                .of_match_table = lcc_msm8960_match_table,
index f0ee6bde11af3b4e31d4566329c07004657414c1..30777f9f1a439eef1ad5e8d4446017d7f3999392 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -26,6 +26,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
        P_XO,
@@ -571,17 +572,11 @@ static struct clk_rcg2 jpeg2_clk_src = {
        },
 };
 
-static struct freq_tbl pixel_freq_tbl[] = {
-       { .src = P_DSI0PLL },
-       { }
-};
-
 static struct clk_rcg2 pclk0_clk_src = {
        .cmd_rcgr = 0x2000,
        .mnd_width = 8,
        .hid_width = 5,
        .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-       .freq_tbl = pixel_freq_tbl,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk0_clk_src",
                .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -596,7 +591,6 @@ static struct clk_rcg2 pclk1_clk_src = {
        .mnd_width = 8,
        .hid_width = 5,
        .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-       .freq_tbl = pixel_freq_tbl,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk1_clk_src",
                .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -844,21 +838,15 @@ static struct clk_rcg2 cpp_clk_src = {
        },
 };
 
-static struct freq_tbl byte_freq_tbl[] = {
-       { .src = P_DSI0PLL_BYTE },
-       { }
-};
-
 static struct clk_rcg2 byte0_clk_src = {
        .cmd_rcgr = 0x2120,
        .hid_width = 5,
        .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
-       .freq_tbl = byte_freq_tbl,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "byte0_clk_src",
                .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
                .num_parents = 6,
-               .ops = &clk_byte_ops,
+               .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -867,12 +855,11 @@ static struct clk_rcg2 byte1_clk_src = {
        .cmd_rcgr = 0x2140,
        .hid_width = 5,
        .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map,
-       .freq_tbl = byte_freq_tbl,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "byte1_clk_src",
                .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
                .num_parents = 6,
-               .ops = &clk_byte_ops,
+               .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -3077,6 +3064,76 @@ static const struct pll_config mmpll3_config = {
        .aux_output_mask = BIT(1),
 };
 
+static struct gdsc venus0_gdsc = {
+       .gdscr = 0x1024,
+       .pd = {
+               .name = "venus0",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus0_core0_gdsc = {
+       .gdscr = 0x1040,
+       .pd = {
+               .name = "venus0_core0",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus0_core1_gdsc = {
+       .gdscr = 0x1044,
+       .pd = {
+               .name = "venus0_core1",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x2304,
+       .cxcs = (unsigned int []){ 0x231c, 0x2320 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "mdss",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_jpeg_gdsc = {
+       .gdscr = 0x35a4,
+       .pd = {
+               .name = "camss_jpeg",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe_gdsc = {
+       .gdscr = 0x36a4,
+       .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x36b0 },
+       .cxc_count = 3,
+       .pd = {
+               .name = "camss_vfe",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+       .gdscr = 0x4024,
+       .cxcs = (unsigned int []){ 0x4028 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "oxili",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxilicx_gdsc = {
+       .gdscr = 0x4034,
+       .pd = {
+               .name = "oxilicx",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *mmcc_apq8084_clocks[] = {
        [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
        [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -3294,6 +3351,17 @@ static const struct qcom_reset_map mmcc_apq8084_resets[] = {
        [MMSSNOCAXI_RESET] = { 0x5060 },
 };
 
+static struct gdsc *mmcc_apq8084_gdscs[] = {
+       [VENUS0_GDSC] = &venus0_gdsc,
+       [VENUS0_CORE0_GDSC] = &venus0_core0_gdsc,
+       [VENUS0_CORE1_GDSC] = &venus0_core1_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
+       [CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
+       [OXILI_GDSC] = &oxili_gdsc,
+       [OXILICX_GDSC] = &oxilicx_gdsc,
+};
+
 static const struct regmap_config mmcc_apq8084_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
@@ -3308,6 +3376,8 @@ static const struct qcom_cc_desc mmcc_apq8084_desc = {
        .num_clks = ARRAY_SIZE(mmcc_apq8084_clocks),
        .resets = mmcc_apq8084_resets,
        .num_resets = ARRAY_SIZE(mmcc_apq8084_resets),
+       .gdscs = mmcc_apq8084_gdscs,
+       .num_gdscs = ARRAY_SIZE(mmcc_apq8084_gdscs),
 };
 
 static const struct of_device_id mmcc_apq8084_match_table[] = {
@@ -3332,15 +3402,8 @@ static int mmcc_apq8084_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int mmcc_apq8084_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver mmcc_apq8084_driver = {
        .probe          = mmcc_apq8084_probe,
-       .remove         = mmcc_apq8084_remove,
        .driver         = {
                .name   = "mmcc-apq8084",
                .of_match_table = mmcc_apq8084_match_table,
index bad02aebf959b6caed9b1941d8b9decf4152f7dd..00e36192a1defe9131f1f1505f89b88b574f4284 100644 (file)
@@ -41,6 +41,10 @@ enum {
        P_PLL3,
        P_PLL15,
        P_HDMI_PLL,
+       P_DSI1_PLL_DSICLK,
+       P_DSI2_PLL_DSICLK,
+       P_DSI1_PLL_BYTECLK,
+       P_DSI2_PLL_BYTECLK,
 };
 
 #define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n }
@@ -85,6 +89,30 @@ static const char * const mmcc_pxo_pll8_pll2_pll3[] = {
        "pll3",
 };
 
+static const struct parent_map mmcc_pxo_dsi2_dsi1_map[] = {
+       { P_PXO, 0 },
+       { P_DSI2_PLL_DSICLK, 1 },
+       { P_DSI1_PLL_DSICLK, 3 },
+};
+
+static const char * const mmcc_pxo_dsi2_dsi1[] = {
+       "pxo",
+       "dsi2pll",
+       "dsi1pll",
+};
+
+static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = {
+       { P_PXO, 0 },
+       { P_DSI1_PLL_BYTECLK, 1 },
+       { P_DSI2_PLL_BYTECLK, 2 },
+};
+
+static const char * const mmcc_pxo_dsi1_dsi2_byte[] = {
+       "pxo",
+       "dsi1pllbyte",
+       "dsi2pllbyte",
+};
+
 static struct clk_pll pll2 = {
        .l_reg = 0x320,
        .m_reg = 0x324,
@@ -2042,6 +2070,350 @@ static struct clk_branch dsi2_s_ahb_clk = {
        },
 };
 
+static struct clk_rcg dsi1_src = {
+       .ns_reg = 0x0054,
+       .md_reg = 0x0050,
+       .mn = {
+               .mnctr_en_bit = 5,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 6,
+               .n_val_shift = 24,
+               .m_val_shift = 8,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 14,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi2_dsi1_map,
+       },
+       .clkr = {
+               .enable_reg = 0x004c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_src",
+                       .parent_names = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_bypass2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch dsi1_clk = {
+       .halt_reg = 0x01d0,
+       .halt_bit = 2,
+       .clkr = {
+               .enable_reg = 0x004c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_clk",
+                       .parent_names = (const char *[]){ "dsi1_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi2_src = {
+       .ns_reg = 0x012c,
+       .md_reg = 0x00a8,
+       .mn = {
+               .mnctr_en_bit = 5,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 6,
+               .n_val_shift = 24,
+               .m_val_shift = 8,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 14,
+               .pre_div_width = 2,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi2_dsi1_map,
+       },
+       .clkr = {
+               .enable_reg = 0x003c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_src",
+                       .parent_names = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_bypass2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch dsi2_clk = {
+       .halt_reg = 0x01d0,
+       .halt_bit = 20,
+       .clkr = {
+               .enable_reg = 0x003c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_clk",
+                       .parent_names = (const char *[]){ "dsi2_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi1_byte_src = {
+       .ns_reg = 0x00b0,
+       .p = {
+               .pre_div_shift = 12,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
+       },
+       .clkr = {
+               .enable_reg = 0x0090,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_byte_src",
+                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_bypass2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch dsi1_byte_clk = {
+       .halt_reg = 0x01cc,
+       .halt_bit = 21,
+       .clkr = {
+               .enable_reg = 0x0090,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_byte_clk",
+                       .parent_names = (const char *[]){ "dsi1_byte_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi2_byte_src = {
+       .ns_reg = 0x012c,
+       .p = {
+               .pre_div_shift = 12,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
+       },
+       .clkr = {
+               .enable_reg = 0x0130,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_byte_src",
+                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_bypass2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch dsi2_byte_clk = {
+       .halt_reg = 0x01cc,
+       .halt_bit = 20,
+       .clkr = {
+               .enable_reg = 0x00b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_byte_clk",
+                       .parent_names = (const char *[]){ "dsi2_byte_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi1_esc_src = {
+       .ns_reg = 0x0011c,
+       .p = {
+               .pre_div_shift = 12,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
+       },
+       .clkr = {
+               .enable_reg = 0x00cc,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_esc_src",
+                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_esc_ops,
+               },
+       },
+};
+
+static struct clk_branch dsi1_esc_clk = {
+       .halt_reg = 0x01e8,
+       .halt_bit = 1,
+       .clkr = {
+               .enable_reg = 0x00cc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_esc_clk",
+                       .parent_names = (const char *[]){ "dsi1_esc_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi2_esc_src = {
+       .ns_reg = 0x0150,
+       .p = {
+               .pre_div_shift = 12,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi1_dsi2_byte_map,
+       },
+       .clkr = {
+               .enable_reg = 0x013c,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_esc_src",
+                       .parent_names = mmcc_pxo_dsi1_dsi2_byte,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_esc_ops,
+               },
+       },
+};
+
+static struct clk_branch dsi2_esc_clk = {
+       .halt_reg = 0x01e8,
+       .halt_bit = 3,
+       .clkr = {
+               .enable_reg = 0x013c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_esc_clk",
+                       .parent_names = (const char *[]){ "dsi2_esc_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi1_pixel_src = {
+       .ns_reg = 0x0138,
+       .md_reg = 0x0134,
+       .mn = {
+               .mnctr_en_bit = 5,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 6,
+               .n_val_shift = 16,
+               .m_val_shift = 8,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 12,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi2_dsi1_map,
+       },
+       .clkr = {
+               .enable_reg = 0x0130,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi1_pixel_src",
+                       .parent_names = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_pixel_ops,
+               },
+       },
+};
+
+static struct clk_branch dsi1_pixel_clk = {
+       .halt_reg = 0x01d0,
+       .halt_bit = 6,
+       .clkr = {
+               .enable_reg = 0x0130,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdp_pclk1_clk",
+                       .parent_names = (const char *[]){ "dsi1_pixel_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_rcg dsi2_pixel_src = {
+       .ns_reg = 0x00e4,
+       .md_reg = 0x00b8,
+       .mn = {
+               .mnctr_en_bit = 5,
+               .mnctr_reset_bit = 7,
+               .mnctr_mode_shift = 6,
+               .n_val_shift = 16,
+               .m_val_shift = 8,
+               .width = 8,
+       },
+       .p = {
+               .pre_div_shift = 12,
+               .pre_div_width = 4,
+       },
+       .s = {
+               .src_sel_shift = 0,
+               .parent_map = mmcc_pxo_dsi2_dsi1_map,
+       },
+       .clkr = {
+               .enable_reg = 0x0094,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "dsi2_pixel_src",
+                       .parent_names = mmcc_pxo_dsi2_dsi1,
+                       .num_parents = 3,
+                       .ops = &clk_rcg_pixel_ops,
+               },
+       },
+};
+
+static struct clk_branch dsi2_pixel_clk = {
+       .halt_reg = 0x01d0,
+       .halt_bit = 19,
+       .clkr = {
+               .enable_reg = 0x0094,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdp_pclk2_clk",
+                       .parent_names = (const char *[]){ "dsi2_pixel_src" },
+                       .num_parents = 1,
+                       .ops = &clk_branch_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
 static struct clk_branch gfx2d0_ahb_clk = {
        .hwcg_reg = 0x0038,
        .hwcg_bit = 28,
@@ -2325,6 +2697,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
        [CSI2_SRC] = &csi2_src.clkr,
        [CSI2_CLK] = &csi2_clk.clkr,
        [CSI2_PHY_CLK] = &csi2_phy_clk.clkr,
+       [DSI_SRC] = &dsi1_src.clkr,
+       [DSI_CLK] = &dsi1_clk.clkr,
        [CSI_PIX_CLK] = &csi_pix_clk.clkr,
        [CSI_RDI_CLK] = &csi_rdi_clk.clkr,
        [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr,
@@ -2345,6 +2719,18 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
        [MDP_SRC] = &mdp_src.clkr,
        [MDP_CLK] = &mdp_clk.clkr,
        [MDP_LUT_CLK] = &mdp_lut_clk.clkr,
+       [DSI2_PIXEL_SRC] = &dsi2_pixel_src.clkr,
+       [DSI2_PIXEL_CLK] = &dsi2_pixel_clk.clkr,
+       [DSI2_SRC] = &dsi2_src.clkr,
+       [DSI2_CLK] = &dsi2_clk.clkr,
+       [DSI1_BYTE_SRC] = &dsi1_byte_src.clkr,
+       [DSI1_BYTE_CLK] = &dsi1_byte_clk.clkr,
+       [DSI2_BYTE_SRC] = &dsi2_byte_src.clkr,
+       [DSI2_BYTE_CLK] = &dsi2_byte_clk.clkr,
+       [DSI1_ESC_SRC] = &dsi1_esc_src.clkr,
+       [DSI1_ESC_CLK] = &dsi1_esc_clk.clkr,
+       [DSI2_ESC_SRC] = &dsi2_esc_src.clkr,
+       [DSI2_ESC_CLK] = &dsi2_esc_clk.clkr,
        [ROT_SRC] = &rot_src.clkr,
        [ROT_CLK] = &rot_clk.clkr,
        [TV_ENC_CLK] = &tv_enc_clk.clkr,
@@ -2359,6 +2745,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
        [VFE_CSI_CLK] = &vfe_csi_clk.clkr,
        [VPE_SRC] = &vpe_src.clkr,
        [VPE_CLK] = &vpe_clk.clkr,
+       [DSI_PIXEL_SRC] = &dsi1_pixel_src.clkr,
+       [DSI_PIXEL_CLK] = &dsi1_pixel_clk.clkr,
        [CAMCLK0_SRC] = &camclk0_src.clkr,
        [CAMCLK0_CLK] = &camclk0_clk.clkr,
        [CAMCLK1_SRC] = &camclk1_src.clkr,
@@ -2490,6 +2878,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
        [CSI2_SRC] = &csi2_src.clkr,
        [CSI2_CLK] = &csi2_clk.clkr,
        [CSI2_PHY_CLK] = &csi2_phy_clk.clkr,
+       [DSI_SRC] = &dsi1_src.clkr,
+       [DSI_CLK] = &dsi1_clk.clkr,
        [CSI_PIX_CLK] = &csi_pix_clk.clkr,
        [CSI_RDI_CLK] = &csi_rdi_clk.clkr,
        [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr,
@@ -2506,6 +2896,18 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
        [MDP_SRC] = &mdp_src.clkr,
        [MDP_CLK] = &mdp_clk.clkr,
        [MDP_LUT_CLK] = &mdp_lut_clk.clkr,
+       [DSI2_PIXEL_SRC] = &dsi2_pixel_src.clkr,
+       [DSI2_PIXEL_CLK] = &dsi2_pixel_clk.clkr,
+       [DSI2_SRC] = &dsi2_src.clkr,
+       [DSI2_CLK] = &dsi2_clk.clkr,
+       [DSI1_BYTE_SRC] = &dsi1_byte_src.clkr,
+       [DSI1_BYTE_CLK] = &dsi1_byte_clk.clkr,
+       [DSI2_BYTE_SRC] = &dsi2_byte_src.clkr,
+       [DSI2_BYTE_CLK] = &dsi2_byte_clk.clkr,
+       [DSI1_ESC_SRC] = &dsi1_esc_src.clkr,
+       [DSI1_ESC_CLK] = &dsi1_esc_clk.clkr,
+       [DSI2_ESC_SRC] = &dsi2_esc_src.clkr,
+       [DSI2_ESC_CLK] = &dsi2_esc_clk.clkr,
        [ROT_SRC] = &rot_src.clkr,
        [ROT_CLK] = &rot_clk.clkr,
        [TV_DAC_CLK] = &tv_dac_clk.clkr,
@@ -2519,6 +2921,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
        [VFE_CSI_CLK] = &vfe_csi_clk.clkr,
        [VPE_SRC] = &vpe_src.clkr,
        [VPE_CLK] = &vpe_clk.clkr,
+       [DSI_PIXEL_SRC] = &dsi1_pixel_src.clkr,
+       [DSI_PIXEL_CLK] = &dsi1_pixel_clk.clkr,
        [CAMCLK0_SRC] = &camclk0_src.clkr,
        [CAMCLK0_CLK] = &camclk0_clk.clkr,
        [CAMCLK1_SRC] = &camclk1_src.clkr,
@@ -2686,15 +3090,8 @@ static int mmcc_msm8960_probe(struct platform_device *pdev)
        return qcom_cc_really_probe(pdev, match->data, regmap);
 }
 
-static int mmcc_msm8960_remove(struct platform_device *pdev)
-{
-       qcom_cc_remove(pdev);
-       return 0;
-}
-
 static struct platform_driver mmcc_msm8960_driver = {
        .probe          = mmcc_msm8960_probe,
-       .remove         = mmcc_msm8960_remove,
        .driver         = {
                .name   = "mmcc-msm8960",
                .of_match_table = mmcc_msm8960_match_table,
index 0987bf443e1f3f57d6a0c36ff0702505abe10041..9d790bcadf25a75a360f8d5aebfdf4ab50237c61 100644 (file)
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
        P_XO,
@@ -522,17 +523,11 @@ static struct clk_rcg2 jpeg2_clk_src = {
        },
 };
 
-static struct freq_tbl pixel_freq_tbl[] = {
-       { .src = P_DSI0PLL },
-       { }
-};
-
 static struct clk_rcg2 pclk0_clk_src = {
        .cmd_rcgr = 0x2000,
        .mnd_width = 8,
        .hid_width = 5,
        .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-       .freq_tbl = pixel_freq_tbl,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk0_clk_src",
                .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -547,7 +542,6 @@ static struct clk_rcg2 pclk1_clk_src = {
        .mnd_width = 8,
        .hid_width = 5,
        .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map,
-       .freq_tbl = pixel_freq_tbl,
        .clkr.hw.init = &(struct clk_init_data){
                .name = "pclk1_clk_src",
                .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0,
@@ -785,7 +779,7 @@ static struct clk_rcg2 byte0_clk_src = {
                .name = "byte0_clk_src",
                .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
                .num_parents = 6,
-               .ops = &clk_byte_ops,
+               .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -799,7 +793,7 @@ static struct clk_rcg2 byte1_clk_src = {
                .name = "byte1_clk_src",
                .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0,
                .num_parents = 6,
-               .ops = &clk_byte_ops,
+               .ops = &clk_byte2_ops,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2349,6 +2343,66 @@ static struct pll_config mmpll3_config = {
        .aux_output_mask = BIT(1),
 };
 
+static struct gdsc venus0_gdsc = {
+       .gdscr = 0x1024,
+       .cxcs = (unsigned int []){ 0x1028 },
+       .cxc_count = 1,
+       .resets = (unsigned int []){ VENUS0_RESET },
+       .reset_count = 1,
+       .pd = {
+               .name = "venus0",
+       },
+       .pwrsts = PWRSTS_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x2304,
+       .cxcs = (unsigned int []){ 0x231c, 0x2320 },
+       .cxc_count = 2,
+       .pd = {
+               .name = "mdss",
+       },
+       .pwrsts = PWRSTS_RET_ON,
+};
+
+static struct gdsc camss_jpeg_gdsc = {
+       .gdscr = 0x35a4,
+       .cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 },
+       .cxc_count = 3,
+       .pd = {
+               .name = "camss_jpeg",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe_gdsc = {
+       .gdscr = 0x36a4,
+       .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 },
+       .cxc_count = 5,
+       .pd = {
+               .name = "camss_vfe",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+       .gdscr = 0x4024,
+       .cxcs = (unsigned int []){ 0x4028 },
+       .cxc_count = 1,
+       .pd = {
+               .name = "oxili",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxilicx_gdsc = {
+       .gdscr = 0x4034,
+       .pd = {
+               .name = "oxilicx",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *mmcc_msm8974_clocks[] = {
        [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
        [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -2525,6 +2579,15 @@ static const struct qcom_reset_map mmcc_msm8974_resets[] = {
        [OCMEMNOC_RESET] = { 0x50b0 },
 };
 
+static struct gdsc *mmcc_msm8974_gdscs[] = {
+       [VENUS0_GDSC] = &venus0_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
+       [CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
+       [OXILI_GDSC] = &oxili_gdsc,
+       [OXILICX_GDSC] = &oxilicx_gdsc,
+};
+
 static const struct regmap_config mmcc_msm8974_regmap_config = {
        .reg_bits       = 32,
        .reg_stride     = 4,
@@ -2539,6 +2602,8 @@ static const struct qcom_cc_desc mmcc_msm8974_desc = {
        .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks),
        .resets = mmcc_msm8974_resets,
        .num_resets = ARRAY_SIZE(mmcc_msm8974_resets),
+       .gdscs = mmcc_msm8974_gdscs,
+       .num_gdscs = ARRAY_SIZE(mmcc_msm8974_gdscs),
 };
 
 static const struct of_device_id mmcc_msm8974_match_table[] = {
@@ -2550,6 +2615,7 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table);
 static int mmcc_msm8974_probe(struct platform_device *pdev)
 {
        struct regmap *regmap;
+       int ret;
 
        regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc);
        if (IS_ERR(regmap))
@@ -2558,12 +2624,16 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
        clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true);
        clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false);
 
-       return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap);
+       ret = qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap);
+       if (ret)
+               return ret;
+
+       return pm_genpd_add_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd);
 }
 
 static int mmcc_msm8974_remove(struct platform_device *pdev)
 {
-       qcom_cc_remove(pdev);
+       pm_genpd_remove_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd);
        return 0;
 }
 
index bc24e5a002e77cad874a0c010fc55046aa66b0f4..2685644826a06ed5a6f21240ad8af040bf4b0b9e 100644 (file)
@@ -41,6 +41,8 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+#define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
+#define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
 
 #define PSECS_PER_SEC 1000000000000LL
 
@@ -159,6 +161,15 @@ struct clk *rockchip_clk_register_mmc(const char *name,
        mmc_clock->reg = reg;
        mmc_clock->shift = shift;
 
+       /*
+        * Assert init_state to soft reset the CLKGEN
+        * for mmc tuning phase and degree
+        */
+       if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
+               writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
+                                    ROCKCHIP_MMC_INIT_STATE_RESET,
+                                    mmc_clock->shift), mmc_clock->reg);
+
        clk = clk_register(NULL, &mmc_clock->hw);
        if (IS_ERR(clk))
                goto err_free;
index 7737a1df1e4ba09e9d0fb0ccf420be7219d780b4..4881eb8a1576daf517b4b11df4dcdec88b335261 100644 (file)
@@ -126,11 +126,32 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 #define RK3066_PLLCON3_PWRDOWN         (1 << 1)
 #define RK3066_PLLCON3_BYPASS          (1 << 0)
 
+static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll,
+                                       struct rockchip_pll_rate_table *rate)
+{
+       u32 pllcon;
+
+       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
+       rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT)
+                               & RK3066_PLLCON0_NR_MASK) + 1;
+       rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT)
+                               & RK3066_PLLCON0_OD_MASK) + 1;
+
+       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
+       rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT)
+                               & RK3066_PLLCON1_NF_MASK) + 1;
+
+       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
+       rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT)
+                               & RK3066_PLLCON2_NB_MASK) + 1;
+}
+
 static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
                                                     unsigned long prate)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-       u64 nf, nr, no, rate64 = prate;
+       struct rockchip_pll_rate_table cur;
+       u64 rate64 = prate;
        u32 pllcon;
 
        pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3));
@@ -140,53 +161,31 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
                return prate;
        }
 
-       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-       nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK;
-
-       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-       nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK;
-       no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK;
+       rockchip_rk3066_pll_get_params(pll, &cur);
 
-       rate64 *= (nf + 1);
-       do_div(rate64, nr + 1);
-       do_div(rate64, no + 1);
+       rate64 *= cur.nf;
+       do_div(rate64, cur.nr);
+       do_div(rate64, cur.no);
 
        return (unsigned long)rate64;
 }
 
-static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
-                                       unsigned long prate)
+static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll,
+                               const struct rockchip_pll_rate_table *rate)
 {
-       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
-       const struct rockchip_pll_rate_table *rate;
-       unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
-       struct regmap *grf = rockchip_clk_get_grf();
-       struct clk_mux *pll_mux = &pll->pll_mux;
        const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+       struct clk_mux *pll_mux = &pll->pll_mux;
+       struct rockchip_pll_rate_table cur;
        int rate_change_remuxed = 0;
        int cur_parent;
        int ret;
 
-       if (IS_ERR(grf)) {
-               pr_debug("%s: grf regmap not available, aborting rate change\n",
-                        __func__);
-               return PTR_ERR(grf);
-       }
-
-       pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
-                __func__, clk_hw_get_name(hw), old_rate, drate, prate);
-
-       /* Get required rate settings from table */
-       rate = rockchip_get_pll_settings(pll, drate);
-       if (!rate) {
-               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-                       drate, clk_hw_get_name(hw));
-               return -EINVAL;
-       }
-
        pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n",
                 __func__, rate->rate, rate->nr, rate->no, rate->nf);
 
+       rockchip_rk3066_pll_get_params(pll, &cur);
+       cur.rate = 0;
+
        cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
        if (cur_parent == PLL_MODE_NORM) {
                pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
@@ -219,9 +218,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
        /* wait for the pll to lock */
        ret = rockchip_pll_wait_lock(pll);
        if (ret) {
-               pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
-                       __func__, old_rate);
-               rockchip_rk3066_pll_set_rate(hw, old_rate, prate);
+               pr_warn("%s: pll update unsucessful, trying to restore old params\n",
+                       __func__);
+               rockchip_rk3066_pll_set_params(pll, &cur);
        }
 
        if (rate_change_remuxed)
@@ -230,6 +229,34 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
        return ret;
 }
 
+static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+                                       unsigned long prate)
+{
+       struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+       const struct rockchip_pll_rate_table *rate;
+       unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
+       struct regmap *grf = rockchip_clk_get_grf();
+
+       if (IS_ERR(grf)) {
+               pr_debug("%s: grf regmap not available, aborting rate change\n",
+                        __func__);
+               return PTR_ERR(grf);
+       }
+
+       pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+                __func__, clk_hw_get_name(hw), old_rate, drate, prate);
+
+       /* Get required rate settings from table */
+       rate = rockchip_get_pll_settings(pll, drate);
+       if (!rate) {
+               pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+                       drate, clk_hw_get_name(hw));
+               return -EINVAL;
+       }
+
+       return rockchip_rk3066_pll_set_params(pll, rate);
+}
+
 static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
@@ -261,9 +288,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
-       unsigned int nf, nr, no, nb;
+       struct rockchip_pll_rate_table cur;
        unsigned long drate;
-       u32 pllcon;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
                return;
@@ -275,34 +301,21 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
        if (!rate)
                return;
 
-       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0));
-       nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
-       no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
-
-       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1));
-       nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
-
-       pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2));
-       nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
+       rockchip_rk3066_pll_get_params(pll, &cur);
 
        pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n",
-                __func__, clk_hw_get_name(hw), drate, rate->nr, nr,
-               rate->no, no, rate->nf, nf, rate->nb, nb);
-       if (rate->nr != nr || rate->no != no || rate->nf != nf
-                                            || rate->nb != nb) {
-               struct clk_hw *parent = clk_hw_get_parent(hw);
-               unsigned long prate;
-
-               if (!parent) {
-                       pr_warn("%s: parent of %s not available\n",
-                               __func__, clk_hw_get_name(hw));
+                __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr,
+                rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb);
+       if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf
+                                                    || rate->nb != cur.nb) {
+               struct regmap *grf = rockchip_clk_get_grf();
+
+               if (IS_ERR(grf))
                        return;
-               }
 
                pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
                         __func__, clk_hw_get_name(hw));
-               prate = clk_hw_get_rate(parent);
-               rockchip_rk3066_pll_set_rate(hw, drate, prate);
+               rockchip_rk3066_pll_set_params(pll, rate);
        }
 }
 
index 24938815655fa847512bf2e970589e112a7d35f7..be6c7fd8315df99de06c81ce66118761326a9290 100644 (file)
@@ -135,9 +135,11 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
        div->flags = div_flags;
        div->reg = base + muxdiv_offset;
        div->mshift = 16;
-       div->mmask = 0xffff0000;
+       div->mwidth = 16;
+       div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift;
        div->nshift = 0;
-       div->nmask = 0xffff;
+       div->nwidth = 16;
+       div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift;
        div->lock = lock;
        div_ops = &clk_fractional_divider_ops;
 
index 8524e667097e062cf426a1e4b18cd1eb0c90e708..55f8e2e24ab852f4f5260f429525d0f864038952 100644 (file)
 #define DIV_TOPC0              0x0600
 #define DIV_TOPC1              0x0604
 #define DIV_TOPC3              0x060C
+#define ENABLE_ACLK_TOPC0      0x0800
 #define ENABLE_ACLK_TOPC1      0x0804
+#define ENABLE_SCLK_TOPC1      0x0A04
 
 static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
-       FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0),
+       FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_topc_bus0_pll", 1, 2, 0),
        FFACTOR(0, "ffac_topc_bus0_pll_div4",
                "ffac_topc_bus0_pll_div2", 1, 2, 0),
-       FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0),
-       FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0),
-       FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0),
+       FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_topc_bus1_pll", 1, 2, 0),
+       FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_topc_cc_pll", 1, 2, 0),
+       FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_topc_mfc_pll", 1, 2, 0),
 };
 
 /* List of parent clocks for Muxes in CMU_TOPC */
-PNAME(mout_aud_pll_ctrl_p)     = { "fin_pll", "fout_aud_pll" };
-PNAME(mout_bus0_pll_ctrl_p)    = { "fin_pll", "fout_bus0_pll" };
-PNAME(mout_bus1_pll_ctrl_p)    = { "fin_pll", "fout_bus1_pll" };
-PNAME(mout_cc_pll_ctrl_p)      = { "fin_pll", "fout_cc_pll" };
-PNAME(mout_mfc_pll_ctrl_p)     = { "fin_pll", "fout_mfc_pll" };
+PNAME(mout_topc_aud_pll_ctrl_p)        = { "fin_pll", "fout_aud_pll" };
+PNAME(mout_topc_bus0_pll_ctrl_p)       = { "fin_pll", "fout_bus0_pll" };
+PNAME(mout_topc_bus1_pll_ctrl_p)       = { "fin_pll", "fout_bus1_pll" };
+PNAME(mout_topc_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" };
+PNAME(mout_topc_mfc_pll_ctrl_p)        = { "fin_pll", "fout_mfc_pll" };
 
-PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc",
-       "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc",
-       "mout_sclk_mfc_pll_cmuc" };
+PNAME(mout_topc_group2) = { "mout_topc_bus0_pll_half",
+       "mout_topc_bus1_pll_half", "mout_topc_cc_pll_half",
+       "mout_topc_mfc_pll_half" };
 
-PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl",
+PNAME(mout_topc_bus0_pll_half_p) = { "mout_topc_bus0_pll",
        "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"};
-PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl",
+PNAME(mout_topc_bus1_pll_half_p) = { "mout_topc_bus1_pll",
        "ffac_topc_bus1_pll_div2"};
-PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl",
+PNAME(mout_topc_cc_pll_half_p) = { "mout_topc_cc_pll",
        "ffac_topc_cc_pll_div2"};
-PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl",
+PNAME(mout_topc_mfc_pll_half_p) = { "mout_topc_mfc_pll",
        "ffac_topc_mfc_pll_div2"};
 
 
-PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl",
+PNAME(mout_topc_bus0_pll_out_p) = {"mout_topc_bus0_pll",
        "ffac_topc_bus0_pll_div2"};
 
 static unsigned long topc_clk_regs[] __initdata = {
@@ -88,23 +90,27 @@ static unsigned long topc_clk_regs[] __initdata = {
 };
 
 static struct samsung_mux_clock topc_mux_clks[] __initdata = {
-       MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1),
-       MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1),
-       MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1),
-       MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1),
-
-       MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p,
+       MUX(0, "mout_topc_bus0_pll", mout_topc_bus0_pll_ctrl_p,
+               MUX_SEL_TOPC0, 0, 1),
+       MUX(0, "mout_topc_bus1_pll", mout_topc_bus1_pll_ctrl_p,
+               MUX_SEL_TOPC0, 4, 1),
+       MUX(0, "mout_topc_cc_pll", mout_topc_cc_pll_ctrl_p,
+               MUX_SEL_TOPC0, 8, 1),
+       MUX(0, "mout_topc_mfc_pll", mout_topc_mfc_pll_ctrl_p,
+               MUX_SEL_TOPC0, 12, 1),
+       MUX(0, "mout_topc_bus0_pll_half", mout_topc_bus0_pll_half_p,
                MUX_SEL_TOPC0, 16, 2),
-       MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p,
+       MUX(0, "mout_topc_bus1_pll_half", mout_topc_bus1_pll_half_p,
                MUX_SEL_TOPC0, 20, 1),
-       MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p,
+       MUX(0, "mout_topc_cc_pll_half", mout_topc_cc_pll_half_p,
                MUX_SEL_TOPC0, 24, 1),
-       MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p,
+       MUX(0, "mout_topc_mfc_pll_half", mout_topc_mfc_pll_half_p,
                MUX_SEL_TOPC0, 28, 1),
 
-       MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p,
+       MUX(0, "mout_topc_aud_pll", mout_topc_aud_pll_ctrl_p,
+               MUX_SEL_TOPC1, 0, 1),
+       MUX(0, "mout_topc_bus0_pll_out", mout_topc_bus0_pll_out_p,
                MUX_SEL_TOPC1, 16, 1),
-       MUX(0, "mout_aud_pll_ctrl", mout_aud_pll_ctrl_p, MUX_SEL_TOPC1, 0, 1),
 
        MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2),
 
@@ -121,16 +127,16 @@ static struct samsung_div_clock topc_div_clks[] __initdata = {
        DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66",
                DIV_TOPC1, 24, 4),
 
-       DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out",
-               DIV_TOPC3, 0, 3),
-       DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl",
-               DIV_TOPC3, 8, 3),
-       DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl",
-               DIV_TOPC3, 12, 3),
-       DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl",
-               DIV_TOPC3, 16, 3),
-       DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_aud_pll_ctrl",
-               DIV_TOPC3, 28, 3),
+       DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_topc_bus0_pll_out",
+               DIV_TOPC3, 0, 4),
+       DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_topc_bus1_pll",
+               DIV_TOPC3, 8, 4),
+       DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_topc_cc_pll",
+               DIV_TOPC3, 12, 4),
+       DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_topc_mfc_pll",
+               DIV_TOPC3, 16, 4),
+       DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_topc_aud_pll",
+               DIV_TOPC3, 28, 4),
 };
 
 static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
@@ -139,8 +145,33 @@ static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
 };
 
 static struct samsung_gate_clock topc_gate_clks[] __initdata = {
+       GATE(ACLK_CCORE_133, "aclk_ccore_133", "dout_aclk_ccore_133",
+               ENABLE_ACLK_TOPC0, 4, 0, 0),
+
        GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532",
                ENABLE_ACLK_TOPC1, 20, 0, 0),
+
+       GATE(ACLK_PERIS_66, "aclk_peris_66", "dout_aclk_peris_66",
+               ENABLE_ACLK_TOPC1, 24, 0, 0),
+
+       GATE(SCLK_AUD_PLL, "sclk_aud_pll", "dout_sclk_aud_pll",
+               ENABLE_SCLK_TOPC1, 20, 0, 0),
+       GATE(SCLK_MFC_PLL_B, "sclk_mfc_pll_b", "dout_sclk_mfc_pll",
+               ENABLE_SCLK_TOPC1, 17, 0, 0),
+       GATE(SCLK_MFC_PLL_A, "sclk_mfc_pll_a", "dout_sclk_mfc_pll",
+               ENABLE_SCLK_TOPC1, 16, 0, 0),
+       GATE(SCLK_BUS1_PLL_B, "sclk_bus1_pll_b", "dout_sclk_bus1_pll",
+               ENABLE_SCLK_TOPC1, 13, 0, 0),
+       GATE(SCLK_BUS1_PLL_A, "sclk_bus1_pll_a", "dout_sclk_bus1_pll",
+               ENABLE_SCLK_TOPC1, 12, 0, 0),
+       GATE(SCLK_BUS0_PLL_B, "sclk_bus0_pll_b", "dout_sclk_bus0_pll",
+               ENABLE_SCLK_TOPC1, 5, 0, 0),
+       GATE(SCLK_BUS0_PLL_A, "sclk_bus0_pll_a", "dout_sclk_bus0_pll",
+               ENABLE_SCLK_TOPC1, 4, 0, 0),
+       GATE(SCLK_CC_PLL_B, "sclk_cc_pll_b", "dout_sclk_cc_pll",
+               ENABLE_SCLK_TOPC1, 1, 0, 0),
+       GATE(SCLK_CC_PLL_A, "sclk_cc_pll_a", "dout_sclk_cc_pll",
+               ENABLE_SCLK_TOPC1, 0, 0, 0),
 };
 
 static struct samsung_pll_clock topc_pll_clks[] __initdata = {
@@ -193,36 +224,37 @@ CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc",
 #define DIV_TOP0_PERIC1                        0x0634
 #define DIV_TOP0_PERIC2                        0x0638
 #define DIV_TOP0_PERIC3                        0x063C
+#define ENABLE_ACLK_TOP03              0x080C
 #define ENABLE_SCLK_TOP0_PERIC0                0x0A30
 #define ENABLE_SCLK_TOP0_PERIC1                0x0A34
 #define ENABLE_SCLK_TOP0_PERIC2                0x0A38
 #define ENABLE_SCLK_TOP0_PERIC3                0x0A3C
 
 /* List of parent clocks for Muxes in CMU_TOP0 */
-PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" };
-PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" };
-PNAME(mout_cc_pll_p)   = { "fin_pll", "dout_sclk_cc_pll" };
-PNAME(mout_mfc_pll_p)  = { "fin_pll", "dout_sclk_mfc_pll" };
-PNAME(mout_aud_pll_p)  = { "fin_pll", "dout_sclk_aud_pll" };
+PNAME(mout_top0_bus0_pll_user_p)       = { "fin_pll", "sclk_bus0_pll_a" };
+PNAME(mout_top0_bus1_pll_user_p)       = { "fin_pll", "sclk_bus1_pll_a" };
+PNAME(mout_top0_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_a" };
+PNAME(mout_top0_mfc_pll_user_p)        = { "fin_pll", "sclk_mfc_pll_a" };
+PNAME(mout_top0_aud_pll_user_p)        = { "fin_pll", "sclk_aud_pll" };
 
-PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll",
+PNAME(mout_top0_bus0_pll_half_p) = {"mout_top0_bus0_pll_user",
        "ffac_top0_bus0_pll_div2"};
-PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll",
+PNAME(mout_top0_bus1_pll_half_p) = {"mout_top0_bus1_pll_user",
        "ffac_top0_bus1_pll_div2"};
-PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll",
+PNAME(mout_top0_cc_pll_half_p) = {"mout_top0_cc_pll_user",
        "ffac_top0_cc_pll_div2"};
-PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll",
+PNAME(mout_top0_mfc_pll_half_p) = {"mout_top0_mfc_pll_user",
        "ffac_top0_mfc_pll_div2"};
 
-PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll",
-       "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll",
-       "mout_top0_half_mfc_pll"};
+PNAME(mout_top0_group1) = {"mout_top0_bus0_pll_half",
+       "mout_top0_bus1_pll_half", "mout_top0_cc_pll_half",
+       "mout_top0_mfc_pll_half"};
 PNAME(mout_top0_group3) = {"ioclk_audiocdclk0",
        "ioclk_audiocdclk1", "ioclk_spdif_extclk",
-       "mout_top0_aud_pll", "mout_top0_half_bus0_pll",
-       "mout_top0_half_bus1_pll"};
-PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll",
-       "mout_top0_half_bus0_pll", "mout_top0_half_bus1_pll"};
+       "mout_top0_aud_pll_user", "mout_top0_bus0_pll_half",
+       "mout_top0_bus1_pll_half"};
+PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll_user",
+       "mout_top0_bus0_pll_half", "mout_top0_bus1_pll_half"};
 
 static unsigned long top0_clk_regs[] __initdata = {
        MUX_SEL_TOP00,
@@ -244,19 +276,24 @@ static unsigned long top0_clk_regs[] __initdata = {
 };
 
 static struct samsung_mux_clock top0_mux_clks[] __initdata = {
-       MUX(0, "mout_top0_aud_pll", mout_aud_pll_p, MUX_SEL_TOP00, 0, 1),
-       MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1),
-       MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1),
-       MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1),
-       MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1),
-
-       MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p,
+       MUX(0, "mout_top0_aud_pll_user", mout_top0_aud_pll_user_p,
+               MUX_SEL_TOP00, 0, 1),
+       MUX(0, "mout_top0_mfc_pll_user", mout_top0_mfc_pll_user_p,
+               MUX_SEL_TOP00, 4, 1),
+       MUX(0, "mout_top0_cc_pll_user", mout_top0_cc_pll_user_p,
+               MUX_SEL_TOP00, 8, 1),
+       MUX(0, "mout_top0_bus1_pll_user", mout_top0_bus1_pll_user_p,
+               MUX_SEL_TOP00, 12, 1),
+       MUX(0, "mout_top0_bus0_pll_user", mout_top0_bus0_pll_user_p,
+               MUX_SEL_TOP00, 16, 1),
+
+       MUX(0, "mout_top0_mfc_pll_half", mout_top0_mfc_pll_half_p,
                MUX_SEL_TOP01, 4, 1),
-       MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p,
+       MUX(0, "mout_top0_cc_pll_half", mout_top0_cc_pll_half_p,
                MUX_SEL_TOP01, 8, 1),
-       MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p,
+       MUX(0, "mout_top0_bus1_pll_half", mout_top0_bus1_pll_half_p,
                MUX_SEL_TOP01, 12, 1),
-       MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p,
+       MUX(0, "mout_top0_bus0_pll_half", mout_top0_bus0_pll_half_p,
                MUX_SEL_TOP01, 16, 1),
 
        MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2),
@@ -302,6 +339,11 @@ static struct samsung_div_clock top0_div_clks[] __initdata = {
 };
 
 static struct samsung_gate_clock top0_gate_clks[] __initdata = {
+       GATE(CLK_ACLK_PERIC0_66, "aclk_peric0_66", "dout_aclk_peric0_66",
+               ENABLE_ACLK_TOP03, 20, CLK_SET_RATE_PARENT, 0),
+       GATE(CLK_ACLK_PERIC1_66, "aclk_peric1_66", "dout_aclk_peric1_66",
+               ENABLE_ACLK_TOP03, 12, CLK_SET_RATE_PARENT, 0),
+
        GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif",
                ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1",
@@ -331,10 +373,12 @@ static struct samsung_gate_clock top0_gate_clks[] __initdata = {
 };
 
 static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
-       FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0),
-       FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0),
-       FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0),
-       FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0),
+       FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll_user",
+               1, 2, 0),
+       FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll_user",
+               1, 2, 0),
+       FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll_user", 1, 2, 0),
+       FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll_user", 1, 2, 0),
 };
 
 static struct samsung_cmu_info top0_cmu_info __initdata = {
@@ -365,31 +409,34 @@ CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0",
 #define MUX_SEL_TOP13                  0x020C
 #define MUX_SEL_TOP1_FSYS0             0x0224
 #define MUX_SEL_TOP1_FSYS1             0x0228
+#define MUX_SEL_TOP1_FSYS11            0x022C
 #define DIV_TOP13                      0x060C
 #define DIV_TOP1_FSYS0                 0x0624
 #define DIV_TOP1_FSYS1                 0x0628
+#define DIV_TOP1_FSYS11                        0x062C
 #define ENABLE_ACLK_TOP13              0x080C
 #define ENABLE_SCLK_TOP1_FSYS0         0x0A24
 #define ENABLE_SCLK_TOP1_FSYS1         0x0A28
+#define ENABLE_SCLK_TOP1_FSYS11                0x0A2C
 
 /* List of parent clocks for Muxes in CMU_TOP1 */
-PNAME(mout_top1_bus0_pll_p)    = { "fin_pll", "dout_sclk_bus0_pll" };
-PNAME(mout_top1_bus1_pll_p)    = { "fin_pll", "dout_sclk_bus1_pll_b" };
-PNAME(mout_top1_cc_pll_p)      = { "fin_pll", "dout_sclk_cc_pll_b" };
-PNAME(mout_top1_mfc_pll_p)     = { "fin_pll", "dout_sclk_mfc_pll_b" };
+PNAME(mout_top1_bus0_pll_user_p)       = { "fin_pll", "sclk_bus0_pll_b" };
+PNAME(mout_top1_bus1_pll_user_p)       = { "fin_pll", "sclk_bus1_pll_b" };
+PNAME(mout_top1_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_b" };
+PNAME(mout_top1_mfc_pll_user_p)        = { "fin_pll", "sclk_mfc_pll_b" };
 
-PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll",
+PNAME(mout_top1_bus0_pll_half_p) = {"mout_top1_bus0_pll_user",
        "ffac_top1_bus0_pll_div2"};
-PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll",
+PNAME(mout_top1_bus1_pll_half_p) = {"mout_top1_bus1_pll_user",
        "ffac_top1_bus1_pll_div2"};
-PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll",
+PNAME(mout_top1_cc_pll_half_p) = {"mout_top1_cc_pll_user",
        "ffac_top1_cc_pll_div2"};
-PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll",
+PNAME(mout_top1_mfc_pll_half_p) = {"mout_top1_mfc_pll_user",
        "ffac_top1_mfc_pll_div2"};
 
-PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll",
-       "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll",
-       "mout_top1_half_mfc_pll"};
+PNAME(mout_top1_group1) = {"mout_top1_bus0_pll_half",
+       "mout_top1_bus1_pll_half", "mout_top1_cc_pll_half",
+       "mout_top1_mfc_pll_half"};
 
 static unsigned long top1_clk_regs[] __initdata = {
        MUX_SEL_TOP10,
@@ -397,40 +444,54 @@ static unsigned long top1_clk_regs[] __initdata = {
        MUX_SEL_TOP13,
        MUX_SEL_TOP1_FSYS0,
        MUX_SEL_TOP1_FSYS1,
+       MUX_SEL_TOP1_FSYS11,
        DIV_TOP13,
        DIV_TOP1_FSYS0,
        DIV_TOP1_FSYS1,
+       DIV_TOP1_FSYS11,
        ENABLE_ACLK_TOP13,
        ENABLE_SCLK_TOP1_FSYS0,
        ENABLE_SCLK_TOP1_FSYS1,
+       ENABLE_SCLK_TOP1_FSYS11,
 };
 
 static struct samsung_mux_clock top1_mux_clks[] __initdata = {
-       MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1),
-       MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1),
-       MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p,
+       MUX(0, "mout_top1_mfc_pll_user", mout_top1_mfc_pll_user_p,
+               MUX_SEL_TOP10, 4, 1),
+       MUX(0, "mout_top1_cc_pll_user", mout_top1_cc_pll_user_p,
+               MUX_SEL_TOP10, 8, 1),
+       MUX(0, "mout_top1_bus1_pll_user", mout_top1_bus1_pll_user_p,
                MUX_SEL_TOP10, 12, 1),
-       MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p,
+       MUX(0, "mout_top1_bus0_pll_user", mout_top1_bus0_pll_user_p,
                MUX_SEL_TOP10, 16, 1),
 
-       MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p,
+       MUX(0, "mout_top1_mfc_pll_half", mout_top1_mfc_pll_half_p,
                MUX_SEL_TOP11, 4, 1),
-       MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p,
+       MUX(0, "mout_top1_cc_pll_half", mout_top1_cc_pll_half_p,
                MUX_SEL_TOP11, 8, 1),
-       MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p,
+       MUX(0, "mout_top1_bus1_pll_half", mout_top1_bus1_pll_half_p,
                MUX_SEL_TOP11, 12, 1),
-       MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p,
+       MUX(0, "mout_top1_bus0_pll_half", mout_top1_bus0_pll_half_p,
                MUX_SEL_TOP11, 16, 1),
 
        MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2),
        MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2),
 
-       MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2),
+       MUX(0, "mout_sclk_phy_fsys0_26m", mout_top1_group1,
+               MUX_SEL_TOP1_FSYS0, 0, 2),
+       MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 16, 2),
        MUX(0, "mout_sclk_usbdrd300", mout_top1_group1,
                MUX_SEL_TOP1_FSYS0, 28, 2),
 
-       MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2),
-       MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2),
+       MUX(0, "mout_sclk_phy_fsys1", mout_top1_group1,
+               MUX_SEL_TOP1_FSYS1, 0, 2),
+       MUX(0, "mout_sclk_ufsunipro20", mout_top1_group1,
+               MUX_SEL_TOP1_FSYS1, 16, 2),
+
+       MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 0, 2),
+       MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 12, 2),
+       MUX(0, "mout_sclk_phy_fsys1_26m", mout_top1_group1,
+               MUX_SEL_TOP1_FSYS11, 24, 2),
 };
 
 static struct samsung_div_clock top1_div_clks[] __initdata = {
@@ -439,34 +500,61 @@ static struct samsung_div_clock top1_div_clks[] __initdata = {
        DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200",
                DIV_TOP13, 28, 4),
 
+       DIV(DOUT_SCLK_PHY_FSYS1, "dout_sclk_phy_fsys1",
+               "mout_sclk_phy_fsys1", DIV_TOP1_FSYS1, 0, 6),
+
+       DIV(DOUT_SCLK_UFSUNIPRO20, "dout_sclk_ufsunipro20",
+               "mout_sclk_ufsunipro20",
+               DIV_TOP1_FSYS1, 16, 6),
+
        DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2",
-               DIV_TOP1_FSYS0, 24, 4),
+               DIV_TOP1_FSYS0, 16, 10),
        DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300",
                DIV_TOP1_FSYS0, 28, 4),
 
        DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1",
-               DIV_TOP1_FSYS1, 24, 4),
+               DIV_TOP1_FSYS11, 0, 10),
        DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0",
-               DIV_TOP1_FSYS1, 28, 4),
+               DIV_TOP1_FSYS11, 12, 10),
+
+       DIV(DOUT_SCLK_PHY_FSYS1_26M, "dout_sclk_phy_fsys1_26m",
+               "mout_sclk_phy_fsys1_26m", DIV_TOP1_FSYS11, 24, 6),
 };
 
 static struct samsung_gate_clock top1_gate_clks[] __initdata = {
        GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
-               ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0),
+               ENABLE_SCLK_TOP1_FSYS0, 16, CLK_SET_RATE_PARENT, 0),
        GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300",
                ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0),
 
+       GATE(CLK_SCLK_PHY_FSYS1, "sclk_phy_fsys1", "dout_sclk_phy_fsys1",
+               ENABLE_SCLK_TOP1_FSYS1, 0, CLK_SET_RATE_PARENT, 0),
+
+       GATE(CLK_SCLK_UFSUNIPRO20, "sclk_ufsunipro20", "dout_sclk_ufsunipro20",
+               ENABLE_SCLK_TOP1_FSYS1, 16, CLK_SET_RATE_PARENT, 0),
+
        GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1",
-               ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0),
+               ENABLE_SCLK_TOP1_FSYS11, 0, CLK_SET_RATE_PARENT, 0),
        GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0",
-               ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0),
+               ENABLE_SCLK_TOP1_FSYS11, 12, CLK_SET_RATE_PARENT, 0),
+
+       GATE(CLK_ACLK_FSYS0_200, "aclk_fsys0_200", "dout_aclk_fsys0_200",
+               ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT, 0),
+       GATE(CLK_ACLK_FSYS1_200, "aclk_fsys1_200", "dout_aclk_fsys1_200",
+               ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT, 0),
+
+       GATE(CLK_SCLK_PHY_FSYS1_26M, "sclk_phy_fsys1_26m",
+               "dout_sclk_phy_fsys1_26m", ENABLE_SCLK_TOP1_FSYS11,
+               24, CLK_SET_RATE_PARENT, 0),
 };
 
 static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = {
-       FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0),
-       FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0),
-       FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0),
-       FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0),
+       FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll_user",
+               1, 2, 0),
+       FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll_user",
+               1, 2, 0),
+       FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll_user", 1, 2, 0),
+       FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll_user", 1, 2, 0),
 };
 
 static struct samsung_cmu_info top1_cmu_info __initdata = {
@@ -501,7 +589,7 @@ CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1",
 /*
  * List of parent clocks for Muxes in CMU_CCORE
  */
-PNAME(mout_aclk_ccore_133_p)   = { "fin_pll", "dout_aclk_ccore_133" };
+PNAME(mout_aclk_ccore_133_user_p)      = { "fin_pll", "aclk_ccore_133" };
 
 static unsigned long ccore_clk_regs[] __initdata = {
        MUX_SEL_CCORE,
@@ -509,7 +597,7 @@ static unsigned long ccore_clk_regs[] __initdata = {
 };
 
 static struct samsung_mux_clock ccore_mux_clks[] __initdata = {
-       MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p,
+       MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_user_p,
                MUX_SEL_CCORE, 1, 1),
 };
 
@@ -542,8 +630,8 @@ CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore",
 #define ENABLE_SCLK_PERIC0             0x0A00
 
 /* List of parent clocks for Muxes in CMU_PERIC0 */
-PNAME(mout_aclk_peric0_66_p)   = { "fin_pll", "dout_aclk_peric0_66" };
-PNAME(mout_sclk_uart0_p)       = { "fin_pll", "sclk_uart0" };
+PNAME(mout_aclk_peric0_66_user_p)      = { "fin_pll", "aclk_peric0_66" };
+PNAME(mout_sclk_uart0_user_p)  = { "fin_pll", "sclk_uart0" };
 
 static unsigned long peric0_clk_regs[] __initdata = {
        MUX_SEL_PERIC0,
@@ -552,9 +640,9 @@ static unsigned long peric0_clk_regs[] __initdata = {
 };
 
 static struct samsung_mux_clock peric0_mux_clks[] __initdata = {
-       MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p,
+       MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_user_p,
                MUX_SEL_PERIC0, 0, 1),
-       MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p,
+       MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_user_p,
                MUX_SEL_PERIC0, 16, 1),
 };
 
@@ -611,15 +699,15 @@ CLK_OF_DECLARE(exynos7_clk_peric0, "samsung,exynos7-clock-peric0",
        exynos7_clk_peric0_init);
 
 /* List of parent clocks for Muxes in CMU_PERIC1 */
-PNAME(mout_aclk_peric1_66_p)   = { "fin_pll", "dout_aclk_peric1_66" };
-PNAME(mout_sclk_uart1_p)       = { "fin_pll", "sclk_uart1" };
-PNAME(mout_sclk_uart2_p)       = { "fin_pll", "sclk_uart2" };
-PNAME(mout_sclk_uart3_p)       = { "fin_pll", "sclk_uart3" };
-PNAME(mout_sclk_spi0_p)                = { "fin_pll", "sclk_spi0" };
-PNAME(mout_sclk_spi1_p)                = { "fin_pll", "sclk_spi1" };
-PNAME(mout_sclk_spi2_p)                = { "fin_pll", "sclk_spi2" };
-PNAME(mout_sclk_spi3_p)                = { "fin_pll", "sclk_spi3" };
-PNAME(mout_sclk_spi4_p)                = { "fin_pll", "sclk_spi4" };
+PNAME(mout_aclk_peric1_66_user_p)      = { "fin_pll", "aclk_peric1_66" };
+PNAME(mout_sclk_uart1_user_p)  = { "fin_pll", "sclk_uart1" };
+PNAME(mout_sclk_uart2_user_p)  = { "fin_pll", "sclk_uart2" };
+PNAME(mout_sclk_uart3_user_p)  = { "fin_pll", "sclk_uart3" };
+PNAME(mout_sclk_spi0_user_p)           = { "fin_pll", "sclk_spi0" };
+PNAME(mout_sclk_spi1_user_p)           = { "fin_pll", "sclk_spi1" };
+PNAME(mout_sclk_spi2_user_p)           = { "fin_pll", "sclk_spi2" };
+PNAME(mout_sclk_spi3_user_p)           = { "fin_pll", "sclk_spi3" };
+PNAME(mout_sclk_spi4_user_p)           = { "fin_pll", "sclk_spi4" };
 
 static unsigned long peric1_clk_regs[] __initdata = {
        MUX_SEL_PERIC10,
@@ -630,24 +718,24 @@ static unsigned long peric1_clk_regs[] __initdata = {
 };
 
 static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
-       MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p,
+       MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_user_p,
                MUX_SEL_PERIC10, 0, 1),
 
-       MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_p,
+       MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_user_p,
                MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0),
-       MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_p,
+       MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_user_p,
                MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0),
-       MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_p,
+       MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_user_p,
                MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0),
-       MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_p,
+       MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_user_p,
                MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0),
-       MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_p,
+       MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_user_p,
                MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0),
-       MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p,
+       MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_user_p,
                MUX_SEL_PERIC11, 20, 1),
-       MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p,
+       MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_user_p,
                MUX_SEL_PERIC11, 24, 1),
-       MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p,
+       MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_user_p,
                MUX_SEL_PERIC11, 28, 1),
 };
 
@@ -735,7 +823,7 @@ CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1",
 #define ENABLE_SCLK_PERIS_SECURE_CHIPID        0x0A10
 
 /* List of parent clocks for Muxes in CMU_PERIS */
-PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" };
+PNAME(mout_aclk_peris_66_user_p) = { "fin_pll", "aclk_peris_66" };
 
 static unsigned long peris_clk_regs[] __initdata = {
        MUX_SEL_PERIS,
@@ -747,7 +835,7 @@ static unsigned long peris_clk_regs[] __initdata = {
 
 static struct samsung_mux_clock peris_mux_clks[] __initdata = {
        MUX(0, "mout_aclk_peris_66_user",
-               mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1),
+               mout_aclk_peris_66_user_p, MUX_SEL_PERIS, 0, 1),
 };
 
 static struct samsung_gate_clock peris_gate_clks[] __initdata = {
@@ -795,17 +883,17 @@ CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris",
 /*
  * List of parent clocks for Muxes in CMU_FSYS0
  */
-PNAME(mout_aclk_fsys0_200_p)   = { "fin_pll", "dout_aclk_fsys0_200" };
-PNAME(mout_sclk_mmc2_p)                = { "fin_pll", "sclk_mmc2" };
+PNAME(mout_aclk_fsys0_200_user_p)      = { "fin_pll", "aclk_fsys0_200" };
+PNAME(mout_sclk_mmc2_user_p)           = { "fin_pll", "sclk_mmc2" };
 
-PNAME(mout_sclk_usbdrd300_p)   = { "fin_pll", "sclk_usbdrd300" };
-PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_p)   = { "fin_pll",
+PNAME(mout_sclk_usbdrd300_user_p)      = { "fin_pll", "sclk_usbdrd300" };
+PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_user_p)      = { "fin_pll",
                                "phyclk_usbdrd300_udrd30_phyclock" };
-PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_p)        = { "fin_pll",
+PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p)   = { "fin_pll",
                                "phyclk_usbdrd300_udrd30_pipe_pclk" };
 
 /* fixed rate clocks used in the FSYS0 block */
-struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
+static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
        FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL,
                CLK_IS_ROOT, 60000000),
        FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL,
@@ -824,29 +912,30 @@ static unsigned long fsys0_clk_regs[] __initdata = {
 };
 
 static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
-       MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p,
+       MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_user_p,
                MUX_SEL_FSYS00, 24, 1),
 
-       MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1),
-       MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_p,
+       MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_user_p,
+               MUX_SEL_FSYS01, 24, 1),
+       MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_user_p,
                MUX_SEL_FSYS01, 28, 1),
 
        MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user",
-               mout_phyclk_usbdrd300_udrd30_pipe_pclk_p,
+               mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p,
                MUX_SEL_FSYS02, 24, 1),
        MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user",
-               mout_phyclk_usbdrd300_udrd30_phyclk_p,
+               mout_phyclk_usbdrd300_udrd30_phyclk_user_p,
                MUX_SEL_FSYS02, 28, 1),
 };
 
 static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
-       GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
-               "mout_aclk_fsys0_200_user",
-               ENABLE_ACLK_FSYS00, 19, 0, 0),
        GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user",
                        ENABLE_ACLK_FSYS00, 3, 0, 0),
        GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user",
                        ENABLE_ACLK_FSYS00, 4, 0, 0),
+       GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x",
+               "mout_aclk_fsys0_200_user",
+               ENABLE_ACLK_FSYS00, 19, 0, 0),
 
        GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user",
                ENABLE_ACLK_FSYS01, 29, 0, 0),
@@ -874,11 +963,13 @@ static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
 };
 
 static struct samsung_cmu_info fsys0_cmu_info __initdata = {
+       .fixed_clks             = fixed_rate_clks_fsys0,
+       .nr_fixed_clks          = ARRAY_SIZE(fixed_rate_clks_fsys0),
        .mux_clks               = fsys0_mux_clks,
        .nr_mux_clks            = ARRAY_SIZE(fsys0_mux_clks),
        .gate_clks              = fsys0_gate_clks,
        .nr_gate_clks           = ARRAY_SIZE(fsys0_gate_clks),
-       .nr_clk_ids             = TOP1_NR_CLK,
+       .nr_clk_ids             = FSYS0_NR_CLK,
        .clk_regs               = fsys0_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(fsys0_clk_regs),
 };
@@ -894,42 +985,122 @@ CLK_OF_DECLARE(exynos7_clk_fsys0, "samsung,exynos7-clock-fsys0",
 /* Register Offset definitions for CMU_FSYS1 (0x156E0000) */
 #define MUX_SEL_FSYS10                 0x0200
 #define MUX_SEL_FSYS11                 0x0204
+#define MUX_SEL_FSYS12                 0x0208
+#define DIV_FSYS1                      0x0600
 #define ENABLE_ACLK_FSYS1              0x0800
+#define ENABLE_PCLK_FSYS1               0x0900
+#define ENABLE_SCLK_FSYS11              0x0A04
+#define ENABLE_SCLK_FSYS12              0x0A08
+#define ENABLE_SCLK_FSYS13              0x0A0C
 
 /*
  * List of parent clocks for Muxes in CMU_FSYS1
  */
-PNAME(mout_aclk_fsys1_200_p)   = { "fin_pll",  "dout_aclk_fsys1_200" };
-PNAME(mout_sclk_mmc0_p)                = { "fin_pll", "sclk_mmc0" };
-PNAME(mout_sclk_mmc1_p)                = { "fin_pll", "sclk_mmc1" };
+PNAME(mout_aclk_fsys1_200_user_p)      = { "fin_pll", "aclk_fsys1_200" };
+PNAME(mout_fsys1_group_p)      = { "fin_pll", "fin_pll_26m",
+                               "sclk_phy_fsys1_26m" };
+PNAME(mout_sclk_mmc0_user_p)           = { "fin_pll", "sclk_mmc0" };
+PNAME(mout_sclk_mmc1_user_p)           = { "fin_pll", "sclk_mmc1" };
+PNAME(mout_sclk_ufsunipro20_user_p)  = { "fin_pll", "sclk_ufsunipro20" };
+PNAME(mout_phyclk_ufs20_tx0_user_p) = { "fin_pll", "phyclk_ufs20_tx0_symbol" };
+PNAME(mout_phyclk_ufs20_rx0_user_p) = { "fin_pll", "phyclk_ufs20_rx0_symbol" };
+PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" };
+
+/* fixed rate clocks used in the FSYS1 block */
+static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = {
+       FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL,
+                       CLK_IS_ROOT, 300000000),
+       FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL,
+                       CLK_IS_ROOT, 300000000),
+       FRATE(PHYCLK_UFS20_RX1_SYMBOL, "phyclk_ufs20_rx1_symbol", NULL,
+                       CLK_IS_ROOT, 300000000),
+};
 
 static unsigned long fsys1_clk_regs[] __initdata = {
        MUX_SEL_FSYS10,
        MUX_SEL_FSYS11,
+       MUX_SEL_FSYS12,
+       DIV_FSYS1,
        ENABLE_ACLK_FSYS1,
+       ENABLE_PCLK_FSYS1,
+       ENABLE_SCLK_FSYS11,
+       ENABLE_SCLK_FSYS12,
+       ENABLE_SCLK_FSYS13,
 };
 
 static struct samsung_mux_clock fsys1_mux_clks[] __initdata = {
-       MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p,
+       MUX(MOUT_FSYS1_PHYCLK_SEL1, "mout_fsys1_phyclk_sel1",
+               mout_fsys1_group_p, MUX_SEL_FSYS10, 16, 2),
+       MUX(0, "mout_fsys1_phyclk_sel0", mout_fsys1_group_p,
+                MUX_SEL_FSYS10, 20, 2),
+       MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_user_p,
                MUX_SEL_FSYS10, 28, 1),
 
-       MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1),
-       MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1),
+       MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_user_p,
+               MUX_SEL_FSYS11, 24, 1),
+       MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_user_p,
+               MUX_SEL_FSYS11, 28, 1),
+       MUX(0, "mout_sclk_ufsunipro20_user", mout_sclk_ufsunipro20_user_p,
+               MUX_SEL_FSYS11, 20, 1),
+
+       MUX(0, "mout_phyclk_ufs20_rx1_symbol_user",
+               mout_phyclk_ufs20_rx1_user_p, MUX_SEL_FSYS12, 16, 1),
+       MUX(0, "mout_phyclk_ufs20_rx0_symbol_user",
+               mout_phyclk_ufs20_rx0_user_p, MUX_SEL_FSYS12, 24, 1),
+       MUX(0, "mout_phyclk_ufs20_tx0_symbol_user",
+               mout_phyclk_ufs20_tx0_user_p, MUX_SEL_FSYS12, 28, 1),
+};
+
+static struct samsung_div_clock fsys1_div_clks[] __initdata = {
+       DIV(DOUT_PCLK_FSYS1, "dout_pclk_fsys1", "mout_aclk_fsys1_200_user",
+               DIV_FSYS1, 0, 2),
 };
 
 static struct samsung_gate_clock fsys1_gate_clks[] __initdata = {
+       GATE(SCLK_UFSUNIPRO20_USER, "sclk_ufsunipro20_user",
+               "mout_sclk_ufsunipro20_user",
+               ENABLE_SCLK_FSYS11, 20, 0, 0),
+
        GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user",
                ENABLE_ACLK_FSYS1, 29, 0, 0),
        GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user",
                ENABLE_ACLK_FSYS1, 30, 0, 0),
+
+       GATE(ACLK_UFS20_LINK, "aclk_ufs20_link", "dout_pclk_fsys1",
+               ENABLE_ACLK_FSYS1, 31, 0, 0),
+       GATE(PCLK_GPIO_FSYS1, "pclk_gpio_fsys1", "mout_aclk_fsys1_200_user",
+               ENABLE_PCLK_FSYS1, 30, 0, 0),
+
+       GATE(PHYCLK_UFS20_RX1_SYMBOL_USER, "phyclk_ufs20_rx1_symbol_user",
+               "mout_phyclk_ufs20_rx1_symbol_user",
+               ENABLE_SCLK_FSYS12, 16, 0, 0),
+       GATE(PHYCLK_UFS20_RX0_SYMBOL_USER, "phyclk_ufs20_rx0_symbol_user",
+               "mout_phyclk_ufs20_rx0_symbol_user",
+               ENABLE_SCLK_FSYS12, 24, 0, 0),
+       GATE(PHYCLK_UFS20_TX0_SYMBOL_USER, "phyclk_ufs20_tx0_symbol_user",
+               "mout_phyclk_ufs20_tx0_symbol_user",
+               ENABLE_SCLK_FSYS12, 28, 0, 0),
+
+       GATE(OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY,
+               "oscclk_phy_clkout_embedded_combo_phy",
+               "fin_pll",
+               ENABLE_SCLK_FSYS12, 4, CLK_IGNORE_UNUSED, 0),
+
+       GATE(SCLK_COMBO_PHY_EMBEDDED_26M, "sclk_combo_phy_embedded_26m",
+               "mout_fsys1_phyclk_sel1",
+               ENABLE_SCLK_FSYS13, 24, CLK_IGNORE_UNUSED, 0),
 };
 
 static struct samsung_cmu_info fsys1_cmu_info __initdata = {
+       .fixed_clks             = fixed_rate_clks_fsys1,
+       .nr_fixed_clks          = ARRAY_SIZE(fixed_rate_clks_fsys1),
        .mux_clks               = fsys1_mux_clks,
        .nr_mux_clks            = ARRAY_SIZE(fsys1_mux_clks),
+       .div_clks               = fsys1_div_clks,
+       .nr_div_clks            = ARRAY_SIZE(fsys1_div_clks),
        .gate_clks              = fsys1_gate_clks,
        .nr_gate_clks           = ARRAY_SIZE(fsys1_gate_clks),
-       .nr_clk_ids             = TOP1_NR_CLK,
+       .nr_clk_ids             = FSYS1_NR_CLK,
        .clk_regs               = fsys1_clk_regs,
        .nr_clk_regs            = ARRAY_SIZE(fsys1_clk_regs),
 };
index a0a56e99882ac9ab028e290c3eb6be463e89e9dc..3b09716ebda28227eebd52da5616c40245e490d5 100644 (file)
@@ -214,7 +214,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
                        break;
 
                if (clkidx >= MSTP_MAX_CLOCKS) {
-                       pr_err("%s: invalid clock %s %s index %u)\n",
+                       pr_err("%s: invalid clock %s %s index %u\n",
                               __func__, np->name, name, clkidx);
                        continue;
                }
index 87c1d2f2fb57a46c7c4a790d7363456195b63154..b1741551fff2a6c9d555f3639891d78dffc48c02 100644 (file)
@@ -20,10 +20,10 @@ struct r8a7778_cpg {
 };
 
 /* PLL multipliers per bits 11, 12, and 18 of MODEMR */
-struct {
+static const struct {
        unsigned long plla_mult;
        unsigned long pllb_mult;
-} r8a7778_rates[] __initdata = {
+} r8a7778_rates[] __initconst = {
        [0] = { 21, 21 },
        [1] = { 24, 24 },
        [2] = { 28, 28 },
@@ -34,10 +34,10 @@ struct {
 };
 
 /* Clock dividers per bits 1 and 2 of MODEMR */
-struct {
+static const struct {
        const char *name;
        unsigned int div[4];
-} r8a7778_divs[6] __initdata = {
+} r8a7778_divs[6] __initconst = {
        { "b",   { 12, 12, 16, 18 } },
        { "out", { 12, 12, 16, 18 } },
        { "p",   { 16, 12, 16, 12 } },
index a98e21fe773a364739f299aac651ccc4d2e18656..957aae63e7cce2796417a96555ed5cf43bff11fd 100644 (file)
 #define SIRFSOC_CLKC_LEAF_CLK_EN7_SET        0x0530
 #define SIRFSOC_CLKC_LEAF_CLK_EN8_SET        0x0548
 
-
-static void __iomem *sirfsoc_clk_vbase;
-static struct clk_onecell_data clk_data;
-
-static const struct clk_div_table pll_div_table[] = {
-       { .val = 0, .div = 1 },
-       { .val = 1, .div = 2 },
-       { .val = 2, .div = 4 },
-       { .val = 3, .div = 8 },
-       { .val = 4, .div = 16 },
-       { .val = 5, .div = 32 },
-};
+#define SIRFSOC_NOC_CLK_IDLEREQ_SET            0x02D0
+#define SIRFSOC_NOC_CLK_IDLEREQ_CLR            0x02D4
+#define SIRFSOC_NOC_CLK_SLVRDY_SET             0x02E8
+#define SIRFSOC_NOC_CLK_SLVRDY_CLR             0x02EC
+#define SIRFSOC_NOC_CLK_IDLE_STATUS            0x02F4
 
 struct clk_pll {
        struct clk_hw hw;
@@ -231,10 +224,18 @@ struct clk_dto {
 };
 #define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw)
 
+enum clk_unit_type {
+       CLK_UNIT_NOC_OTHER,
+       CLK_UNIT_NOC_CLOCK,
+       CLK_UNIT_NOC_SOCKET,
+};
+
 struct clk_unit {
        struct clk_hw hw;
        u16 regofs;
        u16 bit;
+       u32 type;
+       u8 idle_bit;
        spinlock_t *lock;
 };
 #define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw)
@@ -272,6 +273,8 @@ struct atlas7_unit_init_data {
        unsigned long flags;
        u32 regofs;
        u8 bit;
+       u32 type;
+       u8 idle_bit;
        spinlock_t *lock;
 };
 
@@ -284,6 +287,18 @@ struct atlas7_reset_desc {
        spinlock_t *lock;
 };
 
+static void __iomem *sirfsoc_clk_vbase;
+static struct clk_onecell_data clk_data;
+
+static const struct clk_div_table pll_div_table[] = {
+       { .val = 0, .div = 1 },
+       { .val = 1, .div = 2 },
+       { .val = 2, .div = 4 },
+       { .val = 3, .div = 8 },
+       { .val = 4, .div = 16 },
+       { .val = 5, .div = 32 },
+};
+
 static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
 static DEFINE_SPINLOCK(mempll_ctrl1_lock);
 static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
@@ -1040,148 +1055,148 @@ static struct atlas7_mux_init_data mux_list[] __initdata = {
        /* new unit should add start from the tail of list */
 static struct atlas7_unit_init_data unit_list[] __initdata = {
        /* unit_name, parent_name, flags, regofs, bit, lock */
-       { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock },
-       { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock },
-       { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock },
-       { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock },
-       { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock },
-       { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock },
-       { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock },
-       { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock },
-       { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock },
-       { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock },
-       { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock },
-       { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock },
-       { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock },
-       { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock },
-       { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock },
-       { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock },
-       { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock },
-       { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock },
-       { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock },
-       { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock },
-       { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock },
-       { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock },
-       { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock },
-       { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock },
-       { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock },
-       { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock },
-       { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock },
-       { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock },
-       { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock },
-       { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock },
-       { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock },
-       { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock },
-       { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock },
-       { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock },
-       { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock },
-       { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock },
-       { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock },
-       { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock },
-       { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock },
-       { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock },
-       { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock },
-       { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock },
-       { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock },
-       { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock },
-       { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock },
-       { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock },
-       { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock },
-       { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock },
-       { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock },
-       { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock },
-       { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock },
-       { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock },
-       { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock },
-       { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock },
-       { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock },
-       { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock },
-       { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock },
-       { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock },
-       { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock },
-       { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock },
-       { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock },
-       { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock },
-       { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock },
-       { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock },
-       { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock },
-       { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock },
-       { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock },
-       { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock },
-       { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock },
-       { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock },
-       { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock },
-       { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock },
-       { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock },
-       { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock },
-       { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock },
-       { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock },
-       { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock },
-       { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock },
-       { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock },
-       { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock },
-       { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock },
-       { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock },
-       { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock },
-       { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock },
-       { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock },
-       { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock },
-       { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock },
-       { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock },
-       { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock },
-       { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock },
-       { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock },
-       { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock },
-       { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock },
-       { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock },
-       { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock },
-       { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock },
-       { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock },
-       { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock },
-       { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock },
-       { 99,  "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock },
-       { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock },
-       { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock },
-       { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock },
-       { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock },
-       { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock },
-       { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock },
-       { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock },
-       { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock },
-       { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock },
-       { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock },
-       { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock },
-       { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock },
-       { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock },
-       { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock },
-       { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock },
-       { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock },
-       { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock },
-       { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock },
-       { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock },
-       { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock },
-       { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock },
-       { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock },
-       { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
-       { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
-       { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
-       { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
-       { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock },
-       { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
-       { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
-       { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock },
-       { 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
-       { 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
-       { 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
-       { 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
-       { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock },
-       { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
-       { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
-       { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
-       { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock },
-       { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock },
-       { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock },
-       { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock },
+       { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, 0, 0, &root0_gate_lock },
+       { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, 0, 0, &root0_gate_lock },
+       { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, 0, 0, &root0_gate_lock },
+       { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, 0, 0, &root0_gate_lock },
+       { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, 0, 0, &root0_gate_lock },
+       { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, 0, 0, &root0_gate_lock },
+       { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, 0, 0, &root0_gate_lock },
+       { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, 0, 0, &root0_gate_lock },
+       { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, 0, 0, &root0_gate_lock },
+       { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, 0, 0, &root0_gate_lock },
+       { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, 0, 0, &root0_gate_lock },
+       { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, 0, 0, &root0_gate_lock },
+       { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, 0, 0, &root0_gate_lock },
+       { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, 0, 0, &root0_gate_lock },
+       { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, 0, 0, &root0_gate_lock },
+       { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, 0, 0, &root0_gate_lock },
+       { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, 0, 0, &root0_gate_lock },
+       { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, 0, 0, &root0_gate_lock },
+       { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, 0, 0, &root0_gate_lock },
+       { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, 0, 0, &root0_gate_lock },
+       { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, 0, 0, &root0_gate_lock },
+       { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, 0, 0, &root0_gate_lock },
+       { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, 0, 0, &root0_gate_lock },
+       { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, 0, 0, &root1_gate_lock },
+       { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, 0, 0, &root1_gate_lock },
+       { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, 0, 0, &root1_gate_lock },
+       { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, 0, 0, &root1_gate_lock },
+       { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, 0, 0, &root1_gate_lock },
+       { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, 0, 0, &root1_gate_lock },
+       { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, 0, 0, &root1_gate_lock },
+       { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, 0, 0, &root1_gate_lock },
+       { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, 0, 0, &root1_gate_lock },
+       { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, 0, 0, &root1_gate_lock },
+       { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, 0, 0, &root1_gate_lock },
+       { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, 0, 0, &root1_gate_lock },
+       { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, 0, 0, &root1_gate_lock },
+       { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, 0, 0, &root1_gate_lock },
+       { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, 0, 0, &root1_gate_lock },
+       { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, 0, 0, &root1_gate_lock },
+       { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, 0, 0, &root1_gate_lock },
+       { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, 0, 0, &root1_gate_lock },
+       { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, 0, 0, &root1_gate_lock },
+       { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, 0, 0, &root1_gate_lock },
+       { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, 0, 0, &root1_gate_lock },
+       { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, 0, 0, &root1_gate_lock },
+       { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, 0, 0, &root1_gate_lock },
+       { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, CLK_UNIT_NOC_CLOCK, 4, &leaf1_gate_lock },
+       { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, 0, 0, &leaf1_gate_lock },
+       { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, 0, 0, &leaf1_gate_lock },
+       { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, 0, 0, &leaf1_gate_lock },
+       { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, 0, 0, &leaf1_gate_lock },
+       { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, 0, 0, &leaf1_gate_lock },
+       { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, 0, 0, &leaf1_gate_lock },
+       { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, CLK_UNIT_NOC_SOCKET, 7, &leaf1_gate_lock },
+       { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, CLK_UNIT_NOC_SOCKET, 8, &leaf1_gate_lock },
+       { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
+       { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, 0, 0, &leaf1_gate_lock },
+       { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, CLK_UNIT_NOC_SOCKET, 4, &leaf1_gate_lock },
+       { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, CLK_UNIT_NOC_SOCKET, 5, &leaf1_gate_lock },
+       { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, CLK_UNIT_NOC_SOCKET, 6, &leaf1_gate_lock },
+       { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, CLK_UNIT_NOC_SOCKET, 1, &leaf1_gate_lock },
+       { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, CLK_UNIT_NOC_SOCKET, 2, &leaf1_gate_lock },
+       { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, CLK_UNIT_NOC_SOCKET, 0, &leaf1_gate_lock },
+       { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
+       { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, 0, 0, &leaf1_gate_lock },
+       { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, 0, 0, &leaf1_gate_lock },
+       { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, CLK_UNIT_NOC_CLOCK, 20, &leaf2_gate_lock },
+       { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, 0, 0, &leaf2_gate_lock },
+       { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, 0, 0, &leaf2_gate_lock },
+       { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, 0, 0, &leaf2_gate_lock },
+       { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, 0, 0, &leaf2_gate_lock },
+       { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, 0, 0, &leaf2_gate_lock },
+       { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, 0, 0, &leaf2_gate_lock },
+       { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, 0, 0, &leaf2_gate_lock },
+       { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, CLK_UNIT_NOC_CLOCK, 21, &leaf2_gate_lock },
+       { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, 0, 0, &leaf2_gate_lock },
+       { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, 0, 0, &leaf2_gate_lock },
+       { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, 0, 0, &leaf2_gate_lock },
+       { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, CLK_UNIT_NOC_CLOCK, 22, &leaf2_gate_lock },
+       { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, CLK_UNIT_NOC_CLOCK, 18, &leaf2_gate_lock },
+       { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, CLK_UNIT_NOC_CLOCK, 23, &leaf2_gate_lock },
+       { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, CLK_UNIT_NOC_CLOCK, 19, &leaf2_gate_lock },
+       { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15,  CLK_UNIT_NOC_CLOCK, 17, &leaf2_gate_lock },
+       { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, 0, 0, &leaf2_gate_lock },
+       { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, 0, 0, &leaf2_gate_lock },
+       { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, 0, 0, &leaf2_gate_lock },
+       { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, 0, 0, &leaf3_gate_lock },
+       { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, CLK_UNIT_NOC_CLOCK, 10, &leaf3_gate_lock },
+       { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, CLK_UNIT_NOC_SOCKET, 14, &leaf3_gate_lock },
+       { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, CLK_UNIT_NOC_SOCKET, 11, &leaf3_gate_lock },
+       { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, CLK_UNIT_NOC_SOCKET, 13, &leaf3_gate_lock },
+       { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, CLK_UNIT_NOC_SOCKET, 15, &leaf3_gate_lock },
+       { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, CLK_UNIT_NOC_SOCKET, 16, &leaf3_gate_lock },
+       { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, CLK_UNIT_NOC_SOCKET, 17, &leaf3_gate_lock },
+       { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, CLK_UNIT_NOC_SOCKET, 18, &leaf3_gate_lock },
+       { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, CLK_UNIT_NOC_SOCKET, 12, &leaf3_gate_lock },
+       { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, 0, 0, &leaf3_gate_lock },
+       { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, CLK_UNIT_NOC_CLOCK, 7, &leaf3_gate_lock },
+       { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, CLK_UNIT_NOC_CLOCK, 9, &leaf3_gate_lock },
+       { 99,  "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, CLK_UNIT_NOC_CLOCK, 8, &leaf3_gate_lock },
+       { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, 0, 0, &leaf3_gate_lock },
+       { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, 0, 0, &leaf3_gate_lock },
+       { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, CLK_UNIT_NOC_CLOCK, 3, &leaf4_gate_lock },
+       { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, CLK_UNIT_NOC_CLOCK, 1, &leaf4_gate_lock },
+       { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, CLK_UNIT_NOC_CLOCK, 12, &leaf4_gate_lock },
+       { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, CLK_UNIT_NOC_SOCKET, 21, &leaf4_gate_lock },
+       { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, CLK_UNIT_NOC_SOCKET, 20, &leaf4_gate_lock },
+       { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, CLK_UNIT_NOC_SOCKET, 19,  &leaf4_gate_lock },
+       { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, 0, 0, &leaf4_gate_lock },
+       { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, 0, 0, &leaf4_gate_lock },
+       { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, CLK_UNIT_NOC_CLOCK, 13, &leaf4_gate_lock },
+       { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, 0, 0, &leaf4_gate_lock },
+       { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, CLK_UNIT_NOC_CLOCK, 14, &leaf4_gate_lock },
+       { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, CLK_UNIT_NOC_CLOCK, 15, &leaf4_gate_lock },
+       { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12,  CLK_UNIT_NOC_CLOCK, 16, &leaf4_gate_lock },
+       { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, 0, 0, &leaf4_gate_lock },
+       { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, 0, 0, &leaf4_gate_lock },
+       { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, 0, 0, &leaf4_gate_lock },
+       { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, 0, 0, &leaf5_gate_lock },
+       { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, 0, 0, &leaf5_gate_lock },
+       { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, 0, 0, &leaf5_gate_lock },
+       { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, 0, 0, &leaf5_gate_lock },
+       { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, CLK_UNIT_NOC_SOCKET, 9, &leaf6_gate_lock },
+       { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, CLK_UNIT_NOC_SOCKET, 10, &leaf6_gate_lock },
+       { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, 0, 0, &leaf6_gate_lock },
+       { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, 0, 0, &leaf6_gate_lock },
+       { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, CLK_UNIT_NOC_CLOCK, 0, &leaf7_gate_lock },
+       { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, CLK_UNIT_NOC_CLOCK, 11, &leaf7_gate_lock },
+       { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, 0, 0, &leaf7_gate_lock },
+       { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, 0, 0, &leaf8_gate_lock },
+       { 130, "dmac4_io", "a7ca_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, 0, 0, &leaf8_gate_lock },
+       { 131, "uart6_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, 0, 0, &leaf8_gate_lock },
+       { 132, "usp3_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, 0, 0, &leaf8_gate_lock },
+       { 133, "a7ca_io", "noc_btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, 0, 0, &leaf8_gate_lock },
+       { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, 0, 0, &leaf8_gate_lock },
+       { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, 0, 0, &leaf8_gate_lock },
+       { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, 0, 0, &root1_gate_lock },
+       { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, 0, 0, &leaf8_gate_lock },
+       { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, 0, 0, &leaf0_gate_lock },
+       { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, 0, 0, &leaf0_gate_lock },
+       { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, 0, 0, &leaf0_gate_lock },
+       { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, 0, 0, &leaf0_gate_lock },
 };
 
 static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)];
@@ -1206,20 +1221,44 @@ static int unit_clk_enable(struct clk_hw *hw)
 
        spin_lock_irqsave(clk->lock, flags);
        clkc_writel(BIT(clk->bit), reg);
+       if (clk->type == CLK_UNIT_NOC_CLOCK)
+               clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
+       else if (clk->type == CLK_UNIT_NOC_SOCKET)
+               clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_SET);
+
        spin_unlock_irqrestore(clk->lock, flags);
        return 0;
 }
 
 static void unit_clk_disable(struct clk_hw *hw)
 {
-       u32  reg;
+       u32 reg;
+       u32 i = 0;
        struct clk_unit *clk = to_unitclk(hw);
        unsigned long flags;
 
        reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
-
        spin_lock_irqsave(clk->lock, flags);
+       if (clk->type == CLK_UNIT_NOC_CLOCK) {
+               clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_SET);
+               while (!(clkc_readl(SIRFSOC_NOC_CLK_IDLE_STATUS) &
+                               BIT(clk->idle_bit)) && (i++ < 100)) {
+                       cpu_relax();
+                       udelay(10);
+               }
+
+               if (i == 100) {
+                       pr_err("unit NoC Clock disconnect Error:timeout\n");
+                       /*once timeout, undo idlereq by CLR*/
+                       clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
+                       goto err;
+               }
+
+       } else if (clk->type == CLK_UNIT_NOC_SOCKET)
+               clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_CLR);
+
        clkc_writel(BIT(clk->bit), reg);
+err:
        spin_unlock_irqrestore(clk->lock, flags);
 }
 
@@ -1232,7 +1271,7 @@ static const struct clk_ops unit_clk_ops = {
 static struct clk * __init
 atlas7_unit_clk_register(struct device *dev, const char *name,
                 const char * const parent_name, unsigned long flags,
-                u32 regofs, u8 bit, spinlock_t *lock)
+                u32 regofs, u8 bit, u32 type, u8 idle_bit, spinlock_t *lock)
 {
        struct clk *clk;
        struct clk_unit *unit;
@@ -1251,6 +1290,9 @@ atlas7_unit_clk_register(struct device *dev, const char *name,
        unit->hw.init = &init;
        unit->regofs = regofs;
        unit->bit = bit;
+
+       unit->type = type;
+       unit->idle_bit = idle_bit;
        unit->lock = lock;
 
        clk = clk_register(dev, &unit->hw);
@@ -1624,7 +1666,7 @@ static void __init atlas7_clk_init(struct device_node *np)
        for (i = 0; i < ARRAY_SIZE(unit_list); i++) {
                unit = &unit_list[i];
                atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name,
-                               unit->flags, unit->regofs, unit->bit, unit->lock);
+                               unit->flags, unit->regofs, unit->bit, unit->type, unit->idle_bit, unit->lock);
                BUG_ON(!atlas7_clks[i]);
        }
 
index bd355ee33766b807556c848fcabeeb0c9293a187..24d99594c0b30d667251754982ebff75e1a56e26 100644 (file)
@@ -268,6 +268,7 @@ static void __init st_of_flexgen_setup(struct device_node *np)
        int num_parents, i;
        spinlock_t *rlock = NULL;
        unsigned long flex_flags = 0;
+       int ret;
 
        pnode = of_get_parent(np);
        if (!pnode)
@@ -285,13 +286,13 @@ static void __init st_of_flexgen_setup(struct device_node *np)
        if (!clk_data)
                goto err;
 
-       clk_data->clk_num = of_property_count_strings(np ,
-                       "clock-output-names");
-       if (clk_data->clk_num <= 0) {
+       ret = of_property_count_strings(np, "clock-output-names");
+       if (ret <= 0) {
                pr_err("%s: Failed to get number of output clocks (%d)",
                                __func__, clk_data->clk_num);
                goto err;
        }
+       clk_data->clk_num = ret;
 
        clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
                        GFP_KERNEL);
index 4f7f6c00b219dc005e98e5fc68733742c93efdcf..5dc5ce21796065df6739d4e395a35ce5c50375b2 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include "clkgen.h"
 
 static DEFINE_SPINLOCK(clkgena_divmux_lock);
 static DEFINE_SPINLOCK(clkgenf_lock);
@@ -576,6 +577,7 @@ static struct clkgen_mux_data stih415_a9_mux_data = {
        .offset = 0,
        .shift = 1,
        .width = 2,
+       .lock = &clkgen_a9_lock,
 };
 static struct clkgen_mux_data stih416_a9_mux_data = {
        .offset = 0,
@@ -586,6 +588,7 @@ static struct clkgen_mux_data stih407_a9_mux_data = {
        .offset = 0x1a4,
        .shift = 0,
        .width = 2,
+       .lock = &clkgen_a9_lock,
 };
 
 static const struct of_device_id mux_of_match[] = {
index b2a332cf8985706574f89acc4d46d8fe17f2166c..38f6f3a9098e0279789f370b1a518414cd14eb81 100644 (file)
 #include <linux/of_address.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/iopoll.h>
 
 #include "clkgen.h"
 
 static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
+DEFINE_SPINLOCK(clkgen_a9_lock);
 
 /*
  * Common PLL configuration register bits for PLL800 and PLL1600 C65
@@ -38,30 +40,46 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
 #define C32_IDF_MASK (0x7)
 #define C32_ODF_MASK (0x3f)
 #define C32_LDF_MASK (0x7f)
+#define C32_CP_MASK (0x1f)
 
 #define C32_MAX_ODFS (4)
 
+/*
+ * PLL configuration register bits for PLL4600 C28
+ */
+#define C28_NDIV_MASK (0xff)
+#define C28_IDF_MASK (0x7)
+#define C28_ODF_MASK (0x3f)
+
 struct clkgen_pll_data {
        struct clkgen_field pdn_status;
+       struct clkgen_field pdn_ctrl;
        struct clkgen_field locked_status;
        struct clkgen_field mdiv;
        struct clkgen_field ndiv;
        struct clkgen_field pdiv;
        struct clkgen_field idf;
        struct clkgen_field ldf;
+       struct clkgen_field cp;
        unsigned int num_odfs;
        struct clkgen_field odf[C32_MAX_ODFS];
        struct clkgen_field odf_gate[C32_MAX_ODFS];
+       bool switch2pll_en;
+       struct clkgen_field switch2pll;
+       spinlock_t *lock;
        const struct clk_ops *ops;
 };
 
 static const struct clk_ops st_pll1600c65_ops;
 static const struct clk_ops st_pll800c65_ops;
 static const struct clk_ops stm_pll3200c32_ops;
+static const struct clk_ops stm_pll3200c32_a9_ops;
 static const struct clk_ops st_pll1200c32_ops;
+static const struct clk_ops stm_pll4600c28_ops;
 
 static const struct clkgen_pll_data st_pll1600c65_ax = {
        .pdn_status     = CLKGEN_FIELD(0x0, 0x1,                        19),
+       .pdn_ctrl       = CLKGEN_FIELD(0x10,    0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x0, 0x1,                        31),
        .mdiv           = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK,      0),
        .ndiv           = CLKGEN_FIELD(0x0, C65_NDIV_MASK,              8),
@@ -70,6 +88,7 @@ static const struct clkgen_pll_data st_pll1600c65_ax = {
 
 static const struct clkgen_pll_data st_pll800c65_ax = {
        .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    19),
+       .pdn_ctrl       = CLKGEN_FIELD(0xC,     0x1,                    1),
        .locked_status  = CLKGEN_FIELD(0x0,     0x1,                    31),
        .mdiv           = CLKGEN_FIELD(0x0,     C65_MDIV_PLL800_MASK,   0),
        .ndiv           = CLKGEN_FIELD(0x0,     C65_NDIV_MASK,          8),
@@ -79,6 +98,7 @@ static const struct clkgen_pll_data st_pll800c65_ax = {
 
 static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
        .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    31),
+       .pdn_ctrl       = CLKGEN_FIELD(0x18,    0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x4,     0x1,                    31),
        .ndiv           = CLKGEN_FIELD(0x0,     C32_NDIV_MASK,          0x0),
        .idf            = CLKGEN_FIELD(0x4,     C32_IDF_MASK,           0x0),
@@ -96,6 +116,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
 
 static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
        .pdn_status     = CLKGEN_FIELD(0xC,     0x1,                    31),
+       .pdn_ctrl       = CLKGEN_FIELD(0x18,    0x1,                    1),
        .locked_status  = CLKGEN_FIELD(0x10,    0x1,                    31),
        .ndiv           = CLKGEN_FIELD(0xC,     C32_NDIV_MASK,          0x0),
        .idf            = CLKGEN_FIELD(0x10,    C32_IDF_MASK,           0x0),
@@ -114,6 +135,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
 /* 415 specific */
 static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
        .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x0,     0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x6C,    0x1,                    0),
        .ndiv           = CLKGEN_FIELD(0x0,     C32_NDIV_MASK,          9),
        .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           22),
@@ -125,6 +147,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
 
 static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
        .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x0,     0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x100,   0x1,                    0),
        .ndiv           = CLKGEN_FIELD(0x8,     C32_NDIV_MASK,          0),
        .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           25),
@@ -137,7 +160,8 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
 };
 
 static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
-       .pdn_status     = CLKGEN_FIELD(0x144,   0x1,                    3),
+       .pdn_status     = CLKGEN_FIELD(0x4,     0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x4,     0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x168,   0x1,                    0),
        .ldf            = CLKGEN_FIELD(0x0,     C32_LDF_MASK,           3),
        .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           0),
@@ -149,6 +173,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
 /* 416 specific */
 static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
        .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x0,     0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x6C,    0x1,                    0),
        .ndiv           = CLKGEN_FIELD(0x8,     C32_NDIV_MASK,          0),
        .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           25),
@@ -160,6 +185,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
 
 static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
        .pdn_status     = CLKGEN_FIELD(0x0,     0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x0,     0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x10C,   0x1,                    0),
        .ndiv           = CLKGEN_FIELD(0x8,     C32_NDIV_MASK,          0),
        .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           25),
@@ -173,6 +199,7 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
 
 static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
        .pdn_status     = CLKGEN_FIELD(0x8E4,   0x1,                    3),
+       .pdn_ctrl       = CLKGEN_FIELD(0x8E4,   0x1,                    3),
        .locked_status  = CLKGEN_FIELD(0x90C,   0x1,                    0),
        .ldf            = CLKGEN_FIELD(0x0,     C32_LDF_MASK,           3),
        .idf            = CLKGEN_FIELD(0x0,     C32_IDF_MASK,           0),
@@ -184,6 +211,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
 static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
        /* 407 A0 */
        .pdn_status     = CLKGEN_FIELD(0x2a0,   0x1,                    8),
+       .pdn_ctrl       = CLKGEN_FIELD(0x2a0,   0x1,                    8),
        .locked_status  = CLKGEN_FIELD(0x2a0,   0x1,                    24),
        .ndiv           = CLKGEN_FIELD(0x2a4,   C32_NDIV_MASK,          16),
        .idf            = CLKGEN_FIELD(0x2a4,   C32_IDF_MASK,           0x0),
@@ -196,6 +224,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
 static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
        /* 407 C0 PLL0 */
        .pdn_status     = CLKGEN_FIELD(0x2a0,   0x1,                    8),
+       .pdn_ctrl       = CLKGEN_FIELD(0x2a0,   0x1,                    8),
        .locked_status  = CLKGEN_FIELD(0x2a0,   0x1,                    24),
        .ndiv           = CLKGEN_FIELD(0x2a4,   C32_NDIV_MASK,          16),
        .idf            = CLKGEN_FIELD(0x2a4,   C32_IDF_MASK,           0x0),
@@ -208,6 +237,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
 static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
        /* 407 C0 PLL1 */
        .pdn_status     = CLKGEN_FIELD(0x2c8,   0x1,                    8),
+       .pdn_ctrl       = CLKGEN_FIELD(0x2c8,   0x1,                    8),
        .locked_status  = CLKGEN_FIELD(0x2c8,   0x1,                    24),
        .ndiv           = CLKGEN_FIELD(0x2cc,   C32_NDIV_MASK,          16),
        .idf            = CLKGEN_FIELD(0x2cc,   C32_IDF_MASK,           0x0),
@@ -220,13 +250,34 @@ static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
 static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
        /* 407 A9 */
        .pdn_status     = CLKGEN_FIELD(0x1a8,   0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x1a8,   0x1,                    0),
        .locked_status  = CLKGEN_FIELD(0x87c,   0x1,                    0),
        .ndiv           = CLKGEN_FIELD(0x1b0,   C32_NDIV_MASK,          0),
        .idf            = CLKGEN_FIELD(0x1a8,   C32_IDF_MASK,           25),
        .num_odfs = 1,
        .odf            = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK,           8) },
        .odf_gate       = { CLKGEN_FIELD(0x1ac, 0x1,                    28) },
-       .ops            = &stm_pll3200c32_ops,
+       .switch2pll_en  = true,
+       .cp             = CLKGEN_FIELD(0x1a8,   C32_CP_MASK,            1),
+       .switch2pll     = CLKGEN_FIELD(0x1a4,   0x1,                    1),
+       .lock = &clkgen_a9_lock,
+       .ops            = &stm_pll3200c32_a9_ops,
+};
+
+static struct clkgen_pll_data st_pll4600c28_418_a9 = {
+       /* 418 A9 */
+       .pdn_status     = CLKGEN_FIELD(0x1a8,   0x1,                    0),
+       .pdn_ctrl       = CLKGEN_FIELD(0x1a8,   0x1,                    0),
+       .locked_status  = CLKGEN_FIELD(0x87c,   0x1,                    0),
+       .ndiv           = CLKGEN_FIELD(0x1b0,   C28_NDIV_MASK,          0),
+       .idf            = CLKGEN_FIELD(0x1a8,   C28_IDF_MASK,           25),
+       .num_odfs = 1,
+       .odf            = { CLKGEN_FIELD(0x1b0, C28_ODF_MASK,           8) },
+       .odf_gate       = { CLKGEN_FIELD(0x1ac, 0x1,                    28) },
+       .switch2pll_en  = true,
+       .switch2pll     = CLKGEN_FIELD(0x1a4,   0x1,                    1),
+       .lock           = &clkgen_a9_lock,
+       .ops            = &stm_pll4600c28_ops,
 };
 
 /**
@@ -252,10 +303,26 @@ struct clkgen_pll {
        struct clk_hw           hw;
        struct clkgen_pll_data  *data;
        void __iomem            *regs_base;
+       spinlock_t      *lock;
+
+       u32 ndiv;
+       u32 idf;
+       u32 odf;
+       u32 cp;
 };
 
 #define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
 
+struct stm_pll {
+       unsigned long mdiv;
+       unsigned long ndiv;
+       unsigned long pdiv;
+       unsigned long odf;
+       unsigned long idf;
+       unsigned long ldf;
+       unsigned long cp;
+};
+
 static int clkgen_pll_is_locked(struct clk_hw *hw)
 {
        struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -271,6 +338,78 @@ static int clkgen_pll_is_enabled(struct clk_hw *hw)
        return !poweroff;
 }
 
+static int __clkgen_pll_enable(struct clk_hw *hw)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       void __iomem *base =  pll->regs_base;
+       struct clkgen_field *field = &pll->data->locked_status;
+       int ret = 0;
+       u32 reg;
+
+       if (clkgen_pll_is_enabled(hw))
+               return 0;
+
+       CLKGEN_WRITE(pll, pdn_ctrl, 0);
+
+       ret = readl_relaxed_poll_timeout(base + field->offset, reg,
+                       !!((reg >> field->shift) & field->mask),  0, 10000);
+
+       if (!ret) {
+               if (pll->data->switch2pll_en)
+                       CLKGEN_WRITE(pll, switch2pll, 0);
+
+               pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__);
+       }
+
+       return ret;
+}
+
+static int clkgen_pll_enable(struct clk_hw *hw)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       unsigned long flags = 0;
+       int ret = 0;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       ret = __clkgen_pll_enable(hw);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static void __clkgen_pll_disable(struct clk_hw *hw)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+
+       if (!clkgen_pll_is_enabled(hw))
+               return;
+
+       if (pll->data->switch2pll_en)
+               CLKGEN_WRITE(pll, switch2pll, 1);
+
+       CLKGEN_WRITE(pll, pdn_ctrl, 1);
+
+       pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__);
+}
+
+static void clkgen_pll_disable(struct clk_hw *hw)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       unsigned long flags = 0;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       __clkgen_pll_disable(hw);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+}
+
 static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -322,6 +461,67 @@ static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
        return rate;
 }
 
+static int clk_pll3200c32_get_params(unsigned long input, unsigned long output,
+                         struct stm_pll *pll)
+{
+       unsigned long i, n;
+       unsigned long deviation = ~0;
+       unsigned long new_freq;
+       long new_deviation;
+       /* Charge pump table: highest ndiv value for cp=6 to 25 */
+       static const unsigned char cp_table[] = {
+               48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
+               128, 136, 144, 152, 160, 168, 176, 184, 192
+       };
+
+       /* Output clock range: 800Mhz to 1600Mhz */
+       if (output < 800000000 || output > 1600000000)
+               return -EINVAL;
+
+       input /= 1000;
+       output /= 1000;
+
+       for (i = 1; i <= 7 && deviation; i++) {
+               n = i * output / (2 * input);
+
+               /* Checks */
+               if (n < 8)
+                       continue;
+               if (n > 200)
+                       break;
+
+               new_freq = (input * 2 * n) / i;
+
+               new_deviation = abs(new_freq - output);
+
+               if (!new_deviation || new_deviation < deviation) {
+                       pll->idf  = i;
+                       pll->ndiv = n;
+                       deviation = new_deviation;
+               }
+       }
+
+       if (deviation == ~0) /* No solution found */
+               return -EINVAL;
+
+       /* Computing recommended charge pump value */
+       for (pll->cp = 6; pll->ndiv > cp_table[pll->cp-6]; (pll->cp)++)
+               ;
+
+       return 0;
+}
+
+static int clk_pll3200c32_get_rate(unsigned long input, struct stm_pll *pll,
+                       unsigned long *rate)
+{
+       if (!pll->idf)
+               pll->idf = 1;
+
+       *rate = ((2 * (input / 1000) * pll->ndiv) / pll->idf) * 1000;
+
+       return 0;
+}
+
 static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -344,6 +544,70 @@ static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
        return rate;
 }
 
+static long round_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
+               unsigned long *prate)
+{
+       struct stm_pll params;
+
+       if (!clk_pll3200c32_get_params(*prate, rate, &params))
+               clk_pll3200c32_get_rate(*prate, &params, &rate);
+       else {
+               pr_debug("%s: %s rate %ld Invalid\n", __func__,
+                        __clk_get_name(hw->clk), rate);
+               return 0;
+       }
+
+       pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
+                __func__, __clk_get_name(hw->clk),
+                rate, (unsigned int)params.ndiv,
+                (unsigned int)params.idf);
+
+       return rate;
+}
+
+static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       struct stm_pll params;
+       long hwrate = 0;
+       unsigned long flags = 0;
+
+       if (!rate || !parent_rate)
+               return -EINVAL;
+
+       if (!clk_pll3200c32_get_params(parent_rate, rate, &params))
+               clk_pll3200c32_get_rate(parent_rate, &params, &hwrate);
+
+       pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
+                __func__, __clk_get_name(hw->clk),
+                hwrate, (unsigned int)params.ndiv,
+                (unsigned int)params.idf);
+
+       if (!hwrate)
+               return -EINVAL;
+
+       pll->ndiv = params.ndiv;
+       pll->idf = params.idf;
+       pll->cp = params.cp;
+
+       __clkgen_pll_disable(hw);
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       CLKGEN_WRITE(pll, ndiv, pll->ndiv);
+       CLKGEN_WRITE(pll, idf, pll->idf);
+       CLKGEN_WRITE(pll, cp, pll->cp);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       __clkgen_pll_enable(hw);
+
+       return 0;
+}
+
 static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -371,30 +635,213 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
        return rate;
 }
 
+/* PLL output structure
+ * FVCO >> /2 >> FVCOBY2 (no output)
+ *                 |> Divider (ODF) >> PHI
+ *
+ * FVCOby2 output = (input * 2 * NDIV) / IDF (assuming FRAC_CONTROL==L)
+ *
+ * Rules:
+ *   4Mhz <= INFF input <= 350Mhz
+ *   4Mhz <= INFIN (INFF / IDF) <= 50Mhz
+ *   19.05Mhz <= FVCOby2 output (PHI w ODF=1) <= 3000Mhz
+ *   1 <= i (register/dec value for IDF) <= 7
+ *   8 <= n (register/dec value for NDIV) <= 246
+ */
+
+static int clk_pll4600c28_get_params(unsigned long input, unsigned long output,
+                         struct stm_pll *pll)
+{
+
+       unsigned long i, infin, n;
+       unsigned long deviation = ~0;
+       unsigned long new_freq, new_deviation;
+
+       /* Output clock range: 19Mhz to 3000Mhz */
+       if (output < 19000000 || output > 3000000000u)
+               return -EINVAL;
+
+       /* For better jitter, IDF should be smallest and NDIV must be maximum */
+       for (i = 1; i <= 7 && deviation; i++) {
+               /* INFIN checks */
+               infin = input / i;
+               if (infin < 4000000 || infin > 50000000)
+                       continue;       /* Invalid case */
+
+               n = output / (infin * 2);
+               if (n < 8 || n > 246)
+                       continue;       /* Invalid case */
+               if (n < 246)
+                       n++;    /* To work around 'y' when n=x.y */
+
+               for (; n >= 8 && deviation; n--) {
+                       new_freq = infin * 2 * n;
+                       if (new_freq < output)
+                               break;  /* Optimization: shorting loop */
+
+                       new_deviation = new_freq - output;
+                       if (!new_deviation || new_deviation < deviation) {
+                               pll->idf  = i;
+                               pll->ndiv = n;
+                               deviation = new_deviation;
+                       }
+               }
+       }
+
+       if (deviation == ~0) /* No solution found */
+               return -EINVAL;
+
+       return 0;
+}
+
+static int clk_pll4600c28_get_rate(unsigned long input, struct stm_pll *pll,
+                       unsigned long *rate)
+{
+       if (!pll->idf)
+               pll->idf = 1;
+
+       *rate = (input / pll->idf) * 2 * pll->ndiv;
+
+       return 0;
+}
+
+static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw,
+                                   unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       struct stm_pll params;
+       unsigned long rate;
+
+       if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
+               return 0;
+
+       params.ndiv = CLKGEN_READ(pll, ndiv);
+       params.idf = CLKGEN_READ(pll, idf);
+
+       clk_pll4600c28_get_rate(parent_rate, &params, &rate);
+
+       pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+       return rate;
+}
+
+static long round_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
+                                     unsigned long *prate)
+{
+       struct stm_pll params;
+
+       if (!clk_pll4600c28_get_params(*prate, rate, &params)) {
+               clk_pll4600c28_get_rate(*prate, &params, &rate);
+       } else {
+               pr_debug("%s: %s rate %ld Invalid\n", __func__,
+                        __clk_get_name(hw->clk), rate);
+               return 0;
+       }
+
+       pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
+                __func__, __clk_get_name(hw->clk),
+                rate, (unsigned int)params.ndiv,
+                (unsigned int)params.idf);
+
+       return rate;
+}
+
+static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long parent_rate)
+{
+       struct clkgen_pll *pll = to_clkgen_pll(hw);
+       struct stm_pll params;
+       long hwrate;
+       unsigned long flags = 0;
+
+       if (!rate || !parent_rate)
+               return -EINVAL;
+
+       if (!clk_pll4600c28_get_params(parent_rate, rate, &params)) {
+               clk_pll4600c28_get_rate(parent_rate, &params, &hwrate);
+       } else {
+               pr_debug("%s: %s rate %ld Invalid\n", __func__,
+                        __clk_get_name(hw->clk), rate);
+               return -EINVAL;
+       }
+
+       pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
+                __func__, __clk_get_name(hw->clk),
+                hwrate, (unsigned int)params.ndiv,
+                (unsigned int)params.idf);
+
+       if (!hwrate)
+               return -EINVAL;
+
+       pll->ndiv = params.ndiv;
+       pll->idf = params.idf;
+
+       __clkgen_pll_disable(hw);
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       CLKGEN_WRITE(pll, ndiv, pll->ndiv);
+       CLKGEN_WRITE(pll, idf, pll->idf);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       __clkgen_pll_enable(hw);
+
+       return 0;
+}
+
 static const struct clk_ops st_pll1600c65_ops = {
+       .enable         = clkgen_pll_enable,
+       .disable        = clkgen_pll_disable,
        .is_enabled     = clkgen_pll_is_enabled,
        .recalc_rate    = recalc_stm_pll1600c65,
 };
 
 static const struct clk_ops st_pll800c65_ops = {
+       .enable         = clkgen_pll_enable,
+       .disable        = clkgen_pll_disable,
        .is_enabled     = clkgen_pll_is_enabled,
        .recalc_rate    = recalc_stm_pll800c65,
 };
 
 static const struct clk_ops stm_pll3200c32_ops = {
+       .enable         = clkgen_pll_enable,
+       .disable        = clkgen_pll_disable,
        .is_enabled     = clkgen_pll_is_enabled,
        .recalc_rate    = recalc_stm_pll3200c32,
 };
 
+static const struct clk_ops stm_pll3200c32_a9_ops = {
+       .enable         = clkgen_pll_enable,
+       .disable        = clkgen_pll_disable,
+       .is_enabled     = clkgen_pll_is_enabled,
+       .recalc_rate    = recalc_stm_pll3200c32,
+       .round_rate     = round_rate_stm_pll3200c32,
+       .set_rate       = set_rate_stm_pll3200c32,
+};
+
 static const struct clk_ops st_pll1200c32_ops = {
+       .enable         = clkgen_pll_enable,
+       .disable        = clkgen_pll_disable,
        .is_enabled     = clkgen_pll_is_enabled,
        .recalc_rate    = recalc_stm_pll1200c32,
 };
 
+static const struct clk_ops stm_pll4600c28_ops = {
+       .enable         = clkgen_pll_enable,
+       .disable        = clkgen_pll_disable,
+       .is_enabled     = clkgen_pll_is_enabled,
+       .recalc_rate    = recalc_stm_pll4600c28,
+       .round_rate     = round_rate_stm_pll4600c28,
+       .set_rate       = set_rate_stm_pll4600c28,
+};
+
 static struct clk * __init clkgen_pll_register(const char *parent_name,
                                struct clkgen_pll_data  *pll_data,
                                void __iomem *reg,
-                               const char *clk_name)
+                               const char *clk_name, spinlock_t *lock)
 {
        struct clkgen_pll *pll;
        struct clk *clk;
@@ -414,6 +861,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name,
        pll->data = pll_data;
        pll->regs_base = reg;
        pll->hw.init = &init;
+       pll->lock = lock;
 
        clk = clk_register(NULL, &pll->hw);
        if (IS_ERR(clk)) {
@@ -500,7 +948,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
         */
        clk_data->clks[0] = clkgen_pll_register(parent_name,
                        (struct clkgen_pll_data *) &st_pll1600c65_ax,
-                       reg + CLKGENAx_PLL0_OFFSET, clk_name);
+                       reg + CLKGENAx_PLL0_OFFSET, clk_name, NULL);
 
        if (IS_ERR(clk_data->clks[0]))
                goto err;
@@ -529,7 +977,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
         */
        clk_data->clks[2] = clkgen_pll_register(parent_name,
                        (struct clkgen_pll_data *) &st_pll800c65_ax,
-                       reg + CLKGENAx_PLL1_OFFSET, clk_name);
+                       reg + CLKGENAx_PLL1_OFFSET, clk_name, NULL);
 
        if (IS_ERR(clk_data->clks[2]))
                goto err;
@@ -556,7 +1004,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
        struct clk_gate *gate;
        struct clk_divider *div;
 
-       flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE;
+       flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
 
        gate = kzalloc(sizeof(*gate), GFP_KERNEL);
        if (!gate)
@@ -635,6 +1083,10 @@ static const struct of_device_id c32_pll_of_match[] = {
                .compatible = "st,stih407-plls-c32-a9",
                .data = &st_pll3200c32_407_a9,
        },
+       {
+               .compatible = "st,stih418-plls-c28-a9",
+               .data = &st_pll4600c28_418_a9,
+       },
        {}
 };
 
@@ -664,7 +1116,8 @@ static void __init clkgen_c32_pll_setup(struct device_node *np)
        if (!pll_base)
                return;
 
-       clk = clkgen_pll_register(parent_name, data, pll_base, np->name);
+       clk = clkgen_pll_register(parent_name, data, pll_base, np->name,
+                                 data->lock);
        if (IS_ERR(clk))
                return;
 
@@ -753,7 +1206,7 @@ static void __init clkgengpu_c32_pll_setup(struct device_node *np)
        /*
         * PLL 1200MHz output
         */
-       clk = clkgen_pll_register(parent_name, data, reg, clk_name);
+       clk = clkgen_pll_register(parent_name, data, reg, clk_name, data->lock);
 
        if (!IS_ERR(clk))
                of_clk_add_provider(np, of_clk_src_simple_get, clk);
index 35c863295268107f7e451c65161465d3a9a01c5a..f7ec2d9139d63f5dcf87f714665d8cde2c643452 100644 (file)
@@ -9,6 +9,8 @@ Copyright (C) 2014 STMicroelectronics
 #ifndef __CLKGEN_INFO_H
 #define __CLKGEN_INFO_H
 
+extern spinlock_t clkgen_a9_lock;
+
 struct clkgen_field {
        unsigned int offset;
        unsigned int mask;
index 64f3e46d383cc2ede89889cb7b2d4e9b26d0a22a..23d042aabb4f7724d2cf1602b8a2b1f4028a8c41 100644 (file)
@@ -34,6 +34,7 @@ static const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
        { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_gates_clk_dt_ids);
 
 static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
 {
index 70763600aeaeed91e73203fdc9a1e68efc5a97b2..e703e1895b76bf3affb282be6c1827ea1f5a7e61 100644 (file)
@@ -61,6 +61,7 @@ static const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = {
        { .compatible = "allwinner,sun6i-a31-apb0-clk" },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_clk_dt_ids);
 
 static struct platform_driver sun6i_a31_apb0_clk_driver = {
        .driver = {
index 806fd019c05dd103c272446ef03e01e3a9def11f..20887686bdbee09fe7fbc90963f179ed45c651ab 100644 (file)
@@ -219,6 +219,7 @@ static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
        { .compatible = "allwinner,sun6i-a31-ar100-clk" },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun6i_a31_ar100_clk_dt_ids);
 
 static struct platform_driver sun6i_a31_ar100_clk_driver = {
        .driver = {
index 155d0022194f2665068b46ed92a0b70cefbca601..7ae5d2c2cde17b1cdaf265a831f3983cd3892d75 100644 (file)
@@ -52,6 +52,7 @@ static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
        { .compatible = "allwinner,sun8i-a23-apb0-clk" },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun8i_a23_apb0_clk_dt_ids);
 
 static struct platform_driver sun8i_a23_apb0_clk_driver = {
        .driver = {
index 3436a948b796fc42b53181cda67ca89ab731f690..a9b176139aca8b159329e25ef76b805825423229 100644 (file)
@@ -204,6 +204,7 @@ static const struct of_device_id sun9i_a80_mmc_config_clk_dt_ids[] = {
        { .compatible = "allwinner,sun9i-a80-mmc-config-clk" },
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun9i_a80_mmc_config_clk_dt_ids);
 
 static struct platform_driver sun9i_a80_mmc_config_clk_driver = {
        .driver = {
index 138a94b99b5bb5ce0863ef9a0110b4bea928159a..e1fe8f35d45c47c553997845657e09d3b71ca9a1 100644 (file)
@@ -491,10 +491,8 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
        for_each_child_of_node(np, node) {
                err = of_property_read_u32(node, "nvidia,ram-code",
                                           &node_ram_code);
-               if (err) {
-                       of_node_put(node);
+               if (err)
                        continue;
-               }
 
                /*
                 * Store timings for all ram codes as we cannot read the
index 1530c9352a7638eb60501a6bc18f8418a9b4d54f..fc50b6264bedf4b1772f7abc2e0b6418c18642e2 100644 (file)
@@ -1,6 +1,6 @@
 config COMMON_CLK_VERSATILE
        bool "Clock driver for ARM Reference designs"
-       depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64
+       depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 || COMPILE_TEST
        ---help---
           Supports clocking on ARM Reference designs:
          - Integrator/AP and Integrator/CP
index a3893ea2199dafa5412207711a1d33fca04c287f..08c5ee976879932ab2dfc48d41391a6836942526 100644 (file)
@@ -157,8 +157,10 @@ struct clk *icst_clk_register(struct device *dev,
        icst->lockreg = base + desc->lock_offset;
 
        clk = clk_register(dev, &icst->hw);
-       if (IS_ERR(clk))
+       if (IS_ERR(clk)) {
+               kfree(pclone);
                kfree(icst);
+       }
 
        return clk;
 }
index a0cdbf35dcb19bd637632f55d514ad16d1588036..a5d319e4aae65dad90f64bafd33c2ad02bed7034 100644 (file)
@@ -227,10 +227,6 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
        if (IS_ERR(d->clk) || !old)
                goto out;
 
-       /* Not requesting clock rates below 1.8432Mhz */
-       if (baud < 115200)
-               baud = 115200;
-
        clk_disable_unprepare(d->clk);
        rate = clk_round_rate(d->clk, baud * 16);
        ret = clk_set_rate(d->clk, rate);
index 0b4cb999a3f7a2b2aa714b45e0b9d6cd960d55d5..ab3ee241d10c50577694ab5eeacabf8c8cabcb39 100644 (file)
@@ -18,5 +18,6 @@
 #define AT91_PMC_MOSCSELS      16              /* Main Oscillator Selection */
 #define AT91_PMC_MOSCRCS       17              /* Main On-Chip RC */
 #define AT91_PMC_CFDEV         18              /* Clock Failure Detector Event */
+#define AT91_PMC_GCKRDY                24              /* Generated Clocks */
 
 #endif
diff --git a/include/dt-bindings/clock/bcm-ns2.h b/include/dt-bindings/clock/bcm-ns2.h
new file mode 100644 (file)
index 0000000..d99c7a2
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CLOCK_BCM_NS2_H
+#define _CLOCK_BCM_NS2_H
+
+/* GENPLL SCR clock channel ID */
+#define BCM_NS2_GENPLL_SCR             0
+#define BCM_NS2_GENPLL_SCR_SCR_CLK     1
+#define BCM_NS2_GENPLL_SCR_FS_CLK      2
+#define BCM_NS2_GENPLL_SCR_AUDIO_CLK   3
+#define BCM_NS2_GENPLL_SCR_CH3_UNUSED  4
+#define BCM_NS2_GENPLL_SCR_CH4_UNUSED  5
+#define BCM_NS2_GENPLL_SCR_CH5_UNUSED  6
+
+/* GENPLL SW clock channel ID */
+#define BCM_NS2_GENPLL_SW              0
+#define BCM_NS2_GENPLL_SW_RPE_CLK      1
+#define BCM_NS2_GENPLL_SW_250_CLK      2
+#define BCM_NS2_GENPLL_SW_NIC_CLK      3
+#define BCM_NS2_GENPLL_SW_CHIMP_CLK    4
+#define BCM_NS2_GENPLL_SW_PORT_CLK     5
+#define BCM_NS2_GENPLL_SW_SDIO_CLK     6
+
+/* LCPLL DDR clock channel ID */
+#define BCM_NS2_LCPLL_DDR              0
+#define BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK    1
+#define BCM_NS2_LCPLL_DDR_DDR_CLK      2
+#define BCM_NS2_LCPLL_DDR_CH2_UNUSED   3
+#define BCM_NS2_LCPLL_DDR_CH3_UNUSED   4
+#define BCM_NS2_LCPLL_DDR_CH4_UNUSED   5
+#define BCM_NS2_LCPLL_DDR_CH5_UNUSED   6
+
+/* LCPLL PORTS clock channel ID */
+#define BCM_NS2_LCPLL_PORTS            0
+#define BCM_NS2_LCPLL_PORTS_WAN_CLK    1
+#define BCM_NS2_LCPLL_PORTS_RGMII_CLK  2
+#define BCM_NS2_LCPLL_PORTS_CH2_UNUSED 3
+#define BCM_NS2_LCPLL_PORTS_CH3_UNUSED 4
+#define BCM_NS2_LCPLL_PORTS_CH4_UNUSED 5
+#define BCM_NS2_LCPLL_PORTS_CH5_UNUSED 6
+
+#endif /* _CLOCK_BCM_NS2_H */
diff --git a/include/dt-bindings/clock/bcm-nsp.h b/include/dt-bindings/clock/bcm-nsp.h
new file mode 100644 (file)
index 0000000..ad5827c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Broadcom Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CLOCK_BCM_NSP_H
+#define _CLOCK_BCM_NSP_H
+
+/* GENPLL clock channel ID */
+#define BCM_NSP_GENPLL                 0
+#define BCM_NSP_GENPLL_PHY_CLK         1
+#define BCM_NSP_GENPLL_ENET_SW_CLK     2
+#define BCM_NSP_GENPLL_USB_PHY_REF_CLK 3
+#define BCM_NSP_GENPLL_IPROCFAST_CLK   4
+#define BCM_NSP_GENPLL_SATA1_CLK       5
+#define BCM_NSP_GENPLL_SATA2_CLK       6
+
+/* LCPLL0 clock channel ID */
+#define BCM_NSP_LCPLL0                 0
+#define BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK        1
+#define BCM_NSP_LCPLL0_SDIO_CLK                2
+#define BCM_NSP_LCPLL0_DDR_PHY_CLK     3
+
+#endif /* _CLOCK_BCM_NSP_H */
index e33c75a3c09dc7caf26575a7e3469788aa6cc234..10c558611085df705e982623a1934031015de461 100644 (file)
 #define ACLK_MSCL_532                  8
 #define DOUT_SCLK_AUD_PLL              9
 #define FOUT_AUD_PLL                   10
-#define TOPC_NR_CLK                    11
+#define SCLK_AUD_PLL                   11
+#define SCLK_MFC_PLL_B                 12
+#define SCLK_MFC_PLL_A                 13
+#define SCLK_BUS1_PLL_B                        14
+#define SCLK_BUS1_PLL_A                        15
+#define SCLK_BUS0_PLL_B                        16
+#define SCLK_BUS0_PLL_A                        17
+#define SCLK_CC_PLL_B                  18
+#define SCLK_CC_PLL_A                  19
+#define ACLK_CCORE_133                 20
+#define ACLK_PERIS_66                  21
+#define TOPC_NR_CLK                    22
 
 /* TOP0 */
 #define DOUT_ACLK_PERIC1               1
@@ -38,7 +49,9 @@
 #define CLK_SCLK_SPDIF                 12
 #define CLK_SCLK_PCM1                  13
 #define CLK_SCLK_I2S1                  14
-#define TOP0_NR_CLK                    15
+#define CLK_ACLK_PERIC0_66             15
+#define CLK_ACLK_PERIC1_66             16
+#define TOP0_NR_CLK                    17
 
 /* TOP1 */
 #define DOUT_ACLK_FSYS1_200            1
 #define CLK_SCLK_MMC2                  6
 #define CLK_SCLK_MMC1                  7
 #define CLK_SCLK_MMC0                  8
-#define TOP1_NR_CLK                    9
+#define CLK_ACLK_FSYS0_200             9
+#define CLK_ACLK_FSYS1_200             10
+#define CLK_SCLK_PHY_FSYS1             11
+#define CLK_SCLK_PHY_FSYS1_26M         12
+#define MOUT_SCLK_UFSUNIPRO20          13
+#define DOUT_SCLK_UFSUNIPRO20          14
+#define CLK_SCLK_UFSUNIPRO20           15
+#define DOUT_SCLK_PHY_FSYS1            16
+#define DOUT_SCLK_PHY_FSYS1_26M                17
+#define TOP1_NR_CLK                    18
 
 /* CCORE */
 #define PCLK_RTC                       1
 /* FSYS1 */
 #define ACLK_MMC1                      1
 #define ACLK_MMC0                      2
-#define FSYS1_NR_CLK                   3
+#define PHYCLK_UFS20_TX0_SYMBOL                3
+#define PHYCLK_UFS20_RX0_SYMBOL                4
+#define PHYCLK_UFS20_RX1_SYMBOL                5
+#define ACLK_UFS20_LINK                        6
+#define SCLK_UFSUNIPRO20_USER          7
+#define PHYCLK_UFS20_RX1_SYMBOL_USER   8
+#define PHYCLK_UFS20_RX0_SYMBOL_USER   9
+#define PHYCLK_UFS20_TX0_SYMBOL_USER   10
+#define OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY   11
+#define SCLK_COMBO_PHY_EMBEDDED_26M    12
+#define DOUT_PCLK_FSYS1                        13
+#define PCLK_GPIO_FSYS1                        14
+#define MOUT_FSYS1_PHYCLK_SEL1         15
+#define FSYS1_NR_CLK                   16
 
 /* MSCL */
 #define USERMUX_ACLK_MSCL_532          1
index 4ad76ed882ad3abd9c61dc730a66a9c6753262a1..7956ba1bc9744a5fccd7b5b3cc915929752a146f 100644 (file)
@@ -18,7 +18,6 @@
 /* TOPCKGEN */
 
 #define CLK_TOP_CLKPH_MCK_O            1
-#define CLK_TOP_DPI                    2
 #define CLK_TOP_USB_SYSPLL_125M                3
 #define CLK_TOP_HDMITX_DIG_CTS         4
 #define CLK_TOP_ARMCA7PLL_754M         5
 #define CLK_TOP_I2S2_M_SEL             135
 #define CLK_TOP_I2S3_M_SEL             136
 #define CLK_TOP_I2S3_B_SEL             137
-#define CLK_TOP_NR_CLK                 138
+#define CLK_TOP_DSI0_DIG               138
+#define CLK_TOP_DSI1_DIG               139
+#define CLK_TOP_LVDS_PXL               140
+#define CLK_TOP_LVDS_CTS               141
+#define CLK_TOP_NR_CLK                 142
 
 /* APMIXED_SYS */
 
-#define CLK_APMIXED_ARMCA15PLL 1
-#define CLK_APMIXED_ARMCA7PLL  2
+#define CLK_APMIXED_ARMCA15PLL         1
+#define CLK_APMIXED_ARMCA7PLL          2
 #define CLK_APMIXED_MAINPLL            3
 #define CLK_APMIXED_UNIVPLL            4
 #define CLK_APMIXED_MMPLL              5
 #define CLK_APMIXED_APLL2              12
 #define CLK_APMIXED_LVDSPLL            13
 #define CLK_APMIXED_MSDCPLL2           14
-#define CLK_APMIXED_NR_CLK             15
+#define CLK_APMIXED_REF2USB_TX         15
+#define CLK_APMIXED_NR_CLK             16
 
 /* INFRA_SYS */
 
 #define CLK_INFRA_CEC                  9
 #define CLK_INFRA_PMICSPI              10
 #define CLK_INFRA_PMICWRAP             11
-#define CLK_INFRA_NR_CLK               12
+#define CLK_INFRA_CLK_13M              12
+#define CLK_INFRA_NR_CLK               13
 
 /* PERI_SYS */
 
 #define CLK_PERI_UART3_SEL             39
 #define CLK_PERI_NR_CLK                        40
 
+/* IMG_SYS */
+
+#define CLK_IMG_LARB2_SMI              1
+#define CLK_IMG_CAM_SMI                        2
+#define CLK_IMG_CAM_CAM                        3
+#define CLK_IMG_SEN_TG                 4
+#define CLK_IMG_SEN_CAM                        5
+#define CLK_IMG_CAM_SV                 6
+#define CLK_IMG_FD                     7
+#define CLK_IMG_NR_CLK                 8
+
+/* MM_SYS */
+
+#define CLK_MM_SMI_COMMON              1
+#define CLK_MM_SMI_LARB0               2
+#define CLK_MM_CAM_MDP                 3
+#define CLK_MM_MDP_RDMA0               4
+#define CLK_MM_MDP_RDMA1               5
+#define CLK_MM_MDP_RSZ0                        6
+#define CLK_MM_MDP_RSZ1                        7
+#define CLK_MM_MDP_RSZ2                        8
+#define CLK_MM_MDP_TDSHP0              9
+#define CLK_MM_MDP_TDSHP1              10
+#define CLK_MM_MDP_WDMA                        11
+#define CLK_MM_MDP_WROT0               12
+#define CLK_MM_MDP_WROT1               13
+#define CLK_MM_FAKE_ENG                        14
+#define CLK_MM_MUTEX_32K               15
+#define CLK_MM_DISP_OVL0               16
+#define CLK_MM_DISP_OVL1               17
+#define CLK_MM_DISP_RDMA0              18
+#define CLK_MM_DISP_RDMA1              19
+#define CLK_MM_DISP_RDMA2              20
+#define CLK_MM_DISP_WDMA0              21
+#define CLK_MM_DISP_WDMA1              22
+#define CLK_MM_DISP_COLOR0             23
+#define CLK_MM_DISP_COLOR1             24
+#define CLK_MM_DISP_AAL                        25
+#define CLK_MM_DISP_GAMMA              26
+#define CLK_MM_DISP_UFOE               27
+#define CLK_MM_DISP_SPLIT0             28
+#define CLK_MM_DISP_SPLIT1             29
+#define CLK_MM_DISP_MERGE              30
+#define CLK_MM_DISP_OD                 31
+#define CLK_MM_DISP_PWM0MM             32
+#define CLK_MM_DISP_PWM026M            33
+#define CLK_MM_DISP_PWM1MM             34
+#define CLK_MM_DISP_PWM126M            35
+#define CLK_MM_DSI0_ENGINE             36
+#define CLK_MM_DSI0_DIGITAL            37
+#define CLK_MM_DSI1_ENGINE             38
+#define CLK_MM_DSI1_DIGITAL            39
+#define CLK_MM_DPI_PIXEL               40
+#define CLK_MM_DPI_ENGINE              41
+#define CLK_MM_DPI1_PIXEL              42
+#define CLK_MM_DPI1_ENGINE             43
+#define CLK_MM_HDMI_PIXEL              44
+#define CLK_MM_HDMI_PLLCK              45
+#define CLK_MM_HDMI_AUDIO              46
+#define CLK_MM_HDMI_SPDIF              47
+#define CLK_MM_LVDS_PIXEL              48
+#define CLK_MM_LVDS_CTS                        49
+#define CLK_MM_SMI_LARB4               50
+#define CLK_MM_HDMI_HDCP               51
+#define CLK_MM_HDMI_HDCP24M            52
+#define CLK_MM_NR_CLK                  53
+
+/* VDEC_SYS */
+
+#define CLK_VDEC_CKEN                  1
+#define CLK_VDEC_LARB_CKEN             2
+#define CLK_VDEC_NR_CLK                        3
+
+/* VENC_SYS */
+
+#define CLK_VENC_CKE0                  1
+#define CLK_VENC_CKE1                  2
+#define CLK_VENC_CKE2                  3
+#define CLK_VENC_CKE3                  4
+#define CLK_VENC_NR_CLK                        5
+
+/* VENCLT_SYS */
+
+#define CLK_VENCLT_CKE0                        1
+#define CLK_VENCLT_CKE1                        2
+#define CLK_VENCLT_NR_CLK              3
+
 #endif /* _DT_BINDINGS_CLK_MT8173_H */
index 2c0da566c46adc450dd237523ff5d4c80a286df3..5aa7ebeae411091ef5c073d4c91651242fc723c3 100644 (file)
 #define GCC_PCIE_1_PIPE_CLK                            331
 #define GCC_PCIE_1_SLV_AXI_CLK                         332
 
+/* gdscs */
+#define USB_HS_HSIC_GDSC                               0
+#define PCIE0_GDSC                                     1
+#define PCIE1_GDSC                                     2
+#define USB30_GDSC                                     3
+
 #endif
index e430f644dd6cd679138f1bb1e5500cabfa0550fd..257e2fbedd9466ff19d25169e394a847a5e5755b 100644 (file)
 #define GCC_VENUS0_AHB_CLK                     135
 #define GCC_VENUS0_AXI_CLK                     136
 #define GCC_VENUS0_VCODEC0_CLK                 137
+#define BIMC_DDR_CLK_SRC                       138
+#define GCC_APSS_TCU_CLK                       139
+#define GCC_GFX_TCU_CLK                                140
+#define BIMC_GPU_CLK_SRC                       141
+#define GCC_BIMC_GFX_CLK                       142
+#define GCC_BIMC_GPU_CLK                       143
+#define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC         144
+#define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC         145
+#define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC         146
+#define ULTAUDIO_XO_CLK_SRC                    147
+#define ULTAUDIO_AHBFABRIC_CLK_SRC             148
+#define CODEC_DIGCODEC_CLK_SRC                 149
+#define GCC_ULTAUDIO_PCNOC_MPORT_CLK           150
+#define GCC_ULTAUDIO_PCNOC_SWAY_CLK            151
+#define GCC_ULTAUDIO_AVSYNC_XO_CLK             152
+#define GCC_ULTAUDIO_STC_XO_CLK                        153
+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK    154
+#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK        155
+#define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK         156
+#define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK         157
+#define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK         158
+#define GCC_CODEC_DIGCODEC_CLK                 159
+
+/* Indexes for GDSCs */
+#define BIMC_GDSC                              0
+#define VENUS_GDSC                             1
+#define MDSS_GDSC                              2
+#define JPEG_GDSC                              3
+#define VFE_GDSC                               4
+#define OXILI_GDSC                             5
 
 #endif
index 51e51c860fe674b4e50532cccdbff3a6411e1220..81d32f63919007403ae576e15dfb87a70c23f9cd 100644 (file)
 #define GCC_SDCC1_CDCCAL_SLEEP_CLK                             304
 #define GCC_SDCC1_CDCCAL_FF_CLK                                        305
 
+/* gdscs */
+#define USB_HS_HSIC_GDSC                                       0
+
 #endif
index d72b5b35f15edd965b89de2c4759bd9bc964f14f..03861e3f498ef480840f0d860be9d33535f0410a 100644 (file)
 #define VPU_SLEEP_CLK                  163
 #define VPU_VDP_CLK                    164
 
+/* GDSCs */
+#define VENUS0_GDSC                    0
+#define VENUS0_CORE0_GDSC              1
+#define VENUS0_CORE1_GDSC              2
+#define MDSS_GDSC                      3
+#define CAMSS_JPEG_GDSC                        4
+#define CAMSS_VFE_GDSC                 5
+#define OXILI_GDSC                     6
+#define OXILICX_GDSC                   7
+
 #endif
index 032ed87ef0f332afbe94f79ae3b982f060a181ce..28651e54c9aeeb8a1b41ad025e69aeb4cc04a4c1 100644 (file)
 #define SPDM_RM_AXI                                    141
 #define SPDM_RM_OCMEMNOC                               142
 
+/* gdscs */
+#define VENUS0_GDSC                                    0
+#define MDSS_GDSC                                      1
+#define CAMSS_JPEG_GDSC                                        2
+#define CAMSS_VFE_GDSC                                 3
+#define OXILI_GDSC                                     4
+#define OXILICX_GDSC                                   5
+
 #endif
diff --git a/include/dt-bindings/clock/r8a7795-cpg-mssr.h b/include/dt-bindings/clock/r8a7795-cpg-mssr.h
new file mode 100644 (file)
index 0000000..e864aae
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__
+
+#include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+/* r8a7795 CPG Core Clocks */
+#define R8A7795_CLK_Z                  0
+#define R8A7795_CLK_Z2                 1
+#define R8A7795_CLK_ZR                 2
+#define R8A7795_CLK_ZG                 3
+#define R8A7795_CLK_ZTR                        4
+#define R8A7795_CLK_ZTRD2              5
+#define R8A7795_CLK_ZT                 6
+#define R8A7795_CLK_ZX                 7
+#define R8A7795_CLK_S0D1               8
+#define R8A7795_CLK_S0D4               9
+#define R8A7795_CLK_S1D1               10
+#define R8A7795_CLK_S1D2               11
+#define R8A7795_CLK_S1D4               12
+#define R8A7795_CLK_S2D1               13
+#define R8A7795_CLK_S2D2               14
+#define R8A7795_CLK_S2D4               15
+#define R8A7795_CLK_S3D1               16
+#define R8A7795_CLK_S3D2               17
+#define R8A7795_CLK_S3D4               18
+#define R8A7795_CLK_LB                 19
+#define R8A7795_CLK_CL                 20
+#define R8A7795_CLK_ZB3                        21
+#define R8A7795_CLK_ZB3D2              22
+#define R8A7795_CLK_CR                 23
+#define R8A7795_CLK_CRD2               24
+#define R8A7795_CLK_SD0H               25
+#define R8A7795_CLK_SD0                        26
+#define R8A7795_CLK_SD1H               27
+#define R8A7795_CLK_SD1                        28
+#define R8A7795_CLK_SD2H               29
+#define R8A7795_CLK_SD2                        30
+#define R8A7795_CLK_SD3H               31
+#define R8A7795_CLK_SD3                        32
+#define R8A7795_CLK_SSP2               33
+#define R8A7795_CLK_SSP1               34
+#define R8A7795_CLK_SSPRS              35
+#define R8A7795_CLK_RPC                        36
+#define R8A7795_CLK_RPCD2              37
+#define R8A7795_CLK_MSO                        38
+#define R8A7795_CLK_CANFD              39
+#define R8A7795_CLK_HDMI               40
+#define R8A7795_CLK_CSI0               41
+#define R8A7795_CLK_CSIREF             42
+#define R8A7795_CLK_CP                 43
+#define R8A7795_CLK_CPEX               44
+#define R8A7795_CLK_R                  45
+#define R8A7795_CLK_OSC                        46
+
+#endif /* __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/renesas-cpg-mssr.h b/include/dt-bindings/clock/renesas-cpg-mssr.h
new file mode 100644 (file)
index 0000000..569a3cc
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2015 Renesas Electronics Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__
+#define __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__
+
+#define CPG_CORE                       0       /* Core Clock */
+#define CPG_MOD                                1       /* Module Clock */
+
+#endif /* __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ */
index 6a7dfe33a317f44f459436ed55640383986f3cce..c56988ac63f7801d5a93b004b80c20f7089bf2e3 100644 (file)
@@ -500,13 +500,14 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
  *
  * Clock with adjustable fractional divider affecting its output frequency.
  */
-
 struct clk_fractional_divider {
        struct clk_hw   hw;
        void __iomem    *reg;
        u8              mshift;
+       u8              mwidth;
        u32             mmask;
        u8              nshift;
+       u8              nwidth;
        u32             nmask;
        u8              flags;
        spinlock_t      *lock;
@@ -553,13 +554,6 @@ struct clk_multiplier {
 
 extern const struct clk_ops clk_multiplier_ops;
 
-struct clk *clk_register_multiplier(struct device *dev, const char *name,
-                                   const char *parent_name,
-                                   unsigned long flags,
-                                   void __iomem *reg, u8 shift, u8 width,
-                                   u8 clk_mult_flags, spinlock_t *lock);
-void clk_unregister_multiplier(struct clk *clk);
-
 /***
  * struct clk_composite - aggregate clock of mux, divider and gate clocks
  *
@@ -648,7 +642,7 @@ void clk_unregister(struct clk *clk);
 void devm_clk_unregister(struct device *dev, struct clk *clk);
 
 /* helper functions */
-const char *__clk_get_name(struct clk *clk);
+const char *__clk_get_name(const struct clk *clk);
 const char *clk_hw_get_name(const struct clk_hw *hw);
 struct clk_hw *__clk_get_hw(struct clk *clk);
 unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
@@ -660,6 +654,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw);
 unsigned long __clk_get_flags(struct clk *clk);
 unsigned long clk_hw_get_flags(const struct clk_hw *hw);
 bool clk_hw_is_prepared(const struct clk_hw *hw);
+bool clk_hw_is_enabled(const struct clk_hw *hw);
 bool __clk_is_enabled(struct clk *clk);
 struct clk *__clk_lookup(const char *name);
 int __clk_mux_determine_rate(struct clk_hw *hw,
@@ -732,6 +727,15 @@ static inline struct clk *of_clk_src_onecell_get(
 {
        return ERR_PTR(-ENOENT);
 }
+static inline int of_clk_get_parent_count(struct device_node *np)
+{
+       return 0;
+}
+static inline int of_clk_parent_fill(struct device_node *np,
+                                    const char **parents, unsigned int size)
+{
+       return 0;
+}
 static inline const char *of_clk_get_parent_name(struct device_node *np,
                                                 int index)
 {
index 7669f7618f397be6e526d2e388f4b068c83f45c4..1e6932222e110df87c78ca499213fc42a577fc8a 100644 (file)
@@ -164,6 +164,7 @@ extern void __iomem *at91_pmc_base;
 #define                AT91_PMC_MOSCSELS       (1 << 16)               /* Main Oscillator Selection [some SAM9] */
 #define                AT91_PMC_MOSCRCS        (1 << 17)               /* Main On-Chip RC [some SAM9] */
 #define                AT91_PMC_CFDEV          (1 << 18)               /* Clock Failure Detector Event [some SAM9] */
+#define                AT91_PMC_GCKRDY         (1 << 24)               /* Generated Clocks */
 #define        AT91_PMC_IMR            0x6c                    /* Interrupt Mask Register */
 
 #define AT91_PMC_PLLICPR       0x80                    /* PLL Charge Pump Current Register */
@@ -182,13 +183,18 @@ extern void __iomem *at91_pmc_base;
 #define AT91_PMC_PCSR1         0x108                   /* Peripheral Clock Enable Register 1 */
 
 #define AT91_PMC_PCR           0x10c                   /* Peripheral Control Register [some SAM9 and SAMA5] */
-#define                AT91_PMC_PCR_PID        (0x3f  <<  0)           /* Peripheral ID */
-#define                AT91_PMC_PCR_CMD        (0x1  <<  12)           /* Command (read=0, write=1) */
-#define                AT91_PMC_PCR_DIV(n)     ((n)  <<  16)           /* Divisor Value */
-#define                        AT91_PMC_PCR_DIV0       0x0                     /* Peripheral clock is MCK */
-#define                        AT91_PMC_PCR_DIV2       0x1                     /* Peripheral clock is MCK/2 */
-#define                        AT91_PMC_PCR_DIV4       0x2                     /* Peripheral clock is MCK/4 */
-#define                        AT91_PMC_PCR_DIV8       0x3                     /* Peripheral clock is MCK/8 */
-#define                AT91_PMC_PCR_EN         (0x1  <<  28)           /* Enable */
+#define                AT91_PMC_PCR_PID_MASK           0x3f
+#define                AT91_PMC_PCR_GCKCSS_OFFSET      8
+#define                AT91_PMC_PCR_GCKCSS_MASK        (0x7  << AT91_PMC_PCR_GCKCSS_OFFSET)
+#define                AT91_PMC_PCR_GCKCSS(n)          ((n)  << AT91_PMC_PCR_GCKCSS_OFFSET)    /* GCK Clock Source Selection */
+#define                AT91_PMC_PCR_CMD                (0x1  <<  12)                           /* Command (read=0, write=1) */
+#define                AT91_PMC_PCR_DIV_OFFSET         16
+#define                AT91_PMC_PCR_DIV_MASK           (0x3  << AT91_PMC_PCR_DIV_OFFSET)
+#define                AT91_PMC_PCR_DIV(n)             ((n)  << AT91_PMC_PCR_DIV_OFFSET)       /* Divisor Value */
+#define                AT91_PMC_PCR_GCKDIV_OFFSET      20
+#define                AT91_PMC_PCR_GCKDIV_MASK        (0xff  << AT91_PMC_PCR_GCKDIV_OFFSET)
+#define                AT91_PMC_PCR_GCKDIV(n)          ((n)  << AT91_PMC_PCR_GCKDIV_OFFSET)    /* Generated Clock Divisor Value */
+#define                AT91_PMC_PCR_EN                 (0x1  <<  28)                           /* Enable */
+#define                AT91_PMC_PCR_GCKEN              (0x1  <<  29)                           /* GCK Enable */
 
 #endif