Commit 18a8d499 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull clock framework updates from Mike Turquette:
 "The clock framework changes contain the usual driver additions,
  enhancements and fixes mostly for ARM32, ARM64, MIPS and Power-based
  devices.

  Additionally the framework core underwent a bit of surgery with two
  major changes:

   - The boundary between the clock core and clock providers (e.g clock
     drivers) is now more well defined with dedicated provider helper
     functions.  struct clk no longer maps 1:1 with the hardware clock
     but is a true per-user cookie which helps us tracker users of
     hardware clocks and debug bad behavior.

   - The addition of rate constraints for clocks.  Rate ranges are now
     supported which are analogous to the voltage ranges in the
     regulator framework.

  Unfortunately these changes to the core created some breakeage.  We
  think we fixed it all up but for this reason there are lots of last
  minute commits trying to undo the damage"

* tag 'clk-for-linus-3.20' of git://git.linaro.org/people/mike.turquette/linux: (113 commits)
  clk: Only recalculate the rate if needed
  Revert "clk: mxs: Fix invalid 32-bit access to frac registers"
  clk: qoriq: Add support for the platform PLL
  powerpc/corenet: Enable CLK_QORIQ
  clk: Replace explicit clk assignment with __clk_hw_set_clk
  clk: Add __clk_hw_set_clk helper function
  clk: Don't dereference parent clock if is NULL
  MIPS: Alchemy: Remove bogus args from alchemy_clk_fgcs_detr
  clkdev: Always allocate a struct clk and call __clk_get() w/ CCF
  clk: shmobile: div6: Avoid division by zero in .round_rate()
  clk: mxs: Fix invalid 32-bit access to frac registers
  clk: omap: compile legacy omap3 clocks conditionally
  clkdev: Export clk_register_clkdev
  clk: Add rate constraints to clocks
  clk: remove clk-private.h
  pci: xgene: do not use clk-private.h
  arm: omap2+ remove dead clock code
  clk: Make clk API return per-user struct clk instances
  clk: tegra: Define PLLD_DSI and remove dsia(b)_mux
  clk: tegra: Add support for the Tegra132 CAR IP block
  ...
parents c189cb8e ec02ace8
......@@ -73,6 +73,8 @@ the operations defined in clk.h:
unsigned long *parent_rate);
long (*determine_rate)(struct clk_hw *hw,
unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk);
int (*set_parent)(struct clk_hw *hw, u8 index);
......
......@@ -34,6 +34,8 @@ Required Properties for Clock Controller:
- "samsung,exynos7-clock-peris"
- "samsung,exynos7-clock-fsys0"
- "samsung,exynos7-clock-fsys1"
- "samsung,exynos7-clock-mscl"
- "samsung,exynos7-clock-aud"
- reg: physical base address of the controller and the length of
memory mapped region.
......@@ -53,6 +55,7 @@ Input clocks for top0 clock controller:
- dout_sclk_bus1_pll
- dout_sclk_cc_pll
- dout_sclk_mfc_pll
- dout_sclk_aud_pll
Input clocks for top1 clock controller:
- fin_pll
......@@ -76,6 +79,14 @@ Input clocks for peric1 clock controller:
- sclk_uart1
- sclk_uart2
- sclk_uart3
- sclk_spi0
- sclk_spi1
- sclk_spi2
- sclk_spi3
- sclk_spi4
- sclk_i2s1
- sclk_pcm1
- sclk_spdif
Input clocks for peris clock controller:
- fin_pll
......@@ -91,3 +102,7 @@ Input clocks for fsys1 clock controller:
- dout_aclk_fsys1_200
- dout_sclk_mmc0
- dout_sclk_mmc1
Input clocks for aud clock controller:
- fin_pll
- fout_aud_pll
NVIDIA Tegra124 Clock And Reset Controller
NVIDIA Tegra124 and Tegra132 Clock And Reset Controller
This binding uses the common clock binding:
Documentation/devicetree/bindings/clock/clock-bindings.txt
......@@ -7,14 +7,16 @@ The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
for muxing and gating Tegra's clocks, and setting their rates.
Required properties :
- compatible : Should be "nvidia,tegra124-car"
- compatible : Should be "nvidia,tegra124-car" or "nvidia,tegra132-car"
- reg : Should contain CAR registers location and length
- clocks : Should contain phandle and clock specifiers for two clocks:
the 32 KHz "32k_in", and the board-specific oscillator "osc".
- #clock-cells : Should be 1.
In clock consumers, this cell represents the clock ID exposed by the
CAR. The assignments may be found in header file
<dt-bindings/clock/tegra124-car.h>.
CAR. The assignments may be found in the header files
<dt-bindings/clock/tegra124-car-common.h> (which covers IDs common
to Tegra124 and Tegra132) and <dt-bindings/clock/tegra124-car.h>
(for Tegra124-specific clocks).
- #reset-cells : Should be 1.
In clock consumers, this cell represents the bit number in the CAR's
array of CLK_RST_CONTROLLER_RST_DEVICES_* registers.
......
Qualcomm LPASS Clock & Reset Controller Binding
------------------------------------------------
Required properties :
- compatible : shall contain only one of the following:
"qcom,lcc-msm8960"
"qcom,lcc-apq8064"
"qcom,lcc-ipq8064"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
- #reset-cells : shall contain 1
Example:
clock-controller@28000000 {
compatible = "qcom,lcc-ipq8064";
reg = <0x28000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
* Clock Block on Freescale CoreNet Platforms
* Clock Block on Freescale QorIQ Platforms
Freescale CoreNet chips take primary clocking input from the external
Freescale qoriq chips take primary clocking input from the external
SYSCLK signal. The SYSCLK input (frequency) is multiplied using
multiple phase locked loops (PLL) to create a variety of frequencies
which can then be passed to a variety of internal logic, including
......@@ -29,6 +29,7 @@ Required properties:
* "fsl,t4240-clockgen"
* "fsl,b4420-clockgen"
* "fsl,b4860-clockgen"
* "fsl,ls1021a-clockgen"
Chassis clock strings include:
* "fsl,qoriq-clockgen-1.0": for chassis 1.0 clocks
* "fsl,qoriq-clockgen-2.0": for chassis 2.0 clocks
......
......@@ -11,6 +11,7 @@ Required Properties:
- compatible: Must be one of the following
- "renesas,r7s72100-mstp-clocks" for R7S72100 (RZ) MSTP gate clocks
- "renesas,r8a73a4-mstp-clocks" for R8A73A4 (R-Mobile APE6) MSTP gate clocks
- "renesas,r8a7740-mstp-clocks" for R8A7740 (R-Mobile A1) 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 R8A73A4 Clock Pulse Generator (CPG)
The CPG generates core clocks for the R8A73A4 SoC. It includes five PLLs
and several fixed ratio dividers.
Required Properties:
- compatible: Must be "renesas,r8a73a4-cpg-clocks"
- reg: Base address and length of the memory resource used by the CPG
- clocks: Reference to the parent clocks ("extal1" and "extal2")
- #clock-cells: Must be 1
- clock-output-names: The names of the clocks. Supported clocks are "main",
"pll0", "pll1", "pll2", "pll2s", "pll2h", "z", "z2", "i", "m3", "b",
"m1", "m2", "zx", "zs", and "hp".
Example
-------
cpg_clocks: cpg_clocks@e6150000 {
compatible = "renesas,r8a73a4-cpg-clocks";
reg = <0 0xe6150000 0 0x10000>;
clocks = <&extal1_clk>, <&extal2_clk>;
#clock-cells = <1>;
clock-output-names = "main", "pll0", "pll1", "pll2",
"pll2s", "pll2h", "z", "z2",
"i", "m3", "b", "m1", "m2",
"zx", "zs", "hp";
};
......@@ -8,15 +8,18 @@ Required Properties:
- compatible: Must be one of
- "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
- "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
- "renesas,r8a7793-cpg-clocks" for the r8a7793 CPG
- "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG
- "renesas,rcar-gen2-cpg-clocks" for the generic R-Car Gen2 CPG
- reg: Base address and length of the memory resource used by the CPG
- clocks: Reference to the parent clock
- clocks: References to the parent clocks: first to the EXTAL clock, second
to the USB_EXTAL clock
- #clock-cells: Must be 1
- clock-output-names: The names of the clocks. Supported clocks are "main",
"pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1" and "z"
"pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and
"adsp"
Example
......@@ -26,8 +29,9 @@ Example
compatible = "renesas,r8a7790-cpg-clocks",
"renesas,rcar-gen2-cpg-clocks";
reg = <0 0xe6150000 0 0x1000>;
clocks = <&extal_clk>;
clocks = <&extal_clk &usb_extal_clk>;
#clock-cells = <1>;
clock-output-names = "main", "pll0, "pll1", "pll3",
"lb", "qspi", "sdh", "sd0", "sd1", "z";
"lb", "qspi", "sdh", "sd0", "sd1", "z",
"rcan", "adsp";
};
......@@ -26,7 +26,7 @@ Required properties:
"allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
"allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
"allwinner,sun6i-a31-ar100-clk" - for the AR100 on A31
"allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
"allwinner,sun6i-a31-ahb1-clk" - for the AHB1 clock on A31
"allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
"allwinner,sun8i-a23-ahb1-gates-clk" - for the AHB1 gates on A23
"allwinner,sun9i-a80-ahb0-gates-clk" - for the AHB0 gates on A80
......@@ -55,9 +55,11 @@ Required properties:
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
"allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23
"allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13
"allwinner,sun4i-a10-mmc-output-clk" - for the MMC output clock on A10
"allwinner,sun4i-a10-mmc-sample-clk" - for the MMC sample clock on A10
"allwinner,sun4i-a10-mmc-clk" - for the MMC clock
"allwinner,sun9i-a80-mmc-clk" - for mmc module clocks on A80
"allwinner,sun9i-a80-mmc-config-clk" - for mmc gates + resets on A80
"allwinner,sun4i-a10-mod0-clk" - for the module 0 family of clocks
"allwinner,sun9i-a80-mod0-clk" - for module 0 (storage) clocks on A80
"allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23
"allwinner,sun7i-a20-out-clk" - for the external output clocks
"allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31
......@@ -73,7 +75,9 @@ Required properties for all clocks:
- #clock-cells : from common clock binding; shall be set to 0 except for
the following compatibles where it shall be set to 1:
"allwinner,*-gates-clk", "allwinner,sun4i-pll5-clk",
"allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk"
"allwinner,sun4i-pll6-clk", "allwinner,sun6i-a31-pll6-clk",
"allwinner,*-usb-clk", "allwinner,*-mmc-clk",
"allwinner,*-mmc-config-clk"
- clock-output-names : shall be the corresponding names of the outputs.
If the clock module only has one output, the name shall be the
module name.
......@@ -81,6 +85,10 @@ Required properties for all clocks:
And "allwinner,*-usb-clk" clocks also require:
- reset-cells : shall be set to 1
The "allwinner,sun9i-a80-mmc-config-clk" clock also requires:
- #reset-cells : shall be set to 1
- resets : shall be the reset control phandle for the mmc block.
For "allwinner,sun7i-a20-gmac-clk", the parent clocks shall be fixed rate
dummy clocks at 25 MHz and 125 MHz, respectively. See example.
......@@ -95,6 +103,14 @@ For "allwinner,sun6i-a31-pll6-clk", there are 2 outputs. The first output
is the normal PLL6 output, or "pll6". The second output is rate doubled
PLL6, or "pll6x2".
The "allwinner,*-mmc-clk" clocks have three different outputs: the
main clock, with the ID 0, and the output and sample clocks, with the
IDs 1 and 2, respectively.
The "allwinner,sun9i-a80-mmc-config-clk" clock has one clock/reset output
per mmc controller. The number of outputs is determined by the size of
the address block, which is related to the overall mmc block.
For example:
osc24M: clk@01c20050 {
......@@ -138,11 +154,11 @@ cpu: cpu@01c20054 {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0";
clock-output-names = "mmc0", "mmc0_output", "mmc0_sample";
};
mii_phy_tx_clk: clk@2 {
......@@ -170,3 +186,16 @@ gmac_clk: clk@01c20164 {
clocks = <&mii_phy_tx_clk>, <&gmac_int_tx_clk>;
clock-output-names = "gmac";
};
mmc_config_clk: clk@01c13000 {
compatible = "allwinner,sun9i-a80-mmc-config-clk";
reg = <0x01c13000 0x10>;
clocks = <&ahb0_gates 8>;
clock-names = "ahb";
resets = <&ahb0_resets 8>;
reset-names = "ahb";
#clock-cells = <1>;
#reset-cells = <1>;
clock-output-names = "mmc0_config", "mmc1_config",
"mmc2_config", "mmc3_config";
};
Bindings for Texas Instruments CDCE706 programmable 3-PLL clock
synthesizer/multiplier/divider.
Reference: http://www.ti.com/lit/ds/symlink/cdce706.pdf
I2C device node required properties:
- compatible: shall be "ti,cdce706".
- reg: i2c device address, shall be in range [0x68...0x6b].
- #clock-cells: from common clock binding; shall be set to 1.
- clocks: from common clock binding; list of parent clock
handles, shall be reference clock(s) connected to CLK_IN0
and CLK_IN1 pins.
- clock-names: shall be clk_in0 and/or clk_in1. Use clk_in0
in case of crystal oscillator or differential signal input
configuration. Use clk_in0 and clk_in1 in case of independent
single-ended LVCMOS inputs configuration.
Example:
clocks {
clk54: clk54 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <54000000>;
};
};
...
i2c0: i2c-master@0d090000 {
...
cdce706: clock-synth@69 {
compatible = "ti,cdce706";
#clock-cells = <1>;
reg = <0x69>;
clocks = <&clk54>;
clock-names = "clk_in0";
};
};
...
simple-audio-card,codec {
...
clocks = <&cdce706 4>;
};
Binding for Texas Instruments FAPLL clock.
Binding status: Unstable - ABI compatibility may be broken in the future
This binding uses the common clock binding[1]. It assumes a
register-mapped FAPLL with usually two selectable input clocks
(reference clock and bypass clock), and one or more child
syntesizers.
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible : shall be "ti,dm816-fapll-clock"
- #clock-cells : from common clock binding; shall be set to 0.
- clocks : link phandles of parent clocks (clk-ref and clk-bypass)
- reg : address and length of the register set for controlling the FAPLL.
Examples:
main_fapll: main_fapll {
#clock-cells = <1>;
compatible = "ti,dm816-fapll-clock";
reg = <0x400 0x40>;
clocks = <&sys_clkin_ck &sys_clkin_ck>;
clock-indices = <1>, <2>, <3>, <4>, <5>,
<6>, <7>;
clock-output-names = "main_pll_clk1",
"main_pll_clk2",
"main_pll_clk3",
"main_pll_clk4",
"main_pll_clk5",
"main_pll_clk6",
"main_pll_clk7";
};
......@@ -10,8 +10,8 @@ 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"
- clocks : a list with 4 phandle + clock specifier pairs
- clock-names : must contain "ahb", "mmc", "output" and "sample"
- interrupts : mmc controller interrupt
Optional properties:
......@@ -25,8 +25,8 @@ Examples:
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mod";
clocks = <&ahb_gates 8>, <&mmc0_clk>, <&mmc0_output_clk>, <&mmc0_sample_clk>;
clock-names = "ahb", "mod", "output", "sample";
interrupts = <0 32 4>;
status = "disabled";
};
......
......@@ -9719,6 +9719,11 @@ L: linux-omap@vger.kernel.org
S: Maintained
F: drivers/thermal/ti-soc-thermal/
TI CDCE706 CLOCK DRIVER
M: Max Filippov <jcmvbkbc@gmail.com>
S: Maintained
F: drivers/clk/clk-cdce706.c
TI CLOCK DRIVER
M: Tero Kristo <t-kristo@ti.com>
L: linux-omap@vger.kernel.org
......
......@@ -294,35 +294,43 @@ ms_clk: clk@01c20084 {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0";
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc1";
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc2";
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
mmc3_clk: clk@01c20094 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20094 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc3";
clock-output-names = "mmc3",
"mmc3_output",
"mmc3_sample";
};
ts_clk: clk@01c20098 {
......@@ -468,8 +476,14 @@ mdio: mdio@01c0b080 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun4i-a10-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <32>;
status = "disabled";
};
......@@ -477,8 +491,14 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun4i-a10-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>, <&mmc1_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <33>;
status = "disabled";
};
......@@ -486,8 +506,14 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun4i-a10-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <34>;
status = "disabled";
};
......@@ -495,8 +521,14 @@ mmc2: mmc@01c11000 {
mmc3: mmc@01c12000 {
compatible = "allwinner,sun4i-a10-mmc";
reg = <0x01c12000 0x1000>;
clocks = <&ahb_gates 11>, <&mmc3_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 11>,
<&mmc3_clk 0>,
<&mmc3_clk 1>,
<&mmc3_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <35>;
status = "disabled";
};
......
......@@ -218,27 +218,33 @@ ms_clk: clk@01c20084 {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0";
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc1";
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc2";
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
ts_clk: clk@01c20098 {
......@@ -368,8 +374,14 @@ mdio: mdio@01c0b080 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <32>;
status = "disabled";
};
......@@ -377,8 +389,14 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>, <&mmc1_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <33>;
status = "disabled";
};
......@@ -386,8 +404,14 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <34>;
status = "disabled";
};
......
......@@ -257,27 +257,33 @@ ms_clk: clk@01c20084 {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0";
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc1";
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc2";
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
ts_clk: clk@01c20098 {
......@@ -391,8 +397,14 @@ spi1: spi@01c06000 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <32>;
status = "disabled";
};
......@@ -400,8 +412,14 @@ mmc0: mmc@01c0f000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <34>;
status = "disabled";
};
......
......@@ -190,19 +190,11 @@ axi: axi@01c20050 {
clock-output-names = "axi";
};
ahb1_mux: ahb1_mux@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
reg = <0x01c20054 0x4>;
clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
clock-output-names = "ahb1_mux";
};
ahb1: ahb1@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-ahb-clk";
compatible = "allwinner,sun6i-a31-ahb1-clk";
reg = <0x01c20054 0x4>;
clocks = <&ahb1_mux>;
clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
clock-output-names = "ahb1";
};
......@@ -265,35 +257,43 @@ apb2_gates: clk@01c2006c {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc0";
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc1";
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc2";
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
mmc3_clk: clk@01c20094 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20094 0x4>;
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc3";
clock-output-names = "mmc3",
"mmc3_output",
"mmc3_sample";
};
spi0_clk: clk@01c200a0 {
......@@ -383,15 +383,21 @@ dma: dma-controller@01c02000 {
#dma-cells = <1>;
/* DMA controller requires AHB1 clocked from PLL6 */
assigned-clocks = <&ahb1_mux>;
assigned-clocks = <&ahb1>;
assigned-clock-parents = <&pll6 0>;
};
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb1_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 8>;
reset-names = "ahb";
interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
......@@ -401,8 +407,14 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb1_gates 9>, <&mmc1_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 9>;
reset-names = "ahb";
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
......@@ -412,8 +424,14 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb1_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 10>;
reset-names = "ahb";
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
......@@ -423,8 +441,14 @@ mmc2: mmc@01c11000 {
mmc3: mmc@01c12000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c12000 0x1000>;
clocks = <&ahb1_gates 11>, <&mmc3_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 11>,
<&mmc3_clk 0>,
<&mmc3_clk 1>,
<&mmc3_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 11>;
reset-names = "ahb";
interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
......
......@@ -337,35 +337,43 @@ ms_clk: clk@01c20084 {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0";
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc1";
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc2";
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
mmc3_clk: clk@01c20094 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20094 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc3";
clock-output-names = "mmc3",
"mmc3_output",
"mmc3_sample";
};
ts_clk: clk@01c20098 {
......@@ -583,8 +591,14 @@ mdio: mdio@01c0b080 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
......@@ -592,8 +606,14 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>, <&mmc1_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
......@@ -601,8 +621,14 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
......@@ -610,8 +636,14 @@ mmc2: mmc@01c11000 {
mmc3: mmc@01c12000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c12000 0x1000>;
clocks = <&ahb_gates 11>, <&mmc3_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb_gates 11>,
<&mmc3_clk 0>,
<&mmc3_clk 1>,
<&mmc3_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
......
......@@ -119,11 +119,19 @@ pll1: clk@01c20000 {
};
/* dummy clock until actually implemented */
pll6: pll6_clk {
pll5: pll5_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <600000000>;
clock-output-names = "pll6";
clock-frequency = <0>;
clock-output-names = "pll5";
};
pll6: clk@01c20028 {
#clock-cells = <1>;
compatible = "allwinner,sun6i-a31-pll6-clk";
reg = <0x01c20028 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll6", "pll6x2";
};
cpu: cpu_clk@01c20050 {
......@@ -149,19 +157,11 @@ axi: axi_clk@01c20050 {
clock-output-names = "axi";
};
ahb1_mux: ahb1_mux_clk@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun6i-a31-ahb1-mux-clk";
reg = <0x01c20054 0x4>;
clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6>;
clock-output-names = "ahb1_mux";
};
ahb1: ahb1_clk@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-ahb-clk";
compatible = "allwinner,sun6i-a31-ahb1-clk";
reg = <0x01c20054 0x4>;
clocks = <&ahb1_mux>;
clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
clock-output-names = "ahb1";
};
......@@ -202,7 +202,7 @@ apb2: clk@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb1-clk";
reg = <0x01c20058 0x4>;
clocks = <&osc32k>, <&osc24M>, <&pll6>, <&pll6>;
clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
clock-output-names = "apb2";
};
......@@ -218,27 +218,41 @@ apb2_gates: clk@01c2006c {
};
mmc0_clk: clk@01c20088 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6>;
clock-output-names = "mmc0";
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6>;
clock-output-names = "mmc1";
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6>;
clock-output-names = "mmc2";
clocks = <&osc24M>, <&pll6 0>;
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun8i-a23-mbus-clk";
reg = <0x01c2015c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5>;
clock-output-names = "mbus";
};
};
......@@ -260,8 +274,14 @@ dma: dma-controller@01c02000 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb1_gates 8>, <&mmc0_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 8>;
reset-names = "ahb";
interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
......@@ -271,8 +291,14 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb1_gates 9>, <&mmc1_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 9>;
reset-names = "ahb";
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
......@@ -282,8 +308,14 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb1_gates 10>, <&mmc2_clk>;
clock-names = "ahb", "mmc";
clocks = <&ahb1_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
resets = <&ahb1_rst 10>;
reset-names = "ahb";
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
......
......@@ -190,7 +190,7 @@ obj-$(CONFIG_SOC_OMAP2430) += clock2430.o
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o
obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common)
obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,7 +23,6 @@
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/clk-private.h>
#include <asm/cpu.h>
#include <trace/events/power.h>
......@@ -632,21 +631,6 @@ const struct clk_hw_omap_ops clkhwops_wait = {
.find_companion = omap2_clk_dflt_find_companion,
};
/**
* omap_clocks_register - register an array of omap_clk
* @ocs: pointer to an array of omap_clk to register
*/
void __init omap_clocks_register(struct omap_clk oclks[], int cnt)
{
struct omap_clk *c;
for (c = oclks; c < oclks + cnt; c++) {
clkdev_add(&c->lk);
if (!__clk_init(NULL, c->lk.clk))
omap2_init_clk_hw_omap_clocks(c->lk.clk);
}
}
/**
* omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
* @mpurate_ck_name: clk name of the clock to change rate
......
......@@ -40,23 +40,29 @@ struct omap_clk {
struct clockdomain;
#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \
static struct clk _name = { \
static struct clk_core _name##_core = { \
.name = #_name, \
.hw = &_name##_hw.hw, \
.parent_names = _parent_array_name, \
.num_parents = ARRAY_SIZE(_parent_array_name), \
.ops = &_clkops_name, \
}; \
static struct clk _name = { \
.core = &_name##_core, \
};
#define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name, \
_clkops_name, _flags) \
static struct clk _name = { \
static struct clk_core _name##_core = { \
.name = #_name, \
.hw = &_name##_hw.hw, \
.parent_names = _parent_array_name, \
.num_parents = ARRAY_SIZE(_parent_array_name), \
.ops = &_clkops_name, \
.flags = _flags, \
}; \
static struct clk _name = { \
.core = &_name##_core, \
};
#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \
......@@ -238,7 +244,6 @@ struct ti_clk_features {
extern struct ti_clk_features ti_clk_features;
extern const struct clkops clkops_omap2_dflt_wait;
extern const struct clkops clkops_dummy;
extern const struct clkops clkops_omap2_dflt;
extern struct clk_functions omap2_clk_functions;
......@@ -247,7 +252,6 @@ extern const struct clksel_rate gpt_32k_rates[];
extern const struct clksel_rate gpt_sys_rates[];
extern const struct clksel_rate gfx_l3_rates[];
extern const struct clksel_rate dsp_ick_rates[];
extern struct clk dummy_ck;
extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
extern const struct clk_hw_omap_ops clkhwops_wait;
......@@ -272,7 +276,5 @@ extern void __iomem *clk_memmaps[];
extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
extern void omap_clocks_register(struct omap_clk *oclks, int cnt);
void __init ti_clk_init_features(void);
#endif
......@@ -16,7 +16,6 @@
* OMAP3xxx clock definition files.
*/
#include <linux/clk-private.h>
#include "clock.h"
/* clksel_rate data common to 24xx/343x */
......@@ -114,13 +113,3 @@ const struct clksel_rate div31_1to31_rates[] = {
{ .div = 31, .val = 31, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
{ .div = 0 },
};
/* Clocks shared between various OMAP SoCs */
static struct clk_ops dummy_ck_ops = {};
struct clk dummy_ck = {
.name = "dummy_clk",
.ops = &dummy_ck_ops,
.flags = CLK_IS_BASIC,
};
......@@ -410,7 +410,7 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw)
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
int r;
struct dpll_data *dd;
struct clk *parent;
struct clk_hw *parent;
dd = clk->dpll_data;
if (!dd)
......@@ -427,13 +427,13 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw)
}
}
parent = __clk_get_parent(hw->clk);
parent = __clk_get_hw(__clk_get_parent(hw->clk));
if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) {
WARN_ON(parent != dd->clk_bypass);
WARN_ON(parent != __clk_get_hw(dd->clk_bypass));
r = _omap3_noncore_dpll_bypass(clk);
} else {
WARN_ON(parent != dd->clk_ref);
WARN_ON(parent != __clk_get_hw(dd->clk_ref));
r = _omap3_noncore_dpll_lock(clk);
}
......@@ -473,6 +473,8 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw)
* in failure.
*/
long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......@@ -549,7 +551,8 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
if (!dd)
return -EINVAL;
if (__clk_get_parent(hw->clk) != dd->clk_ref)
if (__clk_get_hw(__clk_get_parent(hw->clk)) !=
__clk_get_hw(dd->clk_ref))
return -EINVAL;
if (dd->last_rounded_rate == 0)
......
......@@ -202,6 +202,8 @@ long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
* in failure.
*/
long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......
......@@ -461,7 +461,17 @@ void __init omap3_init_early(void)
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap3xxx_clk_init;
if (!of_have_populated_dt()) {
omap3_prcm_legacy_iomaps_init();
if (soc_is_am35xx())
omap_clk_soc_init = am35xx_clk_legacy_init;
else if (cpu_is_omap3630())
omap_clk_soc_init = omap36xx_clk_legacy_init;
else if (omap_rev() == OMAP3430_REV_ES1_0)
omap_clk_soc_init = omap3430es1_clk_legacy_init;
else
omap_clk_soc_init = omap3430_clk_legacy_init;
}
}
void __init omap3430_init_early(void)
......@@ -753,6 +763,7 @@ int __init omap_clk_init(void)
ti_clk_init_features();
if (of_have_populated_dt()) {
ret = of_prcm_init();
if (ret)
return ret;
......@@ -762,6 +773,7 @@ int __init omap_clk_init(void)
ti_dt_clk_init_retry_clks();
ti_dt_clockdomains_setup();
}
ret = omap_clk_soc_init();
......
......@@ -20,6 +20,7 @@ extern void __iomem *prm_base;
extern u16 prm_features;
extern void omap2_set_globals_prm(void __iomem *prm);
int of_prcm_init(void);
void omap3_prcm_legacy_iomaps_init(void);
# endif
/*
......
......@@ -35,6 +35,8 @@
#include "prm44xx.h"
#include "common.h"
#include "clock.h"
#include "cm.h"
#include "control.h"
/*
* OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
......@@ -641,6 +643,15 @@ int __init of_prcm_init(void)
return 0;
}
void __init omap3_prcm_legacy_iomaps_init(void)
{
ti_clk_ll_ops = &omap_clk_ll_ops;
clk_memmaps[TI_CLKM_CM] = cm_base + OMAP3430_IVA2_MOD;
clk_memmaps[TI_CLKM_PRM] = prm_base + OMAP3430_IVA2_MOD;
clk_memmaps[TI_CLKM_SCRM] = omap_ctrl_base_get();
}
static int __init prm_late_init(void)
{
if (prm_ll_data->late_init)
......
......@@ -91,8 +91,6 @@ static void __init tegra_dt_init(void)
struct soc_device *soc_dev;
struct device *parent = NULL;
tegra_clocks_apply_init_table();
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr)
goto out;
......
......@@ -546,6 +546,8 @@ static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw,
}
static long alchemy_clk_fgv1_detr(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......@@ -678,6 +680,8 @@ static unsigned long alchemy_clk_fgv2_recalc(struct clk_hw *hw,
}
static long alchemy_clk_fgv2_detr(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......@@ -897,6 +901,8 @@ static int alchemy_clk_csrc_setr(struct clk_hw *hw, unsigned long rate,
}
static long alchemy_clk_csrc_detr(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......
......@@ -142,6 +142,7 @@ CONFIG_VIRT_DRIVERS=y
CONFIG_FSL_HV_MANAGER=y
CONFIG_STAGING=y
CONFIG_FSL_CORENET_CF=y
CONFIG_CLK_QORIQ=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
......
......@@ -122,6 +122,7 @@ CONFIG_DMADEVICES=y
CONFIG_FSL_DMA=y
CONFIG_VIRT_DRIVERS=y
CONFIG_FSL_HV_MANAGER=y
CONFIG_CLK_QORIQ=y
CONFIG_FSL_CORENET_CF=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
......
......@@ -54,6 +54,7 @@
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/irq_work.h>
#include <linux/clk-provider.h>
#include <asm/trace.h>
#include <asm/io.h>
......@@ -975,6 +976,10 @@ void __init time_init(void)
init_decrementer_clockevent();
tick_setup_hrtimer_broadcast();
#ifdef CONFIG_COMMON_CLK
of_clk_init(NULL);
#endif
}
......
......@@ -1168,6 +1168,11 @@ static void mpc5121_clk_provide_backwards_compat(void)
}
}
/*
* The "fixed-clock" nodes (which includes the oscillator node if the board's
* DT provides one) has already been scanned by the of_clk_init() in
* time_init().
*/
int __init mpc5121_clk_init(void)
{
struct device_node *clk_np;
......@@ -1186,12 +1191,6 @@ int __init mpc5121_clk_init(void)
/* invalidate all not yet registered clock slots */
mpc512x_clk_preset_data();
/*
* have the device tree scanned for "fixed-clock" nodes (which
* includes the oscillator node if the board's DT provides one)
*/
of_clk_init(NULL);
/*
* add a dummy clock for those situations where a clock spec is
* required yet no real clock is involved
......
......@@ -102,12 +102,12 @@ config COMMON_CLK_AXI_CLKGEN
Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
FPGAs. It is commonly used in Analog Devices' reference designs.
config CLK_PPC_CORENET
bool "Clock driver for PowerPC corenet platforms"
depends on PPC_E500MC && OF
config CLK_QORIQ
bool "Clock driver for Freescale QorIQ platforms"
depends on (PPC_E500MC || ARM) && OF
---help---
This adds the clock driver support for Freescale PowerPC corenet
platforms using common clock framework.
This adds the clock driver support for Freescale QorIQ platforms
using common clock framework.
config COMMON_CLK_XGENE
bool "Clock driver for APM XGene SoC"
......@@ -135,6 +135,14 @@ config COMMON_CLK_PXA
---help---
Sypport for the Marvell PXA SoC.
config COMMON_CLK_CDCE706
tristate "Clock driver for TI CDCE706 clock synthesizer"
depends on I2C
select REGMAP_I2C
select RATIONAL
---help---
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
source "drivers/clk/qcom/Kconfig"
endmenu
......
......@@ -16,9 +16,11 @@ endif
# hardware specific clock types
# please keep this section sorted lexicographically by file/directory path name
obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.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_COMMON_CLK_CDCE706) += clk-cdce706.o
obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
......@@ -30,7 +32,7 @@ obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o
obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
......
......@@ -56,6 +56,8 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
static long clk_programmable_determine_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_hw)
{
......
......@@ -1032,6 +1032,8 @@ static long kona_peri_clk_round_rate(struct clk_hw *hw, unsigned long rate,
}
static long kona_peri_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate, struct clk_hw **best_parent)
{
struct kona_clk *bcm_clk = to_kona_clk(hw);
......
This diff is collapsed.
This diff is collapsed.
......@@ -27,7 +27,7 @@ static u8 clk_composite_get_parent(struct clk_hw *hw)
const struct clk_ops *mux_ops = composite->mux_ops;
struct clk_hw *mux_hw = composite->mux_hw;
mux_hw->clk = hw->clk;
__clk_hw_set_clk(mux_hw, hw);
return mux_ops->get_parent(mux_hw);
}
......@@ -38,7 +38,7 @@ static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
const struct clk_ops *mux_ops = composite->mux_ops;
struct clk_hw *mux_hw = composite->mux_hw;
mux_hw->clk = hw->clk;
__clk_hw_set_clk(mux_hw, hw);
return mux_ops->set_parent(mux_hw, index);
}
......@@ -50,12 +50,14 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
const struct clk_ops *rate_ops = composite->rate_ops;
struct clk_hw *rate_hw = composite->rate_hw;
rate_hw->clk = hw->clk;
__clk_hw_set_clk(rate_hw, hw);
return rate_ops->recalc_rate(rate_hw, parent_rate);
}
static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_p)
{
......@@ -72,8 +74,10 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
int i;
if (rate_hw && rate_ops && rate_ops->determine_rate) {
rate_hw->clk = hw->clk;
return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
__clk_hw_set_clk(rate_hw, hw);
return rate_ops->determine_rate(rate_hw, rate, min_rate,
max_rate,
best_parent_rate,
best_parent_p);
} else if (rate_hw && rate_ops && rate_ops->round_rate &&
mux_hw && mux_ops && mux_ops->set_parent) {
......@@ -116,8 +120,9 @@ static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
return best_rate;
} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
mux_hw->clk = hw->clk;
return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
__clk_hw_set_clk(mux_hw, hw);
return mux_ops->determine_rate(mux_hw, rate, min_rate,
max_rate, best_parent_rate,
best_parent_p);
} else {
pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
......@@ -132,7 +137,7 @@ static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
const struct clk_ops *rate_ops = composite->rate_ops;
struct clk_hw *rate_hw = composite->rate_hw;
rate_hw->clk = hw->clk;
__clk_hw_set_clk(rate_hw, hw);
return rate_ops->round_rate(rate_hw, rate, prate);
}
......@@ -144,7 +149,7 @@ static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
const struct clk_ops *rate_ops = composite->rate_ops;
struct clk_hw *rate_hw = composite->rate_hw;
rate_hw->clk = hw->clk;
__clk_hw_set_clk(rate_hw, hw);
return rate_ops->set_rate(rate_hw, rate, parent_rate);
}
......@@ -155,7 +160,7 @@ static int clk_composite_is_enabled(struct clk_hw *hw)
const struct clk_ops *gate_ops = composite->gate_ops;
struct clk_hw *gate_hw = composite->gate_hw;
gate_hw->clk = hw->clk;
__clk_hw_set_clk(gate_hw, hw);
return gate_ops->is_enabled(gate_hw);
}
......@@ -166,7 +171,7 @@ static int clk_composite_enable(struct clk_hw *hw)
const struct clk_ops *gate_ops = composite->gate_ops;
struct clk_hw *gate_hw = composite->gate_hw;
gate_hw->clk = hw->clk;
__clk_hw_set_clk(gate_hw, hw);
return gate_ops->enable(gate_hw);
}
......@@ -177,7 +182,7 @@ static void clk_composite_disable(struct clk_hw *hw)
const struct clk_ops *gate_ops = composite->gate_ops;
struct clk_hw *gate_hw = composite->gate_hw;
gate_hw->clk = hw->clk;
__clk_hw_set_clk(gate_hw, hw);
gate_ops->disable(gate_hw);
}
......
This diff is collapsed.
......@@ -128,7 +128,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
struct clk_init_data init;
if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
if (bit_idx > 16) {
if (bit_idx > 15) {
pr_err("gate bit exceeds LOWORD field\n");
return ERR_PTR(-EINVAL);
}
......@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
return clk;
}
EXPORT_SYMBOL_GPL(clk_register_gate);
void clk_unregister_gate(struct clk *clk)
{
struct clk_gate *gate;
struct clk_hw *hw;
hw = __clk_get_hw(clk);
if (!hw)
return;
gate = to_clk_gate(hw);
clk_unregister(clk);
kfree(gate);
}
EXPORT_SYMBOL_GPL(clk_unregister_gate);
......@@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
NULL, lock);
}
EXPORT_SYMBOL_GPL(clk_register_mux);
void clk_unregister_mux(struct clk *clk)
{
struct clk_mux *mux;
struct clk_hw *hw;
hw = __clk_get_hw(clk);
if (!hw)
return;
mux = to_clk_mux(hw);
clk_unregister(clk);
kfree(mux);
}
EXPORT_SYMBOL_GPL(clk_unregister_mux);
......@@ -5,8 +5,11 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* clock driver for Freescale PowerPC corenet SoCs.
* clock driver for Freescale QorIQ SoCs.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/kernel.h>
......@@ -19,6 +22,7 @@
struct cmux_clk {
struct clk_hw hw;
void __iomem *reg;
unsigned int clk_per_pll;
u32 flags;
};
......@@ -27,14 +31,12 @@ struct cmux_clk {
#define CLKSEL_ADJUST BIT(0)
#define to_cmux_clk(p) container_of(p, struct cmux_clk, hw)
static unsigned int clocks_per_pll;
static int cmux_set_parent(struct clk_hw *hw, u8 idx)
{
struct cmux_clk *clk = to_cmux_clk(hw);
u32 clksel;
clksel = ((idx / clocks_per_pll) << 2) + idx % clocks_per_pll;
clksel = ((idx / clk->clk_per_pll) << 2) + idx % clk->clk_per_pll;
if (clk->flags & CLKSEL_ADJUST)
clksel += 8;
clksel = (clksel & 0xf) << CLKSEL_SHIFT;
......@@ -52,12 +54,12 @@ static u8 cmux_get_parent(struct clk_hw *hw)
clksel = (clksel >> CLKSEL_SHIFT) & 0xf;
if (clk->flags & CLKSEL_ADJUST)
clksel -= 8;
clksel = (clksel >> 2) * clocks_per_pll + clksel % 4;
clksel = (clksel >> 2) * clk->clk_per_pll + clksel % 4;
return clksel;
}
const struct clk_ops cmux_ops = {
static const struct clk_ops cmux_ops = {
.get_parent = cmux_get_parent,
.set_parent = cmux_set_parent,
};
......@@ -72,6 +74,7 @@ static void __init core_mux_init(struct device_node *np)
u32 offset;
const char *clk_name;
const char **parent_names;
struct of_phandle_args clkspec;
rc = of_property_read_u32(np, "reg", &offset);
if (rc) {
......@@ -85,26 +88,34 @@ static void __init core_mux_init(struct device_node *np)
pr_err("%s: get clock count error\n", np->name);
return;
}
parent_names = kzalloc((sizeof(char *) * count), GFP_KERNEL);
if (!parent_names) {
pr_err("%s: could not allocate parent_names\n", __func__);
parent_names = kcalloc(count, sizeof(char *), GFP_KERNEL);
if (!parent_names)
return;
}
for (i = 0; i < count; i++)
parent_names[i] = of_clk_get_parent_name(np, i);
cmux_clk = kzalloc(sizeof(struct cmux_clk), GFP_KERNEL);
if (!cmux_clk) {
pr_err("%s: could not allocate cmux_clk\n", __func__);
cmux_clk = kzalloc(sizeof(*cmux_clk), GFP_KERNEL);
if (!cmux_clk)
goto err_name;
}
cmux_clk->reg = of_iomap(np, 0);
if (!cmux_clk->reg) {
pr_err("%s: could not map register\n", __func__);
goto err_clk;
}
rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
&clkspec);
if (rc) {
pr_err("%s: parse clock node error\n", __func__);
goto err_clk;
}
cmux_clk->clk_per_pll = of_property_count_strings(clkspec.np,
"clock-output-names");
of_node_put(clkspec.np);
node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");
if (node && (offset >= 0x80))
cmux_clk->flags = CLKSEL_ADJUST;
......@@ -155,7 +166,7 @@ static void __init core_pll_init(struct device_node *np)
base = of_iomap(np, 0);
if (!base) {
pr_err("clk-ppc: iomap error\n");
pr_err("iomap error\n");
return;
}
......@@ -181,20 +192,13 @@ static void __init core_pll_init(struct device_node *np)
goto err_map;
}
/* output clock number per PLL */
clocks_per_pll = count;
subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);
if (!subclks) {
pr_err("%s: could not allocate subclks\n", __func__);
subclks = kcalloc(count, sizeof(struct clk *), GFP_KERNEL);
if (!subclks)
goto err_map;
}
onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
if (!onecell_data) {
pr_err("%s: could not allocate onecell_data\n", __func__);
onecell_data = kmalloc(sizeof(*onecell_data), GFP_KERNEL);
if (!onecell_data)
goto err_clks;
}
for (i = 0; i < count; i++) {
rc = of_property_read_string_index(np, "clock-output-names",
......@@ -252,7 +256,7 @@ static void __init sysclk_init(struct device_node *node)
u32 rate;
if (!np) {
pr_err("ppc-clk: could not get parent node\n");
pr_err("could not get parent node\n");
return;
}
......@@ -268,39 +272,91 @@ static void __init sysclk_init(struct device_node *node)
of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
static const struct of_device_id clk_match[] __initconst = {
{ .compatible = "fsl,qoriq-sysclk-1.0", .data = sysclk_init, },
{ .compatible = "fsl,qoriq-sysclk-2.0", .data = sysclk_init, },
{ .compatible = "fsl,qoriq-core-pll-1.0", .data = core_pll_init, },
{ .compatible = "fsl,qoriq-core-pll-2.0", .data = core_pll_init, },
{ .compatible = "fsl,qoriq-core-mux-1.0", .data = core_mux_init, },
{ .compatible = "fsl,qoriq-core-mux-2.0", .data = core_mux_init, },
{}
};
static int __init ppc_corenet_clk_probe(struct platform_device *pdev)
static void __init pltfrm_pll_init(struct device_node *np)
{
of_clk_init(clk_match);
void __iomem *base;
uint32_t mult;
const char *parent_name, *clk_name;
int i, _errno;
struct clk_onecell_data *cod;
return 0;
}
base = of_iomap(np, 0);
if (!base) {
pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name);
return;
}
static const struct of_device_id ppc_clk_ids[] __initconst = {
{ .compatible = "fsl,qoriq-clockgen-1.0", },
{ .compatible = "fsl,qoriq-clockgen-2.0", },
{}
};
/* Get the multiple of PLL */
mult = ioread32be(base);
static struct platform_driver ppc_corenet_clk_driver = {
.driver = {
.name = "ppc_corenet_clock",
.of_match_table = ppc_clk_ids,
},
.probe = ppc_corenet_clk_probe,
};
iounmap(base);
static int __init ppc_corenet_clk_init(void)
{
return platform_driver_register(&ppc_corenet_clk_driver);
/* Check if this PLL is disabled */
if (mult & PLL_KILL) {
pr_debug("%s(): %s: Disabled\n", __func__, np->name);
return;
}
mult = (mult & GENMASK(6, 1)) >> 1;
parent_name = of_clk_get_parent_name(np, 0);
if (!parent_name) {
pr_err("%s(): %s: of_clk_get_parent_name() failed\n",
__func__, np->name);
return;
}
i = of_property_count_strings(np, "clock-output-names");
if (i < 0) {
pr_err("%s(): %s: of_property_count_strings(clock-output-names) = %d\n",
__func__, np->name, i);
return;
}
cod = kmalloc(sizeof(*cod) + i * sizeof(struct clk *), GFP_KERNEL);
if (!cod)
return;
cod->clks = (struct clk **)(cod + 1);
cod->clk_num = i;
for (i = 0; i < cod->clk_num; i++) {
_errno = of_property_read_string_index(np, "clock-output-names",
i, &clk_name);
if (_errno < 0) {
pr_err("%s(): %s: of_property_read_string_index(clock-output-names) = %d\n",
__func__, np->name, _errno);
goto return_clk_unregister;
}
cod->clks[i] = clk_register_fixed_factor(NULL, clk_name,
parent_name, 0, mult, 1 + i);
if (IS_ERR(cod->clks[i])) {
pr_err("%s(): %s: clk_register_fixed_factor(%s) = %ld\n",
__func__, np->name,
clk_name, PTR_ERR(cod->clks[i]));
goto return_clk_unregister;
}
}
_errno = of_clk_add_provider(np, of_clk_src_onecell_get, cod);
if (_errno < 0) {
pr_err("%s(): %s: of_clk_add_provider() = %d\n",
__func__, np->name, _errno);
goto return_clk_unregister;
}
return;
return_clk_unregister:
while (--i >= 0)
clk_unregister(cod->clks[i]);
kfree(cod);
}
subsys_initcall(ppc_corenet_clk_init);
CLK_OF_DECLARE(qoriq_sysclk_1, "fsl,qoriq-sysclk-1.0", sysclk_init);
CLK_OF_DECLARE(qoriq_sysclk_2, "fsl,qoriq-sysclk-2.0", sysclk_init);
CLK_OF_DECLARE(qoriq_core_pll_1, "fsl,qoriq-core-pll-1.0", core_pll_init);
CLK_OF_DECLARE(qoriq_core_pll_2, "fsl,qoriq-core-pll-2.0", core_pll_init);
CLK_OF_DECLARE(qoriq_core_mux_1, "fsl,qoriq-core-mux-1.0", core_mux_init);
CLK_OF_DECLARE(qoriq_core_mux_2, "fsl,qoriq-core-mux-2.0", core_mux_init);
CLK_OF_DECLARE(qoriq_pltfrm_pll_1, "fsl,qoriq-platform-pll-1.0", pltfrm_pll_init);
CLK_OF_DECLARE(qoriq_pltfrm_pll_2, "fsl,qoriq-platform-pll-2.0", pltfrm_pll_init);
This diff is collapsed.
......@@ -9,9 +9,31 @@
* published by the Free Software Foundation.
*/
struct clk_hw;
#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,
const char *dev_id, const char *con_id);
void of_clk_lock(void);
void of_clk_unlock(void);
#endif
#ifdef CONFIG_COMMON_CLK
struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
const char *con_id);
void __clk_free_clk(struct clk *clk);
#else
/* All these casts to avoid ifdefs in clkdev... */
static inline struct clk *
__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id)
{
return (struct clk *)hw;
}
static inline void __clk_free_clk(struct clk *clk) { }
static struct clk_hw *__clk_get_hw(struct clk *clk)
{
return (struct clk_hw *)clk;
}
#endif
......@@ -19,6 +19,7 @@
#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include "clk.h"
......@@ -28,6 +29,20 @@ static DEFINE_MUTEX(clocks_mutex);
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
static struct clk *__of_clk_get_by_clkspec(struct of_phandle_args *clkspec,
const char *dev_id, const char *con_id)
{
struct clk *clk;
if (!clkspec)
return ERR_PTR(-EINVAL);
of_clk_lock();
clk = __of_clk_get_from_provider(clkspec, dev_id, con_id);
of_clk_unlock();
return clk;
}
/**
* of_clk_get_by_clkspec() - Lookup a clock form a clock provider
* @clkspec: pointer to a clock specifier data structure
......@@ -38,22 +53,11 @@ static DEFINE_MUTEX(clocks_mutex);
*/
struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
{
struct clk *clk;
if (!clkspec)
return ERR_PTR(-EINVAL);
of_clk_lock();
clk = __of_clk_get_from_provider(clkspec);
if (!IS_ERR(clk) && !__clk_get(clk))
clk = ERR_PTR(-ENOENT);
of_clk_unlock();
return clk;
return __of_clk_get_by_clkspec(clkspec, NULL, __func__);
}
struct clk *of_clk_get(struct device_node *np, int index)
static struct clk *__of_clk_get(struct device_node *np, int index,
const char *dev_id, const char *con_id)
{
struct of_phandle_args clkspec;
struct clk *clk;
......@@ -67,22 +71,21 @@ struct clk *of_clk_get(struct device_node *np, int index)
if (rc)
return ERR_PTR(rc);
clk = of_clk_get_by_clkspec(&clkspec);
clk = __of_clk_get_by_clkspec(&clkspec, dev_id, con_id);
of_node_put(clkspec.np);
return clk;
}
struct clk *of_clk_get(struct device_node *np, int index)
{
return __of_clk_get(np, index, np->full_name, NULL);
}
EXPORT_SYMBOL(of_clk_get);
/**
* of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
* @np: pointer to clock consumer node
* @name: name of consumer's clock input, or NULL for the first clock reference
*
* This function parses the clocks and clock-names properties,
* and uses them to look up the struct clk from the registered list of clock
* providers.
*/
struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
const char *name)
{
struct clk *clk = ERR_PTR(-ENOENT);
......@@ -97,10 +100,10 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
*/
if (name)
index = of_property_match_string(np, "clock-names", name);
clk = of_clk_get(np, index);
if (!IS_ERR(clk))
clk = __of_clk_get(np, index, dev_id, name);
if (!IS_ERR(clk)) {
break;
else if (name && index >= 0) {
} else if (name && index >= 0) {
if (PTR_ERR(clk) != -EPROBE_DEFER)
pr_err("ERROR: could not get clock %s:%s(%i)\n",
np->full_name, name ? name : "", index);
......@@ -119,7 +122,33 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
return clk;
}
/**
* of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
* @np: pointer to clock consumer node
* @name: name of consumer's clock input, or NULL for the first clock reference
*
* This function parses the clocks and clock-names properties,
* and uses them to look up the struct clk from the registered list of clock
* providers.
*/
struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
{
if (!np)
return ERR_PTR(-ENOENT);
return __of_clk_get_by_name(np, np->full_name, name);
}
EXPORT_SYMBOL(of_clk_get_by_name);
#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
static struct clk *__of_clk_get_by_name(struct device_node *np,
const char *dev_id,
const char *name)
{
return ERR_PTR(-ENOENT);
}
#endif
/*
......@@ -168,14 +197,28 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
struct clk *clk_get_sys(const char *dev_id, const char *con_id)
{
struct clk_lookup *cl;
struct clk *clk = NULL;
mutex_lock(&clocks_mutex);
cl = clk_find(dev_id, con_id);
if (cl && !__clk_get(cl->clk))
if (!cl)
goto out;
clk = __clk_create_clk(__clk_get_hw(cl->clk), dev_id, con_id);
if (IS_ERR(clk))
goto out;
if (!__clk_get(clk)) {
__clk_free_clk(clk);
cl = NULL;
goto out;
}
out:
mutex_unlock(&clocks_mutex);
return cl ? cl->clk : ERR_PTR(-ENOENT);
return cl ? clk : ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get_sys);
......@@ -185,10 +228,8 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
if (dev) {
clk = of_clk_get_by_name(dev->of_node, con_id);
if (!IS_ERR(clk))
return clk;
if (PTR_ERR(clk) == -EPROBE_DEFER)
clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}
......@@ -331,6 +372,7 @@ int clk_register_clkdev(struct clk *clk, const char *con_id,
return 0;
}
EXPORT_SYMBOL(clk_register_clkdev);
/**
* clk_register_clkdevs - register a set of clk_lookup for a struct clk
......
......@@ -295,6 +295,8 @@ static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
}
static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_p)
{
......
......@@ -202,6 +202,8 @@ static int _set_rate(struct mmp_clk_mix *mix, u32 mux_val, u32 div_val,
}
static long mmp_clk_mix_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......
obj-y += clk-pxa.o
obj-$(CONFIG_PXA25x) += clk-pxa25x.o
obj-$(CONFIG_PXA27x) += clk-pxa27x.o
obj-$(CONFIG_PXA3xx) += clk-pxa3xx.o
......@@ -46,7 +46,7 @@ static unsigned long cken_recalc_rate(struct clk_hw *hw,
fix = &pclk->lp;
else
fix = &pclk->hp;
fix->hw.clk = hw->clk;
__clk_hw_set_clk(&fix->hw, hw);
return clk_fixed_factor_ops.recalc_rate(&fix->hw, parent_rate);
}
......
This diff is collapsed.
......@@ -29,6 +29,15 @@ config IPQ_GCC_806X
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, SD/eMMC, etc.
config IPQ_LCC_806X
tristate "IPQ806x LPASS Clock Controller"
select IPQ_GCC_806X
depends on COMMON_CLK_QCOM
help
Support for the LPASS clock controller on ipq806x devices.
Say Y if you want to use audio devices such as i2s, pcm,
S/PDIF, etc.
config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
......@@ -45,6 +54,15 @@ config MSM_GCC_8960
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, SD/eMMC, SATA, PCIe, etc.
config MSM_LCC_8960
tristate "APQ8064/MSM8960 LPASS Clock Controller"
select MSM_GCC_8960
depends on COMMON_CLK_QCOM
help
Support for the LPASS clock controller on apq8064/msm8960 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
......
......@@ -6,13 +6,17 @@ clk-qcom-y += clk-pll.o
clk-qcom-y += clk-rcg.o
clk-qcom-y += clk-rcg2.o
clk-qcom-y += clk-branch.o
clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o
clk-qcom-y += reset.o
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.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_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
......@@ -141,6 +141,7 @@ struct pll_freq_tbl *find_freq(const struct pll_freq_tbl *f, unsigned long rate)
static long
clk_pll_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p)
{
struct clk_pll *pll = to_clk_pll(hw);
......
......@@ -368,6 +368,7 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
static long _freq_tbl_determine_rate(struct clk_hw *hw,
const struct freq_tbl *f, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p_hw)
{
unsigned long clk_flags;
......@@ -397,22 +398,27 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
}
static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
max_rate, p_rate, p);
}
static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
max_rate, p_rate, p);
}
static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p_hw)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
......
......@@ -208,6 +208,7 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
}
static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
......@@ -361,6 +362,8 @@ static int clk_edp_pixel_set_rate_and_parent(struct clk_hw *hw,
}
static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
......@@ -412,6 +415,7 @@ const struct clk_ops clk_edp_pixel_ops = {
EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate, unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p_hw)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
......@@ -476,6 +480,8 @@ static const struct frac_entry frac_table_pixel[] = {
};
static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *p_rate, struct clk_hw **p)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
......
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* 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/regmap.h>
#include <linux/export.h>
#include "clk-regmap-divider.h"
static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
{
return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
}
static long div_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct clk_regmap_div *divider = to_clk_regmap_div(hw);
return divider_round_rate(hw, rate, prate, NULL, divider->width,
CLK_DIVIDER_ROUND_CLOSEST);
}
static int div_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_regmap_div *divider = to_clk_regmap_div(hw);
struct clk_regmap *clkr = &divider->clkr;
u32 div;
div = divider_get_val(rate, parent_rate, NULL, divider->width,
CLK_DIVIDER_ROUND_CLOSEST);
return regmap_update_bits(clkr->regmap, divider->reg,
(BIT(divider->width) - 1) << divider->shift,
div << divider->shift);
}
static unsigned long div_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_regmap_div *divider = to_clk_regmap_div(hw);
struct clk_regmap *clkr = &divider->clkr;
u32 div;
regmap_read(clkr->regmap, divider->reg, &div);
div >>= divider->shift;
div &= BIT(divider->width) - 1;
return divider_recalc_rate(hw, parent_rate, div, NULL,
CLK_DIVIDER_ROUND_CLOSEST);
}
const struct clk_ops clk_regmap_div_ops = {
.round_rate = div_round_rate,
.set_rate = div_set_rate,
.recalc_rate = div_recalc_rate,
};
EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
/*
* Copyright 2013 - Hans de Goede <hdegoede@redhat.com>
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* 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
......@@ -12,11 +11,19 @@
* GNU General Public License for more details.
*/
#ifndef __LINUX_CLK_SUNXI_H_
#define __LINUX_CLK_SUNXI_H_
#ifndef __QCOM_CLK_REGMAP_DIVIDER_H__
#define __QCOM_CLK_REGMAP_DIVIDER_H__
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include "clk-regmap.h"
void clk_sunxi_mmc_phase_control(struct clk *clk, u8 sample, u8 output);
struct clk_regmap_div {
u32 reg;
u32 shift;
u32 width;
struct clk_regmap clkr;
};
extern const struct clk_ops clk_regmap_div_ops;
#endif
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* 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/regmap.h>
#include <linux/export.h>
#include "clk-regmap-mux.h"
static inline struct clk_regmap_mux *to_clk_regmap_mux(struct clk_hw *hw)
{
return container_of(to_clk_regmap(hw), struct clk_regmap_mux, clkr);
}
static u8 mux_get_parent(struct clk_hw *hw)
{
struct clk_regmap_mux *mux = to_clk_regmap_mux(hw);
struct clk_regmap *clkr = to_clk_regmap(hw);
unsigned int mask = GENMASK(mux->width - 1, 0);
unsigned int val;
regmap_read(clkr->regmap, mux->reg, &val);
val >>= mux->shift;
val &= mask;
return val;
}
static int mux_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_regmap_mux *mux = to_clk_regmap_mux(hw);
struct clk_regmap *clkr = to_clk_regmap(hw);
unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift);
unsigned int val;
val = index;
val <<= mux->shift;
return regmap_update_bits(clkr->regmap, mux->reg, mask, val);
}
const struct clk_ops clk_regmap_mux_closest_ops = {
.get_parent = mux_get_parent,
.set_parent = mux_set_parent,
.determine_rate = __clk_mux_determine_rate_closest,
};
EXPORT_SYMBOL_GPL(clk_regmap_mux_closest_ops);
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* 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 __QCOM_CLK_REGMAP_MUX_H__
#define __QCOM_CLK_REGMAP_MUX_H__
#include <linux/clk-provider.h>
#include "clk-regmap.h"
struct clk_regmap_mux {
u32 reg;
u32 shift;
u32 width;
struct clk_regmap clkr;
};
extern const struct clk_ops clk_regmap_mux_closest_ops;
#endif
......@@ -75,6 +75,17 @@ static struct clk_pll pll3 = {
},
};
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,
......@@ -2163,6 +2174,7 @@ static struct clk_regmap *gcc_ipq806x_clks[] = {
[PLL0] = &pll0.clkr,
[PLL0_VOTE] = &pll0_vote,
[PLL3] = &pll3.clkr,
[PLL4_VOTE] = &pll4_vote,
[PLL8] = &pll8.clkr,
[PLL8_VOTE] = &pll8_vote,
[PLL14] = &pll14.clkr,
......
This diff is collapsed.
This diff is collapsed.
......@@ -535,44 +535,44 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
RK3288_CLKGATE_CON(1), 8, GFLAGS),
COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", 0,
COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(17), 0,
RK3288_CLKGATE_CON(1), 9, GFLAGS),
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, 0,
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
RK3288_CLKGATE_CON(1), 10, GFLAGS),
COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", 0,
COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(18), 0,
RK3288_CLKGATE_CON(1), 11, GFLAGS),
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, 0,
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
RK3288_CLKGATE_CON(1), 12, GFLAGS),
COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", 0,
COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(19), 0,
RK3288_CLKGATE_CON(1), 13, GFLAGS),
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, 0,
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
RK3288_CLKGATE_CON(1), 14, GFLAGS),
COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", 0,
COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(20), 0,
RK3288_CLKGATE_CON(1), 15, GFLAGS),
MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, 0,
MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
RK3288_CLKGATE_CON(2), 12, GFLAGS),
COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", 0,
COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(7), 0,
RK3288_CLKGATE_CON(2), 13, GFLAGS),
MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, 0,
MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
......@@ -598,7 +598,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
GATE(0, "jtag", "ext_jtag", 0,
RK3288_CLKGATE_CON(4), 14, GFLAGS),
COMPOSITE_NODIV(0, "usbphy480m_src", mux_usbphy480m_p, 0,
COMPOSITE_NODIV(SCLK_USBPHY480M_SRC, "usbphy480m_src", mux_usbphy480m_p, 0,
RK3288_CLKSEL_CON(13), 11, 2, MFLAGS,
RK3288_CLKGATE_CON(5), 14, GFLAGS),
COMPOSITE_NODIV(SCLK_HSICPHY480M, "sclk_hsicphy480m", mux_hsicphy480m_p, 0,
......@@ -704,8 +704,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
GATE(SCLK_LCDC_PWM0, "sclk_lcdc_pwm0", "xin24m", 0, RK3288_CLKGATE_CON(13), 10, GFLAGS),
GATE(SCLK_LCDC_PWM1, "sclk_lcdc_pwm1", "xin24m", 0, RK3288_CLKGATE_CON(13), 11, GFLAGS),
GATE(0, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
GATE(0, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK3288_CLKGATE_CON(5), 9, GFLAGS),
GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK3288_CLKGATE_CON(5), 10, GFLAGS),
GATE(0, "sclk_mipidsi_24m", "xin24m", 0, RK3288_CLKGATE_CON(5), 15, GFLAGS),
/* sclk_gpu gates */
......@@ -805,6 +805,20 @@ static int rk3288_clk_suspend(void)
rk3288_saved_cru_regs[i] =
readl_relaxed(rk3288_cru_base + reg_id);
}
/*
* Switch PLLs other than DPLL (for SDRAM) to slow mode to
* avoid crashes on resume. The Mask ROM on the system will
* put APLL, CPLL, and GPLL into slow mode at resume time
* anyway (which is why we restore them), but we might not
* even make it to the Mask ROM if this isn't done at suspend
* time.
*
* NOTE: only APLL truly matters here, but we'll do them all.
*/
writel_relaxed(0xf3030000, rk3288_cru_base + RK3288_MODE_CON);
return 0;
}
......@@ -866,6 +880,14 @@ static void __init rk3288_clk_init(struct device_node *np)
pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
__func__, PTR_ERR(clk));
/* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */
clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1);
if (IS_ERR(clk))
pr_warn("%s: could not register clock pclk_wdt: %ld\n",
__func__, PTR_ERR(clk));
else
rockchip_clk_add_lookup(clk, PCLK_WDT);
rockchip_clk_register_plls(rk3288_pll_clks,
ARRAY_SIZE(rk3288_pll_clks),
RK3288_GRF_SOC_STATUS1);
......
......@@ -82,6 +82,26 @@ static const struct of_device_id exynos_audss_clk_of_match[] = {
{},
};
static void exynos_audss_clk_teardown(void)
{
int i;
for (i = EXYNOS_MOUT_AUDSS; i < EXYNOS_DOUT_SRP; i++) {
if (!IS_ERR(clk_table[i]))
clk_unregister_mux(clk_table[i]);
}
for (; i < EXYNOS_SRP_CLK; i++) {
if (!IS_ERR(clk_table[i]))
clk_unregister_divider(clk_table[i]);
}
for (; i < clk_data.clk_num; i++) {
if (!IS_ERR(clk_table[i]))
clk_unregister_gate(clk_table[i]);
}
}
/* register exynos_audss clocks */
static int exynos_audss_clk_probe(struct platform_device *pdev)
{
......@@ -219,10 +239,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
return 0;
unregister:
for (i = 0; i < clk_data.clk_num; i++) {
if (!IS_ERR(clk_table[i]))
clk_unregister(clk_table[i]);
}
exynos_audss_clk_teardown();
if (!IS_ERR(epll))
clk_disable_unprepare(epll);
......@@ -232,18 +249,13 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
static int exynos_audss_clk_remove(struct platform_device *pdev)
{
int i;
#ifdef CONFIG_PM_SLEEP
unregister_syscore_ops(&exynos_audss_clk_syscore_ops);
#endif
of_clk_del_provider(pdev->dev.of_node);
for (i = 0; i < clk_data.clk_num; i++) {
if (!IS_ERR(clk_table[i]))
clk_unregister(clk_table[i]);
}
exynos_audss_clk_teardown();
if (!IS_ERR(epll))
clk_disable_unprepare(epll);
......
This diff is collapsed.
......@@ -703,12 +703,12 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
/* list of divider clocks supported in all exynos4 soc's */
static struct samsung_div_clock exynos4_div_clks[] __initdata = {
DIV(0, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
DIV(0, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
CLKOUT_CMU_LEFTBUS, 8, 6),
DIV(0, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
DIV(0, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
DIV(0, "div_clkout_rightbus", "mout_clkout_rightbus",
CLKOUT_CMU_RIGHTBUS, 8, 6),
......@@ -781,10 +781,10 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
CLK_SET_RATE_PARENT, 0),
DIV(0, "div_clkout_top", "mout_clkout_top", CLKOUT_CMU_TOP, 8, 6),
DIV(0, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
DIV(CLK_DIV_ACP, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
DIV(0, "div_acp_pclk", "div_acp", DIV_DMC0, 4, 3),
DIV(0, "div_dphy", "mout_dphy", DIV_DMC0, 8, 3),
DIV(0, "div_dmc", "mout_dmc_bus", DIV_DMC0, 12, 3),
DIV(CLK_DIV_DMC, "div_dmc", "mout_dmc_bus", DIV_DMC0, 12, 3),
DIV(0, "div_dmcd", "div_dmc", DIV_DMC0, 16, 3),
DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
DIV(0, "div_pwi", "mout_pwi", DIV_DMC1, 8, 4),
......@@ -829,7 +829,7 @@ static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
8, 3, CLK_GET_RATE_NOCACHE, 0),
DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
DIV(0, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
DIV(CLK_DIV_C2C, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -374,19 +374,24 @@ static void samsung_clk_sleep_init(void __iomem *reg_base,
* Common function which registers plls, muxes, dividers and gates
* for each CMU. It also add CMU register list to register cache.
*/
void __init samsung_cmu_register_one(struct device_node *np,
struct samsung_clk_provider * __init samsung_cmu_register_one(
struct device_node *np,
struct samsung_cmu_info *cmu)
{
void __iomem *reg_base;
struct samsung_clk_provider *ctx;
reg_base = of_iomap(np, 0);
if (!reg_base)
if (!reg_base) {
panic("%s: failed to map registers\n", __func__);
return NULL;
}
ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
if (!ctx)
if (!ctx) {
panic("%s: unable to alllocate ctx\n", __func__);
return ctx;
}
if (cmu->pll_clks)
samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
......@@ -410,4 +415,6 @@ void __init samsung_cmu_register_one(struct device_node *np,
cmu->nr_clk_regs);
samsung_clk_of_add_provider(np, ctx);
return ctx;
}
......@@ -392,7 +392,8 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
struct samsung_pll_clock *pll_list,
unsigned int nr_clk, void __iomem *base);
extern void __init samsung_cmu_register_one(struct device_node *,
extern struct samsung_clk_provider __init *samsung_cmu_register_one(
struct device_node *,
struct samsung_cmu_info *);
extern unsigned long _get_rate(const char *clk_name);
......
obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o
obj-$(CONFIG_ARCH_R7S72100) += clk-rz.o
obj-$(CONFIG_ARCH_R8A73A4) += clk-r8a73a4.o
obj-$(CONFIG_ARCH_R8A7740) += clk-r8a7740.o
obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
......
......@@ -54,12 +54,19 @@ static int cpg_div6_clock_enable(struct clk_hw *hw)
static void cpg_div6_clock_disable(struct clk_hw *hw)
{
struct div6_clock *clock = to_div6_clock(hw);
u32 val;
/* DIV6 clocks require the divisor field to be non-zero when stopping
* the clock.
val = clk_readl(clock->reg);
val |= CPG_DIV6_CKSTP;
/*
* DIV6 clocks require the divisor field to be non-zero when stopping
* the clock. However, some clocks (e.g. ZB on sh73a0) fail to be
* re-enabled later if the divisor field is changed when stopping the
* clock
*/
clk_writel(clk_readl(clock->reg) | CPG_DIV6_CKSTP | CPG_DIV6_DIV_MASK,
clock->reg);
if (!(val & CPG_DIV6_DIV_MASK))
val |= CPG_DIV6_DIV_MASK;
clk_writel(val, clock->reg);
}
static int cpg_div6_clock_is_enabled(struct clk_hw *hw)
......@@ -83,6 +90,9 @@ static unsigned int cpg_div6_clock_calc_div(unsigned long rate,
{
unsigned int div;
if (!rate)
rate = 1;
div = DIV_ROUND_CLOSEST(parent_rate, rate);
return clamp_t(unsigned int, div, 1, 64);
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -8,6 +8,7 @@ obj-y += clk-a20-gmac.o
obj-y += clk-mod0.o
obj-y += clk-sun8i-mbus.o
obj-y += clk-sun9i-core.o
obj-y += clk-sun9i-mmc.o
obj-$(CONFIG_MFD_SUN6I_PRCM) += \
clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
......
This diff is collapsed.
......@@ -36,8 +36,9 @@ struct clk_factors {
spinlock_t *lock;
};
struct clk * __init sunxi_factors_register(struct device_node *node,
struct clk *sunxi_factors_register(struct device_node *node,
const struct factors_data *data,
spinlock_t *lock);
spinlock_t *lock,
void __iomem *reg);
#endif
This diff is collapsed.
......@@ -45,6 +45,8 @@ static unsigned long ar100_recalc_rate(struct clk_hw *hw,
}
static long ar100_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long min_rate,
unsigned long max_rate,
unsigned long *best_parent_rate,
struct clk_hw **best_parent_clk)
{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -15,3 +15,4 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clk-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += clk-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += clk-tegra114.o
obj-$(CONFIG_ARCH_TEGRA_124_SOC) += clk-tegra124.o
obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.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.
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