Commit 1a5700bc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'clk-for-linus-3.16' of git://git.linaro.org/people/mike.turquette/linux into next

Pull clock framework updates from Mike Turquette:
 "The clock framework changes for 3.16 are pretty typical: mostly clock
  driver additions and fixes.  There are additions to the clock core
  code for some of the basic types (e.g. the common divider type has
  some fixes and featured added to it).

  One minor annoyance is a last-minute dependency that wasn't handled
  quite right.  Commit ba0fae3b ("clk: berlin: add core clock driver
  for BG2/BG2CD") in this pull request depends on
  include/dt-bindings/clock/berlin2.h, which is already in your tree via
  the arm-soc pull request.  Building for the berlin platform will break
  when the clk tree is built on it's own, but merged into your master
  branch everything should be fine"

* tag 'clk-for-linus-3.16' of git://git.linaro.org/people/mike.turquette/linux: (75 commits)
  mmc: sunxi: Add driver for SD/MMC hosts found on Allwinner sunxi SoCs
  clk: export __clk_round_rate for providers
  clk: versatile: free icst on error return
  clk: qcom: Return error pointers for unimplemented clocks
  clk: qcom: Support msm8974pro global clock control hardware
  clk: qcom: Properly support display clocks on msm8974
  clk: qcom: Support display RCG clocks
  clk: qcom: Return highest rate when round_rate() exceeds plan
  clk: qcom: Fix mmcc-8974's PLL configurations
  clk: qcom: Fix clk_rcg2_is_enabled() check
  clk: berlin: add core clock driver for BG2Q
  clk: berlin: add core clock driver for BG2/BG2CD
  clk: berlin: add driver for BG2x complex divider cells
  clk: berlin: add driver for BG2x simple PLLs
  clk: berlin: add driver for BG2x audio/video PLL
  clk: st: Terminate of match table
  clk/exynos4: Fix compilation warning
  ARM: shmobile: r8a7779: Add clock index macros for DT sources
  clk: divider: Fix overflow in clk_divider_bestdiv
  clk: u300: Terminate of match table
  ...
parents a68a7509 3cbcb160
...@@ -68,21 +68,27 @@ the operations defined in clk.h: ...@@ -68,21 +68,27 @@ the operations defined in clk.h:
int (*is_enabled)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw);
unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long (*recalc_rate)(struct clk_hw *hw,
unsigned long parent_rate); unsigned long parent_rate);
long (*round_rate)(struct clk_hw *hw, unsigned long, long (*round_rate)(struct clk_hw *hw,
unsigned long *); unsigned long rate,
unsigned long *parent_rate);
long (*determine_rate)(struct clk_hw *hw, long (*determine_rate)(struct clk_hw *hw,
unsigned long rate, unsigned long rate,
unsigned long *best_parent_rate, unsigned long *best_parent_rate,
struct clk **best_parent_clk); struct clk **best_parent_clk);
int (*set_parent)(struct clk_hw *hw, u8 index); int (*set_parent)(struct clk_hw *hw, u8 index);
u8 (*get_parent)(struct clk_hw *hw); u8 (*get_parent)(struct clk_hw *hw);
int (*set_rate)(struct clk_hw *hw, unsigned long); int (*set_rate)(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate);
int (*set_rate_and_parent)(struct clk_hw *hw, int (*set_rate_and_parent)(struct clk_hw *hw,
unsigned long rate, unsigned long rate,
unsigned long parent_rate, u8 index); unsigned long parent_rate,
u8 index);
unsigned long (*recalc_accuracy)(struct clk_hw *hw, unsigned long (*recalc_accuracy)(struct clk_hw *hw,
unsigned long parent_accuracy); unsigned long parent_accuracy);
void (*init)(struct clk_hw *hw); void (*init)(struct clk_hw *hw);
int (*debug_init)(struct clk_hw *hw,
struct dentry *dentry);
}; };
Part 3 - hardware clk implementations Part 3 - hardware clk implementations
......
...@@ -10,12 +10,12 @@ This binding uses the common clock binding: ...@@ -10,12 +10,12 @@ This binding uses the common clock binding:
Required properties: Required properties:
- compatible - compatible
Shall have one of the following values: Shall have a value of the form "brcm,<model>-<which>-ccu",
- "brcm,bcm11351-root-ccu" where <model> is a Broadcom SoC model number and <which> is
- "brcm,bcm11351-aon-ccu" the name of a defined CCU. For example:
- "brcm,bcm11351-hub-ccu" "brcm,bcm11351-root-ccu"
- "brcm,bcm11351-master-ccu" The compatible strings used for each supported SoC family
- "brcm,bcm11351-slave-ccu" are defined below.
- reg - reg
Shall define the base and range of the address space Shall define the base and range of the address space
containing clock control registers containing clock control registers
...@@ -26,12 +26,48 @@ Required properties: ...@@ -26,12 +26,48 @@ Required properties:
Shall be an ordered list of strings defining the names of Shall be an ordered list of strings defining the names of
the clocks provided by the CCU. the clocks provided by the CCU.
Device tree example:
slave_ccu: slave_ccu {
compatible = "brcm,bcm11351-slave-ccu";
reg = <0x3e011000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "uartb",
"uartb2",
"uartb3",
"uartb4";
};
ref_crystal_clk: ref_crystal {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <26000000>;
};
uart@3e002000 {
compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
status = "disabled";
reg = <0x3e002000 0x1000>;
clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
};
BCM281XX family
---------------
CCU compatible string values for SoCs in the BCM281XX family are:
"brcm,bcm11351-root-ccu"
"brcm,bcm11351-aon-ccu"
"brcm,bcm11351-hub-ccu"
"brcm,bcm11351-master-ccu"
"brcm,bcm11351-slave-ccu"
BCM281XX family SoCs use Kona CCUs. The following table defines The following table defines the set of CCUs and clock specifiers for
the set of CCUs and clock specifiers for BCM281XX clocks. When BCM281XX family clocks. When a clock consumer references a clocks,
a clock consumer references a clocks, its symbolic specifier its symbolic specifier (rather than its numeric index value) should
(rather than its numeric index value) should be used. These be used. These specifiers are defined in:
specifiers are defined in "include/dt-bindings/clock/bcm281xx.h". "include/dt-bindings/clock/bcm281xx.h"
CCU Clock Type Index Specifier CCU Clock Type Index Specifier
--- ----- ---- ----- --------- --- ----- ---- ----- ---------
...@@ -64,30 +100,40 @@ specifiers are defined in "include/dt-bindings/clock/bcm281xx.h". ...@@ -64,30 +100,40 @@ specifiers are defined in "include/dt-bindings/clock/bcm281xx.h".
slave pwm peri 9 BCM281XX_SLAVE_CCU_PWM slave pwm peri 9 BCM281XX_SLAVE_CCU_PWM
Device tree example: BCM21664 family
---------------
CCU compatible string values for SoCs in the BCM21664 family are:
"brcm,bcm21664-root-ccu"
"brcm,bcm21664-aon-ccu"
"brcm,bcm21664-master-ccu"
"brcm,bcm21664-slave-ccu"
slave_ccu: slave_ccu { The following table defines the set of CCUs and clock specifiers for
compatible = "brcm,bcm11351-slave-ccu"; BCM21664 family clocks. When a clock consumer references a clocks,
reg = <0x3e011000 0x0f00>; its symbolic specifier (rather than its numeric index value) should
#clock-cells = <1>; be used. These specifiers are defined in:
clock-output-names = "uartb", "include/dt-bindings/clock/bcm21664.h"
"uartb2",
"uartb3",
"uartb4";
};
ref_crystal_clk: ref_crystal { CCU Clock Type Index Specifier
#clock-cells = <0>; --- ----- ---- ----- ---------
compatible = "fixed-clock"; root frac_1m peri 0 BCM21664_ROOT_CCU_FRAC_1M
clock-frequency = <26000000>;
};
uart@3e002000 { aon hub_timer peri 0 BCM21664_AON_CCU_HUB_TIMER
compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
status = "disabled"; master sdio1 peri 0 BCM21664_MASTER_CCU_SDIO1
reg = <0x3e002000 0x1000>; master sdio2 peri 1 BCM21664_MASTER_CCU_SDIO2
clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>; master sdio3 peri 2 BCM21664_MASTER_CCU_SDIO3
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; master sdio4 peri 3 BCM21664_MASTER_CCU_SDIO4
reg-shift = <2>; master sdio1_sleep peri 4 BCM21664_MASTER_CCU_SDIO1_SLEEP
reg-io-width = <4>; master sdio2_sleep peri 5 BCM21664_MASTER_CCU_SDIO2_SLEEP
}; master sdio3_sleep peri 6 BCM21664_MASTER_CCU_SDIO3_SLEEP
master sdio4_sleep peri 7 BCM21664_MASTER_CCU_SDIO4_SLEEP
slave uartb peri 0 BCM21664_SLAVE_CCU_UARTB
slave uartb2 peri 1 BCM21664_SLAVE_CCU_UARTB2
slave uartb3 peri 2 BCM21664_SLAVE_CCU_UARTB3
slave uartb4 peri 3 BCM21664_SLAVE_CCU_UARTB4
slave bsc1 peri 4 BCM21664_SLAVE_CCU_BSC1
slave bsc2 peri 5 BCM21664_SLAVE_CCU_BSC2
slave bsc3 peri 6 BCM21664_SLAVE_CCU_BSC3
slave bsc4 peri 7 BCM21664_SLAVE_CCU_BSC4
...@@ -44,10 +44,9 @@ For example: ...@@ -44,10 +44,9 @@ For example:
clocks by index. The names should reflect the clock output signal clocks by index. The names should reflect the clock output signal
names for the device. names for the device.
clock-indices: If the identifyng number for the clocks in the node clock-indices: If the identifying number for the clocks in the node
is not linear from zero, then the this mapping allows is not linear from zero, then this allows the mapping of
the mapping of identifiers into the clock-output-names identifiers into the clock-output-names array.
array.
For example, if we have two clocks <&oscillator 1> and <&oscillator 3>: For example, if we have two clocks <&oscillator 1> and <&oscillator 3>:
...@@ -58,7 +57,7 @@ For example, if we have two clocks <&oscillator 1> and <&oscillator 3>: ...@@ -58,7 +57,7 @@ For example, if we have two clocks <&oscillator 1> and <&oscillator 3>:
clock-output-names = "clka", "clkb"; clock-output-names = "clka", "clkb";
} }
This ensures we do not have any empty nodes in clock-output-names This ensures we do not have any empty strings in clock-output-names
==Clock consumers== ==Clock consumers==
......
...@@ -12,7 +12,6 @@ Required properties: ...@@ -12,7 +12,6 @@ Required properties:
Optional properties: Optional properties:
- clock-accuracy : accuracy of clock in ppb (parts per billion). - clock-accuracy : accuracy of clock in ppb (parts per billion).
Should be a single cell. Should be a single cell.
- gpios : From common gpio binding; gpio connection to clock enable pin.
- clock-output-names : From common clock binding. - clock-output-names : From common clock binding.
Example: Example:
......
* Hisilicon Hix5hd2 Clock Controller
The hix5hd2 clock controller generates and supplies clock to various
controllers within the hix5hd2 SoC.
Required Properties:
- compatible: should be "hisilicon,hix5hd2-clock"
- reg: Address and length of the register set
- #clock-cells: Should be <1>
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
All these identifier could be found in <dt-bindings/clock/hix5hd2-clock.h>.
Examples:
clock: clock@f8a22000 {
compatible = "hisilicon,hix5hd2-clock";
reg = <0xf8a22000 0x1000>;
#clock-cells = <1>;
};
uart0: uart@f8b00000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0xf8b00000 0x1000>;
interrupts = <0 49 4>;
clocks = <&clock HIX5HD2_FIXED_83M>;
clock-names = "apb_pclk";
status = "disabled";
};
AXM5516 clock driver bindings
-----------------------------
Required properties :
- compatible : shall contain "lsi,axm5516-clks"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
The consumer specifies the desired clock by having the clock ID in its "clocks"
phandle cell. See <dt-bindings/clock/lsi,axxia-clock.h> for the list of
supported clock IDs.
Example:
clks: clock-controller@2010020000 {
compatible = "lsi,axm5516-clks";
#clock-cells = <1>;
reg = <0x20 0x10020000 0 0x20000>;
};
serial0: uart@2010080000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x20 0x10080000 0 0x1000>;
interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks AXXIA_CLK_PER>;
clock-names = "apb_pclk";
};
};
...@@ -29,6 +29,11 @@ The following is a list of provided IDs and clock names on Kirkwood and Dove: ...@@ -29,6 +29,11 @@ The following is a list of provided IDs and clock names on Kirkwood and Dove:
2 = l2clk (L2 Cache clock derived from CPU0 clock) 2 = l2clk (L2 Cache clock derived from CPU0 clock)
3 = ddrclk (DDR controller clock derived from CPU0 clock) 3 = ddrclk (DDR controller clock derived from CPU0 clock)
The following is a list of provided IDs and clock names on Orion5x:
0 = tclk (Internal Bus clock)
1 = cpuclk (CPU0 clock)
2 = ddrclk (DDR controller clock derived from CPU0 clock)
Required properties: Required properties:
- compatible : shall be one of the following: - compatible : shall be one of the following:
"marvell,armada-370-core-clock" - For Armada 370 SoC core clocks "marvell,armada-370-core-clock" - For Armada 370 SoC core clocks
...@@ -38,6 +43,9 @@ Required properties: ...@@ -38,6 +43,9 @@ Required properties:
"marvell,dove-core-clock" - for Dove SoC core clocks "marvell,dove-core-clock" - for Dove SoC core clocks
"marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180) "marvell,kirkwood-core-clock" - for Kirkwood SoC (except mv88f6180)
"marvell,mv88f6180-core-clock" - for Kirkwood MV88f6180 SoC "marvell,mv88f6180-core-clock" - for Kirkwood MV88f6180 SoC
"marvell,mv88f5182-core-clock" - for Orion MV88F5182 SoC
"marvell,mv88f5281-core-clock" - for Orion MV88F5281 SoC
"marvell,mv88f6183-core-clock" - for Orion MV88F6183 SoC
- reg : shall be the register address of the Sample-At-Reset (SAR) register - reg : shall be the register address of the Sample-At-Reset (SAR) register
- #clock-cells : from common clock binding; shall be set to 1 - #clock-cells : from common clock binding; shall be set to 1
......
...@@ -4,9 +4,12 @@ Qualcomm Global Clock & Reset Controller Binding ...@@ -4,9 +4,12 @@ Qualcomm Global Clock & Reset Controller Binding
Required properties : Required properties :
- compatible : shall contain only one of the following: - compatible : shall contain only one of the following:
"qcom,gcc-apq8064"
"qcom,gcc-msm8660" "qcom,gcc-msm8660"
"qcom,gcc-msm8960" "qcom,gcc-msm8960"
"qcom,gcc-msm8974" "qcom,gcc-msm8974"
"qcom,gcc-msm8974pro"
"qcom,gcc-msm8974pro-ac"
- reg : shall contain base register location and length - reg : shall contain base register location and length
- #clock-cells : shall contain 1 - #clock-cells : shall contain 1
......
...@@ -11,6 +11,7 @@ Required Properties: ...@@ -11,6 +11,7 @@ Required Properties:
- compatible: Must be one of the following - compatible: Must be one of the following
- "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks - "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
- "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
- "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks - "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
- "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks - "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2) MSTP gate clocks
- "renesas,cpg-mstp-clock" for generic MSTP gate clocks - "renesas,cpg-mstp-clock" for generic MSTP gate clocks
......
These bindings should be considered EXPERIMENTAL for now.
* Renesas R8A7740 Clock Pulse Generator (CPG)
The CPG generates core clocks for the R8A7740 SoC. It includes three PLLs
and several fixed ratio and variable ratio dividers.
Required Properties:
- compatible: Must be "renesas,r8a7740-cpg-clocks"
- reg: Base address and length of the memory resource used by the CPG
- clocks: Reference to the three parent clocks
- #clock-cells: Must be 1
- clock-output-names: The names of the clocks. Supported clocks are
"system", "pllc0", "pllc1", "pllc2", "r", "usb24s", "i", "zg", "b",
"m1", "hp", "hpp", "usbp", "s", "zb", "m3", and "cp".
- renesas,mode: board-specific settings of the MD_CK* bits
Example
-------
cpg_clocks: cpg_clocks@e6150000 {
compatible = "renesas,r8a7740-cpg-clocks";
reg = <0xe6150000 0x10000>;
clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>;
#clock-cells = <1>;
clock-output-names = "system", "pllc0", "pllc1",
"pllc2", "r",
"usb24s",
"i", "zg", "b", "m1", "hp",
"hpp", "usbp", "s", "zb", "m3",
"cp";
};
&cpg_clocks {
renesas,mode = <0x05>;
};
* Renesas R8A7779 Clock Pulse Generator (CPG)
The CPG generates core clocks for the R8A7779. It includes one PLL and
several fixed ratio dividers
Required Properties:
- compatible: Must be "renesas,r8a7779-cpg-clocks"
- reg: Base address and length of the memory resource used by the CPG
- clocks: Reference to the parent clock
- #clock-cells: Must be 1
- clock-output-names: The names of the clocks. Supported clocks are "plla",
"z", "zs", "s", "s1", "p", "b", "out".
Example
-------
cpg_clocks: cpg_clocks@ffc80000 {
compatible = "renesas,r8a7779-cpg-clocks";
reg = <0 0xffc80000 0 0x30>;
clocks = <&extal_clk>;
#clock-cells = <1>;
clock-output-names = "plla", "z", "zs", "s", "s1", "p",
"b", "out";
};
* Allwinner sunxi MMC controller
The highspeed MMC host controller on Allwinner SoCs provides an interface
for MMC, SD and SDIO types of memory cards.
Supported maximum speeds are the ones of the eMMC standard 4.5 as well
as the speed of SD standard 3.0.
Absolute maximum transfer rate is 200MB/s
Required properties:
- compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc"
- reg : mmc controller base registers
- clocks : a list with 2 phandle + clock specifier pairs
- clock-names : must contain "ahb" and "mmc"
- interrupts : mmc controller interrupt
Optional properties:
- resets : phandle + reset specifier pair
- reset-names : must contain "ahb"
- for cd, bus-width and additional generic mmc parameters
please refer to mmc.txt within this directory
Examples:
- Within .dtsi:
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mod";
interrupts = <0 32 4>;
status = "disabled";
};
- Within dts:
mmc0: mmc@01c0f000 {
pinctrl-names = "default", "default";
pinctrl-0 = <&mmc0_pins_a>;
pinctrl-1 = <&mmc0_cd_pin_reference_design>;
bus-width = <4>;
cd-gpios = <&pio 7 1 0>; /* PH1 */
cd-inverted;
status = "okay";
};
...@@ -815,6 +815,11 @@ F: arch/arm/boot/dts/at91*.dtsi ...@@ -815,6 +815,11 @@ F: arch/arm/boot/dts/at91*.dtsi
F: arch/arm/boot/dts/sama*.dts F: arch/arm/boot/dts/sama*.dts
F: arch/arm/boot/dts/sama*.dtsi F: arch/arm/boot/dts/sama*.dtsi
ARM/ATMEL AT91 Clock Support
M: Boris Brezillon <boris.brezillon@free-electrons.com>
S: Maintained
F: drivers/clk/at91
ARM/CALXEDA HIGHBANK ARCHITECTURE ARM/CALXEDA HIGHBANK ARCHITECTURE
M: Rob Herring <robh@kernel.org> M: Rob Herring <robh@kernel.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/interrupt-controller/irq.h>
#include "dt-bindings/clock/bcm21664.h"
#include "skeleton.dtsi" #include "skeleton.dtsi"
/ { / {
...@@ -43,7 +45,7 @@ uart@3e000000 { ...@@ -43,7 +45,7 @@ uart@3e000000 {
compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart"; compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
status = "disabled"; status = "disabled";
reg = <0x3e000000 0x118>; reg = <0x3e000000 0x118>;
clocks = <&uartb_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB>;
interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>; reg-shift = <2>;
reg-io-width = <4>; reg-io-width = <4>;
...@@ -53,7 +55,7 @@ uart@3e001000 { ...@@ -53,7 +55,7 @@ uart@3e001000 {
compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart"; compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
status = "disabled"; status = "disabled";
reg = <0x3e001000 0x118>; reg = <0x3e001000 0x118>;
clocks = <&uartb2_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB2>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>; reg-shift = <2>;
reg-io-width = <4>; reg-io-width = <4>;
...@@ -63,7 +65,7 @@ uart@3e002000 { ...@@ -63,7 +65,7 @@ uart@3e002000 {
compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart"; compatible = "brcm,bcm21664-dw-apb-uart", "snps,dw-apb-uart";
status = "disabled"; status = "disabled";
reg = <0x3e002000 0x118>; reg = <0x3e002000 0x118>;
clocks = <&uartb3_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_UARTB3>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>; reg-shift = <2>;
reg-io-width = <4>; reg-io-width = <4>;
...@@ -85,7 +87,7 @@ timer@35006000 { ...@@ -85,7 +87,7 @@ timer@35006000 {
compatible = "brcm,kona-timer"; compatible = "brcm,kona-timer";
reg = <0x35006000 0x1c>; reg = <0x35006000 0x1c>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&hub_timer_clk>; clocks = <&aon_ccu BCM21664_AON_CCU_HUB_TIMER>;
}; };
gpio: gpio@35003000 { gpio: gpio@35003000 {
...@@ -106,7 +108,7 @@ sdio1: sdio@3f180000 { ...@@ -106,7 +108,7 @@ sdio1: sdio@3f180000 {
compatible = "brcm,kona-sdhci"; compatible = "brcm,kona-sdhci";
reg = <0x3f180000 0x801c>; reg = <0x3f180000 0x801c>;
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sdio1_clk>; clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO1>;
status = "disabled"; status = "disabled";
}; };
...@@ -114,7 +116,7 @@ sdio2: sdio@3f190000 { ...@@ -114,7 +116,7 @@ sdio2: sdio@3f190000 {
compatible = "brcm,kona-sdhci"; compatible = "brcm,kona-sdhci";
reg = <0x3f190000 0x801c>; reg = <0x3f190000 0x801c>;
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sdio2_clk>; clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO2>;
status = "disabled"; status = "disabled";
}; };
...@@ -122,7 +124,7 @@ sdio3: sdio@3f1a0000 { ...@@ -122,7 +124,7 @@ sdio3: sdio@3f1a0000 {
compatible = "brcm,kona-sdhci"; compatible = "brcm,kona-sdhci";
reg = <0x3f1a0000 0x801c>; reg = <0x3f1a0000 0x801c>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sdio3_clk>; clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO3>;
status = "disabled"; status = "disabled";
}; };
...@@ -130,7 +132,7 @@ sdio4: sdio@3f1b0000 { ...@@ -130,7 +132,7 @@ sdio4: sdio@3f1b0000 {
compatible = "brcm,kona-sdhci"; compatible = "brcm,kona-sdhci";
reg = <0x3f1b0000 0x801c>; reg = <0x3f1b0000 0x801c>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sdio4_clk>; clocks = <&master_ccu BCM21664_MASTER_CCU_SDIO4>;
status = "disabled"; status = "disabled";
}; };
...@@ -140,7 +142,7 @@ i2c@3e016000 { ...@@ -140,7 +142,7 @@ i2c@3e016000 {
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&bsc1_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC1>;
status = "disabled"; status = "disabled";
}; };
...@@ -150,7 +152,7 @@ i2c@3e017000 { ...@@ -150,7 +152,7 @@ i2c@3e017000 {
interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&bsc2_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC2>;
status = "disabled"; status = "disabled";
}; };
...@@ -160,7 +162,7 @@ i2c@3e018000 { ...@@ -160,7 +162,7 @@ i2c@3e018000 {
interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&bsc3_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC3>;
status = "disabled"; status = "disabled";
}; };
...@@ -170,105 +172,149 @@ i2c@3e01c000 { ...@@ -170,105 +172,149 @@ i2c@3e01c000 {
interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
clocks = <&bsc4_clk>; clocks = <&slave_ccu BCM21664_SLAVE_CCU_BSC4>;
status = "disabled"; status = "disabled";
}; };
clocks { clocks {
bsc1_clk: bsc1 { #address-cells = <1>;
compatible = "fixed-clock"; #size-cells = <1>;
clock-frequency = <13000000>; ranges;
#clock-cells = <0>;
};
bsc2_clk: bsc2 { /*
compatible = "fixed-clock"; * Fixed clocks are defined before CCUs whose
clock-frequency = <13000000>; * clocks may depend on them.
*/
ref_32k_clk: ref_32k {
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
}; };
bsc3_clk: bsc3 { bbl_32k_clk: bbl_32k {
compatible = "fixed-clock";
clock-frequency = <13000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
}; };
bsc4_clk: bsc4 { ref_13m_clk: ref_13m {
#clock-cells = <0>;
compatible = "fixed-clock"; compatible = "fixed-clock";
clock-frequency = <13000000>; clock-frequency = <13000000>;
#clock-cells = <0>;
}; };
pmu_bsc_clk: pmu_bsc { var_13m_clk: var_13m {
#clock-cells = <0>;
compatible = "fixed-clock"; compatible = "fixed-clock";
clock-frequency = <13000000>; clock-frequency = <13000000>;
#clock-cells = <0>;
}; };
hub_timer_clk: hub_timer { dft_19_5m_clk: dft_19_5m {
compatible = "fixed-clock";
clock-frequency = <32768>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <19500000>;
}; };
pwm_clk: pwm { ref_crystal_clk: ref_crystal {
#clock-cells = <0>;
compatible = "fixed-clock"; compatible = "fixed-clock";
clock-frequency = <26000000>; clock-frequency = <26000000>;
#clock-cells = <0>;
}; };
sdio1_clk: sdio1 { ref_52m_clk: ref_52m {
compatible = "fixed-clock";
clock-frequency = <48000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <52000000>;
}; };
sdio2_clk: sdio2 { var_52m_clk: var_52m {
compatible = "fixed-clock";
clock-frequency = <48000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <52000000>;
}; };
sdio3_clk: sdio3 { usb_otg_ahb_clk: usb_otg_ahb {
compatible = "fixed-clock";
clock-frequency = <48000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <52000000>;
}; };
sdio4_clk: sdio4 { ref_96m_clk: ref_96m {
compatible = "fixed-clock";
clock-frequency = <48000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <96000000>;
}; };
tmon_1m_clk: tmon_1m { var_96m_clk: var_96m {
compatible = "fixed-clock";
clock-frequency = <1000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <96000000>;
}; };
uartb_clk: uartb { ref_104m_clk: ref_104m {
compatible = "fixed-clock";
clock-frequency = <13000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <104000000>;
}; };
uartb2_clk: uartb2 { var_104m_clk: var_104m {
compatible = "fixed-clock";
clock-frequency = <13000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <104000000>;
}; };
uartb3_clk: uartb3 { ref_156m_clk: ref_156m {
compatible = "fixed-clock";
clock-frequency = <13000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <156000000>;
}; };
usb_otg_ahb_clk: usb_otg_ahb { var_156m_clk: var_156m {
compatible = "fixed-clock";
clock-frequency = <52000000>;
#clock-cells = <0>; #clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <156000000>;
};
root_ccu: root_ccu {
compatible = BCM21664_DT_ROOT_CCU_COMPAT;
reg = <0x35001000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "frac_1m";
};
aon_ccu: aon_ccu {
compatible = BCM21664_DT_AON_CCU_COMPAT;
reg = <0x35002000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "hub_timer";
};
master_ccu: master_ccu {
compatible = BCM21664_DT_MASTER_CCU_COMPAT;
reg = <0x3f001000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "sdio1",
"sdio2",
"sdio3",
"sdio4",
"sdio1_sleep",
"sdio2_sleep",
"sdio3_sleep",
"sdio4_sleep";
};
slave_ccu: slave_ccu {
compatible = BCM21664_DT_SLAVE_CCU_COMPAT;
reg = <0x3e011000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "uartb",
"uartb2",
"uartb3",
"bsc1",
"bsc2",
"bsc3",
"bsc4";
}; };
}; };
......
...@@ -58,12 +58,12 @@ config COMMON_CLK_SI570 ...@@ -58,12 +58,12 @@ config COMMON_CLK_SI570
clock generators. clock generators.
config COMMON_CLK_S2MPS11 config COMMON_CLK_S2MPS11
tristate "Clock driver for S2MPS11/S5M8767 MFD" tristate "Clock driver for S2MPS1X/S5M8767 MFD"
depends on MFD_SEC_CORE depends on MFD_SEC_CORE
---help--- ---help---
This driver supports S2MPS11/S5M8767 crystal oscillator clock. These This driver supports S2MPS11/S2MPS14/S5M8767 crystal oscillator
multi-function devices have 3 fixed-rate oscillators, clocked at clock. These multi-function devices have two (S2MPS14) or three
32KHz each. (S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.
config CLK_TWL6040 config CLK_TWL6040
tristate "External McPDM functional clock from twl6040" tristate "External McPDM functional clock from twl6040"
......
...@@ -13,6 +13,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o ...@@ -13,6 +13,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o
# hardware specific clock types # hardware specific clock types
# please keep this section sorted lexicographically by file/directory path name # please keep this section sorted lexicographically by file/directory path name
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
...@@ -32,8 +33,10 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o ...@@ -32,8 +33,10 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
obj-$(CONFIG_COMMON_CLK_AT91) += at91/ obj-$(CONFIG_COMMON_CLK_AT91) += at91/
obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/ obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm/
obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
obj-$(CONFIG_ARCH_HIP04) += hisilicon/ obj-$(CONFIG_ARCH_HIP04) += hisilicon/
obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
ifeq ($(CONFIG_COMMON_CLK), y) ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/ obj-$(CONFIG_ARCH_MMP) += mmp/
......
...@@ -6,4 +6,4 @@ config CLK_BCM_KONA ...@@ -6,4 +6,4 @@ config CLK_BCM_KONA
help help
Enable common clock framework support for Broadcom SoCs Enable common clock framework support for Broadcom SoCs
using "Kona" style clock control units, including those using "Kona" style clock control units, including those
in the BCM281xx family. in the BCM281xx and BCM21664 families.
obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o
obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o
obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o
/*
* Copyright (C) 2014 Broadcom Corporation
* Copyright 2014 Linaro Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "clk-kona.h"
#include "dt-bindings/clock/bcm21664.h"
#define BCM21664_CCU_COMMON(_name, _capname) \
KONA_CCU_COMMON(BCM21664, _name, _capname)
/* Root CCU */
static struct peri_clk_data frac_1m_data = {
.gate = HW_SW_GATE(0x214, 16, 0, 1),
.clocks = CLOCKS("ref_crystal"),
};
static struct ccu_data root_ccu_data = {
BCM21664_CCU_COMMON(root, ROOT),
/* no policy control */
.kona_clks = {
[BCM21664_ROOT_CCU_FRAC_1M] =
KONA_CLK(root, frac_1m, peri),
[BCM21664_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* AON CCU */
static struct peri_clk_data hub_timer_data = {
.gate = HW_SW_GATE(0x0414, 16, 0, 1),
.hyst = HYST(0x0414, 8, 9),
.clocks = CLOCKS("bbl_32k",
"frac_1m",
"dft_19_5m"),
.sel = SELECTOR(0x0a10, 0, 2),
.trig = TRIGGER(0x0a40, 4),
};
static struct ccu_data aon_ccu_data = {
BCM21664_CCU_COMMON(aon, AON),
.policy = {
.enable = CCU_LVM_EN(0x0034, 0),
.control = CCU_POLICY_CTL(0x000c, 0, 1, 2),
},
.kona_clks = {
[BCM21664_AON_CCU_HUB_TIMER] =
KONA_CLK(aon, hub_timer, peri),
[BCM21664_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* Master CCU */
static struct peri_clk_data sdio1_data = {
.gate = HW_SW_GATE(0x0358, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_52m",
"ref_52m",
"var_96m",
"ref_96m"),
.sel = SELECTOR(0x0a28, 0, 3),
.div = DIVIDER(0x0a28, 4, 14),
.trig = TRIGGER(0x0afc, 9),
};
static struct peri_clk_data sdio2_data = {
.gate = HW_SW_GATE(0x035c, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_52m",
"ref_52m",
"var_96m",
"ref_96m"),
.sel = SELECTOR(0x0a2c, 0, 3),
.div = DIVIDER(0x0a2c, 4, 14),
.trig = TRIGGER(0x0afc, 10),
};
static struct peri_clk_data sdio3_data = {
.gate = HW_SW_GATE(0x0364, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_52m",
"ref_52m",
"var_96m",
"ref_96m"),
.sel = SELECTOR(0x0a34, 0, 3),
.div = DIVIDER(0x0a34, 4, 14),
.trig = TRIGGER(0x0afc, 12),
};
static struct peri_clk_data sdio4_data = {
.gate = HW_SW_GATE(0x0360, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_52m",
"ref_52m",
"var_96m",
"ref_96m"),
.sel = SELECTOR(0x0a30, 0, 3),
.div = DIVIDER(0x0a30, 4, 14),
.trig = TRIGGER(0x0afc, 11),
};
static struct peri_clk_data sdio1_sleep_data = {
.clocks = CLOCKS("ref_32k"), /* Verify */
.gate = HW_SW_GATE(0x0358, 18, 2, 3),
};
static struct peri_clk_data sdio2_sleep_data = {
.clocks = CLOCKS("ref_32k"), /* Verify */
.gate = HW_SW_GATE(0x035c, 18, 2, 3),
};
static struct peri_clk_data sdio3_sleep_data = {
.clocks = CLOCKS("ref_32k"), /* Verify */
.gate = HW_SW_GATE(0x0364, 18, 2, 3),
};
static struct peri_clk_data sdio4_sleep_data = {
.clocks = CLOCKS("ref_32k"), /* Verify */
.gate = HW_SW_GATE(0x0360, 18, 2, 3),
};
static struct ccu_data master_ccu_data = {
BCM21664_CCU_COMMON(master, MASTER),
.policy = {
.enable = CCU_LVM_EN(0x0034, 0),
.control = CCU_POLICY_CTL(0x000c, 0, 1, 2),
},
.kona_clks = {
[BCM21664_MASTER_CCU_SDIO1] =
KONA_CLK(master, sdio1, peri),
[BCM21664_MASTER_CCU_SDIO2] =
KONA_CLK(master, sdio2, peri),
[BCM21664_MASTER_CCU_SDIO3] =
KONA_CLK(master, sdio3, peri),
[BCM21664_MASTER_CCU_SDIO4] =
KONA_CLK(master, sdio4, peri),
[BCM21664_MASTER_CCU_SDIO1_SLEEP] =
KONA_CLK(master, sdio1_sleep, peri),
[BCM21664_MASTER_CCU_SDIO2_SLEEP] =
KONA_CLK(master, sdio2_sleep, peri),
[BCM21664_MASTER_CCU_SDIO3_SLEEP] =
KONA_CLK(master, sdio3_sleep, peri),
[BCM21664_MASTER_CCU_SDIO4_SLEEP] =
KONA_CLK(master, sdio4_sleep, peri),
[BCM21664_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* Slave CCU */
static struct peri_clk_data uartb_data = {
.gate = HW_SW_GATE(0x0400, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_156m",
"ref_156m"),
.sel = SELECTOR(0x0a10, 0, 2),
.div = FRAC_DIVIDER(0x0a10, 4, 12, 8),
.trig = TRIGGER(0x0afc, 2),
};
static struct peri_clk_data uartb2_data = {
.gate = HW_SW_GATE(0x0404, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_156m",
"ref_156m"),
.sel = SELECTOR(0x0a14, 0, 2),
.div = FRAC_DIVIDER(0x0a14, 4, 12, 8),
.trig = TRIGGER(0x0afc, 3),
};
static struct peri_clk_data uartb3_data = {
.gate = HW_SW_GATE(0x0408, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_156m",
"ref_156m"),
.sel = SELECTOR(0x0a18, 0, 2),
.div = FRAC_DIVIDER(0x0a18, 4, 12, 8),
.trig = TRIGGER(0x0afc, 4),
};
static struct peri_clk_data bsc1_data = {
.gate = HW_SW_GATE(0x0458, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_104m",
"ref_104m",
"var_13m",
"ref_13m"),
.sel = SELECTOR(0x0a64, 0, 3),
.trig = TRIGGER(0x0afc, 23),
};
static struct peri_clk_data bsc2_data = {
.gate = HW_SW_GATE(0x045c, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_104m",
"ref_104m",
"var_13m",
"ref_13m"),
.sel = SELECTOR(0x0a68, 0, 3),
.trig = TRIGGER(0x0afc, 24),
};
static struct peri_clk_data bsc3_data = {
.gate = HW_SW_GATE(0x0470, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_104m",
"ref_104m",
"var_13m",
"ref_13m"),
.sel = SELECTOR(0x0a7c, 0, 3),
.trig = TRIGGER(0x0afc, 18),
};
static struct peri_clk_data bsc4_data = {
.gate = HW_SW_GATE(0x0474, 18, 2, 3),
.clocks = CLOCKS("ref_crystal",
"var_104m",
"ref_104m",
"var_13m",
"ref_13m"),
.sel = SELECTOR(0x0a80, 0, 3),
.trig = TRIGGER(0x0afc, 19),
};
static struct ccu_data slave_ccu_data = {
BCM21664_CCU_COMMON(slave, SLAVE),
.policy = {
.enable = CCU_LVM_EN(0x0034, 0),
.control = CCU_POLICY_CTL(0x000c, 0, 1, 2),
},
.kona_clks = {
[BCM21664_SLAVE_CCU_UARTB] =
KONA_CLK(slave, uartb, peri),
[BCM21664_SLAVE_CCU_UARTB2] =
KONA_CLK(slave, uartb2, peri),
[BCM21664_SLAVE_CCU_UARTB3] =
KONA_CLK(slave, uartb3, peri),
[BCM21664_SLAVE_CCU_BSC1] =
KONA_CLK(slave, bsc1, peri),
[BCM21664_SLAVE_CCU_BSC2] =
KONA_CLK(slave, bsc2, peri),
[BCM21664_SLAVE_CCU_BSC3] =
KONA_CLK(slave, bsc3, peri),
[BCM21664_SLAVE_CCU_BSC4] =
KONA_CLK(slave, bsc4, peri),
[BCM21664_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* Device tree match table callback functions */
static void __init kona_dt_root_ccu_setup(struct device_node *node)
{
kona_dt_ccu_setup(&root_ccu_data, node);
}
static void __init kona_dt_aon_ccu_setup(struct device_node *node)
{
kona_dt_ccu_setup(&aon_ccu_data, node);
}
static void __init kona_dt_master_ccu_setup(struct device_node *node)
{
kona_dt_ccu_setup(&master_ccu_data, node);
}
static void __init kona_dt_slave_ccu_setup(struct device_node *node)
{
kona_dt_ccu_setup(&slave_ccu_data, node);
}
CLK_OF_DECLARE(bcm21664_root_ccu, BCM21664_DT_ROOT_CCU_COMPAT,
kona_dt_root_ccu_setup);
CLK_OF_DECLARE(bcm21664_aon_ccu, BCM21664_DT_AON_CCU_COMPAT,
kona_dt_aon_ccu_setup);
CLK_OF_DECLARE(bcm21664_master_ccu, BCM21664_DT_MASTER_CCU_COMPAT,
kona_dt_master_ccu_setup);
CLK_OF_DECLARE(bcm21664_slave_ccu, BCM21664_DT_SLAVE_CCU_COMPAT,
kona_dt_slave_ccu_setup);
...@@ -15,14 +15,10 @@ ...@@ -15,14 +15,10 @@
#include "clk-kona.h" #include "clk-kona.h"
#include "dt-bindings/clock/bcm281xx.h" #include "dt-bindings/clock/bcm281xx.h"
/* bcm11351 CCU device tree "compatible" strings */ #define BCM281XX_CCU_COMMON(_name, _ucase_name) \
#define BCM11351_DT_ROOT_CCU_COMPAT "brcm,bcm11351-root-ccu" KONA_CCU_COMMON(BCM281XX, _name, _ucase_name)
#define BCM11351_DT_AON_CCU_COMPAT "brcm,bcm11351-aon-ccu"
#define BCM11351_DT_HUB_CCU_COMPAT "brcm,bcm11351-hub-ccu"
#define BCM11351_DT_MASTER_CCU_COMPAT "brcm,bcm11351-master-ccu"
#define BCM11351_DT_SLAVE_CCU_COMPAT "brcm,bcm11351-slave-ccu"
/* Root CCU clocks */ /* Root CCU */
static struct peri_clk_data frac_1m_data = { static struct peri_clk_data frac_1m_data = {
.gate = HW_SW_GATE(0x214, 16, 0, 1), .gate = HW_SW_GATE(0x214, 16, 0, 1),
...@@ -31,7 +27,16 @@ static struct peri_clk_data frac_1m_data = { ...@@ -31,7 +27,16 @@ static struct peri_clk_data frac_1m_data = {
.clocks = CLOCKS("ref_crystal"), .clocks = CLOCKS("ref_crystal"),
}; };
/* AON CCU clocks */ static struct ccu_data root_ccu_data = {
BCM281XX_CCU_COMMON(root, ROOT),
.kona_clks = {
[BCM281XX_ROOT_CCU_FRAC_1M] =
KONA_CLK(root, frac_1m, peri),
[BCM281XX_ROOT_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* AON CCU */
static struct peri_clk_data hub_timer_data = { static struct peri_clk_data hub_timer_data = {
.gate = HW_SW_GATE(0x0414, 16, 0, 1), .gate = HW_SW_GATE(0x0414, 16, 0, 1),
...@@ -60,7 +65,20 @@ static struct peri_clk_data pmu_bsc_var_data = { ...@@ -60,7 +65,20 @@ static struct peri_clk_data pmu_bsc_var_data = {
.trig = TRIGGER(0x0a40, 2), .trig = TRIGGER(0x0a40, 2),
}; };
/* Hub CCU clocks */ static struct ccu_data aon_ccu_data = {
BCM281XX_CCU_COMMON(aon, AON),
.kona_clks = {
[BCM281XX_AON_CCU_HUB_TIMER] =
KONA_CLK(aon, hub_timer, peri),
[BCM281XX_AON_CCU_PMU_BSC] =
KONA_CLK(aon, pmu_bsc, peri),
[BCM281XX_AON_CCU_PMU_BSC_VAR] =
KONA_CLK(aon, pmu_bsc_var, peri),
[BCM281XX_AON_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* Hub CCU */
static struct peri_clk_data tmon_1m_data = { static struct peri_clk_data tmon_1m_data = {
.gate = HW_SW_GATE(0x04a4, 18, 2, 3), .gate = HW_SW_GATE(0x04a4, 18, 2, 3),
...@@ -70,7 +88,16 @@ static struct peri_clk_data tmon_1m_data = { ...@@ -70,7 +88,16 @@ static struct peri_clk_data tmon_1m_data = {
.trig = TRIGGER(0x0e84, 1), .trig = TRIGGER(0x0e84, 1),
}; };
/* Master CCU clocks */ static struct ccu_data hub_ccu_data = {
BCM281XX_CCU_COMMON(hub, HUB),
.kona_clks = {
[BCM281XX_HUB_CCU_TMON_1M] =
KONA_CLK(hub, tmon_1m, peri),
[BCM281XX_HUB_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* Master CCU */
static struct peri_clk_data sdio1_data = { static struct peri_clk_data sdio1_data = {
.gate = HW_SW_GATE(0x0358, 18, 2, 3), .gate = HW_SW_GATE(0x0358, 18, 2, 3),
...@@ -153,7 +180,28 @@ static struct peri_clk_data hsic2_12m_data = { ...@@ -153,7 +180,28 @@ static struct peri_clk_data hsic2_12m_data = {
.trig = TRIGGER(0x0afc, 5), .trig = TRIGGER(0x0afc, 5),
}; };
/* Slave CCU clocks */ static struct ccu_data master_ccu_data = {
BCM281XX_CCU_COMMON(master, MASTER),
.kona_clks = {
[BCM281XX_MASTER_CCU_SDIO1] =
KONA_CLK(master, sdio1, peri),
[BCM281XX_MASTER_CCU_SDIO2] =
KONA_CLK(master, sdio2, peri),
[BCM281XX_MASTER_CCU_SDIO3] =
KONA_CLK(master, sdio3, peri),
[BCM281XX_MASTER_CCU_SDIO4] =
KONA_CLK(master, sdio4, peri),
[BCM281XX_MASTER_CCU_USB_IC] =
KONA_CLK(master, usb_ic, peri),
[BCM281XX_MASTER_CCU_HSIC2_48M] =
KONA_CLK(master, hsic2_48m, peri),
[BCM281XX_MASTER_CCU_HSIC2_12M] =
KONA_CLK(master, hsic2_12m, peri),
[BCM281XX_MASTER_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
},
};
/* Slave CCU */
static struct peri_clk_data uartb_data = { static struct peri_clk_data uartb_data = {
.gate = HW_SW_GATE(0x0400, 18, 2, 3), .gate = HW_SW_GATE(0x0400, 18, 2, 3),
...@@ -261,156 +309,67 @@ static struct peri_clk_data pwm_data = { ...@@ -261,156 +309,67 @@ static struct peri_clk_data pwm_data = {
.trig = TRIGGER(0x0afc, 15), .trig = TRIGGER(0x0afc, 15),
}; };
/* static struct ccu_data slave_ccu_data = {
* CCU setup routines BCM281XX_CCU_COMMON(slave, SLAVE),
* .kona_clks = {
* These are called from kona_dt_ccu_setup() to initialize the array [BCM281XX_SLAVE_CCU_UARTB] =
* of clocks provided by the CCU. Once allocated, the entries in KONA_CLK(slave, uartb, peri),
* the array are initialized by calling kona_clk_setup() with the [BCM281XX_SLAVE_CCU_UARTB2] =
* initialization data for each clock. They return 0 if successful KONA_CLK(slave, uartb2, peri),
* or an error code otherwise. [BCM281XX_SLAVE_CCU_UARTB3] =
*/ KONA_CLK(slave, uartb3, peri),
static int __init bcm281xx_root_ccu_clks_setup(struct ccu_data *ccu) [BCM281XX_SLAVE_CCU_UARTB4] =
{ KONA_CLK(slave, uartb4, peri),
struct clk **clks; [BCM281XX_SLAVE_CCU_SSP0] =
size_t count = BCM281XX_ROOT_CCU_CLOCK_COUNT; KONA_CLK(slave, ssp0, peri),
[BCM281XX_SLAVE_CCU_SSP2] =
clks = kzalloc(count * sizeof(*clks), GFP_KERNEL); KONA_CLK(slave, ssp2, peri),
if (!clks) { [BCM281XX_SLAVE_CCU_BSC1] =
pr_err("%s: failed to allocate root clocks\n", __func__); KONA_CLK(slave, bsc1, peri),
return -ENOMEM; [BCM281XX_SLAVE_CCU_BSC2] =
} KONA_CLK(slave, bsc2, peri),
ccu->data.clks = clks; [BCM281XX_SLAVE_CCU_BSC3] =
ccu->data.clk_num = count; KONA_CLK(slave, bsc3, peri),
[BCM281XX_SLAVE_CCU_PWM] =
PERI_CLK_SETUP(clks, ccu, BCM281XX_ROOT_CCU_FRAC_1M, frac_1m); KONA_CLK(slave, pwm, peri),
[BCM281XX_SLAVE_CCU_CLOCK_COUNT] = LAST_KONA_CLK,
return 0; },
} };
static int __init bcm281xx_aon_ccu_clks_setup(struct ccu_data *ccu)
{
struct clk **clks;
size_t count = BCM281XX_AON_CCU_CLOCK_COUNT;
clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
if (!clks) {
pr_err("%s: failed to allocate aon clocks\n", __func__);
return -ENOMEM;
}
ccu->data.clks = clks;
ccu->data.clk_num = count;
PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_HUB_TIMER, hub_timer);
PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC, pmu_bsc);
PERI_CLK_SETUP(clks, ccu, BCM281XX_AON_CCU_PMU_BSC_VAR, pmu_bsc_var);
return 0;
}
static int __init bcm281xx_hub_ccu_clks_setup(struct ccu_data *ccu)
{
struct clk **clks;
size_t count = BCM281XX_HUB_CCU_CLOCK_COUNT;
clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
if (!clks) {
pr_err("%s: failed to allocate hub clocks\n", __func__);
return -ENOMEM;
}
ccu->data.clks = clks;
ccu->data.clk_num = count;
PERI_CLK_SETUP(clks, ccu, BCM281XX_HUB_CCU_TMON_1M, tmon_1m);
return 0;
}
static int __init bcm281xx_master_ccu_clks_setup(struct ccu_data *ccu)
{
struct clk **clks;
size_t count = BCM281XX_MASTER_CCU_CLOCK_COUNT;
clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
if (!clks) {
pr_err("%s: failed to allocate master clocks\n", __func__);
return -ENOMEM;
}
ccu->data.clks = clks;
ccu->data.clk_num = count;
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO1, sdio1);
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO2, sdio2);
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO3, sdio3);
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_SDIO4, sdio4);
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_USB_IC, usb_ic);
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_48M, hsic2_48m);
PERI_CLK_SETUP(clks, ccu, BCM281XX_MASTER_CCU_HSIC2_12M, hsic2_12m);
return 0;
}
static int __init bcm281xx_slave_ccu_clks_setup(struct ccu_data *ccu)
{
struct clk **clks;
size_t count = BCM281XX_SLAVE_CCU_CLOCK_COUNT;
clks = kzalloc(count * sizeof(*clks), GFP_KERNEL);
if (!clks) {
pr_err("%s: failed to allocate slave clocks\n", __func__);
return -ENOMEM;
}
ccu->data.clks = clks;
ccu->data.clk_num = count;
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB, uartb);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB2, uartb2);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB3, uartb3);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_UARTB4, uartb4);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP0, ssp0);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_SSP2, ssp2);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC1, bsc1);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC2, bsc2);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_BSC3, bsc3);
PERI_CLK_SETUP(clks, ccu, BCM281XX_SLAVE_CCU_PWM, pwm);
return 0;
}
/* Device tree match table callback functions */ /* Device tree match table callback functions */
static void __init kona_dt_root_ccu_setup(struct device_node *node) static void __init kona_dt_root_ccu_setup(struct device_node *node)
{ {
kona_dt_ccu_setup(node, bcm281xx_root_ccu_clks_setup); kona_dt_ccu_setup(&root_ccu_data, node);
} }
static void __init kona_dt_aon_ccu_setup(struct device_node *node) static void __init kona_dt_aon_ccu_setup(struct device_node *node)
{ {
kona_dt_ccu_setup(node, bcm281xx_aon_ccu_clks_setup); kona_dt_ccu_setup(&aon_ccu_data, node);
} }
static void __init kona_dt_hub_ccu_setup(struct device_node *node) static void __init kona_dt_hub_ccu_setup(struct device_node *node)
{ {
kona_dt_ccu_setup(node, bcm281xx_hub_ccu_clks_setup); kona_dt_ccu_setup(&hub_ccu_data, node);
} }
static void __init kona_dt_master_ccu_setup(struct device_node *node) static void __init kona_dt_master_ccu_setup(struct device_node *node)
{ {
kona_dt_ccu_setup(node, bcm281xx_master_ccu_clks_setup); kona_dt_ccu_setup(&master_ccu_data, node);
} }
static void __init kona_dt_slave_ccu_setup(struct device_node *node) static void __init kona_dt_slave_ccu_setup(struct device_node *node)
{ {
kona_dt_ccu_setup(node, bcm281xx_slave_ccu_clks_setup); kona_dt_ccu_setup(&slave_ccu_data, node);
} }
CLK_OF_DECLARE(bcm11351_root_ccu, BCM11351_DT_ROOT_CCU_COMPAT, CLK_OF_DECLARE(bcm281xx_root_ccu, BCM281XX_DT_ROOT_CCU_COMPAT,
kona_dt_root_ccu_setup); kona_dt_root_ccu_setup);
CLK_OF_DECLARE(bcm11351_aon_ccu, BCM11351_DT_AON_CCU_COMPAT, CLK_OF_DECLARE(bcm281xx_aon_ccu, BCM281XX_DT_AON_CCU_COMPAT,
kona_dt_aon_ccu_setup); kona_dt_aon_ccu_setup);
CLK_OF_DECLARE(bcm11351_hub_ccu, BCM11351_DT_HUB_CCU_COMPAT, CLK_OF_DECLARE(bcm281xx_hub_ccu, BCM281XX_DT_HUB_CCU_COMPAT,
kona_dt_hub_ccu_setup); kona_dt_hub_ccu_setup);
CLK_OF_DECLARE(bcm11351_master_ccu, BCM11351_DT_MASTER_CCU_COMPAT, CLK_OF_DECLARE(bcm281xx_master_ccu, BCM281XX_DT_MASTER_CCU_COMPAT,
kona_dt_master_ccu_setup); kona_dt_master_ccu_setup);
CLK_OF_DECLARE(bcm11351_slave_ccu, BCM11351_DT_SLAVE_CCU_COMPAT, CLK_OF_DECLARE(bcm281xx_slave_ccu, BCM281XX_DT_SLAVE_CCU_COMPAT,
kona_dt_slave_ccu_setup); kona_dt_slave_ccu_setup);
This diff is collapsed.
This diff is collapsed.
...@@ -43,8 +43,14 @@ ...@@ -43,8 +43,14 @@
#define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag)) #define FLAG_FLIP(obj, type, flag) ((obj)->flags ^= FLAG(type, flag))
#define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag))) #define FLAG_TEST(obj, type, flag) (!!((obj)->flags & FLAG(type, flag)))
/* CCU field state tests */
#define ccu_policy_exists(ccu_policy) ((ccu_policy)->enable.offset != 0)
/* Clock field state tests */ /* Clock field state tests */
#define policy_exists(policy) ((policy)->offset != 0)
#define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS) #define gate_exists(gate) FLAG_TEST(gate, GATE, EXISTS)
#define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED) #define gate_is_enabled(gate) FLAG_TEST(gate, GATE, ENABLED)
#define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW) #define gate_is_hw_controllable(gate) FLAG_TEST(gate, GATE, HW)
...@@ -54,6 +60,8 @@ ...@@ -54,6 +60,8 @@
#define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED) #define gate_flip_enabled(gate) FLAG_FLIP(gate, GATE, ENABLED)
#define hyst_exists(hyst) ((hyst)->offset != 0)
#define divider_exists(div) FLAG_TEST(div, DIV, EXISTS) #define divider_exists(div) FLAG_TEST(div, DIV, EXISTS)
#define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED) #define divider_is_fixed(div) FLAG_TEST(div, DIV, FIXED)
#define divider_has_fraction(div) (!divider_is_fixed(div) && \ #define divider_has_fraction(div) (!divider_is_fixed(div) && \
...@@ -62,6 +70,9 @@ ...@@ -62,6 +70,9 @@
#define selector_exists(sel) ((sel)->width != 0) #define selector_exists(sel) ((sel)->width != 0)
#define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS) #define trigger_exists(trig) FLAG_TEST(trig, TRIG, EXISTS)
#define policy_lvm_en_exists(enable) ((enable)->offset != 0)
#define policy_ctl_exists(control) ((control)->offset != 0)
/* Clock type, used to tell common block what it's part of */ /* Clock type, used to tell common block what it's part of */
enum bcm_clk_type { enum bcm_clk_type {
bcm_clk_none, /* undefined clock type */ bcm_clk_none, /* undefined clock type */
...@@ -71,25 +82,26 @@ enum bcm_clk_type { ...@@ -71,25 +82,26 @@ enum bcm_clk_type {
}; };
/* /*
* Each CCU defines a mapped area of memory containing registers * CCU policy control for clocks. Clocks can be enabled or disabled
* used to manage clocks implemented by the CCU. Access to memory * based on the CCU policy in effect. One bit in each policy mask
* within the CCU's space is serialized by a spinlock. Before any * register (one per CCU policy) represents whether the clock is
* (other) address can be written, a special access "password" value * enabled when that policy is effect or not. The CCU policy engine
* must be written to its WR_ACCESS register (located at the base * must be stopped to update these bits, and must be restarted again
* address of the range). We keep track of the name of each CCU as * afterward.
* it is set up, and maintain them in a list.
*/ */
struct ccu_data { struct bcm_clk_policy {
void __iomem *base; /* base of mapped address space */ u32 offset; /* first policy mask register offset */
spinlock_t lock; /* serialization lock */ u32 bit; /* bit used in all mask registers */
bool write_enabled; /* write access is currently enabled */
struct list_head links; /* for ccu_list */
struct device_node *node;
struct clk_onecell_data data;
const char *name;
u32 range; /* byte range of address space */
}; };
/* Policy initialization macro */
#define POLICY(_offset, _bit) \
{ \
.offset = (_offset), \
.bit = (_bit), \
}
/* /*
* Gating control and status is managed by a 32-bit gate register. * Gating control and status is managed by a 32-bit gate register.
* *
...@@ -195,6 +207,22 @@ struct bcm_clk_gate { ...@@ -195,6 +207,22 @@ struct bcm_clk_gate {
.flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \ .flags = FLAG(GATE, HW)|FLAG(GATE, EXISTS), \
} }
/* Gate hysteresis for clocks */
struct bcm_clk_hyst {
u32 offset; /* hyst register offset (normally CLKGATE) */
u32 en_bit; /* bit used to enable hysteresis */
u32 val_bit; /* if enabled: 0 = low delay; 1 = high delay */
};
/* Hysteresis initialization macro */
#define HYST(_offset, _en_bit, _val_bit) \
{ \
.offset = (_offset), \
.en_bit = (_en_bit), \
.val_bit = (_val_bit), \
}
/* /*
* Each clock can have zero, one, or two dividers which change the * Each clock can have zero, one, or two dividers which change the
* output rate of the clock. Each divider can be either fixed or * output rate of the clock. Each divider can be either fixed or
...@@ -360,7 +388,9 @@ struct bcm_clk_trig { ...@@ -360,7 +388,9 @@ struct bcm_clk_trig {
} }
struct peri_clk_data { struct peri_clk_data {
struct bcm_clk_policy policy;
struct bcm_clk_gate gate; struct bcm_clk_gate gate;
struct bcm_clk_hyst hyst;
struct bcm_clk_trig pre_trig; struct bcm_clk_trig pre_trig;
struct bcm_clk_div pre_div; struct bcm_clk_div pre_div;
struct bcm_clk_trig trig; struct bcm_clk_trig trig;
...@@ -373,8 +403,7 @@ struct peri_clk_data { ...@@ -373,8 +403,7 @@ struct peri_clk_data {
struct kona_clk { struct kona_clk {
struct clk_hw hw; struct clk_hw hw;
struct clk_init_data init_data; struct clk_init_data init_data; /* includes name of this clock */
const char *name; /* name of this clock */
struct ccu_data *ccu; /* ccu this clock is associated with */ struct ccu_data *ccu; /* ccu this clock is associated with */
enum bcm_clk_type type; enum bcm_clk_type type;
union { union {
...@@ -385,14 +414,92 @@ struct kona_clk { ...@@ -385,14 +414,92 @@ struct kona_clk {
#define to_kona_clk(_hw) \ #define to_kona_clk(_hw) \
container_of(_hw, struct kona_clk, hw) container_of(_hw, struct kona_clk, hw)
/* Exported globals */ /* Initialization macro for an entry in a CCU's kona_clks[] array. */
#define KONA_CLK(_ccu_name, _clk_name, _type) \
{ \
.init_data = { \
.name = #_clk_name, \
.ops = &kona_ ## _type ## _clk_ops, \
}, \
.ccu = &_ccu_name ## _ccu_data, \
.type = bcm_clk_ ## _type, \
.u.data = &_clk_name ## _data, \
}
#define LAST_KONA_CLK { .type = bcm_clk_none }
extern struct clk_ops kona_peri_clk_ops; /*
* CCU policy control. To enable software update of the policy
* tables the CCU policy engine must be stopped by setting the
* software update enable bit (LVM_EN). After an update the engine
* is restarted using the GO bit and either the GO_ATL or GO_AC bit.
*/
struct bcm_lvm_en {
u32 offset; /* LVM_EN register offset */
u32 bit; /* POLICY_CONFIG_EN bit in register */
};
/* Policy enable initialization macro */
#define CCU_LVM_EN(_offset, _bit) \
{ \
.offset = (_offset), \
.bit = (_bit), \
}
struct bcm_policy_ctl {
u32 offset; /* POLICY_CTL register offset */
u32 go_bit;
u32 atl_bit; /* GO, GO_ATL, and GO_AC bits */
u32 ac_bit;
};
/* Policy control initialization macro */
#define CCU_POLICY_CTL(_offset, _go_bit, _ac_bit, _atl_bit) \
{ \
.offset = (_offset), \
.go_bit = (_go_bit), \
.ac_bit = (_ac_bit), \
.atl_bit = (_atl_bit), \
}
struct ccu_policy {
struct bcm_lvm_en enable;
struct bcm_policy_ctl control;
};
/*
* Each CCU defines a mapped area of memory containing registers
* used to manage clocks implemented by the CCU. Access to memory
* within the CCU's space is serialized by a spinlock. Before any
* (other) address can be written, a special access "password" value
* must be written to its WR_ACCESS register (located at the base
* address of the range). We keep track of the name of each CCU as
* it is set up, and maintain them in a list.
*/
struct ccu_data {
void __iomem *base; /* base of mapped address space */
spinlock_t lock; /* serialization lock */
bool write_enabled; /* write access is currently enabled */
struct ccu_policy policy;
struct list_head links; /* for ccu_list */
struct device_node *node;
struct clk_onecell_data clk_data;
const char *name;
u32 range; /* byte range of address space */
struct kona_clk kona_clks[]; /* must be last */
};
/* Help functions */ /* Initialization for common fields in a Kona ccu_data structure */
#define KONA_CCU_COMMON(_prefix, _name, _ccuname) \
.name = #_name "_ccu", \
.lock = __SPIN_LOCK_UNLOCKED(_name ## _ccu_data.lock), \
.links = LIST_HEAD_INIT(_name ## _ccu_data.links), \
.clk_data = { \
.clk_num = _prefix ## _ ## _ccuname ## _CCU_CLOCK_COUNT, \
}
/* Exported globals */
#define PERI_CLK_SETUP(clks, ccu, id, name) \ extern struct clk_ops kona_peri_clk_ops;
clks[id] = kona_clk_setup(ccu, #name, bcm_clk_peri, &name ## _data)
/* Externally visible functions */ /* Externally visible functions */
...@@ -401,10 +508,9 @@ extern u64 scaled_div_max(struct bcm_clk_div *div); ...@@ -401,10 +508,9 @@ extern u64 scaled_div_max(struct bcm_clk_div *div);
extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value, extern u64 scaled_div_build(struct bcm_clk_div *div, u32 div_value,
u32 billionths); u32 billionths);
extern struct clk *kona_clk_setup(struct ccu_data *ccu, const char *name, extern struct clk *kona_clk_setup(struct kona_clk *bcm_clk);
enum bcm_clk_type type, void *data); extern void __init kona_dt_ccu_setup(struct ccu_data *ccu,
extern void __init kona_dt_ccu_setup(struct device_node *node, struct device_node *node);
int (*ccu_clks_setup)(struct ccu_data *));
extern bool __init kona_ccu_init(struct ccu_data *ccu); extern bool __init kona_ccu_init(struct ccu_data *ccu);
#endif /* _CLK_KONA_H */ #endif /* _CLK_KONA_H */
obj-y += berlin2-avpll.o berlin2-pll.o berlin2-div.o
obj-$(CONFIG_MACH_BERLIN_BG2) += bg2.o
obj-$(CONFIG_MACH_BERLIN_BG2CD) += bg2.o
obj-$(CONFIG_MACH_BERLIN_BG2Q) += bg2q.o
This diff is collapsed.
/*
* Copyright (c) 2014 Marvell Technology Group Ltd.
*
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
* Alexandre Belloni <alexandre.belloni@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __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,
const char *parent_name, u8 vco_flags, unsigned long flags);
struct clk * __init
berlin2_avpll_channel_register(void __iomem *base, const char *name,
u8 index, const char *parent_name, u8 ch_flags,
unsigned long flags);
#endif /* __BERLIN2_AVPLL_H */
/*
* Copyright (c) 2014 Marvell Technology Group Ltd.
*
* Alexandre Belloni <alexandre.belloni@free-electrons.com>
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/bitops.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include "berlin2-div.h"
/*
* Clock dividers in Berlin2 SoCs comprise a complex cell to select
* input pll and divider. The virtual structure as it is used in Marvell
* BSP code can be seen as:
*
* +---+
* pll0 --------------->| 0 | +---+
* +---+ |(B)|--+--------------->| 0 | +---+
* pll1.0 -->| 0 | +-->| 1 | | +--------+ |(E)|----->| 0 | +---+
* pll1.1 -->| 1 | | +---+ +-->|(C) 1:M |-->| 1 | |(F)|-->|(G)|->
* ... -->|(A)|--+ | +--------+ +---+ +-->| 1 | +---+
* ... -->| | +-->|(D) 1:3 |----------+ +---+
* pll1.N -->| N | +---------
* +---+
*
* (A) input pll clock mux controlled by <PllSelect[1:n]>
* (B) input pll bypass mux controlled by <PllSwitch>
* (C) programmable clock divider controlled by <Select[1:n]>
* (D) constant div-by-3 clock divider
* (E) programmable clock divider bypass controlled by <Switch>
* (F) constant div-by-3 clock mux controlled by <D3Switch>
* (G) clock gate controlled by <Enable>
*
* For whatever reason, above control signals come in two flavors:
* - single register dividers with all bits in one register
* - shared register dividers with bits spread over multiple registers
* (including signals for the same cell spread over consecutive registers)
*
* Also, clock gate and pll mux is not available on every div cell, so
* we have to deal with those, too. We reuse common clock composite driver
* for it.
*/
#define PLL_SELECT_MASK 0x7
#define DIV_SELECT_MASK 0x7
struct berlin2_div {
struct clk_hw hw;
void __iomem *base;
struct berlin2_div_map map;
spinlock_t *lock;
};
#define to_berlin2_div(hw) container_of(hw, struct berlin2_div, hw)
static u8 clk_div[] = { 1, 2, 4, 6, 8, 12, 1, 1 };
static int berlin2_div_is_enabled(struct clk_hw *hw)
{
struct berlin2_div *div = to_berlin2_div(hw);
struct berlin2_div_map *map = &div->map;
u32 reg;
if (div->lock)
spin_lock(div->lock);
reg = readl_relaxed(div->base + map->gate_offs);
reg >>= map->gate_shift;
if (div->lock)
spin_unlock(div->lock);
return (reg & 0x1);
}
static int berlin2_div_enable(struct clk_hw *hw)
{
struct berlin2_div *div = to_berlin2_div(hw);
struct berlin2_div_map *map = &div->map;
u32 reg;
if (div->lock)
spin_lock(div->lock);
reg = readl_relaxed(div->base + map->gate_offs);
reg |= BIT(map->gate_shift);
writel_relaxed(reg, div->base + map->gate_offs);
if (div->lock)
spin_unlock(div->lock);
return 0;
}
static void berlin2_div_disable(struct clk_hw *hw)
{
struct berlin2_div *div = to_berlin2_div(hw);
struct berlin2_div_map *map = &div->map;
u32 reg;
if (div->lock)
spin_lock(div->lock);
reg = readl_relaxed(div->base + map->gate_offs);
reg &= ~BIT(map->gate_shift);
writel_relaxed(reg, div->base + map->gate_offs);
if (div->lock)
spin_unlock(div->lock);
}
static int berlin2_div_set_parent(struct clk_hw *hw, u8 index)
{
struct berlin2_div *div = to_berlin2_div(hw);
struct berlin2_div_map *map = &div->map;
u32 reg;
if (div->lock)
spin_lock(div->lock);
/* index == 0 is PLL_SWITCH */
reg = readl_relaxed(div->base + map->pll_switch_offs);
if (index == 0)
reg &= ~BIT(map->pll_switch_shift);
else
reg |= BIT(map->pll_switch_shift);
writel_relaxed(reg, div->base + map->pll_switch_offs);
/* index > 0 is PLL_SELECT */
if (index > 0) {
reg = readl_relaxed(div->base + map->pll_select_offs);
reg &= ~(PLL_SELECT_MASK << map->pll_select_shift);
reg |= (index - 1) << map->pll_select_shift;
writel_relaxed(reg, div->base + map->pll_select_offs);
}
if (div->lock)
spin_unlock(div->lock);
return 0;
}
static u8 berlin2_div_get_parent(struct clk_hw *hw)
{
struct berlin2_div *div = to_berlin2_div(hw);
struct berlin2_div_map *map = &div->map;
u32 reg;
u8 index = 0;
if (div->lock)
spin_lock(div->lock);
/* PLL_SWITCH == 0 is index 0 */
reg = readl_relaxed(div->base + map->pll_switch_offs);
reg &= BIT(map->pll_switch_shift);
if (reg) {
reg = readl_relaxed(div->base + map->pll_select_offs);
reg >>= map->pll_select_shift;
reg &= PLL_SELECT_MASK;
index = 1 + reg;
}
if (div->lock)
spin_unlock(div->lock);
return index;
}
static unsigned long berlin2_div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct berlin2_div *div = to_berlin2_div(hw);
struct berlin2_div_map *map = &div->map;
u32 divsw, div3sw, divider = 1;
if (div->lock)
spin_lock(div->lock);
divsw = readl_relaxed(div->base + map->div_switch_offs) &
(1 << map->div_switch_shift);
div3sw = readl_relaxed(div->base + map->div3_switch_offs) &
(1 << map->div3_switch_shift);
/* constant divide-by-3 (dominant) */
if (div3sw != 0) {
divider = 3;
/* divider can be bypassed with DIV_SWITCH == 0 */
} else if (divsw == 0) {
divider = 1;
/* clock divider determined by DIV_SELECT */
} else {
u32 reg;
reg = readl_relaxed(div->base + map->div_select_offs);
reg >>= map->div_select_shift;
reg &= DIV_SELECT_MASK;
divider = clk_div[reg];
}
if (div->lock)
spin_unlock(div->lock);
return parent_rate / divider;
}
static const struct clk_ops berlin2_div_rate_ops = {
.recalc_rate = berlin2_div_recalc_rate,
};
static const struct clk_ops berlin2_div_gate_ops = {
.is_enabled = berlin2_div_is_enabled,
.enable = berlin2_div_enable,
.disable = berlin2_div_disable,
};
static const struct clk_ops berlin2_div_mux_ops = {
.set_parent = berlin2_div_set_parent,
.get_parent = berlin2_div_get_parent,
};
struct clk * __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,
unsigned long flags, spinlock_t *lock)
{
const struct clk_ops *mux_ops = &berlin2_div_mux_ops;
const struct clk_ops *rate_ops = &berlin2_div_rate_ops;
const struct clk_ops *gate_ops = &berlin2_div_gate_ops;
struct berlin2_div *div;
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
return ERR_PTR(-ENOMEM);
/* copy div_map to allow __initconst */
memcpy(&div->map, map, sizeof(*map));
div->base = base;
div->lock = lock;
if ((div_flags & BERLIN2_DIV_HAS_GATE) == 0)
gate_ops = NULL;
if ((div_flags & BERLIN2_DIV_HAS_MUX) == 0)
mux_ops = NULL;
return clk_register_composite(NULL, name, parent_names, num_parents,
&div->hw, mux_ops, &div->hw, rate_ops,
&div->hw, gate_ops, flags);
}
/*
* Copyright (c) 2014 Marvell Technology Group Ltd.
*
* Alexandre Belloni <alexandre.belloni@free-electrons.com>
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BERLIN2_DIV_H
#define __BERLIN2_DIV_H
struct clk;
#define BERLIN2_DIV_HAS_GATE BIT(0)
#define BERLIN2_DIV_HAS_MUX BIT(1)
#define BERLIN2_PLL_SELECT(_off, _sh) \
.pll_select_offs = _off, \
.pll_select_shift = _sh
#define BERLIN2_PLL_SWITCH(_off, _sh) \
.pll_switch_offs = _off, \
.pll_switch_shift = _sh
#define BERLIN2_DIV_SELECT(_off, _sh) \
.div_select_offs = _off, \
.div_select_shift = _sh
#define BERLIN2_DIV_SWITCH(_off, _sh) \
.div_switch_offs = _off, \
.div_switch_shift = _sh
#define BERLIN2_DIV_D3SWITCH(_off, _sh) \
.div3_switch_offs = _off, \
.div3_switch_shift = _sh
#define BERLIN2_DIV_GATE(_off, _sh) \
.gate_offs = _off, \
.gate_shift = _sh
#define BERLIN2_SINGLE_DIV(_off) \
BERLIN2_DIV_GATE(_off, 0), \
BERLIN2_PLL_SELECT(_off, 1), \
BERLIN2_PLL_SWITCH(_off, 4), \
BERLIN2_DIV_SWITCH(_off, 5), \
BERLIN2_DIV_D3SWITCH(_off, 6), \
BERLIN2_DIV_SELECT(_off, 7)
struct berlin2_div_map {
u16 pll_select_offs;
u16 pll_switch_offs;
u16 div_select_offs;
u16 div_switch_offs;
u16 div3_switch_offs;
u16 gate_offs;
u8 pll_select_shift;
u8 pll_switch_shift;
u8 div_select_shift;
u8 div_switch_shift;
u8 div3_switch_shift;
u8 gate_shift;
};
struct berlin2_div_data {
const char *name;
const u8 *parent_ids;
int num_parents;
unsigned long flags;
struct berlin2_div_map map;
u8 div_flags;
};
struct clk * __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,
unsigned long flags, spinlock_t *lock);
#endif /* __BERLIN2_DIV_H */
/*
* Copyright (c) 2014 Marvell Technology Group Ltd.
*
* Alexandre Belloni <alexandre.belloni@free-electrons.com>
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <asm/div64.h>
#include "berlin2-div.h"
struct berlin2_pll_map {
const u8 vcodiv[16];
u8 mult;
u8 fbdiv_shift;
u8 rfdiv_shift;
u8 divsel_shift;
};
struct berlin2_pll {
struct clk_hw hw;
void __iomem *base;
struct berlin2_pll_map map;
};
#define to_berlin2_pll(hw) container_of(hw, struct berlin2_pll, hw)
#define SPLL_CTRL0 0x00
#define SPLL_CTRL1 0x04
#define SPLL_CTRL2 0x08
#define SPLL_CTRL3 0x0c
#define SPLL_CTRL4 0x10
#define FBDIV_MASK 0x1ff
#define RFDIV_MASK 0x1f
#define DIVSEL_MASK 0xf
/*
* The output frequency formula for the pll is:
* clkout = fbdiv / refdiv * parent / vcodiv
*/
static unsigned long
berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct berlin2_pll *pll = to_berlin2_pll(hw);
struct berlin2_pll_map *map = &pll->map;
u32 val, fbdiv, rfdiv, vcodivsel, vcodiv;
u64 rate = parent_rate;
val = readl_relaxed(pll->base + SPLL_CTRL0);
fbdiv = (val >> map->fbdiv_shift) & FBDIV_MASK;
rfdiv = (val >> map->rfdiv_shift) & RFDIV_MASK;
if (rfdiv == 0) {
pr_warn("%s has zero rfdiv\n", __clk_get_name(hw->clk));
rfdiv = 1;
}
val = readl_relaxed(pll->base + SPLL_CTRL1);
vcodivsel = (val >> map->divsel_shift) & DIVSEL_MASK;
vcodiv = map->vcodiv[vcodivsel];
if (vcodiv == 0) {
pr_warn("%s has zero vcodiv (index %d)\n",
__clk_get_name(hw->clk), vcodivsel);
vcodiv = 1;
}
rate *= fbdiv * map->mult;
do_div(rate, rfdiv * vcodiv);
return (unsigned long)rate;
}
static const struct clk_ops berlin2_pll_ops = {
.recalc_rate = berlin2_pll_recalc_rate,
};
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)
{
struct clk_init_data init;
struct berlin2_pll *pll;
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
if (!pll)
return ERR_PTR(-ENOMEM);
/* copy pll_map to allow __initconst */
memcpy(&pll->map, map, sizeof(*map));
pll->base = base;
pll->hw.init = &init;
init.name = name;
init.ops = &berlin2_pll_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = flags;
return clk_register(NULL, &pll->hw);
}
/*
* Copyright (c) 2014 Marvell Technology Group Ltd.
*
* Alexandre Belloni <alexandre.belloni@free-electrons.com>
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BERLIN2_PLL_H
#define __BERLIN2_PLL_H
struct clk;
struct berlin2_pll_map {
const u8 vcodiv[16];
u8 mult;
u8 fbdiv_shift;
u8 rfdiv_shift;
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);
#endif /* __BERLIN2_PLL_H */
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (c) 2014 Marvell Technology Group Ltd.
*
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
* Alexandre Belloni <alexandre.belloni@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BERLIN2_COMMON_H
#define __BERLIN2_COMMON_H
struct berlin2_gate_data {
const char *name;
const char *parent_name;
u8 bit_idx;
unsigned long flags;
};
#endif /* BERLIN2_COMMON_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -526,6 +526,6 @@ static struct i2c_driver si570_driver = { ...@@ -526,6 +526,6 @@ static struct i2c_driver si570_driver = {
module_i2c_driver(si570_driver); module_i2c_driver(si570_driver);
MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com"); MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com>");
MODULE_DESCRIPTION("Si570 driver"); MODULE_DESCRIPTION("Si570 driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -1168,6 +1168,7 @@ static const struct of_device_id u300_clk_match[] __initconst = { ...@@ -1168,6 +1168,7 @@ static const struct of_device_id u300_clk_match[] __initconst = {
.compatible = "stericsson,u300-syscon-mclk", .compatible = "stericsson,u300-syscon-mclk",
.data = of_u300_syscon_mclk_init, .data = of_u300_syscon_mclk_init,
}, },
{}
}; };
......
This diff is collapsed.
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec);
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec); struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec);
void of_clk_lock(void); void of_clk_lock(void);
void of_clk_unlock(void); void of_clk_unlock(void);
......
This diff is collapsed.
...@@ -6,3 +6,4 @@ obj-y += clk.o clkgate-separated.o ...@@ -6,3 +6,4 @@ obj-y += clk.o clkgate-separated.o
obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o
obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o
obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o
This diff is collapsed.
This diff is collapsed.
...@@ -62,6 +62,7 @@ struct hisi_mux_clock { ...@@ -62,6 +62,7 @@ struct hisi_mux_clock {
u8 shift; u8 shift;
u8 width; u8 width;
u8 mux_flags; u8 mux_flags;
u32 *table;
const char *alias; const char *alias;
}; };
...@@ -103,6 +104,8 @@ void __init hisi_clk_register_mux(struct hisi_mux_clock *, int, ...@@ -103,6 +104,8 @@ void __init hisi_clk_register_mux(struct hisi_mux_clock *, int,
struct hisi_clock_data *); struct hisi_clock_data *);
void __init hisi_clk_register_divider(struct hisi_divider_clock *, void __init hisi_clk_register_divider(struct hisi_divider_clock *,
int, struct hisi_clock_data *); int, struct hisi_clock_data *);
void __init hisi_clk_register_gate(struct hisi_gate_clock *,
int, struct hisi_clock_data *);
void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *, void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *,
int, struct hisi_clock_data *); int, struct hisi_clock_data *);
#endif /* __HISI_CLK_H */ #endif /* __HISI_CLK_H */
...@@ -34,3 +34,7 @@ config DOVE_CLK ...@@ -34,3 +34,7 @@ config DOVE_CLK
config KIRKWOOD_CLK config KIRKWOOD_CLK
bool bool
select MVEBU_CLK_COMMON select MVEBU_CLK_COMMON
config ORION_CLK
bool
select MVEBU_CLK_COMMON
...@@ -8,3 +8,4 @@ obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o ...@@ -8,3 +8,4 @@ obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o
obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o
obj-$(CONFIG_DOVE_CLK) += dove.o obj-$(CONFIG_DOVE_CLK) += dove.o
obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o
obj-$(CONFIG_ORION_CLK) += orion.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment