diff options
111 files changed, 5971 insertions, 1131 deletions
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt index 936166fbee09..cb0054ac7121 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt @@ -5,7 +5,8 @@ The Mediatek apmixedsys controller provides the PLLs to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-apmixedsys" - "mediatek,mt8135-apmixedsys" - "mediatek,mt8173-apmixedsys" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt new file mode 100644 index 000000000000..4137196dd686 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,bdpsys.txt @@ -0,0 +1,22 @@ +Mediatek bdpsys controller +============================ + +The Mediatek bdpsys controller provides various clocks to the system. + +Required Properties: + +- compatible: Should be: + - "mediatek,mt2701-bdpsys", "syscon" +- #clock-cells: Must be 1 + +The bdpsys controller uses the common clk binding from +Documentation/devicetree/bindings/clock/clock-bindings.txt +The available clocks are defined in dt-bindings/clock/mt*-clk.h. + +Example: + +bdpsys: clock-controller@1c000000 { + compatible = "mediatek,mt2701-bdpsys", "syscon"; + reg = <0 0x1c000000 0 0x1000>; + #clock-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt new file mode 100644 index 000000000000..768f3a5bc055 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt @@ -0,0 +1,22 @@ +Mediatek ethsys controller +============================ + +The Mediatek ethsys controller provides various clocks to the system. + +Required Properties: + +- compatible: Should be: + - "mediatek,mt2701-ethsys", "syscon" +- #clock-cells: Must be 1 + +The ethsys controller uses the common clk binding from +Documentation/devicetree/bindings/clock/clock-bindings.txt +The available clocks are defined in dt-bindings/clock/mt*-clk.h. + +Example: + +ethsys: clock-controller@1b000000 { + compatible = "mediatek,mt2701-ethsys", "syscon"; + reg = <0 0x1b000000 0 0x1000>; + #clock-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt new file mode 100644 index 000000000000..beed7b594cea --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,hifsys.txt @@ -0,0 +1,24 @@ +Mediatek hifsys controller +============================ + +The Mediatek hifsys controller provides various clocks and reset +outputs to the system. + +Required Properties: + +- compatible: Should be: + - "mediatek,mt2701-hifsys", "syscon" +- #clock-cells: Must be 1 + +The hifsys controller uses the common clk binding from +Documentation/devicetree/bindings/clock/clock-bindings.txt +The available clocks are defined in dt-bindings/clock/mt*-clk.h. + +Example: + +hifsys: clock-controller@1a000000 { + compatible = "mediatek,mt2701-hifsys", "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt index b1f2ce17dff8..f6a916686f4c 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt @@ -5,7 +5,8 @@ The Mediatek imgsys controller provides various clocks to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-imgsys", "syscon" - "mediatek,mt8173-imgsys", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt index aaf8d1460c4d..1620ec2a5a3f 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt @@ -6,7 +6,8 @@ outputs to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-infracfg", "syscon" - "mediatek,mt8135-infracfg", "syscon" - "mediatek,mt8173-infracfg", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt index 4385946eadef..67dd2e473d25 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt @@ -5,7 +5,8 @@ The Mediatek mmsys controller provides various clocks to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-mmsys", "syscon" - "mediatek,mt8173-mmsys", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt index 2f6ff86df49f..e494366782aa 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt @@ -6,7 +6,8 @@ outputs to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-pericfg", "syscon" - "mediatek,mt8135-pericfg", "syscon" - "mediatek,mt8173-pericfg", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt index f9e917994ced..9f2fe7860114 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt @@ -5,7 +5,8 @@ The Mediatek topckgen controller provides various clocks to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-topckgen" - "mediatek,mt8135-topckgen" - "mediatek,mt8173-topckgen" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt index 1faacf1c1b25..2440f73450c3 100644 --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt @@ -5,7 +5,8 @@ The Mediatek vdecsys controller provides various clocks to the system. Required Properties: -- compatible: Should be: +- compatible: Should be one of: + - "mediatek,mt2701-vdecsys", "syscon" - "mediatek,mt8173-vdecsys", "syscon" - #clock-cells: Must be 1 diff --git a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt index 8b7177cecb36..27468119fd94 100644 --- a/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt +++ b/Documentation/devicetree/bindings/clock/arm-syscon-icst.txt @@ -5,20 +5,50 @@ Technology (IDT). ARM integrated these oscillators deeply into their reference designs by adding special control registers that manage such oscillators to their system controllers. -The ARM system controller contains logic to serialize and initialize +The various ARM system controllers contain logic to serialize and initialize an ICST clock request after a write to the 32 bit register at an offset into the system controller. Furthermore, to even be able to alter one of these frequencies, the system controller must first be unlocked by writing a special token to another offset in the system controller. +Some ARM hardware contain special versions of the serial interface that only +connects the low 8 bits of the VDW (missing one bit), hardwires RDW to +different values and sometimes also hardwire the output divider. They +therefore have special compatible strings as per this table (the OD value is +the value on the pins, not the resulting output divider): + +Hardware variant: RDW OD VDW + +Integrator/AP 22 1 Bit 8 0, rest variable +integratorap-cm + +Integrator/AP 46 3 Bit 8 0, rest variable +integratorap-sys + +Integrator/AP 22 or 1 17 or (33 or 25 MHz) +integratorap-pci 14 1 14 + +Integrator/CP 22 variable Bit 8 0, rest variable +integratorcp-cm-core + +Integrator/CP 22 variable Bit 8 0, rest variable +integratorcp-cm-mem + The ICST oscillator must be provided inside a system controller node. Required properties: +- compatible: must be one of + "arm,syscon-icst525" + "arm,syscon-icst307" + "arm,syscon-icst525-integratorap-cm" + "arm,syscon-icst525-integratorap-sys" + "arm,syscon-icst525-integratorap-pci" + "arm,syscon-icst525-integratorcp-cm-core" + "arm,syscon-icst525-integratorcp-cm-mem" - lock-offset: the offset address into the system controller where the unlocking register is located - vco-offset: the offset address into the system controller where the ICST control register is located (even 32 bit address) -- compatible: must be one of "arm,syscon-icst525" or "arm,syscon-icst307" - #clock-cells: must be <0> - clocks: parent clock, since the ICST needs a parent clock to derive its frequency from, this attribute is compulsory. diff --git a/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt new file mode 100644 index 000000000000..1e3370ba189f --- /dev/null +++ b/Documentation/devicetree/bindings/clock/armada3700-periph-clock.txt @@ -0,0 +1,70 @@ +* Peripheral Clock bindings for Marvell Armada 37xx SoCs + +Marvell Armada 37xx SoCs provide peripheral clocks which are +used as clock source for the peripheral of the SoC. + +There are two different blocks associated to north bridge and south +bridge. + +The peripheral clock consumer should specify the desired clock by +having the clock ID in its "clocks" phandle cell. + +The following is a list of provided IDs for Armada 370 North bridge clocks: +ID Clock name Description +----------------------------------- +0 mmc MMC controller +1 sata_host Sata Host +2 sec_at Security AT +3 sac_dap Security DAP +4 tsecm Security Engine +5 setm_tmx Serial Embedded Trace Module +6 avs Adaptive Voltage Scaling +7 sqf SPI +8 pwm PWM +9 i2c_2 I2C 2 +10 i2c_1 I2C 1 +11 ddr_phy DDR PHY +12 ddr_fclk DDR F clock +13 trace Trace +14 counter Counter +15 eip97 EIP 97 +16 cpu CPU + +The following is a list of provided IDs for Armada 370 South bridge clocks: +ID Clock name Description +----------------------------------- +0 gbe-50 50 MHz parent clock for Gigabit Ethernet +1 gbe-core parent clock for Gigabit Ethernet core +2 gbe-125 125 MHz parent clock for Gigabit Ethernet +3 gbe1-50 50 MHz clock for Gigabit Ethernet port 1 +4 gbe0-50 50 MHz clock for Gigabit Ethernet port 0 +5 gbe1-125 125 MHz clock for Gigabit Ethernet port 1 +6 gbe0-125 125 MHz clock for Gigabit Ethernet port 0 +7 gbe1-core Gigabit Ethernet core port 1 +8 gbe0-core Gigabit Ethernet core port 0 +9 gbe-bm Gigabit Ethernet Buffer Manager +10 sdio SDIO +11 usb32-sub2-sys USB 2 clock +12 usb32-ss-sys USB 3 clock + +Required properties: + +- compatible : shall be "marvell,armada-3700-periph-clock-nb" for the + north bridge block, or + "marvell,armada-3700-periph-clock-sb" for the south bridge block +- reg : must be the register address of North/South Bridge Clock register +- #clock-cells : from common clock binding; shall be set to 1 + +- clocks : list of the parent clock phandle in the following order: + TBG-A P, TBG-B P, TBG-A S, TBG-B S and finally the xtal clock. + + +Example: + +nb_perih_clk: nb-periph-clk@13000{ + compatible = "marvell,armada-3700-periph-clock-nb"; + reg = <0x13000 0x1000>; + clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, + <&tbg 3>, <&xtalclk>; + #clock-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt new file mode 100644 index 000000000000..0ba1d83ff363 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/armada3700-tbg-clock.txt @@ -0,0 +1,27 @@ +* Time Base Generator Clock bindings for Marvell Armada 37xx SoCs + +Marvell Armada 37xx SoCs provde Time Base Generator clocks which are +used as parent clocks for the peripheral clocks. + +The TBG clock consumer should specify the desired clock by having the +clock ID in its "clocks" phandle cell. + +The following is a list of provided IDs and clock names on Armada 3700: + 0 = TBG A P + 1 = TBG B P + 2 = TBG A S + 3 = TBG B S + +Required properties: +- compatible : shall be "marvell,armada-3700-tbg-clock" +- reg : must be the register address of North Bridge PLL register +- #clock-cells : from common clock binding; shall be set to 1 + +Example: + +tbg: tbg@13200 { + compatible = "marvell,armada-3700-tbg-clock"; + reg = <0x13200 0x1000>; + clocks = <&xtalclk>; + #clock-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt b/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt new file mode 100644 index 000000000000..a88f1f05fbd6 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/armada3700-xtal-clock.txt @@ -0,0 +1,28 @@ +* Xtal Clock bindings for Marvell Armada 37xx SoCs + +Marvell Armada 37xx SoCs allow to determine the xtal clock frequencies by +reading the gpio latch register. + +This node must be a subnode of the node exposing the register address +of the GPIO block where the gpio latch is located. + +Required properties: +- compatible : shall be one of the following: + "marvell,armada-3700-xtal-clock" +- #clock-cells : from common clock binding; shall be set to 0 + +Optional properties: +- clock-output-names : from common clock binding; allows overwrite default clock + output names ("xtal") + +Example: +gpio1: gpio@13800 { + compatible = "marvell,armada-3700-gpio", "syscon", "simple-mfd"; + reg = <0x13800 0x1000>; + + xtalclk: xtal-clk { + compatible = "marvell,armada-3700-xtal-clock"; + clock-output-names = "xtal"; + #clock-cells = <0>; + }; +}; diff --git a/Documentation/devicetree/bindings/clock/maxim,max77686.txt b/Documentation/devicetree/bindings/clock/maxim,max77686.txt index 9c40739a661a..8398a3a5e106 100644 --- a/Documentation/devicetree/bindings/clock/maxim,max77686.txt +++ b/Documentation/devicetree/bindings/clock/maxim,max77686.txt @@ -1,10 +1,24 @@ -Binding for Maxim MAX77686 32k clock generator block +Binding for Maxim MAX77686/MAX77802/MAX77620 32k clock generator block -This is a part of device tree bindings of MAX77686 multi-function device. -More information can be found in bindings/mfd/max77686.txt file. +This is a part of device tree bindings of MAX77686/MAX77802/MAX77620 +multi-function device. More information can be found in MFD DT binding +doc as follows: + bindings/mfd/max77686.txt for MAX77686 and + bindings/mfd/max77802.txt for MAX77802 and + bindings/mfd/max77620.txt for MAX77620. The MAX77686 contains three 32.768khz clock outputs that can be controlled -(gated/ungated) over I2C. +(gated/ungated) over I2C. Clocks are defined as preprocessor macros in +dt-bindings/clock/maxim,max77686.h. + + +The MAX77802 contains two 32.768khz clock outputs that can be controlled +(gated/ungated) over I2C. Clocks are defined as preprocessor macros in +dt-bindings/clock/maxim,max77802.h. + +The MAX77686 contains one 32.768khz clock outputs that can be controlled +(gated/ungated) over I2C. Clocks are defined as preprocessor macros in +dt-bindings/clock/maxim,max77620.h. Following properties should be presend in main device node of the MFD chip. @@ -17,30 +31,84 @@ Optional properties: Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. Following indices are allowed: - - 0: 32khz_ap clock, - - 1: 32khz_cp clock, - - 2: 32khz_pmic clock. + - 0: 32khz_ap clock (max77686, max77802), 32khz_out0 (max77620) + - 1: 32khz_cp clock (max77686, max77802), + - 2: 32khz_pmic clock (max77686). + +Clocks are defined as preprocessor macros in above dt-binding header for +respective chips. + +Example: + +1. With MAX77686: + +#include <dt-bindings/clock/maxim,max77686.h> +/* ... */ + + Node of the MFD chip + max77686: max77686@09 { + compatible = "maxim,max77686"; + interrupt-parent = <&wakeup_eint>; + interrupts = <26 0>; + reg = <0x09>; + #clock-cells = <1>; + + /* ... */ + }; + + Clock consumer node + + foo@0 { + compatible = "bar,foo"; + /* ... */ + clock-names = "my-clock"; + clocks = <&max77686 MAX77686_CLK_PMIC>; + }; + +2. With MAX77802: + +#include <dt-bindings/clock/maxim,max77802.h> +/* ... */ + + Node of the MFD chip + max77802: max77802@09 { + compatible = "maxim,max77802"; + interrupt-parent = <&wakeup_eint>; + interrupts = <26 0>; + reg = <0x09>; + #clock-cells = <1>; + + /* ... */ + }; + + Clock consumer node + + foo@0 { + compatible = "bar,foo"; + /* ... */ + clock-names = "my-clock"; + clocks = <&max77802 MAX77802_CLK_32K_AP>; + }; -Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77686.h -header and can be used in device tree sources. -Example: Node of the MFD chip +3. With MAX77620: - max77686: max77686@09 { - compatible = "maxim,max77686"; - interrupt-parent = <&wakeup_eint>; - interrupts = <26 0>; - reg = <0x09>; - #clock-cells = <1>; +#include <dt-bindings/clock/maxim,max77620.h> +/* ... */ - /* ... */ - }; + Node of the MFD chip + max77620: max77620@3c { + compatible = "maxim,max77620"; + reg = <0x3c>; + #clock-cells = <1>; + /* ... */ + }; -Example: Clock consumer node + Clock consumer node - foo@0 { - compatible = "bar,foo"; - /* ... */ - clock-names = "my-clock"; - clocks = <&max77686 MAX77686_CLK_PMIC>; - }; + foo@0 { + compatible = "bar,foo"; + /* ... */ + clock-names = "my-clock"; + clocks = <&max77620 MAX77620_CLK_32K_OUT0>; + }; diff --git a/Documentation/devicetree/bindings/clock/maxim,max77802.txt b/Documentation/devicetree/bindings/clock/maxim,max77802.txt deleted file mode 100644 index c6dc7835f06c..000000000000 --- a/Documentation/devicetree/bindings/clock/maxim,max77802.txt +++ /dev/null @@ -1,44 +0,0 @@ -Binding for Maxim MAX77802 32k clock generator block - -This is a part of device tree bindings of MAX77802 multi-function device. -More information can be found in bindings/mfd/max77802.txt file. - -The MAX77802 contains two 32.768khz clock outputs that can be controlled -(gated/ungated) over I2C. - -Following properties should be present in main device node of the MFD chip. - -Required properties: -- #clock-cells: From common clock binding; shall be set to 1. - -Optional properties: -- clock-output-names: From common clock binding. - -Each clock is assigned an identifier and client nodes can use this identifier -to specify the clock which they consume. Following indices are allowed: - - 0: 32khz_ap clock, - - 1: 32khz_cp clock. - -Clocks are defined as preprocessor macros in dt-bindings/clock/maxim,max77802.h -header and can be used in device tree sources. - -Example: Node of the MFD chip - - max77802: max77802@09 { - compatible = "maxim,max77802"; - interrupt-parent = <&wakeup_eint>; - interrupts = <26 0>; - reg = <0x09>; - #clock-cells = <1>; - - /* ... */ - }; - -Example: Clock consumer node - - foo@0 { - compatible = "bar,foo"; - /* ... */ - clock-names = "my-clock"; - clocks = <&max77802 MAX77802_CLK_32K_AP>; - }; diff --git a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt index 660e64912cce..cb8542d910b3 100644 --- a/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt +++ b/Documentation/devicetree/bindings/clock/mvebu-gated-clock.txt @@ -86,6 +86,8 @@ ID Clock Peripheral 7 pex3 PCIe 3 8 pex0 PCIe 0 9 usb3h0 USB3 Host 0 +10 usb3h1 USB3 Host 1 +15 sata0 SATA 0 17 sdio SDIO 22 xor0 XOR 0 28 xor1 XOR 1 diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 9a60fde32b02..869a2f0e2ff6 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -15,6 +15,7 @@ Required properties : "qcom,gcc-msm8974pro" "qcom,gcc-msm8974pro-ac" "qcom,gcc-msm8996" + "qcom,gcc-mdm9615" - reg : shall contain base register location and length - #clock-cells : shall contain 1 diff --git a/Documentation/devicetree/bindings/clock/qcom,lcc.txt b/Documentation/devicetree/bindings/clock/qcom,lcc.txt index dd755be63a01..a3c78aa88038 100644 --- a/Documentation/devicetree/bindings/clock/qcom,lcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,lcc.txt @@ -7,6 +7,7 @@ Required properties : "qcom,lcc-msm8960" "qcom,lcc-apq8064" "qcom,lcc-ipq8064" + "qcom,lcc-mdm9615" - reg : shall contain base register location and length - #clock-cells : shall contain 1 diff --git a/MAINTAINERS b/MAINTAINERS index 20bb1d00098c..5436d3addce9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3150,6 +3150,7 @@ COMMON CLK FRAMEWORK M: Michael Turquette <mturquette@baylibre.com> M: Stephen Boyd <sboyd@codeaurora.org> L: linux-clk@vger.kernel.org +Q: http://patchwork.kernel.org/project/linux-clk/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git S: Maintained F: Documentation/devicetree/bindings/clock/ diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e2d9bd760c84..bf7d540d6965 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -31,22 +31,12 @@ config COMMON_CLK_WM831X source "drivers/clk/versatile/Kconfig" -config COMMON_CLK_MAX_GEN - bool - config COMMON_CLK_MAX77686 - tristate "Clock driver for Maxim 77686 MFD" - depends on MFD_MAX77686 - select COMMON_CLK_MAX_GEN - ---help--- - This driver supports Maxim 77686 crystal oscillator clock. - -config COMMON_CLK_MAX77802 - tristate "Clock driver for Maxim 77802 PMIC" - depends on MFD_MAX77686 - select COMMON_CLK_MAX_GEN + tristate "Clock driver for Maxim 77620/77686/77802 MFD" + depends on MFD_MAX77686 || MFD_MAX77620 ---help--- - This driver supports Maxim 77802 crystal oscillator clock. + This driver supports Maxim 77620/77686/77802 crystal oscillator + clock. config COMMON_CLK_RK808 tristate "Clock driver for RK808/RK818" @@ -210,6 +200,7 @@ config COMMON_CLK_OXNAS source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" +source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/qcom/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 3b6f9cf3464a..e775a836247c 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -27,9 +27,7 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o -obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o -obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o diff --git a/drivers/clk/axis/clk-artpec6.c b/drivers/clk/axis/clk-artpec6.c index ffc988b098e4..da1a073c2236 100644 --- a/drivers/clk/axis/clk-artpec6.c +++ b/drivers/clk/axis/clk-artpec6.c @@ -113,8 +113,8 @@ static void of_artpec6_clkctrl_setup(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data); } -CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl", - of_artpec6_clkctrl_setup); +CLK_OF_DECLARE_DRIVER(artpec6_clkctrl, "axis,artpec6-clkctrl", + of_artpec6_clkctrl_setup); static int artpec6_clkctrl_probe(struct platform_device *pdev) { diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index 526b0b0e9a9f..f2359b3b73bc 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c @@ -696,77 +696,69 @@ static void bcm_clk_teardown(struct kona_clk *bcm_clk) bcm_clk->type = bcm_clk_none; } -static void kona_clk_teardown(struct clk *clk) +static void kona_clk_teardown(struct clk_hw *hw) { - struct clk_hw *hw; struct kona_clk *bcm_clk; - if (!clk) + if (!hw) return; - hw = __clk_get_hw(clk); - if (!hw) { - pr_err("%s: clk %p has null hw pointer\n", __func__, clk); - return; - } - clk_unregister(clk); + clk_hw_unregister(hw); bcm_clk = to_kona_clk(hw); bcm_clk_teardown(bcm_clk); } -struct clk *kona_clk_setup(struct kona_clk *bcm_clk) +static int kona_clk_setup(struct kona_clk *bcm_clk) { + int ret; struct clk_init_data *init_data = &bcm_clk->init_data; - struct clk *clk = NULL; switch (bcm_clk->type) { case bcm_clk_peri: - if (peri_clk_setup(bcm_clk->u.data, init_data)) - return NULL; + ret = peri_clk_setup(bcm_clk->u.data, init_data); + if (ret) + return ret; break; default: pr_err("%s: clock type %d invalid for %s\n", __func__, (int)bcm_clk->type, init_data->name); - return NULL; + return -EINVAL; } /* Make sure everything makes sense before we set it up */ if (!kona_clk_valid(bcm_clk)) { pr_err("%s: clock data invalid for %s\n", __func__, init_data->name); + ret = -EINVAL; goto out_teardown; } bcm_clk->hw.init = init_data; - clk = clk_register(NULL, &bcm_clk->hw); - if (IS_ERR(clk)) { - pr_err("%s: error registering clock %s (%ld)\n", __func__, - init_data->name, PTR_ERR(clk)); + ret = clk_hw_register(NULL, &bcm_clk->hw); + if (ret) { + pr_err("%s: error registering clock %s (%d)\n", __func__, + init_data->name, ret); goto out_teardown; } - BUG_ON(!clk); - return clk; + return 0; out_teardown: bcm_clk_teardown(bcm_clk); - return NULL; + return ret; } static void ccu_clks_teardown(struct ccu_data *ccu) { u32 i; - for (i = 0; i < ccu->clk_data.clk_num; i++) - kona_clk_teardown(ccu->clk_data.clks[i]); - kfree(ccu->clk_data.clks); + for (i = 0; i < ccu->clk_num; i++) + kona_clk_teardown(&ccu->kona_clks[i].hw); } static void kona_ccu_teardown(struct ccu_data *ccu) { - kfree(ccu->clk_data.clks); - ccu->clk_data.clks = NULL; if (!ccu->base) return; @@ -793,6 +785,20 @@ static bool ccu_data_valid(struct ccu_data *ccu) return true; } +static struct clk_hw * +of_clk_kona_onecell_get(struct of_phandle_args *clkspec, void *data) +{ + struct ccu_data *ccu = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= ccu->clk_num) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &ccu->kona_clks[idx].hw; +} + /* * Set up a CCU. Call the provided ccu_clks_setup callback to * initialize the array of clocks provided by the CCU. @@ -805,18 +811,6 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, unsigned int i; int ret; - if (ccu->clk_data.clk_num) { - size_t size; - - size = ccu->clk_data.clk_num * sizeof(*ccu->clk_data.clks); - ccu->clk_data.clks = kzalloc(size, GFP_KERNEL); - if (!ccu->clk_data.clks) { - pr_err("%s: unable to allocate %u clocks for %s\n", - __func__, ccu->clk_data.clk_num, node->name); - return; - } - } - ret = of_address_to_resource(node, 0, &res); if (ret) { pr_err("%s: no valid CCU registers found for %s\n", __func__, @@ -851,13 +845,13 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, * the clock framework clock array (in ccu->data). Then * register as a provider for these clocks. */ - for (i = 0; i < ccu->clk_data.clk_num; i++) { + for (i = 0; i < ccu->clk_num; i++) { if (!ccu->kona_clks[i].ccu) continue; - ccu->clk_data.clks[i] = kona_clk_setup(&ccu->kona_clks[i]); + kona_clk_setup(&ccu->kona_clks[i]); } - ret = of_clk_add_provider(node, of_clk_src_onecell_get, &ccu->clk_data); + ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu); if (ret) { pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, node->name, ret); diff --git a/drivers/clk/bcm/clk-kona.c b/drivers/clk/bcm/clk-kona.c index 3a15347b4233..eee64b9e5d10 100644 --- a/drivers/clk/bcm/clk-kona.c +++ b/drivers/clk/bcm/clk-kona.c @@ -1256,19 +1256,18 @@ bool __init kona_ccu_init(struct ccu_data *ccu) { unsigned long flags; unsigned int which; - struct clk **clks = ccu->clk_data.clks; struct kona_clk *kona_clks = ccu->kona_clks; bool success = true; flags = ccu_lock(ccu); __ccu_write_enable(ccu); - for (which = 0; which < ccu->clk_data.clk_num; which++) { - struct kona_clk *bcm_clk; + for (which = 0; which < ccu->clk_num; which++) { + struct kona_clk *bcm_clk = &kona_clks[which]; - if (!clks[which]) + if (!bcm_clk->ccu) continue; - bcm_clk = &kona_clks[which]; + success &= __kona_clk_init(bcm_clk); } diff --git a/drivers/clk/bcm/clk-kona.h b/drivers/clk/bcm/clk-kona.h index 906576ec97b6..f4b39bb5558a 100644 --- a/drivers/clk/bcm/clk-kona.h +++ b/drivers/clk/bcm/clk-kona.h @@ -481,7 +481,7 @@ struct ccu_data { bool write_enabled; /* write access is currently enabled */ struct ccu_policy policy; struct device_node *node; - struct clk_onecell_data clk_data; + size_t clk_num; const char *name; u32 range; /* byte range of address space */ struct kona_clk kona_clks[]; /* must be last */ @@ -491,9 +491,7 @@ struct ccu_data { #define KONA_CCU_COMMON(_prefix, _name, _ccuname) \ .name = #_name "_ccu", \ .lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \ - .clk_data = { \ - .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \ - } + .clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT /* Exported globals */ @@ -505,7 +503,6 @@ extern u64 scaled_div_max(struct bcm_clk_div *div); extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, u32 billionths); -extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk); extern void __init kona_dt_ccu_setup(struct ccu_data *ccu, struct device_node *node); extern bool __init kona_ccu_init(struct ccu_data *ccu); diff --git a/drivers/clk/berlin/berlin2-avpll.c b/drivers/clk/berlin/berlin2-avpll.c index fd0f26c38465..cfcae468e989 100644 --- a/drivers/clk/berlin/berlin2-avpll.c +++ b/drivers/clk/berlin/berlin2-avpll.c @@ -188,7 +188,7 @@ static const struct clk_ops berlin2_avpll_vco_ops = { .recalc_rate = berlin2_avpll_vco_recalc_rate, }; -struct clk * __init berlin2_avpll_vco_register(void __iomem *base, +int __init berlin2_avpll_vco_register(void __iomem *base, const char *name, const char *parent_name, u8 vco_flags, unsigned long flags) { @@ -197,7 +197,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base, vco = kzalloc(sizeof(*vco), GFP_KERNEL); if (!vco) - return ERR_PTR(-ENOMEM); + return -ENOMEM; vco->base = base; vco->flags = vco_flags; @@ -208,7 +208,7 @@ struct clk * __init berlin2_avpll_vco_register(void __iomem *base, init.num_parents = 1; init.flags = flags; - return clk_register(NULL, &vco->hw); + return clk_hw_register(NULL, &vco->hw); } struct berlin2_avpll_channel { @@ -364,7 +364,7 @@ static const struct clk_ops berlin2_avpll_channel_ops = { */ static const u8 quirk_index[] __initconst = { 0, 6, 5, 4, 3, 2, 1, 7 }; -struct clk * __init berlin2_avpll_channel_register(void __iomem *base, +int __init berlin2_avpll_channel_register(void __iomem *base, const char *name, u8 index, const char *parent_name, u8 ch_flags, unsigned long flags) { @@ -373,7 +373,7 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base, ch = kzalloc(sizeof(*ch), GFP_KERNEL); if (!ch) - return ERR_PTR(-ENOMEM); + return -ENOMEM; ch->base = base; if (ch_flags & BERLIN2_AVPLL_SCRAMBLE_QUIRK) @@ -389,5 +389,5 @@ struct clk * __init berlin2_avpll_channel_register(void __iomem *base, init.num_parents = 1; init.flags = flags; - return clk_register(NULL, &ch->hw); + return clk_hw_register(NULL, &ch->hw); } diff --git a/drivers/clk/berlin/berlin2-avpll.h b/drivers/clk/berlin/berlin2-avpll.h index a37f5068d299..17e311153b42 100644 --- a/drivers/clk/berlin/berlin2-avpll.h +++ b/drivers/clk/berlin/berlin2-avpll.h @@ -19,17 +19,13 @@ #ifndef __BERLIN2_AVPLL_H #define __BERLIN2_AVPLL_H -struct clk; - #define BERLIN2_AVPLL_BIT_QUIRK BIT(0) #define BERLIN2_AVPLL_SCRAMBLE_QUIRK BIT(1) -struct clk * __init -berlin2_avpll_vco_register(void __iomem *base, const char *name, +int berlin2_avpll_vco_register(void __iomem *base, const char *name, const char *parent_name, u8 vco_flags, unsigned long flags); -struct clk * __init -berlin2_avpll_channel_register(void __iomem *base, const char *name, +int berlin2_avpll_channel_register(void __iomem *base, const char *name, u8 index, const char *parent_name, u8 ch_flags, unsigned long flags); diff --git a/drivers/clk/berlin/berlin2-div.c b/drivers/clk/berlin/berlin2-div.c index 81ff97f8aa0b..41ab2d392c57 100644 --- a/drivers/clk/berlin/berlin2-div.c +++ b/drivers/clk/berlin/berlin2-div.c @@ -234,7 +234,7 @@ static const struct clk_ops berlin2_div_mux_ops = { .get_parent = berlin2_div_get_parent, }; -struct clk * __init +struct clk_hw * __init berlin2_div_register(const struct berlin2_div_map *map, void __iomem *base, const char *name, u8 div_flags, const char **parent_names, int num_parents, @@ -259,7 +259,7 @@ berlin2_div_register(const struct berlin2_div_map *map, if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0) mux_ops = NULL; - return clk_register_composite(NULL, name, parent_names, num_parents, + return clk_hw_register_composite(NULL, name, parent_names, num_parents, &div->hw, mux_ops, &div->hw, rate_ops, &div->hw, gate_ops, flags); } diff --git a/drivers/clk/berlin/berlin2-div.h b/drivers/clk/berlin/berlin2-div.h index 15e3384f3116..e835ddf8374a 100644 --- a/drivers/clk/berlin/berlin2-div.h +++ b/drivers/clk/berlin/berlin2-div.h @@ -19,7 +19,7 @@ #ifndef __BERLIN2_DIV_H #define __BERLIN2_DIV_H -struct clk; +struct clk_hw; #define BERLIN2_DIV_HAS_GATE BIT(0) #define BERLIN2_DIV_HAS_MUX BIT(1) @@ -80,7 +80,7 @@ struct berlin2_div_data { u8 div_flags; }; -struct clk * __init +struct clk_hw * berlin2_div_register(const struct berlin2_div_map *map, void __iomem *base, const char *name, u8 div_flags, const char **parent_names, int num_parents, diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c index 1c2294d3ba85..4ffbe80f6323 100644 --- a/drivers/clk/berlin/berlin2-pll.c +++ b/drivers/clk/berlin/berlin2-pll.c @@ -84,7 +84,7 @@ static const struct clk_ops berlin2_pll_ops = { .recalc_rate = berlin2_pll_recalc_rate, }; -struct clk * __init +int __init berlin2_pll_register(const struct berlin2_pll_map *map, void __iomem *base, const char *name, const char *parent_name, unsigned long flags) @@ -94,7 +94,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map, pll = kzalloc(sizeof(*pll), GFP_KERNEL); if (!pll) - return ERR_PTR(-ENOMEM); + return -ENOMEM; /* copy pll_map to allow __initconst */ memcpy(&pll->map, map, sizeof(*map)); @@ -106,5 +106,5 @@ berlin2_pll_register(const struct berlin2_pll_map *map, init.num_parents = 1; init.flags = flags; - return clk_register(NULL, &pll->hw); + return clk_hw_register(NULL, &pll->hw); } diff --git a/drivers/clk/berlin/berlin2-pll.h b/drivers/clk/berlin/berlin2-pll.h index 8831ce27ac1e..583e024b9bed 100644 --- a/drivers/clk/berlin/berlin2-pll.h +++ b/drivers/clk/berlin/berlin2-pll.h @@ -19,8 +19,6 @@ #ifndef __BERLIN2_PLL_H #define __BERLIN2_PLL_H -struct clk; - struct berlin2_pll_map { const u8 vcodiv[16]; u8 mult; @@ -29,9 +27,8 @@ struct berlin2_pll_map { u8 divsel_shift; }; -struct clk * __init -berlin2_pll_register(const struct berlin2_pll_map *map, - void __iomem *base, const char *name, - const char *parent_name, unsigned long flags); +int berlin2_pll_register(const struct berlin2_pll_map *map, + void __iomem *base, const char *name, + const char *parent_name, unsigned long flags); #endif /* __BERLIN2_PLL_H */ diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index 23e0e3be6c37..edf3b96b3b73 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c @@ -92,8 +92,7 @@ */ #define MAX_CLKS 41 -static struct clk *clks[MAX_CLKS]; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_data; static DEFINE_SPINLOCK(lock); static void __iomem *gbase; @@ -505,8 +504,17 @@ static void __init berlin2_clock_setup(struct device_node *np) struct device_node *parent_np = of_get_parent(np); const char *parent_names[9]; struct clk *clk; + struct clk_hw *hw; + struct clk_hw **hws; u8 avpll_flags = 0; - int n; + int n, ret; + + clk_data = kzalloc(sizeof(*clk_data) + + sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL); + if (!clk_data) + return; + clk_data->num = MAX_CLKS; + hws = clk_data->hws; gbase = of_iomap(parent_np, 0); if (!gbase) @@ -526,118 +534,118 @@ static void __init berlin2_clock_setup(struct device_node *np) } /* simple register PLLs */ - clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0, + ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_SYSPLLCTL0, clk_names[SYSPLL], clk_names[REFCLK], 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; - clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0, + ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_MEMPLLCTL0, clk_names[MEMPLL], clk_names[REFCLK], 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; - clk = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0, + ret = berlin2_pll_register(&bg2_pll_map, gbase + REG_CPUPLLCTL0, clk_names[CPUPLL], clk_names[REFCLK], 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; if (of_device_is_compatible(np, "marvell,berlin2-global-register")) avpll_flags |= BERLIN2_AVPLL_SCRAMBLE_QUIRK; /* audio/video VCOs */ - clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA", + ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL0, "avpll_vcoA", clk_names[REFCLK], avpll_flags, 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; for (n = 0; n < 8; n++) { - clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0, + ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL0, clk_names[AVPLL_A1 + n], n, "avpll_vcoA", avpll_flags, 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; } - clk = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB", + ret = berlin2_avpll_vco_register(gbase + REG_AVPLLCTL31, "avpll_vcoB", clk_names[REFCLK], BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; for (n = 0; n < 8; n++) { - clk = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31, + ret = berlin2_avpll_channel_register(gbase + REG_AVPLLCTL31, clk_names[AVPLL_B1 + n], n, "avpll_vcoB", BERLIN2_AVPLL_BIT_QUIRK | avpll_flags, 0); - if (IS_ERR(clk)) + if (ret) goto bg2_fail; } /* reference clock bypass switches */ parent_names[0] = clk_names[SYSPLL]; parent_names[1] = clk_names[REFCLK]; - clk = clk_register_mux(NULL, "syspll_byp", parent_names, 2, + hw = clk_hw_register_mux(NULL, "syspll_byp", parent_names, 2, 0, gbase + REG_CLKSWITCH0, 0, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; - clk_names[SYSPLL] = __clk_get_name(clk); + clk_names[SYSPLL] = clk_hw_get_name(hw); parent_names[0] = clk_names[MEMPLL]; parent_names[1] = clk_names[REFCLK]; - clk = clk_register_mux(NULL, "mempll_byp", parent_names, 2, + hw = clk_hw_register_mux(NULL, "mempll_byp", parent_names, 2, 0, gbase + REG_CLKSWITCH0, 1, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; - clk_names[MEMPLL] = __clk_get_name(clk); + clk_names[MEMPLL] = clk_hw_get_name(hw); parent_names[0] = clk_names[CPUPLL]; parent_names[1] = clk_names[REFCLK]; - clk = clk_register_mux(NULL, "cpupll_byp", parent_names, 2, + hw = clk_hw_register_mux(NULL, "cpupll_byp", parent_names, 2, 0, gbase + REG_CLKSWITCH0, 2, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; - clk_names[CPUPLL] = __clk_get_name(clk); + clk_names[CPUPLL] = clk_hw_get_name(hw); /* clock muxes */ parent_names[0] = clk_names[AVPLL_B3]; parent_names[1] = clk_names[AVPLL_A3]; - clk = clk_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2, + hw = clk_hw_register_mux(NULL, clk_names[AUDIO1_PLL], parent_names, 2, 0, gbase + REG_CLKSELECT2, 29, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; parent_names[0] = clk_names[VIDEO0_PLL]; parent_names[1] = clk_names[VIDEO_EXT0]; - clk = clk_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2, + hw = clk_hw_register_mux(NULL, clk_names[VIDEO0_IN], parent_names, 2, 0, gbase + REG_CLKSELECT3, 4, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; parent_names[0] = clk_names[VIDEO1_PLL]; parent_names[1] = clk_names[VIDEO_EXT0]; - clk = clk_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2, + hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_IN], parent_names, 2, 0, gbase + REG_CLKSELECT3, 6, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; parent_names[0] = clk_names[AVPLL_A2]; parent_names[1] = clk_names[AVPLL_B2]; - clk = clk_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2, + hw = clk_hw_register_mux(NULL, clk_names[VIDEO1_PLL], parent_names, 2, 0, gbase + REG_CLKSELECT3, 7, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; parent_names[0] = clk_names[VIDEO2_PLL]; parent_names[1] = clk_names[VIDEO_EXT0]; - clk = clk_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2, + hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_IN], parent_names, 2, 0, gbase + REG_CLKSELECT3, 9, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; parent_names[0] = clk_names[AVPLL_B1]; parent_names[1] = clk_names[AVPLL_A5]; - clk = clk_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2, + hw = clk_hw_register_mux(NULL, clk_names[VIDEO2_PLL], parent_names, 2, 0, gbase + REG_CLKSELECT3, 10, 1, 0, &lock); - if (IS_ERR(clk)) + if (IS_ERR(hw)) goto bg2_fail; /* clock divider cells */ @@ -648,7 +656,7 @@ static void __init berlin2_clock_setup(struct device_node *np) for (k = 0; k < dd->num_parents; k++) parent_names[k] = clk_names[dd->parent_ids[k]]; - clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, + hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, dd->name, dd->div_flags, parent_names, dd->num_parents, dd->flags, &lock); } @@ -657,18 +665,18 @@ static void __init berlin2_clock_setup(struct device_node *np) for (n = 0; n < ARRAY_SIZE(bg2_gates); n++) { const struct berlin2_gate_data *gd = &bg2_gates[n]; - clks[CLKID_GETH0 + n] = clk_register_gate(NULL, gd->name, + hws[CLKID_GETH0 + n] = clk_hw_register_gate(NULL, gd->name, gd->parent_name, gd->flags, gbase + REG_CLKENABLE, gd->bit_idx, 0, &lock); } /* twdclk is derived from cpu/3 */ - clks[CLKID_TWD] = - clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); + hws[CLKID_TWD] = + clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); /* check for errors on leaf clocks */ for (n = 0; n < MAX_CLKS; n++) { - if (!IS_ERR(clks[n])) + if (!IS_ERR(hws[n])) continue; pr_err("%s: Unable to register leaf clock %d\n", @@ -677,9 +685,7 @@ static void __init berlin2_clock_setup(struct device_node *np) } /* register clk-provider */ - clk_data.clks = clks; - clk_data.clk_num = MAX_CLKS; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data); return; diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index f144547cf76c..0718e831475f 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -46,8 +46,7 @@ #define REG_SDIO1XIN_CLKCTL 0x015c #define MAX_CLKS 28 -static struct clk *clks[MAX_CLKS]; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_data; static DEFINE_SPINLOCK(lock); static void __iomem *gbase; static void __iomem *cpupll_base; @@ -293,7 +292,15 @@ static void __init berlin2q_clock_setup(struct device_node *np) struct device_node *parent_np = of_get_parent(np); const char *parent_names[9]; struct clk *clk; - int n; + struct clk_hw **hws; + int n, ret; + + clk_data = kzalloc(sizeof(*clk_data) + + sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL); + if (!clk_data) + return; + clk_data->num = MAX_CLKS; + hws = clk_data->hws; gbase = of_iomap(parent_np, 0); if (!gbase) { @@ -317,14 +324,14 @@ static void __init berlin2q_clock_setup(struct device_node *np) } /* simple register PLLs */ - clk = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0, + ret = berlin2_pll_register(&bg2q_pll_map, gbase + REG_SYSPLLCTL0, clk_names[SYSPLL], clk_names[REFCLK], 0); - if (IS_ERR(clk)) + if (ret) goto bg2q_fail; - clk = berlin2_pll_register(&bg2q_pll_map, cpupll_base, + ret = berlin2_pll_register(&bg2q_pll_map, cpupll_base, clk_names[CPUPLL], clk_names[REFCLK], 0); - if (IS_ERR(clk)) + if (ret) goto bg2q_fail; /* TODO: add BG2Q AVPLL */ @@ -342,7 +349,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) for (k = 0; k < dd->num_parents; k++) parent_names[k] = clk_names[dd->parent_ids[k]]; - clks[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, + hws[CLKID_SYS + n] = berlin2_div_register(&dd->map, gbase, dd->name, dd->div_flags, parent_names, dd->num_parents, dd->flags, &lock); } @@ -351,22 +358,22 @@ static void __init berlin2q_clock_setup(struct device_node *np) for (n = 0; n < ARRAY_SIZE(bg2q_gates); n++) { const struct berlin2_gate_data *gd = &bg2q_gates[n]; - clks[CLKID_GFX2DAXI + n] = clk_register_gate(NULL, gd->name, + hws[CLKID_GFX2DAXI + n] = clk_hw_register_gate(NULL, gd->name, gd->parent_name, gd->flags, gbase + REG_CLKENABLE, gd->bit_idx, 0, &lock); } /* cpuclk divider is fixed to 1 */ - clks[CLKID_CPU] = - clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL], + hws[CLKID_CPU] = + clk_hw_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL], 0, 1, 1); /* twdclk is derived from cpu/3 */ - clks[CLKID_TWD] = - clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); + hws[CLKID_TWD] = + clk_hw_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3); /* check for errors on leaf clocks */ for (n = 0; n < MAX_CLKS; n++) { - if (!IS_ERR(clks[n])) + if (!IS_ERR(hws[n])) continue; pr_err("%s: Unable to register leaf clock %d\n", @@ -375,9 +382,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) } /* register clk-provider */ - clk_data.clks = clks; - clk_data.clk_num = MAX_CLKS; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data); return; diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index 90897af8d9f7..ea8568536193 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c @@ -68,8 +68,7 @@ #define HW_LCDCLKDIV 0x01fc #define HW_ADCANACLKDIV 0x0200 -static struct clk *clks[MAX_CLKS]; -static struct clk_onecell_data clk_data; +static struct clk_hw_onecell_data *clk_data; static DEFINE_SPINLOCK(asm9260_clk_lock); struct asm9260_div_clk { @@ -267,12 +266,20 @@ static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = { static void __init asm9260_acc_init(struct device_node *np) { - struct clk *clk; + struct clk_hw *hw; + struct clk_hw **hws; const char *ref_clk, *pll_clk = "pll"; u32 rate; int n; u32 accuracy = 0; + clk_data = kzalloc(sizeof(*clk_data) + + sizeof(*clk_data->hws) * MAX_CLKS, GFP_KERNEL); + if (!clk_data) + return; + clk_data->num = MAX_CLKS; + hws = clk_data->hws; + base = of_io_request_and_map(np, 0, np->name); if (IS_ERR(base)) panic("%s: unable to map resource", np->name); @@ -282,10 +289,10 @@ static void __init asm9260_acc_init(struct device_node *np) ref_clk = of_clk_get_parent_name(np, 0); accuracy = clk_get_accuracy(__clk_lookup(ref_clk)); - clk = clk_register_fixed_rate_with_accuracy(NULL, pll_clk, + hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk, ref_clk, 0, rate, accuracy); - if (IS_ERR(clk)) + if (IS_ERR(hw)) panic("%s: can't register REFCLK. Check DT!", np->name); for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) { @@ -293,7 +300,7 @@ static void __init asm9260_acc_init(struct device_node *np) mc->parent_names[0] = ref_clk; mc->parent_names[1] = pll_clk; - clk = clk_register_mux_table(NULL, mc->name, mc->parent_names, + hw = clk_hw_register_mux_table(NULL, mc->name, mc->parent_names, mc->num_parents, mc->flags, base + mc->offset, 0, mc->mask, 0, mc->table, &asm9260_clk_lock); } @@ -302,7 +309,7 @@ static void __init asm9260_acc_init(struct device_node *np) for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) { const struct asm9260_gate_data *gd = &asm9260_mux_gates[n]; - clk = clk_register_gate(NULL, gd->name, + hw = clk_hw_register_gate(NULL, gd->name, gd->parent_name, gd->flags | CLK_SET_RATE_PARENT, base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock); } @@ -311,7 +318,7 @@ static void __init asm9260_acc_init(struct device_node *np) for (n = 0; n < ARRAY_SIZE(asm9260_div_clks); n++) { const struct asm9260_div_clk *dc = &asm9260_div_clks[n]; - clks[dc->idx] = clk_register_divider(NULL, dc->name, + hws[dc->idx] = clk_hw_register_divider(NULL, dc->name, dc->parent_name, CLK_SET_RATE_PARENT, base + dc->reg, 0, 8, CLK_DIVIDER_ONE_BASED, &asm9260_clk_lock); @@ -321,14 +328,14 @@ static void __init asm9260_acc_init(struct device_node *np) for (n = 0; n < ARRAY_SIZE(asm9260_ahb_gates); n++) { const struct asm9260_gate_data *gd = &asm9260_ahb_gates[n]; - clks[gd->idx] = clk_register_gate(NULL, gd->name, + hws[gd->idx] = clk_hw_register_gate(NULL, gd->name, gd->parent_name, gd->flags, base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock); } /* check for errors on leaf clocks */ for (n = 0; n < MAX_CLKS; n++) { - if (!IS_ERR(clks[n])) + if (!IS_ERR(hws[n])) continue; pr_err("%s: Unable to register leaf clock %d\n", @@ -337,9 +344,7 @@ static void __init asm9260_acc_init(struct device_node *np) } /* register clk-provider */ - clk_data.clks = clks; - clk_data.clk_num = MAX_CLKS; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); return; fail: iounmap(base); diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 3294db3b4e4e..5e918e7afaba 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -392,8 +392,8 @@ static int axi_clkgen_probe(struct platform_device *pdev) const char *parent_names[2]; const char *clk_name; struct resource *mem; - struct clk *clk; unsigned int i; + int ret; if (!pdev->dev.of_node) return -ENODEV; @@ -433,12 +433,12 @@ static int axi_clkgen_probe(struct platform_device *pdev) axi_clkgen_mmcm_enable(axi_clkgen, false); axi_clkgen->clk_hw.init = &init; - clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(&pdev->dev, &axi_clkgen->clk_hw); + if (ret) + return ret; - return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, - clk); + return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get, + &axi_clkgen->clk_hw); } static int axi_clkgen_remove(struct platform_device *pdev) diff --git a/drivers/clk/clk-axm5516.c b/drivers/clk/clk-axm5516.c index c7c91a5ecf8b..5d7ae333257e 100644 --- a/drivers/clk/clk-axm5516.c +++ b/drivers/clk/clk-axm5516.c @@ -516,6 +516,19 @@ static struct axxia_clk *axmclk_clocks[] = { [AXXIA_CLK_MMC] = &clk_mmc_mux.aclk, }; +static struct clk_hw * +of_clk_axmclk_get(struct of_phandle_args *clkspec, void *unused) +{ + unsigned int idx = clkspec->args[0]; + + if (idx >= ARRAY_SIZE(axmclk_clocks)) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &axmclk_clocks[idx]->hw; +} + static const struct regmap_config axmclk_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -530,21 +543,14 @@ static const struct of_device_id axmclk_match_table[] = { }; MODULE_DEVICE_TABLE(of, axmclk_match_table); -struct axmclk_priv { - struct clk_onecell_data onecell; - struct clk *clks[]; -}; - static int axmclk_probe(struct platform_device *pdev) { void __iomem *base; struct resource *res; int i, ret; struct device *dev = &pdev->dev; - struct clk *clk; struct regmap *regmap; size_t num_clks; - struct axmclk_priv *priv; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, res); @@ -557,29 +563,18 @@ static int axmclk_probe(struct platform_device *pdev) num_clks = ARRAY_SIZE(axmclk_clocks); pr_info("axmclk: supporting %zu clocks\n", num_clks); - priv = devm_kzalloc(dev, sizeof(*priv) + sizeof(*priv->clks) * num_clks, - GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->onecell.clks = priv->clks; - priv->onecell.clk_num = num_clks; /* Update each entry with the allocated regmap and register the clock * with the common clock framework */ for (i = 0; i < num_clks; i++) { axmclk_clocks[i]->regmap = regmap; - clk = devm_clk_register(dev, &axmclk_clocks[i]->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); - priv->clks[i] = clk; + ret = devm_clk_hw_register(dev, &axmclk_clocks[i]->hw); + if (ret) + return ret; } - ret = of_clk_add_provider(dev->of_node, - of_clk_src_onecell_get, &priv->onecell); - - return ret; + return of_clk_add_hw_provider(dev->of_node, of_clk_axmclk_get, NULL); } static int axmclk_remove(struct platform_device *pdev) diff --git a/drivers/clk/clk-cdce706.c b/drivers/clk/clk-cdce706.c index 01877f64eff6..f21d9092564f 100644 --- a/drivers/clk/clk-cdce706.c +++ b/drivers/clk/clk-cdce706.c @@ -71,7 +71,6 @@ struct cdce706_hw_data { struct cdce706_dev_data *dev_data; unsigned idx; unsigned parent; - struct clk *clk; struct clk_hw hw; unsigned div; unsigned mul; @@ -81,8 +80,6 @@ struct cdce706_hw_data { struct cdce706_dev_data { struct i2c_client *client; struct regmap *regmap; - struct clk_onecell_data onecell; - struct clk *clks[6]; struct clk *clkin_clk[2]; const char *clkin_name[2]; struct cdce706_hw_data clkin[1]; @@ -455,18 +452,19 @@ static int cdce706_register_hw(struct cdce706_dev_data *cdce, struct clk_init_data *init) { unsigned i; + int ret; for (i = 0; i < num_hw; ++i, ++hw) { init->name = clk_names[i]; hw->dev_data = cdce; hw->idx = i; hw->hw.init = init; - hw->clk = devm_clk_register(&cdce->client->dev, + ret = devm_clk_hw_register(&cdce->client->dev, &hw->hw); - if (IS_ERR(hw->clk)) { + if (ret) { dev_err(&cdce->client->dev, "Failed to register %s\n", clk_names[i]); - return PTR_ERR(hw->clk); + return ret; } } return 0; @@ -613,13 +611,23 @@ static int cdce706_register_clkouts(struct cdce706_dev_data *cdce) cdce->clkout[i].parent); } - ret = cdce706_register_hw(cdce, cdce->clkout, - ARRAY_SIZE(cdce->clkout), - cdce706_clkout_name, &init); - for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i) - cdce->clks[i] = cdce->clkout[i].clk; + return cdce706_register_hw(cdce, cdce->clkout, + ARRAY_SIZE(cdce->clkout), + cdce706_clkout_name, &init); +} - return ret; +static struct clk_hw * +of_clk_cdce_get(struct of_phandle_args *clkspec, void *data) +{ + struct cdce706_dev_data *cdce = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= ARRAY_SIZE(cdce->clkout)) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &cdce->clkout[idx].hw; } static int cdce706_probe(struct i2c_client *client, @@ -657,12 +665,8 @@ static int cdce706_probe(struct i2c_client *client, ret = cdce706_register_clkouts(cdce); if (ret < 0) return ret; - cdce->onecell.clks = cdce->clks; - cdce->onecell.clk_num = ARRAY_SIZE(cdce->clks); - ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, - &cdce->onecell); - - return ret; + return of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce_get, + cdce); } static int cdce706_remove(struct i2c_client *client) diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 089bf88ffa8d..b8459c14a1b7 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -62,8 +62,6 @@ struct clk_cdce925_chip { struct i2c_client *i2c_client; struct clk_cdce925_pll pll[NUMBER_OF_PLLS]; struct clk_cdce925_output clk[NUMBER_OF_OUTPUTS]; - struct clk *dt_clk[NUMBER_OF_OUTPUTS]; - struct clk_onecell_data onecell; }; /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ @@ -557,6 +555,20 @@ static int cdce925_regmap_i2c_read(void *context, return -EIO; } +static struct clk_hw * +of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data) +{ + struct clk_cdce925_chip *data = _data; + unsigned int idx = clkspec->args[0]; + + if (idx >= ARRAY_SIZE(data->clk)) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &data->clk[idx].hw; +} + /* The CDCE925 uses a funky way to read/write registers. Bulk mode is * just weird, so just use the single byte mode exclusively. */ static struct regmap_bus regmap_cdce925_bus = { @@ -572,7 +584,6 @@ static int cdce925_probe(struct i2c_client *client, const char *parent_name; const char *pll_clk_name[NUMBER_OF_PLLS] = {NULL,}; struct clk_init_data init; - struct clk *clk; u32 value; int i; int err; @@ -622,10 +633,9 @@ static int cdce925_probe(struct i2c_client *client, data->pll[i].chip = data; data->pll[i].hw.init = &init; data->pll[i].index = i; - clk = devm_clk_register(&client->dev, &data->pll[i].hw); - if (IS_ERR(clk)) { + err = devm_clk_hw_register(&client->dev, &data->pll[i].hw); + if (err) { dev_err(&client->dev, "Failed register PLL %d\n", i); - err = PTR_ERR(clk); goto error; } sprintf(child_name, "PLL%d", i+1); @@ -634,7 +644,7 @@ static int cdce925_probe(struct i2c_client *client, continue; if (!of_property_read_u32(np_output, "clock-frequency", &value)) { - err = clk_set_rate(clk, value); + err = clk_set_rate(data->pll[i].hw.clk, value); if (err) dev_err(&client->dev, "unable to set PLL frequency %ud\n", @@ -663,14 +673,12 @@ static int cdce925_probe(struct i2c_client *client, data->clk[0].hw.init = &init; data->clk[0].index = 0; data->clk[0].pdiv = 1; - clk = devm_clk_register(&client->dev, &data->clk[0].hw); + err = devm_clk_hw_register(&client->dev, &data->clk[0].hw); kfree(init.name); /* clock framework made a copy of the name */ - if (IS_ERR(clk)) { + if (err) { dev_err(&client->dev, "clock registration Y1 failed\n"); - err = PTR_ERR(clk); goto error; } - data->dt_clk[0] = clk; /* Register output clocks Y2 .. Y5*/ init.ops = &cdce925_clk_ops; @@ -695,21 +703,17 @@ static int cdce925_probe(struct i2c_client *client, init.parent_names = &pll_clk_name[1]; break; } - clk = devm_clk_register(&client->dev, &data->clk[i].hw); + err = devm_clk_hw_register(&client->dev, &data->clk[i].hw); kfree(init.name); /* clock framework made a copy of the name */ - if (IS_ERR(clk)) { + if (err) { dev_err(&client->dev, "clock registration failed\n"); - err = PTR_ERR(clk); goto error; } - data->dt_clk[i] = clk; } /* Register the output clocks */ - data->onecell.clk_num = NUMBER_OF_OUTPUTS; - data->onecell.clks = data->dt_clk; - err = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, - &data->onecell); + err = of_clk_add_hw_provider(client->dev.of_node, of_clk_cdce925_get, + data); if (err) dev_err(&client->dev, "unable to add OF clock provider\n"); diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c index adaf109f2fe2..9193f64561f6 100644 --- a/drivers/clk/clk-clps711x.c +++ b/drivers/clk/clk-clps711x.c @@ -40,9 +40,8 @@ static const struct clk_div_table timer_div_table[] = { }; struct clps711x_clk { - struct clk_onecell_data clk_data; - spinlock_t lock; - struct clk *clks[CLPS711X_CLK_MAX]; + spinlock_t lock; + struct clk_hw_onecell_data clk_data; }; static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base, @@ -55,7 +54,9 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base, if (!base) return ERR_PTR(-ENOMEM); - clps711x_clk = kzalloc(sizeof(*clps711x_clk), GFP_KERNEL); + clps711x_clk = kzalloc(sizeof(*clps711x_clk) + + sizeof(*clps711x_clk->clk_data.hws) * CLPS711X_CLK_MAX, + GFP_KERNEL); if (!clps711x_clk) return ERR_PTR(-ENOMEM); @@ -106,40 +107,40 @@ static struct clps711x_clk * __init _clps711x_clk_init(void __iomem *base, tmp |= SYSCON1_TC2M | SYSCON1_TC2S; writel(tmp, base + CLPS711X_SYSCON1); - clps711x_clk->clks[CLPS711X_CLK_DUMMY] = - clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0); - clps711x_clk->clks[CLPS711X_CLK_CPU] = - clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu); - clps711x_clk->clks[CLPS711X_CLK_BUS] = - clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus); - clps711x_clk->clks[CLPS711X_CLK_PLL] = - clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll); - clps711x_clk->clks[CLPS711X_CLK_TIMERREF] = - clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim); - clps711x_clk->clks[CLPS711X_CLK_TIMER1] = - clk_register_divider_table(NULL, "timer1", "timer_ref", 0, + clps711x_clk->clk_data.hws[CLPS711X_CLK_DUMMY] = + clk_hw_register_fixed_rate(NULL, "dummy", NULL, 0, 0); + clps711x_clk->clk_data.hws[CLPS711X_CLK_CPU] = + clk_hw_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu); + clps711x_clk->clk_data.hws[CLPS711X_CLK_BUS] = + clk_hw_register_fixed_rate(NULL, "bus", NULL, 0, f_bus); + clps711x_clk->clk_data.hws[CLPS711X_CLK_PLL] = + clk_hw_register_fixed_rate(NULL, "pll", NULL, 0, f_pll); + clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMERREF] = + clk_hw_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim); + clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1] = + clk_hw_register_divider_table(NULL, "timer1", "timer_ref", 0, base + CLPS711X_SYSCON1, 5, 1, 0, timer_div_table, &clps711x_clk->lock); - clps711x_clk->clks[CLPS711X_CLK_TIMER2] = - clk_register_divider_table(NULL, "timer2", "timer_ref", 0, + clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2] = + clk_hw_register_divider_table(NULL, "timer2", "timer_ref", 0, base + CLPS711X_SYSCON1, 7, 1, 0, timer_div_table, &clps711x_clk->lock); - clps711x_clk->clks[CLPS711X_CLK_PWM] = - clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm); - clps711x_clk->clks[CLPS711X_CLK_SPIREF] = - clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi); - clps711x_clk->clks[CLPS711X_CLK_SPI] = - clk_register_divider_table(NULL, "spi", "spi_ref", 0, + clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM] = + clk_hw_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm); + clps711x_clk->clk_data.hws[CLPS711X_CLK_SPIREF] = + clk_hw_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi); + clps711x_clk->clk_data.hws[CLPS711X_CLK_SPI] = + clk_hw_register_divider_table(NULL, "spi", "spi_ref", 0, base + CLPS711X_SYSCON1, 16, 2, 0, spi_div_table, &clps711x_clk->lock); - clps711x_clk->clks[CLPS711X_CLK_UART] = - clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10); - clps711x_clk->clks[CLPS711X_CLK_TICK] = - clk_register_fixed_rate(NULL, "tick", NULL, 0, 64); + clps711x_clk->clk_data.hws[CLPS711X_CLK_UART] = + clk_hw_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10); + clps711x_clk->clk_data.hws[CLPS711X_CLK_TICK] = + clk_hw_register_fixed_rate(NULL, "tick", NULL, 0, 64); for (i = 0; i < CLPS711X_CLK_MAX; i++) - if (IS_ERR(clps711x_clk->clks[i])) + if (IS_ERR(clps711x_clk->clk_data.hws[i])) pr_err("clk %i: register failed with %ld\n", - i, PTR_ERR(clps711x_clk->clks[i])); + i, PTR_ERR(clps711x_clk->clk_data.hws[i])); return clps711x_clk; } @@ -153,17 +154,17 @@ void __init clps711x_clk_init(void __iomem *base) BUG_ON(IS_ERR(clps711x_clk)); /* Clocksource */ - clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER1], + clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER1], NULL, "clps711x-timer.0"); - clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_TIMER2], + clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_TIMER2], NULL, "clps711x-timer.1"); /* Drivers */ - clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_PWM], + clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_PWM], NULL, "clps711x-pwm"); - clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART], + clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART], NULL, "clps711x-uart.0"); - clk_register_clkdev(clps711x_clk->clks[CLPS711X_CLK_UART], + clk_hw_register_clkdev(clps711x_clk->clk_data.hws[CLPS711X_CLK_UART], NULL, "clps711x-uart.1"); } @@ -179,10 +180,9 @@ static void __init clps711x_clk_init_dt(struct device_node *np) clps711x_clk = _clps711x_clk_init(base, fref); BUG_ON(IS_ERR(clps711x_clk)); - clps711x_clk->clk_data.clks = clps711x_clk->clks; - clps711x_clk->clk_data.clk_num = CLPS711X_CLK_MAX; - of_clk_add_provider(np, of_clk_src_onecell_get, - &clps711x_clk->clk_data); + clps711x_clk->clk_data.num = CLPS711X_CLK_MAX; + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, + &clps711x_clk->clk_data); } CLK_OF_DECLARE(clps711x, "cirrus,ep7209-clk", clps711x_clk_init_dt); #endif diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index 7379de8dc894..021f3daf34e1 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c @@ -59,7 +59,6 @@ struct cs2000_priv { struct i2c_client *client; struct clk *clk_in; struct clk *ref_clk; - struct clk *clk_out; }; static const struct of_device_id cs2000_of_match[] = { @@ -371,7 +370,6 @@ static int cs2000_clk_register(struct cs2000_priv *priv) struct device_node *np = dev->of_node; struct clk_init_data init; const char *name = np->name; - struct clk *clk; static const char *parent_names[CLK_MAX]; int ch = 0; /* it uses ch0 only at this point */ int rate; @@ -400,18 +398,16 @@ static int cs2000_clk_register(struct cs2000_priv *priv) priv->hw.init = &init; - clk = clk_register(dev, &priv->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = clk_hw_register(dev, &priv->hw); + if (ret) + return ret; - ret = of_clk_add_provider(np, of_clk_src_simple_get, clk); + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); if (ret < 0) { - clk_unregister(clk); + clk_hw_unregister(&priv->hw); return ret; } - priv->clk_out = clk; - return 0; } @@ -454,7 +450,7 @@ static int cs2000_remove(struct i2c_client *client) of_clk_del_provider(np); - clk_unregister(priv->clk_out); + clk_hw_unregister(&priv->hw); return 0; } diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index a0f55bc1ad3d..96386ffc8483 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -352,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, /* if read only, just return current value */ if (divider->flags & CLK_DIVIDER_READ_ONLY) { - bestdiv = readl(divider->reg) >> divider->shift; + bestdiv = clk_readl(divider->reg) >> divider->shift; bestdiv &= div_mask(divider->width); bestdiv = _get_div(divider->table, bestdiv, divider->flags, divider->width); diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c index 22e4c659704e..8802a2dd56ac 100644 --- a/drivers/clk/clk-efm32gg.c +++ b/drivers/clk/clk-efm32gg.c @@ -10,24 +10,31 @@ #include <linux/clk-provider.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/slab.h> #include <dt-bindings/clock/efm32-cmu.h> #define CMU_HFPERCLKEN0 0x44 +#define CMU_MAX_CLKS 37 -static struct clk *clk[37]; -static struct clk_onecell_data clk_data = { - .clks = clk, - .clk_num = ARRAY_SIZE(clk), -}; +static struct clk_hw_onecell_data *clk_data; static void __init efm32gg_cmu_init(struct device_node *np) { int i; void __iomem *base; + struct clk_hw **hws; - for (i = 0; i < ARRAY_SIZE(clk); ++i) - clk[i] = ERR_PTR(-ENOENT); + clk_data = kzalloc(sizeof(*clk_data) + + sizeof(*clk_data->hws) * CMU_MAX_CLKS, GFP_KERNEL); + + if (!clk_data) + return; + + hws = clk_data->hws; + + for (i = 0; i < CMU_MAX_CLKS; ++i) + hws[i] = ERR_PTR(-ENOENT); base = of_iomap(np, 0); if (!base) { @@ -35,46 +42,46 @@ static void __init efm32gg_cmu_init(struct device_node *np) return; } - clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL, - 0, 48000000); + hws[clk_HFXO] = clk_hw_register_fixed_rate(NULL, "HFXO", NULL, 0, + 48000000); - clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0", + hws[clk_HFPERCLKUSART0] = clk_hw_register_gate(NULL, "HFPERCLK.USART0", "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL); - clk[clk_HFPERCLKUSART1] = clk_register_gate(NULL, "HFPERCLK.USART1", + hws[clk_HFPERCLKUSART1] = clk_hw_register_gate(NULL, "HFPERCLK.USART1", "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL); - clk[clk_HFPERCLKUSART2] = clk_register_gate(NULL, "HFPERCLK.USART2", + hws[clk_HFPERCLKUSART2] = clk_hw_register_gate(NULL, "HFPERCLK.USART2", "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL); - clk[clk_HFPERCLKUART0] = clk_register_gate(NULL, "HFPERCLK.UART0", + hws[clk_HFPERCLKUART0] = clk_hw_register_gate(NULL, "HFPERCLK.UART0", "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL); - clk[clk_HFPERCLKUART1] = clk_register_gate(NULL, "HFPERCLK.UART1", + hws[clk_HFPERCLKUART1] = clk_hw_register_gate(NULL, "HFPERCLK.UART1", "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL); - clk[clk_HFPERCLKTIMER0] = clk_register_gate(NULL, "HFPERCLK.TIMER0", + hws[clk_HFPERCLKTIMER0] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER0", "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL); - clk[clk_HFPERCLKTIMER1] = clk_register_gate(NULL, "HFPERCLK.TIMER1", + hws[clk_HFPERCLKTIMER1] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER1", "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL); - clk[clk_HFPERCLKTIMER2] = clk_register_gate(NULL, "HFPERCLK.TIMER2", + hws[clk_HFPERCLKTIMER2] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER2", "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL); - clk[clk_HFPERCLKTIMER3] = clk_register_gate(NULL, "HFPERCLK.TIMER3", + hws[clk_HFPERCLKTIMER3] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER3", "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL); - clk[clk_HFPERCLKACMP0] = clk_register_gate(NULL, "HFPERCLK.ACMP0", + hws[clk_HFPERCLKACMP0] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP0", "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL); - clk[clk_HFPERCLKACMP1] = clk_register_gate(NULL, "HFPERCLK.ACMP1", + hws[clk_HFPERCLKACMP1] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP1", "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL); - clk[clk_HFPERCLKI2C0] = clk_register_gate(NULL, "HFPERCLK.I2C0", + hws[clk_HFPERCLKI2C0] = clk_hw_register_gate(NULL, "HFPERCLK.I2C0", "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL); - clk[clk_HFPERCLKI2C1] = clk_register_gate(NULL, "HFPERCLK.I2C1", + hws[clk_HFPERCLKI2C1] = clk_hw_register_gate(NULL, "HFPERCLK.I2C1", "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL); - clk[clk_HFPERCLKGPIO] = clk_register_gate(NULL, "HFPERCLK.GPIO", + hws[clk_HFPERCLKGPIO] = clk_hw_register_gate(NULL, "HFPERCLK.GPIO", "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL); - clk[clk_HFPERCLKVCMP] = clk_register_gate(NULL, "HFPERCLK.VCMP", + hws[clk_HFPERCLKVCMP] = clk_hw_register_gate(NULL, "HFPERCLK.VCMP", "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL); - clk[clk_HFPERCLKPRS] = clk_register_gate(NULL, "HFPERCLK.PRS", + hws[clk_HFPERCLKPRS] = clk_hw_register_gate(NULL, "HFPERCLK.PRS", "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL); - clk[clk_HFPERCLKADC0] = clk_register_gate(NULL, "HFPERCLK.ADC0", + hws[clk_HFPERCLKADC0] = clk_hw_register_gate(NULL, "HFPERCLK.ADC0", "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL); - clk[clk_HFPERCLKDAC0] = clk_register_gate(NULL, "HFPERCLK.DAC0", + hws[clk_HFPERCLKDAC0] = clk_hw_register_gate(NULL, "HFPERCLK.DAC0", "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data); } CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init); diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 4db3be214077..a5d402de5584 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -12,6 +12,7 @@ #include <linux/slab.h> #include <linux/err.h> #include <linux/of.h> +#include <linux/platform_device.h> /* * DOC: basic fixed multiplier and divider clock that cannot gate @@ -147,27 +148,25 @@ static const struct of_device_id set_rate_parent_matches[] = { { /* Sentinel */ }, }; -/** - * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock - */ -void __init of_fixed_factor_clk_setup(struct device_node *node) +static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) { struct clk *clk; const char *clk_name = node->name; const char *parent_name; unsigned long flags = 0; u32 div, mult; + int ret; if (of_property_read_u32(node, "clock-div", &div)) { pr_err("%s Fixed factor clock <%s> must have a clock-div property\n", __func__, node->name); - return; + return ERR_PTR(-EIO); } if (of_property_read_u32(node, "clock-mult", &mult)) { pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n", __func__, node->name); - return; + return ERR_PTR(-EIO); } of_property_read_string(node, "clock-output-names", &clk_name); @@ -178,10 +177,67 @@ void __init of_fixed_factor_clk_setup(struct device_node *node) clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, mult, div); - if (!IS_ERR(clk)) - of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (IS_ERR(clk)) + return clk; + + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (ret) { + clk_unregister(clk); + return ERR_PTR(ret); + } + + return clk; +} + +/** + * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock + */ +void __init of_fixed_factor_clk_setup(struct device_node *node) +{ + _of_fixed_factor_clk_setup(node); } -EXPORT_SYMBOL_GPL(of_fixed_factor_clk_setup); CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock", of_fixed_factor_clk_setup); + +static int of_fixed_factor_clk_remove(struct platform_device *pdev) +{ + struct clk *clk = platform_get_drvdata(pdev); + + clk_unregister_fixed_factor(clk); + + return 0; +} + +static int of_fixed_factor_clk_probe(struct platform_device *pdev) +{ + struct clk *clk; + + /* + * This function is not executed when of_fixed_factor_clk_setup + * succeeded. + */ + clk = _of_fixed_factor_clk_setup(pdev->dev.of_node); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + platform_set_drvdata(pdev, clk); + + return 0; +} + +static const struct of_device_id of_fixed_factor_clk_ids[] = { + { .compatible = "fixed-factor-clock" }, + { } +}; +MODULE_DEVICE_TABLE(of, of_fixed_factor_clk_ids); + +static struct platform_driver of_fixed_factor_clk_driver = { + .driver = { + .name = "of_fixed_factor_clk", + .of_match_table = of_fixed_factor_clk_ids, + }, + .probe = of_fixed_factor_clk_probe, + .remove = of_fixed_factor_clk_remove, +}; +builtin_platform_driver(of_fixed_factor_clk_driver); #endif diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 2edb39342a02..b5c46b3f8764 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -15,6 +15,7 @@ #include <linux/io.h> #include <linux/err.h> #include <linux/of.h> +#include <linux/platform_device.h> /* * DOC: basic fixed-rate clock that cannot gate @@ -157,18 +158,16 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw) EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate); #ifdef CONFIG_OF -/** - * of_fixed_clk_setup() - Setup function for simple fixed rate clock - */ -void of_fixed_clk_setup(struct device_node *node) +static struct clk *_of_fixed_clk_setup(struct device_node *node) { struct clk *clk; const char *clk_name = node->name; u32 rate; u32 accuracy = 0; + int ret; if (of_property_read_u32(node, "clock-frequency", &rate)) - return; + return ERR_PTR(-EIO); of_property_read_u32(node, "clock-accuracy", &accuracy); @@ -176,9 +175,66 @@ void of_fixed_clk_setup(struct device_node *node) clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, 0, rate, accuracy); - if (!IS_ERR(clk)) - of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (IS_ERR(clk)) + return clk; + + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (ret) { + clk_unregister(clk); + return ERR_PTR(ret); + } + + return clk; +} + +/** + * of_fixed_clk_setup() - Setup function for simple fixed rate clock + */ +void __init of_fixed_clk_setup(struct device_node *node) +{ + _of_fixed_clk_setup(node); } -EXPORT_SYMBOL_GPL(of_fixed_clk_setup); CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup); + +static int of_fixed_clk_remove(struct platform_device *pdev) +{ + struct clk *clk = platform_get_drvdata(pdev); + + clk_unregister_fixed_rate(clk); + + return 0; +} + +static int of_fixed_clk_probe(struct platform_device *pdev) +{ + struct clk *clk; + + /* + * This function is not executed when of_fixed_clk_setup + * succeeded. + */ + clk = _of_fixed_clk_setup(pdev->dev.of_node); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + platform_set_drvdata(pdev, clk); + + return 0; +} + +static const struct of_device_id of_fixed_clk_ids[] = { + { .compatible = "fixed-clock" }, + { } +}; +MODULE_DEVICE_TABLE(of, of_fixed_clk_ids); + +static struct platform_driver of_fixed_clk_driver = { + .driver = { + .name = "of_fixed_clk", + .of_match_table = of_fixed_clk_ids, + }, + .probe = of_fixed_clk_probe, + .remove = of_fixed_clk_remove, +}; +builtin_platform_driver(of_fixed_clk_driver); #endif diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c index 5097831387ff..8430e45427f4 100644 --- a/drivers/clk/clk-ls1x.c +++ b/drivers/clk/clk-ls1x.c @@ -48,13 +48,13 @@ static const struct clk_ops ls1x_pll_clk_ops = { .recalc_rate = ls1x_pll_recalc_rate, }; -static struct clk *__init clk_register_pll(struct device *dev, - const char *name, - const char *parent_name, - unsigned long flags) +static struct clk_hw *__init clk_hw_register_pll(struct device *dev, + const char *name, + const char *parent_name, + unsigned long flags) { + int ret; struct clk_hw *hw; - struct clk *clk; struct clk_init_data init; /* allocate the divider */ @@ -72,12 +72,13 @@ static struct clk *__init clk_register_pll(struct device *dev, hw->init = &init; /* register the clock */ - clk = clk_register(dev, hw); - - if (IS_ERR(clk)) + ret = clk_hw_register(dev, hw); + if (ret) { kfree(hw); + hw = ERR_PTR(ret); + } - return clk; + return hw; } static const char * const cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", }; @@ -86,14 +87,14 @@ static const char * const dc_parents[] = { "dc_clk_div", "osc_33m_clk", }; void __init ls1x_clk_init(void) { - struct clk *clk; + struct clk_hw *hw; - clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC); - clk_register_clkdev(clk, "osc_33m_clk", NULL); + hw = clk_hw_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC); + clk_hw_register_clkdev(hw, "osc_33m_clk", NULL); /* clock derived from 33 MHz OSC clk */ - clk = clk_register_pll(NULL, "pll_clk", "osc_33m_clk", 0); - clk_register_clkdev(clk, "pll_clk", NULL); + hw = clk_hw_register_pll(NULL, "pll_clk", "osc_33m_clk", 0); + clk_hw_register_clkdev(hw, "pll_clk", NULL); /* clock derived from PLL clk */ /* _____ @@ -102,17 +103,17 @@ void __init ls1x_clk_init(void) * \___ PLL ___ CPU DIV ___| | * |_____| */ - clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk", + hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk", CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV, DIV_CPU_SHIFT, DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST, &_lock); - clk_register_clkdev(clk, "cpu_clk_div", NULL); - clk = clk_register_mux(NULL, "cpu_clk", cpu_parents, + clk_hw_register_clkdev(hw, "cpu_clk_div", NULL); + hw = clk_hw_register_mux(NULL, "cpu_clk", cpu_parents, ARRAY_SIZE(cpu_parents), CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock); - clk_register_clkdev(clk, "cpu_clk", NULL); + clk_hw_register_clkdev(hw, "cpu_clk", NULL); /* _____ * _______________________| | @@ -120,15 +121,15 @@ void __init ls1x_clk_init(void) * \___ PLL ___ DC DIV ___| | * |_____| */ - clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk", + hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk", 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_register_clkdev(clk, "dc_clk_div", NULL); - clk = clk_register_mux(NULL, "dc_clk", dc_parents, + clk_hw_register_clkdev(hw, "dc_clk_div", NULL); + hw = clk_hw_register_mux(NULL, "dc_clk", dc_parents, ARRAY_SIZE(dc_parents), CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock); - clk_register_clkdev(clk, "dc_clk", NULL); + clk_hw_register_clkdev(hw, "dc_clk", NULL); /* _____ * _______________________| | @@ -136,26 +137,26 @@ void __init ls1x_clk_init(void) * \___ PLL ___ DDR DIV ___| | * |_____| */ - clk = clk_register_divider(NULL, "ahb_clk_div", "pll_clk", + hw = clk_hw_register_divider(NULL, "ahb_clk_div", "pll_clk", 0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_register_clkdev(clk, "ahb_clk_div", NULL); - clk = clk_register_mux(NULL, "ahb_clk", ahb_parents, + clk_hw_register_clkdev(hw, "ahb_clk_div", NULL); + hw = clk_hw_register_mux(NULL, "ahb_clk", ahb_parents, ARRAY_SIZE(ahb_parents), CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock); - clk_register_clkdev(clk, "ahb_clk", NULL); - clk_register_clkdev(clk, "stmmaceth", NULL); + clk_hw_register_clkdev(hw, "ahb_clk", NULL); + clk_hw_register_clkdev(hw, "stmmaceth", NULL); /* clock derived from AHB clk */ /* APB clk is always half of the AHB clk */ - clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, + hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, DIV_APB); - clk_register_clkdev(clk, "apb_clk", NULL); - clk_register_clkdev(clk, "ls1x_i2c", NULL); - clk_register_clkdev(clk, "ls1x_pwmtimer", NULL); - clk_register_clkdev(clk, "ls1x_spi", NULL); - clk_register_clkdev(clk, "ls1x_wdt", NULL); - clk_register_clkdev(clk, "serial8250", NULL); + clk_hw_register_clkdev(hw, "apb_clk", NULL); + clk_hw_register_clkdev(hw, "ls1x_i2c", NULL); + clk_hw_register_clkdev(hw, "ls1x_pwmtimer", NULL); + clk_hw_register_clkdev(hw, "ls1x_spi", NULL); + clk_hw_register_clkdev(hw, "ls1x_wdt", NULL); + clk_hw_register_clkdev(hw, "serial8250", NULL); } diff --git a/drivers/clk/clk-max-gen.c b/drivers/clk/clk-max-gen.c deleted file mode 100644 index 35af9cb6da4f..000000000000 --- a/drivers/clk/clk-max-gen.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * clk-max-gen.c - Generic clock driver for Maxim PMICs clocks - * - * Copyright (C) 2014 Google, Inc - * - * Copyright (C) 2012 Samsung Electornics - * Jonghwa Lee <jonghwa3.lee@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This driver is based on clk-max77686.c - * - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/regmap.h> -#include <linux/platform_device.h> -#include <linux/clk-provider.h> -#include <linux/mutex.h> -#include <linux/clkdev.h> -#include <linux/of.h> -#include <linux/export.h> - -#include "clk-max-gen.h" - -struct max_gen_clk { - struct regmap *regmap; - u32 mask; - u32 reg; - struct clk_hw hw; -}; - -static struct max_gen_clk *to_max_gen_clk(struct clk_hw *hw) -{ - return container_of(hw, struct max_gen_clk, hw); -} - -static int max_gen_clk_prepare(struct clk_hw *hw) -{ - struct max_gen_clk *max_gen = to_max_gen_clk(hw); - - return regmap_update_bits(max_gen->regmap, max_gen->reg, - max_gen->mask, max_gen->mask); -} - -static void max_gen_clk_unprepare(struct clk_hw *hw) -{ - struct max_gen_clk *max_gen = to_max_gen_clk(hw); - - regmap_update_bits(max_gen->regmap, max_gen->reg, - max_gen->mask, ~max_gen->mask); -} - -static int max_gen_clk_is_prepared(struct clk_hw *hw) -{ - struct max_gen_clk *max_gen = to_max_gen_clk(hw); - int ret; - u32 val; - - ret = regmap_read(max_gen->regmap, max_gen->reg, &val); - - if (ret < 0) - return -EINVAL; - - return val & max_gen->mask; -} - -static unsigned long max_gen_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - return 32768; -} - -struct clk_ops max_gen_clk_ops = { - .prepare = max_gen_clk_prepare, - .unprepare = max_gen_clk_unprepare, - .is_prepared = max_gen_clk_is_prepared, - .recalc_rate = max_gen_recalc_rate, -}; -EXPORT_SYMBOL_GPL(max_gen_clk_ops); - -static struct clk *max_gen_clk_register(struct device *dev, - struct max_gen_clk *max_gen) -{ - struct clk *clk; - struct clk_hw *hw = &max_gen->hw; - int ret; - - clk = devm_clk_register(dev, hw); - if (IS_ERR(clk)) - return clk; - - ret = clk_register_clkdev(clk, hw->init->name, NULL); - - if (ret) - return ERR_PTR(ret); - - return clk; -} - -int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap, - u32 reg, struct clk_init_data *clks_init, int num_init) -{ - int i, ret; - struct max_gen_clk *max_gen_clks; - struct clk **clocks; - struct device *dev = pdev->dev.parent; - const char *clk_name; - struct clk_init_data *init; - - clocks = devm_kzalloc(dev, sizeof(struct clk *) * num_init, GFP_KERNEL); - if (!clocks) - return -ENOMEM; - - max_gen_clks = devm_kzalloc(dev, sizeof(struct max_gen_clk) - * num_init, GFP_KERNEL); - if (!max_gen_clks) - return -ENOMEM; - - for (i = 0; i < num_init; i++) { - max_gen_clks[i].regmap = regmap; - max_gen_clks[i].mask = 1 << i; - max_gen_clks[i].reg = reg; - - init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL); - if (!init) - return -ENOMEM; - - if (dev->of_node && - !of_property_read_string_index(dev->of_node, - "clock-output-names", - i, &clk_name)) - init->name = clk_name; - else - init->name = clks_init[i].name; - - init->ops = clks_init[i].ops; - init->flags = clks_init[i].flags; - - max_gen_clks[i].hw.init = init; - - clocks[i] = max_gen_clk_register(dev, &max_gen_clks[i]); - if (IS_ERR(clocks[i])) { - ret = PTR_ERR(clocks[i]); - dev_err(dev, "failed to register %s\n", - max_gen_clks[i].hw.init->name); - return ret; - } - } - - platform_set_drvdata(pdev, clocks); - - if (dev->of_node) { - struct clk_onecell_data *of_data; - - of_data = devm_kzalloc(dev, sizeof(*of_data), GFP_KERNEL); - if (!of_data) - return -ENOMEM; - - of_data->clks = clocks; - of_data->clk_num = num_init; - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, - of_data); - - if (ret) { - dev_err(dev, "failed to register OF clock provider\n"); - return ret; - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(max_gen_clk_probe); - -int max_gen_clk_remove(struct platform_device *pdev, int num_init) -{ - struct device *dev = pdev->dev.parent; - - if (dev->of_node) - of_clk_del_provider(dev->of_node); - - return 0; -} -EXPORT_SYMBOL_GPL(max_gen_clk_remove); diff --git a/drivers/clk/clk-max-gen.h b/drivers/clk/clk-max-gen.h deleted file mode 100644 index 997e86fc3f4d..000000000000 --- a/drivers/clk/clk-max-gen.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * clk-max-gen.h - Generic clock driver for Maxim PMICs clocks - * - * Copyright (C) 2014 Google, Inc - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __CLK_MAX_GEN_H__ -#define __CLK_MAX_GEN_H__ - -#include <linux/types.h> -#include <linux/device.h> -#include <linux/clkdev.h> -#include <linux/regmap.h> -#include <linux/platform_device.h> - -int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap, - u32 reg, struct clk_init_data *clks_init, int num_init); -int max_gen_clk_remove(struct platform_device *pdev, int num_init); -extern struct clk_ops max_gen_clk_ops; - -#endif /* __CLK_MAX_GEN_H__ */ diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index 9b6f2772e948..b637f5979023 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -1,5 +1,5 @@ /* - * clk-max77686.c - Clock driver for Maxim 77686 + * clk-max77686.c - Clock driver for Maxim 77686/MAX77802 * * Copyright (C) 2012 Samsung Electornics * Jonghwa Lee <jonghwa3.lee@samsung.com> @@ -25,46 +25,284 @@ #include <linux/err.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/mfd/max77620.h> #include <linux/mfd/max77686.h> #include <linux/mfd/max77686-private.h> #include <linux/clk-provider.h> #include <linux/mutex.h> #include <linux/clkdev.h> +#include <linux/of.h> +#include <linux/regmap.h> #include <dt-bindings/clock/maxim,max77686.h> -#include "clk-max-gen.h" +#include <dt-bindings/clock/maxim,max77802.h> +#include <dt-bindings/clock/maxim,max77620.h> -static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { +#define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3 + +enum max77686_chip_name { + CHIP_MAX77686, + CHIP_MAX77802, + CHIP_MAX77620, +}; + +struct max77686_hw_clk_info { + const char *name; + u32 clk_reg; + u32 clk_enable_mask; + u32 flags; +}; + +struct max77686_clk_init_data { + struct regmap *regmap; + struct clk_hw hw; + struct clk_init_data clk_idata; + const struct max77686_hw_clk_info *clk_info; +}; + +struct max77686_clk_driver_data { + enum max77686_chip_name chip; + struct max77686_clk_init_data *max_clk_data; + size_t num_clks; +}; + +static const struct +max77686_hw_clk_info max77686_hw_clks_info[MAX77686_CLKS_NUM] = { [MAX77686_CLK_AP] = { .name = "32khz_ap", - .ops = &max_gen_clk_ops, + .clk_reg = MAX77686_REG_32KHZ, + .clk_enable_mask = BIT(MAX77686_CLK_AP), }, [MAX77686_CLK_CP] = { .name = "32khz_cp", - .ops = &max_gen_clk_ops, + .clk_reg = MAX77686_REG_32KHZ, + .clk_enable_mask = BIT(MAX77686_CLK_CP), }, [MAX77686_CLK_PMIC] = { .name = "32khz_pmic", - .ops = &max_gen_clk_ops, + .clk_reg = MAX77686_REG_32KHZ, + .clk_enable_mask = BIT(MAX77686_CLK_PMIC), + }, +}; + +static const struct +max77686_hw_clk_info max77802_hw_clks_info[MAX77802_CLKS_NUM] = { + [MAX77802_CLK_32K_AP] = { + .name = "32khz_ap", + .clk_reg = MAX77802_REG_32KHZ, + .clk_enable_mask = BIT(MAX77802_CLK_32K_AP), + }, + [MAX77802_CLK_32K_CP] = { + .name = "32khz_cp", + .clk_reg = MAX77802_REG_32KHZ, + .clk_enable_mask = BIT(MAX77802_CLK_32K_CP), + }, +}; + +static const struct +max77686_hw_clk_info max77620_hw_clks_info[MAX77620_CLKS_NUM] = { + [MAX77620_CLK_32K_OUT0] = { + .name = "32khz_out0", + .clk_reg = MAX77620_REG_CNFG1_32K, + .clk_enable_mask = MAX77620_CNFG1_32K_OUT0_EN, }, }; +static struct max77686_clk_init_data *to_max77686_clk_init_data( + struct clk_hw *hw) +{ + return container_of(hw, struct max77686_clk_init_data, hw); +} + +static int max77686_clk_prepare(struct clk_hw *hw) +{ + struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw); + + return regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg, + max77686->clk_info->clk_enable_mask, + max77686->clk_info->clk_enable_mask); +} + +static void max77686_clk_unprepare(struct clk_hw *hw) +{ + struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw); + + regmap_update_bits(max77686->regmap, max77686->clk_info->clk_reg, + max77686->clk_info->clk_enable_mask, + ~max77686->clk_info->clk_enable_mask); +} + +static int max77686_clk_is_prepared(struct clk_hw *hw) +{ + struct max77686_clk_init_data *max77686 = to_max77686_clk_init_data(hw); + int ret; + u32 val; + + ret = regmap_read(max77686->regmap, max77686->clk_info->clk_reg, &val); + + if (ret < 0) + return -EINVAL; + + return val & max77686->clk_info->clk_enable_mask; +} + +static unsigned long max77686_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return 32768; +} + +static struct clk_ops max77686_clk_ops = { + .prepare = max77686_clk_prepare, + .unprepare = max77686_clk_unprepare, + .is_prepared = max77686_clk_is_prepared, + .recalc_rate = max77686_recalc_rate, +}; + +static struct clk_hw * +of_clk_max77686_get(struct of_phandle_args *clkspec, void *data) +{ + struct max77686_clk_driver_data *drv_data = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= drv_data->num_clks) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &drv_data->max_clk_data[idx].hw; +} + static int max77686_clk_probe(struct platform_device *pdev) { - struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + struct device *parent = dev->parent; + const struct platform_device_id *id = platform_get_device_id(pdev); + struct max77686_clk_driver_data *drv_data; + const struct max77686_hw_clk_info *hw_clks; + struct regmap *regmap; + int i, ret, num_clks; + + drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); + if (!drv_data) + return -ENOMEM; + + regmap = dev_get_regmap(parent, NULL); + if (!regmap) { + dev_err(dev, "Failed to get rtc regmap\n"); + return -ENODEV; + } + + drv_data->chip = id->driver_data; + + switch (drv_data->chip) { + case CHIP_MAX77686: + num_clks = MAX77686_CLKS_NUM; + hw_clks = max77686_hw_clks_info; + break; + + case CHIP_MAX77802: + num_clks = MAX77802_CLKS_NUM; + hw_clks = max77802_hw_clks_info; + break; + + case CHIP_MAX77620: + num_clks = MAX77620_CLKS_NUM; + hw_clks = max77620_hw_clks_info; + break; - return max_gen_clk_probe(pdev, iodev->regmap, MAX77686_REG_32KHZ, - max77686_clks_init, MAX77686_CLKS_NUM); + default: + dev_err(dev, "Unknown Chip ID\n"); + return -EINVAL; + } + + drv_data->max_clk_data = devm_kcalloc(dev, num_clks, + sizeof(*drv_data->max_clk_data), + GFP_KERNEL); + if (!drv_data->max_clk_data) + return -ENOMEM; + + for (i = 0; i < num_clks; i++) { + struct max77686_clk_init_data *max_clk_data; + const char *clk_name; + + max_clk_data = &drv_data->max_clk_data[i]; + + max_clk_data->regmap = regmap; + max_clk_data->clk_info = &hw_clks[i]; + max_clk_data->clk_idata.flags = hw_clks[i].flags; + max_clk_data->clk_idata.ops = &max77686_clk_ops; + + if (parent->of_node && + !of_property_read_string_index(parent->of_node, + "clock-output-names", + i, &clk_name)) + max_clk_data->clk_idata.name = clk_name; + else + max_clk_data->clk_idata.name = hw_clks[i].name; + + max_clk_data->hw.init = &max_clk_data->clk_idata; + + ret = devm_clk_hw_register(dev, &max_clk_data->hw); + if (ret) { + dev_err(dev, "Failed to clock register: %d\n", ret); + return ret; + } + + ret = clk_hw_register_clkdev(&max_clk_data->hw, + max_clk_data->clk_idata.name, NULL); + if (ret < 0) { + dev_err(dev, "Failed to clkdev register: %d\n", ret); + return ret; + } + } + + if (parent->of_node) { + ret = of_clk_add_hw_provider(parent->of_node, of_clk_max77686_get, + drv_data); + + if (ret < 0) { + dev_err(dev, "Failed to register OF clock provider: %d\n", + ret); + return ret; + } + } + + /* MAX77802: Enable low-jitter mode on the 32khz clocks. */ + if (drv_data->chip == CHIP_MAX77802) { + ret = regmap_update_bits(regmap, MAX77802_REG_32KHZ, + 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT, + 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT); + if (ret < 0) { + dev_err(dev, "Failed to config low-jitter: %d\n", ret); + goto remove_of_clk_provider; + } + } + + return 0; + +remove_of_clk_provider: + if (parent->of_node) + of_clk_del_provider(parent->of_node); + + return ret; } static int max77686_clk_remove(struct platform_device *pdev) { - return max_gen_clk_remove(pdev, MAX77686_CLKS_NUM); + struct device *parent = pdev->dev.parent; + + if (parent->of_node) + of_clk_del_provider(parent->of_node); + + return 0; } static const struct platform_device_id max77686_clk_id[] = { - { "max77686-clk", 0}, - { }, + { "max77686-clk", .driver_data = CHIP_MAX77686, }, + { "max77802-clk", .driver_data = CHIP_MAX77802, }, + { "max77620-clock", .driver_data = CHIP_MAX77620, }, + {}, }; MODULE_DEVICE_TABLE(platform, max77686_clk_id); diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c deleted file mode 100644 index 355dd2e522c3..000000000000 --- a/drivers/clk/clk-max77802.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * clk-max77802.c - Clock driver for Maxim 77802 - * - * Copyright (C) 2014 Google, Inc - * - * Copyright (C) 2012 Samsung Electornics - * Jonghwa Lee <jonghwa3.lee@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This driver is based on clk-max77686.c - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/mfd/max77686-private.h> -#include <linux/clk-provider.h> -#include <linux/mutex.h> -#include <linux/clkdev.h> - -#include <dt-bindings/clock/maxim,max77802.h> -#include "clk-max-gen.h" - -#define MAX77802_CLOCK_OPMODE_MASK 0x1 -#define MAX77802_CLOCK_LOW_JITTER_SHIFT 0x3 - -static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = { - [MAX77802_CLK_32K_AP] = { - .name = "32khz_ap", - .ops = &max_gen_clk_ops, - }, - [MAX77802_CLK_32K_CP] = { - .name = "32khz_cp", - .ops = &max_gen_clk_ops, - }, -}; - -static int max77802_clk_probe(struct platform_device *pdev) -{ - struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); - int ret; - - ret = max_gen_clk_probe(pdev, iodev->regmap, MAX77802_REG_32KHZ, - max77802_clks_init, MAX77802_CLKS_NUM); - - if (ret) { - dev_err(&pdev->dev, "generic probe failed %d\n", ret); - return ret; - } - - /* Enable low-jitter mode on the 32khz clocks. */ - ret = regmap_update_bits(iodev->regmap, MAX77802_REG_32KHZ, - 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT, - 1 << MAX77802_CLOCK_LOW_JITTER_SHIFT); - if (ret < 0) - dev_err(&pdev->dev, "failed to enable low-jitter mode\n"); - - return ret; -} - -static int max77802_clk_remove(struct platform_device *pdev) -{ - return max_gen_clk_remove(pdev, MAX77802_CLKS_NUM); -} - -static const struct platform_device_id max77802_clk_id[] = { - { "max77802-clk", 0}, - { }, -}; -MODULE_DEVICE_TABLE(platform, max77802_clk_id); - -static struct platform_driver max77802_clk_driver = { - .driver = { - .name = "max77802-clk", - }, - .probe = max77802_clk_probe, - .remove = max77802_clk_remove, - .id_table = max77802_clk_id, -}; - -module_platform_driver(max77802_clk_driver); - -MODULE_DESCRIPTION("MAXIM 77802 Clock Driver"); -MODULE_AUTHOR("Javier Martinez Canillas <javier@osg.samsung.com"); -MODULE_LICENSE("GPL"); diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c index e0817754ca3e..2a83a3ff1d09 100644 --- a/drivers/clk/clk-mb86s7x.c +++ b/drivers/clk/clk-mb86s7x.c @@ -327,10 +327,11 @@ static struct clk_ops clk_clc_ops = { .set_rate = clc_set_rate, }; -struct clk *mb86s7x_clclk_register(struct device *cpu_dev) +static struct clk_hw *mb86s7x_clclk_register(struct device *cpu_dev) { struct clk_init_data init; struct cl_clk *clc; + int ret; clc = kzalloc(sizeof(*clc), GFP_KERNEL); if (!clc) @@ -344,14 +345,17 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev) init.flags = CLK_GET_RATE_NOCACHE; init.num_parents = 0; - return devm_clk_register(cpu_dev, &clc->hw); + ret = devm_clk_hw_register(cpu_dev, &clc->hw); + if (ret) + return ERR_PTR(ret); + return &clc->hw; } static int mb86s7x_clclk_of_init(void) { int cpu, ret = -ENODEV; struct device_node *np; - struct clk *clk; + struct clk_hw *hw; np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0"); if (!np || !of_device_is_available(np)) @@ -365,12 +369,12 @@ static int mb86s7x_clclk_of_init(void) continue; } - clk = mb86s7x_clclk_register(cpu_dev); - if (IS_ERR(clk)) { + hw = mb86s7x_clclk_register(cpu_dev); + if (IS_ERR(hw)) { pr_err("failed to register cpu%d clock\n", cpu); continue; } - if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) { + if (clk_hw_register_clkdev(hw, NULL, dev_name(cpu_dev))) { pr_err("failed to register cpu%d clock lookup\n", cpu); continue; } diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c index f37f719643ec..b86dac851116 100644 --- a/drivers/clk/clk-moxart.c +++ b/drivers/clk/clk-moxart.c @@ -19,7 +19,8 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) { static void __iomem *base; - struct clk *clk, *ref_clk; + struct clk_hw *hw; + struct clk *ref_clk; unsigned int mul; const char *name = node->name; const char *parent_name; @@ -42,14 +43,14 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) return; } - clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); - if (IS_ERR(clk)) { + hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); + if (IS_ERR(hw)) { pr_err("%s: failed to register clock\n", node->full_name); return; } - clk_register_clkdev(clk, NULL, name); - of_clk_add_provider(node, of_clk_src_simple_get, clk); + clk_hw_register_clkdev(hw, NULL, name); + of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); } CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", moxart_of_pll_clk_init); @@ -57,7 +58,8 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", static void __init moxart_of_apb_clk_init(struct device_node *node) { static void __iomem *base; - struct clk *clk, *pll_clk; + struct clk_hw *hw; + struct clk *pll_clk; unsigned int div, val; unsigned int div_idx[] = { 2, 3, 4, 6, 8}; const char *name = node->name; @@ -85,14 +87,14 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) return; } - clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div); - if (IS_ERR(clk)) { + hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); + if (IS_ERR(hw)) { pr_err("%s: failed to register clock\n", node->full_name); return; } - clk_register_clkdev(clk, NULL, name); - of_clk_add_provider(node, of_clk_src_simple_get, clk); + clk_hw_register_clkdev(hw, NULL, name); + of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); } CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock", moxart_of_apb_clk_init); diff --git a/drivers/clk/clk-nspire.c b/drivers/clk/clk-nspire.c index 64f196a90816..f861011d5d21 100644 --- a/drivers/clk/clk-nspire.c +++ b/drivers/clk/clk-nspire.c @@ -69,7 +69,7 @@ static void __init nspire_ahbdiv_setup(struct device_node *node, { u32 val; void __iomem *io; - struct clk *clk; + struct clk_hw *hw; const char *clk_name = node->name; const char *parent_name; struct nspire_clk_info info; @@ -85,10 +85,10 @@ static void __init nspire_ahbdiv_setup(struct device_node *node, of_property_read_string(node, "clock-output-names", &clk_name); parent_name = of_clk_get_parent_name(node, 0); - clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, - 1, info.base_ahb_ratio); - if (!IS_ERR(clk)) - of_clk_add_provider(node, of_clk_src_simple_get, clk); + hw = clk_hw_register_fixed_factor(NULL, clk_name, parent_name, 0, + 1, info.base_ahb_ratio); + if (!IS_ERR(hw)) + of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); } static void __init nspire_ahbdiv_setup_cx(struct device_node *node) @@ -111,7 +111,7 @@ static void __init nspire_clk_setup(struct device_node *node, { u32 val; void __iomem *io; - struct clk *clk; + struct clk_hw *hw; const char *clk_name = node->name; struct nspire_clk_info info; @@ -125,9 +125,10 @@ static void __init nspire_clk_setup(struct device_node *node, of_property_read_string(node, "clock-output-names", &clk_name); - clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, info.base_clock); - if (!IS_ERR(clk)) - of_clk_add_provider(node, of_clk_src_simple_get, clk); + hw = clk_hw_register_fixed_rate(NULL, clk_name, NULL, 0, + info.base_clock); + if (!IS_ERR(hw)) + of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); else return; diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 8328863cb0e0..31f590cea493 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -41,7 +41,6 @@ struct palmas_clk32k_desc { struct palmas_clock_info { struct device *dev; - struct clk *clk; struct clk_hw hw; struct palmas *palmas; const struct palmas_clk32k_desc *clk_desc; @@ -218,7 +217,7 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo) } if (cinfo->ext_control_pin) { - ret = clk_prepare(cinfo->clk); + ret = clk_prepare(cinfo->hw.clk); if (ret < 0) { dev_err(cinfo->dev, "Clock prep failed, %d\n", ret); return ret; @@ -242,7 +241,6 @@ static int palmas_clks_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; const struct palmas_clks_of_match_data *match_data; struct palmas_clock_info *cinfo; - struct clk *clk; int ret; match_data = of_device_get_match_data(&pdev->dev); @@ -261,22 +259,20 @@ static int palmas_clks_probe(struct platform_device *pdev) cinfo->clk_desc = &match_data->desc; cinfo->hw.init = &match_data->init; - clk = devm_clk_register(&pdev->dev, &cinfo->hw); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); + ret = devm_clk_hw_register(&pdev->dev, &cinfo->hw); + if (ret) { dev_err(&pdev->dev, "Fail to register clock %s, %d\n", match_data->desc.clk_name, ret); return ret; } - cinfo->clk = clk; ret = palmas_clks_init_configure(cinfo); if (ret < 0) { dev_err(&pdev->dev, "Clock config failed, %d\n", ret); return ret; } - ret = of_clk_add_provider(node, of_clk_src_simple_get, cinfo->clk); + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &cinfo->hw); if (ret < 0) dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret); return ret; diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c index 1630a1f085f7..8cb9d117fdbf 100644 --- a/drivers/clk/clk-pwm.c +++ b/drivers/clk/clk-pwm.c @@ -61,7 +61,6 @@ static int clk_pwm_probe(struct platform_device *pdev) struct pwm_device *pwm; struct pwm_args pargs; const char *clk_name; - struct clk *clk; int ret; clk_pwm = devm_kzalloc(&pdev->dev, sizeof(*clk_pwm), GFP_KERNEL); @@ -107,11 +106,11 @@ static int clk_pwm_probe(struct platform_device *pdev) clk_pwm->pwm = pwm; clk_pwm->hw.init = &init; - clk = devm_clk_register(&pdev->dev, &clk_pwm->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(&pdev->dev, &clk_pwm->hw); + if (ret) + return ret; - return of_clk_add_provider(node, of_clk_src_simple_get, clk); + return of_clk_add_hw_provider(node, of_clk_hw_simple_get, &clk_pwm->hw); } static int clk_pwm_remove(struct platform_device *pdev) diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 58566a17944a..20b105584f82 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -766,7 +766,11 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) if (!hwc) return NULL; - hwc->reg = cg->regs + 0x20 * idx; + if (cg->info.flags & CG_VER3) + hwc->reg = cg->regs + 0x70000 + 0x20 * idx; + else + hwc->reg = cg->regs + 0x20 * idx; + hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]]; /* diff --git a/drivers/clk/clk-rk808.c b/drivers/clk/clk-rk808.c index 74383039761e..faa447e191ef 100644 --- a/drivers/clk/clk-rk808.c +++ b/drivers/clk/clk-rk808.c @@ -22,11 +22,8 @@ #include <linux/mfd/rk808.h> #include <linux/i2c.h> -#define RK808_NR_OUTPUT 2 - struct rk808_clkout { struct rk808 *rk808; - struct clk_onecell_data clk_data; struct clk_hw clkout1_hw; struct clk_hw clkout2_hw; }; @@ -85,14 +82,28 @@ static const struct clk_ops rk808_clkout2_ops = { .recalc_rate = rk808_clkout_recalc_rate, }; +static struct clk_hw * +of_clk_rk808_get(struct of_phandle_args *clkspec, void *data) +{ + struct rk808_clkout *rk808_clkout = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= 2) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return idx ? &rk808_clkout->clkout2_hw : &rk808_clkout->clkout1_hw; +} + static int rk808_clkout_probe(struct platform_device *pdev) { struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); struct i2c_client *client = rk808->i2c; struct device_node *node = client->dev.of_node; struct clk_init_data init = {}; - struct clk **clk_table; struct rk808_clkout *rk808_clkout; + int ret; rk808_clkout = devm_kzalloc(&client->dev, sizeof(*rk808_clkout), GFP_KERNEL); @@ -101,11 +112,6 @@ static int rk808_clkout_probe(struct platform_device *pdev) rk808_clkout->rk808 = rk808; - clk_table = devm_kcalloc(&client->dev, RK808_NR_OUTPUT, - sizeof(struct clk *), GFP_KERNEL); - if (!clk_table) - return -ENOMEM; - init.parent_names = NULL; init.num_parents = 0; init.name = "rk808-clkout1"; @@ -116,10 +122,9 @@ static int rk808_clkout_probe(struct platform_device *pdev) of_property_read_string_index(node, "clock-output-names", 0, &init.name); - clk_table[0] = devm_clk_register(&client->dev, - &rk808_clkout->clkout1_hw); - if (IS_ERR(clk_table[0])) - return PTR_ERR(clk_table[0]); + ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout1_hw); + if (ret) + return ret; init.name = "rk808-clkout2"; init.ops = &rk808_clkout2_ops; @@ -129,16 +134,11 @@ static int rk808_clkout_probe(struct platform_device *pdev) of_property_read_string_index(node, "clock-output-names", 1, &init.name); - clk_table[1] = devm_clk_register(&client->dev, - &rk808_clkout->clkout2_hw); - if (IS_ERR(clk_table[1])) - return PTR_ERR(clk_table[1]); - - rk808_clkout->clk_data.clks = clk_table; - rk808_clkout->clk_data.clk_num = RK808_NR_OUTPUT; + ret = devm_clk_hw_register(&client->dev, &rk808_clkout->clkout2_hw); + if (ret) + return ret; - return of_clk_add_provider(node, of_clk_src_onecell_get, - &rk808_clkout->clk_data); + return of_clk_add_hw_provider(node, of_clk_rk808_get, &rk808_clkout); } static int rk808_clkout_remove(struct platform_device *pdev) diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 6962ee5d1e9a..2a3e9d8e88b0 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -146,13 +146,13 @@ static const struct of_device_id scpi_clk_match[] = { {} }; -static struct clk * +static int scpi_clk_ops_init(struct device *dev, const struct of_device_id *match, struct scpi_clk *sclk, const char *name) { struct clk_init_data init; - struct clk *clk; unsigned long min = 0, max = 0; + int ret; init.name = name; init.flags = 0; @@ -164,18 +164,18 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match, if (init.ops == &scpi_dvfs_ops) { sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id); if (IS_ERR(sclk->info)) - return NULL; + return PTR_ERR(sclk->info); } else if (init.ops == &scpi_clk_ops) { if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max) - return NULL; + return -EINVAL; } else { - return NULL; + return -EINVAL; } - clk = devm_clk_register(dev, &sclk->hw); - if (!IS_ERR(clk) && max) + ret = devm_clk_hw_register(dev, &sclk->hw); + if (!ret && max) clk_hw_set_rate_range(&sclk->hw, min, max); - return clk; + return ret; } struct scpi_clk_data { @@ -183,7 +183,7 @@ struct scpi_clk_data { unsigned int clk_num; }; -static struct clk * +static struct clk_hw * scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data) { struct scpi_clk *sclk; @@ -193,7 +193,7 @@ scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data) for (count = 0; count < clk_data->clk_num; count++) { sclk = clk_data->clk[count]; if (idx == sclk->id) - return sclk->hw.clk; + return &sclk->hw; } return ERR_PTR(-EINVAL); @@ -202,8 +202,7 @@ scpi_of_clk_src_get(struct of_phandle_args *clkspec, void *data) static int scpi_clk_add(struct device *dev, struct device_node *np, const struct of_device_id *match) { - struct clk **clks; - int idx, count; + int idx, count, err; struct scpi_clk_data *clk_data; count = of_property_count_strings(np, "clock-output-names"); @@ -222,10 +221,6 @@ static int scpi_clk_add(struct device *dev, struct device_node *np, if (!clk_data->clk) return -ENOMEM; - clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; - for (idx = 0; idx < count; idx++) { struct scpi_clk *sclk; const char *name; @@ -249,15 +244,15 @@ static int scpi_clk_add(struct device *dev, struct device_node *np, sclk->id = val; - clks[idx] = scpi_clk_ops_init(dev, match, sclk, name); - if (IS_ERR_OR_NULL(clks[idx])) + err = scpi_clk_ops_init(dev, match, sclk, name); + if (err) dev_err(dev, "failed to register clock '%s'\n", name); else dev_dbg(dev, "Registered clock '%s'\n", name); clk_data->clk[idx] = sclk; } - return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data); + return of_clk_add_hw_provider(np, scpi_of_clk_src_get, clk_data); } static int scpi_clocks_remove(struct platform_device *pdev) diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index ceef25b0990b..09b6718956bd 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c @@ -305,7 +305,6 @@ static int si514_probe(struct i2c_client *client, { struct clk_si514 *data; struct clk_init_data init; - struct clk *clk; int err; data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); @@ -330,13 +329,13 @@ static int si514_probe(struct i2c_client *client, i2c_set_clientdata(client, data); - clk = devm_clk_register(&client->dev, &data->hw); - if (IS_ERR(clk)) { + err = devm_clk_hw_register(&client->dev, &data->hw); + if (err) { dev_err(&client->dev, "clock registration failed\n"); - return PTR_ERR(clk); + return err; } - err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get, - clk); + err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get, + &data->hw); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); return err; diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index b1bc12c045d3..b051db43fae1 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -54,7 +54,6 @@ struct si5351_driver_data { enum si5351_variant variant; struct i2c_client *client; struct regmap *regmap; - struct clk_onecell_data onecell; struct clk *pxtal; const char *pxtal_name; @@ -66,6 +65,7 @@ struct si5351_driver_data { struct si5351_hw_data pll[2]; struct si5351_hw_data *msynth; struct si5351_hw_data *clkout; + size_t num_clkout; }; static const char * const si5351_input_names[] = { @@ -1307,11 +1307,31 @@ put_child: of_node_put(child); return -EINVAL; } + +static struct clk_hw * +si53351_of_clk_get(struct of_phandle_args *clkspec, void *data) +{ + struct si5351_driver_data *drvdata = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= drvdata->num_clkout) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &drvdata->clkout[idx].hw; +} #else static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant) { return 0; } + +static struct clk_hw * +si53351_of_clk_get(struct of_phandle_args *clkspec, void *data) +{ + return NULL; +} #endif /* CONFIG_OF */ static int si5351_i2c_probe(struct i2c_client *client, @@ -1321,7 +1341,6 @@ static int si5351_i2c_probe(struct i2c_client *client, struct si5351_platform_data *pdata; struct si5351_driver_data *drvdata; struct clk_init_data init; - struct clk *clk; const char *parent_names[4]; u8 num_parents, num_clocks; int ret, n; @@ -1438,10 +1457,9 @@ static int si5351_i2c_probe(struct i2c_client *client, init.num_parents = 1; } drvdata->xtal.init = &init; - clk = devm_clk_register(&client->dev, &drvdata->xtal); - if (IS_ERR(clk)) { + ret = devm_clk_hw_register(&client->dev, &drvdata->xtal); + if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); - ret = PTR_ERR(clk); goto err_clk; } @@ -1456,11 +1474,10 @@ static int si5351_i2c_probe(struct i2c_client *client, init.num_parents = 1; } drvdata->clkin.init = &init; - clk = devm_clk_register(&client->dev, &drvdata->clkin); - if (IS_ERR(clk)) { + ret = devm_clk_hw_register(&client->dev, &drvdata->clkin); + if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); - ret = PTR_ERR(clk); goto err_clk; } } @@ -1480,10 +1497,9 @@ static int si5351_i2c_probe(struct i2c_client *client, init.flags = 0; init.parent_names = parent_names; init.num_parents = num_parents; - clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw); - if (IS_ERR(clk)) { + ret = devm_clk_hw_register(&client->dev, &drvdata->pll[0].hw); + if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); - ret = PTR_ERR(clk); goto err_clk; } @@ -1505,10 +1521,9 @@ static int si5351_i2c_probe(struct i2c_client *client, init.parent_names = parent_names; init.num_parents = num_parents; } - clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw); - if (IS_ERR(clk)) { + ret = devm_clk_hw_register(&client->dev, &drvdata->pll[1].hw); + if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); - ret = PTR_ERR(clk); goto err_clk; } @@ -1524,13 +1539,9 @@ static int si5351_i2c_probe(struct i2c_client *client, sizeof(*drvdata->msynth), GFP_KERNEL); drvdata->clkout = devm_kzalloc(&client->dev, num_clocks * sizeof(*drvdata->clkout), GFP_KERNEL); + drvdata->num_clkout = num_clocks; - drvdata->onecell.clk_num = num_clocks; - drvdata->onecell.clks = devm_kzalloc(&client->dev, - num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL); - - if (WARN_ON(!drvdata->msynth || !drvdata->clkout || - !drvdata->onecell.clks)) { + if (WARN_ON(!drvdata->msynth || !drvdata->clkout)) { ret = -ENOMEM; goto err_clk; } @@ -1547,11 +1558,11 @@ static int si5351_i2c_probe(struct i2c_client *client, init.flags |= CLK_SET_RATE_PARENT; init.parent_names = parent_names; init.num_parents = 2; - clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw); - if (IS_ERR(clk)) { + ret = devm_clk_hw_register(&client->dev, + &drvdata->msynth[n].hw); + if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); - ret = PTR_ERR(clk); goto err_clk; } } @@ -1575,19 +1586,19 @@ static int si5351_i2c_probe(struct i2c_client *client, init.flags |= CLK_SET_RATE_PARENT; init.parent_names = parent_names; init.num_parents = num_parents; - clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw); - if (IS_ERR(clk)) { + ret = devm_clk_hw_register(&client->dev, + &drvdata->clkout[n].hw); + if (ret) { dev_err(&client->dev, "unable to register %s\n", init.name); - ret = PTR_ERR(clk); goto err_clk; } - drvdata->onecell.clks[n] = clk; /* set initial clkout rate */ if (pdata->clkout[n].rate != 0) { int ret; - ret = clk_set_rate(clk, pdata->clkout[n].rate); + ret = clk_set_rate(drvdata->clkout[n].hw.clk, + pdata->clkout[n].rate); if (ret != 0) { dev_err(&client->dev, "Cannot set rate : %d\n", ret); @@ -1595,8 +1606,8 @@ static int si5351_i2c_probe(struct i2c_client *client, } } - ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, - &drvdata->onecell); + ret = of_clk_add_hw_provider(client->dev.of_node, si53351_of_clk_get, + drvdata); if (ret) { dev_err(&client->dev, "unable to add clk provider\n"); goto err_clk; diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c index d56648521a95..646af1d1898d 100644 --- a/drivers/clk/clk-si570.c +++ b/drivers/clk/clk-si570.c @@ -408,7 +408,6 @@ static int si570_probe(struct i2c_client *client, { struct clk_si570 *data; struct clk_init_data init; - struct clk *clk; u32 initial_fout, factory_fout, stability; int err; enum clk_si570_variant variant = id->driver_data; @@ -462,13 +461,13 @@ static int si570_probe(struct i2c_client *client, if (err) return err; - clk = devm_clk_register(&client->dev, &data->hw); - if (IS_ERR(clk)) { + err = devm_clk_hw_register(&client->dev, &data->hw); + if (err) { dev_err(&client->dev, "clock registration failed\n"); - return PTR_ERR(clk); + return err; } - err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get, - clk); + err = of_clk_add_hw_provider(client->dev.of_node, of_clk_hw_simple_get, + &data->hw); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); return err; @@ -477,7 +476,7 @@ static int si570_probe(struct i2c_client *client, /* Read the requested initial output frequency from device tree */ if (!of_property_read_u32(client->dev.of_node, "clock-frequency", &initial_fout)) { - err = clk_set_rate(clk, initial_fout); + err = clk_set_rate(data->hw.clk, initial_fout); if (err) { of_clk_del_provider(client->dev.of_node); return err; diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c index 697c66757400..7b222a5db931 100644 --- a/drivers/clk/clk-twl6040.c +++ b/drivers/clk/clk-twl6040.c @@ -26,60 +26,73 @@ #include <linux/mfd/twl6040.h> #include <linux/clk-provider.h> -struct twl6040_clk { +struct twl6040_pdmclk { struct twl6040 *twl6040; struct device *dev; - struct clk_hw mcpdm_fclk; - struct clk *clk; + struct clk_hw pdmclk_hw; int enabled; }; -static int twl6040_bitclk_is_enabled(struct clk_hw *hw) +static int twl6040_pdmclk_is_prepared(struct clk_hw *hw) { - struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, - mcpdm_fclk); - return twl6040_clk->enabled; + struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk, + pdmclk_hw); + + return pdmclk->enabled; } -static int twl6040_bitclk_prepare(struct clk_hw *hw) +static int twl6040_pdmclk_prepare(struct clk_hw *hw) { - struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, - mcpdm_fclk); + struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk, + pdmclk_hw); int ret; - ret = twl6040_power(twl6040_clk->twl6040, 1); + ret = twl6040_power(pdmclk->twl6040, 1); if (!ret) - twl6040_clk->enabled = 1; + pdmclk->enabled = 1; return ret; } -static void twl6040_bitclk_unprepare(struct clk_hw *hw) +static void twl6040_pdmclk_unprepare(struct clk_hw *hw) { - struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, - mcpdm_fclk); + struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk, + pdmclk_hw); int ret; - ret = twl6040_power(twl6040_clk->twl6040, 0); + ret = twl6040_power(pdmclk->twl6040, 0); if (!ret) - twl6040_clk->enabled = 0; + pdmclk->enabled = 0; + } -static const struct clk_ops twl6040_mcpdm_ops = { - .is_enabled = twl6040_bitclk_is_enabled, - .prepare = twl6040_bitclk_prepare, - .unprepare = twl6040_bitclk_unprepare, +static unsigned long twl6040_pdmclk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk, + pdmclk_hw); + + return twl6040_get_sysclk(pdmclk->twl6040); +} + +static const struct clk_ops twl6040_pdmclk_ops = { + .is_prepared = twl6040_pdmclk_is_prepared, + .prepare = twl6040_pdmclk_prepare, + .unprepare = twl6040_pdmclk_unprepare, + .recalc_rate = twl6040_pdmclk_recalc_rate, }; -static struct clk_init_data wm831x_clkout_init = { - .name = "mcpdm_fclk", - .ops = &twl6040_mcpdm_ops, +static struct clk_init_data twl6040_pdmclk_init = { + .name = "pdmclk", + .ops = &twl6040_pdmclk_ops, + .flags = CLK_GET_RATE_NOCACHE, }; -static int twl6040_clk_probe(struct platform_device *pdev) +static int twl6040_pdmclk_probe(struct platform_device *pdev) { struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent); - struct twl6040_clk *clkdata; + struct twl6040_pdmclk *clkdata; + int ret; clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL); if (!clkdata) @@ -88,26 +101,28 @@ static int twl6040_clk_probe(struct platform_device *pdev) clkdata->dev = &pdev->dev; clkdata->twl6040 = twl6040; - clkdata->mcpdm_fclk.init = &wm831x_clkout_init; - clkdata->clk = devm_clk_register(&pdev->dev, &clkdata->mcpdm_fclk); - if (IS_ERR(clkdata->clk)) - return PTR_ERR(clkdata->clk); + clkdata->pdmclk_hw.init = &twl6040_pdmclk_init; + ret = devm_clk_hw_register(&pdev->dev, &clkdata->pdmclk_hw); + if (ret) + return ret; platform_set_drvdata(pdev, clkdata); - return 0; + return of_clk_add_hw_provider(pdev->dev.parent->of_node, + of_clk_hw_simple_get, + &clkdata->pdmclk_hw); } -static struct platform_driver twl6040_clk_driver = { +static struct platform_driver twl6040_pdmclk_driver = { .driver = { - .name = "twl6040-clk", + .name = "twl6040-pdmclk", }, - .probe = twl6040_clk_probe, + .probe = twl6040_pdmclk_probe, }; -module_platform_driver(twl6040_clk_driver); +module_platform_driver(twl6040_pdmclk_driver); MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock"); MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); -MODULE_ALIAS("platform:twl6040-clk"); +MODULE_ALIAS("platform:twl6040-pdmclk"); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 37368a399ff9..4161a6f25741 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -232,7 +232,7 @@ static const struct clk_ops vt8500_gated_divisor_clk_ops = { static __init void vtwm_device_clk_init(struct device_node *node) { u32 en_reg, div_reg; - struct clk *clk; + struct clk_hw *hw; struct clk_device *dev_clk; const char *clk_name = node->name; const char *parent_name; @@ -301,13 +301,14 @@ static __init void vtwm_device_clk_init(struct device_node *node) dev_clk->hw.init = &init; - clk = clk_register(NULL, &dev_clk->hw); - if (WARN_ON(IS_ERR(clk))) { + hw = &dev_clk->hw; + rc = clk_hw_register(NULL, hw); + if (WARN_ON(rc)) { kfree(dev_clk); return; } - rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); + clk_hw_register_clkdev(hw, clk_name, NULL); } CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init); @@ -681,7 +682,7 @@ static const struct clk_ops vtwm_pll_ops = { static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type) { u32 reg; - struct clk *clk; + struct clk_hw *hw; struct clk_pll *pll_clk; const char *clk_name = node->name; const char *parent_name; @@ -714,13 +715,14 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type) pll_clk->hw.init = &init; - clk = clk_register(NULL, &pll_clk->hw); - if (WARN_ON(IS_ERR(clk))) { + hw = &pll_clk->hw; + rc = clk_hw_register(NULL, &pll_clk->hw); + if (WARN_ON(rc)) { kfree(pll_clk); return; } - rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); + clk_hw_register_clkdev(hw, clk_name, NULL); } diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c index 88def4b2761c..f4fdac55727c 100644 --- a/drivers/clk/clk-wm831x.c +++ b/drivers/clk/clk-wm831x.c @@ -24,9 +24,6 @@ struct wm831x_clk { struct clk_hw xtal_hw; struct clk_hw fll_hw; struct clk_hw clkout_hw; - struct clk *xtal; - struct clk *fll; - struct clk *clkout; bool xtal_ena; }; @@ -370,19 +367,19 @@ static int wm831x_clk_probe(struct platform_device *pdev) clkdata->xtal_ena = ret & WM831X_XTAL_ENA; clkdata->xtal_hw.init = &wm831x_xtal_init; - clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw); - if (IS_ERR(clkdata->xtal)) - return PTR_ERR(clkdata->xtal); + ret = devm_clk_hw_register(&pdev->dev, &clkdata->xtal_hw); + if (ret) + return ret; clkdata->fll_hw.init = &wm831x_fll_init; - clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw); - if (IS_ERR(clkdata->fll)) - return PTR_ERR(clkdata->fll); + ret = devm_clk_hw_register(&pdev->dev, &clkdata->fll_hw); + if (ret) + return ret; clkdata->clkout_hw.init = &wm831x_clkout_init; - clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw); - if (IS_ERR(clkdata->clkout)) - return PTR_ERR(clkdata->clkout); + ret = devm_clk_hw_register(&pdev->dev, &clkdata->clkout_hw); + if (ret) + return ret; platform_set_drvdata(pdev, clkdata); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 820a939fb6bb..0fb39fe217d1 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1908,10 +1908,6 @@ int clk_set_phase(struct clk *clk, int degrees) clk_prepare_lock(); - /* bail early if nothing to do */ - if (degrees == clk->core->phase) - goto out; - trace_clk_set_phase(clk->core, degrees); if (clk->core->ops->set_phase) @@ -1922,7 +1918,6 @@ int clk_set_phase(struct clk *clk, int degrees) if (!ret) clk->core->phase = degrees; -out: clk_prepare_unlock(); return ret; @@ -2449,8 +2444,16 @@ static int __clk_core_init(struct clk_core *core) hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { struct clk_core *parent = __clk_init_parent(orphan); - if (parent) - clk_core_reparent(orphan, parent); + /* + * we could call __clk_set_parent, but that would result in a + * redundant call to the .set_rate op, if it exists + */ + if (parent) { + __clk_set_parent_before(orphan, parent); + __clk_set_parent_after(orphan, parent, NULL); + __clk_recalc_accuracies(orphan); + __clk_recalc_rates(orphan, 0); + } } /* @@ -2491,7 +2494,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id, /* This is to allow this function to be chained to others */ if (IS_ERR_OR_NULL(hw)) - return (struct clk *) hw; + return ERR_CAST(hw); clk = kzalloc(sizeof(*clk), GFP_KERNEL); if (!clk) @@ -3166,19 +3169,14 @@ __of_clk_get_hw_from_provider(struct of_clk_provider *provider, struct of_phandle_args *clkspec) { struct clk *clk; - struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); - if (provider->get_hw) { - hw = provider->get_hw(clkspec, provider->data); - } else if (provider->get) { - clk = provider->get(clkspec, provider->data); - if (!IS_ERR(clk)) - hw = __clk_get_hw(clk); - else - hw = ERR_CAST(clk); - } + if (provider->get_hw) + return provider->get_hw(clkspec, provider->data); - return hw; + clk = provider->get(clkspec, provider->data); + if (IS_ERR(clk)) + return ERR_CAST(clk); + return __clk_get_hw(clk); } struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, @@ -3186,7 +3184,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, { struct of_clk_provider *provider; struct clk *clk = ERR_PTR(-EPROBE_DEFER); - struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); + struct clk_hw *hw; if (!clkspec) return ERR_PTR(-EINVAL); @@ -3194,12 +3192,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, /* Check if we have such a provider in our array */ mutex_lock(&of_clk_mutex); list_for_each_entry(provider, &of_clk_providers, link) { - if (provider->node == clkspec->np) + if (provider->node == clkspec->np) { hw = __of_clk_get_hw_from_provider(provider, clkspec); - if (!IS_ERR(hw)) { clk = __clk_create_clk(hw, dev_id, con_id); + } - if (!IS_ERR(clk) && !__clk_get(clk)) { + if (!IS_ERR(clk)) { + if (!__clk_get(clk)) { __clk_free_clk(clk); clk = ERR_PTR(-ENOENT); } @@ -3451,6 +3450,10 @@ void __init of_clk_init(const struct of_device_id *matches) &clk_provider_list, node) { if (force || parent_ready(clk_provider->np)) { + /* Don't populate platform devices */ + of_node_set_flag(clk_provider->np, + OF_POPULATED); + clk_provider->clk_init_cb(clk_provider->np); of_clk_set_defaults(clk_provider->np, true); diff --git a/drivers/clk/h8300/clk-div.c b/drivers/clk/h8300/clk-div.c index 4bf44a25d950..715b882205a8 100644 --- a/drivers/clk/h8300/clk-div.c +++ b/drivers/clk/h8300/clk-div.c @@ -14,7 +14,7 @@ static DEFINE_SPINLOCK(clklock); static void __init h8300_div_clk_setup(struct device_node *node) { unsigned int num_parents; - struct clk *clk; + struct clk_hw *hw; const char *clk_name = node->name; const char *parent_name; void __iomem *divcr = NULL; @@ -38,15 +38,15 @@ static void __init h8300_div_clk_setup(struct device_node *node) parent_name = of_clk_get_parent_name(node, 0); of_property_read_u32(node, "renesas,width", &width); - clk = clk_register_divider(NULL, clk_name, parent_name, + hw = clk_hw_register_divider(NULL, clk_name, parent_name, CLK_SET_RATE_GATE, divcr, offset, width, CLK_DIVIDER_POWER_OF_TWO, &clklock); - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (!IS_ERR(hw)) { + of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw); return; } pr_err("%s: failed to register %s div clock (%ld)\n", - __func__, clk_name, PTR_ERR(clk)); + __func__, clk_name, PTR_ERR(hw)); error: if (divcr) iounmap(divcr); diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c index c9c2fd575ef7..a26312460621 100644 --- a/drivers/clk/h8300/clk-h8s2678.c +++ b/drivers/clk/h8300/clk-h8s2678.c @@ -84,11 +84,11 @@ static const struct clk_ops pll_ops = { static void __init h8s2678_pll_clk_setup(struct device_node *node) { unsigned int num_parents; - struct clk *clk; const char *clk_name = node->name; const char *parent_name; struct pll_clock *pll_clock; struct clk_init_data init; + int ret; num_parents = of_clk_get_parent_count(node); if (!num_parents) { @@ -121,14 +121,14 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node) init.num_parents = 1; pll_clock->hw.init = &init; - clk = clk_register(NULL, &pll_clock->hw); - if (IS_ERR(clk)) { - pr_err("%s: failed to register %s div clock (%ld)\n", - __func__, clk_name, PTR_ERR(clk)); + ret = clk_hw_register(NULL, &pll_clock->hw); + if (ret) { + pr_err("%s: failed to register %s div clock (%d)\n", + __func__, clk_name, ret); goto unmap_pllcr; } - of_clk_add_provider(node, of_clk_src_simple_get, clk); + of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clock->hw); return; unmap_pllcr: diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 6ed4f8fa0667..e7c7353a86fc 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -22,43 +22,63 @@ #include "clk.h" +static u32 share_count_sai1; +static u32 share_count_sai2; +static u32 share_count_sai3; + +static struct clk_div_table test_div_table[] = { + { .val = 3, .div = 1, }, + { .val = 2, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 0, .div = 4, }, + { } +}; + +static struct clk_div_table post_div_table[] = { + { .val = 3, .div = 4, }, + { .val = 2, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 0, .div = 1, }, + { } +}; + static struct clk *clks[IMX7D_CLK_END]; static const char *arm_a7_sel[] = { "osc", "pll_arm_main_clk", "pll_enet_500m_clk", "pll_dram_main_clk", - "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_main_clk", + "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_audio_post_div", "pll_usb_main_clk", }; static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk", "pll_enet_250m_clk", "pll_sys_pfd2_270m_clk", - "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", }; static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk", "pll_enet_125m_clk", "pll_sys_pfd2_135m_clk", - "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", }; static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk", - "pll_audio_main_clk", "pll_video_main_clk", "pll_sys_pfd7_clk", }; + "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd7_clk", }; static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk", "pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk", - "pll_sys_pfd7_clk", "pll_audio_main_clk", "pll_video_main_clk", }; + "pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_main_clk", }; static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk", "pll_dram_533m_clk", "pll_enet_250m_clk", - "pll_sys_main_240m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd4_clk", }; static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk", "pll_dram_533m_clk", "pll_sys_main_240m_clk", "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", - "pll_audio_main_clk", }; + "pll_audio_post_div", }; static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk", "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", - "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk", + "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_post_div", "pll_video_main_clk", }; static const char *dram_phym_sel[] = { "pll_dram_main_clk", @@ -69,13 +89,13 @@ static const char *dram_sel[] = { "pll_dram_main_clk", static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk", "pll_sys_main_clk", "pll_enet_500m_clk", - "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_main_clk", + "pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_main_clk", }; static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk", "pll_sys_main_clk", "pll_enet_500m_clk", "pll_enet_250m_clk", "pll_sys_pfd0_392m_clk", - "pll_audio_main_clk", "pll_sys_pfd2_270m_clk", }; + "pll_audio_post_div", "pll_sys_pfd2_270m_clk", }; static const char *usb_hsic_sel[] = { "osc", "pll_sys_main_clk", "pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", @@ -101,53 +121,53 @@ static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk", static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk", "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", - "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; + "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", }; static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk", "pll_sys_pfd3_clk", "pll_sys_main_clk", "pll_sys_pfd0_196m_clk", - "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_main_clk", }; + "pll_dram_533m_clk", "pll_video_main_clk", "pll_audio_post_div", }; static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk", "pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2", "pll_video_main_clk", "ext_clk_3", }; static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", - "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk", "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", - "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk", "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", }; static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk", - "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk", "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", }; static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk", - "pll_audio_main_clk", "pll_dram_533m_clk", "pll_video_main_clk", + "pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main_clk", "pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", }; static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk", "pll_enet_50m_clk", "pll_enet_25m_clk", - "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk", "ext_clk_4", }; static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk", - "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", + "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3", "ext_clk_4", "pll_video_main_clk", }; static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk", "pll_enet_50m_clk", "pll_enet_25m_clk", - "pll_sys_main_120m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main_clk", "ext_clk_4", }; static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk", - "pll_audio_main_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3", + "pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3", "ext_clk_4", "pll_video_main_clk", }; static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk", "pll_enet_50m_clk", "pll_enet_125m_clk", - "pll_dram_533m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main_clk", "pll_sys_pfd3_clk", }; static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk", @@ -188,22 +208,22 @@ static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk", static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk", "pll_enet_50m_clk", "pll_dram_533m_clk", - "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", "pll_sys_pfd2_135m_clk", }; static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk", "pll_enet_50m_clk", "pll_dram_533m_clk", - "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", "pll_sys_pfd2_135m_clk", }; static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk", "pll_enet_50m_clk", "pll_dram_533m_clk", - "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", "pll_sys_pfd2_135m_clk", }; static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk", "pll_enet_50m_clk", "pll_dram_533m_clk", - "pll_audio_main_clk", "pll_video_main_clk", "pll_usb_main_clk", + "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", "pll_sys_pfd2_135m_clk", }; static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk", @@ -262,32 +282,32 @@ static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk", "pll_usb_main_clk", }; static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk", - "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div", "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk", - "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div", "ext_clk_1", "ref_1m_clk", "pll_video_main_clk", }; static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk", - "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div", "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk", - "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div", "ext_clk_2", "ref_1m_clk", "pll_video_main_clk", }; static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk", - "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div", "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk", - "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_main_clk", + "pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div", "ext_clk_3", "ref_1m_clk", "pll_video_main_clk", }; static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk", "pll_sys_main_120m_clk", "pll_dram_533m_clk", - "pll_usb_main_clk", "pll_audio_main_clk", "pll_enet_125m_clk", + "pll_usb_main_clk", "pll_audio_post_div", "pll_enet_125m_clk", "pll_sys_pfd7_clk", }; static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", @@ -297,19 +317,19 @@ static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk", static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk", "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", - "ref_1m_clk", "pll_audio_main_clk", "ext_clk_1", }; + "ref_1m_clk", "pll_audio_post_div", "ext_clk_1", }; static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk", "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", - "ref_1m_clk", "pll_audio_main_clk", "ext_clk_2", }; + "ref_1m_clk", "pll_audio_post_div", "ext_clk_2", }; static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk", "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", - "ref_1m_clk", "pll_audio_main_clk", "ext_clk_3", }; + "ref_1m_clk", "pll_audio_post_div", "ext_clk_3", }; static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk", "pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main_clk", - "ref_1m_clk", "pll_audio_main_clk", "ext_clk_4", }; + "ref_1m_clk", "pll_audio_post_div", "ext_clk_4", }; static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk", "pll_sys_main_120m_clk", "pll_dram_533m_clk", @@ -323,12 +343,12 @@ static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk", static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", "pll_sys_main_120m_clk", "pll_dram_533m_clk", - "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", }; static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk", "pll_sys_main_120m_clk", "pll_dram_533m_clk", - "pll_enet_125m_clk", "pll_audio_main_clk", "pll_video_main_clk", + "pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main_clk", "pll_usb_main_clk", }; static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk", @@ -342,13 +362,13 @@ static const char *clko1_sel[] = { "osc", "pll_sys_main_clk", static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk", - "pll_audio_main_clk", "pll_video_main_clk", "ckil", }; + "pll_audio_post_div", "pll_video_main_clk", "ckil", }; static const char *lvds1_sel[] = { "pll_arm_main_clk", "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk", "pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk", "pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", - "pll_audio_main_clk", "pll_video_main_clk", "pll_enet_500m_clk", + "pll_audio_post_div", "pll_video_main_clk", "pll_enet_500m_clk", "pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk", "pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk", "pll_dram_main_clk", }; @@ -430,6 +450,11 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_PLL_AUDIO_MAIN_CLK] = imx_clk_gate("pll_audio_main_clk", "pll_audio_main_bypass", base + 0xf0, 13); clks[IMX7D_PLL_VIDEO_MAIN_CLK] = imx_clk_gate("pll_video_main_clk", "pll_video_main_bypass", base + 0x130, 13); + clks[IMX7D_PLL_AUDIO_TEST_DIV] = clk_register_divider_table(NULL, "pll_audio_test_div", "pll_audio_main_clk", + CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 19, 2, 0, test_div_table, &imx_ccm_lock); + clks[IMX7D_PLL_AUDIO_POST_DIV] = clk_register_divider_table(NULL, "pll_audio_post_div", "pll_audio_test_div", + CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0xf0, 22, 2, 0, post_div_table, &imx_ccm_lock); + clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main_clk", base + 0xc0, 0); clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main_clk", base + 0xc0, 1); clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main_clk", base + 0xc0, 2); @@ -779,6 +804,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0); clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0); + clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0); clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0); clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0); clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0); @@ -786,9 +812,12 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0); clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0); clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0); - clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate4("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0); - clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate4("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0); - clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate4("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0); + clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1); + clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1); + clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2); + clks[IMX7D_SAI2_IPG_CLK] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root_clk", base + 0x48d0, 0, &share_count_sai2); + clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3); + clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3); clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0); clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0); clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0); @@ -860,8 +889,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) /* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */ clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); - clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]); - /* set uart module clock's parent clock source that must be great then 80MHz */ clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index a81c0385ed64..3799ff82a9b4 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -134,6 +134,15 @@ static inline struct clk *imx_clk_gate2_shared(const char *name, shift, 0x3, 0, &imx_ccm_lock, share_count); } +static inline struct clk *imx_clk_gate2_shared2(const char *name, + const char *parent, void __iomem *reg, u8 shift, + unsigned int *share_count) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | + CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, + &imx_ccm_lock, share_count); +} + static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) { diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig new file mode 100644 index 000000000000..380c372d528e --- /dev/null +++ b/drivers/clk/mediatek/Kconfig @@ -0,0 +1,21 @@ +# +# MediaTek SoC drivers +# +config COMMON_CLK_MEDIATEK + bool + ---help--- + Mediatek SoCs' clock support. + +config COMMON_CLK_MT8135 + bool "Clock driver for Mediatek MT8135" + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK + ---help--- + This driver supports Mediatek MT8135 clocks. + +config COMMON_CLK_MT8173 + bool "Clock driver for Mediatek MT8173" + select COMMON_CLK_MEDIATEK + default ARCH_MEDIATEK + ---help--- + This driver supports Mediatek MT8173 clocks. diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 95fdfacb2ebf..32e7222e7305 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -1,4 +1,4 @@ -obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o +obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o obj-$(CONFIG_RESET_CONTROLLER) += reset.o -obj-y += clk-mt8135.o -obj-y += clk-mt8173.o +obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o +obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 2a76901bf04b..d8787bf444eb 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = { .disable = mtk_cg_disable_inv, }; -struct clk * __init mtk_clk_register_gate( +struct clk *mtk_clk_register_gate( const char *name, const char *parent_name, struct regmap *regmap, diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 5ada644e6200..bb30f7063569 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -24,7 +24,7 @@ #include "clk-mtk.h" #include "clk-gate.h" -struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num) +struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num) { int i; struct clk_onecell_data *clk_data; @@ -49,7 +49,7 @@ err_out: return NULL; } -void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, +void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num, struct clk_onecell_data *clk_data) { int i; @@ -72,7 +72,7 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, } } -void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks, +void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num, struct clk_onecell_data *clk_data) { int i; @@ -95,7 +95,7 @@ void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks, } } -int __init mtk_clk_register_gates(struct device_node *node, +int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, int num, struct clk_onecell_data *clk_data) { @@ -135,7 +135,7 @@ int __init mtk_clk_register_gates(struct device_node *node, return 0; } -struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc, +struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, void __iomem *base, spinlock_t *lock) { struct clk *clk; @@ -222,7 +222,7 @@ err_out: return ERR_PTR(ret); } -void __init mtk_clk_register_composites(const struct mtk_composite *mcs, +void mtk_clk_register_composites(const struct mtk_composite *mcs, int num, void __iomem *base, spinlock_t *lock, struct clk_onecell_data *clk_data) { diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index 966cab1348da..0c2deac17ce9 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -313,7 +313,7 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data, return clk; } -void __init mtk_clk_register_plls(struct device_node *node, +void mtk_clk_register_plls(struct device_node *node, const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data) { void __iomem *base; diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index b3bd813a0772..9d9af446bafc 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -946,8 +946,4 @@ static struct platform_driver gxbb_driver = { }, }; -static int __init gxbb_clkc_init(void) -{ - return platform_driver_register(&gxbb_driver); -} -device_initcall(gxbb_clkc_init); +builtin_platform_driver(gxbb_driver); diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index ca85cea17839..c3b301463425 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -199,9 +199,9 @@ static int pbclk_set_rate(struct clk_hw *hw, unsigned long rate, spin_unlock_irqrestore(&pb->core->reg_lock, flags); - /* wait again, for pbdivready */ - err = readl_poll_timeout_atomic(pb->ctrl_reg, v, v & PB_DIV_READY, - 1, LOCK_TIMEOUT_US); + /* wait again for DIV_READY */ + err = readl_poll_timeout(pb->ctrl_reg, v, v & PB_DIV_READY, + 1, LOCK_TIMEOUT_US); if (err) return err; diff --git a/drivers/clk/microchip/clk-pic32mzda.c b/drivers/clk/microchip/clk-pic32mzda.c index 51f54380474b..9f734779be92 100644 --- a/drivers/clk/microchip/clk-pic32mzda.c +++ b/drivers/clk/microchip/clk-pic32mzda.c @@ -118,6 +118,7 @@ static const struct pic32_sec_osc_data sosc_clk = { .status_reg = 0x1d0, .enable_mask = BIT(1), .status_mask = BIT(4), + .fixed_rate = 32768, .init_data = { .name = "sosc_clk", .parent_names = NULL, diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 3165da77d525..fddc8ac5faff 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -24,6 +24,9 @@ config ARMADA_39X_CLK bool select MVEBU_CLK_COMMON +config ARMADA_37XX_CLK + bool + config ARMADA_XP_CLK bool select MVEBU_CLK_COMMON diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 7172ef65693d..d9ae97fb43c4 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -6,6 +6,9 @@ obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o +obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o +obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o +obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c new file mode 100644 index 000000000000..45905fc0d75b --- /dev/null +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -0,0 +1,447 @@ +/* + * Marvell Armada 37xx SoC Peripheral clocks + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2 or later. This program is licensed "as is" + * without any warranty of any kind, whether express or implied. + * + * Most of the peripheral clocks can be modelled like this: + * _____ _______ _______ + * TBG-A-P --| | | | | | ______ + * TBG-B-P --| Mux |--| /div1 |--| /div2 |--| Gate |--> perip_clk + * TBG-A-S --| | | | | | |______| + * TBG-B-S --|_____| |_______| |_______| + * + * However some clocks may use only one or two block or and use the + * xtal clock as parent. + */ + +#include <linux/clk-provider.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#define TBG_SEL 0x0 +#define DIV_SEL0 0x4 +#define DIV_SEL1 0x8 +#define DIV_SEL2 0xC +#define CLK_SEL 0x10 +#define CLK_DIS 0x14 + +struct clk_periph_driver_data { + struct clk_hw_onecell_data *hw_data; + spinlock_t lock; +}; + +struct clk_double_div { + struct clk_hw hw; + void __iomem *reg1; + u8 shift1; + void __iomem *reg2; + u8 shift2; +}; + +#define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw) + +struct clk_periph_data { + const char *name; + const char * const *parent_names; + int num_parents; + struct clk_hw *mux_hw; + struct clk_hw *rate_hw; + struct clk_hw *gate_hw; + bool is_double_div; +}; + +static const struct clk_div_table clk_table6[] = { + { .val = 1, .div = 1, }, + { .val = 2, .div = 2, }, + { .val = 3, .div = 3, }, + { .val = 4, .div = 4, }, + { .val = 5, .div = 5, }, + { .val = 6, .div = 6, }, + { .val = 0, .div = 0, }, /* last entry */ +}; + +static const struct clk_div_table clk_table1[] = { + { .val = 0, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 0, .div = 0, }, /* last entry */ +}; + +static const struct clk_div_table clk_table2[] = { + { .val = 0, .div = 2, }, + { .val = 1, .div = 4, }, + { .val = 0, .div = 0, }, /* last entry */ +}; +static const struct clk_ops clk_double_div_ops; + +#define PERIPH_GATE(_name, _bit) \ +struct clk_gate gate_##_name = { \ + .reg = (void *)CLK_DIS, \ + .bit_idx = _bit, \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_gate_ops, \ + } \ +}; + +#define PERIPH_MUX(_name, _shift) \ +struct clk_mux mux_##_name = { \ + .reg = (void *)TBG_SEL, \ + .shift = _shift, \ + .mask = 3, \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_mux_ro_ops, \ + } \ +}; + +#define PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2) \ +struct clk_double_div rate_##_name = { \ + .reg1 = (void *)_reg1, \ + .reg2 = (void *)_reg2, \ + .shift1 = _shift1, \ + .shift2 = _shift2, \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_double_div_ops, \ + } \ +}; + +#define PERIPH_DIV(_name, _reg, _shift, _table) \ +struct clk_divider rate_##_name = { \ + .reg = (void *)_reg, \ + .table = _table, \ + .shift = _shift, \ + .hw.init = &(struct clk_init_data){ \ + .ops = &clk_divider_ro_ops, \ + } \ +}; + +#define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\ +static PERIPH_GATE(_name, _bit); \ +static PERIPH_MUX(_name, _shift); \ +static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2); + +#define PERIPH_CLK_FULL(_name, _bit, _shift, _reg, _shift1, _table) \ +static PERIPH_GATE(_name, _bit); \ +static PERIPH_MUX(_name, _shift); \ +static PERIPH_DIV(_name, _reg, _shift1, _table); + +#define PERIPH_CLK_GATE_DIV(_name, _bit, _reg, _shift, _table) \ +static PERIPH_GATE(_name, _bit); \ +static PERIPH_DIV(_name, _reg, _shift, _table); + +#define PERIPH_CLK_MUX_DIV(_name, _shift, _reg, _shift_div, _table) \ +static PERIPH_MUX(_name, _shift); \ +static PERIPH_DIV(_name, _reg, _shift_div, _table); + +#define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\ +static PERIPH_MUX(_name, _shift); \ +static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2); + +#define REF_CLK_FULL(_name) \ + { .name = #_name, \ + .parent_names = (const char *[]){ "TBG-A-P", \ + "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \ + .num_parents = 4, \ + .mux_hw = &mux_##_name.hw, \ + .gate_hw = &gate_##_name.hw, \ + .rate_hw = &rate_##_name.hw, \ + } + +#define REF_CLK_FULL_DD(_name) \ + { .name = #_name, \ + .parent_names = (const char *[]){ "TBG-A-P", \ + "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \ + .num_parents = 4, \ + .mux_hw = &mux_##_name.hw, \ + .gate_hw = &gate_##_name.hw, \ + .rate_hw = &rate_##_name.hw, \ + .is_double_div = true, \ + } + +#define REF_CLK_GATE(_name, _parent_name) \ + { .name = #_name, \ + .parent_names = (const char *[]){ _parent_name}, \ + .num_parents = 1, \ + .gate_hw = &gate_##_name.hw, \ + } + +#define REF_CLK_GATE_DIV(_name, _parent_name) \ + { .name = #_name, \ + .parent_names = (const char *[]){ _parent_name}, \ + .num_parents = 1, \ + .gate_hw = &gate_##_name.hw, \ + .rate_hw = &rate_##_name.hw, \ + } + +#define REF_CLK_MUX_DIV(_name) \ + { .name = #_name, \ + .parent_names = (const char *[]){ "TBG-A-P", \ + "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \ + .num_parents = 4, \ + .mux_hw = &mux_##_name.hw, \ + .rate_hw = &rate_##_name.hw, \ + } + +#define REF_CLK_MUX_DD(_name) \ + { .name = #_name, \ + .parent_names = (const char *[]){ "TBG-A-P", \ + "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \ + .num_parents = 4, \ + .mux_hw = &mux_##_name.hw, \ + .rate_hw = &rate_##_name.hw, \ + .is_double_div = true, \ + } + +/* NB periph clocks */ +PERIPH_CLK_FULL_DD(mmc, 2, 0, DIV_SEL2, DIV_SEL2, 16, 13); +PERIPH_CLK_FULL_DD(sata_host, 3, 2, DIV_SEL2, DIV_SEL2, 10, 7); +PERIPH_CLK_FULL_DD(sec_at, 6, 4, DIV_SEL1, DIV_SEL1, 3, 0); +PERIPH_CLK_FULL_DD(sec_dap, 7, 6, DIV_SEL1, DIV_SEL1, 9, 6); +PERIPH_CLK_FULL_DD(tscem, 8, 8, DIV_SEL1, DIV_SEL1, 15, 12); +PERIPH_CLK_FULL(tscem_tmx, 10, 10, DIV_SEL1, 18, clk_table6); +static PERIPH_GATE(avs, 11); +PERIPH_CLK_FULL_DD(pwm, 13, 14, DIV_SEL0, DIV_SEL0, 3, 0); +PERIPH_CLK_FULL_DD(sqf, 12, 12, DIV_SEL1, DIV_SEL1, 27, 24); +static PERIPH_GATE(i2c_2, 16); +static PERIPH_GATE(i2c_1, 17); +PERIPH_CLK_GATE_DIV(ddr_phy, 19, DIV_SEL0, 18, clk_table2); +PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV_SEL0, DIV_SEL0, 15, 12); +PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6); +PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6); +PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19); +PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6); + +static struct clk_periph_data data_nb[] ={ + REF_CLK_FULL_DD(mmc), + REF_CLK_FULL_DD(sata_host), + REF_CLK_FULL_DD(sec_at), + REF_CLK_FULL_DD(sec_dap), + REF_CLK_FULL_DD(tscem), + REF_CLK_FULL(tscem_tmx), + REF_CLK_GATE(avs, "xtal"), + REF_CLK_FULL_DD(sqf), + REF_CLK_FULL_DD(pwm), + REF_CLK_GATE(i2c_2, "xtal"), + REF_CLK_GATE(i2c_1, "xtal"), + REF_CLK_GATE_DIV(ddr_phy, "TBG-A-S"), + REF_CLK_FULL_DD(ddr_fclk), + REF_CLK_FULL(trace), + REF_CLK_FULL(counter), + REF_CLK_FULL_DD(eip97), + REF_CLK_MUX_DIV(cpu), + { }, +}; + +/* SB periph clocks */ +PERIPH_CLK_MUX_DD(gbe_50, 6, DIV_SEL2, DIV_SEL2, 6, 9); +PERIPH_CLK_MUX_DD(gbe_core, 8, DIV_SEL1, DIV_SEL1, 18, 21); +PERIPH_CLK_MUX_DD(gbe_125, 10, DIV_SEL1, DIV_SEL1, 6, 9); +static PERIPH_GATE(gbe1_50, 0); +static PERIPH_GATE(gbe0_50, 1); +static PERIPH_GATE(gbe1_125, 2); +static PERIPH_GATE(gbe0_125, 3); +PERIPH_CLK_GATE_DIV(gbe1_core, 4, DIV_SEL1, 13, clk_table1); +PERIPH_CLK_GATE_DIV(gbe0_core, 5, DIV_SEL1, 14, clk_table1); +PERIPH_CLK_GATE_DIV(gbe_bm, 12, DIV_SEL1, 0, clk_table1); +PERIPH_CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6); +PERIPH_CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12); +PERIPH_CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18); + +static struct clk_periph_data data_sb[] = { + REF_CLK_MUX_DD(gbe_50), + REF_CLK_MUX_DD(gbe_core), + REF_CLK_MUX_DD(gbe_125), + REF_CLK_GATE(gbe1_50, "gbe_50"), + REF_CLK_GATE(gbe0_50, "gbe_50"), + REF_CLK_GATE(gbe1_125, "gbe_125"), + REF_CLK_GATE(gbe0_125, "gbe_125"), + REF_CLK_GATE_DIV(gbe1_core, "gbe_core"), + REF_CLK_GATE_DIV(gbe0_core, "gbe_core"), + REF_CLK_GATE_DIV(gbe_bm, "gbe_core"), + REF_CLK_FULL_DD(sdio), + REF_CLK_FULL_DD(usb32_usb2_sys), + REF_CLK_FULL_DD(usb32_ss_sys), + { }, +}; + +static unsigned int get_div(void __iomem *reg, int shift) +{ + u32 val; + + val = (readl(reg) >> shift) & 0x7; + if (val > 6) + return 0; + return val; +} + +static unsigned long clk_double_div_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_double_div *double_div = to_clk_double_div(hw); + unsigned int div; + + div = get_div(double_div->reg1, double_div->shift1); + div *= get_div(double_div->reg2, double_div->shift2); + + return DIV_ROUND_UP_ULL((u64)parent_rate, div); +} + +static const struct clk_ops clk_double_div_ops = { + .recalc_rate = clk_double_div_recalc_rate, +}; + +static const struct of_device_id armada_3700_periph_clock_of_match[] = { + { .compatible = "marvell,armada-3700-periph-clock-nb", + .data = data_nb, }, + { .compatible = "marvell,armada-3700-periph-clock-sb", + .data = data_sb, }, + { } +}; +static int armada_3700_add_composite_clk(const struct clk_periph_data *data, + void __iomem *reg, spinlock_t *lock, + struct device *dev, struct clk_hw *hw) +{ + const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, + *rate_ops = NULL; + struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *rate_hw = NULL; + + if (data->mux_hw) { + struct clk_mux *mux; + + mux_hw = data->mux_hw; + mux = to_clk_mux(mux_hw); + mux->lock = lock; + mux_ops = mux_hw->init->ops; + mux->reg = reg + (u64)mux->reg; + } + + if (data->gate_hw) { + struct clk_gate *gate; + + gate_hw = data->gate_hw; + gate = to_clk_gate(gate_hw); + gate->lock = lock; + gate_ops = gate_hw->init->ops; + gate->reg = reg + (u64)gate->reg; + } + + if (data->rate_hw) { + rate_hw = data->rate_hw; + rate_ops = rate_hw->init->ops; + if (data->is_double_div) { + struct clk_double_div *rate; + + rate = to_clk_double_div(rate_hw); + rate->reg1 = reg + (u64)rate->reg1; + rate->reg2 = reg + (u64)rate->reg2; + } else { + struct clk_divider *rate = to_clk_divider(rate_hw); + const struct clk_div_table *clkt; + int table_size = 0; + + rate->reg = reg + (u64)rate->reg; + for (clkt = rate->table; clkt->div; clkt++) + table_size++; + rate->width = order_base_2(table_size); + rate->lock = lock; + } + } + + hw = clk_hw_register_composite(dev, data->name, data->parent_names, + data->num_parents, mux_hw, + mux_ops, rate_hw, rate_ops, + gate_hw, gate_ops, CLK_IGNORE_UNUSED); + + if (IS_ERR(hw)) + return PTR_ERR(hw); + + return 0; +} + +static int armada_3700_periph_clock_probe(struct platform_device *pdev) +{ + struct clk_periph_driver_data *driver_data; + struct device_node *np = pdev->dev.of_node; + const struct clk_periph_data *data; + struct device *dev = &pdev->dev; + int num_periph = 0, i, ret; + struct resource *res; + void __iomem *reg; + + data = of_device_get_match_data(dev); + if (!data) + return -ENODEV; + + while (data[num_periph].name) + num_periph++; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(dev, res); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL); + if (!driver_data) + return -ENOMEM; + + driver_data->hw_data = devm_kzalloc(dev, sizeof(*driver_data->hw_data) + + sizeof(*driver_data->hw_data->hws) * num_periph, + GFP_KERNEL); + if (!driver_data->hw_data) + return -ENOMEM; + driver_data->hw_data->num = num_periph; + + spin_lock_init(&driver_data->lock); + + for (i = 0; i < num_periph; i++) { + struct clk_hw *hw = driver_data->hw_data->hws[i]; + + if (armada_3700_add_composite_clk(&data[i], reg, + &driver_data->lock, dev, hw)) + dev_err(dev, "Can't register periph clock %s\n", + data[i].name); + + } + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, + driver_data->hw_data); + if (ret) { + for (i = 0; i < num_periph; i++) + clk_hw_unregister(driver_data->hw_data->hws[i]); + return ret; + } + + platform_set_drvdata(pdev, driver_data); + return 0; +} + +static int armada_3700_periph_clock_remove(struct platform_device *pdev) +{ + struct clk_periph_driver_data *data = platform_get_drvdata(pdev); + struct clk_hw_onecell_data *hw_data = data->hw_data; + int i; + + of_clk_del_provider(pdev->dev.of_node); + + for (i = 0; i < hw_data->num; i++) + clk_hw_unregister(hw_data->hws[i]); + + return 0; +} + +static struct platform_driver armada_3700_periph_clock_driver = { + .probe = armada_3700_periph_clock_probe, + .remove = armada_3700_periph_clock_remove, + .driver = { + .name = "marvell-armada-3700-periph-clock", + .of_match_table = armada_3700_periph_clock_of_match, + }, +}; + +builtin_platform_driver(armada_3700_periph_clock_driver); diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c new file mode 100644 index 000000000000..aa80db11f543 --- /dev/null +++ b/drivers/clk/mvebu/armada-37xx-tbg.c @@ -0,0 +1,158 @@ +/* + * Marvell Armada 37xx SoC Time Base Generator clocks + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2 or later. This program is licensed "as is" + * without any warranty of any kind, whether express or implied. + */ + +#include <linux/clk-provider.h> +#include <linux/clk.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#define NUM_TBG 4 + +#define TBG_CTRL0 0x4 +#define TBG_CTRL1 0x8 +#define TBG_CTRL7 0x20 +#define TBG_CTRL8 0x30 + +#define TBG_DIV_MASK 0x1FF + +#define TBG_A_REFDIV 0 +#define TBG_B_REFDIV 16 + +#define TBG_A_FBDIV 2 +#define TBG_B_FBDIV 18 + +#define TBG_A_VCODIV_SE 0 +#define TBG_B_VCODIV_SE 16 + +#define TBG_A_VCODIV_DIFF 1 +#define TBG_B_VCODIV_DIFF 17 + +struct tbg_def { + char *name; + u32 refdiv_offset; + u32 fbdiv_offset; + u32 vcodiv_reg; + u32 vcodiv_offset; +}; + +static const struct tbg_def tbg[NUM_TBG] = { + {"TBG-A-P", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL8, TBG_A_VCODIV_DIFF}, + {"TBG-B-P", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL8, TBG_B_VCODIV_DIFF}, + {"TBG-A-S", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL1, TBG_A_VCODIV_SE}, + {"TBG-B-S", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL1, TBG_B_VCODIV_SE}, +}; + +static unsigned int tbg_get_mult(void __iomem *reg, const struct tbg_def *ptbg) +{ + u32 val; + + val = readl(reg + TBG_CTRL0); + + return ((val >> ptbg->fbdiv_offset) & TBG_DIV_MASK) << 2; +} + +static unsigned int tbg_get_div(void __iomem *reg, const struct tbg_def *ptbg) +{ + u32 val; + unsigned int div; + + val = readl(reg + TBG_CTRL7); + + div = (val >> ptbg->refdiv_offset) & TBG_DIV_MASK; + if (div == 0) + div = 1; + val = readl(reg + ptbg->vcodiv_reg); + + div *= 1 << ((val >> ptbg->vcodiv_offset) & TBG_DIV_MASK); + + return div; +} + + +static int armada_3700_tbg_clock_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk_hw_onecell_data *hw_tbg_data; + struct device *dev = &pdev->dev; + const char *parent_name; + struct resource *res; + struct clk *parent; + void __iomem *reg; + int i, ret; + + hw_tbg_data = devm_kzalloc(&pdev->dev, sizeof(*hw_tbg_data) + + sizeof(*hw_tbg_data->hws) * NUM_TBG, + GFP_KERNEL); + if (!hw_tbg_data) + return -ENOMEM; + hw_tbg_data->num = NUM_TBG; + platform_set_drvdata(pdev, hw_tbg_data); + + parent = devm_clk_get(dev, NULL); + if (IS_ERR(parent)) { + dev_err(dev, "Could get the clock parent\n"); + return -EINVAL; + } + parent_name = __clk_get_name(parent); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + reg = devm_ioremap_resource(dev, res); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + for (i = 0; i < NUM_TBG; i++) { + const char *name; + unsigned int mult, div; + + name = tbg[i].name; + mult = tbg_get_mult(reg, &tbg[i]); + div = tbg_get_div(reg, &tbg[i]); + hw_tbg_data->hws[i] = clk_hw_register_fixed_factor(NULL, name, + parent_name, 0, mult, div); + if (IS_ERR(hw_tbg_data->hws[i])) + dev_err(dev, "Can't register TBG clock %s\n", name); + } + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, hw_tbg_data); + + return ret; +} + +static int armada_3700_tbg_clock_remove(struct platform_device *pdev) +{ + int i; + struct clk_hw_onecell_data *hw_tbg_data = platform_get_drvdata(pdev); + + of_clk_del_provider(pdev->dev.of_node); + for (i = 0; i < hw_tbg_data->num; i++) + clk_hw_unregister_fixed_factor(hw_tbg_data->hws[i]); + + return 0; +} + +static const struct of_device_id armada_3700_tbg_clock_of_match[] = { + { .compatible = "marvell,armada-3700-tbg-clock", }, + { } +}; + +static struct platform_driver armada_3700_tbg_clock_driver = { + .probe = armada_3700_tbg_clock_probe, + .remove = armada_3700_tbg_clock_remove, + .driver = { + .name = "marvell-armada-3700-tbg-clock", + .of_match_table = armada_3700_tbg_clock_of_match, + }, +}; + +builtin_platform_driver(armada_3700_tbg_clock_driver); diff --git a/drivers/clk/mvebu/armada-37xx-xtal.c b/drivers/clk/mvebu/armada-37xx-xtal.c new file mode 100644 index 000000000000..612d65ede10a --- /dev/null +++ b/drivers/clk/mvebu/armada-37xx-xtal.c @@ -0,0 +1,91 @@ +/* + * Marvell Armada 37xx SoC xtal clocks + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/clk-provider.h> +#include <linux/mfd/syscon.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define NB_GPIO1_LATCH 0xC +#define XTAL_MODE BIT(31) + +static int armada_3700_xtal_clock_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + const char *xtal_name = "xtal"; + struct device_node *parent; + struct regmap *regmap; + struct clk_hw *xtal_hw; + unsigned int rate; + u32 reg; + int ret; + + xtal_hw = devm_kzalloc(&pdev->dev, sizeof(*xtal_hw), GFP_KERNEL); + if (!xtal_hw) + return -ENOMEM; + + platform_set_drvdata(pdev, xtal_hw); + + parent = np->parent; + if (!parent) { + dev_err(&pdev->dev, "no parent\n"); + return -ENODEV; + } + + regmap = syscon_node_to_regmap(parent); + if (IS_ERR(regmap)) { + dev_err(&pdev->dev, "cannot get regmap\n"); + return PTR_ERR(regmap); + } + + ret = regmap_read(regmap, NB_GPIO1_LATCH, ®); + if (ret) { + dev_err(&pdev->dev, "cannot read from regmap\n"); + return ret; + } + + if (reg & XTAL_MODE) + rate = 40000000; + else + rate = 25000000; + + of_property_read_string_index(np, "clock-output-names", 0, &xtal_name); + xtal_hw = clk_hw_register_fixed_rate(NULL, xtal_name, NULL, 0, rate); + if (IS_ERR(xtal_hw)) + return PTR_ERR(xtal_hw); + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, xtal_hw); + + return ret; +} + +static int armada_3700_xtal_clock_remove(struct platform_device *pdev) +{ + of_clk_del_provider(pdev->dev.of_node); + + return 0; +} + +static const struct of_device_id armada_3700_xtal_clock_of_match[] = { + { .compatible = "marvell,armada-3700-xtal-clock", }, + { } +}; + +static struct platform_driver armada_3700_xtal_clock_driver = { + .probe = armada_3700_xtal_clock_probe, + .remove = armada_3700_xtal_clock_remove, + .driver = { + .name = "marvell-armada-3700-xtal-clock", + .of_match_table = armada_3700_xtal_clock_of_match, + }, +}; + +builtin_platform_driver(armada_3700_xtal_clock_driver); diff --git a/drivers/clk/mvebu/armada-39x.c b/drivers/clk/mvebu/armada-39x.c index efb974df9822..4fdfd32247a9 100644 --- a/drivers/clk/mvebu/armada-39x.c +++ b/drivers/clk/mvebu/armada-39x.c @@ -142,6 +142,8 @@ static const struct clk_gating_soc_desc armada_39x_gating_desc[] __initconst = { { "pex3", NULL, 7 }, { "pex0", NULL, 8 }, { "usb3h0", NULL, 9 }, + { "usb3h1", NULL, 10 }, + { "sata0", NULL, 15 }, { "sdio", NULL, 17 }, { "xor0", NULL, 22 }, { "xor1", NULL, 28 }, diff --git a/drivers/clk/nxp/clk-lpc18xx-creg.c b/drivers/clk/nxp/clk-lpc18xx-creg.c index 9e35749dafdf..c6e802e7e6ec 100644 --- a/drivers/clk/nxp/clk-lpc18xx-creg.c +++ b/drivers/clk/nxp/clk-lpc18xx-creg.c @@ -184,7 +184,8 @@ static void __init lpc18xx_creg_clk_init(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data); } -CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init); +CLK_OF_DECLARE_DRIVER(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", + lpc18xx_creg_clk_init); static struct clk *clk_creg[CREG_CLK_MAX]; static struct clk_onecell_data clk_creg_data = { diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 95e3b3e0fa1c..0146d3c2547f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -87,6 +87,23 @@ config MSM_LCC_8960 Say Y if you want to use audio devices such as i2s, pcm, SLIMBus, etc. +config MDM_GCC_9615 + tristate "MDM9615 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on mdm9615 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, etc. + +config MDM_LCC_9615 + tristate "MDM9615 LPASS Clock Controller" + select MDM_GCC_9615 + depends on COMMON_CLK_QCOM + help + Support for the LPASS clock controller on mdm9615 devices. + Say Y if you want to use audio devices such as i2s, pcm, + SLIMBus, etc. + config MSM_MMCC_8960 tristate "MSM8960 Multimedia Clock Controller" select MSM_GCC_8960 @@ -117,6 +134,7 @@ config MSM_MMCC_8974 config MSM_GCC_8996 tristate "MSM8996 Global Clock Controller" + select QCOM_GDSC depends on COMMON_CLK_QCOM help Support for the global clock controller on msm8996 devices. @@ -126,6 +144,7 @@ config MSM_GCC_8996 config MSM_MMCC_8996 tristate "MSM8996 Multimedia Clock Controller" select MSM_GCC_8996 + select QCOM_GDSC depends on COMMON_CLK_QCOM help Support for the multimedia clock controller on msm8996 devices. diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 2a25f4e75f49..1fb1f5476cb0 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -12,17 +12,20 @@ clk-qcom-y += clk-regmap-mux.o clk-qcom-y += reset.o clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o +# Keep alphabetically sorted by config obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o +obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o +obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o -obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o +obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o diff --git a/drivers/clk/qcom/clk-regmap.c b/drivers/clk/qcom/clk-regmap.c index a58ba39a900c..1c856d330733 100644 --- a/drivers/clk/qcom/clk-regmap.c +++ b/drivers/clk/qcom/clk-regmap.c @@ -101,14 +101,13 @@ EXPORT_SYMBOL_GPL(clk_disable_regmap); * clk_regmap struct via this function so that the regmap is initialized * and so that the clock is registered with the common clock framework. */ -struct clk *devm_clk_register_regmap(struct device *dev, - struct clk_regmap *rclk) +int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk) { if (dev && dev_get_regmap(dev, NULL)) rclk->regmap = dev_get_regmap(dev, NULL); else if (dev && dev->parent) rclk->regmap = dev_get_regmap(dev->parent, NULL); - return devm_clk_register(dev, &rclk->hw); + return devm_clk_hw_register(dev, &rclk->hw); } EXPORT_SYMBOL_GPL(devm_clk_register_regmap); diff --git a/drivers/clk/qcom/clk-regmap.h b/drivers/clk/qcom/clk-regmap.h index 491a63d537df..90d95cd11ec6 100644 --- a/drivers/clk/qcom/clk-regmap.h +++ b/drivers/clk/qcom/clk-regmap.h @@ -39,7 +39,6 @@ struct clk_regmap { int clk_is_enabled_regmap(struct clk_hw *hw); int clk_enable_regmap(struct clk_hw *hw); void clk_disable_regmap(struct clk_hw *hw); -struct clk * -devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk); +int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk); #endif diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index f7c226ab4307..fffcbaf0fba7 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -27,8 +27,8 @@ struct qcom_cc { struct qcom_reset_controller reset; - struct clk_onecell_data data; - struct clk *clks[]; + struct clk_regmap **rclks; + size_t num_rclks; }; const @@ -102,8 +102,8 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, struct device_node *clocks_node; struct clk_fixed_factor *factor; struct clk_fixed_rate *fixed; - struct clk *clk; struct clk_init_data init_data = { }; + int ret; clocks_node = of_find_node_by_path("/clocks"); if (clocks_node) @@ -121,9 +121,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, init_data.name = path; init_data.ops = &clk_fixed_rate_ops; - clk = devm_clk_register(dev, &fixed->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, &fixed->hw); + if (ret) + return ret; } of_node_put(node); @@ -141,9 +141,9 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, init_data.flags = 0; init_data.ops = &clk_fixed_factor_ops; - clk = devm_clk_register(dev, &factor->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, &factor->hw); + if (ret) + return ret; } return 0; @@ -174,42 +174,48 @@ int qcom_cc_register_sleep_clk(struct device *dev) } EXPORT_SYMBOL_GPL(qcom_cc_register_sleep_clk); +static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec, + void *data) +{ + struct qcom_cc *cc = data; + unsigned int idx = clkspec->args[0]; + + if (idx >= cc->num_rclks) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT); +} + int qcom_cc_really_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc, struct regmap *regmap) { int i, ret; struct device *dev = &pdev->dev; - struct clk *clk; - struct clk_onecell_data *data; - struct clk **clks; struct qcom_reset_controller *reset; struct qcom_cc *cc; struct gdsc_desc *scd; size_t num_clks = desc->num_clks; struct clk_regmap **rclks = desc->clks; - cc = devm_kzalloc(dev, sizeof(*cc) + sizeof(*clks) * num_clks, - GFP_KERNEL); + cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); if (!cc) return -ENOMEM; - clks = cc->clks; - data = &cc->data; - data->clks = clks; - data->clk_num = num_clks; + cc->rclks = rclks; + cc->num_rclks = num_clks; for (i = 0; i < num_clks; i++) { - if (!rclks[i]) { - clks[i] = ERR_PTR(-ENOENT); + if (!rclks[i]) continue; - } - clk = devm_clk_register_regmap(dev, rclks[i]); - if (IS_ERR(clk)) - return PTR_ERR(clk); - clks[i] = clk; + + ret = devm_clk_register_regmap(dev, rclks[i]); + if (ret) + return ret; } - ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, data); + ret = of_clk_add_hw_provider(dev->of_node, qcom_cc_clk_hw_get, cc); if (ret) return ret; diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c index 3cd1af0af0d9..b593065de8db 100644 --- a/drivers/clk/qcom/gcc-ipq4019.c +++ b/drivers/clk/qcom/gcc-ipq4019.c @@ -1332,7 +1332,6 @@ static struct platform_driver gcc_ipq4019_driver = { .probe = gcc_ipq4019_probe, .driver = { .name = "qcom,gcc-ipq4019", - .owner = THIS_MODULE, .of_match_table = gcc_ipq4019_match_table, }, }; diff --git a/drivers/clk/qcom/gcc-mdm9615.c b/drivers/clk/qcom/gcc-mdm9615.c new file mode 100644 index 000000000000..581a17f67379 --- /dev/null +++ b/drivers/clk/qcom/gcc-mdm9615.c @@ -0,0 +1,1727 @@ +/* + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) BayLibre, SAS. + * Author : Neil Armstrong <narmstrong@baylibre.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-mdm9615.h> +#include <dt-bindings/reset/qcom,gcc-mdm9615.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +static struct clk_fixed_factor cxo = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "cxo", + .parent_names = (const char *[]){ "cxo_board" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_pll pll0 = { + .l_reg = 0x30c4, + .m_reg = 0x30c8, + .n_reg = 0x30cc, + .config_reg = 0x30d4, + .mode_reg = 0x30c0, + .status_reg = 0x30d8, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll0", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap pll0_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "pll0_vote", + .parent_names = (const char *[]){ "pll8" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_regmap pll4_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "pll4_vote", + .parent_names = (const char *[]){ "pll4" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_pll pll8 = { + .l_reg = 0x3144, + .m_reg = 0x3148, + .n_reg = 0x314c, + .config_reg = 0x3154, + .mode_reg = 0x3140, + .status_reg = 0x3158, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll8", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap pll8_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "pll8_vote", + .parent_names = (const char *[]){ "pll8" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static struct clk_pll pll14 = { + .l_reg = 0x31c4, + .m_reg = 0x31c8, + .n_reg = 0x31cc, + .config_reg = 0x31d4, + .mode_reg = 0x31c0, + .status_reg = 0x31d8, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll14", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap pll14_vote = { + .enable_reg = 0x34c0, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "pll14_vote", + .parent_names = (const char *[]){ "pll14" }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +enum { + P_CXO, + P_PLL8, + P_PLL14, +}; + +static const struct parent_map gcc_cxo_pll8_map[] = { + { P_CXO, 0 }, + { P_PLL8, 3 } +}; + +static const char * const gcc_cxo_pll8[] = { + "cxo", + "pll8_vote", +}; + +static const struct parent_map gcc_cxo_pll14_map[] = { + { P_CXO, 0 }, + { P_PLL14, 4 } +}; + +static const char * const gcc_cxo_pll14[] = { + "cxo", + "pll14_vote", +}; + +static const struct parent_map gcc_cxo_map[] = { + { P_CXO, 0 }, +}; + +static const char * const gcc_cxo[] = { + "cxo", +}; + +static struct freq_tbl clk_tbl_gsbi_uart[] = { + { 1843200, P_PLL8, 2, 6, 625 }, + { 3686400, P_PLL8, 2, 12, 625 }, + { 7372800, P_PLL8, 2, 24, 625 }, + { 14745600, P_PLL8, 2, 48, 625 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 32000000, P_PLL8, 4, 1, 3 }, + { 40000000, P_PLL8, 1, 5, 48 }, + { 46400000, P_PLL8, 1, 29, 240 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 51200000, P_PLL8, 1, 2, 15 }, + { 56000000, P_PLL8, 1, 7, 48 }, + { 58982400, P_PLL8, 1, 96, 625 }, + { 64000000, P_PLL8, 2, 1, 3 }, + { } +}; + +static struct clk_rcg gsbi1_uart_src = { + .ns_reg = 0x29d4, + .md_reg = 0x29d0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x29d4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_uart_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi1_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x29d4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_uart_clk", + .parent_names = (const char *[]){ + "gsbi1_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi2_uart_src = { + .ns_reg = 0x29f4, + .md_reg = 0x29f0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x29f4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_uart_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi2_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x29f4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_uart_clk", + .parent_names = (const char *[]){ + "gsbi2_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi3_uart_src = { + .ns_reg = 0x2a14, + .md_reg = 0x2a10, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a14, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_uart_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi3_uart_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 2, + .clkr = { + .enable_reg = 0x2a14, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_uart_clk", + .parent_names = (const char *[]){ + "gsbi3_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi4_uart_src = { + .ns_reg = 0x2a34, + .md_reg = 0x2a30, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a34, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_uart_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi4_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 26, + .clkr = { + .enable_reg = 0x2a34, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_uart_clk", + .parent_names = (const char *[]){ + "gsbi4_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi5_uart_src = { + .ns_reg = 0x2a54, + .md_reg = 0x2a50, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_uart, + .clkr = { + .enable_reg = 0x2a54, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_uart_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi5_uart_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x2a54, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_uart_clk", + .parent_names = (const char *[]){ + "gsbi5_uart_src", + }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct freq_tbl clk_tbl_gsbi_qup[] = { + { 960000, P_CXO, 4, 1, 5 }, + { 4800000, P_CXO, 4, 0, 1 }, + { 9600000, P_CXO, 2, 0, 1 }, + { 15060000, P_PLL8, 1, 2, 51 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 25600000, P_PLL8, 1, 1, 15 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 51200000, P_PLL8, 1, 2, 15 }, + { } +}; + +static struct clk_rcg gsbi1_qup_src = { + .ns_reg = 0x29cc, + .md_reg = 0x29c8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x29cc, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_qup_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi1_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x29cc, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_qup_clk", + .parent_names = (const char *[]){ "gsbi1_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi2_qup_src = { + .ns_reg = 0x29ec, + .md_reg = 0x29e8, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x29ec, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_qup_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi2_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x29ec, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_qup_clk", + .parent_names = (const char *[]){ "gsbi2_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi3_qup_src = { + .ns_reg = 0x2a0c, + .md_reg = 0x2a08, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a0c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_qup_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi3_qup_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x2a0c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_qup_clk", + .parent_names = (const char *[]){ "gsbi3_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi4_qup_src = { + .ns_reg = 0x2a2c, + .md_reg = 0x2a28, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a2c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_qup_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi4_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 24, + .clkr = { + .enable_reg = 0x2a2c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_qup_clk", + .parent_names = (const char *[]){ "gsbi4_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gsbi5_qup_src = { + .ns_reg = 0x2a4c, + .md_reg = 0x2a48, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_gsbi_qup, + .clkr = { + .enable_reg = 0x2a4c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_qup_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + }, +}; + +static struct clk_branch gsbi5_qup_clk = { + .halt_reg = 0x2fd0, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x2a4c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_qup_clk", + .parent_names = (const char *[]){ "gsbi5_qup_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_gp[] = { + { 9600000, P_CXO, 2, 0, 0 }, + { 19200000, P_CXO, 1, 0, 0 }, + { } +}; + +static struct clk_rcg gp0_src = { + .ns_reg = 0x2d24, + .md_reg = 0x2d00, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d24, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp0_src", + .parent_names = gcc_cxo, + .num_parents = 1, + .ops = &clk_rcg_ops, + .flags = CLK_SET_PARENT_GATE, + }, + } +}; + +static struct clk_branch gp0_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2d24, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp0_clk", + .parent_names = (const char *[]){ "gp0_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gp1_src = { + .ns_reg = 0x2d44, + .md_reg = 0x2d40, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d44, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp1_src", + .parent_names = gcc_cxo, + .num_parents = 1, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch gp1_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x2d44, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp1_clk", + .parent_names = (const char *[]){ "gp1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg gp2_src = { + .ns_reg = 0x2d64, + .md_reg = 0x2d60, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_map, + }, + .freq_tbl = clk_tbl_gp, + .clkr = { + .enable_reg = 0x2d64, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gp2_src", + .parent_names = gcc_cxo, + .num_parents = 1, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch gp2_clk = { + .halt_reg = 0x2fd8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x2d64, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gp2_clk", + .parent_names = (const char *[]){ "gp2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch pmem_clk = { + .hwcg_reg = 0x25a0, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 20, + .clkr = { + .enable_reg = 0x25a0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "pmem_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_rcg prng_src = { + .ns_reg = 0x2e80, + .p = { + .pre_div_shift = 3, + .pre_div_width = 4, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "prng_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + }, + }, +}; + +static struct clk_branch prng_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "prng_clk", + .parent_names = (const char *[]){ "prng_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + }, + }, +}; + +static const struct freq_tbl clk_tbl_sdc[] = { + { 144000, P_CXO, 1, 1, 133 }, + { 400000, P_PLL8, 4, 1, 240 }, + { 16000000, P_PLL8, 4, 1, 6 }, + { 17070000, P_PLL8, 1, 2, 45 }, + { 20210000, P_PLL8, 1, 1, 19 }, + { 24000000, P_PLL8, 4, 1, 4 }, + { 38400000, P_PLL8, 2, 1, 5 }, + { 48000000, P_PLL8, 4, 1, 2 }, + { 64000000, P_PLL8, 3, 1, 2 }, + { 76800000, P_PLL8, 1, 1, 5 }, + { } +}; + +static struct clk_rcg sdc1_src = { + .ns_reg = 0x282c, + .md_reg = 0x2828, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x282c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc1_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 6, + .clkr = { + .enable_reg = 0x282c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_clk", + .parent_names = (const char *[]){ "sdc1_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg sdc2_src = { + .ns_reg = 0x284c, + .md_reg = 0x2848, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_sdc, + .clkr = { + .enable_reg = 0x284c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch sdc2_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 5, + .clkr = { + .enable_reg = 0x284c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_clk", + .parent_names = (const char *[]){ "sdc2_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_usb[] = { + { 60000000, P_PLL8, 1, 5, 32 }, + { } +}; + +static struct clk_rcg usb_hs1_xcvr_src = { + .ns_reg = 0x290c, + .md_reg = 0x2908, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x290c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_xcvr_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hs1_xcvr_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 0, + .clkr = { + .enable_reg = 0x290c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_xcvr_clk", + .parent_names = (const char *[]){ "usb_hs1_xcvr_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg usb_hsic_xcvr_fs_src = { + .ns_reg = 0x2928, + .md_reg = 0x2924, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb, + .clkr = { + .enable_reg = 0x2928, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_xcvr_fs_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hsic_xcvr_fs_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 9, + .clkr = { + .enable_reg = 0x2928, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_xcvr_fs_clk", + .parent_names = + (const char *[]){ "usb_hsic_xcvr_fs_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_usb_hs1_system[] = { + { 60000000, P_PLL8, 1, 5, 32 }, + { } +}; + +static struct clk_rcg usb_hs1_system_src = { + .ns_reg = 0x36a4, + .md_reg = 0x36a0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb_hs1_system, + .clkr = { + .enable_reg = 0x36a4, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_system_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hs1_system_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 4, + .clkr = { + .enable_reg = 0x36a4, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .parent_names = + (const char *[]){ "usb_hs1_system_src" }, + .num_parents = 1, + .name = "usb_hs1_system_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, + }, + }, +}; + +static const struct freq_tbl clk_tbl_usb_hsic_system[] = { + { 64000000, P_PLL8, 1, 1, 6 }, + { } +}; + +static struct clk_rcg usb_hsic_system_src = { + .ns_reg = 0x2b58, + .md_reg = 0x2b54, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll8_map, + }, + .freq_tbl = clk_tbl_usb_hsic_system, + .clkr = { + .enable_reg = 0x2b58, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_system_src", + .parent_names = gcc_cxo_pll8, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hsic_system_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x2b58, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .parent_names = + (const char *[]){ "usb_hsic_system_src" }, + .num_parents = 1, + .name = "usb_hsic_system_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl clk_tbl_usb_hsic_hsic[] = { + { 48000000, P_PLL14, 1, 0, 0 }, + { } +}; + +static struct clk_rcg usb_hsic_hsic_src = { + .ns_reg = 0x2b50, + .md_reg = 0x2b4c, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = gcc_cxo_pll14_map, + }, + .freq_tbl = clk_tbl_usb_hsic_hsic, + .clkr = { + .enable_reg = 0x2b50, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_hsic_src", + .parent_names = gcc_cxo_pll14, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + } +}; + +static struct clk_branch usb_hsic_hsic_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x2b50, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "usb_hsic_hsic_src" }, + .num_parents = 1, + .name = "usb_hsic_hsic_clk", + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch usb_hsic_hsio_cal_clk = { + .halt_reg = 0x2fc8, + .halt_bit = 8, + .clkr = { + .enable_reg = 0x2b48, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .name = "usb_hsic_hsio_cal_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch ce1_core_clk = { + .hwcg_reg = 0x2724, + .hwcg_bit = 6, + .halt_reg = 0x2fd4, + .halt_bit = 27, + .clkr = { + .enable_reg = 0x2724, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "ce1_core_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch ce1_h_clk = { + .halt_reg = 0x2fd4, + .halt_bit = 1, + .clkr = { + .enable_reg = 0x2720, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "ce1_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch dma_bam_h_clk = { + .hwcg_reg = 0x25c0, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x25c0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "dma_bam_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch gsbi1_h_clk = { + .hwcg_reg = 0x29c0, + .hwcg_bit = 6, + .halt_reg = 0x2fcc, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x29c0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi1_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch gsbi2_h_clk = { + .hwcg_reg = 0x29e0, + .hwcg_bit = 6, + .halt_reg = 0x2fcc, + .halt_bit = 7, + .clkr = { + .enable_reg = 0x29e0, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi2_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch gsbi3_h_clk = { + .hwcg_reg = 0x2a00, + .hwcg_bit = 6, + .halt_reg = 0x2fcc, + .halt_bit = 3, + .clkr = { + .enable_reg = 0x2a00, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi3_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch gsbi4_h_clk = { + .hwcg_reg = 0x2a20, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 27, + .clkr = { + .enable_reg = 0x2a20, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi4_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch gsbi5_h_clk = { + .hwcg_reg = 0x2a40, + .hwcg_bit = 6, + .halt_reg = 0x2fd0, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x2a40, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gsbi5_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch usb_hs1_h_clk = { + .hwcg_reg = 0x2900, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 1, + .clkr = { + .enable_reg = 0x2900, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_hs1_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch usb_hsic_h_clk = { + .halt_reg = 0x2fcc, + .halt_bit = 28, + .clkr = { + .enable_reg = 0x2920, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "usb_hsic_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch sdc1_h_clk = { + .hwcg_reg = 0x2820, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 11, + .clkr = { + .enable_reg = 0x2820, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc1_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch sdc2_h_clk = { + .hwcg_reg = 0x2840, + .hwcg_bit = 6, + .halt_reg = 0x2fc8, + .halt_bit = 10, + .clkr = { + .enable_reg = 0x2840, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "sdc2_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch adm0_clk = { + .halt_reg = 0x2fdc, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 14, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "adm0_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch adm0_pbus_clk = { + .hwcg_reg = 0x2208, + .hwcg_bit = 6, + .halt_reg = 0x2fdc, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 13, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "adm0_pbus_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch pmic_arb0_h_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 22, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "pmic_arb0_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch pmic_arb1_h_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 21, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "pmic_arb1_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch pmic_ssbi2_clk = { + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 23, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "pmic_ssbi2_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_branch rpm_msg_ram_h_clk = { + .hwcg_reg = 0x27e0, + .hwcg_bit = 6, + .halt_reg = 0x2fd8, + .halt_check = BRANCH_HALT_VOTED, + .halt_bit = 12, + .clkr = { + .enable_reg = 0x3080, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "rpm_msg_ram_h_clk", + .ops = &clk_branch_ops, + }, + }, +}; + +static struct clk_hw *gcc_mdm9615_hws[] = { + &cxo.hw, +}; + +static struct clk_regmap *gcc_mdm9615_clks[] = { + [PLL0] = &pll0.clkr, + [PLL0_VOTE] = &pll0_vote, + [PLL4_VOTE] = &pll4_vote, + [PLL8] = &pll8.clkr, + [PLL8_VOTE] = &pll8_vote, + [PLL14] = &pll14.clkr, + [PLL14_VOTE] = &pll14_vote, + [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr, + [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr, + [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr, + [GSBI2_UART_CLK] = &gsbi2_uart_clk.clkr, + [GSBI3_UART_SRC] = &gsbi3_uart_src.clkr, + [GSBI3_UART_CLK] = &gsbi3_uart_clk.clkr, + [GSBI4_UART_SRC] = &gsbi4_uart_src.clkr, + [GSBI4_UART_CLK] = &gsbi4_uart_clk.clkr, + [GSBI5_UART_SRC] = &gsbi5_uart_src.clkr, + [GSBI5_UART_CLK] = &gsbi5_uart_clk.clkr, + [GSBI1_QUP_SRC] = &gsbi1_qup_src.clkr, + [GSBI1_QUP_CLK] = &gsbi1_qup_clk.clkr, + [GSBI2_QUP_SRC] = &gsbi2_qup_src.clkr, + [GSBI2_QUP_CLK] = &gsbi2_qup_clk.clkr, + [GSBI3_QUP_SRC] = &gsbi3_qup_src.clkr, + [GSBI3_QUP_CLK] = &gsbi3_qup_clk.clkr, + [GSBI4_QUP_SRC] = &gsbi4_qup_src.clkr, + [GSBI4_QUP_CLK] = &gsbi4_qup_clk.clkr, + [GSBI5_QUP_SRC] = &gsbi5_qup_src.clkr, + [GSBI5_QUP_CLK] = &gsbi5_qup_clk.clkr, + [GP0_SRC] = &gp0_src.clkr, + [GP0_CLK] = &gp0_clk.clkr, + [GP1_SRC] = &gp1_src.clkr, + [GP1_CLK] = &gp1_clk.clkr, + [GP2_SRC] = &gp2_src.clkr, + [GP2_CLK] = &gp2_clk.clkr, + [PMEM_A_CLK] = &pmem_clk.clkr, + [PRNG_SRC] = &prng_src.clkr, + [PRNG_CLK] = &prng_clk.clkr, + [SDC1_SRC] = &sdc1_src.clkr, + [SDC1_CLK] = &sdc1_clk.clkr, + [SDC2_SRC] = &sdc2_src.clkr, + [SDC2_CLK] = &sdc2_clk.clkr, + [USB_HS1_XCVR_SRC] = &usb_hs1_xcvr_src.clkr, + [USB_HS1_XCVR_CLK] = &usb_hs1_xcvr_clk.clkr, + [USB_HS1_SYSTEM_CLK_SRC] = &usb_hs1_system_src.clkr, + [USB_HS1_SYSTEM_CLK] = &usb_hs1_system_clk.clkr, + [USB_HSIC_XCVR_FS_SRC] = &usb_hsic_xcvr_fs_src.clkr, + [USB_HSIC_XCVR_FS_CLK] = &usb_hsic_xcvr_fs_clk.clkr, + [USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_src.clkr, + [USB_HSIC_SYSTEM_CLK] = &usb_hsic_system_clk.clkr, + [USB_HSIC_HSIC_CLK_SRC] = &usb_hsic_hsic_src.clkr, + [USB_HSIC_HSIC_CLK] = &usb_hsic_hsic_clk.clkr, + [USB_HSIC_HSIO_CAL_CLK] = &usb_hsic_hsio_cal_clk.clkr, + [CE1_CORE_CLK] = &ce1_core_clk.clkr, + [CE1_H_CLK] = &ce1_h_clk.clkr, + [DMA_BAM_H_CLK] = &dma_bam_h_clk.clkr, + [GSBI1_H_CLK] = &gsbi1_h_clk.clkr, + [GSBI2_H_CLK] = &gsbi2_h_clk.clkr, + [GSBI3_H_CLK] = &gsbi3_h_clk.clkr, + [GSBI4_H_CLK] = &gsbi4_h_clk.clkr, + [GSBI5_H_CLK] = &gsbi5_h_clk.clkr, + [USB_HS1_H_CLK] = &usb_hs1_h_clk.clkr, + [USB_HSIC_H_CLK] = &usb_hsic_h_clk.clkr, + [SDC1_H_CLK] = &sdc1_h_clk.clkr, + [SDC2_H_CLK] = &sdc2_h_clk.clkr, + [ADM0_CLK] = &adm0_clk.clkr, + [ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr, + [PMIC_ARB0_H_CLK] = &pmic_arb0_h_clk.clkr, + [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, + [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, + [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, +}; + +static const struct qcom_reset_map gcc_mdm9615_resets[] = { + [DMA_BAM_RESET] = { 0x25c0, 7 }, + [CE1_H_RESET] = { 0x2720, 7 }, + [CE1_CORE_RESET] = { 0x2724, 7 }, + [SDC1_RESET] = { 0x2830 }, + [SDC2_RESET] = { 0x2850 }, + [ADM0_C2_RESET] = { 0x220c, 4 }, + [ADM0_C1_RESET] = { 0x220c, 3 }, + [ADM0_C0_RESET] = { 0x220c, 2 }, + [ADM0_PBUS_RESET] = { 0x220c, 1 }, + [ADM0_RESET] = { 0x220c }, + [USB_HS1_RESET] = { 0x2910 }, + [USB_HSIC_RESET] = { 0x2934 }, + [GSBI1_RESET] = { 0x29dc }, + [GSBI2_RESET] = { 0x29fc }, + [GSBI3_RESET] = { 0x2a1c }, + [GSBI4_RESET] = { 0x2a3c }, + [GSBI5_RESET] = { 0x2a5c }, + [PDM_RESET] = { 0x2CC0, 12 }, +}; + +static const struct regmap_config gcc_mdm9615_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x3660, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_mdm9615_desc = { + .config = &gcc_mdm9615_regmap_config, + .clks = gcc_mdm9615_clks, + .num_clks = ARRAY_SIZE(gcc_mdm9615_clks), + .resets = gcc_mdm9615_resets, + .num_resets = ARRAY_SIZE(gcc_mdm9615_resets), +}; + +static const struct of_device_id gcc_mdm9615_match_table[] = { + { .compatible = "qcom,gcc-mdm9615" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_mdm9615_match_table); + +static int gcc_mdm9615_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + int ret; + int i; + + regmap = qcom_cc_map(pdev, &gcc_mdm9615_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + for (i = 0; i < ARRAY_SIZE(gcc_mdm9615_hws); i++) { + ret = devm_clk_hw_register(dev, gcc_mdm9615_hws[i]); + if (ret) + return ret; + } + + return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap); +} + +static struct platform_driver gcc_mdm9615_driver = { + .probe = gcc_mdm9615_probe, + .driver = { + .name = "gcc-mdm9615", + .of_match_table = gcc_mdm9615_match_table, + }, +}; + +static int __init gcc_mdm9615_init(void) +{ + return platform_driver_register(&gcc_mdm9615_driver); +} +core_initcall(gcc_mdm9615_init); + +static void __exit gcc_mdm9615_exit(void) +{ + platform_driver_unregister(&gcc_mdm9615_driver); +} +module_exit(gcc_mdm9615_exit); + +MODULE_DESCRIPTION("QCOM GCC MDM9615 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:gcc-mdm9615"); diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index bbf732bbc3fd..ebe5d187fa1b 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -2592,9 +2592,9 @@ static struct clk_branch gcc_pcie_2_aux_clk = { }; static struct clk_branch gcc_pcie_2_pipe_clk = { - .halt_reg = 0x6e108, + .halt_reg = 0x6e018, .clkr = { - .enable_reg = 0x6e108, + .enable_reg = 0x6e018, .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_pcie_2_pipe_clk", @@ -3404,6 +3404,8 @@ static const struct qcom_reset_map gcc_msm8996_resets[] = { [GCC_PCIE_2_BCR] = { 0x6e000 }, [GCC_PCIE_2_PHY_BCR] = { 0x6e038 }, [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f014 }, + [GCC_PCIE_PHY_COM_NOCSR_BCR] = { 0x6f00c }, [GCC_DCD_BCR] = { 0x70000 }, [GCC_OBT_ODT_BCR] = { 0x73000 }, [GCC_UFS_BCR] = { 0x75000 }, @@ -3447,9 +3449,8 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table); static int gcc_msm8996_probe(struct platform_device *pdev) { - struct clk *clk; struct device *dev = &pdev->dev; - int i; + int i, ret; struct regmap *regmap; regmap = qcom_cc_map(pdev, &gcc_msm8996_desc); @@ -3463,9 +3464,9 @@ static int gcc_msm8996_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21)); for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) { - clk = devm_clk_register(dev, gcc_msm8996_hws[i]); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, gcc_msm8996_hws[i]); + if (ret) + return ret; } return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); diff --git a/drivers/clk/qcom/lcc-mdm9615.c b/drivers/clk/qcom/lcc-mdm9615.c new file mode 100644 index 000000000000..3237ef4c1197 --- /dev/null +++ b/drivers/clk/qcom/lcc-mdm9615.c @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) BayLibre, SAS. + * Author : Neil Armstrong <narmstrong@baylibre.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> + +#include <dt-bindings/clock/qcom,lcc-mdm9615.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" + +static struct clk_pll pll4 = { + .l_reg = 0x4, + .m_reg = 0x8, + .n_reg = 0xc, + .config_reg = 0x14, + .mode_reg = 0x0, + .status_reg = 0x18, + .status_bit = 16, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pll4", + .parent_names = (const char *[]){ "cxo" }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +enum { + P_CXO, + P_PLL4, +}; + +static const struct parent_map lcc_cxo_pll4_map[] = { + { P_CXO, 0 }, + { P_PLL4, 2 } +}; + +static const char * const lcc_cxo_pll4[] = { + "cxo", + "pll4_vote", +}; + +static struct freq_tbl clk_tbl_aif_osr_492[] = { + { 512000, P_PLL4, 4, 1, 240 }, + { 768000, P_PLL4, 4, 1, 160 }, + { 1024000, P_PLL4, 4, 1, 120 }, + { 1536000, P_PLL4, 4, 1, 80 }, + { 2048000, P_PLL4, 4, 1, 60 }, + { 3072000, P_PLL4, 4, 1, 40 }, + { 4096000, P_PLL4, 4, 1, 30 }, + { 6144000, P_PLL4, 4, 1, 20 }, + { 8192000, P_PLL4, 4, 1, 15 }, + { 12288000, P_PLL4, 4, 1, 10 }, + { 24576000, P_PLL4, 4, 1, 5 }, + { 27000000, P_CXO, 1, 0, 0 }, + { } +}; + +static struct freq_tbl clk_tbl_aif_osr_393[] = { + { 512000, P_PLL4, 4, 1, 192 }, + { 768000, P_PLL4, 4, 1, 128 }, + { 1024000, P_PLL4, 4, 1, 96 }, + { 1536000, P_PLL4, 4, 1, 64 }, + { 2048000, P_PLL4, 4, 1, 48 }, + { 3072000, P_PLL4, 4, 1, 32 }, + { 4096000, P_PLL4, 4, 1, 24 }, + { 6144000, P_PLL4, 4, 1, 16 }, + { 8192000, P_PLL4, 4, 1, 12 }, + { 12288000, P_PLL4, 4, 1, 8 }, + { 24576000, P_PLL4, 4, 1, 4 }, + { 27000000, P_CXO, 1, 0, 0 }, + { } +}; + +static struct clk_rcg mi2s_osr_src = { + .ns_reg = 0x48, + .md_reg = 0x4c, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = lcc_cxo_pll4_map, + }, + .freq_tbl = clk_tbl_aif_osr_393, + .clkr = { + .enable_reg = 0x48, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "mi2s_osr_src", + .parent_names = lcc_cxo_pll4, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + }, +}; + +static const char * const lcc_mi2s_parents[] = { + "mi2s_osr_src", +}; + +static struct clk_branch mi2s_osr_clk = { + .halt_reg = 0x50, + .halt_bit = 1, + .halt_check = BRANCH_HALT_ENABLE, + .clkr = { + .enable_reg = 0x48, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "mi2s_osr_clk", + .parent_names = lcc_mi2s_parents, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_div mi2s_div_clk = { + .reg = 0x48, + .shift = 10, + .width = 4, + .clkr = { + .enable_reg = 0x48, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "mi2s_div_clk", + .parent_names = lcc_mi2s_parents, + .num_parents = 1, + .ops = &clk_regmap_div_ops, + }, + }, +}; + +static struct clk_branch mi2s_bit_div_clk = { + .halt_reg = 0x50, + .halt_bit = 0, + .halt_check = BRANCH_HALT_ENABLE, + .clkr = { + .enable_reg = 0x48, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "mi2s_bit_div_clk", + .parent_names = (const char *[]){ "mi2s_div_clk" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_mux mi2s_bit_clk = { + .reg = 0x48, + .shift = 14, + .width = 1, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "mi2s_bit_clk", + .parent_names = (const char *[]){ + "mi2s_bit_div_clk", + "mi2s_codec_clk", + }, + .num_parents = 2, + .ops = &clk_regmap_mux_closest_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr) \ +static struct clk_rcg prefix##_osr_src = { \ + .ns_reg = _ns, \ + .md_reg = _md, \ + .mn = { \ + .mnctr_en_bit = 8, \ + .mnctr_reset_bit = 7, \ + .mnctr_mode_shift = 5, \ + .n_val_shift = 24, \ + .m_val_shift = 8, \ + .width = 8, \ + }, \ + .p = { \ + .pre_div_shift = 3, \ + .pre_div_width = 2, \ + }, \ + .s = { \ + .src_sel_shift = 0, \ + .parent_map = lcc_cxo_pll4_map, \ + }, \ + .freq_tbl = clk_tbl_aif_osr_393, \ + .clkr = { \ + .enable_reg = _ns, \ + .enable_mask = BIT(9), \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_osr_src", \ + .parent_names = lcc_cxo_pll4, \ + .num_parents = 2, \ + .ops = &clk_rcg_ops, \ + .flags = CLK_SET_RATE_GATE, \ + }, \ + }, \ +}; \ + \ +static const char * const lcc_##prefix##_parents[] = { \ + #prefix "_osr_src", \ +}; \ + \ +static struct clk_branch prefix##_osr_clk = { \ + .halt_reg = hr, \ + .halt_bit = 1, \ + .halt_check = BRANCH_HALT_ENABLE, \ + .clkr = { \ + .enable_reg = _ns, \ + .enable_mask = BIT(21), \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_osr_clk", \ + .parent_names = lcc_##prefix##_parents, \ + .num_parents = 1, \ + .ops = &clk_branch_ops, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; \ + \ +static struct clk_regmap_div prefix##_div_clk = { \ + .reg = _ns, \ + .shift = 10, \ + .width = 8, \ + .clkr = { \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_div_clk", \ + .parent_names = lcc_##prefix##_parents, \ + .num_parents = 1, \ + .ops = &clk_regmap_div_ops, \ + }, \ + }, \ +}; \ + \ +static struct clk_branch prefix##_bit_div_clk = { \ + .halt_reg = hr, \ + .halt_bit = 0, \ + .halt_check = BRANCH_HALT_ENABLE, \ + .clkr = { \ + .enable_reg = _ns, \ + .enable_mask = BIT(19), \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_bit_div_clk", \ + .parent_names = (const char *[]){ \ + #prefix "_div_clk" \ + }, \ + .num_parents = 1, \ + .ops = &clk_branch_ops, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ + }, \ +}; \ + \ +static struct clk_regmap_mux prefix##_bit_clk = { \ + .reg = _ns, \ + .shift = 18, \ + .width = 1, \ + .clkr = { \ + .hw.init = &(struct clk_init_data){ \ + .name = #prefix "_bit_clk", \ + .parent_names = (const char *[]){ \ + #prefix "_bit_div_clk", \ + #prefix "_codec_clk", \ + }, \ + .num_parents = 2, \ + .ops = &clk_regmap_mux_closest_ops, \ + .flags = CLK_SET_RATE_PARENT, \ + }, \ + }, \ +} + +CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68); +CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80); +CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74); +CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c); + +static struct freq_tbl clk_tbl_pcm_492[] = { + { 256000, P_PLL4, 4, 1, 480 }, + { 512000, P_PLL4, 4, 1, 240 }, + { 768000, P_PLL4, 4, 1, 160 }, + { 1024000, P_PLL4, 4, 1, 120 }, + { 1536000, P_PLL4, 4, 1, 80 }, + { 2048000, P_PLL4, 4, 1, 60 }, + { 3072000, P_PLL4, 4, 1, 40 }, + { 4096000, P_PLL4, 4, 1, 30 }, + { 6144000, P_PLL4, 4, 1, 20 }, + { 8192000, P_PLL4, 4, 1, 15 }, + { 12288000, P_PLL4, 4, 1, 10 }, + { 24576000, P_PLL4, 4, 1, 5 }, + { 27000000, P_CXO, 1, 0, 0 }, + { } +}; + +static struct freq_tbl clk_tbl_pcm_393[] = { + { 256000, P_PLL4, 4, 1, 384 }, + { 512000, P_PLL4, 4, 1, 192 }, + { 768000, P_PLL4, 4, 1, 128 }, + { 1024000, P_PLL4, 4, 1, 96 }, + { 1536000, P_PLL4, 4, 1, 64 }, + { 2048000, P_PLL4, 4, 1, 48 }, + { 3072000, P_PLL4, 4, 1, 32 }, + { 4096000, P_PLL4, 4, 1, 24 }, + { 6144000, P_PLL4, 4, 1, 16 }, + { 8192000, P_PLL4, 4, 1, 12 }, + { 12288000, P_PLL4, 4, 1, 8 }, + { 24576000, P_PLL4, 4, 1, 4 }, + { 27000000, P_CXO, 1, 0, 0 }, + { } +}; + +static struct clk_rcg pcm_src = { + .ns_reg = 0x54, + .md_reg = 0x58, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 16, + .m_val_shift = 16, + .width = 16, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = lcc_cxo_pll4_map, + }, + .freq_tbl = clk_tbl_pcm_393, + .clkr = { + .enable_reg = 0x54, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "pcm_src", + .parent_names = lcc_cxo_pll4, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + }, +}; + +static struct clk_branch pcm_clk_out = { + .halt_reg = 0x5c, + .halt_bit = 0, + .halt_check = BRANCH_HALT_ENABLE, + .clkr = { + .enable_reg = 0x54, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "pcm_clk_out", + .parent_names = (const char *[]){ "pcm_src" }, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap_mux pcm_clk = { + .reg = 0x54, + .shift = 10, + .width = 1, + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "pcm_clk", + .parent_names = (const char *[]){ + "pcm_clk_out", + "pcm_codec_clk", + }, + .num_parents = 2, + .ops = &clk_regmap_mux_closest_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg slimbus_src = { + .ns_reg = 0xcc, + .md_reg = 0xd0, + .mn = { + .mnctr_en_bit = 8, + .mnctr_reset_bit = 7, + .mnctr_mode_shift = 5, + .n_val_shift = 24, + .m_val_shift = 8, + .width = 8, + }, + .p = { + .pre_div_shift = 3, + .pre_div_width = 2, + }, + .s = { + .src_sel_shift = 0, + .parent_map = lcc_cxo_pll4_map, + }, + .freq_tbl = clk_tbl_aif_osr_393, + .clkr = { + .enable_reg = 0xcc, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "slimbus_src", + .parent_names = lcc_cxo_pll4, + .num_parents = 2, + .ops = &clk_rcg_ops, + .flags = CLK_SET_RATE_GATE, + }, + }, +}; + +static const char * const lcc_slimbus_parents[] = { + "slimbus_src", +}; + +static struct clk_branch audio_slimbus_clk = { + .halt_reg = 0xd4, + .halt_bit = 0, + .halt_check = BRANCH_HALT_ENABLE, + .clkr = { + .enable_reg = 0xcc, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "audio_slimbus_clk", + .parent_names = lcc_slimbus_parents, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch sps_slimbus_clk = { + .halt_reg = 0xd4, + .halt_bit = 1, + .halt_check = BRANCH_HALT_ENABLE, + .clkr = { + .enable_reg = 0xcc, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "sps_slimbus_clk", + .parent_names = lcc_slimbus_parents, + .num_parents = 1, + .ops = &clk_branch_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap *lcc_mdm9615_clks[] = { + [PLL4] = &pll4.clkr, + [MI2S_OSR_SRC] = &mi2s_osr_src.clkr, + [MI2S_OSR_CLK] = &mi2s_osr_clk.clkr, + [MI2S_DIV_CLK] = &mi2s_div_clk.clkr, + [MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr, + [MI2S_BIT_CLK] = &mi2s_bit_clk.clkr, + [PCM_SRC] = &pcm_src.clkr, + [PCM_CLK_OUT] = &pcm_clk_out.clkr, + [PCM_CLK] = &pcm_clk.clkr, + [SLIMBUS_SRC] = &slimbus_src.clkr, + [AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr, + [SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr, + [CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr, + [CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr, + [CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr, + [CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr, + [CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr, + [SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr, + [SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr, + [SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr, + [SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr, + [SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr, + [CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr, + [CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr, + [CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr, + [CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr, + [CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr, + [SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr, + [SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr, + [SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr, + [SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr, + [SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr, +}; + +static const struct regmap_config lcc_mdm9615_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xfc, + .fast_io = true, +}; + +static const struct qcom_cc_desc lcc_mdm9615_desc = { + .config = &lcc_mdm9615_regmap_config, + .clks = lcc_mdm9615_clks, + .num_clks = ARRAY_SIZE(lcc_mdm9615_clks), +}; + +static const struct of_device_id lcc_mdm9615_match_table[] = { + { .compatible = "qcom,lcc-mdm9615" }, + { } +}; +MODULE_DEVICE_TABLE(of, lcc_mdm9615_match_table); + +static int lcc_mdm9615_probe(struct platform_device *pdev) +{ + u32 val; + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &lcc_mdm9615_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Use the correct frequency plan depending on speed of PLL4 */ + regmap_read(regmap, 0x4, &val); + if (val == 0x12) { + slimbus_src.freq_tbl = clk_tbl_aif_osr_492; + mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492; + codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492; + spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492; + codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492; + spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492; + pcm_src.freq_tbl = clk_tbl_pcm_492; + } + /* Enable PLL4 source on the LPASS Primary PLL Mux */ + regmap_write(regmap, 0xc4, 0x1); + + return qcom_cc_really_probe(pdev, &lcc_mdm9615_desc, regmap); +} + +static struct platform_driver lcc_mdm9615_driver = { + .probe = lcc_mdm9615_probe, + .driver = { + .name = "lcc-mdm9615", + .of_match_table = lcc_mdm9615_match_table, + }, +}; +module_platform_driver(lcc_mdm9615_driver); + +MODULE_DESCRIPTION("QCOM LCC MDM9615 Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:lcc-mdm9615"); diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 847dd9dadeca..ca97e1151797 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -2888,6 +2888,14 @@ static struct clk_hw *mmcc_msm8996_hws[] = { &gpll0_div.hw, }; +static struct gdsc mmagic_bimc_gdsc = { + .gdscr = 0x529c, + .pd = { + .name = "mmagic_bimc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct gdsc mmagic_video_gdsc = { .gdscr = 0x119c, .gds_hw_ctrl = 0x120c, @@ -3201,6 +3209,7 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = { }; static struct gdsc *mmcc_msm8996_gdscs[] = { + [MMAGIC_BIMC_GDSC] = &mmagic_bimc_gdsc, [MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc, [MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc, [MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc, @@ -3305,9 +3314,8 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8996_match_table); static int mmcc_msm8996_probe(struct platform_device *pdev) { - struct clk *clk; struct device *dev = &pdev->dev; - int i; + int i, ret; struct regmap *regmap; regmap = qcom_cc_map(pdev, &mmcc_msm8996_desc); @@ -3320,9 +3328,9 @@ static int mmcc_msm8996_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x5054, BIT(15), 0); for (i = 0; i < ARRAY_SIZE(mmcc_msm8996_hws); i++) { - clk = devm_clk_register(dev, mmcc_msm8996_hws[i]); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, mmcc_msm8996_hws[i]); + if (ret) + return ret; } return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap); diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index d359c92e13a6..e38bf60c0ff4 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -69,6 +69,7 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), /* Core Clock Outputs */ DEF_FIXED("ztr", R8A7795_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), @@ -87,10 +88,10 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), - DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), - DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), - DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), - DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), + DEF_GEN3_SD("sd0", R8A7795_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A7795_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd2", R8A7795_CLK_SD2, CLK_SDSRC, 0x0268), + DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x026c), DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index c84b549c14d2..891b353e8105 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -45,6 +45,7 @@ enum clk_ids { CLK_S3, CLK_SDSRC, CLK_SSPSRC, + CLK_RINT, /* Module Clocks */ MOD_CLK_BASE @@ -69,6 +70,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), /* Core Clock Outputs */ DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), @@ -92,13 +94,36 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1), + DEF_GEN3_SD("sd0", R8A7796_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A7796_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd2", R8A7796_CLK_SD2, CLK_SDSRC, 0x0268), + DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, CLK_SDSRC, 0x026c), + DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_BASE("r", R8A7796_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { DEF_MOD("scif2", 310, R8A7796_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A7796_CLK_SD3), + DEF_MOD("sdif2", 312, R8A7796_CLK_SD2), + DEF_MOD("sdif1", 313, R8A7796_CLK_SD1), + DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), + DEF_MOD("rwdt0", 402, R8A7796_CLK_R), DEF_MOD("intc-ap", 408, R8A7796_CLK_S3D1), + DEF_MOD("gpio7", 905, R8A7796_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A7796_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A7796_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A7796_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A7796_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A7796_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A7796_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A7796_CLK_S3D4), }; static const unsigned int r8a7796_crit_mod_clks[] __initconst = { diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index c109d80e7a8a..cdfabeb9a034 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -833,9 +833,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* perihp */ GATE(0, "cpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED, - RK3399_CLKGATE_CON(5), 0, GFLAGS), - GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(5), 1, GFLAGS), + GATE(0, "gpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(5), 0, GFLAGS), COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS, RK3399_CLKGATE_CON(5), 2, GFLAGS), @@ -923,9 +923,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKGATE_CON(6), 14, GFLAGS), GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED, - RK3399_CLKGATE_CON(6), 12, GFLAGS), - GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(6), 13, GFLAGS), + GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(6), 12, GFLAGS), COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS), GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED, @@ -1071,7 +1071,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* vio */ COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, - RK3399_CLKGATE_CON(11), 10, GFLAGS), + RK3399_CLKGATE_CON(11), 0, GFLAGS), COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0, RK3399_CLKSEL_CON(43), 0, 5, DFLAGS, RK3399_CLKGATE_CON(11), 1, GFLAGS), @@ -1484,6 +1484,7 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { "hclk_perilp1", "hclk_perilp1_noc", "aclk_dmac0_perilp", + "aclk_emmc_noc", "gpll_hclk_perilp1_src", "gpll_aclk_perilp0_src", "gpll_aclk_perihp_src", diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index fc17b5295e16..51d4bac97ab3 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -31,7 +31,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) return; WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg, - !(reg & lock), 100, 70000)); + reg & lock, 100, 70000)); } int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index b38d71cec74c..e54266cc1c51 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -91,7 +91,8 @@ static void __init sun4i_a10_mod0_setup(struct device_node *node) sunxi_factors_register(node, &sun4i_a10_mod0_data, &sun4i_a10_mod0_lock, reg); } -CLK_OF_DECLARE(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", sun4i_a10_mod0_setup); +CLK_OF_DECLARE_DRIVER(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk", + sun4i_a10_mod0_setup); static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev) { diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c index a5666e1d0ce7..ea1eed24778c 100644 --- a/drivers/clk/sunxi/clk-sun8i-apb0.c +++ b/drivers/clk/sunxi/clk-sun8i-apb0.c @@ -82,8 +82,8 @@ err_unmap: of_address_to_resource(node, 0, &res); release_mem_region(res.start, resource_size(&res)); } -CLK_OF_DECLARE(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk", - sun8i_a23_apb0_setup); +CLK_OF_DECLARE_DRIVER(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk", + sun8i_a23_apb0_setup); static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev) { diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 64da7b79a6e4..933b5dd698b8 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -428,7 +428,7 @@ static struct tegra_clk_pll_params pll_d_params = { .div_nmp = &pllp_nmp, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + TEGRA_PLL_HAS_LOCK_ENABLE, }; static struct tegra_clk_pll_params pll_d2_params = { @@ -446,7 +446,7 @@ static struct tegra_clk_pll_params pll_d2_params = { .div_nmp = &pllp_nmp, .freq_table = pll_d_freq_table, .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | - TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, + TEGRA_PLL_HAS_LOCK_ENABLE, }; static const struct pdiv_map pllu_p[] = { diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 5e9b65278e4c..4faa94440779 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -27,6 +27,26 @@ /* Magic unlocking token used on all Versatile boards */ #define VERSATILE_LOCK_VAL 0xA05F +#define VERSATILE_AUX_OSC_BITS 0x7FFFF +#define INTEGRATOR_AP_CM_BITS 0xFF +#define INTEGRATOR_AP_SYS_BITS 0xFF +#define INTEGRATOR_CP_CM_CORE_BITS 0x7FF +#define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000 + +#define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8) + +/** + * enum icst_control_type - the type of ICST control register + */ +enum icst_control_type { + ICST_VERSATILE, /* The standard type, all control bits available */ + ICST_INTEGRATOR_AP_CM, /* Only 8 bits of VDW available */ + ICST_INTEGRATOR_AP_SYS, /* Only 8 bits of VDW available */ + ICST_INTEGRATOR_AP_PCI, /* Odd bit pattern storage */ + ICST_INTEGRATOR_CP_CM_CORE, /* Only 8 bits of VDW and 3 bits of OD */ + ICST_INTEGRATOR_CP_CM_MEM, /* Only 8 bits of VDW and 3 bits of OD */ +}; + /** * struct clk_icst - ICST VCO clock wrapper * @hw: corresponding clock hardware entry @@ -34,6 +54,7 @@ * @lockreg: VCO lock register address * @params: parameters for this ICST instance * @rate: current rate + * @ctype: the type of control register for the ICST */ struct clk_icst { struct clk_hw hw; @@ -42,6 +63,7 @@ struct clk_icst { u32 lockreg_off; struct icst_params *params; unsigned long rate; + enum icst_control_type ctype; }; #define to_icst(_hw) container_of(_hw, struct clk_icst, hw) @@ -59,6 +81,76 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco) ret = regmap_read(icst->map, icst->vcoreg_off, &val); if (ret) return ret; + + /* + * The Integrator/AP core clock can only access the low eight + * bits of the v PLL divider. Bit 8 is tied low and always zero, + * r is hardwired to 22 and output divider s is hardwired to 1 + * (divide by 2) according to the document + * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and + * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14. + */ + if (icst->ctype == ICST_INTEGRATOR_AP_CM) { + vco->v = val & INTEGRATOR_AP_CM_BITS; + vco->r = 22; + vco->s = 1; + return 0; + } + + /* + * The Integrator/AP system clock on the base board can only + * access the low eight bits of the v PLL divider. Bit 8 is tied low + * and always zero, r is hardwired to 46, and the output divider is + * hardwired to 3 (divide by 4) according to the document + * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B, + * page 3-16. + */ + if (icst->ctype == ICST_INTEGRATOR_AP_SYS) { + vco->v = val & INTEGRATOR_AP_SYS_BITS; + vco->r = 46; + vco->s = 3; + return 0; + } + + /* + * The Integrator/AP PCI clock is using an odd pattern to create + * the child clock, basically a single bit called DIVX/Y is used + * to select between two different hardwired values: setting the + * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the + * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies + * 33 or 25 MHz respectively. + */ + if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { + bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ); + + vco->v = divxy ? 17 : 14; + vco->r = divxy ? 22 : 14; + vco->s = 1; + return 0; + } + + /* + * The Integrator/CP core clock can access the low eight bits + * of the v PLL divider. Bit 8 is tied low and always zero, + * r is hardwired to 22 and the output divider s is accessible + * in bits 8 thru 10 according to the document + * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide" + * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10. + */ + if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) { + vco->v = val & 0xFF; + vco->r = 22; + vco->s = (val >> 8) & 7; + return 0; + } + + if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) { + vco->v = (val >> 12) & 0xFF; + vco->r = 22; + vco->s = (val >> 20) & 7; + return 0; + } + vco->v = val & 0x1ff; vco->r = (val >> 9) & 0x7f; vco->s = (val >> 16) & 03; @@ -72,22 +164,62 @@ static int vco_get(struct clk_icst *icst, struct icst_vco *vco) */ static int vco_set(struct clk_icst *icst, struct icst_vco vco) { + u32 mask; u32 val; int ret; - ret = regmap_read(icst->map, icst->vcoreg_off, &val); - if (ret) - return ret; + /* Mask the bits used by the VCO */ + switch (icst->ctype) { + case ICST_INTEGRATOR_AP_CM: + mask = INTEGRATOR_AP_CM_BITS; + val = vco.v & 0xFF; + if (vco.v & 0x100) + pr_err("ICST error: tried to set bit 8 of VDW\n"); + if (vco.s != 1) + pr_err("ICST error: tried to use VOD != 1\n"); + if (vco.r != 22) + pr_err("ICST error: tried to use RDW != 22\n"); + break; + case ICST_INTEGRATOR_AP_SYS: + mask = INTEGRATOR_AP_SYS_BITS; + val = vco.v & 0xFF; + if (vco.v & 0x100) + pr_err("ICST error: tried to set bit 8 of VDW\n"); + if (vco.s != 3) + pr_err("ICST error: tried to use VOD != 1\n"); + if (vco.r != 46) + pr_err("ICST error: tried to use RDW != 22\n"); + break; + case ICST_INTEGRATOR_CP_CM_CORE: + mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */ + val = (vco.v & 0xFF) | vco.s << 8; + if (vco.v & 0x100) + pr_err("ICST error: tried to set bit 8 of VDW\n"); + if (vco.r != 22) + pr_err("ICST error: tried to use RDW != 22\n"); + break; + case ICST_INTEGRATOR_CP_CM_MEM: + mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */ + val = ((vco.v & 0xFF) << 12) | (vco.s << 20); + if (vco.v & 0x100) + pr_err("ICST error: tried to set bit 8 of VDW\n"); + if (vco.r != 22) + pr_err("ICST error: tried to use RDW != 22\n"); + break; + default: + /* Regular auxilary oscillator */ + mask = VERSATILE_AUX_OSC_BITS; + val = vco.v | (vco.r << 9) | (vco.s << 16); + break; + } - /* Mask the 18 bits used by the VCO */ - val &= ~0x7ffff; - val |= vco.v | (vco.r << 9) | (vco.s << 16); + pr_debug("ICST: new val = 0x%08x\n", val); /* This magic unlocks the VCO so it can be controlled */ ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL); if (ret) return ret; - ret = regmap_write(icst->map, icst->vcoreg_off, val); + ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val); if (ret) return ret; /* This locks the VCO again */ @@ -121,6 +253,46 @@ static long icst_round_rate(struct clk_hw *hw, unsigned long rate, struct clk_icst *icst = to_icst(hw); struct icst_vco vco; + if (icst->ctype == ICST_INTEGRATOR_AP_CM || + icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) { + if (rate <= 12000000) + return 12000000; + if (rate >= 160000000) + return 160000000; + /* Slam to closest megahertz */ + return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000; + } + + if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) { + if (rate <= 6000000) + return 6000000; + if (rate >= 66000000) + return 66000000; + /* Slam to closest 0.5 megahertz */ + return DIV_ROUND_CLOSEST(rate, 500000) * 500000; + } + + if (icst->ctype == ICST_INTEGRATOR_AP_SYS) { + /* Divides between 3 and 50 MHz in steps of 0.25 MHz */ + if (rate <= 3000000) + return 3000000; + if (rate >= 50000000) + return 5000000; + /* Slam to closest 0.25 MHz */ + return DIV_ROUND_CLOSEST(rate, 250000) * 250000; + } + + if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { + /* + * If we're below or less than halfway from 25 to 33 MHz + * select 25 MHz + */ + if (rate <= 25000000 || rate < 29000000) + return 25000000; + /* Else just return the default frequency */ + return 33000000; + } + vco = icst_hz_to_vco(icst->params, rate); return icst_hz(icst->params, vco); } @@ -131,6 +303,36 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate, struct clk_icst *icst = to_icst(hw); struct icst_vco vco; + if (icst->ctype == ICST_INTEGRATOR_AP_PCI) { + /* This clock is especially primitive */ + unsigned int val; + int ret; + + if (rate == 25000000) { + val = 0; + } else if (rate == 33000000) { + val = INTEGRATOR_AP_PCI_25_33_MHZ; + } else { + pr_err("ICST: cannot set PCI frequency %lu\n", + rate); + return -EINVAL; + } + ret = regmap_write(icst->map, icst->lockreg_off, + VERSATILE_LOCK_VAL); + if (ret) + return ret; + ret = regmap_update_bits(icst->map, icst->vcoreg_off, + INTEGRATOR_AP_PCI_25_33_MHZ, + val); + if (ret) + return ret; + /* This locks the VCO again */ + ret = regmap_write(icst->map, icst->lockreg_off, 0); + if (ret) + return ret; + return 0; + } + if (parent_rate) icst->params->ref = parent_rate; vco = icst_hz_to_vco(icst->params, rate); @@ -148,7 +350,8 @@ static struct clk *icst_clk_setup(struct device *dev, const struct clk_icst_desc *desc, const char *name, const char *parent_name, - struct regmap *map) + struct regmap *map, + enum icst_control_type ctype) { struct clk *clk; struct clk_icst *icst; @@ -178,6 +381,7 @@ static struct clk *icst_clk_setup(struct device *dev, icst->params = pclone; icst->vcoreg_off = desc->vco_offset; icst->lockreg_off = desc->lock_offset; + icst->ctype = ctype; clk = clk_register(dev, &icst->hw); if (IS_ERR(clk)) { @@ -206,7 +410,8 @@ struct clk *icst_clk_register(struct device *dev, pr_err("could not initialize ICST regmap\n"); return ERR_CAST(map); } - return icst_clk_setup(dev, desc, name, parent_name, map); + return icst_clk_setup(dev, desc, name, parent_name, map, + ICST_VERSATILE); } EXPORT_SYMBOL_GPL(icst_clk_register); @@ -239,6 +444,56 @@ static const struct icst_params icst307_params = { .idx2s = icst307_idx2s, }; +/** + * The core modules on the Integrator/AP and Integrator/CP have + * especially crippled ICST525 control. + */ +static const struct icst_params icst525_apcp_cm_params = { + .vco_max = ICST525_VCO_MAX_5V, + .vco_min = ICST525_VCO_MIN, + /* Minimum 12 MHz, VDW = 4 */ + .vd_min = 12, + /* + * Maximum 160 MHz, VDW = 152 for all core modules, but + * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually + * go to 200 MHz (max VDW = 192). + */ + .vd_max = 192, + /* r is hardcoded to 22 and this is the actual divisor, +2 */ + .rd_min = 24, + .rd_max = 24, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, +}; + +static const struct icst_params icst525_ap_sys_params = { + .vco_max = ICST525_VCO_MAX_5V, + .vco_min = ICST525_VCO_MIN, + /* Minimum 3 MHz, VDW = 4 */ + .vd_min = 3, + /* Maximum 50 MHz, VDW = 192 */ + .vd_max = 50, + /* r is hardcoded to 46 and this is the actual divisor, +2 */ + .rd_min = 48, + .rd_max = 48, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, +}; + +static const struct icst_params icst525_ap_pci_params = { + .vco_max = ICST525_VCO_MAX_5V, + .vco_min = ICST525_VCO_MIN, + /* Minimum 25 MHz */ + .vd_min = 25, + /* Maximum 33 MHz */ + .vd_max = 33, + /* r is hardcoded to 14 or 22 and this is the actual divisors +2 */ + .rd_min = 16, + .rd_max = 24, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, +}; + static void __init of_syscon_icst_setup(struct device_node *np) { struct device_node *parent; @@ -247,6 +502,7 @@ static void __init of_syscon_icst_setup(struct device_node *np) const char *name = np->name; const char *parent_name; struct clk *regclk; + enum icst_control_type ctype; /* We do not release this reference, we are using it perpetually */ parent = of_get_parent(np); @@ -269,11 +525,28 @@ static void __init of_syscon_icst_setup(struct device_node *np) return; } - if (of_device_is_compatible(np, "arm,syscon-icst525")) + if (of_device_is_compatible(np, "arm,syscon-icst525")) { icst_desc.params = &icst525_params; - else if (of_device_is_compatible(np, "arm,syscon-icst307")) + ctype = ICST_VERSATILE; + } else if (of_device_is_compatible(np, "arm,syscon-icst307")) { icst_desc.params = &icst307_params; - else { + ctype = ICST_VERSATILE; + } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) { + icst_desc.params = &icst525_apcp_cm_params; + ctype = ICST_INTEGRATOR_AP_CM; + } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) { + icst_desc.params = &icst525_ap_sys_params; + ctype = ICST_INTEGRATOR_AP_SYS; + } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) { + icst_desc.params = &icst525_ap_pci_params; + ctype = ICST_INTEGRATOR_AP_PCI; + } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) { + icst_desc.params = &icst525_apcp_cm_params; + ctype = ICST_INTEGRATOR_CP_CM_CORE; + } else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) { + icst_desc.params = &icst525_apcp_cm_params; + ctype = ICST_INTEGRATOR_CP_CM_MEM; + } else { pr_err("unknown ICST clock %s\n", name); return; } @@ -281,7 +554,7 @@ static void __init of_syscon_icst_setup(struct device_node *np) /* Parent clock name is not the same as node parent */ parent_name = of_clk_get_parent_name(np, 0); - regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map); + regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype); if (IS_ERR(regclk)) { pr_err("error setting up syscon ICST clock %s\n", name); return; @@ -294,5 +567,14 @@ CLK_OF_DECLARE(arm_syscon_icst525_clk, "arm,syscon-icst525", of_syscon_icst_setup); CLK_OF_DECLARE(arm_syscon_icst307_clk, "arm,syscon-icst307", of_syscon_icst_setup); - +CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk, + "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup); +CLK_OF_DECLARE(arm_syscon_integratorap_sys_clk, + "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup); +CLK_OF_DECLARE(arm_syscon_integratorap_pci_clk, + "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup); +CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk, + "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup); +CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk, + "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup); #endif diff --git a/include/dt-bindings/clock/maxim,max77620.h b/include/dt-bindings/clock/maxim,max77620.h new file mode 100644 index 000000000000..82aba2849681 --- /dev/null +++ b/include/dt-bindings/clock/maxim,max77620.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Device Tree binding constants clocks for the Maxim 77620 PMIC. + */ + +#ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H +#define _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H + +/* Fixed rate clocks. */ + +#define MAX77620_CLK_32K_OUT0 0 + +/* Total number of clocks. */ +#define MAX77620_CLKS_NUM (MAX77620_CLK_32K_OUT0 + 1) + +#endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX77620_CLOCK_H */ diff --git a/include/dt-bindings/clock/mt2701-clk.h b/include/dt-bindings/clock/mt2701-clk.h new file mode 100644 index 000000000000..2062c67e2e51 --- /dev/null +++ b/include/dt-bindings/clock/mt2701-clk.h @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2014 MediaTek Inc. + * Author: Shunli Wang <shunli.wang@mediatek.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_MT2701_H +#define _DT_BINDINGS_CLK_MT2701_H + +/* TOPCKGEN */ +#define CLK_TOP_SYSPLL 1 +#define CLK_TOP_SYSPLL_D2 2 +#define CLK_TOP_SYSPLL_D3 3 +#define CLK_TOP_SYSPLL_D5 4 +#define CLK_TOP_SYSPLL_D7 5 +#define CLK_TOP_SYSPLL1_D2 6 +#define CLK_TOP_SYSPLL1_D4 7 +#define CLK_TOP_SYSPLL1_D8 8 +#define CLK_TOP_SYSPLL1_D16 9 +#define CLK_TOP_SYSPLL2_D2 10 +#define CLK_TOP_SYSPLL2_D4 11 +#define CLK_TOP_SYSPLL2_D8 12 +#define CLK_TOP_SYSPLL3_D2 13 +#define CLK_TOP_SYSPLL3_D4 14 +#define CLK_TOP_SYSPLL4_D2 15 +#define CLK_TOP_SYSPLL4_D4 16 +#define CLK_TOP_UNIVPLL 17 +#define CLK_TOP_UNIVPLL_D2 18 +#define CLK_TOP_UNIVPLL_D3 19 +#define CLK_TOP_UNIVPLL_D5 20 +#define CLK_TOP_UNIVPLL_D7 21 +#define CLK_TOP_UNIVPLL_D26 22 +#define CLK_TOP_UNIVPLL_D52 23 +#define CLK_TOP_UNIVPLL_D108 24 +#define CLK_TOP_USB_PHY48M 25 +#define CLK_TOP_UNIVPLL1_D2 26 +#define CLK_TOP_UNIVPLL1_D4 27 +#define CLK_TOP_UNIVPLL1_D8 28 +#define CLK_TOP_UNIVPLL2_D2 29 +#define CLK_TOP_UNIVPLL2_D4 30 +#define CLK_TOP_UNIVPLL2_D8 31 +#define CLK_TOP_UNIVPLL2_D16 32 +#define CLK_TOP_UNIVPLL2_D32 33 +#define CLK_TOP_UNIVPLL3_D2 34 +#define CLK_TOP_UNIVPLL3_D4 35 +#define CLK_TOP_UNIVPLL3_D8 36 +#define CLK_TOP_MSDCPLL 37 +#define CLK_TOP_MSDCPLL_D2 38 +#define CLK_TOP_MSDCPLL_D4 39 +#define CLK_TOP_MSDCPLL_D8 40 +#define CLK_TOP_MMPLL 41 +#define CLK_TOP_MMPLL_D2 42 +#define CLK_TOP_DMPLL 43 +#define CLK_TOP_DMPLL_D2 44 +#define CLK_TOP_DMPLL_D4 45 +#define CLK_TOP_DMPLL_X2 46 +#define CLK_TOP_TVDPLL 47 +#define CLK_TOP_TVDPLL_D2 48 +#define CLK_TOP_TVDPLL_D4 49 +#define CLK_TOP_TVD2PLL 50 +#define CLK_TOP_TVD2PLL_D2 51 +#define CLK_TOP_HADDS2PLL_98M 52 +#define CLK_TOP_HADDS2PLL_294M 53 +#define CLK_TOP_HADDS2_FB 54 +#define CLK_TOP_MIPIPLL_D2 55 +#define CLK_TOP_MIPIPLL_D4 56 +#define CLK_TOP_HDMIPLL 57 +#define CLK_TOP_HDMIPLL_D2 58 +#define CLK_TOP_HDMIPLL_D3 59 +#define CLK_TOP_HDMI_SCL_RX 60 +#define CLK_TOP_HDMI_0_PIX340M 61 +#define CLK_TOP_HDMI_0_DEEP340M 62 +#define CLK_TOP_HDMI_0_PLL340M 63 +#define CLK_TOP_AUD1PLL_98M 64 +#define CLK_TOP_AUD2PLL_90M 65 +#define CLK_TOP_AUDPLL 66 +#define CLK_TOP_AUDPLL_D4 67 +#define CLK_TOP_AUDPLL_D8 68 +#define CLK_TOP_AUDPLL_D16 69 +#define CLK_TOP_AUDPLL_D24 70 +#define CLK_TOP_ETHPLL_500M 71 +#define CLK_TOP_VDECPLL 72 +#define CLK_TOP_VENCPLL 73 +#define CLK_TOP_MIPIPLL 74 +#define CLK_TOP_ARMPLL_1P3G 75 + +#define CLK_TOP_MM_SEL 76 +#define CLK_TOP_DDRPHYCFG_SEL 77 +#define CLK_TOP_MEM_SEL 78 +#define CLK_TOP_AXI_SEL 79 +#define CLK_TOP_CAMTG_SEL 80 +#define CLK_TOP_MFG_SEL 81 +#define CLK_TOP_VDEC_SEL 82 +#define CLK_TOP_PWM_SEL 83 +#define CLK_TOP_MSDC30_0_SEL 84 +#define CLK_TOP_USB20_SEL 85 +#define CLK_TOP_SPI0_SEL 86 +#define CLK_TOP_UART_SEL 87 +#define CLK_TOP_AUDINTBUS_SEL 88 +#define CLK_TOP_AUDIO_SEL 89 +#define CLK_TOP_MSDC30_2_SEL 90 +#define CLK_TOP_MSDC30_1_SEL 91 +#define CLK_TOP_DPI1_SEL 92 +#define CLK_TOP_DPI0_SEL 93 +#define CLK_TOP_SCP_SEL 94 +#define CLK_TOP_PMICSPI_SEL 95 +#define CLK_TOP_APLL_SEL 96 +#define CLK_TOP_HDMI_SEL 97 +#define CLK_TOP_TVE_SEL 98 +#define CLK_TOP_EMMC_HCLK_SEL 99 +#define CLK_TOP_NFI2X_SEL 100 +#define CLK_TOP_RTC_SEL 101 +#define CLK_TOP_OSD_SEL 102 +#define CLK_TOP_NR_SEL 103 +#define CLK_TOP_DI_SEL 104 +#define CLK_TOP_FLASH_SEL 105 +#define CLK_TOP_ASM_M_SEL 106 +#define CLK_TOP_ASM_I_SEL 107 +#define CLK_TOP_INTDIR_SEL 108 +#define CLK_TOP_HDMIRX_BIST_SEL 109 +#define CLK_TOP_ETHIF_SEL 110 +#define CLK_TOP_MS_CARD_SEL 111 +#define CLK_TOP_ASM_H_SEL 112 +#define CLK_TOP_SPI1_SEL 113 +#define CLK_TOP_CMSYS_SEL 114 +#define CLK_TOP_MSDC30_3_SEL 115 +#define CLK_TOP_HDMIRX26_24_SEL 116 +#define CLK_TOP_AUD2DVD_SEL 117 +#define CLK_TOP_8BDAC_SEL 118 +#define CLK_TOP_SPI2_SEL 119 +#define CLK_TOP_AUD_MUX1_SEL 120 +#define CLK_TOP_AUD_MUX2_SEL 121 +#define CLK_TOP_AUDPLL_MUX_SEL 122 +#define CLK_TOP_AUD_K1_SRC_SEL 123 +#define CLK_TOP_AUD_K2_SRC_SEL 124 +#define CLK_TOP_AUD_K3_SRC_SEL 125 +#define CLK_TOP_AUD_K4_SRC_SEL 126 +#define CLK_TOP_AUD_K5_SRC_SEL 127 +#define CLK_TOP_AUD_K6_SRC_SEL 128 +#define CLK_TOP_PADMCLK_SEL 129 +#define CLK_TOP_AUD_EXTCK1_DIV 130 +#define CLK_TOP_AUD_EXTCK2_DIV 131 +#define CLK_TOP_AUD_MUX1_DIV 132 +#define CLK_TOP_AUD_MUX2_DIV 133 +#define CLK_TOP_AUD_K1_SRC_DIV 134 +#define CLK_TOP_AUD_K2_SRC_DIV 135 +#define CLK_TOP_AUD_K3_SRC_DIV 136 +#define CLK_TOP_AUD_K4_SRC_DIV 137 +#define CLK_TOP_AUD_K5_SRC_DIV 138 +#define CLK_TOP_AUD_K6_SRC_DIV 139 +#define CLK_TOP_AUD_I2S1_MCLK 140 +#define CLK_TOP_AUD_I2S2_MCLK 141 +#define CLK_TOP_AUD_I2S3_MCLK 142 +#define CLK_TOP_AUD_I2S4_MCLK 143 +#define CLK_TOP_AUD_I2S5_MCLK 144 +#define CLK_TOP_AUD_I2S6_MCLK 145 +#define CLK_TOP_AUD_48K_TIMING 146 +#define CLK_TOP_AUD_44K_TIMING 147 + +#define CLK_TOP_32K_INTERNAL 148 +#define CLK_TOP_32K_EXTERNAL 149 +#define CLK_TOP_CLK26M_D8 150 +#define CLK_TOP_8BDAC 151 +#define CLK_TOP_WBG_DIG_416M 152 +#define CLK_TOP_DPI 153 +#define CLK_TOP_HDMITX_CLKDIG_CTS 154 +#define CLK_TOP_DSI0_LNTC_DSI 155 +#define CLK_TOP_AUD_EXT1 156 +#define CLK_TOP_AUD_EXT2 157 +#define CLK_TOP_NFI1X_PAD 158 +#define CLK_TOP_NR 159 + +/* APMIXEDSYS */ + +#define CLK_APMIXED_ARMPLL 1 +#define CLK_APMIXED_MAINPLL 2 +#define CLK_APMIXED_UNIVPLL 3 +#define CLK_APMIXED_MMPLL 4 +#define CLK_APMIXED_MSDCPLL 5 +#define CLK_APMIXED_TVDPLL 6 +#define CLK_APMIXED_AUD1PLL 7 +#define CLK_APMIXED_TRGPLL 8 +#define CLK_APMIXED_ETHPLL 9 +#define CLK_APMIXED_VDECPLL 10 +#define CLK_APMIXED_HADDS2PLL 11 +#define CLK_APMIXED_AUD2PLL 12 +#define CLK_APMIXED_TVD2PLL 13 +#define CLK_APMIXED_NR 14 + +/* DDRPHY */ + +#define CLK_DDRPHY_VENCPLL 1 +#define CLK_DDRPHY_NR 2 + +/* INFRACFG */ + +#define CLK_INFRA_DBG 1 +#define CLK_INFRA_SMI 2 +#define CLK_INFRA_QAXI_CM4 3 +#define CLK_INFRA_AUD_SPLIN_B 4 +#define CLK_INFRA_AUDIO 5 +#define CLK_INFRA_EFUSE 6 +#define CLK_INFRA_L2C_SRAM 7 +#define CLK_INFRA_M4U 8 +#define CLK_INFRA_CONNMCU 9 +#define CLK_INFRA_TRNG 10 +#define CLK_INFRA_RAMBUFIF 11 +#define CLK_INFRA_CPUM 12 +#define CLK_INFRA_KP 13 +#define CLK_INFRA_CEC 14 +#define CLK_INFRA_IRRX 15 +#define CLK_INFRA_PMICSPI 16 +#define CLK_INFRA_PMICWRAP 17 +#define CLK_INFRA_DDCCI 18 +#define CLK_INFRA_CLK_13M 19 +#define CLK_INFRA_NR 20 + +/* PERICFG */ + +#define CLK_PERI_NFI 1 +#define CLK_PERI_THERM 2 +#define CLK_PERI_PWM1 3 +#define CLK_PERI_PWM2 4 +#define CLK_PERI_PWM3 5 +#define CLK_PERI_PWM4 6 +#define CLK_PERI_PWM5 7 +#define CLK_PERI_PWM6 8 +#define CLK_PERI_PWM7 9 +#define CLK_PERI_PWM 10 +#define CLK_PERI_USB0 11 +#define CLK_PERI_USB1 12 +#define CLK_PERI_AP_DMA 13 +#define CLK_PERI_MSDC30_0 14 +#define CLK_PERI_MSDC30_1 15 +#define CLK_PERI_MSDC30_2 16 +#define CLK_PERI_MSDC30_3 17 +#define CLK_PERI_MSDC50_3 18 +#define CLK_PERI_NLI 19 +#define CLK_PERI_UART0 20 +#define CLK_PERI_UART1 21 +#define CLK_PERI_UART2 22 +#define CLK_PERI_UART3 23 +#define CLK_PERI_BTIF 24 +#define CLK_PERI_I2C0 25 +#define CLK_PERI_I2C1 26 +#define CLK_PERI_I2C2 27 +#define CLK_PERI_I2C3 28 +#define CLK_PERI_AUXADC 29 +#define CLK_PERI_SPI0 30 +#define CLK_PERI_ETH 31 +#define CLK_PERI_USB0_MCU 32 + +#define CLK_PERI_USB1_MCU 33 +#define CLK_PERI_USB_SLV 34 +#define CLK_PERI_GCPU 35 +#define CLK_PERI_NFI_ECC 36 +#define CLK_PERI_NFI_PAD 37 +#define CLK_PERI_FLASH 38 +#define CLK_PERI_HOST89_INT 39 +#define CLK_PERI_HOST89_SPI 40 +#define CLK_PERI_HOST89_DVD 41 +#define CLK_PERI_SPI1 42 +#define CLK_PERI_SPI2 43 +#define CLK_PERI_FCI 44 + +#define CLK_PERI_UART0_SEL 45 +#define CLK_PERI_UART1_SEL 46 +#define CLK_PERI_UART2_SEL 47 +#define CLK_PERI_UART3_SEL 48 +#define CLK_PERI_NR 49 + +/* AUDIO */ + +#define CLK_AUD_AFE 1 +#define CLK_AUD_LRCK_DETECT 2 +#define CLK_AUD_I2S 3 +#define CLK_AUD_APLL_TUNER 4 +#define CLK_AUD_HDMI 5 +#define CLK_AUD_SPDF 6 +#define CLK_AUD_SPDF2 7 +#define CLK_AUD_APLL 8 +#define CLK_AUD_TML 9 +#define CLK_AUD_AHB_IDLE_EXT 10 +#define CLK_AUD_AHB_IDLE_INT 11 + +#define CLK_AUD_I2SIN1 12 +#define CLK_AUD_I2SIN2 13 +#define CLK_AUD_I2SIN3 14 +#define CLK_AUD_I2SIN4 15 +#define CLK_AUD_I2SIN5 16 +#define CLK_AUD_I2SIN6 17 +#define CLK_AUD_I2SO1 18 +#define CLK_AUD_I2SO2 19 +#define CLK_AUD_I2SO3 20 +#define CLK_AUD_I2SO4 21 +#define CLK_AUD_I2SO5 22 +#define CLK_AUD_I2SO6 23 +#define CLK_AUD_ASRCI1 24 +#define CLK_AUD_ASRCI2 25 +#define CLK_AUD_ASRCO1 26 +#define CLK_AUD_ASRCO2 27 +#define CLK_AUD_ASRC11 28 +#define CLK_AUD_ASRC12 29 +#define CLK_AUD_HDMIRX 30 +#define CLK_AUD_INTDIR 31 +#define CLK_AUD_A1SYS 32 +#define CLK_AUD_A2SYS 33 +#define CLK_AUD_AFE_CONN 34 +#define CLK_AUD_AFE_PCMIF 35 +#define CLK_AUD_AFE_MRGIF 36 + +#define CLK_AUD_MMIF_UL1 37 +#define CLK_AUD_MMIF_UL2 38 +#define CLK_AUD_MMIF_UL3 39 +#define CLK_AUD_MMIF_UL4 40 +#define CLK_AUD_MMIF_UL5 41 +#define CLK_AUD_MMIF_UL6 42 +#define CLK_AUD_MMIF_DL1 43 +#define CLK_AUD_MMIF_DL2 44 +#define CLK_AUD_MMIF_DL3 45 +#define CLK_AUD_MMIF_DL4 46 +#define CLK_AUD_MMIF_DL5 47 +#define CLK_AUD_MMIF_DL6 48 +#define CLK_AUD_MMIF_DLMCH 49 +#define CLK_AUD_MMIF_ARB1 50 +#define CLK_AUD_MMIF_AWB1 51 +#define CLK_AUD_MMIF_AWB2 52 +#define CLK_AUD_MMIF_DAI 53 + +#define CLK_AUD_DMIC1 54 +#define CLK_AUD_DMIC2 55 +#define CLK_AUD_ASRCI3 56 +#define CLK_AUD_ASRCI4 57 +#define CLK_AUD_ASRCI5 58 +#define CLK_AUD_ASRCI6 59 +#define CLK_AUD_ASRCO3 60 +#define CLK_AUD_ASRCO4 61 +#define CLK_AUD_ASRCO5 62 +#define CLK_AUD_ASRCO6 63 +#define CLK_AUD_MEM_ASRC1 64 +#define CLK_AUD_MEM_ASRC2 65 +#define CLK_AUD_MEM_ASRC3 66 +#define CLK_AUD_MEM_ASRC4 67 +#define CLK_AUD_MEM_ASRC5 68 +#define CLK_AUD_DSD_ENC 69 +#define CLK_AUD_ASRC_BRG 70 +#define CLK_AUD_NR 71 + +/* MMSYS */ + +#define CLK_MM_SMI_COMMON 1 +#define CLK_MM_SMI_LARB0 2 +#define CLK_MM_CMDQ 3 +#define CLK_MM_MUTEX 4 +#define CLK_MM_DISP_COLOR 5 +#define CLK_MM_DISP_BLS 6 +#define CLK_MM_DISP_WDMA 7 +#define CLK_MM_DISP_RDMA 8 +#define CLK_MM_DISP_OVL 9 +#define CLK_MM_MDP_TDSHP 10 +#define CLK_MM_MDP_WROT 11 +#define CLK_MM_MDP_WDMA 12 +#define CLK_MM_MDP_RSZ1 13 +#define CLK_MM_MDP_RSZ0 14 +#define CLK_MM_MDP_RDMA 15 +#define CLK_MM_MDP_BLS_26M 16 +#define CLK_MM_CAM_MDP 17 +#define CLK_MM_FAKE_ENG 18 +#define CLK_MM_MUTEX_32K 19 +#define CLK_MM_DISP_RDMA1 20 +#define CLK_MM_DISP_UFOE 21 + +#define CLK_MM_DSI_ENGINE 22 +#define CLK_MM_DSI_DIG 23 +#define CLK_MM_DPI_DIGL 24 +#define CLK_MM_DPI_ENGINE 25 +#define CLK_MM_DPI1_DIGL 26 +#define CLK_MM_DPI1_ENGINE 27 +#define CLK_MM_TVE_OUTPUT 28 +#define CLK_MM_TVE_INPUT 29 +#define CLK_MM_HDMI_PIXEL 30 +#define CLK_MM_HDMI_PLL 31 +#define CLK_MM_HDMI_AUDIO 32 +#define CLK_MM_HDMI_SPDIF 33 +#define CLK_MM_TVE_FMM 34 +#define CLK_MM_NR 35 + +/* IMGSYS */ + +#define CLK_IMG_SMI_COMM 1 +#define CLK_IMG_RESZ 2 +#define CLK_IMG_JPGDEC_SMI 3 +#define CLK_IMG_JPGDEC 4 +#define CLK_IMG_VENC_LT 5 +#define CLK_IMG_VENC 6 +#define CLK_IMG_NR 7 + +/* VDEC */ + +#define CLK_VDEC_CKGEN 1 +#define CLK_VDEC_LARB 2 +#define CLK_VDEC_NR 3 + +/* HIFSYS */ + +#define CLK_HIFSYS_USB0PHY 1 +#define CLK_HIFSYS_USB1PHY 2 +#define CLK_HIFSYS_PCIE0 3 +#define CLK_HIFSYS_PCIE1 4 +#define CLK_HIFSYS_PCIE2 5 +#define CLK_HIFSYS_NR 6 + +/* ETHSYS */ +#define CLK_ETHSYS_HSDMA 1 +#define CLK_ETHSYS_ESW 2 +#define CLK_ETHSYS_GP2 3 +#define CLK_ETHSYS_GP1 4 +#define CLK_ETHSYS_PCM 5 +#define CLK_ETHSYS_GDMA 6 +#define CLK_ETHSYS_I2S 7 +#define CLK_ETHSYS_CRYPTO 8 +#define CLK_ETHSYS_NR 9 + +/* BDP */ + +#define CLK_BDP_BRG_BA 1 +#define CLK_BDP_BRG_DRAM 2 +#define CLK_BDP_LARB_DRAM 3 +#define CLK_BDP_WR_VDI_PXL 4 +#define CLK_BDP_WR_VDI_DRAM 5 +#define CLK_BDP_WR_B 6 +#define CLK_BDP_DGI_IN 7 +#define CLK_BDP_DGI_OUT 8 +#define CLK_BDP_FMT_MAST_27 9 +#define CLK_BDP_FMT_B 10 +#define CLK_BDP_OSD_B 11 +#define CLK_BDP_OSD_DRAM 12 +#define CLK_BDP_OSD_AGENT 13 +#define CLK_BDP_OSD_PXL 14 +#define CLK_BDP_RLE_B 15 +#define CLK_BDP_RLE_AGENT 16 +#define CLK_BDP_RLE_DRAM 17 +#define CLK_BDP_F27M 18 +#define CLK_BDP_F27M_VDOUT 19 +#define CLK_BDP_F27_74_74 20 +#define CLK_BDP_F2FS 21 +#define CLK_BDP_F2FS74_148 22 +#define CLK_BDP_FB 23 +#define CLK_BDP_VDO_DRAM 24 +#define CLK_BDP_VDO_2FS 25 +#define CLK_BDP_VDO_B 26 +#define CLK_BDP_WR_DI_PXL 27 +#define CLK_BDP_WR_DI_DRAM 28 +#define CLK_BDP_WR_DI_B 29 +#define CLK_BDP_NR_PXL 30 +#define CLK_BDP_NR_DRAM 31 +#define CLK_BDP_NR_B 32 + +#define CLK_BDP_RX_F 33 +#define CLK_BDP_RX_X 34 +#define CLK_BDP_RXPDT 35 +#define CLK_BDP_RX_CSCL_N 36 +#define CLK_BDP_RX_CSCL 37 +#define CLK_BDP_RX_DDCSCL_N 38 +#define CLK_BDP_RX_DDCSCL 39 +#define CLK_BDP_RX_VCO 40 +#define CLK_BDP_RX_DP 41 +#define CLK_BDP_RX_P 42 +#define CLK_BDP_RX_M 43 +#define CLK_BDP_RX_PLL 44 +#define CLK_BDP_BRG_RT_B 45 +#define CLK_BDP_BRG_RT_DRAM 46 +#define CLK_BDP_LARBRT_DRAM 47 +#define CLK_BDP_TMDS_SYN 48 +#define CLK_BDP_HDMI_MON 49 +#define CLK_BDP_NR 50 + +#endif /* _DT_BINDINGS_CLK_MT2701_H */ diff --git a/include/dt-bindings/clock/qcom,gcc-mdm9615.h b/include/dt-bindings/clock/qcom,gcc-mdm9615.h new file mode 100644 index 000000000000..9ab2c4087120 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-mdm9615.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Copyright (c) BayLibre, SAS. + * Author : Neil Armstrong <narmstrong@baylibre.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_MDM_GCC_9615_H +#define _DT_BINDINGS_CLK_MDM_GCC_9615_H + +#define AFAB_CLK_SRC 0 +#define AFAB_CORE_CLK 1 +#define SFAB_MSS_Q6_SW_A_CLK 2 +#define SFAB_MSS_Q6_FW_A_CLK 3 +#define QDSS_STM_CLK 4 +#define SCSS_A_CLK 5 +#define SCSS_H_CLK 6 +#define SCSS_XO_SRC_CLK 7 +#define AFAB_EBI1_CH0_A_CLK 8 +#define AFAB_EBI1_CH1_A_CLK 9 +#define AFAB_AXI_S0_FCLK 10 +#define AFAB_AXI_S1_FCLK 11 +#define AFAB_AXI_S2_FCLK 12 +#define AFAB_AXI_S3_FCLK 13 +#define AFAB_AXI_S4_FCLK 14 +#define SFAB_CORE_CLK 15 +#define SFAB_AXI_S0_FCLK 16 +#define SFAB_AXI_S1_FCLK 17 +#define SFAB_AXI_S2_FCLK 18 +#define SFAB_AXI_S3_FCLK 19 +#define SFAB_AXI_S4_FCLK 20 +#define SFAB_AHB_S0_FCLK 21 +#define SFAB_AHB_S1_FCLK 22 +#define SFAB_AHB_S2_FCLK 23 +#define SFAB_AHB_S3_FCLK 24 +#define SFAB_AHB_S4_FCLK 25 +#define SFAB_AHB_S5_FCLK 26 +#define SFAB_AHB_S6_FCLK 27 +#define SFAB_AHB_S7_FCLK 28 +#define QDSS_AT_CLK_SRC 29 +#define QDSS_AT_CLK 30 +#define QDSS_TRACECLKIN_CLK_SRC 31 +#define QDSS_TRACECLKIN_CLK 32 +#define QDSS_TSCTR_CLK_SRC 33 +#define QDSS_TSCTR_CLK 34 +#define SFAB_ADM0_M0_A_CLK 35 +#define SFAB_ADM0_M1_A_CLK 36 +#define SFAB_ADM0_M2_H_CLK 37 +#define ADM0_CLK 38 +#define ADM0_PBUS_CLK 39 +#define MSS_XPU_CLK 40 +#define IMEM0_A_CLK 41 +#define QDSS_H_CLK 42 +#define PCIE_A_CLK 43 +#define PCIE_AUX_CLK 44 +#define PCIE_PHY_REF_CLK 45 +#define PCIE_H_CLK 46 +#define SFAB_CLK_SRC 47 +#define MAHB0_CLK 48 +#define Q6SW_CLK_SRC 49 +#define Q6SW_CLK 50 +#define Q6FW_CLK_SRC 51 +#define Q6FW_CLK 52 +#define SFAB_MSS_M_A_CLK 53 +#define SFAB_USB3_M_A_CLK 54 +#define SFAB_LPASS_Q6_A_CLK 55 +#define SFAB_AFAB_M_A_CLK 56 +#define AFAB_SFAB_M0_A_CLK 57 +#define AFAB_SFAB_M1_A_CLK 58 +#define SFAB_SATA_S_H_CLK 59 +#define DFAB_CLK_SRC 60 +#define DFAB_CLK 61 +#define SFAB_DFAB_M_A_CLK 62 +#define DFAB_SFAB_M_A_CLK 63 +#define DFAB_SWAY0_H_CLK 64 +#define DFAB_SWAY1_H_CLK 65 +#define DFAB_ARB0_H_CLK 66 +#define DFAB_ARB1_H_CLK 67 +#define PPSS_H_CLK 68 +#define PPSS_PROC_CLK 69 +#define PPSS_TIMER0_CLK 70 +#define PPSS_TIMER1_CLK 71 +#define PMEM_A_CLK 72 +#define DMA_BAM_H_CLK 73 +#define SIC_H_CLK 74 +#define SPS_TIC_H_CLK 75 +#define SLIMBUS_H_CLK 76 +#define SLIMBUS_XO_SRC_CLK 77 +#define CFPB_2X_CLK_SRC 78 +#define CFPB_CLK 79 +#define CFPB0_H_CLK 80 +#define CFPB1_H_CLK 81 +#define CFPB2_H_CLK 82 +#define SFAB_CFPB_M_H_CLK 83 +#define CFPB_MASTER_H_CLK 84 +#define SFAB_CFPB_S_H_CLK 85 +#define CFPB_SPLITTER_H_CLK 86 +#define TSIF_H_CLK 87 +#define TSIF_INACTIVITY_TIMERS_CLK 88 +#define TSIF_REF_SRC 89 +#define TSIF_REF_CLK 90 +#define CE1_H_CLK 91 +#define CE1_CORE_CLK 92 +#define CE1_SLEEP_CLK 93 +#define CE2_H_CLK 94 +#define CE2_CORE_CLK 95 +#define SFPB_H_CLK_SRC 97 +#define SFPB_H_CLK 98 +#define SFAB_SFPB_M_H_CLK 99 +#define SFAB_SFPB_S_H_CLK 100 +#define RPM_PROC_CLK 101 +#define RPM_BUS_H_CLK 102 +#define RPM_SLEEP_CLK 103 +#define RPM_TIMER_CLK 104 +#define RPM_MSG_RAM_H_CLK 105 +#define PMIC_ARB0_H_CLK 106 +#define PMIC_ARB1_H_CLK 107 +#define PMIC_SSBI2_SRC 108 +#define PMIC_SSBI2_CLK 109 +#define SDC1_H_CLK 110 +#define SDC2_H_CLK 111 +#define SDC3_H_CLK 112 +#define SDC4_H_CLK 113 +#define SDC5_H_CLK 114 +#define SDC1_SRC 115 +#define SDC2_SRC 116 +#define SDC3_SRC 117 +#define SDC4_SRC 118 +#define SDC5_SRC 119 +#define SDC1_CLK 120 +#define SDC2_CLK 121 +#define SDC3_CLK 122 +#define SDC4_CLK 123 +#define SDC5_CLK 124 +#define DFAB_A2_H_CLK 125 +#define USB_HS1_H_CLK 126 +#define USB_HS1_XCVR_SRC 127 +#define USB_HS1_XCVR_CLK 128 +#define USB_HSIC_H_CLK 129 +#define USB_HSIC_XCVR_FS_SRC 130 +#define USB_HSIC_XCVR_FS_CLK 131 +#define USB_HSIC_SYSTEM_CLK_SRC 132 +#define USB_HSIC_SYSTEM_CLK 133 +#define CFPB0_C0_H_CLK 134 +#define CFPB0_C1_H_CLK 135 +#define CFPB0_D0_H_CLK 136 +#define CFPB0_D1_H_CLK 137 +#define USB_FS1_H_CLK 138 +#define USB_FS1_XCVR_FS_SRC 139 +#define USB_FS1_XCVR_FS_CLK 140 +#define USB_FS1_SYSTEM_CLK 141 +#define USB_FS2_H_CLK 142 +#define USB_FS2_XCVR_FS_SRC 143 +#define USB_FS2_XCVR_FS_CLK 144 +#define USB_FS2_SYSTEM_CLK 145 +#define GSBI_COMMON_SIM_SRC 146 +#define GSBI1_H_CLK 147 +#define GSBI2_H_CLK 148 +#define GSBI3_H_CLK 149 +#define GSBI4_H_CLK 150 +#define GSBI5_H_CLK 151 +#define GSBI6_H_CLK 152 +#define GSBI7_H_CLK 153 +#define GSBI8_H_CLK 154 +#define GSBI9_H_CLK 155 +#define GSBI10_H_CLK 156 +#define GSBI11_H_CLK 157 +#define GSBI12_H_CLK 158 +#define GSBI1_UART_SRC 159 +#define GSBI1_UART_CLK 160 +#define GSBI2_UART_SRC 161 +#define GSBI2_UART_CLK 162 +#define GSBI3_UART_SRC 163 +#define GSBI3_UART_CLK 164 +#define GSBI4_UART_SRC 165 +#define GSBI4_UART_CLK 166 +#define GSBI5_UART_SRC 167 +#define GSBI5_UART_CLK 168 +#define GSBI6_UART_SRC 169 +#define GSBI6_UART_CLK 170 +#define GSBI7_UART_SRC 171 +#define GSBI7_UART_CLK 172 +#define GSBI8_UART_SRC 173 +#define GSBI8_UART_CLK 174 +#define GSBI9_UART_SRC 175 +#define GSBI9_UART_CLK 176 +#define GSBI10_UART_SRC 177 +#define GSBI10_UART_CLK 178 +#define GSBI11_UART_SRC 179 +#define GSBI11_UART_CLK 180 +#define GSBI12_UART_SRC 181 +#define GSBI12_UART_CLK 182 +#define GSBI1_QUP_SRC 183 +#define GSBI1_QUP_CLK 184 +#define GSBI2_QUP_SRC 185 +#define GSBI2_QUP_CLK 186 +#define GSBI3_QUP_SRC 187 +#define GSBI3_QUP_CLK 188 +#define GSBI4_QUP_SRC 189 +#define GSBI4_QUP_CLK 190 +#define GSBI5_QUP_SRC 191 +#define GSBI5_QUP_CLK 192 +#define GSBI6_QUP_SRC 193 +#define GSBI6_QUP_CLK 194 +#define GSBI7_QUP_SRC 195 +#define GSBI7_QUP_CLK 196 +#define GSBI8_QUP_SRC 197 +#define GSBI8_QUP_CLK 198 +#define GSBI9_QUP_SRC 199 +#define GSBI9_QUP_CLK 200 +#define GSBI10_QUP_SRC 201 +#define GSBI10_QUP_CLK 202 +#define GSBI11_QUP_SRC 203 +#define GSBI11_QUP_CLK 204 +#define GSBI12_QUP_SRC 205 +#define GSBI12_QUP_CLK 206 +#define GSBI1_SIM_CLK 207 +#define GSBI2_SIM_CLK 208 +#define GSBI3_SIM_CLK 209 +#define GSBI4_SIM_CLK 210 +#define GSBI5_SIM_CLK 211 +#define GSBI6_SIM_CLK 212 +#define GSBI7_SIM_CLK 213 +#define GSBI8_SIM_CLK 214 +#define GSBI9_SIM_CLK 215 +#define GSBI10_SIM_CLK 216 +#define GSBI11_SIM_CLK 217 +#define GSBI12_SIM_CLK 218 +#define USB_HSIC_HSIC_CLK_SRC 219 +#define USB_HSIC_HSIC_CLK 220 +#define USB_HSIC_HSIO_CAL_CLK 221 +#define SPDM_CFG_H_CLK 222 +#define SPDM_MSTR_H_CLK 223 +#define SPDM_FF_CLK_SRC 224 +#define SPDM_FF_CLK 225 +#define SEC_CTRL_CLK 226 +#define SEC_CTRL_ACC_CLK_SRC 227 +#define SEC_CTRL_ACC_CLK 228 +#define TLMM_H_CLK 229 +#define TLMM_CLK 230 +#define SFAB_MSS_S_H_CLK 231 +#define MSS_SLP_CLK 232 +#define MSS_Q6SW_JTAG_CLK 233 +#define MSS_Q6FW_JTAG_CLK 234 +#define MSS_S_H_CLK 235 +#define MSS_CXO_SRC_CLK 236 +#define SATA_H_CLK 237 +#define SATA_CLK_SRC 238 +#define SATA_RXOOB_CLK 239 +#define SATA_PMALIVE_CLK 240 +#define SATA_PHY_REF_CLK 241 +#define TSSC_CLK_SRC 242 +#define TSSC_CLK 243 +#define PDM_SRC 244 +#define PDM_CLK 245 +#define GP0_SRC 246 +#define GP0_CLK 247 +#define GP1_SRC 248 +#define GP1_CLK 249 +#define GP2_SRC 250 +#define GP2_CLK 251 +#define MPM_CLK 252 +#define EBI1_CLK_SRC 253 +#define EBI1_CH0_CLK 254 +#define EBI1_CH1_CLK 255 +#define EBI1_2X_CLK 256 +#define EBI1_CH0_DQ_CLK 257 +#define EBI1_CH1_DQ_CLK 258 +#define EBI1_CH0_CA_CLK 259 +#define EBI1_CH1_CA_CLK 260 +#define EBI1_XO_CLK 261 +#define SFAB_SMPSS_S_H_CLK 262 +#define PRNG_SRC 263 +#define PRNG_CLK 264 +#define PXO_SRC 265 +#define LPASS_CXO_CLK 266 +#define LPASS_PXO_CLK 267 +#define SPDM_CY_PORT0_CLK 268 +#define SPDM_CY_PORT1_CLK 269 +#define SPDM_CY_PORT2_CLK 270 +#define SPDM_CY_PORT3_CLK 271 +#define SPDM_CY_PORT4_CLK 272 +#define SPDM_CY_PORT5_CLK 273 +#define SPDM_CY_PORT6_CLK 274 +#define SPDM_CY_PORT7_CLK 275 +#define PLL0 276 +#define PLL0_VOTE 277 +#define PLL3 278 +#define PLL3_VOTE 279 +#define PLL4_VOTE 280 +#define PLL5 281 +#define PLL5_VOTE 282 +#define PLL6 283 +#define PLL6_VOTE 284 +#define PLL7_VOTE 285 +#define PLL8 286 +#define PLL8_VOTE 287 +#define PLL9 288 +#define PLL10 289 +#define PLL11 290 +#define PLL12 291 +#define PLL13 292 +#define PLL14 293 +#define PLL14_VOTE 294 +#define USB_HS3_H_CLK 295 +#define USB_HS3_XCVR_SRC 296 +#define USB_HS3_XCVR_CLK 297 +#define USB_HS4_H_CLK 298 +#define USB_HS4_XCVR_SRC 299 +#define USB_HS4_XCVR_CLK 300 +#define SATA_PHY_CFG_CLK 301 +#define SATA_A_CLK 302 +#define CE3_SRC 303 +#define CE3_CORE_CLK 304 +#define CE3_H_CLK 305 +#define USB_HS1_SYSTEM_CLK_SRC 306 +#define USB_HS1_SYSTEM_CLK 307 + +#endif diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index 6f814db11c7e..b7ea1e8f5560 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h @@ -335,6 +335,9 @@ #define GCC_MSMPU_BCR 98 #define GCC_MSS_Q6_BCR 99 #define GCC_QREFS_VBG_CAL_BCR 100 +#define GCC_PCIE_PHY_COM_BCR 101 +#define GCC_PCIE_PHY_COM_NOCSR_BCR 102 + /* Indexes for GDSCs */ #define AGGRE0_NOC_GDSC 0 diff --git a/include/dt-bindings/clock/qcom,lcc-mdm9615.h b/include/dt-bindings/clock/qcom,lcc-mdm9615.h new file mode 100644 index 000000000000..cac963a2fdcb --- /dev/null +++ b/include/dt-bindings/clock/qcom,lcc-mdm9615.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) BayLibre, SAS. + * Author : Neil Armstrong <narmstrong@baylibre.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_LCC_MDM9615_H +#define _DT_BINDINGS_CLK_LCC_MDM9615_H + +#define PLL4 0 +#define MI2S_OSR_SRC 1 +#define MI2S_OSR_CLK 2 +#define MI2S_DIV_CLK 3 +#define MI2S_BIT_DIV_CLK 4 +#define MI2S_BIT_CLK 5 +#define PCM_SRC 6 +#define PCM_CLK_OUT 7 +#define PCM_CLK 8 +#define SLIMBUS_SRC 9 +#define AUDIO_SLIMBUS_CLK 10 +#define SPS_SLIMBUS_CLK 11 +#define CODEC_I2S_MIC_OSR_SRC 12 +#define CODEC_I2S_MIC_OSR_CLK 13 +#define CODEC_I2S_MIC_DIV_CLK 14 +#define CODEC_I2S_MIC_BIT_DIV_CLK 15 +#define CODEC_I2S_MIC_BIT_CLK 16 +#define SPARE_I2S_MIC_OSR_SRC 17 +#define SPARE_I2S_MIC_OSR_CLK 18 +#define SPARE_I2S_MIC_DIV_CLK 19 +#define SPARE_I2S_MIC_BIT_DIV_CLK 20 +#define SPARE_I2S_MIC_BIT_CLK 21 +#define CODEC_I2S_SPKR_OSR_SRC 22 +#define CODEC_I2S_SPKR_OSR_CLK 23 +#define CODEC_I2S_SPKR_DIV_CLK 24 +#define CODEC_I2S_SPKR_BIT_DIV_CLK 25 +#define CODEC_I2S_SPKR_BIT_CLK 26 +#define SPARE_I2S_SPKR_OSR_SRC 27 +#define SPARE_I2S_SPKR_OSR_CLK 28 +#define SPARE_I2S_SPKR_DIV_CLK 29 +#define SPARE_I2S_SPKR_BIT_DIV_CLK 30 +#define SPARE_I2S_SPKR_BIT_CLK 31 + +#endif diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8996.h b/include/dt-bindings/clock/qcom,mmcc-msm8996.h index 7d3a7fa1a1bd..5abc445ad815 100644 --- a/include/dt-bindings/clock/qcom,mmcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,mmcc-msm8996.h @@ -298,5 +298,6 @@ #define FD_GDSC 12 #define MDSS_GDSC 13 #define GPU_GX_GDSC 14 +#define MMAGIC_BIMC_GDSC 15 #endif diff --git a/include/dt-bindings/reset/mt2701-resets.h b/include/dt-bindings/reset/mt2701-resets.h new file mode 100644 index 000000000000..aaf03057f755 --- /dev/null +++ b/include/dt-bindings/reset/mt2701-resets.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015 MediaTek, Shunli Wang <shunli.wang@mediatek.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2701 +#define _DT_BINDINGS_RESET_CONTROLLER_MT2701 + +/* INFRACFG resets */ +#define MT2701_INFRA_EMI_REG_RST 0 +#define MT2701_INFRA_DRAMC0_A0_RST 1 +#define MT2701_INFRA_FHCTL_RST 2 +#define MT2701_INFRA_APCIRQ_EINT_RST 3 +#define MT2701_INFRA_APXGPT_RST 4 +#define MT2701_INFRA_SCPSYS_RST 5 +#define MT2701_INFRA_KP_RST 6 +#define MT2701_INFRA_PMIC_WRAP_RST 7 +#define MT2701_INFRA_MIPI_RST 8 +#define MT2701_INFRA_IRRX_RST 9 +#define MT2701_INFRA_CEC_RST 10 +#define MT2701_INFRA_EMI_RST 32 +#define MT2701_INFRA_DRAMC0_RST 34 +#define MT2701_INFRA_TRNG_RST 37 +#define MT2701_INFRA_SYSIRQ_RST 38 + +/* PERICFG resets */ +#define MT2701_PERI_UART0_SW_RST 0 +#define MT2701_PERI_UART1_SW_RST 1 +#define MT2701_PERI_UART2_SW_RST 2 +#define MT2701_PERI_UART3_SW_RST 3 +#define MT2701_PERI_GCPU_SW_RST 5 +#define MT2701_PERI_BTIF_SW_RST 6 +#define MT2701_PERI_PWM_SW_RST 8 +#define MT2701_PERI_AUXADC_SW_RST 10 +#define MT2701_PERI_DMA_SW_RST 11 +#define MT2701_PERI_NFI_SW_RST 14 +#define MT2701_PERI_NLI_SW_RST 15 +#define MT2701_PERI_THERM_SW_RST 16 +#define MT2701_PERI_MSDC2_SW_RST 17 +#define MT2701_PERI_MSDC0_SW_RST 19 +#define MT2701_PERI_MSDC1_SW_RST 20 +#define MT2701_PERI_I2C0_SW_RST 22 +#define MT2701_PERI_I2C1_SW_RST 23 +#define MT2701_PERI_I2C2_SW_RST 24 +#define MT2701_PERI_I2C3_SW_RST 25 +#define MT2701_PERI_USB_SW_RST 28 +#define MT2701_PERI_ETH_SW_RST 29 +#define MT2701_PERI_SPI0_SW_RST 33 + +/* TOPRGU resets */ +#define MT2701_TOPRGU_INFRA_RST 0 +#define MT2701_TOPRGU_MM_RST 1 +#define MT2701_TOPRGU_MFG_RST 2 +#define MT2701_TOPRGU_ETHDMA_RST 3 +#define MT2701_TOPRGU_VDEC_RST 4 +#define MT2701_TOPRGU_VENC_IMG_RST 5 +#define MT2701_TOPRGU_DDRPHY_RST 6 +#define MT2701_TOPRGU_MD_RST 7 +#define MT2701_TOPRGU_INFRA_AO_RST 8 +#define MT2701_TOPRGU_CONN_RST 9 +#define MT2701_TOPRGU_APMIXED_RST 10 +#define MT2701_TOPRGU_HIFSYS_RST 11 +#define MT2701_TOPRGU_CONN_MCU_RST 12 +#define MT2701_TOPRGU_BDP_DISP_RST 13 + +/* HIFSYS resets */ +#define MT2701_HIFSYS_UHOST0_RST 3 +#define MT2701_HIFSYS_UHOST1_RST 4 +#define MT2701_HIFSYS_UPHY0_RST 21 +#define MT2701_HIFSYS_UPHY1_RST 22 +#define MT2701_HIFSYS_PCIE0_RST 24 +#define MT2701_HIFSYS_PCIE1_RST 25 +#define MT2701_HIFSYS_PCIE2_RST 26 + +#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT2701 */ diff --git a/include/dt-bindings/reset/qcom,gcc-mdm9615.h b/include/dt-bindings/reset/qcom,gcc-mdm9615.h new file mode 100644 index 000000000000..7f86e9a59df4 --- /dev/null +++ b/include/dt-bindings/reset/qcom,gcc-mdm9615.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Copyright (c) BayLibre, SAS. + * Author : Neil Armstrong <narmstrong@baylibre.com> + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_RESET_GCC_MDM9615_H +#define _DT_BINDINGS_RESET_GCC_MDM9615_H + +#define SFAB_MSS_Q6_SW_RESET 0 +#define SFAB_MSS_Q6_FW_RESET 1 +#define QDSS_STM_RESET 2 +#define AFAB_SMPSS_S_RESET 3 +#define AFAB_SMPSS_M1_RESET 4 +#define AFAB_SMPSS_M0_RESET 5 +#define AFAB_EBI1_CH0_RESET 6 +#define AFAB_EBI1_CH1_RESET 7 +#define SFAB_ADM0_M0_RESET 8 +#define SFAB_ADM0_M1_RESET 9 +#define SFAB_ADM0_M2_RESET 10 +#define ADM0_C2_RESET 11 +#define ADM0_C1_RESET 12 +#define ADM0_C0_RESET 13 +#define ADM0_PBUS_RESET 14 +#define ADM0_RESET 15 +#define QDSS_CLKS_SW_RESET 16 +#define QDSS_POR_RESET 17 +#define QDSS_TSCTR_RESET 18 +#define QDSS_HRESET_RESET 19 +#define QDSS_AXI_RESET 20 +#define QDSS_DBG_RESET 21 +#define PCIE_A_RESET 22 +#define PCIE_AUX_RESET 23 +#define PCIE_H_RESET 24 +#define SFAB_PCIE_M_RESET 25 +#define SFAB_PCIE_S_RESET 26 +#define SFAB_MSS_M_RESET 27 +#define SFAB_USB3_M_RESET 28 +#define SFAB_RIVA_M_RESET 29 +#define SFAB_LPASS_RESET 30 +#define SFAB_AFAB_M_RESET 31 +#define AFAB_SFAB_M0_RESET 32 +#define AFAB_SFAB_M1_RESET 33 +#define SFAB_SATA_S_RESET 34 +#define SFAB_DFAB_M_RESET 35 +#define DFAB_SFAB_M_RESET 36 +#define DFAB_SWAY0_RESET 37 +#define DFAB_SWAY1_RESET 38 +#define DFAB_ARB0_RESET 39 +#define DFAB_ARB1_RESET 40 +#define PPSS_PROC_RESET 41 +#define PPSS_RESET 42 +#define DMA_BAM_RESET 43 +#define SPS_TIC_H_RESET 44 +#define SLIMBUS_H_RESET 45 +#define SFAB_CFPB_M_RESET 46 +#define SFAB_CFPB_S_RESET 47 +#define TSIF_H_RESET 48 +#define CE1_H_RESET 49 +#define CE1_CORE_RESET 50 +#define CE1_SLEEP_RESET 51 +#define CE2_H_RESET 52 +#define CE2_CORE_RESET 53 +#define SFAB_SFPB_M_RESET 54 +#define SFAB_SFPB_S_RESET 55 +#define RPM_PROC_RESET 56 +#define PMIC_SSBI2_RESET 57 +#define SDC1_RESET 58 +#define SDC2_RESET 59 +#define SDC3_RESET 60 +#define SDC4_RESET 61 +#define SDC5_RESET 62 +#define DFAB_A2_RESET 63 +#define USB_HS1_RESET 64 +#define USB_HSIC_RESET 65 +#define USB_FS1_XCVR_RESET 66 +#define USB_FS1_RESET 67 +#define USB_FS2_XCVR_RESET 68 +#define USB_FS2_RESET 69 +#define GSBI1_RESET 70 +#define GSBI2_RESET 71 +#define GSBI3_RESET 72 +#define GSBI4_RESET 73 +#define GSBI5_RESET 74 +#define GSBI6_RESET 75 +#define GSBI7_RESET 76 +#define GSBI8_RESET 77 +#define GSBI9_RESET 78 +#define GSBI10_RESET 79 +#define GSBI11_RESET 80 +#define GSBI12_RESET 81 +#define SPDM_RESET 82 +#define TLMM_H_RESET 83 +#define SFAB_MSS_S_RESET 84 +#define MSS_SLP_RESET 85 +#define MSS_Q6SW_JTAG_RESET 86 +#define MSS_Q6FW_JTAG_RESET 87 +#define MSS_RESET 88 +#define SATA_H_RESET 89 +#define SATA_RXOOB_RESE 90 +#define SATA_PMALIVE_RESET 91 +#define SATA_SFAB_M_RESET 92 +#define TSSC_RESET 93 +#define PDM_RESET 94 +#define MPM_H_RESET 95 +#define MPM_RESET 96 +#define SFAB_SMPSS_S_RESET 97 +#define PRNG_RESET 98 +#define RIVA_RESET 99 +#define USB_HS3_RESET 100 +#define USB_HS4_RESET 101 +#define CE3_RESET 102 +#define PCIE_EXT_PCI_RESET 103 +#define PCIE_PHY_RESET 104 +#define PCIE_PCI_RESET 105 +#define PCIE_POR_RESET 106 +#define PCIE_HCLK_RESET 107 +#define PCIE_ACLK_RESET 108 +#define CE3_H_RESET 109 +#define SFAB_CE3_M_RESET 110 +#define SFAB_CE3_S_RESET 111 +#define SATA_RESET 112 +#define CE3_SLEEP_RESET 113 +#define GSS_SLP_RESET 114 +#define GSS_RESET 115 + +#endif diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index a39c0c530778..37b8fdce0e49 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -780,6 +780,18 @@ extern struct of_device_id __clk_of_table; #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) +/* + * Use this macro when you have a driver that requires two initialization + * routines, one at of_clk_init(), and one at platform device probe + */ +#define CLK_OF_DECLARE_DRIVER(name, compat, fn) \ + static void name##_of_clk_init_driver(struct device_node *np) \ + { \ + of_node_clear_flag(np, OF_POPULATED); \ + fn(np); \ + } \ + OF_DECLARE_1(clk, name, compat, name##_of_clk_init_driver) + #ifdef CONFIG_OF int of_clk_add_provider(struct device_node *np, struct clk *(*clk_src_get)(struct of_phandle_args *args, @@ -842,7 +854,7 @@ of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data) { return ERR_PTR(-ENOENT); } -static inline int of_clk_get_parent_count(struct device_node *np) +static inline unsigned int of_clk_get_parent_count(struct device_node *np) { return 0; } |