The first half of the clk framework pull request is made up almost

entirely of new platform/driver support. There are some conversions of
 existing drivers to the common-clock Device Tree binding, and a few
 non-critical fixes to the framework.
 
 Due to an entirely unnecessary cyclical dependency with the arm-soc tree
 this pull request is broken into two pieces. The second piece will be
 sent out after arm-soc sends you the pull request that merged in core
 support for the HiSilicon 3620 platform. That same pull request from
 arm-soc depends on this pull request to merge in those HiSilicon bits
 without causing build failures.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.14 (GNU/Linux)
 
 iQIcBAABAgAGBQJS4WZPAAoJEDqPOy9afJhJVz4QAL63xispjEVuABUjgskR1fyo
 7QljpqUJCOViqiVqNi1sPtM0irvfrApNwTpK3mGm20/kbNIBSdqGc/fI5CbWxXAU
 scRqplTTLY6F7nXJXGgiM/e5b31Tb+KmY9Su5chq1Yv6py4/yb6SzoohcBlQJ5in
 JKIxgLqe1VqUkCY2EFlqLwYqUtgr/Zm6ZJDt4LTwxc43apwgG7USMAS8ppx7nTgd
 oGgcsU4dNur1L4+ahvwqC+ntfoZNmVKJm+eY+JrHXJ2sga4PLaJcorgK2NXFpgln
 nwZQzRfbZLg7vNg/ODIDvP94mhc266xq2TCWzD/kMOBwmhsM0lySpzI/IM8qv1U2
 Tdy9EHAj2iHoU+s1yPEUtNRV4h2+BGUUy54690XO30+VCLVEJUCC2KopDAk0G3ua
 qxSCb1mJto8EEq3jCJwKZSOUI7gcizDjHAaqfLlnDytMlsFJR7AJVj5IcRdgC/9s
 Vg975Xklkn33fWEuYQzdQdcmJ8ZCnydo92R2S0CaMgxMZqp2eoYZXJWvgCAvfQYC
 HjAtnBpHxNsZQeASvclb9bQrEisAUjIrxvuzLenQhg88WhBuyUDgBdretCzHFhP4
 i62QGAhSYiNJJQzs+U9EndG6fRr/p98Pmw2pBAAn8UYOT2wWMj8wpR+IVT50Bmdi
 j6LsDpvc7CE2a4f+KoCa
 =Hh66
 -----END PGP SIGNATURE-----

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

Pull clk framework changes from Mike Turquette:
 "The first half of the clk framework pull request is made up almost
  entirely of new platform/driver support.  There are some conversions
  of existing drivers to the common-clock Device Tree binding, and a few
  non-critical fixes to the framework.

  Due to an entirely unnecessary cyclical dependency with the arm-soc
  tree this pull request is broken into two pieces.  The second piece
  will be sent out after arm-soc sends you the pull request that merged
  in core support for the HiSilicon 3620 platform.  That same pull
  request from arm-soc depends on this pull request to merge in those
  HiSilicon bits without causing build failures"

[ Just did the ARM SoC merges, so getting ready for the second clk tree
  pull request   - Linus ]

* tag 'clk-for-linus-3.14-part1' of git://git.linaro.org/people/mike.turquette/linux: (97 commits)
  devicetree: bindings: Document qcom,mmcc
  devicetree: bindings: Document qcom,gcc
  clk: qcom: Add support for MSM8660's global clock controller (GCC)
  clk: qcom: Add support for MSM8974's multimedia clock controller (MMCC)
  clk: qcom: Add support for MSM8974's global clock controller (GCC)
  clk: qcom: Add support for MSM8960's multimedia clock controller (MMCC)
  clk: qcom: Add support for MSM8960's global clock controller (GCC)
  clk: qcom: Add reset controller support
  clk: qcom: Add support for branches/gate clocks
  clk: qcom: Add support for root clock generators (RCGs)
  clk: qcom: Add support for phase locked loops (PLLs)
  clk: qcom: Add a regmap type clock struct
  clk: Add set_rate_and_parent() op
  reset: Silence warning in reset-controller.h
  clk: sirf: re-arch to make the codes support both prima2 and atlas6
  clk: composite: pass mux_hw into determine_rate
  clk: shmobile: Fix MSTP clock array initialization
  clk: shmobile: Fix MSTP clock index
  ARM: dts: Add clock provider specific properties to max77686 node
  clk: max77686: Register OF clock provider
  ...
This commit is contained in:
Linus Torvalds 2014-01-23 18:56:08 -08:00
Родитель 0ba3307a8e 2e84d75116
Коммит 7e21774db5
111 изменённых файлов: 22435 добавлений и 1561 удалений

Просмотреть файл

@ -77,6 +77,11 @@ the operations defined in clk.h:
int (*set_parent)(struct clk_hw *hw, u8 index);
u8 (*get_parent)(struct clk_hw *hw);
int (*set_rate)(struct clk_hw *hw, unsigned long);
int (*set_rate_and_parent)(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate, u8 index);
unsigned long (*recalc_accuracy)(struct clk_hw *hw,
unsigned long parent_accuracy);
void (*init)(struct clk_hw *hw);
};
@ -202,6 +207,8 @@ optional or must be evaluated on a case-by-case basis.
.set_parent | | | n | y | n |
.get_parent | | | n | y | n |
| | | | | |
.recalc_accuracy| | | | | |
| | | | | |
.init | | | | | |
-----------------------------------------------------------
[1] either one of round_rate or determine_rate is required.

Просмотреть файл

@ -8,12 +8,29 @@ Required Properties:
- compatible: should be one of the following:
- "samsung,exynos4210-audss-clock" - controller compatible with all Exynos4 SoCs.
- "samsung,exynos5250-audss-clock" - controller compatible with all Exynos5 SoCs.
- "samsung,exynos5250-audss-clock" - controller compatible with Exynos5250
SoCs.
- "samsung,exynos5420-audss-clock" - controller compatible with Exynos5420
SoCs.
- reg: physical base address and length of the controller's register set.
- #clock-cells: should be 1.
- clocks:
- pll_ref: Fixed rate PLL reference clock, parent of mout_audss. "fin_pll"
is used if not specified.
- pll_in: Input PLL to the AudioSS block, parent of mout_audss. "fout_epll"
is used if not specified.
- cdclk: External i2s clock, parent of mout_i2s. "cdclk0" is used if not
specified.
- sclk_audio: Audio bus clock, parent of mout_i2s. "sclk_audio0" is used if
not specified.
- sclk_pcm_in: PCM clock, parent of sclk_pcm. "sclk_pcm0" is used if not
specified.
- clock-names: Aliases for the above clocks. They should be "pll_ref",
"pll_in", "cdclk", "sclk_audio", and "sclk_pcm_in" respectively.
The following is the list of clocks generated by the controller. Each clock is
assigned an identifier and client nodes use this identifier to specify the
clock which they consume. Some of the clocks are available only on a particular
@ -34,8 +51,10 @@ i2s_bus 6
sclk_i2s 7
pcm_bus 8
sclk_pcm 9
adma 10 Exynos5420
Example 1: An example of a clock controller node is listed below.
Example 1: An example of a clock controller node using the default input
clock names is listed below.
clock_audss: audss-clock-controller@3810000 {
compatible = "samsung,exynos5250-audss-clock";
@ -43,7 +62,19 @@ clock_audss: audss-clock-controller@3810000 {
#clock-cells = <1>;
};
Example 2: I2S controller node that consumes the clock generated by the clock
Example 2: An example of a clock controller node with the input clocks
specified.
clock_audss: audss-clock-controller@3810000 {
compatible = "samsung,exynos5250-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>,
<&ext_i2s_clk>;
clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in", "cdclk";
};
Example 3: I2S controller node that consumes the clock generated by the clock
controller. Refer to the standard clock bindings for information
about 'clocks' and 'clock-names' property.

Просмотреть файл

@ -0,0 +1,98 @@
Device tree Clock bindings for Renesas EMMA Mobile EV2
This binding uses the common clock binding.
* SMU
System Management Unit described in user's manual R19UH0037EJ1000_SMU.
This is not a clock provider, but clocks under SMU depend on it.
Required properties:
- compatible: Should be "renesas,emev2-smu"
- reg: Address and Size of SMU registers
* SMU_CLKDIV
Function block with an input mux and a divider, which corresponds to
"Serial clock generator" in fig."Clock System Overview" of the manual,
and "xxx frequency division setting register" (XXXCLKDIV) registers.
This makes internal (neither input nor output) clock that is provided
to input of xxxGCLK block.
Required properties:
- compatible: Should be "renesas,emev2-smu-clkdiv"
- reg: Byte offset from SMU base and Bit position in the register
- clocks: Parent clocks. Input clocks as described in clock-bindings.txt
- #clock-cells: Should be <0>
* SMU_GCLK
Clock gating node shown as "Clock stop processing block" in the
fig."Clock System Overview" of the manual.
Registers are "xxx clock gate control register" (XXXGCLKCTRL).
Required properties:
- compatible: Should be "renesas,emev2-smu-gclk"
- reg: Byte offset from SMU base and Bit position in the register
- clocks: Input clock as described in clock-bindings.txt
- #clock-cells: Should be <0>
Example of provider:
usia_u0_sclkdiv: usia_u0_sclkdiv {
compatible = "renesas,emev2-smu-clkdiv";
reg = <0x610 0>;
clocks = <&pll3_fo>, <&pll4_fo>, <&pll1_fo>, <&osc1_fo>;
#clock-cells = <0>;
};
usia_u0_sclk: usia_u0_sclk {
compatible = "renesas,emev2-smu-gclk";
reg = <0x4a0 1>;
clocks = <&usia_u0_sclkdiv>;
#clock-cells = <0>;
};
Example of consumer:
uart@e1020000 {
compatible = "renesas,em-uart";
reg = <0xe1020000 0x38>;
interrupts = <0 8 0>;
clocks = <&usia_u0_sclk>;
clock-names = "sclk";
};
Example of clock-tree description:
This describes a clock path in the clock tree
c32ki -> pll3_fo -> usia_u0_sclkdiv -> usia_u0_sclk
smu@e0110000 {
compatible = "renesas,emev2-smu";
reg = <0xe0110000 0x10000>;
#address-cells = <2>;
#size-cells = <0>;
c32ki: c32ki {
compatible = "fixed-clock";
clock-frequency = <32768>;
#clock-cells = <0>;
};
pll3_fo: pll3_fo {
compatible = "fixed-factor-clock";
clocks = <&c32ki>;
clock-div = <1>;
clock-mult = <7000>;
#clock-cells = <0>;
};
usia_u0_sclkdiv: usia_u0_sclkdiv {
compatible = "renesas,emev2-smu-clkdiv";
reg = <0x610 0>;
clocks = <&pll3_fo>;
#clock-cells = <0>;
};
usia_u0_sclk: usia_u0_sclk {
compatible = "renesas,emev2-smu-gclk";
reg = <0x4a0 1>;
clocks = <&usia_u0_sclkdiv>;
#clock-cells = <0>;
};
};

Просмотреть файл

@ -62,6 +62,7 @@ clock which they consume.
div_i2s1 157
div_i2s2 158
sclk_hdmiphy 159
div_pcm0 160
[Peripheral Clock Gates]

Просмотреть файл

@ -10,6 +10,8 @@ Required properties:
- clock-frequency : frequency of clock in Hz. Should be a single cell.
Optional properties:
- clock-accuracy : accuracy of clock in ppb (parts per billion).
Should be a single cell.
- gpios : From common gpio binding; gpio connection to clock enable pin.
- clock-output-names : From common clock binding.
@ -18,4 +20,5 @@ Example:
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <1000000000>;
clock-accuracy = <100>;
};

Просмотреть файл

@ -19,6 +19,6 @@ Example:
compatible = "fixed-factor-clock";
clocks = <&parentclk>;
#clock-cells = <0>;
div = <2>;
mult = <1>;
clock-div = <2>;
clock-mult = <1>;
};

Просмотреть файл

@ -0,0 +1,19 @@
* Hisilicon Hi3620 Clock Controller
The Hi3620 clock controller generates and supplies clock to various
controllers within the Hi3620 SoC.
Required Properties:
- compatible: should be one of the following.
- "hisilicon,hi3620-clock" - controller compatible with Hi3620 SoC.
- reg: physical base address of the controller and length of memory mapped
region.
- #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/hi3620-clock.h>.

Просмотреть файл

@ -17,13 +17,14 @@ Required properties:
- reg - pll control0 and pll multipler registers
- reg-names : control and multiplier. The multiplier is applicable only for
main pll clock
- fixed-postdiv : fixed post divider value
- fixed-postdiv : fixed post divider value. If absent, use clkod register bits
for postdiv
Example:
mainpllclk: mainpllclk@2310110 {
#clock-cells = <0>;
compatible = "ti,keystone,main-pll-clock";
clocks = <&refclkmain>;
clocks = <&refclksys>;
reg = <0x02620350 4>, <0x02310110 4>;
reg-names = "control", "multiplier";
fixed-postdiv = <2>;
@ -32,11 +33,10 @@ Example:
papllclk: papllclk@2620358 {
#clock-cells = <0>;
compatible = "ti,keystone,pll-clock";
clocks = <&refclkmain>;
clocks = <&refclkpass>;
clock-output-names = "pa-pll-clk";
reg = <0x02620358 4>;
reg-names = "control";
fixed-postdiv = <6>;
};
Required properties:

Просмотреть файл

@ -0,0 +1,38 @@
Binding for Maxim MAX77686 32k clock generator block
This is a part of device tree bindings of MAX77686 multi-function device.
More information can be found in bindings/mfd/max77686.txt file.
The MAX77686 contains three 32.768khz clock outputs that can be controlled
(gated/ungated) over I2C.
Following properties should be presend in main device node of the MFD chip.
Required properties:
- #clock-cells: simple one-cell clock specifier format is used, where the
only cell is used as an index of the clock inside the provider. Following
indices are allowed:
- 0: 32khz_ap clock,
- 1: 32khz_cp clock,
- 2: 32khz_pmic clock.
Example: Node of the MFD chip
max77686: max77686@09 {
compatible = "maxim,max77686";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
reg = <0x09>;
#clock-cells = <1>;
/* ... */
};
Example: Clock consumer node
foo@0 {
compatible = "bar,foo";
/* ... */
clock-names = "my-clock";
clocks = <&max77686 2>;
};

Просмотреть файл

@ -0,0 +1,21 @@
Qualcomm Global Clock & Reset Controller Binding
------------------------------------------------
Required properties :
- compatible : shall contain only one of the following:
"qcom,gcc-msm8660"
"qcom,gcc-msm8960"
"qcom,gcc-msm8974"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
- #reset-cells : shall contain 1
Example:
clock-controller@900000 {
compatible = "qcom,gcc-msm8960";
reg = <0x900000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
};

Просмотреть файл

@ -0,0 +1,21 @@
Qualcomm Multimedia Clock & Reset Controller Binding
----------------------------------------------------
Required properties :
- compatible : shall contain only one of the following:
"qcom,mmcc-msm8660"
"qcom,mmcc-msm8960"
"qcom,mmcc-msm8974"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
- #reset-cells : shall contain 1
Example:
clock-controller@4000000 {
compatible = "qcom,mmcc-msm8960";
reg = <0x4000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};

Просмотреть файл

@ -0,0 +1,39 @@
Binding for Silicon Labs 570, 571, 598 and 599 programmable
I2C clock generators.
Reference
This binding uses the common clock binding[1]. Details about the devices can be
found in the data sheets[2][3].
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
[2] Si570/571 Data Sheet
http://www.silabs.com/Support%20Documents/TechnicalDocs/si570.pdf
[3] Si598/599 Data Sheet
http://www.silabs.com/Support%20Documents/TechnicalDocs/si598-99.pdf
Required properties:
- compatible: Shall be one of "silabs,si570", "silabs,si571",
"silabs,si598", "silabs,si599"
- reg: I2C device address.
- #clock-cells: From common clock bindings: Shall be 0.
- factory-fout: Factory set default frequency. This frequency is part specific.
The correct frequency for the part used has to be provided in
order to generate the correct output frequencies. For more
details, please refer to the data sheet.
- temperature-stability: Temperature stability of the device in PPM. Should be
one of: 7, 20, 50 or 100.
Optional properties:
- clock-output-names: From common clock bindings. Recommended to be "si570".
- clock-frequency: Output frequency to generate. This defines the output
frequency set during boot. It can be reprogrammed during
runtime through the common clock framework.
Example:
si570: clock-generator@5d {
#clock-cells = <0>;
compatible = "silabs,si570";
temperature-stability = <50>;
reg = <0x5d>;
factory-fout = <156250000>;
};

Просмотреть файл

@ -7,8 +7,10 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be one of the following:
"allwinner,sun4i-osc-clk" - for a gatable oscillator
"allwinner,sun4i-pll1-clk" - for the main PLL clock
"allwinner,sun4i-pll1-clk" - for the main PLL clock and PLL4
"allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31
"allwinner,sun4i-pll5-clk" - for the PLL5 clock
"allwinner,sun4i-pll6-clk" - for the PLL6 clock
"allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
"allwinner,sun4i-axi-clk" - for the AXI clock
"allwinner,sun4i-axi-gates-clk" - for the AXI gates
@ -33,10 +35,14 @@ Required properties:
"allwinner,sun7i-a20-apb1-gates-clk" - for the APB1 gates on A20
"allwinner,sun6i-a31-apb2-div-clk" - for the APB2 gates on A31
"allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31
"allwinner,sun4i-mod0-clk" - for the module 0 family of clocks
"allwinner,sun7i-a20-out-clk" - for the external output clocks
Required properties for all clocks:
- reg : shall be the control register address for the clock.
- clocks : shall be the input parent clock(s) phandle for the clock
- clocks : shall be the input parent clock(s) phandle for the clock. For
multiplexed clocks, the list order must match the hardware
programming order.
- #clock-cells : from common clock binding; shall be set to 0 except for
"allwinner,*-gates-clk" where it shall be set to 1

Просмотреть файл

@ -22,6 +22,10 @@ Required properties:
Optional properties:
- clocks : as described in the clock bindings
- clock-names : as described in the clock bindings
- fclk-enable : Bit mask to enable FCLKs statically at boot time.
Bit [0..3] correspond to FCLK0..FCLK3. The corresponding
FCLK will only be enabled if it is actually running at
boot time.
Clock inputs:
The following strings are optional parameters to the 'clock-names' property in

Просмотреть файл

@ -7,6 +7,9 @@ different i2c slave address,presently for which we are statically creating i2c
client while probing.This document describes the binding for mfd device and
PMIC submodule.
Binding for the built-in 32k clock generator block is defined separately
in bindings/clk/maxim,max77686.txt file.
Required properties:
- compatible : Must be "maxim,max77686";
- reg : Specifies the i2c slave address of PMIC block.

Просмотреть файл

@ -1345,6 +1345,14 @@ F: drivers/rtc/rtc-ab8500.c
F: drivers/rtc/rtc-pl031.c
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
ARM/Ux500 CLOCK FRAMEWORK SUPPORT
M: Ulf Hansson <ulf.hansson@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
T: git git://git.linaro.org/people/ulfh/clk.git
S: Maintained
F: drivers/clk/ux500/
F: include/linux/platform_data/clk-ux500.h
ARM/VFP SUPPORT
M: Russell King <linux@arm.linux.org.uk>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@ -7431,6 +7439,12 @@ L: linux-media@vger.kernel.org
S: Supported
F: drivers/media/i2c/s5c73m3/*
SAMSUNG SOC CLOCK DRIVERS
M: Tomasz Figa <t.figa@samsung.com>
S: Supported
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
F: drivers/clk/samsung/
SERIAL DRIVERS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: linux-serial@vger.kernel.org

Просмотреть файл

@ -116,6 +116,7 @@
max77686: pmic@09 {
compatible = "maxim,max77686";
reg = <0x09>;
#clock-cells = <1>;
voltage-regulators {
ldo1_reg: LDO1 {

Просмотреть файл

@ -139,6 +139,7 @@
interrupt-parent = <&gpx0>;
interrupts = <7 0>;
reg = <0x09>;
#clock-cells = <1>;
voltage-regulators {
ldo1_reg: ldo1 {

Просмотреть файл

@ -49,6 +49,7 @@
pinctrl-0 = <&max77686_irq>;
wakeup-source;
reg = <0x09>;
#clock-cells = <1>;
voltage-regulators {
ldo1_reg: LDO1 {

Просмотреть файл

@ -90,6 +90,8 @@
compatible = "samsung,exynos5250-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
clocks = <&clock 1>, <&clock 7>, <&clock 138>, <&clock 160>;
clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
};
timer {

Просмотреть файл

@ -119,8 +119,8 @@
compatible = "samsung,exynos5420-audss-clock";
reg = <0x03810000 0x0C>;
#clock-cells = <1>;
clocks = <&clock 148>;
clock-names = "sclk_audio";
clocks = <&clock 1>, <&clock 5>, <&clock 148>, <&clock 149>;
clock-names = "pll_ref", "pll_in", "sclk_audio", "sclk_pcm_in";
};
codec@11000000 {

Просмотреть файл

@ -14,12 +14,14 @@
#include <linux/slab.h>
#ifndef CONFIG_COMMON_CLK
#ifdef CONFIG_HAVE_MACH_CLKDEV
#include <mach/clkdev.h>
#else
#define __clk_get(clk) ({ 1; })
#define __clk_put(clk) do { } while (0)
#endif
#endif
static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
{

Просмотреть файл

@ -8,7 +8,9 @@ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
return kzalloc(size, GFP_KERNEL);
}
#ifndef CONFIG_COMMON_CLK
#define __clk_put(clk)
#define __clk_get(clk) ({ 1; })
#endif
#endif

Просмотреть файл

@ -14,8 +14,10 @@
#include <linux/slab.h>
#ifndef CONFIG_COMMON_CLK
#define __clk_get(clk) ({ 1; })
#define __clk_put(clk) do { } while (0)
#endif
static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
{

Просмотреть файл

@ -25,7 +25,9 @@ static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
return kzalloc(size, GFP_KERNEL);
}
#ifndef CONFIG_COMMON_CLK
#define __clk_put(clk)
#define __clk_get(clk) ({ 1; })
#endif
#endif /* __CLKDEV_H__ */

Просмотреть файл

@ -23,16 +23,6 @@ config COMMON_CLK
menu "Common Clock Framework"
depends on COMMON_CLK
config COMMON_CLK_DEBUG
bool "DebugFS representation of clock tree"
select DEBUG_FS
---help---
Creates a directory hierarchy in debugfs for visualizing the clk
tree structure. Each directory contains read-only members
that export information specific to that clk node: clk_rate,
clk_flags, clk_prepare_count, clk_enable_count &
clk_notifier_count.
config COMMON_CLK_WM831X
tristate "Clock driver for WM831x/2x PMICs"
depends on MFD_WM831X
@ -64,6 +54,16 @@ config COMMON_CLK_SI5351
This driver supports Silicon Labs 5351A/B/C programmable clock
generators.
config COMMON_CLK_SI570
tristate "Clock driver for SiLabs 570 and compatible devices"
depends on I2C
depends on OF
select REGMAP_I2C
help
---help---
This driver supports Silicon Labs 570/571/598/599 programmable
clock generators.
config COMMON_CLK_S2MPS11
tristate "Clock driver for S2MPS11 MFD"
depends on MFD_SEC_CORE
@ -107,6 +107,8 @@ config COMMON_CLK_KEYSTONE
Supports clock drivers for Keystone based SOCs. These SOCs have local
a power sleep control module that gate the clock to the IPs and PLLs.
source "drivers/clk/qcom/Kconfig"
endmenu
source "drivers/clk/mvebu/Kconfig"

Просмотреть файл

@ -14,13 +14,14 @@ obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
obj-$(CONFIG_ARCH_MXS) += mxs/
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
obj-$(CONFIG_PLAT_SPEAR) += spear/
obj-$(CONFIG_ARCH_U300) += clk-u300.o
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
obj-$(CONFIG_PLAT_ORION) += mvebu/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
@ -30,6 +31,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_ARCH_SIRF) += sirf/
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
@ -45,6 +47,7 @@ obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o

Просмотреть файл

@ -55,6 +55,30 @@ static unsigned long clk_composite_recalc_rate(struct clk_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 *best_parent_rate,
struct clk **best_parent_p)
{
struct clk_composite *composite = to_clk_composite(hw);
const struct clk_ops *rate_ops = composite->rate_ops;
const struct clk_ops *mux_ops = composite->mux_ops;
struct clk_hw *rate_hw = composite->rate_hw;
struct clk_hw *mux_hw = composite->mux_hw;
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,
best_parent_p);
} 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,
best_parent_p);
} else {
pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
return 0;
}
}
static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
@ -147,6 +171,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
composite->mux_ops = mux_ops;
clk_composite_ops->get_parent = clk_composite_get_parent;
clk_composite_ops->set_parent = clk_composite_set_parent;
if (mux_ops->determine_rate)
clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (rate_hw && rate_ops) {
@ -170,6 +196,8 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
composite->rate_hw = rate_hw;
composite->rate_ops = rate_ops;
clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
if (rate_ops->determine_rate)
clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (gate_hw && gate_ops) {

Просмотреть файл

@ -34,22 +34,31 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
return to_clk_fixed_rate(hw)->fixed_rate;
}
static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw,
unsigned long parent_accuracy)
{
return to_clk_fixed_rate(hw)->fixed_accuracy;
}
const struct clk_ops clk_fixed_rate_ops = {
.recalc_rate = clk_fixed_rate_recalc_rate,
.recalc_accuracy = clk_fixed_rate_recalc_accuracy,
};
EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
/**
* clk_register_fixed_rate - register fixed-rate clock with the clock framework
* clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the
* clock framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
* @flags: framework-specific flags
* @fixed_rate: non-adjustable clock rate
* @fixed_accuracy: non-adjustable clock rate
*/
struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate)
struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
const char *name, const char *parent_name, unsigned long flags,
unsigned long fixed_rate, unsigned long fixed_accuracy)
{
struct clk_fixed_rate *fixed;
struct clk *clk;
@ -70,16 +79,33 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
/* struct clk_fixed_rate assignments */
fixed->fixed_rate = fixed_rate;
fixed->fixed_accuracy = fixed_accuracy;
fixed->hw.init = &init;
/* register the clock */
clk = clk_register(dev, &fixed->hw);
if (IS_ERR(clk))
kfree(fixed);
return clk;
}
EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
/**
* clk_register_fixed_rate - register fixed-rate clock with the clock framework
* @dev: device that is registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
* @flags: framework-specific flags
* @fixed_rate: non-adjustable clock rate
*/
struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
unsigned long fixed_rate)
{
return clk_register_fixed_rate_with_accuracy(dev, name, parent_name,
flags, fixed_rate, 0);
}
EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
#ifdef CONFIG_OF
@ -91,13 +117,18 @@ void of_fixed_clk_setup(struct device_node *node)
struct clk *clk;
const char *clk_name = node->name;
u32 rate;
u32 accuracy = 0;
if (of_property_read_u32(node, "clock-frequency", &rate))
return;
of_property_read_u32(node, "clock-accuracy", &accuracy);
of_property_read_string(node, "clock-output-names", &clk_name);
clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate);
clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
CLK_IS_ROOT, rate,
accuracy);
if (!IS_ERR(clk))
of_clk_add_provider(node, of_clk_src_simple_get, clk);
}

Просмотреть файл

@ -66,7 +66,7 @@ static void max77686_clk_unprepare(struct clk_hw *hw)
MAX77686_REG_32KHZ, max77686->mask, ~max77686->mask);
}
static int max77686_clk_is_enabled(struct clk_hw *hw)
static int max77686_clk_is_prepared(struct clk_hw *hw)
{
struct max77686_clk *max77686 = to_max77686_clk(hw);
int ret;
@ -81,10 +81,17 @@ static int max77686_clk_is_enabled(struct clk_hw *hw)
return val & max77686->mask;
}
static unsigned long max77686_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return 32768;
}
static struct clk_ops max77686_clk_ops = {
.prepare = max77686_clk_prepare,
.unprepare = max77686_clk_unprepare,
.is_enabled = max77686_clk_is_enabled,
.is_prepared = max77686_clk_is_prepared,
.recalc_rate = max77686_recalc_rate,
};
static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
@ -105,38 +112,38 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = {
},
};
static int max77686_clk_register(struct device *dev,
static struct clk *max77686_clk_register(struct device *dev,
struct max77686_clk *max77686)
{
struct clk *clk;
struct clk_hw *hw = &max77686->hw;
clk = clk_register(dev, hw);
if (IS_ERR(clk))
return -ENOMEM;
return clk;
max77686->lookup = kzalloc(sizeof(struct clk_lookup), GFP_KERNEL);
if (!max77686->lookup)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
max77686->lookup->con_id = hw->init->name;
max77686->lookup->clk = clk;
clkdev_add(max77686->lookup);
return 0;
return clk;
}
static int max77686_clk_probe(struct platform_device *pdev)
{
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77686_clk **max77686_clks;
struct max77686_clk *max77686_clks[MAX77686_CLKS_NUM];
struct clk **clocks;
int i, ret;
max77686_clks = devm_kzalloc(&pdev->dev, sizeof(struct max77686_clk *)
clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *)
* MAX77686_CLKS_NUM, GFP_KERNEL);
if (!max77686_clks)
if (!clocks)
return -ENOMEM;
for (i = 0; i < MAX77686_CLKS_NUM; i++) {
@ -151,47 +158,63 @@ static int max77686_clk_probe(struct platform_device *pdev)
max77686_clks[i]->mask = 1 << i;
max77686_clks[i]->hw.init = &max77686_clks_init[i];
ret = max77686_clk_register(&pdev->dev, max77686_clks[i]);
if (ret) {
switch (i) {
case MAX77686_CLK_AP:
dev_err(&pdev->dev, "Fail to register CLK_AP\n");
goto err_clk_ap;
break;
case MAX77686_CLK_CP:
dev_err(&pdev->dev, "Fail to register CLK_CP\n");
goto err_clk_cp;
break;
case MAX77686_CLK_PMIC:
dev_err(&pdev->dev, "Fail to register CLK_PMIC\n");
goto err_clk_pmic;
}
clocks[i] = max77686_clk_register(&pdev->dev, max77686_clks[i]);
if (IS_ERR(clocks[i])) {
ret = PTR_ERR(clocks[i]);
dev_err(&pdev->dev, "failed to register %s\n",
max77686_clks[i]->hw.init->name);
goto err_clocks;
}
}
platform_set_drvdata(pdev, max77686_clks);
platform_set_drvdata(pdev, clocks);
goto out;
if (iodev->dev->of_node) {
struct clk_onecell_data *of_data;
of_data = devm_kzalloc(&pdev->dev,
sizeof(*of_data), GFP_KERNEL);
if (!of_data) {
ret = -ENOMEM;
goto err_clocks;
}
of_data->clks = clocks;
of_data->clk_num = MAX77686_CLKS_NUM;
ret = of_clk_add_provider(iodev->dev->of_node,
of_clk_src_onecell_get, of_data);
if (ret) {
dev_err(&pdev->dev, "failed to register OF clock provider\n");
goto err_clocks;
}
}
return 0;
err_clocks:
for (--i; i >= 0; --i) {
clkdev_drop(max77686_clks[i]->lookup);
clk_unregister(max77686_clks[i]->hw.clk);
}
err_clk_pmic:
clkdev_drop(max77686_clks[MAX77686_CLK_CP]->lookup);
kfree(max77686_clks[MAX77686_CLK_CP]->hw.clk);
err_clk_cp:
clkdev_drop(max77686_clks[MAX77686_CLK_AP]->lookup);
kfree(max77686_clks[MAX77686_CLK_AP]->hw.clk);
err_clk_ap:
out:
return ret;
}
static int max77686_clk_remove(struct platform_device *pdev)
{
struct max77686_clk **max77686_clks = platform_get_drvdata(pdev);
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct clk **clocks = platform_get_drvdata(pdev);
int i;
if (iodev->dev->of_node)
of_clk_del_provider(iodev->dev->of_node);
for (i = 0; i < MAX77686_CLKS_NUM; i++) {
clkdev_drop(max77686_clks[i]->lookup);
kfree(max77686_clks[i]->hw.clk);
struct clk_hw *hw = __clk_get_hw(clocks[i]);
struct max77686_clk *max77686 = to_max77686_clk(hw);
clkdev_drop(max77686->lookup);
clk_unregister(clocks[i]);
}
return 0;
}

531
drivers/clk/clk-si570.c Normal file
Просмотреть файл

@ -0,0 +1,531 @@
/*
* Driver for Silicon Labs Si570/Si571 Programmable XO/VCXO
*
* Copyright (C) 2010, 2011 Ericsson AB.
* Copyright (C) 2011 Guenter Roeck.
* Copyright (C) 2011 - 2013 Xilinx Inc.
*
* Author: Guenter Roeck <guenter.roeck@ericsson.com>
* Sören Brinkmann <soren.brinkmann@xilinx.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/slab.h>
/* Si570 registers */
#define SI570_REG_HS_N1 7
#define SI570_REG_N1_RFREQ0 8
#define SI570_REG_RFREQ1 9
#define SI570_REG_RFREQ2 10
#define SI570_REG_RFREQ3 11
#define SI570_REG_RFREQ4 12
#define SI570_REG_CONTROL 135
#define SI570_REG_FREEZE_DCO 137
#define SI570_DIV_OFFSET_7PPM 6
#define HS_DIV_SHIFT 5
#define HS_DIV_MASK 0xe0
#define HS_DIV_OFFSET 4
#define N1_6_2_MASK 0x1f
#define N1_1_0_MASK 0xc0
#define RFREQ_37_32_MASK 0x3f
#define SI570_MIN_FREQ 10000000L
#define SI570_MAX_FREQ 1417500000L
#define SI598_MAX_FREQ 525000000L
#define FDCO_MIN 4850000000LL
#define FDCO_MAX 5670000000LL
#define SI570_CNTRL_RECALL (1 << 0)
#define SI570_CNTRL_FREEZE_M (1 << 5)
#define SI570_CNTRL_NEWFREQ (1 << 6)
#define SI570_FREEZE_DCO (1 << 4)
/**
* struct clk_si570:
* @hw: Clock hw struct
* @regmap: Device's regmap
* @div_offset: Rgister offset for dividers
* @max_freq: Maximum frequency for this device
* @fxtal: Factory xtal frequency
* @n1: Clock divider N1
* @hs_div: Clock divider HSDIV
* @rfreq: Clock multiplier RFREQ
* @frequency: Current output frequency
* @i2c_client: I2C client pointer
*/
struct clk_si570 {
struct clk_hw hw;
struct regmap *regmap;
unsigned int div_offset;
u64 max_freq;
u64 fxtal;
unsigned int n1;
unsigned int hs_div;
u64 rfreq;
u64 frequency;
struct i2c_client *i2c_client;
};
#define to_clk_si570(_hw) container_of(_hw, struct clk_si570, hw)
enum clk_si570_variant {
si57x,
si59x
};
/**
* si570_get_divs() - Read clock dividers from HW
* @data: Pointer to struct clk_si570
* @rfreq: Fractional multiplier (output)
* @n1: Divider N1 (output)
* @hs_div: Divider HSDIV (output)
* Returns 0 on success, negative errno otherwise.
*
* Retrieve clock dividers and multipliers from the HW.
*/
static int si570_get_divs(struct clk_si570 *data, u64 *rfreq,
unsigned int *n1, unsigned int *hs_div)
{
int err;
u8 reg[6];
u64 tmp;
err = regmap_bulk_read(data->regmap, SI570_REG_HS_N1 + data->div_offset,
reg, ARRAY_SIZE(reg));
if (err)
return err;
*hs_div = ((reg[0] & HS_DIV_MASK) >> HS_DIV_SHIFT) + HS_DIV_OFFSET;
*n1 = ((reg[0] & N1_6_2_MASK) << 2) + ((reg[1] & N1_1_0_MASK) >> 6) + 1;
/* Handle invalid cases */
if (*n1 > 1)
*n1 &= ~1;
tmp = reg[1] & RFREQ_37_32_MASK;
tmp = (tmp << 8) + reg[2];
tmp = (tmp << 8) + reg[3];
tmp = (tmp << 8) + reg[4];
tmp = (tmp << 8) + reg[5];
*rfreq = tmp;
return 0;
}
/**
* si570_get_defaults() - Get default values
* @data: Driver data structure
* @fout: Factory frequency output
* Returns 0 on success, negative errno otherwise.
*/
static int si570_get_defaults(struct clk_si570 *data, u64 fout)
{
int err;
u64 fdco;
regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL);
err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
if (err)
return err;
/*
* Accept optional precision loss to avoid arithmetic overflows.
* Acceptable per Silicon Labs Application Note AN334.
*/
fdco = fout * data->n1 * data->hs_div;
if (fdco >= (1LL << 36))
data->fxtal = div64_u64(fdco << 24, data->rfreq >> 4);
else
data->fxtal = div64_u64(fdco << 28, data->rfreq);
data->frequency = fout;
return 0;
}
/**
* si570_update_rfreq() - Update clock multiplier
* @data: Driver data structure
* Passes on regmap_bulk_write() return value.
*/
static int si570_update_rfreq(struct clk_si570 *data)
{
u8 reg[5];
reg[0] = ((data->n1 - 1) << 6) |
((data->rfreq >> 32) & RFREQ_37_32_MASK);
reg[1] = (data->rfreq >> 24) & 0xff;
reg[2] = (data->rfreq >> 16) & 0xff;
reg[3] = (data->rfreq >> 8) & 0xff;
reg[4] = data->rfreq & 0xff;
return regmap_bulk_write(data->regmap, SI570_REG_N1_RFREQ0 +
data->div_offset, reg, ARRAY_SIZE(reg));
}
/**
* si570_calc_divs() - Caluclate clock dividers
* @frequency: Target frequency
* @data: Driver data structure
* @out_rfreq: RFREG fractional multiplier (output)
* @out_n1: Clock divider N1 (output)
* @out_hs_div: Clock divider HSDIV (output)
* Returns 0 on success, negative errno otherwise.
*
* Calculate the clock dividers (@out_hs_div, @out_n1) and clock multiplier
* (@out_rfreq) for a given target @frequency.
*/
static int si570_calc_divs(unsigned long frequency, struct clk_si570 *data,
u64 *out_rfreq, unsigned int *out_n1, unsigned int *out_hs_div)
{
int i;
unsigned int n1, hs_div;
u64 fdco, best_fdco = ULLONG_MAX;
static const uint8_t si570_hs_div_values[] = { 11, 9, 7, 6, 5, 4 };
for (i = 0; i < ARRAY_SIZE(si570_hs_div_values); i++) {
hs_div = si570_hs_div_values[i];
/* Calculate lowest possible value for n1 */
n1 = div_u64(div_u64(FDCO_MIN, hs_div), frequency);
if (!n1 || (n1 & 1))
n1++;
while (n1 <= 128) {
fdco = (u64)frequency * (u64)hs_div * (u64)n1;
if (fdco > FDCO_MAX)
break;
if (fdco >= FDCO_MIN && fdco < best_fdco) {
*out_n1 = n1;
*out_hs_div = hs_div;
*out_rfreq = div64_u64(fdco << 28, data->fxtal);
best_fdco = fdco;
}
n1 += (n1 == 1 ? 1 : 2);
}
}
if (best_fdco == ULLONG_MAX)
return -EINVAL;
return 0;
}
static unsigned long si570_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
int err;
u64 rfreq, rate;
unsigned int n1, hs_div;
struct clk_si570 *data = to_clk_si570(hw);
err = si570_get_divs(data, &rfreq, &n1, &hs_div);
if (err) {
dev_err(&data->i2c_client->dev, "unable to recalc rate\n");
return data->frequency;
}
rfreq = div_u64(rfreq, hs_div * n1);
rate = (data->fxtal * rfreq) >> 28;
return rate;
}
static long si570_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
int err;
u64 rfreq;
unsigned int n1, hs_div;
struct clk_si570 *data = to_clk_si570(hw);
if (!rate)
return 0;
if (div64_u64(abs(rate - data->frequency) * 10000LL,
data->frequency) < 35) {
rfreq = div64_u64((data->rfreq * rate) +
div64_u64(data->frequency, 2), data->frequency);
n1 = data->n1;
hs_div = data->hs_div;
} else {
err = si570_calc_divs(rate, data, &rfreq, &n1, &hs_div);
if (err) {
dev_err(&data->i2c_client->dev,
"unable to round rate\n");
return 0;
}
}
return rate;
}
/**
* si570_set_frequency() - Adjust output frequency
* @data: Driver data structure
* @frequency: Target frequency
* Returns 0 on success.
*
* Update output frequency for big frequency changes (> 3,500 ppm).
*/
static int si570_set_frequency(struct clk_si570 *data, unsigned long frequency)
{
int err;
err = si570_calc_divs(frequency, data, &data->rfreq, &data->n1,
&data->hs_div);
if (err)
return err;
/*
* The DCO reg should be accessed with a read-modify-write operation
* per AN334
*/
regmap_write(data->regmap, SI570_REG_FREEZE_DCO, SI570_FREEZE_DCO);
regmap_write(data->regmap, SI570_REG_HS_N1 + data->div_offset,
((data->hs_div - HS_DIV_OFFSET) << HS_DIV_SHIFT) |
(((data->n1 - 1) >> 2) & N1_6_2_MASK));
si570_update_rfreq(data);
regmap_write(data->regmap, SI570_REG_FREEZE_DCO, 0);
regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_NEWFREQ);
/* Applying a new frequency can take up to 10ms */
usleep_range(10000, 12000);
return 0;
}
/**
* si570_set_frequency_small() - Adjust output frequency
* @data: Driver data structure
* @frequency: Target frequency
* Returns 0 on success.
*
* Update output frequency for small frequency changes (< 3,500 ppm).
*/
static int si570_set_frequency_small(struct clk_si570 *data,
unsigned long frequency)
{
/*
* This is a re-implementation of DIV_ROUND_CLOSEST
* using the div64_u64 function lieu of letting the compiler
* insert EABI calls
*/
data->rfreq = div64_u64((data->rfreq * frequency) +
div_u64(data->frequency, 2), data->frequency);
regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_FREEZE_M);
si570_update_rfreq(data);
regmap_write(data->regmap, SI570_REG_CONTROL, 0);
/* Applying a new frequency (small change) can take up to 100us */
usleep_range(100, 200);
return 0;
}
static int si570_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_si570 *data = to_clk_si570(hw);
struct i2c_client *client = data->i2c_client;
int err;
if (rate < SI570_MIN_FREQ || rate > data->max_freq) {
dev_err(&client->dev,
"requested frequency %lu Hz is out of range\n", rate);
return -EINVAL;
}
if (div64_u64(abs(rate - data->frequency) * 10000LL,
data->frequency) < 35)
err = si570_set_frequency_small(data, rate);
else
err = si570_set_frequency(data, rate);
if (err)
return err;
data->frequency = rate;
return 0;
}
static const struct clk_ops si570_clk_ops = {
.recalc_rate = si570_recalc_rate,
.round_rate = si570_round_rate,
.set_rate = si570_set_rate,
};
static bool si570_regmap_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case SI570_REG_CONTROL:
return true;
default:
return false;
}
}
static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg)
{
switch (reg) {
case SI570_REG_HS_N1 ... (SI570_REG_RFREQ4 + SI570_DIV_OFFSET_7PPM):
case SI570_REG_CONTROL:
case SI570_REG_FREEZE_DCO:
return true;
default:
return false;
}
}
static struct regmap_config si570_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.max_register = 137,
.writeable_reg = si570_regmap_is_writeable,
.volatile_reg = si570_regmap_is_volatile,
};
static int si570_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct clk_si570 *data;
struct clk_init_data init;
struct clk *clk;
u32 initial_fout, factory_fout, stability;
int err;
enum clk_si570_variant variant = id->driver_data;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
init.ops = &si570_clk_ops;
init.flags = CLK_IS_ROOT;
init.num_parents = 0;
data->hw.init = &init;
data->i2c_client = client;
if (variant == si57x) {
err = of_property_read_u32(client->dev.of_node,
"temperature-stability", &stability);
if (err) {
dev_err(&client->dev,
"'temperature-stability' property missing\n");
return err;
}
/* adjust register offsets for 7ppm devices */
if (stability == 7)
data->div_offset = SI570_DIV_OFFSET_7PPM;
data->max_freq = SI570_MAX_FREQ;
} else {
data->max_freq = SI598_MAX_FREQ;
}
if (of_property_read_string(client->dev.of_node, "clock-output-names",
&init.name))
init.name = client->dev.of_node->name;
err = of_property_read_u32(client->dev.of_node, "factory-fout",
&factory_fout);
if (err) {
dev_err(&client->dev, "'factory-fout' property missing\n");
return err;
}
data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
if (IS_ERR(data->regmap)) {
dev_err(&client->dev, "failed to allocate register map\n");
return PTR_ERR(data->regmap);
}
i2c_set_clientdata(client, data);
err = si570_get_defaults(data, factory_fout);
if (err)
return err;
clk = devm_clk_register(&client->dev, &data->hw);
if (IS_ERR(clk)) {
dev_err(&client->dev, "clock registration failed\n");
return PTR_ERR(clk);
}
err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get,
clk);
if (err) {
dev_err(&client->dev, "unable to add clk provider\n");
return err;
}
/* Read the requested initial output frequency from device tree */
if (!of_property_read_u32(client->dev.of_node, "clock-frequency",
&initial_fout)) {
err = clk_set_rate(clk, initial_fout);
if (err) {
of_clk_del_provider(client->dev.of_node);
return err;
}
}
/* Display a message indicating that we've successfully registered */
dev_info(&client->dev, "registered, current frequency %llu Hz\n",
data->frequency);
return 0;
}
static int si570_remove(struct i2c_client *client)
{
of_clk_del_provider(client->dev.of_node);
return 0;
}
static const struct i2c_device_id si570_id[] = {
{ "si570", si57x },
{ "si571", si57x },
{ "si598", si59x },
{ "si599", si59x },
{ }
};
MODULE_DEVICE_TABLE(i2c, si570_id);
static const struct of_device_id clk_si570_of_match[] = {
{ .compatible = "silabs,si570" },
{ .compatible = "silabs,si571" },
{ .compatible = "silabs,si598" },
{ .compatible = "silabs,si599" },
{ },
};
MODULE_DEVICE_TABLE(of, clk_si570_of_match);
static struct i2c_driver si570_driver = {
.driver = {
.name = "si570",
.of_match_table = clk_si570_of_match,
},
.probe = si570_probe,
.remove = si570_remove,
.id_table = si570_id,
};
module_i2c_driver(si570_driver);
MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com");
MODULE_DESCRIPTION("Si570 driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -641,7 +641,7 @@ static unsigned long vtwm_pll_recalc_rate(struct clk_hw *hw,
return pll_freq;
}
const struct clk_ops vtwm_pll_ops = {
static const struct clk_ops vtwm_pll_ops = {
.round_rate = vtwm_pll_round_rate,
.set_rate = vtwm_pll_set_rate,
.recalc_rate = vtwm_pll_recalc_rate,

Просмотреть файл

@ -21,6 +21,8 @@
#include <linux/init.h>
#include <linux/sched.h>
#include "clk.h"
static DEFINE_SPINLOCK(enable_lock);
static DEFINE_MUTEX(prepare_lock);
@ -92,7 +94,7 @@ static void clk_enable_unlock(unsigned long flags)
/*** debugfs support ***/
#ifdef CONFIG_COMMON_CLK_DEBUG
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
static struct dentry *rootdir;
@ -104,10 +106,11 @@ static void clk_summary_show_one(struct seq_file *s, struct clk *c, int level)
if (!c)
return;
seq_printf(s, "%*s%-*s %-11d %-12d %-10lu",
seq_printf(s, "%*s%-*s %-11d %-12d %-10lu %-11lu",
level * 3 + 1, "",
30 - level * 3, c->name,
c->enable_count, c->prepare_count, clk_get_rate(c));
c->enable_count, c->prepare_count, clk_get_rate(c),
clk_get_accuracy(c));
seq_printf(s, "\n");
}
@ -129,8 +132,8 @@ static int clk_summary_show(struct seq_file *s, void *data)
{
struct clk *c;
seq_printf(s, " clock enable_cnt prepare_cnt rate\n");
seq_printf(s, "---------------------------------------------------------------------\n");
seq_printf(s, " clock enable_cnt prepare_cnt rate accuracy\n");
seq_printf(s, "---------------------------------------------------------------------------------\n");
clk_prepare_lock();
@ -167,6 +170,7 @@ static void clk_dump_one(struct seq_file *s, struct clk *c, int level)
seq_printf(s, "\"enable_count\": %d,", c->enable_count);
seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
seq_printf(s, "\"accuracy\": %lu", clk_get_accuracy(c));
}
static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
@ -248,6 +252,11 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
if (!d)
goto err_out;
d = debugfs_create_u32("clk_accuracy", S_IRUGO, clk->dentry,
(u32 *)&clk->accuracy);
if (!d)
goto err_out;
d = debugfs_create_x32("clk_flags", S_IRUGO, clk->dentry,
(u32 *)&clk->flags);
if (!d)
@ -272,7 +281,8 @@ static int clk_debug_create_one(struct clk *clk, struct dentry *pdentry)
goto out;
err_out:
debugfs_remove(clk->dentry);
debugfs_remove_recursive(clk->dentry);
clk->dentry = NULL;
out:
return ret;
}
@ -342,6 +352,21 @@ out:
return ret;
}
/**
* clk_debug_unregister - remove a clk node from the debugfs clk tree
* @clk: the clk being removed from the debugfs clk tree
*
* Dynamically removes a clk and all it's children clk nodes from the
* debugfs clk tree if clk->dentry points to debugfs created by
* clk_debug_register in __clk_init.
*
* Caller must hold prepare_lock.
*/
static void clk_debug_unregister(struct clk *clk)
{
debugfs_remove_recursive(clk->dentry);
}
/**
* clk_debug_reparent - reparent clk node in the debugfs clk tree
* @clk: the clk being reparented
@ -432,6 +457,9 @@ static inline int clk_debug_register(struct clk *clk) { return 0; }
static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent)
{
}
static inline void clk_debug_unregister(struct clk *clk)
{
}
#endif
/* caller must hold prepare_lock */
@ -602,6 +630,14 @@ out:
return ret;
}
unsigned long __clk_get_accuracy(struct clk *clk)
{
if (!clk)
return 0;
return clk->accuracy;
}
unsigned long __clk_get_flags(struct clk *clk)
{
return !clk ? 0 : clk->flags;
@ -1015,6 +1051,59 @@ static int __clk_notify(struct clk *clk, unsigned long msg,
return ret;
}
/**
* __clk_recalc_accuracies
* @clk: first clk in the subtree
*
* Walks the subtree of clks starting with clk and recalculates accuracies as
* it goes. Note that if a clk does not implement the .recalc_accuracy
* callback then it is assumed that the clock will take on the accuracy of it's
* parent.
*
* Caller must hold prepare_lock.
*/
static void __clk_recalc_accuracies(struct clk *clk)
{
unsigned long parent_accuracy = 0;
struct clk *child;
if (clk->parent)
parent_accuracy = clk->parent->accuracy;
if (clk->ops->recalc_accuracy)
clk->accuracy = clk->ops->recalc_accuracy(clk->hw,
parent_accuracy);
else
clk->accuracy = parent_accuracy;
hlist_for_each_entry(child, &clk->children, child_node)
__clk_recalc_accuracies(child);
}
/**
* clk_get_accuracy - return the accuracy of clk
* @clk: the clk whose accuracy is being returned
*
* Simply returns the cached accuracy of the clk, unless
* CLK_GET_ACCURACY_NOCACHE flag is set, which means a recalc_rate will be
* issued.
* If clk is NULL then returns 0.
*/
long clk_get_accuracy(struct clk *clk)
{
unsigned long accuracy;
clk_prepare_lock();
if (clk && (clk->flags & CLK_GET_ACCURACY_NOCACHE))
__clk_recalc_accuracies(clk);
accuracy = __clk_get_accuracy(clk);
clk_prepare_unlock();
return accuracy;
}
EXPORT_SYMBOL_GPL(clk_get_accuracy);
/**
* __clk_recalc_rates
* @clk: first clk in the subtree
@ -1129,10 +1218,9 @@ static void clk_reparent(struct clk *clk, struct clk *new_parent)
clk->parent = new_parent;
}
static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
static struct clk *__clk_set_parent_before(struct clk *clk, struct clk *parent)
{
unsigned long flags;
int ret = 0;
struct clk *old_parent = clk->parent;
/*
@ -1163,6 +1251,34 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
clk_reparent(clk, parent);
clk_enable_unlock(flags);
return old_parent;
}
static void __clk_set_parent_after(struct clk *clk, struct clk *parent,
struct clk *old_parent)
{
/*
* Finish the migration of prepare state and undo the changes done
* for preventing a race with clk_enable().
*/
if (clk->prepare_count) {
clk_disable(clk);
clk_disable(old_parent);
__clk_unprepare(old_parent);
}
/* update debugfs with new clk tree topology */
clk_debug_reparent(clk, parent);
}
static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
{
unsigned long flags;
int ret = 0;
struct clk *old_parent;
old_parent = __clk_set_parent_before(clk, parent);
/* change clock input source */
if (parent && clk->ops->set_parent)
ret = clk->ops->set_parent(clk->hw, p_index);
@ -1180,18 +1296,8 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
return ret;
}
/*
* Finish the migration of prepare state and undo the changes done
* for preventing a race with clk_enable().
*/
if (clk->prepare_count) {
clk_disable(clk);
clk_disable(old_parent);
__clk_unprepare(old_parent);
}
__clk_set_parent_after(clk, parent, old_parent);
/* update debugfs with new clk tree topology */
clk_debug_reparent(clk, parent);
return 0;
}
@ -1376,17 +1482,32 @@ static void clk_change_rate(struct clk *clk)
struct clk *child;
unsigned long old_rate;
unsigned long best_parent_rate = 0;
bool skip_set_rate = false;
struct clk *old_parent;
old_rate = clk->rate;
/* set parent */
if (clk->new_parent && clk->new_parent != clk->parent)
__clk_set_parent(clk, clk->new_parent, clk->new_parent_index);
if (clk->parent)
if (clk->new_parent)
best_parent_rate = clk->new_parent->rate;
else if (clk->parent)
best_parent_rate = clk->parent->rate;
if (clk->ops->set_rate)
if (clk->new_parent && clk->new_parent != clk->parent) {
old_parent = __clk_set_parent_before(clk, clk->new_parent);
if (clk->ops->set_rate_and_parent) {
skip_set_rate = true;
clk->ops->set_rate_and_parent(clk->hw, clk->new_rate,
best_parent_rate,
clk->new_parent_index);
} else if (clk->ops->set_parent) {
clk->ops->set_parent(clk->hw, clk->new_parent_index);
}
__clk_set_parent_after(clk, clk->new_parent, old_parent);
}
if (!skip_set_rate && clk->ops->set_rate)
clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);
if (clk->ops->recalc_rate)
@ -1551,6 +1672,7 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent)
{
clk_reparent(clk, new_parent);
clk_debug_reparent(clk, new_parent);
__clk_recalc_accuracies(clk);
__clk_recalc_rates(clk, POST_RATE_CHANGE);
}
@ -1621,11 +1743,13 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
/* do the re-parent */
ret = __clk_set_parent(clk, parent, p_index);
/* propagate rate recalculation accordingly */
if (ret)
/* propagate rate an accuracy recalculation accordingly */
if (ret) {
__clk_recalc_rates(clk, ABORT_RATE_CHANGE);
else
} else {
__clk_recalc_rates(clk, POST_RATE_CHANGE);
__clk_recalc_accuracies(clk);
}
out:
clk_prepare_unlock();
@ -1678,6 +1802,14 @@ int __clk_init(struct device *dev, struct clk *clk)
goto out;
}
if (clk->ops->set_rate_and_parent &&
!(clk->ops->set_parent && clk->ops->set_rate)) {
pr_warn("%s: %s must implement .set_parent & .set_rate\n",
__func__, clk->name);
ret = -EINVAL;
goto out;
}
/* throw a WARN if any entries in parent_names are NULL */
for (i = 0; i < clk->num_parents; i++)
WARN(!clk->parent_names[i],
@ -1729,6 +1861,21 @@ int __clk_init(struct device *dev, struct clk *clk)
else
hlist_add_head(&clk->child_node, &clk_orphan_list);
/*
* Set clk's accuracy. The preferred method is to use
* .recalc_accuracy. For simple clocks and lazy developers the default
* fallback is to use the parent's accuracy. If a clock doesn't have a
* parent (or is orphaned) then accuracy is set to zero (perfect
* clock).
*/
if (clk->ops->recalc_accuracy)
clk->accuracy = clk->ops->recalc_accuracy(clk->hw,
__clk_get_accuracy(clk->parent));
else if (clk->parent)
clk->accuracy = clk->parent->accuracy;
else
clk->accuracy = 0;
/*
* Set clk's rate. The preferred method is to use .recalc_rate. For
* simple clocks and lazy developers the default fallback is to use the
@ -1743,6 +1890,7 @@ int __clk_init(struct device *dev, struct clk *clk)
else
clk->rate = 0;
clk_debug_register(clk);
/*
* walk the list of orphan clocks and reparent any that are children of
* this clock
@ -1773,8 +1921,7 @@ int __clk_init(struct device *dev, struct clk *clk)
if (clk->ops->init)
clk->ops->init(clk->hw);
clk_debug_register(clk);
kref_init(&clk->ref);
out:
clk_prepare_unlock();
@ -1810,6 +1957,10 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
clk->flags = hw->init->flags;
clk->parent_names = hw->init->parent_names;
clk->num_parents = hw->init->num_parents;
if (dev && dev->driver)
clk->owner = dev->driver->owner;
else
clk->owner = NULL;
ret = __clk_init(dev, clk);
if (ret)
@ -1830,6 +1981,8 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
goto fail_name;
}
clk->ops = hw->init->ops;
if (dev && dev->driver)
clk->owner = dev->driver->owner;
clk->hw = hw;
clk->flags = hw->init->flags;
clk->num_parents = hw->init->num_parents;
@ -1904,13 +2057,104 @@ fail_out:
}
EXPORT_SYMBOL_GPL(clk_register);
/*
* Free memory allocated for a clock.
* Caller must hold prepare_lock.
*/
static void __clk_release(struct kref *ref)
{
struct clk *clk = container_of(ref, struct clk, ref);
int i = clk->num_parents;
kfree(clk->parents);
while (--i >= 0)
kfree(clk->parent_names[i]);
kfree(clk->parent_names);
kfree(clk->name);
kfree(clk);
}
/*
* Empty clk_ops for unregistered clocks. These are used temporarily
* after clk_unregister() was called on a clock and until last clock
* consumer calls clk_put() and the struct clk object is freed.
*/
static int clk_nodrv_prepare_enable(struct clk_hw *hw)
{
return -ENXIO;
}
static void clk_nodrv_disable_unprepare(struct clk_hw *hw)
{
WARN_ON_ONCE(1);
}
static int clk_nodrv_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return -ENXIO;
}
static int clk_nodrv_set_parent(struct clk_hw *hw, u8 index)
{
return -ENXIO;
}
static const struct clk_ops clk_nodrv_ops = {
.enable = clk_nodrv_prepare_enable,
.disable = clk_nodrv_disable_unprepare,
.prepare = clk_nodrv_prepare_enable,
.unprepare = clk_nodrv_disable_unprepare,
.set_rate = clk_nodrv_set_rate,
.set_parent = clk_nodrv_set_parent,
};
/**
* clk_unregister - unregister a currently registered clock
* @clk: clock to unregister
*
* Currently unimplemented.
*/
void clk_unregister(struct clk *clk) {}
void clk_unregister(struct clk *clk)
{
unsigned long flags;
if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
return;
clk_prepare_lock();
if (clk->ops == &clk_nodrv_ops) {
pr_err("%s: unregistered clock: %s\n", __func__, clk->name);
goto out;
}
/*
* Assign empty clock ops for consumers that might still hold
* a reference to this clock.
*/
flags = clk_enable_lock();
clk->ops = &clk_nodrv_ops;
clk_enable_unlock(flags);
if (!hlist_empty(&clk->children)) {
struct clk *child;
/* Reparent all children to the orphan list. */
hlist_for_each_entry(child, &clk->children, child_node)
clk_set_parent(child, NULL);
}
clk_debug_unregister(clk);
hlist_del_init(&clk->child_node);
if (clk->prepare_count)
pr_warn("%s: unregistering prepared clock: %s\n",
__func__, clk->name);
kref_put(&clk->ref, __clk_release);
out:
clk_prepare_unlock();
}
EXPORT_SYMBOL_GPL(clk_unregister);
static void devm_clk_release(struct device *dev, void *res)
@ -1970,6 +2214,31 @@ void devm_clk_unregister(struct device *dev, struct clk *clk)
}
EXPORT_SYMBOL_GPL(devm_clk_unregister);
/*
* clkdev helpers
*/
int __clk_get(struct clk *clk)
{
if (clk && !try_module_get(clk->owner))
return 0;
kref_get(&clk->ref);
return 1;
}
void __clk_put(struct clk *clk)
{
if (WARN_ON_ONCE(IS_ERR(clk)))
return;
clk_prepare_lock();
kref_put(&clk->ref, __clk_release);
clk_prepare_unlock();
if (clk)
module_put(clk->owner);
}
/*** clk rate change notifiers ***/
/**
@ -2110,7 +2379,18 @@ static const struct of_device_id __clk_of_table_sentinel
__used __section(__clk_of_table_end);
static LIST_HEAD(of_clk_providers);
static DEFINE_MUTEX(of_clk_lock);
static DEFINE_MUTEX(of_clk_mutex);
/* of_clk_provider list locking helpers */
void of_clk_lock(void)
{
mutex_lock(&of_clk_mutex);
}
void of_clk_unlock(void)
{
mutex_unlock(&of_clk_mutex);
}
struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
void *data)
@ -2154,9 +2434,9 @@ int of_clk_add_provider(struct device_node *np,
cp->data = data;
cp->get = clk_src_get;
mutex_lock(&of_clk_lock);
mutex_lock(&of_clk_mutex);
list_add(&cp->link, &of_clk_providers);
mutex_unlock(&of_clk_lock);
mutex_unlock(&of_clk_mutex);
pr_debug("Added clock from %s\n", np->full_name);
return 0;
@ -2171,7 +2451,7 @@ void of_clk_del_provider(struct device_node *np)
{
struct of_clk_provider *cp;
mutex_lock(&of_clk_lock);
mutex_lock(&of_clk_mutex);
list_for_each_entry(cp, &of_clk_providers, link) {
if (cp->node == np) {
list_del(&cp->link);
@ -2180,24 +2460,33 @@ void of_clk_del_provider(struct device_node *np)
break;
}
}
mutex_unlock(&of_clk_lock);
mutex_unlock(&of_clk_mutex);
}
EXPORT_SYMBOL_GPL(of_clk_del_provider);
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
struct of_clk_provider *provider;
struct clk *clk = ERR_PTR(-ENOENT);
/* Check if we have such a provider in our array */
mutex_lock(&of_clk_lock);
list_for_each_entry(provider, &of_clk_providers, link) {
if (provider->node == clkspec->np)
clk = provider->get(clkspec, provider->data);
if (!IS_ERR(clk))
break;
}
mutex_unlock(&of_clk_lock);
return clk;
}
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
struct clk *clk;
mutex_lock(&of_clk_mutex);
clk = __of_clk_get_from_provider(clkspec);
mutex_unlock(&of_clk_mutex);
return clk;
}

16
drivers/clk/clk.h Normal file
Просмотреть файл

@ -0,0 +1,16 @@
/*
* linux/drivers/clk/clk.h
*
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
* Sylwester Nawrocki <s.nawrocki@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec);
void of_clk_lock(void);
void of_clk_unlock(void);
#endif

Просмотреть файл

@ -21,6 +21,8 @@
#include <linux/clkdev.h>
#include <linux/of.h>
#include "clk.h"
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
@ -39,7 +41,13 @@ struct clk *of_clk_get(struct device_node *np, int index)
if (rc)
return ERR_PTR(rc);
clk = of_clk_get_from_provider(&clkspec);
of_clk_lock();
clk = __of_clk_get_from_provider(&clkspec);
if (!IS_ERR(clk) && !__clk_get(clk))
clk = ERR_PTR(-ENOENT);
of_clk_unlock();
of_node_put(clkspec.np);
return clk;
}
@ -157,7 +165,7 @@ struct clk *clk_get(struct device *dev, const char *con_id)
if (dev) {
clk = of_clk_get_by_name(dev->of_node, con_id);
if (!IS_ERR(clk) && __clk_get(clk))
if (!IS_ERR(clk))
return clk;
}

Просмотреть файл

@ -0,0 +1,5 @@
#
# Hisilicon Clock specific Makefile
#
obj-y += clk.o clkgate-separated.o clk-hi3620.o

Просмотреть файл

@ -0,0 +1,242 @@
/*
* Hisilicon Hi3620 clock driver
*
* Copyright (c) 2012-2013 Hisilicon Limited.
* Copyright (c) 2012-2013 Linaro Limited.
*
* Author: Haojian Zhuang <haojian.zhuang@linaro.org>
* Xin Li <li.xin@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <dt-bindings/clock/hi3620-clock.h>
#include "clk.h"
/* clock parent list */
static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", };
static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", };
static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", };
static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", };
static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", };
static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", };
static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", };
static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", };
static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", };
static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", };
static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", };
static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", };
static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", };
static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", };
static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", };
static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", };
static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", };
static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", };
/* share axi parent */
static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", };
static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", };
static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", };
static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", };
static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4",
"armpll3", "armpll5", };
static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4",
"armpll3", "armpll5", };
static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", };
static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", };
static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", };
/* fixed rate clocks */
static struct hisi_fixed_rate_clock hi3620_fixed_rate_clks[] __initdata = {
{ HI3620_OSC32K, "osc32k", NULL, CLK_IS_ROOT, 32768, },
{ HI3620_OSC26M, "osc26m", NULL, CLK_IS_ROOT, 26000000, },
{ HI3620_PCLK, "pclk", NULL, CLK_IS_ROOT, 26000000, },
{ HI3620_PLL_ARM0, "armpll0", NULL, CLK_IS_ROOT, 1600000000, },
{ HI3620_PLL_ARM1, "armpll1", NULL, CLK_IS_ROOT, 1600000000, },
{ HI3620_PLL_PERI, "armpll2", NULL, CLK_IS_ROOT, 1440000000, },
{ HI3620_PLL_USB, "armpll3", NULL, CLK_IS_ROOT, 1440000000, },
{ HI3620_PLL_HDMI, "armpll4", NULL, CLK_IS_ROOT, 1188000000, },
{ HI3620_PLL_GPU, "armpll5", NULL, CLK_IS_ROOT, 1300000000, },
};
/* fixed factor clocks */
static struct hisi_fixed_factor_clock hi3620_fixed_factor_clks[] __initdata = {
{ HI3620_RCLK_TCXO, "rclk_tcxo", "osc26m", 1, 4, 0, },
{ HI3620_RCLK_CFGAXI, "rclk_cfgaxi", "armpll2", 1, 30, 0, },
{ HI3620_RCLK_PICO, "rclk_pico", "hsic_div", 1, 40, 0, },
};
static struct hisi_mux_clock hi3620_mux_clks[] __initdata = {
{ HI3620_TIMER0_MUX, "timer0_mux", timer0_mux_p, ARRAY_SIZE(timer0_mux_p), CLK_SET_RATE_PARENT, 0, 15, 2, 0, },
{ HI3620_TIMER1_MUX, "timer1_mux", timer1_mux_p, ARRAY_SIZE(timer1_mux_p), CLK_SET_RATE_PARENT, 0, 17, 2, 0, },
{ HI3620_TIMER2_MUX, "timer2_mux", timer2_mux_p, ARRAY_SIZE(timer2_mux_p), CLK_SET_RATE_PARENT, 0, 19, 2, 0, },
{ HI3620_TIMER3_MUX, "timer3_mux", timer3_mux_p, ARRAY_SIZE(timer3_mux_p), CLK_SET_RATE_PARENT, 0, 21, 2, 0, },
{ HI3620_TIMER4_MUX, "timer4_mux", timer4_mux_p, ARRAY_SIZE(timer4_mux_p), CLK_SET_RATE_PARENT, 0x18, 0, 2, 0, },
{ HI3620_TIMER5_MUX, "timer5_mux", timer5_mux_p, ARRAY_SIZE(timer5_mux_p), CLK_SET_RATE_PARENT, 0x18, 2, 2, 0, },
{ HI3620_TIMER6_MUX, "timer6_mux", timer6_mux_p, ARRAY_SIZE(timer6_mux_p), CLK_SET_RATE_PARENT, 0x18, 4, 2, 0, },
{ HI3620_TIMER7_MUX, "timer7_mux", timer7_mux_p, ARRAY_SIZE(timer7_mux_p), CLK_SET_RATE_PARENT, 0x18, 6, 2, 0, },
{ HI3620_TIMER8_MUX, "timer8_mux", timer8_mux_p, ARRAY_SIZE(timer8_mux_p), CLK_SET_RATE_PARENT, 0x18, 8, 2, 0, },
{ HI3620_TIMER9_MUX, "timer9_mux", timer9_mux_p, ARRAY_SIZE(timer9_mux_p), CLK_SET_RATE_PARENT, 0x18, 10, 2, 0, },
{ HI3620_UART0_MUX, "uart0_mux", uart0_mux_p, ARRAY_SIZE(uart0_mux_p), CLK_SET_RATE_PARENT, 0x100, 7, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_UART1_MUX, "uart1_mux", uart1_mux_p, ARRAY_SIZE(uart1_mux_p), CLK_SET_RATE_PARENT, 0x100, 8, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_UART2_MUX, "uart2_mux", uart2_mux_p, ARRAY_SIZE(uart2_mux_p), CLK_SET_RATE_PARENT, 0x100, 9, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_UART3_MUX, "uart3_mux", uart3_mux_p, ARRAY_SIZE(uart3_mux_p), CLK_SET_RATE_PARENT, 0x100, 10, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_UART4_MUX, "uart4_mux", uart4_mux_p, ARRAY_SIZE(uart4_mux_p), CLK_SET_RATE_PARENT, 0x100, 11, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_SPI0_MUX, "spi0_mux", spi0_mux_p, ARRAY_SIZE(spi0_mux_p), CLK_SET_RATE_PARENT, 0x100, 12, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_SPI1_MUX, "spi1_mux", spi1_mux_p, ARRAY_SIZE(spi1_mux_p), CLK_SET_RATE_PARENT, 0x100, 13, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_SPI2_MUX, "spi2_mux", spi2_mux_p, ARRAY_SIZE(spi2_mux_p), CLK_SET_RATE_PARENT, 0x100, 14, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_SAXI_MUX, "saxi_mux", saxi_mux_p, ARRAY_SIZE(saxi_mux_p), CLK_SET_RATE_PARENT, 0x100, 15, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_PWM0_MUX, "pwm0_mux", pwm0_mux_p, ARRAY_SIZE(pwm0_mux_p), CLK_SET_RATE_PARENT, 0x104, 10, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_PWM1_MUX, "pwm1_mux", pwm1_mux_p, ARRAY_SIZE(pwm1_mux_p), CLK_SET_RATE_PARENT, 0x104, 11, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_SD_MUX, "sd_mux", sd_mux_p, ARRAY_SIZE(sd_mux_p), CLK_SET_RATE_PARENT, 0x108, 4, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_MMC1_MUX, "mmc1_mux", mmc1_mux_p, ARRAY_SIZE(mmc1_mux_p), CLK_SET_RATE_PARENT, 0x108, 9, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_MMC1_MUX2, "mmc1_mux2", mmc1_mux2_p, ARRAY_SIZE(mmc1_mux2_p), CLK_SET_RATE_PARENT, 0x108, 10, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_G2D_MUX, "g2d_mux", g2d_mux_p, ARRAY_SIZE(g2d_mux_p), CLK_SET_RATE_PARENT, 0x10c, 5, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_VENC_MUX, "venc_mux", venc_mux_p, ARRAY_SIZE(venc_mux_p), CLK_SET_RATE_PARENT, 0x10c, 11, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_VDEC_MUX, "vdec_mux", vdec_mux_p, ARRAY_SIZE(vdec_mux_p), CLK_SET_RATE_PARENT, 0x110, 5, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_VPP_MUX, "vpp_mux", vpp_mux_p, ARRAY_SIZE(vpp_mux_p), CLK_SET_RATE_PARENT, 0x110, 11, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_EDC0_MUX, "edc0_mux", edc0_mux_p, ARRAY_SIZE(edc0_mux_p), CLK_SET_RATE_PARENT, 0x114, 6, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_LDI0_MUX, "ldi0_mux", ldi0_mux_p, ARRAY_SIZE(ldi0_mux_p), CLK_SET_RATE_PARENT, 0x114, 13, 2, CLK_MUX_HIWORD_MASK, },
{ HI3620_EDC1_MUX, "edc1_mux", edc1_mux_p, ARRAY_SIZE(edc1_mux_p), CLK_SET_RATE_PARENT, 0x118, 6, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_LDI1_MUX, "ldi1_mux", ldi1_mux_p, ARRAY_SIZE(ldi1_mux_p), CLK_SET_RATE_PARENT, 0x118, 14, 2, CLK_MUX_HIWORD_MASK, },
{ HI3620_RCLK_HSIC, "rclk_hsic", rclk_hsic_p, ARRAY_SIZE(rclk_hsic_p), CLK_SET_RATE_PARENT, 0x130, 2, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_MMC2_MUX, "mmc2_mux", mmc2_mux_p, ARRAY_SIZE(mmc2_mux_p), CLK_SET_RATE_PARENT, 0x140, 4, 1, CLK_MUX_HIWORD_MASK, },
{ HI3620_MMC3_MUX, "mmc3_mux", mmc3_mux_p, ARRAY_SIZE(mmc3_mux_p), CLK_SET_RATE_PARENT, 0x140, 9, 1, CLK_MUX_HIWORD_MASK, },
};
static struct hisi_divider_clock hi3620_div_clks[] __initdata = {
{ HI3620_SHAREAXI_DIV, "saxi_div", "saxi_mux", 0, 0x100, 0, 5, CLK_DIVIDER_HIWORD_MASK, NULL, },
{ HI3620_CFGAXI_DIV, "cfgaxi_div", "saxi_div", 0, 0x100, 5, 2, CLK_DIVIDER_HIWORD_MASK, NULL, },
{ HI3620_SD_DIV, "sd_div", "sd_mux", 0, 0x108, 0, 4, CLK_DIVIDER_HIWORD_MASK, NULL, },
{ HI3620_MMC1_DIV, "mmc1_div", "mmc1_mux", 0, 0x108, 5, 4, CLK_DIVIDER_HIWORD_MASK, NULL, },
{ HI3620_HSIC_DIV, "hsic_div", "rclk_hsic", 0, 0x130, 0, 2, CLK_DIVIDER_HIWORD_MASK, NULL, },
{ HI3620_MMC2_DIV, "mmc2_div", "mmc2_mux", 0, 0x140, 0, 4, CLK_DIVIDER_HIWORD_MASK, NULL, },
{ HI3620_MMC3_DIV, "mmc3_div", "mmc3_mux", 0, 0x140, 5, 4, CLK_DIVIDER_HIWORD_MASK, NULL, },
};
static struct hisi_gate_clock hi3620_seperated_gate_clks[] __initdata = {
{ HI3620_TIMERCLK01, "timerclk01", "timer_rclk01", CLK_SET_RATE_PARENT, 0x20, 0, 0, },
{ HI3620_TIMER_RCLK01, "timer_rclk01", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x20, 1, 0, },
{ HI3620_TIMERCLK23, "timerclk23", "timer_rclk23", CLK_SET_RATE_PARENT, 0x20, 2, 0, },
{ HI3620_TIMER_RCLK23, "timer_rclk23", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x20, 3, 0, },
{ HI3620_RTCCLK, "rtcclk", "pclk", CLK_SET_RATE_PARENT, 0x20, 5, 0, },
{ HI3620_KPC_CLK, "kpc_clk", "pclk", CLK_SET_RATE_PARENT, 0x20, 6, 0, },
{ HI3620_GPIOCLK0, "gpioclk0", "pclk", CLK_SET_RATE_PARENT, 0x20, 8, 0, },
{ HI3620_GPIOCLK1, "gpioclk1", "pclk", CLK_SET_RATE_PARENT, 0x20, 9, 0, },
{ HI3620_GPIOCLK2, "gpioclk2", "pclk", CLK_SET_RATE_PARENT, 0x20, 10, 0, },
{ HI3620_GPIOCLK3, "gpioclk3", "pclk", CLK_SET_RATE_PARENT, 0x20, 11, 0, },
{ HI3620_GPIOCLK4, "gpioclk4", "pclk", CLK_SET_RATE_PARENT, 0x20, 12, 0, },
{ HI3620_GPIOCLK5, "gpioclk5", "pclk", CLK_SET_RATE_PARENT, 0x20, 13, 0, },
{ HI3620_GPIOCLK6, "gpioclk6", "pclk", CLK_SET_RATE_PARENT, 0x20, 14, 0, },
{ HI3620_GPIOCLK7, "gpioclk7", "pclk", CLK_SET_RATE_PARENT, 0x20, 15, 0, },
{ HI3620_GPIOCLK8, "gpioclk8", "pclk", CLK_SET_RATE_PARENT, 0x20, 16, 0, },
{ HI3620_GPIOCLK9, "gpioclk9", "pclk", CLK_SET_RATE_PARENT, 0x20, 17, 0, },
{ HI3620_GPIOCLK10, "gpioclk10", "pclk", CLK_SET_RATE_PARENT, 0x20, 18, 0, },
{ HI3620_GPIOCLK11, "gpioclk11", "pclk", CLK_SET_RATE_PARENT, 0x20, 19, 0, },
{ HI3620_GPIOCLK12, "gpioclk12", "pclk", CLK_SET_RATE_PARENT, 0x20, 20, 0, },
{ HI3620_GPIOCLK13, "gpioclk13", "pclk", CLK_SET_RATE_PARENT, 0x20, 21, 0, },
{ HI3620_GPIOCLK14, "gpioclk14", "pclk", CLK_SET_RATE_PARENT, 0x20, 22, 0, },
{ HI3620_GPIOCLK15, "gpioclk15", "pclk", CLK_SET_RATE_PARENT, 0x20, 23, 0, },
{ HI3620_GPIOCLK16, "gpioclk16", "pclk", CLK_SET_RATE_PARENT, 0x20, 24, 0, },
{ HI3620_GPIOCLK17, "gpioclk17", "pclk", CLK_SET_RATE_PARENT, 0x20, 25, 0, },
{ HI3620_GPIOCLK18, "gpioclk18", "pclk", CLK_SET_RATE_PARENT, 0x20, 26, 0, },
{ HI3620_GPIOCLK19, "gpioclk19", "pclk", CLK_SET_RATE_PARENT, 0x20, 27, 0, },
{ HI3620_GPIOCLK20, "gpioclk20", "pclk", CLK_SET_RATE_PARENT, 0x20, 28, 0, },
{ HI3620_GPIOCLK21, "gpioclk21", "pclk", CLK_SET_RATE_PARENT, 0x20, 29, 0, },
{ HI3620_DPHY0_CLK, "dphy0_clk", "osc26m", CLK_SET_RATE_PARENT, 0x30, 15, 0, },
{ HI3620_DPHY1_CLK, "dphy1_clk", "osc26m", CLK_SET_RATE_PARENT, 0x30, 16, 0, },
{ HI3620_DPHY2_CLK, "dphy2_clk", "osc26m", CLK_SET_RATE_PARENT, 0x30, 17, 0, },
{ HI3620_USBPHY_CLK, "usbphy_clk", "rclk_pico", CLK_SET_RATE_PARENT, 0x30, 24, 0, },
{ HI3620_ACP_CLK, "acp_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x30, 28, 0, },
{ HI3620_TIMERCLK45, "timerclk45", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x40, 3, 0, },
{ HI3620_TIMERCLK67, "timerclk67", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x40, 4, 0, },
{ HI3620_TIMERCLK89, "timerclk89", "rclk_tcxo", CLK_SET_RATE_PARENT, 0x40, 5, 0, },
{ HI3620_PWMCLK0, "pwmclk0", "pwm0_mux", CLK_SET_RATE_PARENT, 0x40, 7, 0, },
{ HI3620_PWMCLK1, "pwmclk1", "pwm1_mux", CLK_SET_RATE_PARENT, 0x40, 8, 0, },
{ HI3620_UARTCLK0, "uartclk0", "uart0_mux", CLK_SET_RATE_PARENT, 0x40, 16, 0, },
{ HI3620_UARTCLK1, "uartclk1", "uart1_mux", CLK_SET_RATE_PARENT, 0x40, 17, 0, },
{ HI3620_UARTCLK2, "uartclk2", "uart2_mux", CLK_SET_RATE_PARENT, 0x40, 18, 0, },
{ HI3620_UARTCLK3, "uartclk3", "uart3_mux", CLK_SET_RATE_PARENT, 0x40, 19, 0, },
{ HI3620_UARTCLK4, "uartclk4", "uart4_mux", CLK_SET_RATE_PARENT, 0x40, 20, 0, },
{ HI3620_SPICLK0, "spiclk0", "spi0_mux", CLK_SET_RATE_PARENT, 0x40, 21, 0, },
{ HI3620_SPICLK1, "spiclk1", "spi1_mux", CLK_SET_RATE_PARENT, 0x40, 22, 0, },
{ HI3620_SPICLK2, "spiclk2", "spi2_mux", CLK_SET_RATE_PARENT, 0x40, 23, 0, },
{ HI3620_I2CCLK0, "i2cclk0", "pclk", CLK_SET_RATE_PARENT, 0x40, 24, 0, },
{ HI3620_I2CCLK1, "i2cclk1", "pclk", CLK_SET_RATE_PARENT, 0x40, 25, 0, },
{ HI3620_SCI_CLK, "sci_clk", "osc26m", CLK_SET_RATE_PARENT, 0x40, 26, 0, },
{ HI3620_I2CCLK2, "i2cclk2", "pclk", CLK_SET_RATE_PARENT, 0x40, 28, 0, },
{ HI3620_I2CCLK3, "i2cclk3", "pclk", CLK_SET_RATE_PARENT, 0x40, 29, 0, },
{ HI3620_DDRC_PER_CLK, "ddrc_per_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x50, 9, 0, },
{ HI3620_DMAC_CLK, "dmac_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x50, 10, 0, },
{ HI3620_USB2DVC_CLK, "usb2dvc_clk", "rclk_cfgaxi", CLK_SET_RATE_PARENT, 0x50, 17, 0, },
{ HI3620_SD_CLK, "sd_clk", "sd_div", CLK_SET_RATE_PARENT, 0x50, 20, 0, },
{ HI3620_MMC_CLK1, "mmc_clk1", "mmc1_mux2", CLK_SET_RATE_PARENT, 0x50, 21, 0, },
{ HI3620_MMC_CLK2, "mmc_clk2", "mmc2_div", CLK_SET_RATE_PARENT, 0x50, 22, 0, },
{ HI3620_MMC_CLK3, "mmc_clk3", "mmc3_div", CLK_SET_RATE_PARENT, 0x50, 23, 0, },
{ HI3620_MCU_CLK, "mcu_clk", "acp_clk", CLK_SET_RATE_PARENT, 0x50, 24, 0, },
};
static void __init hi3620_clk_init(struct device_node *np)
{
void __iomem *base;
if (np) {
base = of_iomap(np, 0);
if (!base) {
pr_err("failed to map Hi3620 clock registers\n");
return;
}
} else {
pr_err("failed to find Hi3620 clock node in DTS\n");
return;
}
hisi_clk_init(np, HI3620_NR_CLKS);
hisi_clk_register_fixed_rate(hi3620_fixed_rate_clks,
ARRAY_SIZE(hi3620_fixed_rate_clks),
base);
hisi_clk_register_fixed_factor(hi3620_fixed_factor_clks,
ARRAY_SIZE(hi3620_fixed_factor_clks),
base);
hisi_clk_register_mux(hi3620_mux_clks, ARRAY_SIZE(hi3620_mux_clks),
base);
hisi_clk_register_divider(hi3620_div_clks, ARRAY_SIZE(hi3620_div_clks),
base);
hisi_clk_register_gate_sep(hi3620_seperated_gate_clks,
ARRAY_SIZE(hi3620_seperated_gate_clks),
base);
}
CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);

171
drivers/clk/hisilicon/clk.c Normal file
Просмотреть файл

@ -0,0 +1,171 @@
/*
* Hisilicon clock driver
*
* Copyright (c) 2012-2013 Hisilicon Limited.
* Copyright (c) 2012-2013 Linaro Limited.
*
* Author: Haojian Zhuang <haojian.zhuang@linaro.org>
* Xin Li <li.xin@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include "clk.h"
static DEFINE_SPINLOCK(hisi_clk_lock);
static struct clk **clk_table;
static struct clk_onecell_data clk_data;
void __init hisi_clk_init(struct device_node *np, int nr_clks)
{
clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
if (!clk_table) {
pr_err("%s: could not allocate clock lookup table\n", __func__);
return;
}
clk_data.clks = clk_table;
clk_data.clk_num = nr_clks;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks,
int nums, void __iomem *base)
{
struct clk *clk;
int i;
for (i = 0; i < nums; i++) {
clk = clk_register_fixed_rate(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
clks[i].fixed_rate);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
}
}
void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks,
int nums, void __iomem *base)
{
struct clk *clk;
int i;
for (i = 0; i < nums; i++) {
clk = clk_register_fixed_factor(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags, clks[i].mult,
clks[i].div);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
}
}
void __init hisi_clk_register_mux(struct hisi_mux_clock *clks,
int nums, void __iomem *base)
{
struct clk *clk;
int i;
for (i = 0; i < nums; i++) {
clk = clk_register_mux(NULL, clks[i].name, clks[i].parent_names,
clks[i].num_parents, clks[i].flags,
base + clks[i].offset, clks[i].shift,
clks[i].width, clks[i].mux_flags,
&hisi_clk_lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].alias)
clk_register_clkdev(clk, clks[i].alias, NULL);
clk_table[clks[i].id] = clk;
}
}
void __init hisi_clk_register_divider(struct hisi_divider_clock *clks,
int nums, void __iomem *base)
{
struct clk *clk;
int i;
for (i = 0; i < nums; i++) {
clk = clk_register_divider_table(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
base + clks[i].offset,
clks[i].shift, clks[i].width,
clks[i].div_flags,
clks[i].table,
&hisi_clk_lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].alias)
clk_register_clkdev(clk, clks[i].alias, NULL);
clk_table[clks[i].id] = clk;
}
}
void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks,
int nums, void __iomem *base)
{
struct clk *clk;
int i;
for (i = 0; i < nums; i++) {
clk = hisi_register_clkgate_sep(NULL, clks[i].name,
clks[i].parent_name,
clks[i].flags,
base + clks[i].offset,
clks[i].bit_idx,
clks[i].gate_flags,
&hisi_clk_lock);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
continue;
}
if (clks[i].alias)
clk_register_clkdev(clk, clks[i].alias, NULL);
clk_table[clks[i].id] = clk;
}
}

103
drivers/clk/hisilicon/clk.h Normal file
Просмотреть файл

@ -0,0 +1,103 @@
/*
* Hisilicon Hi3620 clock gate driver
*
* Copyright (c) 2012-2013 Hisilicon Limited.
* Copyright (c) 2012-2013 Linaro Limited.
*
* Author: Haojian Zhuang <haojian.zhuang@linaro.org>
* Xin Li <li.xin@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef __HISI_CLK_H
#define __HISI_CLK_H
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/spinlock.h>
struct hisi_fixed_rate_clock {
unsigned int id;
char *name;
const char *parent_name;
unsigned long flags;
unsigned long fixed_rate;
};
struct hisi_fixed_factor_clock {
unsigned int id;
char *name;
const char *parent_name;
unsigned long mult;
unsigned long div;
unsigned long flags;
};
struct hisi_mux_clock {
unsigned int id;
const char *name;
const char **parent_names;
u8 num_parents;
unsigned long flags;
unsigned long offset;
u8 shift;
u8 width;
u8 mux_flags;
const char *alias;
};
struct hisi_divider_clock {
unsigned int id;
const char *name;
const char *parent_name;
unsigned long flags;
unsigned long offset;
u8 shift;
u8 width;
u8 div_flags;
struct clk_div_table *table;
const char *alias;
};
struct hisi_gate_clock {
unsigned int id;
const char *name;
const char *parent_name;
unsigned long flags;
unsigned long offset;
u8 bit_idx;
u8 gate_flags;
const char *alias;
};
struct clk *hisi_register_clkgate_sep(struct device *, const char *,
const char *, unsigned long,
void __iomem *, u8,
u8, spinlock_t *);
void __init hisi_clk_init(struct device_node *, int);
void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *,
int, void __iomem *);
void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *,
int, void __iomem *);
void __init hisi_clk_register_mux(struct hisi_mux_clock *, int,
void __iomem *);
void __init hisi_clk_register_divider(struct hisi_divider_clock *,
int, void __iomem *);
void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *,
int, void __iomem *);
#endif /* __HISI_CLK_H */

Просмотреть файл

@ -0,0 +1,130 @@
/*
* Hisilicon clock separated gate driver
*
* Copyright (c) 2012-2013 Hisilicon Limited.
* Copyright (c) 2012-2013 Linaro Limited.
*
* Author: Haojian Zhuang <haojian.zhuang@linaro.org>
* Xin Li <li.xin@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include "clk.h"
/* clock separated gate register offset */
#define CLKGATE_SEPERATED_ENABLE 0x0
#define CLKGATE_SEPERATED_DISABLE 0x4
#define CLKGATE_SEPERATED_STATUS 0x8
struct clkgate_separated {
struct clk_hw hw;
void __iomem *enable; /* enable register */
u8 bit_idx; /* bits in enable/disable register */
u8 flags;
spinlock_t *lock;
};
static int clkgate_separated_enable(struct clk_hw *hw)
{
struct clkgate_separated *sclk;
unsigned long flags = 0;
u32 reg;
sclk = container_of(hw, struct clkgate_separated, hw);
if (sclk->lock)
spin_lock_irqsave(sclk->lock, flags);
reg = BIT(sclk->bit_idx);
writel_relaxed(reg, sclk->enable);
readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
if (sclk->lock)
spin_unlock_irqrestore(sclk->lock, flags);
return 0;
}
static void clkgate_separated_disable(struct clk_hw *hw)
{
struct clkgate_separated *sclk;
unsigned long flags = 0;
u32 reg;
sclk = container_of(hw, struct clkgate_separated, hw);
if (sclk->lock)
spin_lock_irqsave(sclk->lock, flags);
reg = BIT(sclk->bit_idx);
writel_relaxed(reg, sclk->enable + CLKGATE_SEPERATED_DISABLE);
readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
if (sclk->lock)
spin_unlock_irqrestore(sclk->lock, flags);
}
static int clkgate_separated_is_enabled(struct clk_hw *hw)
{
struct clkgate_separated *sclk;
u32 reg;
sclk = container_of(hw, struct clkgate_separated, hw);
reg = readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
reg &= BIT(sclk->bit_idx);
return reg ? 1 : 0;
}
static struct clk_ops clkgate_separated_ops = {
.enable = clkgate_separated_enable,
.disable = clkgate_separated_disable,
.is_enabled = clkgate_separated_is_enabled,
};
struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name,
const char *parent_name,
unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock)
{
struct clkgate_separated *sclk;
struct clk *clk;
struct clk_init_data init;
sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
if (!sclk) {
pr_err("%s: fail to allocate separated gated clk\n", __func__);
return ERR_PTR(-ENOMEM);
}
init.name = name;
init.ops = &clkgate_separated_ops;
init.flags = flags | CLK_IS_BASIC;
init.parent_names = (parent_name ? &parent_name : NULL);
init.num_parents = (parent_name ? 1 : 0);
sclk->enable = reg + CLKGATE_SEPERATED_ENABLE;
sclk->bit_idx = bit_idx;
sclk->flags = clk_gate_flags;
sclk->hw.init = &init;
clk = clk_register(dev, &sclk->hw);
if (IS_ERR(clk))
kfree(sclk);
return clk;
}

Просмотреть файл

@ -223,8 +223,7 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
data->domain_base = of_iomap(node, i);
if (!data->domain_base) {
pr_err("%s: domain ioremap failed\n", __func__);
iounmap(data->control_base);
goto out;
goto unmap_ctrl;
}
of_property_read_u32(node, "domain-id", &data->domain_id);
@ -237,16 +236,21 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
parent_name = of_clk_get_parent_name(node, 0);
if (!parent_name) {
pr_err("%s: Parent clock not found\n", __func__);
goto out;
goto unmap_domain;
}
clk = clk_register_psc(NULL, clk_name, parent_name, data, lock);
if (clk) {
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
return;
}
pr_err("%s: error registering clk %s\n", __func__, node->name);
unmap_domain:
iounmap(data->domain_base);
unmap_ctrl:
iounmap(data->control_base);
out:
kfree(data);
return;

Просмотреть файл

@ -24,6 +24,8 @@
#define MAIN_PLLM_HIGH_MASK 0x7f000
#define PLLM_HIGH_SHIFT 6
#define PLLD_MASK 0x3f
#define CLKOD_MASK 0x780000
#define CLKOD_SHIFT 19
/**
* struct clk_pll_data - pll data structure
@ -41,7 +43,10 @@
* @pllm_upper_mask: multiplier upper mask
* @pllm_upper_shift: multiplier upper shift
* @plld_mask: divider mask
* @postdiv: Post divider
* @clkod_mask: output divider mask
* @clkod_shift: output divider shift
* @plld_mask: divider mask
* @postdiv: Fixed post divider
*/
struct clk_pll_data {
bool has_pllctrl;
@ -53,6 +58,8 @@ struct clk_pll_data {
u32 pllm_upper_mask;
u32 pllm_upper_shift;
u32 plld_mask;
u32 clkod_mask;
u32 clkod_shift;
u32 postdiv;
};
@ -90,7 +97,13 @@ static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
mult |= ((val & pll_data->pllm_upper_mask)
>> pll_data->pllm_upper_shift);
prediv = (val & pll_data->plld_mask);
postdiv = pll_data->postdiv;
if (!pll_data->has_pllctrl)
/* read post divider from od bits*/
postdiv = ((val & pll_data->clkod_mask) >>
pll_data->clkod_shift) + 1;
else
postdiv = pll_data->postdiv;
rate /= (prediv + 1);
rate = (rate * (mult + 1));
@ -155,8 +168,11 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
}
parent_name = of_clk_get_parent_name(node, 0);
if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv))
goto out;
if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) {
/* assume the PLL has output divider register bits */
pll_data->clkod_mask = CLKOD_MASK;
pll_data->clkod_shift = CLKOD_SHIFT;
}
i = of_property_match_string(node, "reg-names", "control");
pll_data->pll_ctl0 = of_iomap(node, i);

Просмотреть файл

@ -4,15 +4,20 @@ config MVEBU_CLK_COMMON
config MVEBU_CLK_CPU
bool
config MVEBU_CLK_COREDIV
bool
config ARMADA_370_CLK
bool
select MVEBU_CLK_COMMON
select MVEBU_CLK_CPU
select MVEBU_CLK_COREDIV
config ARMADA_XP_CLK
bool
select MVEBU_CLK_COMMON
select MVEBU_CLK_CPU
select MVEBU_CLK_COREDIV
config DOVE_CLK
bool

Просмотреть файл

@ -1,5 +1,6 @@
obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o
obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o
obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o
obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o

Просмотреть файл

@ -0,0 +1,223 @@
/*
* MVEBU Core divider clock
*
* Copyright (C) 2013 Marvell
*
* Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include "common.h"
#define CORE_CLK_DIV_RATIO_MASK 0xff
#define CORE_CLK_DIV_RATIO_RELOAD BIT(8)
#define CORE_CLK_DIV_ENABLE_OFFSET 24
#define CORE_CLK_DIV_RATIO_OFFSET 0x8
struct clk_corediv_desc {
unsigned int mask;
unsigned int offset;
unsigned int fieldbit;
};
struct clk_corediv {
struct clk_hw hw;
void __iomem *reg;
struct clk_corediv_desc desc;
spinlock_t lock;
};
static struct clk_onecell_data clk_data;
static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
{ .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
};
#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
static int clk_corediv_is_enabled(struct clk_hw *hwclk)
{
struct clk_corediv *corediv = to_corediv_clk(hwclk);
struct clk_corediv_desc *desc = &corediv->desc;
u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET;
return !!(readl(corediv->reg) & enable_mask);
}
static int clk_corediv_enable(struct clk_hw *hwclk)
{
struct clk_corediv *corediv = to_corediv_clk(hwclk);
struct clk_corediv_desc *desc = &corediv->desc;
unsigned long flags = 0;
u32 reg;
spin_lock_irqsave(&corediv->lock, flags);
reg = readl(corediv->reg);
reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
writel(reg, corediv->reg);
spin_unlock_irqrestore(&corediv->lock, flags);
return 0;
}
static void clk_corediv_disable(struct clk_hw *hwclk)
{
struct clk_corediv *corediv = to_corediv_clk(hwclk);
struct clk_corediv_desc *desc = &corediv->desc;
unsigned long flags = 0;
u32 reg;
spin_lock_irqsave(&corediv->lock, flags);
reg = readl(corediv->reg);
reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
writel(reg, corediv->reg);
spin_unlock_irqrestore(&corediv->lock, flags);
}
static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
unsigned long parent_rate)
{
struct clk_corediv *corediv = to_corediv_clk(hwclk);
struct clk_corediv_desc *desc = &corediv->desc;
u32 reg, div;
reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
div = (reg >> desc->offset) & desc->mask;
return parent_rate / div;
}
static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
unsigned long *parent_rate)
{
/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
u32 div;
div = *parent_rate / rate;
if (div < 4)
div = 4;
else if (div > 6)
div = 8;
return *parent_rate / div;
}
static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
unsigned long parent_rate)
{
struct clk_corediv *corediv = to_corediv_clk(hwclk);
struct clk_corediv_desc *desc = &corediv->desc;
unsigned long flags = 0;
u32 reg, div;
div = parent_rate / rate;
spin_lock_irqsave(&corediv->lock, flags);
/* Write new divider to the divider ratio register */
reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
reg &= ~(desc->mask << desc->offset);
reg |= (div & desc->mask) << desc->offset;
writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
/* Set reload-force for this clock */
reg = readl(corediv->reg) | BIT(desc->fieldbit);
writel(reg, corediv->reg);
/* Now trigger the clock update */
reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD;
writel(reg, corediv->reg);
/*
* Wait for clocks to settle down, and then clear all the
* ratios request and the reload request.
*/
udelay(1000);
reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD);
writel(reg, corediv->reg);
udelay(1000);
spin_unlock_irqrestore(&corediv->lock, flags);
return 0;
}
static const struct clk_ops corediv_ops = {
.enable = clk_corediv_enable,
.disable = clk_corediv_disable,
.is_enabled = clk_corediv_is_enabled,
.recalc_rate = clk_corediv_recalc_rate,
.round_rate = clk_corediv_round_rate,
.set_rate = clk_corediv_set_rate,
};
static void __init mvebu_corediv_clk_init(struct device_node *node)
{
struct clk_init_data init;
struct clk_corediv *corediv;
struct clk **clks;
void __iomem *base;
const char *parent_name;
const char *clk_name;
int i;
base = of_iomap(node, 0);
if (WARN_ON(!base))
return;
parent_name = of_clk_get_parent_name(node, 0);
clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc);
/* clks holds the clock array */
clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
GFP_KERNEL);
if (WARN_ON(!clks))
goto err_unmap;
/* corediv holds the clock specific array */
corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),
GFP_KERNEL);
if (WARN_ON(!corediv))
goto err_free_clks;
spin_lock_init(&corediv->lock);
for (i = 0; i < clk_data.clk_num; i++) {
of_property_read_string_index(node, "clock-output-names",
i, &clk_name);
init.num_parents = 1;
init.parent_names = &parent_name;
init.name = clk_name;
init.ops = &corediv_ops;
init.flags = 0;
corediv[i].desc = mvebu_corediv_desc[i];
corediv[i].reg = base;
corediv[i].hw.init = &init;
clks[i] = clk_register(NULL, &corediv[i].hw);
WARN_ON(IS_ERR(clks[i]));
}
clk_data.clks = clks;
of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
return;
err_free_clks:
kfree(clks);
err_unmap:
iounmap(base);
}
CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock",
mvebu_corediv_clk_init);

Просмотреть файл

@ -101,7 +101,7 @@ static const struct clk_ops cpu_ops = {
.set_rate = clk_cpu_set_rate,
};
void __init of_cpu_clk_setup(struct device_node *node)
static void __init of_cpu_clk_setup(struct device_node *node)
{
struct cpu_clk *cpuclk;
void __iomem *clock_complex_base = of_iomap(node, 0);

47
drivers/clk/qcom/Kconfig Normal file
Просмотреть файл

@ -0,0 +1,47 @@
config COMMON_CLK_QCOM
tristate "Support for Qualcomm's clock controllers"
depends on OF
select REGMAP_MMIO
select RESET_CONTROLLER
config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8660 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, SD/eMMC, etc.
config MSM_GCC_8960
tristate "MSM8960 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8960 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, SD/eMMC, SATA, PCIe, etc.
config MSM_MMCC_8960
tristate "MSM8960 Multimedia Clock Controller"
select MSM_GCC_8960
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on msm8960 devices.
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.
config MSM_GCC_8974
tristate "MSM8974 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8974 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, SD/eMMC, SATA, PCIe, etc.
config MSM_MMCC_8974
tristate "MSM8974 Multimedia Clock Controller"
select MSM_GCC_8974
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on msm8974 devices.
Say Y if you want to support multimedia devices such as display,
graphics, video encode/decode, camera, etc.

14
drivers/clk/qcom/Makefile Normal file
Просмотреть файл

@ -0,0 +1,14 @@
obj-$(CONFIG_COMMON_CLK_QCOM) += clk-qcom.o
clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-regmap.o
clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-pll.o
clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg.o
clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-rcg2.o
clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += clk-branch.o
clk-qcom-$(CONFIG_COMMON_CLK_QCOM) += reset.o
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
obj-$(CONFIG_MSM_GCC_8960) += gcc-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

Просмотреть файл

@ -0,0 +1,159 @@
/*
* Copyright (c) 2013, 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/err.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include "clk-branch.h"
static bool clk_branch_in_hwcg_mode(const struct clk_branch *br)
{
u32 val;
if (!br->hwcg_reg)
return 0;
regmap_read(br->clkr.regmap, br->hwcg_reg, &val);
return !!(val & BIT(br->hwcg_bit));
}
static bool clk_branch_check_halt(const struct clk_branch *br, bool enabling)
{
bool invert = (br->halt_check == BRANCH_HALT_ENABLE);
u32 val;
regmap_read(br->clkr.regmap, br->halt_reg, &val);
val &= BIT(br->halt_bit);
if (invert)
val = !val;
return !!val == !enabling;
}
#define BRANCH_CLK_OFF BIT(31)
#define BRANCH_NOC_FSM_STATUS_SHIFT 28
#define BRANCH_NOC_FSM_STATUS_MASK 0x7
#define BRANCH_NOC_FSM_STATUS_ON (0x2 << BRANCH_NOC_FSM_STATUS_SHIFT)
static bool clk_branch2_check_halt(const struct clk_branch *br, bool enabling)
{
u32 val;
u32 mask;
mask = BRANCH_NOC_FSM_STATUS_MASK << BRANCH_NOC_FSM_STATUS_SHIFT;
mask |= BRANCH_CLK_OFF;
regmap_read(br->clkr.regmap, br->halt_reg, &val);
if (enabling) {
val &= mask;
return (val & BRANCH_CLK_OFF) == 0 ||
val == BRANCH_NOC_FSM_STATUS_ON;
} else {
return val & BRANCH_CLK_OFF;
}
}
static int clk_branch_wait(const struct clk_branch *br, bool enabling,
bool (check_halt)(const struct clk_branch *, bool))
{
bool voted = br->halt_check & BRANCH_VOTED;
const char *name = __clk_get_name(br->clkr.hw.clk);
/* Skip checking halt bit if the clock is in hardware gated mode */
if (clk_branch_in_hwcg_mode(br))
return 0;
if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) {
udelay(10);
} else if (br->halt_check == BRANCH_HALT_ENABLE ||
br->halt_check == BRANCH_HALT ||
(enabling && voted)) {
int count = 200;
while (count-- > 0) {
if (check_halt(br, enabling))
return 0;
udelay(1);
}
WARN(1, "%s status stuck at 'o%s'", name,
enabling ? "ff" : "n");
return -EBUSY;
}
return 0;
}
static int clk_branch_toggle(struct clk_hw *hw, bool en,
bool (check_halt)(const struct clk_branch *, bool))
{
struct clk_branch *br = to_clk_branch(hw);
int ret;
if (en) {
ret = clk_enable_regmap(hw);
if (ret)
return ret;
} else {
clk_disable_regmap(hw);
}
return clk_branch_wait(br, en, check_halt);
}
static int clk_branch_enable(struct clk_hw *hw)
{
return clk_branch_toggle(hw, true, clk_branch_check_halt);
}
static void clk_branch_disable(struct clk_hw *hw)
{
clk_branch_toggle(hw, false, clk_branch_check_halt);
}
const struct clk_ops clk_branch_ops = {
.enable = clk_branch_enable,
.disable = clk_branch_disable,
.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch_ops);
static int clk_branch2_enable(struct clk_hw *hw)
{
return clk_branch_toggle(hw, true, clk_branch2_check_halt);
}
static void clk_branch2_disable(struct clk_hw *hw)
{
clk_branch_toggle(hw, false, clk_branch2_check_halt);
}
const struct clk_ops clk_branch2_ops = {
.enable = clk_branch2_enable,
.disable = clk_branch2_disable,
.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch2_ops);
const struct clk_ops clk_branch_simple_ops = {
.enable = clk_enable_regmap,
.disable = clk_disable_regmap,
.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch_simple_ops);

Просмотреть файл

@ -0,0 +1,56 @@
/*
* Copyright (c) 2013, 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_BRANCH_H__
#define __QCOM_CLK_BRANCH_H__
#include <linux/clk-provider.h>
#include "clk-regmap.h"
/**
* struct clk_branch - gating clock with status bit and dynamic hardware gating
*
* @hwcg_reg: dynamic hardware clock gating register
* @hwcg_bit: ORed with @hwcg_reg to enable dynamic hardware clock gating
* @halt_reg: halt register
* @halt_bit: ANDed with @halt_reg to test for clock halted
* @halt_check: type of halt checking to perform
* @clkr: handle between common and hardware-specific interfaces
*
* Clock which can gate its output.
*/
struct clk_branch {
u32 hwcg_reg;
u32 halt_reg;
u8 hwcg_bit;
u8 halt_bit;
u8 halt_check;
#define BRANCH_VOTED BIT(7) /* Delay on disable */
#define BRANCH_HALT 0 /* pol: 1 = halt */
#define BRANCH_HALT_VOTED (BRANCH_HALT | BRANCH_VOTED)
#define BRANCH_HALT_ENABLE 1 /* pol: 0 = halt */
#define BRANCH_HALT_ENABLE_VOTED (BRANCH_HALT_ENABLE | BRANCH_VOTED)
#define BRANCH_HALT_DELAY 2 /* No bit to check; just delay */
struct clk_regmap clkr;
};
extern const struct clk_ops clk_branch_ops;
extern const struct clk_ops clk_branch2_ops;
extern const struct clk_ops clk_branch_simple_ops;
#define to_clk_branch(_hw) \
container_of(to_clk_regmap(_hw), struct clk_branch, clkr)
#endif

222
drivers/clk/qcom/clk-pll.c Normal file
Просмотреть файл

@ -0,0 +1,222 @@
/*
* Copyright (c) 2013, 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/err.h>
#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <asm/div64.h>
#include "clk-pll.h"
#define PLL_OUTCTRL BIT(0)
#define PLL_BYPASSNL BIT(1)
#define PLL_RESET_N BIT(2)
#define PLL_LOCK_COUNT_SHIFT 8
#define PLL_LOCK_COUNT_MASK 0x3f
#define PLL_BIAS_COUNT_SHIFT 14
#define PLL_BIAS_COUNT_MASK 0x3f
#define PLL_VOTE_FSM_ENA BIT(20)
#define PLL_VOTE_FSM_RESET BIT(21)
static int clk_pll_enable(struct clk_hw *hw)
{
struct clk_pll *pll = to_clk_pll(hw);
int ret;
u32 mask, val;
mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
ret = regmap_read(pll->clkr.regmap, pll->mode_reg, &val);
if (ret)
return ret;
/* Skip if already enabled or in FSM mode */
if ((val & mask) == mask || val & PLL_VOTE_FSM_ENA)
return 0;
/* Disable PLL bypass mode. */
ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_BYPASSNL,
PLL_BYPASSNL);
if (ret)
return ret;
/*
* H/W requires a 5us delay between disabling the bypass and
* de-asserting the reset. Delay 10us just to be safe.
*/
udelay(10);
/* De-assert active-low PLL reset. */
ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_RESET_N,
PLL_RESET_N);
if (ret)
return ret;
/* Wait until PLL is locked. */
udelay(50);
/* Enable PLL output. */
ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_OUTCTRL,
PLL_OUTCTRL);
if (ret)
return ret;
return 0;
}
static void clk_pll_disable(struct clk_hw *hw)
{
struct clk_pll *pll = to_clk_pll(hw);
u32 mask;
u32 val;
regmap_read(pll->clkr.regmap, pll->mode_reg, &val);
/* Skip if in FSM mode */
if (val & PLL_VOTE_FSM_ENA)
return;
mask = PLL_OUTCTRL | PLL_RESET_N | PLL_BYPASSNL;
regmap_update_bits(pll->clkr.regmap, pll->mode_reg, mask, 0);
}
static unsigned long
clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct clk_pll *pll = to_clk_pll(hw);
u32 l, m, n;
unsigned long rate;
u64 tmp;
regmap_read(pll->clkr.regmap, pll->l_reg, &l);
regmap_read(pll->clkr.regmap, pll->m_reg, &m);
regmap_read(pll->clkr.regmap, pll->n_reg, &n);
l &= 0x3ff;
m &= 0x7ffff;
n &= 0x7ffff;
rate = parent_rate * l;
if (n) {
tmp = parent_rate;
tmp *= m;
do_div(tmp, n);
rate += tmp;
}
return rate;
}
const struct clk_ops clk_pll_ops = {
.enable = clk_pll_enable,
.disable = clk_pll_disable,
.recalc_rate = clk_pll_recalc_rate,
};
EXPORT_SYMBOL_GPL(clk_pll_ops);
static int wait_for_pll(struct clk_pll *pll)
{
u32 val;
int count;
int ret;
const char *name = __clk_get_name(pll->clkr.hw.clk);
/* Wait for pll to enable. */
for (count = 200; count > 0; count--) {
ret = regmap_read(pll->clkr.regmap, pll->status_reg, &val);
if (ret)
return ret;
if (val & BIT(pll->status_bit))
return 0;
udelay(1);
}
WARN(1, "%s didn't enable after voting for it!\n", name);
return -ETIMEDOUT;
}
static int clk_pll_vote_enable(struct clk_hw *hw)
{
int ret;
struct clk_pll *p = to_clk_pll(__clk_get_hw(__clk_get_parent(hw->clk)));
ret = clk_enable_regmap(hw);
if (ret)
return ret;
return wait_for_pll(p);
}
const struct clk_ops clk_pll_vote_ops = {
.enable = clk_pll_vote_enable,
.disable = clk_disable_regmap,
};
EXPORT_SYMBOL_GPL(clk_pll_vote_ops);
static void
clk_pll_set_fsm_mode(struct clk_pll *pll, struct regmap *regmap)
{
u32 val;
u32 mask;
/* De-assert reset to FSM */
regmap_update_bits(regmap, pll->mode_reg, PLL_VOTE_FSM_RESET, 0);
/* Program bias count and lock count */
val = 1 << PLL_BIAS_COUNT_SHIFT;
mask = PLL_BIAS_COUNT_MASK << PLL_BIAS_COUNT_SHIFT;
mask |= PLL_LOCK_COUNT_MASK << PLL_LOCK_COUNT_SHIFT;
regmap_update_bits(regmap, pll->mode_reg, mask, val);
/* Enable PLL FSM voting */
regmap_update_bits(regmap, pll->mode_reg, PLL_VOTE_FSM_ENA,
PLL_VOTE_FSM_ENA);
}
static void clk_pll_configure(struct clk_pll *pll, struct regmap *regmap,
const struct pll_config *config)
{
u32 val;
u32 mask;
regmap_write(regmap, pll->l_reg, config->l);
regmap_write(regmap, pll->m_reg, config->m);
regmap_write(regmap, pll->n_reg, config->n);
val = config->vco_val;
val |= config->pre_div_val;
val |= config->post_div_val;
val |= config->mn_ena_mask;
val |= config->main_output_mask;
val |= config->aux_output_mask;
mask = config->vco_mask;
mask |= config->pre_div_mask;
mask |= config->post_div_mask;
mask |= config->mn_ena_mask;
mask |= config->main_output_mask;
mask |= config->aux_output_mask;
regmap_update_bits(regmap, pll->config_reg, mask, val);
}
void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap,
const struct pll_config *config, bool fsm_mode)
{
clk_pll_configure(pll, regmap, config);
if (fsm_mode)
clk_pll_set_fsm_mode(pll, regmap);
}
EXPORT_SYMBOL_GPL(clk_pll_configure_sr_hpm_lp);

Просмотреть файл

@ -0,0 +1,66 @@
/*
* Copyright (c) 2013, 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_PLL_H__
#define __QCOM_CLK_PLL_H__
#include <linux/clk-provider.h>
#include "clk-regmap.h"
/**
* struct clk_pll - phase locked loop (PLL)
* @l_reg: L register
* @m_reg: M register
* @n_reg: N register
* @config_reg: config register
* @mode_reg: mode register
* @status_reg: status register
* @status_bit: ANDed with @status_reg to determine if PLL is enabled
* @hw: handle between common and hardware-specific interfaces
*/
struct clk_pll {
u32 l_reg;
u32 m_reg;
u32 n_reg;
u32 config_reg;
u32 mode_reg;
u32 status_reg;
u8 status_bit;
struct clk_regmap clkr;
};
extern const struct clk_ops clk_pll_ops;
extern const struct clk_ops clk_pll_vote_ops;
#define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr)
struct pll_config {
u16 l;
u32 m;
u32 n;
u32 vco_val;
u32 vco_mask;
u32 pre_div_val;
u32 pre_div_mask;
u32 post_div_val;
u32 post_div_mask;
u32 mn_ena_mask;
u32 main_output_mask;
u32 aux_output_mask;
};
void clk_pll_configure_sr_hpm_lp(struct clk_pll *pll, struct regmap *regmap,
const struct pll_config *config, bool fsm_mode);
#endif

517
drivers/clk/qcom/clk-rcg.c Normal file
Просмотреть файл

@ -0,0 +1,517 @@
/*
* Copyright (c) 2013, 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/err.h>
#include <linux/export.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <asm/div64.h>
#include "clk-rcg.h"
static u32 ns_to_src(struct src_sel *s, u32 ns)
{
ns >>= s->src_sel_shift;
ns &= SRC_SEL_MASK;
return ns;
}
static u32 src_to_ns(struct src_sel *s, u8 src, u32 ns)
{
u32 mask;
mask = SRC_SEL_MASK;
mask <<= s->src_sel_shift;
ns &= ~mask;
ns |= src << s->src_sel_shift;
return ns;
}
static u8 clk_rcg_get_parent(struct clk_hw *hw)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
int num_parents = __clk_get_num_parents(hw->clk);
u32 ns;
int i;
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
ns = ns_to_src(&rcg->s, ns);
for (i = 0; i < num_parents; i++)
if (ns == rcg->s.parent_map[i])
return i;
return -EINVAL;
}
static int reg_to_bank(struct clk_dyn_rcg *rcg, u32 bank)
{
bank &= BIT(rcg->mux_sel_bit);
return !!bank;
}
static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
int num_parents = __clk_get_num_parents(hw->clk);
u32 ns, ctl;
int bank;
int i;
struct src_sel *s;
regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
bank = reg_to_bank(rcg, ctl);
s = &rcg->s[bank];
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
ns = ns_to_src(s, ns);
for (i = 0; i < num_parents; i++)
if (ns == s->parent_map[i])
return i;
return -EINVAL;
}
static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
u32 ns;
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
ns = src_to_ns(&rcg->s, rcg->s.parent_map[index], ns);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
return 0;
}
static u32 md_to_m(struct mn *mn, u32 md)
{
md >>= mn->m_val_shift;
md &= BIT(mn->width) - 1;
return md;
}
static u32 ns_to_pre_div(struct pre_div *p, u32 ns)
{
ns >>= p->pre_div_shift;
ns &= BIT(p->pre_div_width) - 1;
return ns;
}
static u32 pre_div_to_ns(struct pre_div *p, u8 pre_div, u32 ns)
{
u32 mask;
mask = BIT(p->pre_div_width) - 1;
mask <<= p->pre_div_shift;
ns &= ~mask;
ns |= pre_div << p->pre_div_shift;
return ns;
}
static u32 mn_to_md(struct mn *mn, u32 m, u32 n, u32 md)
{
u32 mask, mask_w;
mask_w = BIT(mn->width) - 1;
mask = (mask_w << mn->m_val_shift) | mask_w;
md &= ~mask;
if (n) {
m <<= mn->m_val_shift;
md |= m;
md |= ~n & mask_w;
}
return md;
}
static u32 ns_m_to_n(struct mn *mn, u32 ns, u32 m)
{
ns = ~ns >> mn->n_val_shift;
ns &= BIT(mn->width) - 1;
return ns + m;
}
static u32 reg_to_mnctr_mode(struct mn *mn, u32 val)
{
val >>= mn->mnctr_mode_shift;
val &= MNCTR_MODE_MASK;
return val;
}
static u32 mn_to_ns(struct mn *mn, u32 m, u32 n, u32 ns)
{
u32 mask;
mask = BIT(mn->width) - 1;
mask <<= mn->n_val_shift;
ns &= ~mask;
if (n) {
n = n - m;
n = ~n;
n &= BIT(mn->width) - 1;
n <<= mn->n_val_shift;
ns |= n;
}
return ns;
}
static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val)
{
u32 mask;
mask = MNCTR_MODE_MASK << mn->mnctr_mode_shift;
mask |= BIT(mn->mnctr_en_bit);
val &= ~mask;
if (n) {
val |= BIT(mn->mnctr_en_bit);
val |= MNCTR_MODE_DUAL << mn->mnctr_mode_shift;
}
return val;
}
static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
{
u32 ns, md, ctl, *regp;
int bank, new_bank;
struct mn *mn;
struct pre_div *p;
struct src_sel *s;
bool enabled;
u32 md_reg;
u32 bank_reg;
bool banked_mn = !!rcg->mn[1].width;
struct clk_hw *hw = &rcg->clkr.hw;
enabled = __clk_is_enabled(hw->clk);
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
if (banked_mn) {
regp = &ctl;
bank_reg = rcg->clkr.enable_reg;
} else {
regp = &ns;
bank_reg = rcg->ns_reg;
}
bank = reg_to_bank(rcg, *regp);
new_bank = enabled ? !bank : bank;
if (banked_mn) {
mn = &rcg->mn[new_bank];
md_reg = rcg->md_reg[new_bank];
ns |= BIT(mn->mnctr_reset_bit);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
regmap_read(rcg->clkr.regmap, md_reg, &md);
md = mn_to_md(mn, f->m, f->n, md);
regmap_write(rcg->clkr.regmap, md_reg, md);
ns = mn_to_ns(mn, f->m, f->n, ns);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
ctl = mn_to_reg(mn, f->m, f->n, ctl);
regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
ns &= ~BIT(mn->mnctr_reset_bit);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
} else {
p = &rcg->p[new_bank];
ns = pre_div_to_ns(p, f->pre_div - 1, ns);
}
s = &rcg->s[new_bank];
ns = src_to_ns(s, s->parent_map[f->src], ns);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
if (enabled) {
*regp ^= BIT(rcg->mux_sel_bit);
regmap_write(rcg->clkr.regmap, bank_reg, *regp);
}
}
static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
u32 ns, ctl, md, reg;
int bank;
struct freq_tbl f = { 0 };
bool banked_mn = !!rcg->mn[1].width;
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
reg = banked_mn ? ctl : ns;
bank = reg_to_bank(rcg, reg);
if (banked_mn) {
regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
f.m = md_to_m(&rcg->mn[bank], md);
f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
} else {
f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
}
f.src = index;
configure_bank(rcg, &f);
return 0;
}
/*
* Calculate m/n:d rate
*
* parent_rate m
* rate = ----------- x ---
* pre_div n
*/
static unsigned long
calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 pre_div)
{
if (pre_div)
rate /= pre_div + 1;
if (mode) {
u64 tmp = rate;
tmp *= m;
do_div(tmp, n);
rate = tmp;
}
return rate;
}
static unsigned long
clk_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
u32 pre_div, m = 0, n = 0, ns, md, mode = 0;
struct mn *mn = &rcg->mn;
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
pre_div = ns_to_pre_div(&rcg->p, ns);
if (rcg->mn.width) {
regmap_read(rcg->clkr.regmap, rcg->md_reg, &md);
m = md_to_m(mn, md);
n = ns_m_to_n(mn, ns, m);
/* MN counter mode is in hw.enable_reg sometimes */
if (rcg->clkr.enable_reg != rcg->ns_reg)
regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &mode);
else
mode = ns;
mode = reg_to_mnctr_mode(mn, mode);
}
return calc_rate(parent_rate, m, n, mode, pre_div);
}
static unsigned long
clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
u32 m, n, pre_div, ns, md, mode, reg;
int bank;
struct mn *mn;
bool banked_mn = !!rcg->mn[1].width;
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
if (banked_mn)
regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &reg);
else
reg = ns;
bank = reg_to_bank(rcg, reg);
if (banked_mn) {
mn = &rcg->mn[bank];
regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
m = md_to_m(mn, md);
n = ns_m_to_n(mn, ns, m);
mode = reg_to_mnctr_mode(mn, reg);
return calc_rate(parent_rate, m, n, mode, 0);
} else {
pre_div = ns_to_pre_div(&rcg->p[bank], ns);
return calc_rate(parent_rate, 0, 0, 0, pre_div);
}
}
static const
struct freq_tbl *find_freq(const struct freq_tbl *f, unsigned long rate)
{
if (!f)
return NULL;
for (; f->freq; f++)
if (rate <= f->freq)
return f;
return NULL;
}
static long _freq_tbl_determine_rate(struct clk_hw *hw,
const struct freq_tbl *f, unsigned long rate,
unsigned long *p_rate, struct clk **p)
{
unsigned long clk_flags;
f = find_freq(f, rate);
if (!f)
return -EINVAL;
clk_flags = __clk_get_flags(hw->clk);
*p = clk_get_parent_by_index(hw->clk, f->src);
if (clk_flags & CLK_SET_RATE_PARENT) {
rate = rate * f->pre_div;
if (f->n) {
u64 tmp = rate;
tmp = tmp * f->n;
do_div(tmp, f->m);
rate = tmp;
}
} else {
rate = __clk_get_rate(*p);
}
*p_rate = rate;
return f->freq;
}
static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *p_rate, struct clk **p)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
}
static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *p_rate, struct clk **p)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
}
static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
const struct freq_tbl *f;
u32 ns, md, ctl;
struct mn *mn = &rcg->mn;
u32 mask = 0;
unsigned int reset_reg;
f = find_freq(rcg->freq_tbl, rate);
if (!f)
return -EINVAL;
if (rcg->mn.reset_in_cc)
reset_reg = rcg->clkr.enable_reg;
else
reset_reg = rcg->ns_reg;
if (rcg->mn.width) {
mask = BIT(mn->mnctr_reset_bit);
regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, mask);
regmap_read(rcg->clkr.regmap, rcg->md_reg, &md);
md = mn_to_md(mn, f->m, f->n, md);
regmap_write(rcg->clkr.regmap, rcg->md_reg, md);
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
/* MN counter mode is in hw.enable_reg sometimes */
if (rcg->clkr.enable_reg != rcg->ns_reg) {
regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
ctl = mn_to_reg(mn, f->m, f->n, ctl);
regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
} else {
ns = mn_to_reg(mn, f->m, f->n, ns);
}
ns = mn_to_ns(mn, f->m, f->n, ns);
} else {
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
}
ns = pre_div_to_ns(&rcg->p, f->pre_div - 1, ns);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, 0);
return 0;
}
static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate)
{
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
const struct freq_tbl *f;
f = find_freq(rcg->freq_tbl, rate);
if (!f)
return -EINVAL;
configure_bank(rcg, f);
return 0;
}
static int clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return __clk_dyn_rcg_set_rate(hw, rate);
}
static int clk_dyn_rcg_set_rate_and_parent(struct clk_hw *hw,
unsigned long rate, unsigned long parent_rate, u8 index)
{
return __clk_dyn_rcg_set_rate(hw, rate);
}
const struct clk_ops clk_rcg_ops = {
.enable = clk_enable_regmap,
.disable = clk_disable_regmap,
.get_parent = clk_rcg_get_parent,
.set_parent = clk_rcg_set_parent,
.recalc_rate = clk_rcg_recalc_rate,
.determine_rate = clk_rcg_determine_rate,
.set_rate = clk_rcg_set_rate,
};
EXPORT_SYMBOL_GPL(clk_rcg_ops);
const struct clk_ops clk_dyn_rcg_ops = {
.enable = clk_enable_regmap,
.is_enabled = clk_is_enabled_regmap,
.disable = clk_disable_regmap,
.get_parent = clk_dyn_rcg_get_parent,
.set_parent = clk_dyn_rcg_set_parent,
.recalc_rate = clk_dyn_rcg_recalc_rate,
.determine_rate = clk_dyn_rcg_determine_rate,
.set_rate = clk_dyn_rcg_set_rate,
.set_rate_and_parent = clk_dyn_rcg_set_rate_and_parent,
};
EXPORT_SYMBOL_GPL(clk_dyn_rcg_ops);

159
drivers/clk/qcom/clk-rcg.h Normal file
Просмотреть файл

@ -0,0 +1,159 @@
/*
* Copyright (c) 2013, 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_RCG_H__
#define __QCOM_CLK_RCG_H__
#include <linux/clk-provider.h>
#include "clk-regmap.h"
struct freq_tbl {
unsigned long freq;
u8 src;
u8 pre_div;
u16 m;
u16 n;
};
/**
* struct mn - M/N:D counter
* @mnctr_en_bit: bit to enable mn counter
* @mnctr_reset_bit: bit to assert mn counter reset
* @mnctr_mode_shift: lowest bit of mn counter mode field
* @n_val_shift: lowest bit of n value field
* @m_val_shift: lowest bit of m value field
* @width: number of bits in m/n/d values
* @reset_in_cc: true if the mnctr_reset_bit is in the CC register
*/
struct mn {
u8 mnctr_en_bit;
u8 mnctr_reset_bit;
u8 mnctr_mode_shift;
#define MNCTR_MODE_DUAL 0x2
#define MNCTR_MODE_MASK 0x3
u8 n_val_shift;
u8 m_val_shift;
u8 width;
bool reset_in_cc;
};
/**
* struct pre_div - pre-divider
* @pre_div_shift: lowest bit of pre divider field
* @pre_div_width: number of bits in predivider
*/
struct pre_div {
u8 pre_div_shift;
u8 pre_div_width;
};
/**
* struct src_sel - source selector
* @src_sel_shift: lowest bit of source selection field
* @parent_map: map from software's parent index to hardware's src_sel field
*/
struct src_sel {
u8 src_sel_shift;
#define SRC_SEL_MASK 0x7
const u8 *parent_map;
};
/**
* struct clk_rcg - root clock generator
*
* @ns_reg: NS register
* @md_reg: MD register
* @mn: mn counter
* @p: pre divider
* @s: source selector
* @freq_tbl: frequency table
* @clkr: regmap clock handle
* @lock: register lock
*
*/
struct clk_rcg {
u32 ns_reg;
u32 md_reg;
struct mn mn;
struct pre_div p;
struct src_sel s;
const struct freq_tbl *freq_tbl;
struct clk_regmap clkr;
};
extern const struct clk_ops clk_rcg_ops;
#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr)
/**
* struct clk_dyn_rcg - root clock generator with glitch free mux
*
* @mux_sel_bit: bit to switch glitch free mux
* @ns_reg: NS register
* @md_reg: MD0 and MD1 register
* @mn: mn counter (banked)
* @s: source selector (banked)
* @freq_tbl: frequency table
* @clkr: regmap clock handle
* @lock: register lock
*
*/
struct clk_dyn_rcg {
u32 ns_reg;
u32 md_reg[2];
u8 mux_sel_bit;
struct mn mn[2];
struct pre_div p[2];
struct src_sel s[2];
const struct freq_tbl *freq_tbl;
struct clk_regmap clkr;
};
extern const struct clk_ops clk_dyn_rcg_ops;
#define to_clk_dyn_rcg(_hw) \
container_of(to_clk_regmap(_hw), struct clk_dyn_rcg, clkr)
/**
* struct clk_rcg2 - root clock generator
*
* @cmd_rcgr: corresponds to *_CMD_RCGR
* @mnd_width: number of bits in m/n/d values
* @hid_width: number of bits in half integer divider
* @parent_map: map from software's parent index to hardware's src_sel field
* @freq_tbl: frequency table
* @clkr: regmap clock handle
* @lock: register lock
*
*/
struct clk_rcg2 {
u32 cmd_rcgr;
u8 mnd_width;
u8 hid_width;
const u8 *parent_map;
const struct freq_tbl *freq_tbl;
struct clk_regmap clkr;
};
#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
extern const struct clk_ops clk_rcg2_ops;
#endif

291
drivers/clk/qcom/clk-rcg2.c Normal file
Просмотреть файл

@ -0,0 +1,291 @@
/*
* Copyright (c) 2013, 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/err.h>
#include <linux/bug.h>
#include <linux/export.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/regmap.h>
#include <asm/div64.h>
#include "clk-rcg.h"
#define CMD_REG 0x0
#define CMD_UPDATE BIT(0)
#define CMD_ROOT_EN BIT(1)
#define CMD_DIRTY_CFG BIT(4)
#define CMD_DIRTY_N BIT(5)
#define CMD_DIRTY_M BIT(6)
#define CMD_DIRTY_D BIT(7)
#define CMD_ROOT_OFF BIT(31)
#define CFG_REG 0x4
#define CFG_SRC_DIV_SHIFT 0
#define CFG_SRC_SEL_SHIFT 8
#define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT)
#define CFG_MODE_SHIFT 12
#define CFG_MODE_MASK (0x3 << CFG_MODE_SHIFT)
#define CFG_MODE_DUAL_EDGE (0x2 << CFG_MODE_SHIFT)
#define M_REG 0x8
#define N_REG 0xc
#define D_REG 0x10
static int clk_rcg2_is_enabled(struct clk_hw *hw)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
u32 cmd;
int ret;
ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &cmd);
if (ret)
return ret;
return (cmd & CMD_ROOT_OFF) != 0;
}
static u8 clk_rcg2_get_parent(struct clk_hw *hw)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int num_parents = __clk_get_num_parents(hw->clk);
u32 cfg;
int i, ret;
ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
if (ret)
return ret;
cfg &= CFG_SRC_SEL_MASK;
cfg >>= CFG_SRC_SEL_SHIFT;
for (i = 0; i < num_parents; i++)
if (cfg == rcg->parent_map[i])
return i;
return -EINVAL;
}
static int update_config(struct clk_rcg2 *rcg)
{
int count, ret;
u32 cmd;
struct clk_hw *hw = &rcg->clkr.hw;
const char *name = __clk_get_name(hw->clk);
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG,
CMD_UPDATE, CMD_UPDATE);
if (ret)
return ret;
/* Wait for update to take effect */
for (count = 500; count > 0; count--) {
ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, &cmd);
if (ret)
return ret;
if (!(cmd & CMD_UPDATE))
return 0;
udelay(1);
}
WARN(1, "%s: rcg didn't update its configuration.", name);
return 0;
}
static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
CFG_SRC_SEL_MASK,
rcg->parent_map[index] << CFG_SRC_SEL_SHIFT);
if (ret)
return ret;
return update_config(rcg);
}
/*
* Calculate m/n:d rate
*
* parent_rate m
* rate = ----------- x ---
* hid_div n
*/
static unsigned long
calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
{
if (hid_div) {
rate *= 2;
rate /= hid_div + 1;
}
if (mode) {
u64 tmp = rate;
tmp *= m;
do_div(tmp, n);
rate = tmp;
}
return rate;
}
static unsigned long
clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask;
regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
if (rcg->mnd_width) {
mask = BIT(rcg->mnd_width) - 1;
regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, &m);
m &= mask;
regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, &n);
n = ~n;
n &= mask;
n += m;
mode = cfg & CFG_MODE_MASK;
mode >>= CFG_MODE_SHIFT;
}
mask = BIT(rcg->hid_width) - 1;
hid_div = cfg >> CFG_SRC_DIV_SHIFT;
hid_div &= mask;
return calc_rate(parent_rate, m, n, mode, hid_div);
}
static const
struct freq_tbl *find_freq(const struct freq_tbl *f, unsigned long rate)
{
if (!f)
return NULL;
for (; f->freq; f++)
if (rate <= f->freq)
return f;
return NULL;
}
static long _freq_tbl_determine_rate(struct clk_hw *hw,
const struct freq_tbl *f, unsigned long rate,
unsigned long *p_rate, struct clk **p)
{
unsigned long clk_flags;
f = find_freq(f, rate);
if (!f)
return -EINVAL;
clk_flags = __clk_get_flags(hw->clk);
*p = clk_get_parent_by_index(hw->clk, f->src);
if (clk_flags & CLK_SET_RATE_PARENT) {
if (f->pre_div) {
rate /= 2;
rate *= f->pre_div + 1;
}
if (f->n) {
u64 tmp = rate;
tmp = tmp * f->n;
do_div(tmp, f->m);
rate = tmp;
}
} else {
rate = __clk_get_rate(*p);
}
*p_rate = rate;
return f->freq;
}
static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *p_rate, struct clk **p)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
}
static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const struct freq_tbl *f;
u32 cfg, mask;
int ret;
f = find_freq(rcg->freq_tbl, rate);
if (!f)
return -EINVAL;
if (rcg->mnd_width && f->n) {
mask = BIT(rcg->mnd_width) - 1;
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG,
mask, f->m);
if (ret)
return ret;
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG,
mask, ~(f->n - f->m));
if (ret)
return ret;
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + D_REG,
mask, ~f->n);
if (ret)
return ret;
}
mask = BIT(rcg->hid_width) - 1;
mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK;
cfg = f->pre_div << CFG_SRC_DIV_SHIFT;
cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT;
if (rcg->mnd_width && f->n)
cfg |= CFG_MODE_DUAL_EDGE;
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, mask,
cfg);
if (ret)
return ret;
return update_config(rcg);
}
static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return __clk_rcg2_set_rate(hw, rate);
}
static int clk_rcg2_set_rate_and_parent(struct clk_hw *hw,
unsigned long rate, unsigned long parent_rate, u8 index)
{
return __clk_rcg2_set_rate(hw, rate);
}
const struct clk_ops clk_rcg2_ops = {
.is_enabled = clk_rcg2_is_enabled,
.get_parent = clk_rcg2_get_parent,
.set_parent = clk_rcg2_set_parent,
.recalc_rate = clk_rcg2_recalc_rate,
.determine_rate = clk_rcg2_determine_rate,
.set_rate = clk_rcg2_set_rate,
.set_rate_and_parent = clk_rcg2_set_rate_and_parent,
};
EXPORT_SYMBOL_GPL(clk_rcg2_ops);

Просмотреть файл

@ -0,0 +1,114 @@
/*
* 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/device.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <linux/export.h>
#include "clk-regmap.h"
/**
* clk_is_enabled_regmap - standard is_enabled() for regmap users
*
* @hw: clk to operate on
*
* Clocks that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their struct clk_regmap and then use
* this as their is_enabled operation, saving some code.
*/
int clk_is_enabled_regmap(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
unsigned int val;
int ret;
ret = regmap_read(rclk->regmap, rclk->enable_reg, &val);
if (ret != 0)
return ret;
if (rclk->enable_is_inverted)
return (val & rclk->enable_mask) == 0;
else
return (val & rclk->enable_mask) != 0;
}
EXPORT_SYMBOL_GPL(clk_is_enabled_regmap);
/**
* clk_enable_regmap - standard enable() for regmap users
*
* @hw: clk to operate on
*
* Clocks that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their struct clk_regmap and then use
* this as their enable() operation, saving some code.
*/
int clk_enable_regmap(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
unsigned int val;
if (rclk->enable_is_inverted)
val = 0;
else
val = rclk->enable_mask;
return regmap_update_bits(rclk->regmap, rclk->enable_reg,
rclk->enable_mask, val);
}
EXPORT_SYMBOL_GPL(clk_enable_regmap);
/**
* clk_disable_regmap - standard disable() for regmap users
*
* @hw: clk to operate on
*
* Clocks that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their struct clk_regmap and then use
* this as their disable() operation, saving some code.
*/
void clk_disable_regmap(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
unsigned int val;
if (rclk->enable_is_inverted)
val = rclk->enable_mask;
else
val = 0;
regmap_update_bits(rclk->regmap, rclk->enable_reg, rclk->enable_mask,
val);
}
EXPORT_SYMBOL_GPL(clk_disable_regmap);
/**
* devm_clk_register_regmap - register a clk_regmap clock
*
* @rclk: clk to operate on
*
* Clocks that use regmap for their register I/O should register their
* clk_regmap struct via this function so that the regmap is initialized
* and so that the clock is registered with the common clock framework.
*/
struct clk *devm_clk_register_regmap(struct device *dev,
struct clk_regmap *rclk)
{
if (dev && dev_get_regmap(dev, NULL))
rclk->regmap = dev_get_regmap(dev, NULL);
else if (dev && dev->parent)
rclk->regmap = dev_get_regmap(dev->parent, NULL);
return devm_clk_register(dev, &rclk->hw);
}
EXPORT_SYMBOL_GPL(devm_clk_register_regmap);

Просмотреть файл

@ -0,0 +1,45 @@
/*
* 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_H__
#define __QCOM_CLK_REGMAP_H__
#include <linux/clk-provider.h>
struct regmap;
/**
* struct clk_regmap - regmap supporting clock
* @hw: handle between common and hardware-specific interfaces
* @regmap: regmap to use for regmap helpers and/or by providers
* @enable_reg: register when using regmap enable/disable ops
* @enable_mask: mask when using regmap enable/disable ops
* @enable_is_inverted: flag to indicate set enable_mask bits to disable
* when using clock_enable_regmap and friends APIs.
*/
struct clk_regmap {
struct clk_hw hw;
struct regmap *regmap;
unsigned int enable_reg;
unsigned int enable_mask;
bool enable_is_inverted;
};
#define to_clk_regmap(_hw) container_of(_hw, struct clk_regmap, hw)
int clk_is_enabled_regmap(struct clk_hw *hw);
int clk_enable_regmap(struct clk_hw *hw);
void clk_disable_regmap(struct clk_hw *hw);
struct clk *
devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk);
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

63
drivers/clk/qcom/reset.c Normal file
Просмотреть файл

@ -0,0 +1,63 @@
/*
* Copyright (c) 2013, 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/bitops.h>
#include <linux/export.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include <linux/delay.h>
#include "reset.h"
static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id)
{
rcdev->ops->assert(rcdev, id);
udelay(1);
rcdev->ops->deassert(rcdev, id);
return 0;
}
static int
qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
struct qcom_reset_controller *rst;
const struct qcom_reset_map *map;
u32 mask;
rst = to_qcom_reset_controller(rcdev);
map = &rst->reset_map[id];
mask = BIT(map->bit);
return regmap_update_bits(rst->regmap, map->reg, mask, mask);
}
static int
qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{
struct qcom_reset_controller *rst;
const struct qcom_reset_map *map;
u32 mask;
rst = to_qcom_reset_controller(rcdev);
map = &rst->reset_map[id];
mask = BIT(map->bit);
return regmap_update_bits(rst->regmap, map->reg, mask, 0);
}
struct reset_control_ops qcom_reset_ops = {
.reset = qcom_reset,
.assert = qcom_reset_assert,
.deassert = qcom_reset_deassert,
};
EXPORT_SYMBOL_GPL(qcom_reset_ops);

37
drivers/clk/qcom/reset.h Normal file
Просмотреть файл

@ -0,0 +1,37 @@
/*
* Copyright (c) 2013, 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_RESET_H__
#define __QCOM_CLK_RESET_H__
#include <linux/reset-controller.h>
struct qcom_reset_map {
unsigned int reg;
u8 bit;
};
struct regmap;
struct qcom_reset_controller {
const struct qcom_reset_map *reset_map;
struct regmap *regmap;
struct reset_controller_dev rcdev;
};
#define to_qcom_reset_controller(r) \
container_of(r, struct qcom_reset_controller, rcdev);
extern struct reset_control_ops qcom_reset_ops;
#endif

Просмотреть файл

@ -14,9 +14,17 @@
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <dt-bindings/clk/exynos-audss-clk.h>
enum exynos_audss_clk_type {
TYPE_EXYNOS4210,
TYPE_EXYNOS5250,
TYPE_EXYNOS5420,
};
static DEFINE_SPINLOCK(lock);
static struct clk **clk_table;
static void __iomem *reg_base;
@ -26,10 +34,6 @@ static struct clk_onecell_data clk_data;
#define ASS_CLK_DIV 0x4
#define ASS_CLK_GATE 0x8
/* list of all parent clock list */
static const char *mout_audss_p[] = { "fin_pll", "fout_epll" };
static const char *mout_i2s_p[] = { "mout_audss", "cdclk0", "sclk_audio0" };
#ifdef CONFIG_PM_SLEEP
static unsigned long reg_save[][2] = {
{ASS_CLK_SRC, 0},
@ -61,31 +65,69 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = {
};
#endif /* CONFIG_PM_SLEEP */
static const struct of_device_id exynos_audss_clk_of_match[] = {
{ .compatible = "samsung,exynos4210-audss-clock",
.data = (void *)TYPE_EXYNOS4210, },
{ .compatible = "samsung,exynos5250-audss-clock",
.data = (void *)TYPE_EXYNOS5250, },
{ .compatible = "samsung,exynos5420-audss-clock",
.data = (void *)TYPE_EXYNOS5420, },
{},
};
/* register exynos_audss clocks */
static void __init exynos_audss_clk_init(struct device_node *np)
static int exynos_audss_clk_probe(struct platform_device *pdev)
{
reg_base = of_iomap(np, 0);
if (!reg_base) {
pr_err("%s: failed to map audss registers\n", __func__);
return;
int i, ret = 0;
struct resource *res;
const char *mout_audss_p[] = {"fin_pll", "fout_epll"};
const char *mout_i2s_p[] = {"mout_audss", "cdclk0", "sclk_audio0"};
const char *sclk_pcm_p = "sclk_pcm0";
struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
const struct of_device_id *match;
enum exynos_audss_clk_type variant;
match = of_match_node(exynos_audss_clk_of_match, pdev->dev.of_node);
if (!match)
return -EINVAL;
variant = (enum exynos_audss_clk_type)match->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(reg_base)) {
dev_err(&pdev->dev, "failed to map audss registers\n");
return PTR_ERR(reg_base);
}
clk_table = kzalloc(sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
clk_table = devm_kzalloc(&pdev->dev,
sizeof(struct clk *) * EXYNOS_AUDSS_MAX_CLKS,
GFP_KERNEL);
if (!clk_table) {
pr_err("%s: could not allocate clk lookup table\n", __func__);
return;
}
if (!clk_table)
return -ENOMEM;
clk_data.clks = clk_table;
clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
if (variant == TYPE_EXYNOS5420)
clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS;
else
clk_data.clk_num = EXYNOS_AUDSS_MAX_CLKS - 1;
pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
pll_in = devm_clk_get(&pdev->dev, "pll_in");
if (!IS_ERR(pll_ref))
mout_audss_p[0] = __clk_get_name(pll_ref);
if (!IS_ERR(pll_in))
mout_audss_p[1] = __clk_get_name(pll_in);
clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
mout_audss_p, ARRAY_SIZE(mout_audss_p),
CLK_SET_RATE_NO_REPARENT,
reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
cdclk = devm_clk_get(&pdev->dev, "cdclk");
sclk_audio = devm_clk_get(&pdev->dev, "sclk_audio");
if (!IS_ERR(cdclk))
mout_i2s_p[1] = __clk_get_name(cdclk);
if (!IS_ERR(sclk_audio))
mout_i2s_p[2] = __clk_get_name(sclk_audio);
clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
CLK_SET_RATE_NO_REPARENT,
@ -119,17 +161,88 @@ static void __init exynos_audss_clk_init(struct device_node *np)
"sclk_pcm", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 4, 0, &lock);
sclk_pcm_in = devm_clk_get(&pdev->dev, "sclk_pcm_in");
if (!IS_ERR(sclk_pcm_in))
sclk_pcm_p = __clk_get_name(sclk_pcm_in);
clk_table[EXYNOS_SCLK_PCM] = clk_register_gate(NULL, "sclk_pcm",
"div_pcm0", CLK_SET_RATE_PARENT,
sclk_pcm_p, CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 5, 0, &lock);
if (variant == TYPE_EXYNOS5420) {
clk_table[EXYNOS_ADMA] = clk_register_gate(NULL, "adma",
"dout_srp", CLK_SET_RATE_PARENT,
reg_base + ASS_CLK_GATE, 9, 0, &lock);
}
for (i = 0; i < clk_data.clk_num; i++) {
if (IS_ERR(clk_table[i])) {
dev_err(&pdev->dev, "failed to register clock %d\n", i);
ret = PTR_ERR(clk_table[i]);
goto unregister;
}
}
ret = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
&clk_data);
if (ret) {
dev_err(&pdev->dev, "failed to add clock provider\n");
goto unregister;
}
#ifdef CONFIG_PM_SLEEP
register_syscore_ops(&exynos_audss_clk_syscore_ops);
#endif
pr_info("Exynos: Audss: clock setup completed\n");
dev_info(&pdev->dev, "setup completed\n");
return 0;
unregister:
for (i = 0; i < clk_data.clk_num; i++) {
if (!IS_ERR(clk_table[i]))
clk_unregister(clk_table[i]);
}
return ret;
}
CLK_OF_DECLARE(exynos4210_audss_clk, "samsung,exynos4210-audss-clock",
exynos_audss_clk_init);
CLK_OF_DECLARE(exynos5250_audss_clk, "samsung,exynos5250-audss-clock",
exynos_audss_clk_init);
static int exynos_audss_clk_remove(struct platform_device *pdev)
{
int i;
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]);
}
return 0;
}
static struct platform_driver exynos_audss_clk_driver = {
.driver = {
.name = "exynos-audss-clk",
.owner = THIS_MODULE,
.of_match_table = exynos_audss_clk_of_match,
},
.probe = exynos_audss_clk_probe,
.remove = exynos_audss_clk_remove,
};
static int __init exynos_audss_clk_init(void)
{
return platform_driver_register(&exynos_audss_clk_driver);
}
core_initcall(exynos_audss_clk_init);
static void __exit exynos_audss_clk_exit(void)
{
platform_driver_unregister(&exynos_audss_clk_driver);
}
module_exit(exynos_audss_clk_exit);
MODULE_AUTHOR("Padmavathi Venna <padma.v@samsung.com>");
MODULE_DESCRIPTION("Exynos Audio Subsystem Clock Controller");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:exynos-audss-clk");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -10,6 +10,7 @@
* Common Clock Framework support for Exynos5250 SoC.
*/
#include <dt-bindings/clock/exynos5250.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
@ -36,6 +37,7 @@
#define GPLL_CON0 0x10150
#define SRC_TOP0 0x10210
#define SRC_TOP2 0x10218
#define SRC_TOP3 0x1021c
#define SRC_GSCL 0x10220
#define SRC_DISP1_0 0x1022c
#define SRC_MAU 0x10240
@ -66,6 +68,7 @@
#define DIV_PERIC4 0x10568
#define DIV_PERIC5 0x1056c
#define GATE_IP_GSCL 0x10920
#define GATE_IP_DISP1 0x10928
#define GATE_IP_MFC 0x1092c
#define GATE_IP_GEN 0x10934
#define GATE_IP_FSYS 0x10944
@ -75,7 +78,6 @@
#define BPLL_CON0 0x20110
#define SRC_CDREX 0x20200
#define PLL_DIV2_SEL 0x20a24
#define GATE_IP_DISP1 0x10928
/* list of PLLs to be registered */
enum exynos5250_plls {
@ -83,52 +85,6 @@ enum exynos5250_plls {
nr_plls /* number of PLLs */
};
/*
* Let each supported clock get a unique id. This id is used to lookup the clock
* for device tree based platforms. The clocks are categorized into three
* sections: core, sclk gate and bus interface gate clocks.
*
* When adding a new clock to this list, it is advised to choose a clock
* category and add it to the end of that category. That is because the the
* device tree source file is referring to these ids and any change in the
* sequence number of existing clocks will require corresponding change in the
* device tree files. This limitation would go away when pre-processor support
* for dtc would be available.
*/
enum exynos5250_clks {
none,
/* core clocks */
fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll,
fout_epll, fout_vpll,
/* gate for special clocks (sclk) */
sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb,
sclk_fimd1, sclk_mipi1, sclk_dp, sclk_hdmi, sclk_pixel, sclk_audio0,
sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3,
sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm,
sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
div_i2s1, div_i2s2, sclk_hdmiphy,
/* gate clocks */
gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0,
smmu_gscl1, smmu_gscl2, smmu_gscl3, mfc, smmu_mfcl, smmu_mfcr, rotator,
jpeg, mdma1, smmu_rotator, smmu_jpeg, smmu_mdma1, pdma0, pdma1, sata,
usbotg, mipi_hsi, sdmmc0, sdmmc1, sdmmc2, sdmmc3, sromc, usb2, usb3,
sata_phyctrl, sata_phyi2c, uart0, uart1, uart2, uart3, uart4, i2c0,
i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, adc, spi0, spi1,
spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2,
hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1,
tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct,
wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi, g2d, mdma0,
smmu_mdma0,
/* mux clocks */
mout_hdmi = 1024,
nr_clks,
};
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
@ -139,6 +95,7 @@ static unsigned long exynos5250_clk_regs[] __initdata = {
SRC_CORE1,
SRC_TOP0,
SRC_TOP2,
SRC_TOP3,
SRC_GSCL,
SRC_DISP1_0,
SRC_MAU,
@ -182,7 +139,7 @@ static unsigned long exynos5250_clk_regs[] __initdata = {
/* list of all parent clock list */
PNAME(mout_apll_p) = { "fin_pll", "fout_apll", };
PNAME(mout_cpu_p) = { "mout_apll", "sclk_mpll", };
PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", };
PNAME(mout_mpll_fout_p) = { "fout_mplldiv2", "fout_mpll" };
PNAME(mout_mpll_p) = { "fin_pll", "mout_mpll_fout" };
PNAME(mout_bpll_fout_p) = { "fout_bplldiv2", "fout_bpll" };
@ -191,311 +148,432 @@ PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi27m" };
PNAME(mout_vpll_p) = { "mout_vpllsrc", "fout_vpll" };
PNAME(mout_cpll_p) = { "fin_pll", "fout_cpll" };
PNAME(mout_epll_p) = { "fin_pll", "fout_epll" };
PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll" };
PNAME(mout_bpll_user_p) = { "fin_pll", "sclk_bpll" };
PNAME(mout_aclk166_p) = { "sclk_cpll", "sclk_mpll_user" };
PNAME(mout_aclk200_p) = { "sclk_mpll_user", "sclk_bpll_user" };
PNAME(mout_mpll_user_p) = { "fin_pll", "mout_mpll" };
PNAME(mout_bpll_user_p) = { "fin_pll", "mout_bpll" };
PNAME(mout_aclk166_p) = { "mout_cpll", "mout_mpll_user" };
PNAME(mout_aclk200_p) = { "mout_mpll_user", "mout_bpll_user" };
PNAME(mout_aclk200_sub_p) = { "fin_pll", "div_aclk200" };
PNAME(mout_aclk266_sub_p) = { "fin_pll", "div_aclk266" };
PNAME(mout_aclk333_sub_p) = { "fin_pll", "div_aclk333" };
PNAME(mout_hdmi_p) = { "div_hdmi_pixel", "sclk_hdmiphy" };
PNAME(mout_usb3_p) = { "sclk_mpll_user", "sclk_cpll" };
PNAME(mout_usb3_p) = { "mout_mpll_user", "mout_cpll" };
PNAME(mout_group1_p) = { "fin_pll", "fin_pll", "sclk_hdmi27m",
"sclk_dptxphy", "sclk_uhostphy", "sclk_hdmiphy",
"sclk_mpll_user", "sclk_epll", "sclk_vpll",
"sclk_cpll" };
"mout_mpll_user", "mout_epll", "mout_vpll",
"mout_cpll", "none", "none",
"none", "none", "none",
"none" };
PNAME(mout_audio0_p) = { "cdclk0", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy",
"sclk_uhostphy", "sclk_hdmiphy",
"sclk_mpll_user", "sclk_epll", "sclk_vpll",
"sclk_cpll" };
"sclk_uhostphy", "fin_pll",
"mout_mpll_user", "mout_epll", "mout_vpll",
"mout_cpll", "none", "none",
"none", "none", "none",
"none" };
PNAME(mout_audio1_p) = { "cdclk1", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy",
"sclk_uhostphy", "sclk_hdmiphy",
"sclk_mpll_user", "sclk_epll", "sclk_vpll",
"sclk_cpll" };
"sclk_uhostphy", "fin_pll",
"mout_mpll_user", "mout_epll", "mout_vpll",
"mout_cpll", "none", "none",
"none", "none", "none",
"none" };
PNAME(mout_audio2_p) = { "cdclk2", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy",
"sclk_uhostphy", "sclk_hdmiphy",
"sclk_mpll_user", "sclk_epll", "sclk_vpll",
"sclk_cpll" };
"sclk_uhostphy", "fin_pll",
"mout_mpll_user", "mout_epll", "mout_vpll",
"mout_cpll", "none", "none",
"none", "none", "none",
"none" };
PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
"spdif_extclk" };
/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = {
FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
};
/* fixed rate clocks generated inside the soc */
static struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = {
FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
FRATE(none, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
FRATE(none, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000),
FRATE(none, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000),
FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
FRATE(0, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
FRATE(0, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000),
FRATE(0, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000),
};
static struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
FFACTOR(none, "fout_mplldiv2", "fout_mpll", 1, 2, 0),
FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
FFACTOR(0, "fout_mplldiv2", "fout_mpll", 1, 2, 0),
FFACTOR(0, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
};
static struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
};
static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
MUX_A(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, "mout_apll"),
MUX_A(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"),
MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1),
MUX_A(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"),
MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
MUX(none, "sclk_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1),
MUX(none, "sclk_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1),
MUX(none, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1),
MUX(none, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1),
MUX(none, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1),
MUX(none, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4),
MUX(none, "mout_cam0", mout_group1_p, SRC_GSCL, 16, 4),
MUX(none, "mout_cam1", mout_group1_p, SRC_GSCL, 20, 4),
MUX(none, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4),
MUX(none, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4),
MUX(none, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
MUX(none, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4),
MUX(none, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4),
MUX(mout_hdmi, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),
MUX(none, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4),
MUX(none, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4),
MUX(none, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4),
MUX(none, "mout_mmc2", mout_group1_p, SRC_FSYS, 8, 4),
MUX(none, "mout_mmc3", mout_group1_p, SRC_FSYS, 12, 4),
MUX(none, "mout_sata", mout_aclk200_p, SRC_FSYS, 24, 1),
MUX(none, "mout_usb3", mout_usb3_p, SRC_FSYS, 28, 1),
MUX(none, "mout_jpeg", mout_group1_p, SRC_GEN, 0, 4),
MUX(none, "mout_uart0", mout_group1_p, SRC_PERIC0, 0, 4),
MUX(none, "mout_uart1", mout_group1_p, SRC_PERIC0, 4, 4),
MUX(none, "mout_uart2", mout_group1_p, SRC_PERIC0, 8, 4),
MUX(none, "mout_uart3", mout_group1_p, SRC_PERIC0, 12, 4),
MUX(none, "mout_pwm", mout_group1_p, SRC_PERIC0, 24, 4),
MUX(none, "mout_audio1", mout_audio1_p, SRC_PERIC1, 0, 4),
MUX(none, "mout_audio2", mout_audio2_p, SRC_PERIC1, 4, 4),
MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIC1, 8, 2),
MUX(none, "mout_spi0", mout_group1_p, SRC_PERIC1, 16, 4),
MUX(none, "mout_spi1", mout_group1_p, SRC_PERIC1, 20, 4),
MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4),
/*
* NOTE: Following table is sorted by (clock domain, register address,
* bitfield shift) triplet in ascending order. When adding new entries,
* please make sure that the order is kept, to avoid merge conflicts
* and make further work with defined data easier.
*/
/*
* CMU_CPU
*/
MUX_FA(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
CLK_SET_RATE_PARENT, 0, "mout_apll"),
MUX_A(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1, "mout_cpu"),
/*
* CMU_CORE
*/
MUX_A(0, "mout_mpll", mout_mpll_p, SRC_CORE1, 8, 1, "mout_mpll"),
/*
* CMU_TOP
*/
MUX(0, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1),
MUX(0, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1),
MUX(0, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1),
MUX(0, "mout_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
MUX(0, "mout_epll", mout_epll_p, SRC_TOP2, 12, 1),
MUX(0, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
MUX(0, "mout_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1),
MUX(0, "mout_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1),
MUX(0, "mout_aclk200_disp1_sub", mout_aclk200_sub_p, SRC_TOP3, 4, 1),
MUX(0, "mout_aclk266_gscl_sub", mout_aclk266_sub_p, SRC_TOP3, 8, 1),
MUX(0, "mout_aclk333_sub", mout_aclk333_sub_p, SRC_TOP3, 24, 1),
MUX(0, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4),
MUX(0, "mout_cam0", mout_group1_p, SRC_GSCL, 16, 4),
MUX(0, "mout_cam1", mout_group1_p, SRC_GSCL, 20, 4),
MUX(0, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4),
MUX(0, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4),
MUX(0, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
MUX(0, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4),
MUX(0, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4),
MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),
MUX(0, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4),
MUX(0, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4),
MUX(0, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4),
MUX(0, "mout_mmc2", mout_group1_p, SRC_FSYS, 8, 4),
MUX(0, "mout_mmc3", mout_group1_p, SRC_FSYS, 12, 4),
MUX(0, "mout_sata", mout_aclk200_p, SRC_FSYS, 24, 1),
MUX(0, "mout_usb3", mout_usb3_p, SRC_FSYS, 28, 1),
MUX(0, "mout_jpeg", mout_group1_p, SRC_GEN, 0, 4),
MUX(0, "mout_uart0", mout_group1_p, SRC_PERIC0, 0, 4),
MUX(0, "mout_uart1", mout_group1_p, SRC_PERIC0, 4, 4),
MUX(0, "mout_uart2", mout_group1_p, SRC_PERIC0, 8, 4),
MUX(0, "mout_uart3", mout_group1_p, SRC_PERIC0, 12, 4),
MUX(0, "mout_pwm", mout_group1_p, SRC_PERIC0, 24, 4),
MUX(0, "mout_audio1", mout_audio1_p, SRC_PERIC1, 0, 4),
MUX(0, "mout_audio2", mout_audio2_p, SRC_PERIC1, 4, 4),
MUX(0, "mout_spdif", mout_spdif_p, SRC_PERIC1, 8, 2),
MUX(0, "mout_spi0", mout_group1_p, SRC_PERIC1, 16, 4),
MUX(0, "mout_spi1", mout_group1_p, SRC_PERIC1, 20, 4),
MUX(0, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4),
/*
* CMU_CDREX
*/
MUX(0, "mout_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
MUX(0, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1),
MUX(0, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
};
static struct samsung_div_clock exynos5250_div_clks[] __initdata = {
DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
DIV(none, "aclk66_pre", "sclk_mpll_user", DIV_TOP1, 24, 3),
DIV(none, "aclk66", "aclk66_pre", DIV_TOP0, 0, 3),
DIV(none, "aclk266", "sclk_mpll_user", DIV_TOP0, 16, 3),
DIV(none, "aclk166", "mout_aclk166", DIV_TOP0, 8, 3),
DIV(none, "aclk333", "mout_aclk333", DIV_TOP0, 20, 3),
DIV(none, "aclk200", "mout_aclk200", DIV_TOP0, 12, 3),
DIV(none, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4),
DIV(none, "div_cam0", "mout_cam0", DIV_GSCL, 16, 4),
DIV(none, "div_cam1", "mout_cam1", DIV_GSCL, 20, 4),
DIV(none, "div_gscl_wa", "mout_gscl_wa", DIV_GSCL, 24, 4),
DIV(none, "div_gscl_wb", "mout_gscl_wb", DIV_GSCL, 28, 4),
DIV(none, "div_fimd1", "mout_fimd1", DIV_DISP1_0, 0, 4),
DIV(none, "div_mipi1", "mout_mipi1", DIV_DISP1_0, 16, 4),
DIV(none, "div_dp", "mout_dp", DIV_DISP1_0, 24, 4),
DIV(none, "div_jpeg", "mout_jpeg", DIV_GEN, 4, 4),
DIV(none, "div_audio0", "mout_audio0", DIV_MAU, 0, 4),
DIV(none, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8),
DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
DIV(none, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4),
DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4),
DIV(none, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4),
DIV(none, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4),
DIV(none, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4),
DIV(none, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4),
DIV(none, "div_spi0", "mout_spi0", DIV_PERIC1, 0, 4),
DIV(none, "div_spi1", "mout_spi1", DIV_PERIC1, 16, 4),
DIV(none, "div_spi2", "mout_spi2", DIV_PERIC2, 0, 4),
DIV(none, "div_pwm", "mout_pwm", DIV_PERIC3, 0, 4),
DIV(none, "div_audio1", "mout_audio1", DIV_PERIC4, 0, 4),
DIV(none, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8),
DIV(none, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4),
DIV(none, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8),
DIV(div_i2s1, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
DIV(div_i2s2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
DIV(sclk_pixel, "div_hdmi_pixel", "sclk_vpll", DIV_DISP1_0, 28, 4),
DIV_A(none, "armclk", "div_arm", DIV_CPU0, 28, 3, "armclk"),
DIV_F(none, "div_mipi1_pre", "div_mipi1",
/*
* NOTE: Following table is sorted by (clock domain, register address,
* bitfield shift) triplet in ascending order. When adding new entries,
* please make sure that the order is kept, to avoid merge conflicts
* and make further work with defined data easier.
*/
/*
* CMU_CPU
*/
DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
DIV(0, "div_apll", "mout_apll", DIV_CPU0, 24, 3),
DIV_A(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3, "armclk"),
/*
* CMU_TOP
*/
DIV(0, "div_aclk66", "div_aclk66_pre", DIV_TOP0, 0, 3),
DIV(0, "div_aclk166", "mout_aclk166", DIV_TOP0, 8, 3),
DIV(0, "div_aclk200", "mout_aclk200", DIV_TOP0, 12, 3),
DIV(0, "div_aclk266", "mout_mpll_user", DIV_TOP0, 16, 3),
DIV(0, "div_aclk333", "mout_aclk333", DIV_TOP0, 20, 3),
DIV(0, "div_aclk66_pre", "mout_mpll_user", DIV_TOP1, 24, 3),
DIV(0, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4),
DIV(0, "div_cam0", "mout_cam0", DIV_GSCL, 16, 4),
DIV(0, "div_cam1", "mout_cam1", DIV_GSCL, 20, 4),
DIV(0, "div_gscl_wa", "mout_gscl_wa", DIV_GSCL, 24, 4),
DIV(0, "div_gscl_wb", "mout_gscl_wb", DIV_GSCL, 28, 4),
DIV(0, "div_fimd1", "mout_fimd1", DIV_DISP1_0, 0, 4),
DIV(0, "div_mipi1", "mout_mipi1", DIV_DISP1_0, 16, 4),
DIV_F(0, "div_mipi1_pre", "div_mipi1",
DIV_DISP1_0, 20, 4, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_mmc_pre0", "div_mmc0",
DIV(0, "div_dp", "mout_dp", DIV_DISP1_0, 24, 4),
DIV(CLK_SCLK_PIXEL, "div_hdmi_pixel", "mout_vpll", DIV_DISP1_0, 28, 4),
DIV(0, "div_jpeg", "mout_jpeg", DIV_GEN, 4, 4),
DIV(0, "div_audio0", "mout_audio0", DIV_MAU, 0, 4),
DIV(CLK_DIV_PCM0, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8),
DIV(0, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
DIV(0, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4),
DIV(0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
DIV_F(0, "div_mmc_pre0", "div_mmc0",
DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_mmc_pre1", "div_mmc1",
DIV(0, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
DIV_F(0, "div_mmc_pre1", "div_mmc1",
DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_mmc_pre2", "div_mmc2",
DIV(0, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
DIV_F(0, "div_mmc_pre2", "div_mmc2",
DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_mmc_pre3", "div_mmc3",
DIV(0, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4),
DIV_F(0, "div_mmc_pre3", "div_mmc3",
DIV_FSYS2, 24, 8, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_spi_pre0", "div_spi0",
DIV(0, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4),
DIV(0, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4),
DIV(0, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4),
DIV(0, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4),
DIV(0, "div_spi0", "mout_spi0", DIV_PERIC1, 0, 4),
DIV_F(0, "div_spi_pre0", "div_spi0",
DIV_PERIC1, 8, 8, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_spi_pre1", "div_spi1",
DIV(0, "div_spi1", "mout_spi1", DIV_PERIC1, 16, 4),
DIV_F(0, "div_spi_pre1", "div_spi1",
DIV_PERIC1, 24, 8, CLK_SET_RATE_PARENT, 0),
DIV_F(none, "div_spi_pre2", "div_spi2",
DIV(0, "div_spi2", "mout_spi2", DIV_PERIC2, 0, 4),
DIV_F(0, "div_spi_pre2", "div_spi2",
DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0),
DIV(0, "div_pwm", "mout_pwm", DIV_PERIC3, 0, 4),
DIV(0, "div_audio1", "mout_audio1", DIV_PERIC4, 0, 4),
DIV(0, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8),
DIV(0, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4),
DIV(0, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8),
DIV(CLK_DIV_I2S1, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
DIV(CLK_DIV_I2S2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
};
static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
GATE(gscl0, "gscl0", "none", GATE_IP_GSCL, 0, 0, 0),
GATE(gscl1, "gscl1", "none", GATE_IP_GSCL, 1, 0, 0),
GATE(gscl2, "gscl2", "aclk266", GATE_IP_GSCL, 2, 0, 0),
GATE(gscl3, "gscl3", "aclk266", GATE_IP_GSCL, 3, 0, 0),
GATE(gscl_wa, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0),
GATE(gscl_wb, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0),
GATE(smmu_gscl0, "smmu_gscl0", "aclk266", GATE_IP_GSCL, 7, 0, 0),
GATE(smmu_gscl1, "smmu_gscl1", "aclk266", GATE_IP_GSCL, 8, 0, 0),
GATE(smmu_gscl2, "smmu_gscl2", "aclk266", GATE_IP_GSCL, 9, 0, 0),
GATE(smmu_gscl3, "smmu_gscl3", "aclk266", GATE_IP_GSCL, 10, 0, 0),
GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 2, 0, 0),
GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 1, 0, 0),
GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0),
GATE(jpeg, "jpeg", "aclk166", GATE_IP_GEN, 2, 0, 0),
GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0),
GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0),
GATE(smmu_jpeg, "smmu_jpeg", "aclk166", GATE_IP_GEN, 7, 0, 0),
GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0),
GATE(pdma0, "pdma0", "aclk200", GATE_IP_FSYS, 1, 0, 0),
GATE(pdma1, "pdma1", "aclk200", GATE_IP_FSYS, 2, 0, 0),
GATE(sata, "sata", "aclk200", GATE_IP_FSYS, 6, 0, 0),
GATE(usbotg, "usbotg", "aclk200", GATE_IP_FSYS, 7, 0, 0),
GATE(mipi_hsi, "mipi_hsi", "aclk200", GATE_IP_FSYS, 8, 0, 0),
GATE(sdmmc0, "sdmmc0", "aclk200", GATE_IP_FSYS, 12, 0, 0),
GATE(sdmmc1, "sdmmc1", "aclk200", GATE_IP_FSYS, 13, 0, 0),
GATE(sdmmc2, "sdmmc2", "aclk200", GATE_IP_FSYS, 14, 0, 0),
GATE(sdmmc3, "sdmmc3", "aclk200", GATE_IP_FSYS, 15, 0, 0),
GATE(sromc, "sromc", "aclk200", GATE_IP_FSYS, 17, 0, 0),
GATE(usb2, "usb2", "aclk200", GATE_IP_FSYS, 18, 0, 0),
GATE(usb3, "usb3", "aclk200", GATE_IP_FSYS, 19, 0, 0),
GATE(sata_phyctrl, "sata_phyctrl", "aclk200", GATE_IP_FSYS, 24, 0, 0),
GATE(sata_phyi2c, "sata_phyi2c", "aclk200", GATE_IP_FSYS, 25, 0, 0),
GATE(uart0, "uart0", "aclk66", GATE_IP_PERIC, 0, 0, 0),
GATE(uart1, "uart1", "aclk66", GATE_IP_PERIC, 1, 0, 0),
GATE(uart2, "uart2", "aclk66", GATE_IP_PERIC, 2, 0, 0),
GATE(uart3, "uart3", "aclk66", GATE_IP_PERIC, 3, 0, 0),
GATE(uart4, "uart4", "aclk66", GATE_IP_PERIC, 4, 0, 0),
GATE(i2c0, "i2c0", "aclk66", GATE_IP_PERIC, 6, 0, 0),
GATE(i2c1, "i2c1", "aclk66", GATE_IP_PERIC, 7, 0, 0),
GATE(i2c2, "i2c2", "aclk66", GATE_IP_PERIC, 8, 0, 0),
GATE(i2c3, "i2c3", "aclk66", GATE_IP_PERIC, 9, 0, 0),
GATE(i2c4, "i2c4", "aclk66", GATE_IP_PERIC, 10, 0, 0),
GATE(i2c5, "i2c5", "aclk66", GATE_IP_PERIC, 11, 0, 0),
GATE(i2c6, "i2c6", "aclk66", GATE_IP_PERIC, 12, 0, 0),
GATE(i2c7, "i2c7", "aclk66", GATE_IP_PERIC, 13, 0, 0),
GATE(i2c_hdmi, "i2c_hdmi", "aclk66", GATE_IP_PERIC, 14, 0, 0),
GATE(adc, "adc", "aclk66", GATE_IP_PERIC, 15, 0, 0),
GATE(spi0, "spi0", "aclk66", GATE_IP_PERIC, 16, 0, 0),
GATE(spi1, "spi1", "aclk66", GATE_IP_PERIC, 17, 0, 0),
GATE(spi2, "spi2", "aclk66", GATE_IP_PERIC, 18, 0, 0),
GATE(i2s1, "i2s1", "aclk66", GATE_IP_PERIC, 20, 0, 0),
GATE(i2s2, "i2s2", "aclk66", GATE_IP_PERIC, 21, 0, 0),
GATE(pcm1, "pcm1", "aclk66", GATE_IP_PERIC, 22, 0, 0),
GATE(pcm2, "pcm2", "aclk66", GATE_IP_PERIC, 23, 0, 0),
GATE(pwm, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0),
GATE(spdif, "spdif", "aclk66", GATE_IP_PERIC, 26, 0, 0),
GATE(ac97, "ac97", "aclk66", GATE_IP_PERIC, 27, 0, 0),
GATE(hsi2c0, "hsi2c0", "aclk66", GATE_IP_PERIC, 28, 0, 0),
GATE(hsi2c1, "hsi2c1", "aclk66", GATE_IP_PERIC, 29, 0, 0),
GATE(hsi2c2, "hsi2c2", "aclk66", GATE_IP_PERIC, 30, 0, 0),
GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0),
GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0),
GATE(sysreg, "sysreg", "aclk66",
GATE_IP_PERIS, 1, CLK_IGNORE_UNUSED, 0),
GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED, 0),
GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0),
GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0),
GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0),
GATE(tzpc3, "tzpc3", "aclk66", GATE_IP_PERIS, 9, 0, 0),
GATE(tzpc4, "tzpc4", "aclk66", GATE_IP_PERIS, 10, 0, 0),
GATE(tzpc5, "tzpc5", "aclk66", GATE_IP_PERIS, 11, 0, 0),
GATE(tzpc6, "tzpc6", "aclk66", GATE_IP_PERIS, 12, 0, 0),
GATE(tzpc7, "tzpc7", "aclk66", GATE_IP_PERIS, 13, 0, 0),
GATE(tzpc8, "tzpc8", "aclk66", GATE_IP_PERIS, 14, 0, 0),
GATE(tzpc9, "tzpc9", "aclk66", GATE_IP_PERIS, 15, 0, 0),
GATE(hdmi_cec, "hdmi_cec", "aclk66", GATE_IP_PERIS, 16, 0, 0),
GATE(mct, "mct", "aclk66", GATE_IP_PERIS, 18, 0, 0),
GATE(wdt, "wdt", "aclk66", GATE_IP_PERIS, 19, 0, 0),
GATE(rtc, "rtc", "aclk66", GATE_IP_PERIS, 20, 0, 0),
GATE(tmu, "tmu", "aclk66", GATE_IP_PERIS, 21, 0, 0),
GATE(cmu_top, "cmu_top", "aclk66",
GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0),
GATE(cmu_core, "cmu_core", "aclk66",
GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0),
GATE(cmu_mem, "cmu_mem", "aclk66",
GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0),
GATE(sclk_cam_bayer, "sclk_cam_bayer", "div_cam_bayer",
/*
* NOTE: Following table is sorted by (clock domain, register address,
* bitfield shift) triplet in ascending order. When adding new entries,
* please make sure that the order is kept, to avoid merge conflicts
* and make further work with defined data easier.
*/
/*
* CMU_ACP
*/
GATE(CLK_MDMA0, "mdma0", "div_aclk266", GATE_IP_ACP, 1, 0, 0),
GATE(CLK_G2D, "g2d", "div_aclk200", GATE_IP_ACP, 3, 0, 0),
GATE(CLK_SMMU_MDMA0, "smmu_mdma0", "div_aclk266", GATE_IP_ACP, 5, 0, 0),
/*
* CMU_TOP
*/
GATE(CLK_SCLK_CAM_BAYER, "sclk_cam_bayer", "div_cam_bayer",
SRC_MASK_GSCL, 12, CLK_SET_RATE_PARENT, 0),
GATE(sclk_cam0, "sclk_cam0", "div_cam0",
GATE(CLK_SCLK_CAM0, "sclk_cam0", "div_cam0",
SRC_MASK_GSCL, 16, CLK_SET_RATE_PARENT, 0),
GATE(sclk_cam1, "sclk_cam1", "div_cam1",
GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1",
SRC_MASK_GSCL, 20, CLK_SET_RATE_PARENT, 0),
GATE(sclk_gscl_wa, "sclk_gscl_wa", "div_gscl_wa",
GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "div_gscl_wa",
SRC_MASK_GSCL, 24, CLK_SET_RATE_PARENT, 0),
GATE(sclk_gscl_wb, "sclk_gscl_wb", "div_gscl_wb",
GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "div_gscl_wb",
SRC_MASK_GSCL, 28, CLK_SET_RATE_PARENT, 0),
GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1",
GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "div_fimd1",
SRC_MASK_DISP1_0, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mipi1, "sclk_mipi1", "div_mipi1",
GATE(CLK_SCLK_MIPI1, "sclk_mipi1", "div_mipi1",
SRC_MASK_DISP1_0, 12, CLK_SET_RATE_PARENT, 0),
GATE(sclk_dp, "sclk_dp", "div_dp",
GATE(CLK_SCLK_DP, "sclk_dp", "div_dp",
SRC_MASK_DISP1_0, 16, CLK_SET_RATE_PARENT, 0),
GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi",
GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi",
SRC_MASK_DISP1_0, 20, 0, 0),
GATE(sclk_audio0, "sclk_audio0", "div_audio0",
GATE(CLK_SCLK_AUDIO0, "sclk_audio0", "div_audio0",
SRC_MASK_MAU, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc0, "sclk_mmc0", "div_mmc_pre0",
GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc_pre0",
SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc1, "sclk_mmc1", "div_mmc_pre1",
GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc_pre1",
SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc2, "sclk_mmc2", "div_mmc_pre2",
GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc_pre2",
SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc3, "sclk_mmc3", "div_mmc_pre3",
GATE(CLK_SCLK_MMC3, "sclk_mmc3", "div_mmc_pre3",
SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0),
GATE(sclk_sata, "sclk_sata", "div_sata",
GATE(CLK_SCLK_SATA, "sclk_sata", "div_sata",
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
GATE(sclk_usb3, "sclk_usb3", "div_usb3",
GATE(CLK_SCLK_USB3, "sclk_usb3", "div_usb3",
SRC_MASK_FSYS, 28, CLK_SET_RATE_PARENT, 0),
GATE(sclk_jpeg, "sclk_jpeg", "div_jpeg",
GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_jpeg",
SRC_MASK_GEN, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart0, "sclk_uart0", "div_uart0",
GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart1, "sclk_uart1", "div_uart1",
GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart2, "sclk_uart2", "div_uart2",
GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart3, "sclk_uart3", "div_uart3",
GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3",
SRC_MASK_PERIC0, 12, CLK_SET_RATE_PARENT, 0),
GATE(sclk_pwm, "sclk_pwm", "div_pwm",
GATE(CLK_SCLK_PWM, "sclk_pwm", "div_pwm",
SRC_MASK_PERIC0, 24, CLK_SET_RATE_PARENT, 0),
GATE(sclk_audio1, "sclk_audio1", "div_audio1",
GATE(CLK_SCLK_AUDIO1, "sclk_audio1", "div_audio1",
SRC_MASK_PERIC1, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_audio2, "sclk_audio2", "div_audio2",
GATE(CLK_SCLK_AUDIO2, "sclk_audio2", "div_audio2",
SRC_MASK_PERIC1, 4, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spdif, "sclk_spdif", "mout_spdif",
GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif",
SRC_MASK_PERIC1, 4, 0, 0),
GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0",
GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi_pre0",
SRC_MASK_PERIC1, 16, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1",
GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi_pre1",
SRC_MASK_PERIC1, 20, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2",
GATE(CLK_SCLK_SPI2, "sclk_spi2", "div_spi_pre2",
SRC_MASK_PERIC1, 24, CLK_SET_RATE_PARENT, 0),
GATE(fimd1, "fimd1", "aclk200", GATE_IP_DISP1, 0, 0, 0),
GATE(mie1, "mie1", "aclk200", GATE_IP_DISP1, 1, 0, 0),
GATE(dsim0, "dsim0", "aclk200", GATE_IP_DISP1, 3, 0, 0),
GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0),
GATE(mixer, "mixer", "mout_aclk200_disp1", GATE_IP_DISP1, 5, 0, 0),
GATE(hdmi, "hdmi", "mout_aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
GATE(g2d, "g2d", "aclk200", GATE_IP_ACP, 3, 0, 0),
GATE(mdma0, "mdma0", "aclk266", GATE_IP_ACP, 1, 0, 0),
GATE(smmu_mdma0, "smmu_mdma0", "aclk266", GATE_IP_ACP, 5, 0, 0),
GATE(CLK_GSCL0, "gscl0", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 0, 0,
0),
GATE(CLK_GSCL1, "gscl1", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 1, 0,
0),
GATE(CLK_GSCL2, "gscl2", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 2, 0,
0),
GATE(CLK_GSCL3, "gscl3", "mout_aclk266_gscl_sub", GATE_IP_GSCL, 3, 0,
0),
GATE(CLK_GSCL_WA, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0),
GATE(CLK_GSCL_WB, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0),
GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "mout_aclk266_gscl_sub",
GATE_IP_GSCL, 7, 0, 0),
GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "mout_aclk266_gscl_sub",
GATE_IP_GSCL, 8, 0, 0),
GATE(CLK_SMMU_GSCL2, "smmu_gscl2", "mout_aclk266_gscl_sub",
GATE_IP_GSCL, 9, 0, 0),
GATE(CLK_SMMU_GSCL3, "smmu_gscl3", "mout_aclk266_gscl_sub",
GATE_IP_GSCL, 10, 0, 0),
GATE(CLK_FIMD1, "fimd1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 0, 0,
0),
GATE(CLK_MIE1, "mie1", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 1, 0,
0),
GATE(CLK_DSIM0, "dsim0", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 3, 0,
0),
GATE(CLK_DP, "dp", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 4, 0, 0),
GATE(CLK_MIXER, "mixer", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 5, 0,
0),
GATE(CLK_HDMI, "hdmi", "mout_aclk200_disp1_sub", GATE_IP_DISP1, 6, 0,
0),
GATE(CLK_MFC, "mfc", "mout_aclk333_sub", GATE_IP_MFC, 0, 0, 0),
GATE(CLK_SMMU_MFCR, "smmu_mfcr", "mout_aclk333_sub", GATE_IP_MFC, 1, 0,
0),
GATE(CLK_SMMU_MFCL, "smmu_mfcl", "mout_aclk333_sub", GATE_IP_MFC, 2, 0,
0),
GATE(CLK_ROTATOR, "rotator", "div_aclk266", GATE_IP_GEN, 1, 0, 0),
GATE(CLK_JPEG, "jpeg", "div_aclk166", GATE_IP_GEN, 2, 0, 0),
GATE(CLK_MDMA1, "mdma1", "div_aclk266", GATE_IP_GEN, 4, 0, 0),
GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "div_aclk266", GATE_IP_GEN, 6, 0,
0),
GATE(CLK_SMMU_JPEG, "smmu_jpeg", "div_aclk166", GATE_IP_GEN, 7, 0, 0),
GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "div_aclk266", GATE_IP_GEN, 9, 0, 0),
GATE(CLK_PDMA0, "pdma0", "div_aclk200", GATE_IP_FSYS, 1, 0, 0),
GATE(CLK_PDMA1, "pdma1", "div_aclk200", GATE_IP_FSYS, 2, 0, 0),
GATE(CLK_SATA, "sata", "div_aclk200", GATE_IP_FSYS, 6, 0, 0),
GATE(CLK_USBOTG, "usbotg", "div_aclk200", GATE_IP_FSYS, 7, 0, 0),
GATE(CLK_MIPI_HSI, "mipi_hsi", "div_aclk200", GATE_IP_FSYS, 8, 0, 0),
GATE(CLK_SDMMC0, "sdmmc0", "div_aclk200", GATE_IP_FSYS, 12, 0, 0),
GATE(CLK_SDMMC1, "sdmmc1", "div_aclk200", GATE_IP_FSYS, 13, 0, 0),
GATE(CLK_SDMMC2, "sdmmc2", "div_aclk200", GATE_IP_FSYS, 14, 0, 0),
GATE(CLK_SDMMC3, "sdmmc3", "div_aclk200", GATE_IP_FSYS, 15, 0, 0),
GATE(CLK_SROMC, "sromc", "div_aclk200", GATE_IP_FSYS, 17, 0, 0),
GATE(CLK_USB2, "usb2", "div_aclk200", GATE_IP_FSYS, 18, 0, 0),
GATE(CLK_USB3, "usb3", "div_aclk200", GATE_IP_FSYS, 19, 0, 0),
GATE(CLK_SATA_PHYCTRL, "sata_phyctrl", "div_aclk200",
GATE_IP_FSYS, 24, 0, 0),
GATE(CLK_SATA_PHYI2C, "sata_phyi2c", "div_aclk200", GATE_IP_FSYS, 25, 0,
0),
GATE(CLK_UART0, "uart0", "div_aclk66", GATE_IP_PERIC, 0, 0, 0),
GATE(CLK_UART1, "uart1", "div_aclk66", GATE_IP_PERIC, 1, 0, 0),
GATE(CLK_UART2, "uart2", "div_aclk66", GATE_IP_PERIC, 2, 0, 0),
GATE(CLK_UART3, "uart3", "div_aclk66", GATE_IP_PERIC, 3, 0, 0),
GATE(CLK_UART4, "uart4", "div_aclk66", GATE_IP_PERIC, 4, 0, 0),
GATE(CLK_I2C0, "i2c0", "div_aclk66", GATE_IP_PERIC, 6, 0, 0),
GATE(CLK_I2C1, "i2c1", "div_aclk66", GATE_IP_PERIC, 7, 0, 0),
GATE(CLK_I2C2, "i2c2", "div_aclk66", GATE_IP_PERIC, 8, 0, 0),
GATE(CLK_I2C3, "i2c3", "div_aclk66", GATE_IP_PERIC, 9, 0, 0),
GATE(CLK_I2C4, "i2c4", "div_aclk66", GATE_IP_PERIC, 10, 0, 0),
GATE(CLK_I2C5, "i2c5", "div_aclk66", GATE_IP_PERIC, 11, 0, 0),
GATE(CLK_I2C6, "i2c6", "div_aclk66", GATE_IP_PERIC, 12, 0, 0),
GATE(CLK_I2C7, "i2c7", "div_aclk66", GATE_IP_PERIC, 13, 0, 0),
GATE(CLK_I2C_HDMI, "i2c_hdmi", "div_aclk66", GATE_IP_PERIC, 14, 0, 0),
GATE(CLK_ADC, "adc", "div_aclk66", GATE_IP_PERIC, 15, 0, 0),
GATE(CLK_SPI0, "spi0", "div_aclk66", GATE_IP_PERIC, 16, 0, 0),
GATE(CLK_SPI1, "spi1", "div_aclk66", GATE_IP_PERIC, 17, 0, 0),
GATE(CLK_SPI2, "spi2", "div_aclk66", GATE_IP_PERIC, 18, 0, 0),
GATE(CLK_I2S1, "i2s1", "div_aclk66", GATE_IP_PERIC, 20, 0, 0),
GATE(CLK_I2S2, "i2s2", "div_aclk66", GATE_IP_PERIC, 21, 0, 0),
GATE(CLK_PCM1, "pcm1", "div_aclk66", GATE_IP_PERIC, 22, 0, 0),
GATE(CLK_PCM2, "pcm2", "div_aclk66", GATE_IP_PERIC, 23, 0, 0),
GATE(CLK_PWM, "pwm", "div_aclk66", GATE_IP_PERIC, 24, 0, 0),
GATE(CLK_SPDIF, "spdif", "div_aclk66", GATE_IP_PERIC, 26, 0, 0),
GATE(CLK_AC97, "ac97", "div_aclk66", GATE_IP_PERIC, 27, 0, 0),
GATE(CLK_HSI2C0, "hsi2c0", "div_aclk66", GATE_IP_PERIC, 28, 0, 0),
GATE(CLK_HSI2C1, "hsi2c1", "div_aclk66", GATE_IP_PERIC, 29, 0, 0),
GATE(CLK_HSI2C2, "hsi2c2", "div_aclk66", GATE_IP_PERIC, 30, 0, 0),
GATE(CLK_HSI2C3, "hsi2c3", "div_aclk66", GATE_IP_PERIC, 31, 0, 0),
GATE(CLK_CHIPID, "chipid", "div_aclk66", GATE_IP_PERIS, 0, 0, 0),
GATE(CLK_SYSREG, "sysreg", "div_aclk66",
GATE_IP_PERIS, 1, CLK_IGNORE_UNUSED, 0),
GATE(CLK_PMU, "pmu", "div_aclk66", GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED,
0),
GATE(CLK_CMU_TOP, "cmu_top", "div_aclk66",
GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0),
GATE(CLK_CMU_CORE, "cmu_core", "div_aclk66",
GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0),
GATE(CLK_CMU_MEM, "cmu_mem", "div_aclk66",
GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0),
GATE(CLK_TZPC0, "tzpc0", "div_aclk66", GATE_IP_PERIS, 6, 0, 0),
GATE(CLK_TZPC1, "tzpc1", "div_aclk66", GATE_IP_PERIS, 7, 0, 0),
GATE(CLK_TZPC2, "tzpc2", "div_aclk66", GATE_IP_PERIS, 8, 0, 0),
GATE(CLK_TZPC3, "tzpc3", "div_aclk66", GATE_IP_PERIS, 9, 0, 0),
GATE(CLK_TZPC4, "tzpc4", "div_aclk66", GATE_IP_PERIS, 10, 0, 0),
GATE(CLK_TZPC5, "tzpc5", "div_aclk66", GATE_IP_PERIS, 11, 0, 0),
GATE(CLK_TZPC6, "tzpc6", "div_aclk66", GATE_IP_PERIS, 12, 0, 0),
GATE(CLK_TZPC7, "tzpc7", "div_aclk66", GATE_IP_PERIS, 13, 0, 0),
GATE(CLK_TZPC8, "tzpc8", "div_aclk66", GATE_IP_PERIS, 14, 0, 0),
GATE(CLK_TZPC9, "tzpc9", "div_aclk66", GATE_IP_PERIS, 15, 0, 0),
GATE(CLK_HDMI_CEC, "hdmi_cec", "div_aclk66", GATE_IP_PERIS, 16, 0, 0),
GATE(CLK_MCT, "mct", "div_aclk66", GATE_IP_PERIS, 18, 0, 0),
GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0),
GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0),
GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0),
};
static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = {
@ -521,20 +599,41 @@ static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = {
{ },
};
static struct samsung_pll_rate_table apll_24mhz_tbl[] __initdata = {
/* sorted in descending order */
/* PLL_35XX_RATE(rate, m, p, s) */
PLL_35XX_RATE(1700000000, 425, 6, 0),
PLL_35XX_RATE(1600000000, 200, 3, 0),
PLL_35XX_RATE(1500000000, 250, 4, 0),
PLL_35XX_RATE(1400000000, 175, 3, 0),
PLL_35XX_RATE(1300000000, 325, 6, 0),
PLL_35XX_RATE(1200000000, 200, 4, 0),
PLL_35XX_RATE(1100000000, 275, 6, 0),
PLL_35XX_RATE(1000000000, 125, 3, 0),
PLL_35XX_RATE(900000000, 150, 4, 0),
PLL_35XX_RATE(800000000, 100, 3, 0),
PLL_35XX_RATE(700000000, 175, 3, 1),
PLL_35XX_RATE(600000000, 200, 4, 1),
PLL_35XX_RATE(500000000, 125, 3, 1),
PLL_35XX_RATE(400000000, 100, 3, 1),
PLL_35XX_RATE(300000000, 200, 4, 2),
PLL_35XX_RATE(200000000, 100, 3, 2),
};
static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = {
[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
APLL_CON0, "fout_apll", NULL),
[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
MPLL_CON0, "fout_mpll", NULL),
[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
[apll] = PLL_A(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
APLL_LOCK, APLL_CON0, "fout_apll", NULL),
[mpll] = PLL_A(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
MPLL_LOCK, MPLL_CON0, "fout_mpll", NULL),
[bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK,
BPLL_CON0, NULL),
[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
[gpll] = PLL(pll_35xx, CLK_FOUT_GPLL, "fout_gpll", "fin_pll", GPLL_LOCK,
GPLL_CON0, NULL),
[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
[cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK,
CPLL_CON0, NULL),
[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
[epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK,
EPLL_CON0, NULL),
[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
[vpll] = PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll", "mout_vpllsrc",
VPLL_LOCK, VPLL_CON0, NULL),
};
@ -556,7 +655,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
panic("%s: unable to determine soc\n", __func__);
}
samsung_clk_init(np, reg_base, nr_clks,
samsung_clk_init(np, reg_base, CLK_NR_CLKS,
exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs),
NULL, 0);
samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
@ -565,8 +664,10 @@ static void __init exynos5250_clk_init(struct device_node *np)
samsung_clk_register_mux(exynos5250_pll_pmux_clks,
ARRAY_SIZE(exynos5250_pll_pmux_clks));
if (_get_rate("fin_pll") == 24 * MHZ)
if (_get_rate("fin_pll") == 24 * MHZ) {
exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
exynos5250_plls[apll].rate_table = apll_24mhz_tbl;
}
if (_get_rate("mout_vpllsrc") == 24 * MHZ)
exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl;
@ -585,6 +686,6 @@ static void __init exynos5250_clk_init(struct device_node *np)
ARRAY_SIZE(exynos5250_gate_clks));
pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
_get_rate("armclk"));
_get_rate("div_arm2"));
}
CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init);

Просмотреть файл

@ -10,6 +10,7 @@
* Common Clock Framework support for Exynos5420 SoC.
*/
#include <dt-bindings/clock/exynos5420.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
@ -107,48 +108,6 @@ enum exynos5420_plls {
nr_plls /* number of PLLs */
};
enum exynos5420_clks {
none,
/* core clocks */
fin_pll, fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll,
fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll,
/* gate for special clocks (sclk) */
sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
sclk_mmc1, sclk_mmc2, sclk_spi0, sclk_spi1, sclk_spi2, sclk_i2s1,
sclk_i2s2, sclk_pcm1, sclk_pcm2, sclk_spdif, sclk_hdmi, sclk_pixel,
sclk_dp1, sclk_mipi1, sclk_fimd1, sclk_maudio0, sclk_maupcm0,
sclk_usbd300, sclk_usbd301, sclk_usbphy300, sclk_usbphy301, sclk_unipro,
sclk_pwm, sclk_gscl_wa, sclk_gscl_wb, sclk_hdmiphy,
/* gate clocks */
aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3,
i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, spi0, spi1, spi2, keyif, i2s1,
i2s2, pcm1, pcm2, pwm, spdif, i2c8, i2c9, i2c10, aclk66_psgen = 300,
chipid, sysreg, tzpc0, tzpc1, tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7,
tzpc8, tzpc9, hdmi_cec, seckey, mct, wdt, rtc, tmu, tmu_gpu,
pclk66_gpio = 330, aclk200_fsys2 = 350, mmc0, mmc1, mmc2, sromc, ufs,
aclk200_fsys = 360, tsi, pdma0, pdma1, rtic, usbh20, usbd300, usbd301,
aclk400_mscl = 380, mscl0, mscl1, mscl2, smmu_mscl0, smmu_mscl1,
smmu_mscl2, aclk333 = 400, mfc, smmu_mfcl, smmu_mfcr,
aclk200_disp1 = 410, dsim1, dp1, hdmi, aclk300_disp1 = 420, fimd1,
smmu_fimd1, aclk166 = 430, mixer, aclk266 = 440, rotator, mdma1,
smmu_rotator, smmu_mdma1, aclk300_jpeg = 450, jpeg, jpeg2, smmu_jpeg,
aclk300_gscl = 460, smmu_gscl0, smmu_gscl1, gscl_wa, gscl_wb, gscl0,
gscl1, clk_3aa, aclk266_g2d = 470, sss, slim_sss, mdma0,
aclk333_g2d = 480, g2d, aclk333_432_gscl = 490, smmu_3aa, smmu_fimcl0,
smmu_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d, smmu_mixer,
/* mux clocks */
mout_hdmi = 640,
/* divider clocks */
dout_pixel = 768,
nr_clks,
};
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
@ -298,225 +257,226 @@ PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll",
/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = {
FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0),
};
/* fixed rate clocks generated inside the soc */
static struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = {
FRATE(sclk_hdmiphy, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
FRATE(none, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000),
FRATE(none, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000),
FRATE(none, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000),
FRATE(none, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000),
FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
FRATE(0, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000),
FRATE(0, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000),
FRATE(0, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000),
FRATE(0, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000),
};
static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = {
FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0),
FFACTOR(0, "sclk_hsic_12m", "fin_pll", 1, 2, 0),
};
static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
MUX(none, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2),
MUX(none, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2),
MUX(none, "mout_apll", apll_p, SRC_CPU, 0, 1),
MUX(none, "mout_cpu", cpu_p, SRC_CPU, 16, 1),
MUX(none, "mout_kpll", kpll_p, SRC_KFC, 0, 1),
MUX(none, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1),
MUX(0, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2),
MUX(0, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2),
MUX(0, "mout_apll", apll_p, SRC_CPU, 0, 1),
MUX(0, "mout_cpu", cpu_p, SRC_CPU, 16, 1),
MUX(0, "mout_kpll", kpll_p, SRC_KFC, 0, 1),
MUX(0, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1),
MUX(none, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1),
MUX(0, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1),
MUX_A(none, "mout_aclk400_mscl", group1_p,
MUX_A(0, "mout_aclk400_mscl", group1_p,
SRC_TOP0, 4, 2, "aclk400_mscl"),
MUX(none, "mout_aclk200", group1_p, SRC_TOP0, 8, 2),
MUX(none, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2),
MUX(none, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2),
MUX(0, "mout_aclk200", group1_p, SRC_TOP0, 8, 2),
MUX(0, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2),
MUX(0, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2),
MUX(none, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2),
MUX(none, "mout_aclk66", group1_p, SRC_TOP1, 8, 2),
MUX(none, "mout_aclk266", group1_p, SRC_TOP1, 20, 2),
MUX(none, "mout_aclk166", group1_p, SRC_TOP1, 24, 2),
MUX(none, "mout_aclk333", group1_p, SRC_TOP1, 28, 2),
MUX(0, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2),
MUX(0, "mout_aclk66", group1_p, SRC_TOP1, 8, 2),
MUX(0, "mout_aclk266", group1_p, SRC_TOP1, 20, 2),
MUX(0, "mout_aclk166", group1_p, SRC_TOP1, 24, 2),
MUX(0, "mout_aclk333", group1_p, SRC_TOP1, 28, 2),
MUX(none, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2),
MUX(none, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2),
MUX(none, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1),
MUX(none, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2),
MUX(none, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2),
MUX(none, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2),
MUX(0, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2),
MUX(0, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2),
MUX(0, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1),
MUX(0, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2),
MUX(0, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2),
MUX(0, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2),
MUX(none, "mout_user_aclk400_mscl", user_aclk400_mscl_p,
MUX(0, "mout_user_aclk400_mscl", user_aclk400_mscl_p,
SRC_TOP3, 4, 1),
MUX_A(none, "mout_aclk200_disp1", aclk200_disp1_p,
MUX_A(0, "mout_aclk200_disp1", aclk200_disp1_p,
SRC_TOP3, 8, 1, "aclk200_disp1"),
MUX(none, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p,
MUX(0, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p,
SRC_TOP3, 12, 1),
MUX(none, "mout_user_aclk200_fsys", user_aclk200_fsys_p,
MUX(0, "mout_user_aclk200_fsys", user_aclk200_fsys_p,
SRC_TOP3, 28, 1),
MUX(none, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p,
MUX(0, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p,
SRC_TOP4, 0, 1),
MUX(none, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1),
MUX(none, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1),
MUX(none, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1),
MUX(none, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1),
MUX(0, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1),
MUX(0, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1),
MUX(0, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1),
MUX(0, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1),
MUX(none, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1),
MUX(none, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1),
MUX(none, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1),
MUX_A(none, "mout_user_aclk_g3d", user_aclk_g3d_p,
MUX(0, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1),
MUX(0, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1),
MUX(0, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1),
MUX_A(0, "mout_user_aclk_g3d", user_aclk_g3d_p,
SRC_TOP5, 16, 1, "aclkg3d"),
MUX(none, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p,
MUX(0, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p,
SRC_TOP5, 20, 1),
MUX(none, "mout_user_aclk300_disp1", user_aclk300_disp1_p,
MUX(0, "mout_user_aclk300_disp1", user_aclk300_disp1_p,
SRC_TOP5, 24, 1),
MUX(none, "mout_user_aclk300_gscl", user_aclk300_gscl_p,
MUX(0, "mout_user_aclk300_gscl", user_aclk300_gscl_p,
SRC_TOP5, 28, 1),
MUX(none, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1),
MUX(none, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1),
MUX(none, "sclk_spll", spll_p, SRC_TOP6, 8, 1),
MUX(none, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1),
MUX(none, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1),
MUX(none, "sclk_epll", epll_p, SRC_TOP6, 20, 1),
MUX(none, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1),
MUX(none, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1),
MUX(0, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1),
MUX(0, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1),
MUX(0, "sclk_spll", spll_p, SRC_TOP6, 8, 1),
MUX(0, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1),
MUX(0, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1),
MUX(0, "sclk_epll", epll_p, SRC_TOP6, 20, 1),
MUX(0, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1),
MUX(0, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1),
MUX(none, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1),
MUX(none, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1),
MUX(none, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p,
MUX(0, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1),
MUX(0, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1),
MUX(0, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p,
SRC_TOP10, 12, 1),
MUX(none, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1),
MUX(0, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1),
MUX(none, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p,
MUX(0, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p,
SRC_TOP11, 0, 1),
MUX(none, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1),
MUX(none, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1),
MUX(none, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1),
MUX(none, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1),
MUX(0, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1),
MUX(0, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1),
MUX(0, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1),
MUX(0, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1),
MUX(none, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1),
MUX(none, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1),
MUX(none, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1),
MUX(none, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1),
MUX(none, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p,
MUX(0, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1),
MUX(0, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1),
MUX(0, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1),
MUX(0, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1),
MUX(0, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p,
SRC_TOP12, 24, 1),
MUX(none, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1),
MUX(0, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1),
/* DISP1 Block */
MUX(none, "mout_fimd1", group3_p, SRC_DISP10, 4, 1),
MUX(none, "mout_mipi1", group2_p, SRC_DISP10, 16, 3),
MUX(none, "mout_dp1", group2_p, SRC_DISP10, 20, 3),
MUX(none, "mout_pixel", group2_p, SRC_DISP10, 24, 3),
MUX(mout_hdmi, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1),
MUX(0, "mout_fimd1", group3_p, SRC_DISP10, 4, 1),
MUX(0, "mout_mipi1", group2_p, SRC_DISP10, 16, 3),
MUX(0, "mout_dp1", group2_p, SRC_DISP10, 20, 3),
MUX(0, "mout_pixel", group2_p, SRC_DISP10, 24, 3),
MUX(CLK_MOUT_HDMI, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1),
/* MAU Block */
MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3),
MUX(0, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3),
/* FSYS Block */
MUX(none, "mout_usbd301", group2_p, SRC_FSYS, 4, 3),
MUX(none, "mout_mmc0", group2_p, SRC_FSYS, 8, 3),
MUX(none, "mout_mmc1", group2_p, SRC_FSYS, 12, 3),
MUX(none, "mout_mmc2", group2_p, SRC_FSYS, 16, 3),
MUX(none, "mout_usbd300", group2_p, SRC_FSYS, 20, 3),
MUX(none, "mout_unipro", group2_p, SRC_FSYS, 24, 3),
MUX(0, "mout_usbd301", group2_p, SRC_FSYS, 4, 3),
MUX(0, "mout_mmc0", group2_p, SRC_FSYS, 8, 3),
MUX(0, "mout_mmc1", group2_p, SRC_FSYS, 12, 3),
MUX(0, "mout_mmc2", group2_p, SRC_FSYS, 16, 3),
MUX(0, "mout_usbd300", group2_p, SRC_FSYS, 20, 3),
MUX(0, "mout_unipro", group2_p, SRC_FSYS, 24, 3),
/* PERIC Block */
MUX(none, "mout_uart0", group2_p, SRC_PERIC0, 4, 3),
MUX(none, "mout_uart1", group2_p, SRC_PERIC0, 8, 3),
MUX(none, "mout_uart2", group2_p, SRC_PERIC0, 12, 3),
MUX(none, "mout_uart3", group2_p, SRC_PERIC0, 16, 3),
MUX(none, "mout_pwm", group2_p, SRC_PERIC0, 24, 3),
MUX(none, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3),
MUX(none, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3),
MUX(none, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3),
MUX(none, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3),
MUX(none, "mout_spi0", group2_p, SRC_PERIC1, 20, 3),
MUX(none, "mout_spi1", group2_p, SRC_PERIC1, 24, 3),
MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3),
MUX(0, "mout_uart0", group2_p, SRC_PERIC0, 4, 3),
MUX(0, "mout_uart1", group2_p, SRC_PERIC0, 8, 3),
MUX(0, "mout_uart2", group2_p, SRC_PERIC0, 12, 3),
MUX(0, "mout_uart3", group2_p, SRC_PERIC0, 16, 3),
MUX(0, "mout_pwm", group2_p, SRC_PERIC0, 24, 3),
MUX(0, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3),
MUX(0, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3),
MUX(0, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3),
MUX(0, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3),
MUX(0, "mout_spi0", group2_p, SRC_PERIC1, 20, 3),
MUX(0, "mout_spi1", group2_p, SRC_PERIC1, 24, 3),
MUX(0, "mout_spi2", group2_p, SRC_PERIC1, 28, 3),
};
static struct samsung_div_clock exynos5420_div_clks[] __initdata = {
DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
DIV(none, "armclk2", "div_arm", DIV_CPU0, 28, 3),
DIV(none, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3),
DIV(none, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3),
DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
DIV(0, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
DIV(0, "armclk2", "div_arm", DIV_CPU0, 28, 3),
DIV(0, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3),
DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3),
DIV(none, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3),
DIV(none, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3),
DIV(none, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3),
DIV(none, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3),
DIV(none, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3),
DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3),
DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3),
DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3),
DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3),
DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3),
DIV(none, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl",
DIV(0, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl",
DIV_TOP1, 0, 3),
DIV(none, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6),
DIV(none, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3),
DIV(none, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3),
DIV(none, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3),
DIV(0, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6),
DIV(0, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3),
DIV(0, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3),
DIV(0, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3),
DIV(none, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3),
DIV(none, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3),
DIV(none, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3),
DIV(none, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3),
DIV_A(none, "dout_aclk300_disp1", "mout_aclk300_disp1",
DIV(0, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3),
DIV(0, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3),
DIV(0, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3),
DIV(0, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3),
DIV_A(0, "dout_aclk300_disp1", "mout_aclk300_disp1",
DIV_TOP2, 24, 3, "aclk300_disp1"),
DIV(none, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3),
DIV(0, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3),
/* DISP1 Block */
DIV(none, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4),
DIV(none, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8),
DIV(none, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
DIV(dout_pixel, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
DIV(0, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4),
DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8),
DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4),
DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
/* Audio Block */
DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
DIV(none, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8),
DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
DIV(0, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8),
/* USB3.0 */
DIV(none, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 12, 4),
DIV(none, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4),
DIV(none, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 20, 4),
DIV(none, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4),
DIV(0, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 12, 4),
DIV(0, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4),
DIV(0, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 20, 4),
DIV(0, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4),
/* MMC */
DIV(none, "dout_mmc0", "mout_mmc0", DIV_FSYS1, 0, 10),
DIV(none, "dout_mmc1", "mout_mmc1", DIV_FSYS1, 10, 10),
DIV(none, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10),
DIV(0, "dout_mmc0", "mout_mmc0", DIV_FSYS1, 0, 10),
DIV(0, "dout_mmc1", "mout_mmc1", DIV_FSYS1, 10, 10),
DIV(0, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10),
DIV(none, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8),
DIV(0, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8),
/* UART and PWM */
DIV(none, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4),
DIV(none, "dout_uart1", "mout_uart1", DIV_PERIC0, 12, 4),
DIV(none, "dout_uart2", "mout_uart2", DIV_PERIC0, 16, 4),
DIV(none, "dout_uart3", "mout_uart3", DIV_PERIC0, 20, 4),
DIV(none, "dout_pwm", "mout_pwm", DIV_PERIC0, 28, 4),
DIV(0, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4),
DIV(0, "dout_uart1", "mout_uart1", DIV_PERIC0, 12, 4),
DIV(0, "dout_uart2", "mout_uart2", DIV_PERIC0, 16, 4),
DIV(0, "dout_uart3", "mout_uart3", DIV_PERIC0, 20, 4),
DIV(0, "dout_pwm", "mout_pwm", DIV_PERIC0, 28, 4),
/* SPI */
DIV(none, "dout_spi0", "mout_spi0", DIV_PERIC1, 20, 4),
DIV(none, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4),
DIV(none, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4),
DIV(0, "dout_spi0", "mout_spi0", DIV_PERIC1, 20, 4),
DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4),
DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4),
/* PCM */
DIV(none, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8),
DIV(none, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8),
DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8),
DIV(0, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8),
/* Audio - I2S */
DIV(none, "dout_i2s1", "dout_audio1", DIV_PERIC3, 6, 6),
DIV(none, "dout_i2s2", "dout_audio2", DIV_PERIC3, 12, 6),
DIV(none, "dout_audio0", "mout_audio0", DIV_PERIC3, 20, 4),
DIV(none, "dout_audio1", "mout_audio1", DIV_PERIC3, 24, 4),
DIV(none, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4),
DIV(0, "dout_i2s1", "dout_audio1", DIV_PERIC3, 6, 6),
DIV(0, "dout_i2s2", "dout_audio2", DIV_PERIC3, 12, 6),
DIV(0, "dout_audio0", "mout_audio0", DIV_PERIC3, 20, 4),
DIV(0, "dout_audio1", "mout_audio1", DIV_PERIC3, 24, 4),
DIV(0, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4),
/* SPI Pre-Ratio */
DIV(none, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8),
DIV(none, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8),
DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8),
DIV(0, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8),
DIV(0, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8),
DIV(0, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8),
};
static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
/* TODO: Re-verify the CG bits for all the gate clocks */
GATE_A(mct, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, "mct"),
GATE_A(CLK_MCT, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0,
"mct"),
GATE(0, "aclk200_fsys", "mout_user_aclk200_fsys",
GATE_BUS_FSYS0, 9, CLK_IGNORE_UNUSED, 0),
@ -545,217 +505,227 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
GATE_BUS_TOP, 15, CLK_IGNORE_UNUSED, 0),
/* sclk */
GATE(sclk_uart0, "sclk_uart0", "dout_uart0",
GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0",
GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart1, "sclk_uart1", "dout_uart1",
GATE(CLK_SCLK_UART1, "sclk_uart1", "dout_uart1",
GATE_TOP_SCLK_PERIC, 1, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart2, "sclk_uart2", "dout_uart2",
GATE(CLK_SCLK_UART2, "sclk_uart2", "dout_uart2",
GATE_TOP_SCLK_PERIC, 2, CLK_SET_RATE_PARENT, 0),
GATE(sclk_uart3, "sclk_uart3", "dout_uart3",
GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_uart3",
GATE_TOP_SCLK_PERIC, 3, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spi0, "sclk_spi0", "dout_pre_spi0",
GATE(CLK_SCLK_SPI0, "sclk_spi0", "dout_pre_spi0",
GATE_TOP_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spi1, "sclk_spi1", "dout_pre_spi1",
GATE(CLK_SCLK_SPI1, "sclk_spi1", "dout_pre_spi1",
GATE_TOP_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spi2, "sclk_spi2", "dout_pre_spi2",
GATE(CLK_SCLK_SPI2, "sclk_spi2", "dout_pre_spi2",
GATE_TOP_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0),
GATE(sclk_spdif, "sclk_spdif", "mout_spdif",
GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif",
GATE_TOP_SCLK_PERIC, 9, CLK_SET_RATE_PARENT, 0),
GATE(sclk_pwm, "sclk_pwm", "dout_pwm",
GATE(CLK_SCLK_PWM, "sclk_pwm", "dout_pwm",
GATE_TOP_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0),
GATE(sclk_pcm1, "sclk_pcm1", "dout_pcm1",
GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_pcm1",
GATE_TOP_SCLK_PERIC, 15, CLK_SET_RATE_PARENT, 0),
GATE(sclk_pcm2, "sclk_pcm2", "dout_pcm2",
GATE(CLK_SCLK_PCM2, "sclk_pcm2", "dout_pcm2",
GATE_TOP_SCLK_PERIC, 16, CLK_SET_RATE_PARENT, 0),
GATE(sclk_i2s1, "sclk_i2s1", "dout_i2s1",
GATE(CLK_SCLK_I2S1, "sclk_i2s1", "dout_i2s1",
GATE_TOP_SCLK_PERIC, 17, CLK_SET_RATE_PARENT, 0),
GATE(sclk_i2s2, "sclk_i2s2", "dout_i2s2",
GATE(CLK_SCLK_I2S2, "sclk_i2s2", "dout_i2s2",
GATE_TOP_SCLK_PERIC, 18, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc0, "sclk_mmc0", "dout_mmc0",
GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_mmc0",
GATE_TOP_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc1, "sclk_mmc1", "dout_mmc1",
GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_mmc1",
GATE_TOP_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mmc2, "sclk_mmc2", "dout_mmc2",
GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_mmc2",
GATE_TOP_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
GATE(sclk_usbphy301, "sclk_usbphy301", "dout_usbphy301",
GATE(CLK_SCLK_USBPHY301, "sclk_usbphy301", "dout_usbphy301",
GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0),
GATE(sclk_usbphy300, "sclk_usbphy300", "dout_usbphy300",
GATE(CLK_SCLK_USBPHY300, "sclk_usbphy300", "dout_usbphy300",
GATE_TOP_SCLK_FSYS, 8, CLK_SET_RATE_PARENT, 0),
GATE(sclk_usbd300, "sclk_usbd300", "dout_usbd300",
GATE(CLK_SCLK_USBD300, "sclk_usbd300", "dout_usbd300",
GATE_TOP_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
GATE(sclk_usbd301, "sclk_usbd301", "dout_usbd301",
GATE(CLK_SCLK_USBD301, "sclk_usbd301", "dout_usbd301",
GATE_TOP_SCLK_FSYS, 10, CLK_SET_RATE_PARENT, 0),
GATE(sclk_usbd301, "sclk_unipro", "dout_unipro",
GATE(CLK_SCLK_USBD301, "sclk_unipro", "dout_unipro",
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
GATE(sclk_gscl_wa, "sclk_gscl_wa", "aclK333_432_gscl",
GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "aclK333_432_gscl",
GATE_TOP_SCLK_GSCL, 6, CLK_SET_RATE_PARENT, 0),
GATE(sclk_gscl_wb, "sclk_gscl_wb", "aclk333_432_gscl",
GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "aclk333_432_gscl",
GATE_TOP_SCLK_GSCL, 7, CLK_SET_RATE_PARENT, 0),
/* Display */
GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1",
GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "dout_fimd1",
GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_mipi1, "sclk_mipi1", "dout_mipi1",
GATE(CLK_SCLK_MIPI1, "sclk_mipi1", "dout_mipi1",
GATE_TOP_SCLK_DISP1, 3, CLK_SET_RATE_PARENT, 0),
GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi",
GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi",
GATE_TOP_SCLK_DISP1, 9, CLK_SET_RATE_PARENT, 0),
GATE(sclk_pixel, "sclk_pixel", "dout_hdmi_pixel",
GATE(CLK_SCLK_PIXEL, "sclk_pixel", "dout_hdmi_pixel",
GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0),
GATE(sclk_dp1, "sclk_dp1", "dout_dp1",
GATE(CLK_SCLK_DP1, "sclk_dp1", "dout_dp1",
GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0),
/* Maudio Block */
GATE(sclk_maudio0, "sclk_maudio0", "dout_maudio0",
GATE(CLK_SCLK_MAUDIO0, "sclk_maudio0", "dout_maudio0",
GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0),
GATE(sclk_maupcm0, "sclk_maupcm0", "dout_maupcm0",
GATE(CLK_SCLK_MAUPCM0, "sclk_maupcm0", "dout_maupcm0",
GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0),
/* FSYS */
GATE(tsi, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0),
GATE(pdma0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0),
GATE(pdma1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0),
GATE(ufs, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0),
GATE(rtic, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0),
GATE(mmc0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0),
GATE(mmc1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0),
GATE(mmc2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0),
GATE(sromc, "sromc", "aclk200_fsys2",
GATE(CLK_TSI, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0),
GATE(CLK_PDMA0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0),
GATE(CLK_PDMA1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0),
GATE(CLK_UFS, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0),
GATE(CLK_RTIC, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0),
GATE(CLK_MMC0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0),
GATE(CLK_MMC1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0),
GATE(CLK_MMC2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0),
GATE(CLK_SROMC, "sromc", "aclk200_fsys2",
GATE_BUS_FSYS0, 19, CLK_IGNORE_UNUSED, 0),
GATE(usbh20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0),
GATE(usbd300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0),
GATE(usbd301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0),
GATE(CLK_USBH20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0),
GATE(CLK_USBD300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0),
GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0),
/* UART */
GATE(uart0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0),
GATE(uart1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0),
GATE_A(uart2, "uart2", "aclk66_peric",
GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0),
GATE(CLK_UART1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0),
GATE_A(CLK_UART2, "uart2", "aclk66_peric",
GATE_BUS_PERIC, 6, CLK_IGNORE_UNUSED, 0, "uart2"),
GATE(uart3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0),
GATE(CLK_UART3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0),
/* I2C */
GATE(i2c0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0),
GATE(i2c1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0),
GATE(i2c2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0),
GATE(i2c3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0),
GATE(i2c4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0),
GATE(i2c5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0),
GATE(i2c6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0),
GATE(i2c7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0),
GATE(i2c_hdmi, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0, 0),
GATE(tsadc, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0),
GATE(CLK_I2C0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0),
GATE(CLK_I2C1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0),
GATE(CLK_I2C2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0),
GATE(CLK_I2C3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0),
GATE(CLK_I2C4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0),
GATE(CLK_I2C5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0),
GATE(CLK_I2C6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0),
GATE(CLK_I2C7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0),
GATE(CLK_I2C_HDMI, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0,
0),
GATE(CLK_TSADC, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0),
/* SPI */
GATE(spi0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0),
GATE(spi1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0),
GATE(spi2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0),
GATE(keyif, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0),
GATE(CLK_SPI0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0),
GATE(CLK_SPI1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0),
GATE(CLK_SPI2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0),
GATE(CLK_KEYIF, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0),
/* I2S */
GATE(i2s1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0),
GATE(i2s2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0),
GATE(CLK_I2S1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0),
GATE(CLK_I2S2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0),
/* PCM */
GATE(pcm1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0),
GATE(pcm2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0),
GATE(CLK_PCM1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0),
GATE(CLK_PCM2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0),
/* PWM */
GATE(pwm, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0),
GATE(CLK_PWM, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0),
/* SPDIF */
GATE(spdif, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0),
GATE(CLK_SPDIF, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0),
GATE(i2c8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0),
GATE(i2c9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0),
GATE(i2c10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0),
GATE(CLK_I2C8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0),
GATE(CLK_I2C9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0),
GATE(CLK_I2C10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0),
GATE(chipid, "chipid", "aclk66_psgen",
GATE(CLK_CHIPID, "chipid", "aclk66_psgen",
GATE_BUS_PERIS0, 12, CLK_IGNORE_UNUSED, 0),
GATE(sysreg, "sysreg", "aclk66_psgen",
GATE(CLK_SYSREG, "sysreg", "aclk66_psgen",
GATE_BUS_PERIS0, 13, CLK_IGNORE_UNUSED, 0),
GATE(tzpc0, "tzpc0", "aclk66_psgen", GATE_BUS_PERIS0, 18, 0, 0),
GATE(tzpc1, "tzpc1", "aclk66_psgen", GATE_BUS_PERIS0, 19, 0, 0),
GATE(tzpc2, "tzpc2", "aclk66_psgen", GATE_BUS_PERIS0, 20, 0, 0),
GATE(tzpc3, "tzpc3", "aclk66_psgen", GATE_BUS_PERIS0, 21, 0, 0),
GATE(tzpc4, "tzpc4", "aclk66_psgen", GATE_BUS_PERIS0, 22, 0, 0),
GATE(tzpc5, "tzpc5", "aclk66_psgen", GATE_BUS_PERIS0, 23, 0, 0),
GATE(tzpc6, "tzpc6", "aclk66_psgen", GATE_BUS_PERIS0, 24, 0, 0),
GATE(tzpc7, "tzpc7", "aclk66_psgen", GATE_BUS_PERIS0, 25, 0, 0),
GATE(tzpc8, "tzpc8", "aclk66_psgen", GATE_BUS_PERIS0, 26, 0, 0),
GATE(tzpc9, "tzpc9", "aclk66_psgen", GATE_BUS_PERIS0, 27, 0, 0),
GATE(CLK_TZPC0, "tzpc0", "aclk66_psgen", GATE_BUS_PERIS0, 18, 0, 0),
GATE(CLK_TZPC1, "tzpc1", "aclk66_psgen", GATE_BUS_PERIS0, 19, 0, 0),
GATE(CLK_TZPC2, "tzpc2", "aclk66_psgen", GATE_BUS_PERIS0, 20, 0, 0),
GATE(CLK_TZPC3, "tzpc3", "aclk66_psgen", GATE_BUS_PERIS0, 21, 0, 0),
GATE(CLK_TZPC4, "tzpc4", "aclk66_psgen", GATE_BUS_PERIS0, 22, 0, 0),
GATE(CLK_TZPC5, "tzpc5", "aclk66_psgen", GATE_BUS_PERIS0, 23, 0, 0),
GATE(CLK_TZPC6, "tzpc6", "aclk66_psgen", GATE_BUS_PERIS0, 24, 0, 0),
GATE(CLK_TZPC7, "tzpc7", "aclk66_psgen", GATE_BUS_PERIS0, 25, 0, 0),
GATE(CLK_TZPC8, "tzpc8", "aclk66_psgen", GATE_BUS_PERIS0, 26, 0, 0),
GATE(CLK_TZPC9, "tzpc9", "aclk66_psgen", GATE_BUS_PERIS0, 27, 0, 0),
GATE(hdmi_cec, "hdmi_cec", "aclk66_psgen", GATE_BUS_PERIS1, 0, 0, 0),
GATE(seckey, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
GATE(wdt, "wdt", "aclk66_psgen", GATE_BUS_PERIS1, 3, 0, 0),
GATE(rtc, "rtc", "aclk66_psgen", GATE_BUS_PERIS1, 4, 0, 0),
GATE(tmu, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0),
GATE(tmu_gpu, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0),
GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk66_psgen", GATE_BUS_PERIS1, 0, 0,
0),
GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
GATE(CLK_WDT, "wdt", "aclk66_psgen", GATE_BUS_PERIS1, 3, 0, 0),
GATE(CLK_RTC, "rtc", "aclk66_psgen", GATE_BUS_PERIS1, 4, 0, 0),
GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0),
GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0),
GATE(gscl0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
GATE(gscl1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
GATE(clk_3aa, "clk_3aa", "aclk300_gscl", GATE_IP_GSCL0, 4, 0, 0),
GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0),
GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0),
GATE(CLK_CLK_3AA, "clk_3aa", "aclk300_gscl", GATE_IP_GSCL0, 4, 0, 0),
GATE(smmu_3aa, "smmu_3aa", "aclk333_432_gscl", GATE_IP_GSCL1, 2, 0, 0),
GATE(smmu_fimcl0, "smmu_fimcl0", "aclk333_432_gscl",
GATE(CLK_SMMU_3AA, "smmu_3aa", "aclk333_432_gscl", GATE_IP_GSCL1, 2, 0,
0),
GATE(CLK_SMMU_FIMCL0, "smmu_fimcl0", "aclk333_432_gscl",
GATE_IP_GSCL1, 3, 0, 0),
GATE(smmu_fimcl1, "smmu_fimcl1", "aclk333_432_gscl",
GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "aclk333_432_gscl",
GATE_IP_GSCL1, 4, 0, 0),
GATE(smmu_gscl0, "smmu_gscl0", "aclk300_gscl", GATE_IP_GSCL1, 6, 0, 0),
GATE(smmu_gscl1, "smmu_gscl1", "aclk300_gscl", GATE_IP_GSCL1, 7, 0, 0),
GATE(gscl_wa, "gscl_wa", "aclk300_gscl", GATE_IP_GSCL1, 12, 0, 0),
GATE(gscl_wb, "gscl_wb", "aclk300_gscl", GATE_IP_GSCL1, 13, 0, 0),
GATE(smmu_fimcl3, "smmu_fimcl3,", "aclk333_432_gscl",
GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "aclk300_gscl", GATE_IP_GSCL1, 6, 0,
0),
GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "aclk300_gscl", GATE_IP_GSCL1, 7, 0,
0),
GATE(CLK_GSCL_WA, "gscl_wa", "aclk300_gscl", GATE_IP_GSCL1, 12, 0, 0),
GATE(CLK_GSCL_WB, "gscl_wb", "aclk300_gscl", GATE_IP_GSCL1, 13, 0, 0),
GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "aclk333_432_gscl",
GATE_IP_GSCL1, 16, 0, 0),
GATE(fimc_lite3, "fimc_lite3", "aclk333_432_gscl",
GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl",
GATE_IP_GSCL1, 17, 0, 0),
GATE(fimd1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
GATE(dsim1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
GATE(dp1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
GATE(mixer, "mixer", "aclk166", GATE_IP_DISP1, 5, 0, 0),
GATE(hdmi, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
GATE(smmu_fimd1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0, 0),
GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0),
GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0),
GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0),
GATE(CLK_MIXER, "mixer", "aclk166", GATE_IP_DISP1, 5, 0, 0),
GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0),
GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0,
0),
GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0),
GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0),
GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0),
GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0),
GATE(g3d, "g3d", "aclkg3d", GATE_IP_G3D, 9, 0, 0),
GATE(CLK_G3D, "g3d", "aclkg3d", GATE_IP_G3D, 9, 0, 0),
GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0),
GATE(jpeg, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0),
GATE(jpeg2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0),
GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0),
GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0),
GATE(smmu_jpeg, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0),
GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0),
GATE(CLK_ROTATOR, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0),
GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0),
GATE(CLK_JPEG2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0),
GATE(CLK_MDMA1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0),
GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0),
GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0),
GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0),
GATE(mscl0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0),
GATE(mscl1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0),
GATE(mscl2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0),
GATE(smmu_mscl0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, 0),
GATE(smmu_mscl1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, 0),
GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0),
GATE(smmu_mixer, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0, 0),
GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0),
GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0),
GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0),
GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0,
0),
GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0,
0),
GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0,
0),
GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0,
0),
};
static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = {
[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
[apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
APLL_CON0, NULL),
[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
MPLL_CON0, NULL),
[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
[cpll] = PLL(pll_2550, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK,
CPLL_CON0, NULL),
[dpll] = PLL(pll_2550, CLK_FOUT_DPLL, "fout_dpll", "fin_pll", DPLL_LOCK,
DPLL_CON0, NULL),
[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
[epll] = PLL(pll_2650, CLK_FOUT_EPLL, "fout_epll", "fin_pll", EPLL_LOCK,
EPLL_CON0, NULL),
[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
[rpll] = PLL(pll_2650, CLK_FOUT_RPLL, "fout_rpll", "fin_pll", RPLL_LOCK,
RPLL_CON0, NULL),
[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
[ipll] = PLL(pll_2550, CLK_FOUT_IPLL, "fout_ipll", "fin_pll", IPLL_LOCK,
IPLL_CON0, NULL),
[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
[spll] = PLL(pll_2550, CLK_FOUT_SPLL, "fout_spll", "fin_pll", SPLL_LOCK,
SPLL_CON0, NULL),
[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
[vpll] = PLL(pll_2550, CLK_FOUT_VPLL, "fout_vpll", "fin_pll", VPLL_LOCK,
VPLL_CON0, NULL),
[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
[mpll] = PLL(pll_2550, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", MPLL_LOCK,
MPLL_CON0, NULL),
[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
[bpll] = PLL(pll_2550, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK,
BPLL_CON0, NULL),
[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
[kpll] = PLL(pll_2550, CLK_FOUT_KPLL, "fout_kpll", "fin_pll", KPLL_LOCK,
KPLL_CON0, NULL),
};
@ -777,7 +747,7 @@ static void __init exynos5420_clk_init(struct device_node *np)
panic("%s: unable to determine soc\n", __func__);
}
samsung_clk_init(np, reg_base, nr_clks,
samsung_clk_init(np, reg_base, CLK_NR_CLKS,
exynos5420_clk_regs, ARRAY_SIZE(exynos5420_clk_regs),
NULL, 0);
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,

Просмотреть файл

@ -9,6 +9,7 @@
* Common Clock Framework support for Exynos5440 SoC.
*/
#include <dt-bindings/clock/exynos5440.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
@ -22,79 +23,65 @@
#define CPU_CLK_STATUS 0xfc
#define MISC_DOUT1 0x558
/*
* Let each supported clock get a unique id. This id is used to lookup the clock
* for device tree based platforms.
*/
enum exynos5440_clks {
none, xtal, arm_clk,
spi_baud = 16, pb0_250, pr0_250, pr1_250, b_250, b_125, b_200, sata,
usb, gmac0, cs250, pb0_250_o, pr0_250_o, pr1_250_o, b_250_o, b_125_o,
b_200_o, sata_o, usb_o, gmac0_o, cs250_o,
nr_clks,
};
/* parent clock name list */
PNAME(mout_armclk_p) = { "cplla", "cpllb" };
PNAME(mout_spi_p) = { "div125", "div200" };
/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = {
FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0),
FRATE(0, "xtal", NULL, CLK_IS_ROOT, 0),
};
/* fixed rate clocks */
static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
FRATE(none, "ppll", NULL, CLK_IS_ROOT, 1000000000),
FRATE(none, "usb_phy0", NULL, CLK_IS_ROOT, 60000000),
FRATE(none, "usb_phy1", NULL, CLK_IS_ROOT, 60000000),
FRATE(none, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000),
FRATE(none, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000),
FRATE(0, "ppll", NULL, CLK_IS_ROOT, 1000000000),
FRATE(0, "usb_phy0", NULL, CLK_IS_ROOT, 60000000),
FRATE(0, "usb_phy1", NULL, CLK_IS_ROOT, 60000000),
FRATE(0, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000),
FRATE(0, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000),
};
/* fixed factor clocks */
static struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = {
FFACTOR(none, "div250", "ppll", 1, 4, 0),
FFACTOR(none, "div200", "ppll", 1, 5, 0),
FFACTOR(none, "div125", "div250", 1, 2, 0),
FFACTOR(0, "div250", "ppll", 1, 4, 0),
FFACTOR(0, "div200", "ppll", 1, 5, 0),
FFACTOR(0, "div125", "div250", 1, 2, 0),
};
/* mux clocks */
static struct samsung_mux_clock exynos5440_mux_clks[] __initdata = {
MUX(none, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
MUX_A(arm_clk, "arm_clk", mout_armclk_p,
MUX(0, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
MUX_A(CLK_ARM_CLK, "arm_clk", mout_armclk_p,
CPU_CLK_STATUS, 0, 1, "armclk"),
};
/* divider clocks */
static struct samsung_div_clock exynos5440_div_clks[] __initdata = {
DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
DIV(CLK_SPI_BAUD, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
};
/* gate clocks */
static struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
GATE(pb0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0),
GATE(pr0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0),
GATE(pr1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0),
GATE(b_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0),
GATE(b_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0),
GATE(b_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0),
GATE(sata, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0),
GATE(usb, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0),
GATE(gmac0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0),
GATE(cs250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0),
GATE(pb0_250_o, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0),
GATE(pr0_250_o, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0),
GATE(pr1_250_o, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0),
GATE(b_250_o, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0),
GATE(b_125_o, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0),
GATE(b_200_o, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0),
GATE(sata_o, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0),
GATE(usb_o, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0),
GATE(gmac0_o, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0),
GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
GATE(CLK_PB0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0),
GATE(CLK_PR0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0),
GATE(CLK_PR1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0),
GATE(CLK_B_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0),
GATE(CLK_B_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0),
GATE(CLK_B_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0),
GATE(CLK_SATA, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0),
GATE(CLK_USB, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0),
GATE(CLK_GMAC0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0),
GATE(CLK_CS250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0),
GATE(CLK_PB0_250_O, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0),
GATE(CLK_PR0_250_O, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0),
GATE(CLK_PR1_250_O, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0),
GATE(CLK_B_250_O, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0),
GATE(CLK_B_125_O, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0),
GATE(CLK_B_200_O, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0),
GATE(CLK_SATA_O, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0),
GATE(CLK_USB_O, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0),
GATE(CLK_GMAC0_O, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0),
GATE(CLK_CS250_O, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
};
static struct of_device_id ext_clk_match[] __initdata = {
@ -114,7 +101,7 @@ static void __init exynos5440_clk_init(struct device_node *np)
return;
}
samsung_clk_init(np, reg_base, nr_clks, NULL, 0, NULL, 0);
samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0);
samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match);

Просмотреть файл

@ -1,7 +1,7 @@
obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o
# for emply built-in.o
obj-n := dummy

Просмотреть файл

@ -0,0 +1,104 @@
/*
* EMMA Mobile EV2 common clock framework support
*
* Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
* Copyright (C) 2012 Magnus Damm
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
/* EMEV2 SMU registers */
#define USIAU0_RSTCTRL 0x094
#define USIBU1_RSTCTRL 0x0ac
#define USIBU2_RSTCTRL 0x0b0
#define USIBU3_RSTCTRL 0x0b4
#define STI_RSTCTRL 0x124
#define STI_CLKSEL 0x688
static DEFINE_SPINLOCK(lock);
/* not pretty, but hey */
void __iomem *smu_base;
static void __init emev2_smu_write(unsigned long value, int offs)
{
BUG_ON(!smu_base || (offs >= PAGE_SIZE));
writel_relaxed(value, smu_base + offs);
}
static const struct of_device_id smu_id[] __initconst = {
{ .compatible = "renesas,emev2-smu", },
{},
};
static void __init emev2_smu_init(void)
{
struct device_node *np;
np = of_find_matching_node(NULL, smu_id);
BUG_ON(!np);
smu_base = of_iomap(np, 0);
BUG_ON(!smu_base);
of_node_put(np);
/* setup STI timer to run on 32.768 kHz and deassert reset */
emev2_smu_write(0, STI_CLKSEL);
emev2_smu_write(1, STI_RSTCTRL);
/* deassert reset for UART0->UART3 */
emev2_smu_write(2, USIAU0_RSTCTRL);
emev2_smu_write(2, USIBU1_RSTCTRL);
emev2_smu_write(2, USIBU2_RSTCTRL);
emev2_smu_write(2, USIBU3_RSTCTRL);
}
static void __init emev2_smu_clkdiv_init(struct device_node *np)
{
u32 reg[2];
struct clk *clk;
const char *parent_name = of_clk_get_parent_name(np, 0);
if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2)))
return;
if (!smu_base)
emev2_smu_init();
clk = clk_register_divider(NULL, np->name, parent_name, 0,
smu_base + reg[0], reg[1], 8, 0, &lock);
of_clk_add_provider(np, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, np->name, NULL);
pr_debug("## %s %s %p\n", __func__, np->name, clk);
}
CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv",
emev2_smu_clkdiv_init);
static void __init emev2_smu_gclk_init(struct device_node *np)
{
u32 reg[2];
struct clk *clk;
const char *parent_name = of_clk_get_parent_name(np, 0);
if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2)))
return;
if (!smu_base)
emev2_smu_init();
clk = clk_register_gate(NULL, np->name, parent_name, 0,
smu_base + reg[0], reg[1], 0, &lock);
of_clk_add_provider(np, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, np->name, NULL);
pr_debug("## %s %s %p\n", __func__, np->name, clk);
}
CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init);

Просмотреть файл

@ -160,7 +160,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
unsigned int i;
group = kzalloc(sizeof(*group), GFP_KERNEL);
clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
if (group == NULL || clks == NULL) {
kfree(group);
kfree(clks);
@ -181,6 +181,9 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
return;
}
for (i = 0; i < MSTP_MAX_CLOCKS; ++i)
clks[i] = ERR_PTR(-ENOENT);
for (i = 0; i < MSTP_MAX_CLOCKS; ++i) {
const char *parent_name;
const char *name;
@ -205,10 +208,11 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
continue;
}
clks[clkidx] = cpg_mstp_clock_register(name, parent_name, i,
group);
clks[clkidx] = cpg_mstp_clock_register(name, parent_name,
clkidx, group);
if (!IS_ERR(clks[clkidx])) {
group->data.clk_num = max(group->data.clk_num, clkidx);
group->data.clk_num = max(group->data.clk_num,
clkidx + 1);
/*
* Register a clkdev to let board code retrieve the
* clock by name and register aliases for non-DT

Просмотреть файл

@ -0,0 +1,5 @@
#
# Makefile for sirf specific clk
#
obj-$(CONFIG_ARCH_SIRF) += clk-prima2.o clk-atlas6.o

31
drivers/clk/sirf/atlas6.h Normal file
Просмотреть файл

@ -0,0 +1,31 @@
#define SIRFSOC_CLKC_CLK_EN0 0x0000
#define SIRFSOC_CLKC_CLK_EN1 0x0004
#define SIRFSOC_CLKC_REF_CFG 0x0020
#define SIRFSOC_CLKC_CPU_CFG 0x0024
#define SIRFSOC_CLKC_MEM_CFG 0x0028
#define SIRFSOC_CLKC_MEMDIV_CFG 0x002C
#define SIRFSOC_CLKC_SYS_CFG 0x0030
#define SIRFSOC_CLKC_IO_CFG 0x0034
#define SIRFSOC_CLKC_DSP_CFG 0x0038
#define SIRFSOC_CLKC_GFX_CFG 0x003c
#define SIRFSOC_CLKC_MM_CFG 0x0040
#define SIRFSOC_CLKC_GFX2D_CFG 0x0040
#define SIRFSOC_CLKC_LCD_CFG 0x0044
#define SIRFSOC_CLKC_MMC01_CFG 0x0048
#define SIRFSOC_CLKC_MMC23_CFG 0x004C
#define SIRFSOC_CLKC_MMC45_CFG 0x0050
#define SIRFSOC_CLKC_NAND_CFG 0x0054
#define SIRFSOC_CLKC_NANDDIV_CFG 0x0058
#define SIRFSOC_CLKC_PLL1_CFG0 0x0080
#define SIRFSOC_CLKC_PLL2_CFG0 0x0084
#define SIRFSOC_CLKC_PLL3_CFG0 0x0088
#define SIRFSOC_CLKC_PLL1_CFG1 0x008c
#define SIRFSOC_CLKC_PLL2_CFG1 0x0090
#define SIRFSOC_CLKC_PLL3_CFG1 0x0094
#define SIRFSOC_CLKC_PLL1_CFG2 0x0098
#define SIRFSOC_CLKC_PLL2_CFG2 0x009c
#define SIRFSOC_CLKC_PLL3_CFG2 0x00A0
#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)

Просмотреть файл

@ -0,0 +1,152 @@
/*
* Clock tree for CSR SiRFatlasVI
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
* Licensed under GPLv2 or later.
*/
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include "atlas6.h"
#include "clk-common.c"
static struct clk_dmn clk_mmc01 = {
.regofs = SIRFSOC_CLKC_MMC01_CFG,
.enable_bit = 59,
.hw = {
.init = &clk_mmc01_init,
},
};
static struct clk_dmn clk_mmc23 = {
.regofs = SIRFSOC_CLKC_MMC23_CFG,
.enable_bit = 60,
.hw = {
.init = &clk_mmc23_init,
},
};
static struct clk_dmn clk_mmc45 = {
.regofs = SIRFSOC_CLKC_MMC45_CFG,
.enable_bit = 61,
.hw = {
.init = &clk_mmc45_init,
},
};
static struct clk_init_data clk_nand_init = {
.name = "nand",
.ops = &dmn_ops,
.parent_names = dmn_clk_parents,
.num_parents = ARRAY_SIZE(dmn_clk_parents),
};
static struct clk_dmn clk_nand = {
.regofs = SIRFSOC_CLKC_NAND_CFG,
.enable_bit = 34,
.hw = {
.init = &clk_nand_init,
},
};
enum atlas6_clk_index {
/* 0 1 2 3 4 5 6 7 8 9 */
rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
usp2, vip, gfx, gfx2d, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
usb0, usb1, cphif, maxclk,
};
static __initdata struct clk_hw *atlas6_clk_hw_array[maxclk] = {
NULL, /* dummy */
NULL,
&clk_pll1.hw,
&clk_pll2.hw,
&clk_pll3.hw,
&clk_mem.hw,
&clk_sys.hw,
&clk_security.hw,
&clk_dsp.hw,
&clk_gps.hw,
&clk_mf.hw,
&clk_io.hw,
&clk_cpu.hw,
&clk_uart0.hw,
&clk_uart1.hw,
&clk_uart2.hw,
&clk_tsc.hw,
&clk_i2c0.hw,
&clk_i2c1.hw,
&clk_spi0.hw,
&clk_spi1.hw,
&clk_pwmc.hw,
&clk_efuse.hw,
&clk_pulse.hw,
&clk_dmac0.hw,
&clk_dmac1.hw,
&clk_nand.hw,
&clk_audio.hw,
&clk_usp0.hw,
&clk_usp1.hw,
&clk_usp2.hw,
&clk_vip.hw,
&clk_gfx.hw,
&clk_gfx2d.hw,
&clk_lcd.hw,
&clk_vpp.hw,
&clk_mmc01.hw,
&clk_mmc23.hw,
&clk_mmc45.hw,
&usb_pll_clk_hw,
&clk_usb0.hw,
&clk_usb1.hw,
&clk_cphif.hw,
};
static struct clk *atlas6_clks[maxclk];
static void __init atlas6_clk_init(struct device_node *np)
{
struct device_node *rscnp;
int i;
rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
if (!sirfsoc_rsc_vbase)
panic("unable to map rsc registers\n");
of_node_put(rscnp);
sirfsoc_clk_vbase = of_iomap(np, 0);
if (!sirfsoc_clk_vbase)
panic("unable to map clkc registers\n");
/* These are always available (RTC and 26MHz OSC)*/
atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
CLK_IS_ROOT, 32768);
atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
CLK_IS_ROOT, 26000000);
for (i = pll1; i < maxclk; i++) {
atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
BUG_ON(!atlas6_clks[i]);
}
clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu");
clk_register_clkdev(atlas6_clks[io], NULL, "io");
clk_register_clkdev(atlas6_clks[mem], NULL, "mem");
clk_register_clkdev(atlas6_clks[mem], NULL, "osc");
clk_data.clks = atlas6_clks;
clk_data.clk_num = maxclk;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
CLK_OF_DECLARE(atlas6_clk, "sirf,atlas6-clkc", atlas6_clk_init);

Просмотреть файл

@ -1,51 +1,18 @@
/*
* Clock tree for CSR SiRFprimaII
* common clks module for all SiRF SoCs
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
* Licensed under GPLv2 or later.
*/
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#define SIRFSOC_CLKC_CLK_EN0 0x0000
#define SIRFSOC_CLKC_CLK_EN1 0x0004
#define SIRFSOC_CLKC_REF_CFG 0x0014
#define SIRFSOC_CLKC_CPU_CFG 0x0018
#define SIRFSOC_CLKC_MEM_CFG 0x001c
#define SIRFSOC_CLKC_SYS_CFG 0x0020
#define SIRFSOC_CLKC_IO_CFG 0x0024
#define SIRFSOC_CLKC_DSP_CFG 0x0028
#define SIRFSOC_CLKC_GFX_CFG 0x002c
#define SIRFSOC_CLKC_MM_CFG 0x0030
#define SIRFSOC_CLKC_LCD_CFG 0x0034
#define SIRFSOC_CLKC_MMC_CFG 0x0038
#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)
static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase;
#define KHZ 1000
#define MHZ (KHZ * KHZ)
static void *sirfsoc_clk_vbase;
static void *sirfsoc_rsc_vbase;
static struct clk_onecell_data clk_data;
/*
* SiRFprimaII clock controller
* - 2 oscillators: osc-26MHz, rtc-32.768KHz
@ -127,6 +94,7 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
unsigned long fin, nf, nr, od;
u64 dividend;
/*
* fout = fin * nf / (nr * od);
@ -147,7 +115,10 @@ static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
nr = BIT(6);
od = 1;
return fin * nf / (nr * od);
dividend = (u64)fin * nf;
do_div(dividend, nr * od);
return (long)dividend;
}
static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@ -186,6 +157,30 @@ static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static long cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
/*
* SiRF SoC has not cpu clock control,
* So bypass to it's parent pll.
*/
struct clk *parent_clk = clk_get_parent(hw->clk);
struct clk *pll_parent_clk = clk_get_parent(parent_clk);
unsigned long pll_parent_rate = clk_get_rate(pll_parent_clk);
return pll_clk_round_rate(__clk_get_hw(parent_clk), rate, &pll_parent_rate);
}
static unsigned long cpu_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
/*
* SiRF SoC has not cpu clock control,
* So return the parent pll rate.
*/
struct clk *parent_clk = clk_get_parent(hw->clk);
return __clk_get_rate(parent_clk);
}
static struct clk_ops std_pll_ops = {
.recalc_rate = pll_clk_recalc_rate,
.round_rate = pll_clk_round_rate,
@ -403,6 +398,42 @@ static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static int cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
int ret1, ret2;
struct clk *cur_parent;
if (rate == clk_get_rate(clk_pll1.hw.clk)) {
ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk);
return ret1;
}
if (rate == clk_get_rate(clk_pll2.hw.clk)) {
ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk);
return ret1;
}
if (rate == clk_get_rate(clk_pll3.hw.clk)) {
ret1 = clk_set_parent(hw->clk, clk_pll3.hw.clk);
return ret1;
}
cur_parent = clk_get_parent(hw->clk);
/* switch to tmp pll before setting parent clock's rate */
if (cur_parent == clk_pll1.hw.clk) {
ret1 = clk_set_parent(hw->clk, clk_pll2.hw.clk);
BUG_ON(ret1);
}
ret2 = clk_set_rate(clk_pll1.hw.clk, rate);
ret1 = clk_set_parent(hw->clk, clk_pll1.hw.clk);
return ret2 ? ret2 : ret1;
}
static struct clk_ops msi_ops = {
.set_rate = dmn_clk_set_rate,
.round_rate = dmn_clk_round_rate,
@ -457,6 +488,9 @@ static struct clk_dmn clk_io = {
static struct clk_ops cpu_ops = {
.set_parent = dmn_clk_set_parent,
.get_parent = dmn_clk_get_parent,
.set_rate = cpu_clk_set_rate,
.round_rate = cpu_clk_round_rate,
.recalc_rate = cpu_clk_recalc_rate,
};
static struct clk_init_data clk_cpu_init = {
@ -532,6 +566,11 @@ static struct clk_dmn clk_mm = {
},
};
/*
* for atlas6, gfx2d holds the bit of prima2's clk_mm
*/
#define clk_gfx2d clk_mm
static struct clk_init_data clk_lcd_init = {
.name = "lcd",
.ops = &dmn_ops,
@ -569,14 +608,6 @@ static struct clk_init_data clk_mmc01_init = {
.num_parents = ARRAY_SIZE(dmn_clk_parents),
};
static struct clk_dmn clk_mmc01 = {
.regofs = SIRFSOC_CLKC_MMC_CFG,
.enable_bit = 59,
.hw = {
.init = &clk_mmc01_init,
},
};
static struct clk_init_data clk_mmc23_init = {
.name = "mmc23",
.ops = &dmn_ops,
@ -584,14 +615,6 @@ static struct clk_init_data clk_mmc23_init = {
.num_parents = ARRAY_SIZE(dmn_clk_parents),
};
static struct clk_dmn clk_mmc23 = {
.regofs = SIRFSOC_CLKC_MMC_CFG,
.enable_bit = 60,
.hw = {
.init = &clk_mmc23_init,
},
};
static struct clk_init_data clk_mmc45_init = {
.name = "mmc45",
.ops = &dmn_ops,
@ -599,14 +622,6 @@ static struct clk_init_data clk_mmc45_init = {
.num_parents = ARRAY_SIZE(dmn_clk_parents),
};
static struct clk_dmn clk_mmc45 = {
.regofs = SIRFSOC_CLKC_MMC_CFG,
.enable_bit = 61,
.hw = {
.init = &clk_mmc45_init,
},
};
/*
* peripheral controllers in io domain
*/
@ -667,6 +682,20 @@ static struct clk_ops ios_ops = {
.disable = std_clk_disable,
};
static struct clk_init_data clk_cphif_init = {
.name = "cphif",
.ops = &ios_ops,
.parent_names = std_clk_io_parents,
.num_parents = ARRAY_SIZE(std_clk_io_parents),
};
static struct clk_std clk_cphif = {
.enable_bit = 20,
.hw = {
.init = &clk_cphif_init,
},
};
static struct clk_init_data clk_dmac0_init = {
.name = "dmac0",
.ops = &ios_ops,
@ -695,20 +724,6 @@ static struct clk_std clk_dmac1 = {
},
};
static struct clk_init_data clk_nand_init = {
.name = "nand",
.ops = &ios_ops,
.parent_names = std_clk_io_parents,
.num_parents = ARRAY_SIZE(std_clk_io_parents),
};
static struct clk_std clk_nand = {
.enable_bit = 34,
.hw = {
.init = &clk_nand_init,
},
};
static struct clk_init_data clk_audio_init = {
.name = "audio",
.ops = &ios_ops,
@ -970,7 +985,7 @@ static const char *std_clk_sys_parents[] = {
};
static struct clk_init_data clk_security_init = {
.name = "mf",
.name = "security",
.ops = &ios_ops,
.parent_names = std_clk_sys_parents,
.num_parents = ARRAY_SIZE(std_clk_sys_parents),
@ -1014,96 +1029,3 @@ static struct clk_std clk_usb1 = {
.init = &clk_usb1_init,
},
};
enum prima2_clk_index {
/* 0 1 2 3 4 5 6 7 8 9 */
rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
usb0, usb1, maxclk,
};
static struct clk_hw *prima2_clk_hw_array[maxclk] __initdata = {
NULL, /* dummy */
NULL,
&clk_pll1.hw,
&clk_pll2.hw,
&clk_pll3.hw,
&clk_mem.hw,
&clk_sys.hw,
&clk_security.hw,
&clk_dsp.hw,
&clk_gps.hw,
&clk_mf.hw,
&clk_io.hw,
&clk_cpu.hw,
&clk_uart0.hw,
&clk_uart1.hw,
&clk_uart2.hw,
&clk_tsc.hw,
&clk_i2c0.hw,
&clk_i2c1.hw,
&clk_spi0.hw,
&clk_spi1.hw,
&clk_pwmc.hw,
&clk_efuse.hw,
&clk_pulse.hw,
&clk_dmac0.hw,
&clk_dmac1.hw,
&clk_nand.hw,
&clk_audio.hw,
&clk_usp0.hw,
&clk_usp1.hw,
&clk_usp2.hw,
&clk_vip.hw,
&clk_gfx.hw,
&clk_mm.hw,
&clk_lcd.hw,
&clk_vpp.hw,
&clk_mmc01.hw,
&clk_mmc23.hw,
&clk_mmc45.hw,
&usb_pll_clk_hw,
&clk_usb0.hw,
&clk_usb1.hw,
};
static struct clk *prima2_clks[maxclk];
static struct clk_onecell_data clk_data;
static void __init sirfsoc_clk_init(struct device_node *np)
{
struct device_node *rscnp;
int i;
rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
if (!sirfsoc_rsc_vbase)
panic("unable to map rsc registers\n");
of_node_put(rscnp);
sirfsoc_clk_vbase = of_iomap(np, 0);
if (!sirfsoc_clk_vbase)
panic("unable to map clkc registers\n");
/* These are always available (RTC and 26MHz OSC)*/
prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
CLK_IS_ROOT, 32768);
prima2_clks[osc]= clk_register_fixed_rate(NULL, "osc", NULL,
CLK_IS_ROOT, 26000000);
for (i = pll1; i < maxclk; i++) {
prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
BUG_ON(IS_ERR(prima2_clks[i]));
}
clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
clk_register_clkdev(prima2_clks[io], NULL, "io");
clk_register_clkdev(prima2_clks[mem], NULL, "mem");
clk_data.clks = prima2_clks;
clk_data.clk_num = maxclk;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
CLK_OF_DECLARE(sirfsoc_clk, "sirf,prima2-clkc", sirfsoc_clk_init);

Просмотреть файл

@ -0,0 +1,151 @@
/*
* Clock tree for CSR SiRFprimaII
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
* Licensed under GPLv2 or later.
*/
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include "prima2.h"
#include "clk-common.c"
static struct clk_dmn clk_mmc01 = {
.regofs = SIRFSOC_CLKC_MMC_CFG,
.enable_bit = 59,
.hw = {
.init = &clk_mmc01_init,
},
};
static struct clk_dmn clk_mmc23 = {
.regofs = SIRFSOC_CLKC_MMC_CFG,
.enable_bit = 60,
.hw = {
.init = &clk_mmc23_init,
},
};
static struct clk_dmn clk_mmc45 = {
.regofs = SIRFSOC_CLKC_MMC_CFG,
.enable_bit = 61,
.hw = {
.init = &clk_mmc45_init,
},
};
static struct clk_init_data clk_nand_init = {
.name = "nand",
.ops = &ios_ops,
.parent_names = std_clk_io_parents,
.num_parents = ARRAY_SIZE(std_clk_io_parents),
};
static struct clk_std clk_nand = {
.enable_bit = 34,
.hw = {
.init = &clk_nand_init,
},
};
enum prima2_clk_index {
/* 0 1 2 3 4 5 6 7 8 9 */
rtc, osc, pll1, pll2, pll3, mem, sys, security, dsp, gps,
mf, io, cpu, uart0, uart1, uart2, tsc, i2c0, i2c1, spi0,
spi1, pwmc, efuse, pulse, dmac0, dmac1, nand, audio, usp0, usp1,
usp2, vip, gfx, mm, lcd, vpp, mmc01, mmc23, mmc45, usbpll,
usb0, usb1, cphif, maxclk,
};
static __initdata struct clk_hw *prima2_clk_hw_array[maxclk] = {
NULL, /* dummy */
NULL,
&clk_pll1.hw,
&clk_pll2.hw,
&clk_pll3.hw,
&clk_mem.hw,
&clk_sys.hw,
&clk_security.hw,
&clk_dsp.hw,
&clk_gps.hw,
&clk_mf.hw,
&clk_io.hw,
&clk_cpu.hw,
&clk_uart0.hw,
&clk_uart1.hw,
&clk_uart2.hw,
&clk_tsc.hw,
&clk_i2c0.hw,
&clk_i2c1.hw,
&clk_spi0.hw,
&clk_spi1.hw,
&clk_pwmc.hw,
&clk_efuse.hw,
&clk_pulse.hw,
&clk_dmac0.hw,
&clk_dmac1.hw,
&clk_nand.hw,
&clk_audio.hw,
&clk_usp0.hw,
&clk_usp1.hw,
&clk_usp2.hw,
&clk_vip.hw,
&clk_gfx.hw,
&clk_mm.hw,
&clk_lcd.hw,
&clk_vpp.hw,
&clk_mmc01.hw,
&clk_mmc23.hw,
&clk_mmc45.hw,
&usb_pll_clk_hw,
&clk_usb0.hw,
&clk_usb1.hw,
&clk_cphif.hw,
};
static struct clk *prima2_clks[maxclk];
static void __init prima2_clk_init(struct device_node *np)
{
struct device_node *rscnp;
int i;
rscnp = of_find_compatible_node(NULL, NULL, "sirf,prima2-rsc");
sirfsoc_rsc_vbase = of_iomap(rscnp, 0);
if (!sirfsoc_rsc_vbase)
panic("unable to map rsc registers\n");
of_node_put(rscnp);
sirfsoc_clk_vbase = of_iomap(np, 0);
if (!sirfsoc_clk_vbase)
panic("unable to map clkc registers\n");
/* These are always available (RTC and 26MHz OSC)*/
prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL,
CLK_IS_ROOT, 32768);
prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL,
CLK_IS_ROOT, 26000000);
for (i = pll1; i < maxclk; i++) {
prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
BUG_ON(!prima2_clks[i]);
}
clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
clk_register_clkdev(prima2_clks[io], NULL, "io");
clk_register_clkdev(prima2_clks[mem], NULL, "mem");
clk_register_clkdev(prima2_clks[mem], NULL, "osc");
clk_data.clks = prima2_clks;
clk_data.clk_num = maxclk;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
CLK_OF_DECLARE(prima2_clk, "sirf,prima2-clkc", prima2_clk_init);

25
drivers/clk/sirf/prima2.h Normal file
Просмотреть файл

@ -0,0 +1,25 @@
#define SIRFSOC_CLKC_CLK_EN0 0x0000
#define SIRFSOC_CLKC_CLK_EN1 0x0004
#define SIRFSOC_CLKC_REF_CFG 0x0014
#define SIRFSOC_CLKC_CPU_CFG 0x0018
#define SIRFSOC_CLKC_MEM_CFG 0x001c
#define SIRFSOC_CLKC_SYS_CFG 0x0020
#define SIRFSOC_CLKC_IO_CFG 0x0024
#define SIRFSOC_CLKC_DSP_CFG 0x0028
#define SIRFSOC_CLKC_GFX_CFG 0x002c
#define SIRFSOC_CLKC_MM_CFG 0x0030
#define SIRFSOC_CLKC_LCD_CFG 0x0034
#define SIRFSOC_CLKC_MMC_CFG 0x0038
#define SIRFSOC_CLKC_PLL1_CFG0 0x0040
#define SIRFSOC_CLKC_PLL2_CFG0 0x0044
#define SIRFSOC_CLKC_PLL3_CFG0 0x0048
#define SIRFSOC_CLKC_PLL1_CFG1 0x004c
#define SIRFSOC_CLKC_PLL2_CFG1 0x0050
#define SIRFSOC_CLKC_PLL3_CFG1 0x0054
#define SIRFSOC_CLKC_PLL1_CFG2 0x0058
#define SIRFSOC_CLKC_PLL2_CFG2 0x005c
#define SIRFSOC_CLKC_PLL3_CFG2 0x0060
#define SIRFSOC_USBPHY_PLL_CTRL 0x0008
#define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1)
#define SIRFSOC_USBPHY_PLL_BYPASS BIT(2)
#define SIRFSOC_USBPHY_PLL_LOCK BIT(3)

Просмотреть файл

@ -121,9 +121,7 @@ static __init struct clk *socfpga_clk_init(struct device_node *node,
int rc;
u32 fixed_div;
rc = of_property_read_u32(node, "reg", &reg);
if (WARN_ON(rc))
return NULL;
of_property_read_u32(node, "reg", &reg);
socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
if (WARN_ON(!socfpga_clk))
@ -292,7 +290,7 @@ static void __init socfpga_gate_clk_init(struct device_node *node,
socfpga_clk->shift = div_reg[1];
socfpga_clk->width = div_reg[2];
} else {
socfpga_clk->div_reg = 0;
socfpga_clk->div_reg = NULL;
}
of_property_read_string(node, "clock-output-names", &clk_name);

Просмотреть файл

@ -116,7 +116,7 @@ static int clk_frac_set_rate(struct clk_hw *hw, unsigned long drate,
return 0;
}
struct clk_ops clk_frac_ops = {
static struct clk_ops clk_frac_ops = {
.recalc_rate = clk_frac_recalc_rate,
.round_rate = clk_frac_round_rate,
.set_rate = clk_frac_set_rate,

Просмотреть файл

@ -30,17 +30,9 @@
* parent - fixed parent. No clk_set_parent support
*/
struct clk_factors {
struct clk_hw hw;
void __iomem *reg;
struct clk_factors_config *config;
void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
spinlock_t *lock;
};
#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
#define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos))
#define SETMASK(len, pos) (((1U << (len)) - 1) << (pos))
#define CLRMASK(len, pos) (~(SETMASK(len, pos)))
#define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit))
@ -88,7 +80,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
u8 n, k, m, p;
u8 n = 0, k = 0, m = 0, p = 0;
u32 reg;
struct clk_factors *factors = to_clk_factors(hw);
struct clk_factors_config *config = factors->config;
@ -120,61 +112,8 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static const struct clk_ops clk_factors_ops = {
const struct clk_ops clk_factors_ops = {
.recalc_rate = clk_factors_recalc_rate,
.round_rate = clk_factors_round_rate,
.set_rate = clk_factors_set_rate,
};
/**
* clk_register_factors - register a factors clock with
* the clock framework
* @dev: device registering this clock
* @name: name of this clock
* @parent_name: name of clock's parent
* @flags: framework-specific flags
* @reg: register address to adjust factors
* @config: shift and width of factors n, k, m and p
* @get_factors: function to calculate the factors for a given frequency
* @lock: shared register lock for this clock
*/
struct clk *clk_register_factors(struct device *dev, const char *name,
const char *parent_name,
unsigned long flags, void __iomem *reg,
struct clk_factors_config *config,
void (*get_factors)(u32 *rate, u32 parent,
u8 *n, u8 *k, u8 *m, u8 *p),
spinlock_t *lock)
{
struct clk_factors *factors;
struct clk *clk;
struct clk_init_data init;
/* allocate the factors */
factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
if (!factors) {
pr_err("%s: could not allocate factors clk\n", __func__);
return ERR_PTR(-ENOMEM);
}
init.name = name;
init.ops = &clk_factors_ops;
init.flags = flags;
init.parent_names = (parent_name ? &parent_name : NULL);
init.num_parents = (parent_name ? 1 : 0);
/* struct clk_factors assignments */
factors->reg = reg;
factors->config = config;
factors->lock = lock;
factors->hw.init = &init;
factors->get_factors = get_factors;
/* register the clock */
clk = clk_register(dev, &factors->hw);
if (IS_ERR(clk))
kfree(factors);
return clk;
}

Просмотреть файл

@ -17,11 +17,13 @@ struct clk_factors_config {
u8 pwidth;
};
struct clk *clk_register_factors(struct device *dev, const char *name,
const char *parent_name,
unsigned long flags, void __iomem *reg,
struct clk_factors_config *config,
void (*get_factors) (u32 *rate, u32 parent_rate,
u8 *n, u8 *k, u8 *m, u8 *p),
spinlock_t *lock);
struct clk_factors {
struct clk_hw hw;
void __iomem *reg;
struct clk_factors_config *config;
void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
spinlock_t *lock;
};
extern const struct clk_ops clk_factors_ops;
#endif

Просмотреть файл

@ -23,6 +23,9 @@
static DEFINE_SPINLOCK(clk_lock);
/* Maximum number of parents our clocks have */
#define SUNXI_MAX_PARENTS 5
/**
* sun4i_osc_clk_setup() - Setup function for gatable oscillator
*/
@ -37,18 +40,16 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
const char *clk_name = node->name;
u32 rate;
if (of_property_read_u32(node, "clock-frequency", &rate))
return;
/* allocate fixed-rate and gate clock structs */
fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL);
if (!fixed)
return;
gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
if (!gate) {
kfree(fixed);
return;
}
if (of_property_read_u32(node, "clock-frequency", &rate))
return;
if (!gate)
goto err_free_fixed;
/* set up gate and fixed rate properties */
gate->reg = of_iomap(node, 0);
@ -63,10 +64,18 @@ static void __init sun4i_osc_clk_setup(struct device_node *node)
&gate->hw, &clk_gate_ops,
CLK_IS_ROOT);
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, clk_name, NULL);
}
if (IS_ERR(clk))
goto err_free_gate;
of_clk_add_provider(node, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, clk_name, NULL);
return;
err_free_gate:
kfree(gate);
err_free_fixed:
kfree(fixed);
}
CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup);
@ -208,6 +217,40 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
}
}
/**
* sun4i_get_pll5_factors() - calculates n, k factors for PLL5
* PLL5 rate is calculated as follows
* rate = parent_rate * n * (k + 1)
* parent_rate is always 24Mhz
*/
static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate,
u8 *n, u8 *k, u8 *m, u8 *p)
{
u8 div;
/* Normalize value to a parent_rate multiple (24M) */
div = *freq / parent_rate;
*freq = parent_rate * div;
/* we were called to round the frequency, we can now return */
if (n == NULL)
return;
if (div < 31)
*k = 0;
else if (div / 2 < 31)
*k = 1;
else if (div / 3 < 31)
*k = 2;
else
*k = 3;
*n = DIV_ROUND_UP(div, (*k+1));
}
/**
* sun4i_get_apb1_factors() - calculates m, p factors for APB1
* APB1 rate is calculated as follows
@ -251,11 +294,97 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
/**
* sun4i_get_mod0_factors() - calculates m, n factors for MOD0-style clocks
* MMC rate is calculated as follows
* rate = (parent_rate >> p) / (m + 1);
*/
static void sun4i_get_mod0_factors(u32 *freq, u32 parent_rate,
u8 *n, u8 *k, u8 *m, u8 *p)
{
u8 div, calcm, calcp;
/* These clocks can only divide, so we will never be able to achieve
* frequencies higher than the parent frequency */
if (*freq > parent_rate)
*freq = parent_rate;
div = parent_rate / *freq;
if (div < 16)
calcp = 0;
else if (div / 2 < 16)
calcp = 1;
else if (div / 4 < 16)
calcp = 2;
else
calcp = 3;
calcm = DIV_ROUND_UP(div, 1 << calcp);
*freq = (parent_rate >> calcp) / calcm;
/* we were called to round the frequency, we can now return */
if (n == NULL)
return;
*m = calcm - 1;
*p = calcp;
}
/**
* sun7i_a20_get_out_factors() - calculates m, p factors for CLK_OUT_A/B
* CLK_OUT rate is calculated as follows
* rate = (parent_rate >> p) / (m + 1);
*/
static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate,
u8 *n, u8 *k, u8 *m, u8 *p)
{
u8 div, calcm, calcp;
/* These clocks can only divide, so we will never be able to achieve
* frequencies higher than the parent frequency */
if (*freq > parent_rate)
*freq = parent_rate;
div = parent_rate / *freq;
if (div < 32)
calcp = 0;
else if (div / 2 < 32)
calcp = 1;
else if (div / 4 < 32)
calcp = 2;
else
calcp = 3;
calcm = DIV_ROUND_UP(div, 1 << calcp);
*freq = (parent_rate >> calcp) / calcm;
/* we were called to round the frequency, we can now return */
if (n == NULL)
return;
*m = calcm - 1;
*p = calcp;
}
/**
* sunxi_factors_clk_setup() - Setup function for factor clocks
*/
#define SUNXI_FACTORS_MUX_MASK 0x3
struct factors_data {
int enable;
int mux;
struct clk_factors_config *table;
void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
};
@ -280,6 +409,13 @@ static struct clk_factors_config sun6i_a31_pll1_config = {
.mwidth = 2,
};
static struct clk_factors_config sun4i_pll5_config = {
.nshift = 8,
.nwidth = 5,
.kshift = 4,
.kwidth = 2,
};
static struct clk_factors_config sun4i_apb1_config = {
.mshift = 0,
.mwidth = 5,
@ -287,40 +423,143 @@ static struct clk_factors_config sun4i_apb1_config = {
.pwidth = 2,
};
/* user manual says "n" but it's really "p" */
static struct clk_factors_config sun4i_mod0_config = {
.mshift = 0,
.mwidth = 4,
.pshift = 16,
.pwidth = 2,
};
/* user manual says "n" but it's really "p" */
static struct clk_factors_config sun7i_a20_out_config = {
.mshift = 8,
.mwidth = 5,
.pshift = 20,
.pwidth = 2,
};
static const struct factors_data sun4i_pll1_data __initconst = {
.enable = 31,
.table = &sun4i_pll1_config,
.getter = sun4i_get_pll1_factors,
};
static const struct factors_data sun6i_a31_pll1_data __initconst = {
.enable = 31,
.table = &sun6i_a31_pll1_config,
.getter = sun6i_a31_get_pll1_factors,
};
static const struct factors_data sun4i_pll5_data __initconst = {
.enable = 31,
.table = &sun4i_pll5_config,
.getter = sun4i_get_pll5_factors,
};
static const struct factors_data sun4i_apb1_data __initconst = {
.table = &sun4i_apb1_config,
.getter = sun4i_get_apb1_factors,
};
static void __init sunxi_factors_clk_setup(struct device_node *node,
struct factors_data *data)
static const struct factors_data sun4i_mod0_data __initconst = {
.enable = 31,
.mux = 24,
.table = &sun4i_mod0_config,
.getter = sun4i_get_mod0_factors,
};
static const struct factors_data sun7i_a20_out_data __initconst = {
.enable = 31,
.mux = 24,
.table = &sun7i_a20_out_config,
.getter = sun7i_a20_get_out_factors,
};
static struct clk * __init sunxi_factors_clk_setup(struct device_node *node,
const struct factors_data *data)
{
struct clk *clk;
struct clk_factors *factors;
struct clk_gate *gate = NULL;
struct clk_mux *mux = NULL;
struct clk_hw *gate_hw = NULL;
struct clk_hw *mux_hw = NULL;
const char *clk_name = node->name;
const char *parent;
const char *parents[SUNXI_MAX_PARENTS];
void *reg;
int i = 0;
reg = of_iomap(node, 0);
parent = of_clk_get_parent_name(node, 0);
/* if we have a mux, we will have >1 parents */
while (i < SUNXI_MAX_PARENTS &&
(parents[i] = of_clk_get_parent_name(node, i)) != NULL)
i++;
clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
data->table, data->getter, &clk_lock);
/* Nodes should be providing the name via clock-output-names
* but originally our dts didn't, and so we used node->name.
* The new, better nodes look like clk@deadbeef, so we pull the
* name just in this case */
if (!strcmp("clk", clk_name)) {
of_property_read_string_index(node, "clock-output-names",
0, &clk_name);
}
factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
if (!factors)
return NULL;
/* Add a gate if this factor clock can be gated */
if (data->enable) {
gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
if (!gate) {
kfree(factors);
return NULL;
}
/* set up gate properties */
gate->reg = reg;
gate->bit_idx = data->enable;
gate->lock = &clk_lock;
gate_hw = &gate->hw;
}
/* Add a mux if this factor clock can be muxed */
if (data->mux) {
mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
if (!mux) {
kfree(factors);
kfree(gate);
return NULL;
}
/* set up gate properties */
mux->reg = reg;
mux->shift = data->mux;
mux->mask = SUNXI_FACTORS_MUX_MASK;
mux->lock = &clk_lock;
mux_hw = &mux->hw;
}
/* set up factors properties */
factors->reg = reg;
factors->config = data->table;
factors->get_factors = data->getter;
factors->lock = &clk_lock;
clk = clk_register_composite(NULL, clk_name,
parents, i,
mux_hw, &clk_mux_ops,
&factors->hw, &clk_factors_ops,
gate_hw, &clk_gate_ops, 0);
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
clk_register_clkdev(clk, clk_name, NULL);
}
return clk;
}
@ -352,13 +591,14 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
{
struct clk *clk;
const char *clk_name = node->name;
const char *parents[5];
const char *parents[SUNXI_MAX_PARENTS];
void *reg;
int i = 0;
reg = of_iomap(node, 0);
while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
while (i < SUNXI_MAX_PARENTS &&
(parents[i] = of_clk_get_parent_name(node, i)) != NULL)
i++;
clk = clk_register_mux(NULL, clk_name, parents, i,
@ -555,11 +795,186 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
}
/**
* sunxi_divs_clk_setup() helper data
*/
#define SUNXI_DIVS_MAX_QTY 2
#define SUNXI_DIVISOR_WIDTH 2
struct divs_data {
const struct factors_data *factors; /* data for the factor clock */
struct {
u8 fixed; /* is it a fixed divisor? if not... */
struct clk_div_table *table; /* is it a table based divisor? */
u8 shift; /* otherwise it's a normal divisor with this shift */
u8 pow; /* is it power-of-two based? */
u8 gate; /* is it independently gateable? */
} div[SUNXI_DIVS_MAX_QTY];
};
static struct clk_div_table pll6_sata_tbl[] = {
{ .val = 0, .div = 6, },
{ .val = 1, .div = 12, },
{ .val = 2, .div = 18, },
{ .val = 3, .div = 24, },
{ } /* sentinel */
};
static const struct divs_data pll5_divs_data __initconst = {
.factors = &sun4i_pll5_data,
.div = {
{ .shift = 0, .pow = 0, }, /* M, DDR */
{ .shift = 16, .pow = 1, }, /* P, other */
}
};
static const struct divs_data pll6_divs_data __initconst = {
.factors = &sun4i_pll5_data,
.div = {
{ .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
{ .fixed = 2 }, /* P, other */
}
};
/**
* sunxi_divs_clk_setup() - Setup function for leaf divisors on clocks
*
* These clocks look something like this
* ________________________
* | ___divisor 1---|----> to consumer
* parent >--| pll___/___divisor 2---|----> to consumer
* | \_______________|____> to consumer
* |________________________|
*/
static void __init sunxi_divs_clk_setup(struct device_node *node,
struct divs_data *data)
{
struct clk_onecell_data *clk_data;
const char *parent = node->name;
const char *clk_name;
struct clk **clks, *pclk;
struct clk_hw *gate_hw, *rate_hw;
const struct clk_ops *rate_ops;
struct clk_gate *gate = NULL;
struct clk_fixed_factor *fix_factor;
struct clk_divider *divider;
void *reg;
int i = 0;
int flags, clkflags;
/* Set up factor clock that we will be dividing */
pclk = sunxi_factors_clk_setup(node, data->factors);
reg = of_iomap(node, 0);
clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
if (!clk_data)
return;
clks = kzalloc(SUNXI_DIVS_MAX_QTY * sizeof(struct clk *), GFP_KERNEL);
if (!clks)
goto free_clkdata;
clk_data->clks = clks;
/* It's not a good idea to have automatic reparenting changing
* our RAM clock! */
clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
for (i = 0; i < SUNXI_DIVS_MAX_QTY; i++) {
if (of_property_read_string_index(node, "clock-output-names",
i, &clk_name) != 0)
break;
gate_hw = NULL;
rate_hw = NULL;
rate_ops = NULL;
/* If this leaf clock can be gated, create a gate */
if (data->div[i].gate) {
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate)
goto free_clks;
gate->reg = reg;
gate->bit_idx = data->div[i].gate;
gate->lock = &clk_lock;
gate_hw = &gate->hw;
}
/* Leaves can be fixed or configurable divisors */
if (data->div[i].fixed) {
fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL);
if (!fix_factor)
goto free_gate;
fix_factor->mult = 1;
fix_factor->div = data->div[i].fixed;
rate_hw = &fix_factor->hw;
rate_ops = &clk_fixed_factor_ops;
} else {
divider = kzalloc(sizeof(*divider), GFP_KERNEL);
if (!divider)
goto free_gate;
flags = data->div[i].pow ? CLK_DIVIDER_POWER_OF_TWO : 0;
divider->reg = reg;
divider->shift = data->div[i].shift;
divider->width = SUNXI_DIVISOR_WIDTH;
divider->flags = flags;
divider->lock = &clk_lock;
divider->table = data->div[i].table;
rate_hw = &divider->hw;
rate_ops = &clk_divider_ops;
}
/* Wrap the (potential) gate and the divisor on a composite
* clock to unify them */
clks[i] = clk_register_composite(NULL, clk_name, &parent, 1,
NULL, NULL,
rate_hw, rate_ops,
gate_hw, &clk_gate_ops,
clkflags);
WARN_ON(IS_ERR(clk_data->clks[i]));
clk_register_clkdev(clks[i], clk_name, NULL);
}
/* The last clock available on the getter is the parent */
clks[i++] = pclk;
/* Adjust to the real max */
clk_data->clk_num = i;
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
return;
free_gate:
kfree(gate);
free_clks:
kfree(clks);
free_clkdata:
kfree(clk_data);
}
/* Matches for factors clocks */
static const struct of_device_id clk_factors_match[] __initconst = {
{.compatible = "allwinner,sun4i-pll1-clk", .data = &sun4i_pll1_data,},
{.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
{.compatible = "allwinner,sun4i-apb1-clk", .data = &sun4i_apb1_data,},
{.compatible = "allwinner,sun4i-mod0-clk", .data = &sun4i_mod0_data,},
{.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
{}
};
@ -572,6 +987,13 @@ static const struct of_device_id clk_div_match[] __initconst = {
{}
};
/* Matches for divided outputs */
static const struct of_device_id clk_divs_match[] __initconst = {
{.compatible = "allwinner,sun4i-pll5-clk", .data = &pll5_divs_data,},
{.compatible = "allwinner,sun4i-pll6-clk", .data = &pll6_divs_data,},
{}
};
/* Matches for mux clocks */
static const struct of_device_id clk_mux_match[] __initconst = {
{.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
@ -616,7 +1038,32 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
}
}
static void __init sunxi_init_clocks(struct device_node *np)
/**
* System clock protection
*
* By enabling these critical clocks, we prevent their accidental gating
* by the framework
*/
static void __init sunxi_clock_protect(void)
{
struct clk *clk;
/* memory bus clock - sun5i+ */
clk = clk_get(NULL, "mbus");
if (!IS_ERR(clk)) {
clk_prepare_enable(clk);
clk_put(clk);
}
/* DDR clock - sun4i+ */
clk = clk_get(NULL, "pll5_ddr");
if (!IS_ERR(clk)) {
clk_prepare_enable(clk);
clk_put(clk);
}
}
static void __init sunxi_init_clocks(void)
{
/* Register factor clocks */
of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
@ -624,11 +1071,17 @@ static void __init sunxi_init_clocks(struct device_node *np)
/* Register divider clocks */
of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
/* Register divided output clocks */
of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
/* Register mux clocks */
of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
/* Register gate clocks */
of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
/* Enable core system clocks */
sunxi_clock_protect();
}
CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sunxi_init_clocks);
CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sunxi_init_clocks);

Просмотреть файл

@ -122,7 +122,7 @@ const struct clk_ops tegra_clk_periph_ops = {
.disable = clk_periph_disable,
};
const struct clk_ops tegra_clk_periph_nodiv_ops = {
static const struct clk_ops tegra_clk_periph_nodiv_ops = {
.get_parent = clk_periph_get_parent,
.set_parent = clk_periph_set_parent,
.is_enabled = clk_periph_is_enabled,

Просмотреть файл

@ -1433,7 +1433,7 @@ struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
}
#if defined(CONFIG_ARCH_TEGRA_114_SOC) || defined(CONFIG_ARCH_TEGRA_124_SOC)
const struct clk_ops tegra_clk_pllxc_ops = {
static const struct clk_ops tegra_clk_pllxc_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pll_iddq_enable,
.disable = clk_pll_iddq_disable,
@ -1442,7 +1442,7 @@ const struct clk_ops tegra_clk_pllxc_ops = {
.set_rate = clk_pllxc_set_rate,
};
const struct clk_ops tegra_clk_pllm_ops = {
static const struct clk_ops tegra_clk_pllm_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pll_iddq_enable,
.disable = clk_pll_iddq_disable,
@ -1451,7 +1451,7 @@ const struct clk_ops tegra_clk_pllm_ops = {
.set_rate = clk_pllm_set_rate,
};
const struct clk_ops tegra_clk_pllc_ops = {
static const struct clk_ops tegra_clk_pllc_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pllc_enable,
.disable = clk_pllc_disable,
@ -1460,7 +1460,7 @@ const struct clk_ops tegra_clk_pllc_ops = {
.set_rate = clk_pllc_set_rate,
};
const struct clk_ops tegra_clk_pllre_ops = {
static const struct clk_ops tegra_clk_pllre_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pll_iddq_enable,
.disable = clk_pll_iddq_disable,
@ -1469,7 +1469,7 @@ const struct clk_ops tegra_clk_pllre_ops = {
.set_rate = clk_pllre_set_rate,
};
const struct clk_ops tegra_clk_plle_tegra114_ops = {
static const struct clk_ops tegra_clk_plle_tegra114_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_plle_tegra114_enable,
.disable = clk_plle_tegra114_disable,
@ -1731,7 +1731,7 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
#endif
#ifdef CONFIG_ARCH_TEGRA_124_SOC
const struct clk_ops tegra_clk_pllss_ops = {
static const struct clk_ops tegra_clk_pllss_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pll_iddq_enable,
.disable = clk_pll_iddq_disable,

Просмотреть файл

@ -36,7 +36,7 @@ static int clk_prcmu_prepare(struct clk_hw *hw)
if (!ret)
clk->is_prepared = 1;
return ret;;
return ret;
}
static void clk_prcmu_unprepare(struct clk_hw *hw)

Просмотреть файл

@ -123,7 +123,7 @@ static const struct clk_ops clk_sp810_timerclken_ops = {
.set_parent = clk_sp810_timerclken_set_parent,
};
struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec,
static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec,
void *data)
{
struct clk_sp810 *sp810 = data;

Просмотреть файл

@ -102,9 +102,10 @@ static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"};
static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
const char *clk_name, void __iomem *fclk_ctrl_reg,
const char **parents)
const char **parents, int enable)
{
struct clk *clk;
u32 enable_reg;
char *mux_name;
char *div0_name;
char *div1_name;
@ -147,6 +148,12 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
clks[fclk] = clk_register_gate(NULL, clk_name,
div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
enable_reg = readl(fclk_gate_reg) & 1;
if (enable && !enable_reg) {
if (clk_prepare_enable(clks[fclk]))
pr_warn("%s: FCLK%u enable failed\n", __func__,
fclk - fclk0);
}
kfree(mux_name);
kfree(div0_name);
kfree(div1_name);
@ -213,6 +220,7 @@ static void __init zynq_clk_setup(struct device_node *np)
int ret;
struct clk *clk;
char *clk_name;
unsigned int fclk_enable = 0;
const char *clk_output_name[clk_max];
const char *cpu_parents[4];
const char *periph_parents[4];
@ -238,6 +246,8 @@ static void __init zynq_clk_setup(struct device_node *np)
periph_parents[2] = clk_output_name[armpll];
periph_parents[3] = clk_output_name[ddrpll];
of_property_read_u32(np, "fclk-enable", &fclk_enable);
/* ps_clk */
ret = of_property_read_u32(np, "ps-clk-frequency", &tmp);
if (ret) {
@ -340,10 +350,12 @@ static void __init zynq_clk_setup(struct device_node *np)
clk_prepare_enable(clks[dci]);
/* Peripheral clocks */
for (i = fclk0; i <= fclk3; i++)
for (i = fclk0; i <= fclk3; i++) {
int enable = !!(fclk_enable & BIT(i - fclk0));
zynq_clk_register_fclk(i, clk_output_name[i],
SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0),
periph_parents);
periph_parents, enable);
}
zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL,
SLCR_LQSPI_CLK_CTRL, periph_parents, 0);

Просмотреть файл

@ -290,9 +290,11 @@ static int isp_xclk_init(struct isp_device *isp)
struct clk_init_data init;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i)
isp->xclks[i].clk = ERR_PTR(-EINVAL);
for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
struct isp_xclk *xclk = &isp->xclks[i];
struct clk *clk;
xclk->isp = isp;
xclk->id = i == 0 ? ISP_XCLK_A : ISP_XCLK_B;
@ -305,10 +307,15 @@ static int isp_xclk_init(struct isp_device *isp)
init.num_parents = 1;
xclk->hw.init = &init;
clk = devm_clk_register(isp->dev, &xclk->hw);
if (IS_ERR(clk))
return PTR_ERR(clk);
/*
* The first argument is NULL in order to avoid circular
* reference, as this driver takes reference on the
* sensor subdevice modules and the sensors would take
* reference on this module through clk_get().
*/
xclk->clk = clk_register(NULL, &xclk->hw);
if (IS_ERR(xclk->clk))
return PTR_ERR(xclk->clk);
if (pdata->xclks[i].con_id == NULL &&
pdata->xclks[i].dev_id == NULL)
@ -320,7 +327,7 @@ static int isp_xclk_init(struct isp_device *isp)
xclk->lookup->con_id = pdata->xclks[i].con_id;
xclk->lookup->dev_id = pdata->xclks[i].dev_id;
xclk->lookup->clk = clk;
xclk->lookup->clk = xclk->clk;
clkdev_add(xclk->lookup);
}
@ -335,6 +342,9 @@ static void isp_xclk_cleanup(struct isp_device *isp)
for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
struct isp_xclk *xclk = &isp->xclks[i];
if (!IS_ERR(xclk->clk))
clk_unregister(xclk->clk);
if (xclk->lookup)
clkdev_drop(xclk->lookup);
}

Просмотреть файл

@ -135,6 +135,7 @@ struct isp_xclk {
struct isp_device *isp;
struct clk_hw hw;
struct clk_lookup *lookup;
struct clk *clk;
enum isp_xclk_id id;
spinlock_t lock; /* Protects enabled and divider */

Просмотреть файл

@ -19,7 +19,8 @@
#define EXYNOS_SCLK_I2S 7
#define EXYNOS_PCM_BUS 8
#define EXYNOS_SCLK_PCM 9
#define EXYNOS_ADMA 10
#define EXYNOS_AUDSS_MAX_CLKS 10
#define EXYNOS_AUDSS_MAX_CLKS 11
#endif

Просмотреть файл

@ -0,0 +1,244 @@
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* Author: Andrzej Haja <a.hajda@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Device Tree binding constants for Exynos4 clock controller.
*/
#ifndef _DT_BINDINGS_CLOCK_EXYNOS_4_H
#define _DT_BINDINGS_CLOCK_EXYNOS_4_H
/* core clocks */
#define CLK_XXTI 1
#define CLK_XUSBXTI 2
#define CLK_FIN_PLL 3
#define CLK_FOUT_APLL 4
#define CLK_FOUT_MPLL 5
#define CLK_FOUT_EPLL 6
#define CLK_FOUT_VPLL 7
#define CLK_SCLK_APLL 8
#define CLK_SCLK_MPLL 9
#define CLK_SCLK_EPLL 10
#define CLK_SCLK_VPLL 11
#define CLK_ARM_CLK 12
#define CLK_ACLK200 13
#define CLK_ACLK100 14
#define CLK_ACLK160 15
#define CLK_ACLK133 16
#define CLK_MOUT_MPLL_USER_T 17 /* Exynos4x12 only */
#define CLK_MOUT_MPLL_USER_C 18 /* Exynos4x12 only */
#define CLK_MOUT_CORE 19
#define CLK_MOUT_APLL 20
/* gate for special clocks (sclk) */
#define CLK_SCLK_FIMC0 128
#define CLK_SCLK_FIMC1 129
#define CLK_SCLK_FIMC2 130
#define CLK_SCLK_FIMC3 131
#define CLK_SCLK_CAM0 132
#define CLK_SCLK_CAM1 133
#define CLK_SCLK_CSIS0 134
#define CLK_SCLK_CSIS1 135
#define CLK_SCLK_HDMI 136
#define CLK_SCLK_MIXER 137
#define CLK_SCLK_DAC 138
#define CLK_SCLK_PIXEL 139
#define CLK_SCLK_FIMD0 140
#define CLK_SCLK_MDNIE0 141 /* Exynos4412 only */
#define CLK_SCLK_MDNIE_PWM0 142
#define CLK_SCLK_MIPI0 143
#define CLK_SCLK_AUDIO0 144
#define CLK_SCLK_MMC0 145
#define CLK_SCLK_MMC1 146
#define CLK_SCLK_MMC2 147
#define CLK_SCLK_MMC3 148
#define CLK_SCLK_MMC4 149
#define CLK_SCLK_SATA 150 /* Exynos4210 only */
#define CLK_SCLK_UART0 151
#define CLK_SCLK_UART1 152
#define CLK_SCLK_UART2 153
#define CLK_SCLK_UART3 154
#define CLK_SCLK_UART4 155
#define CLK_SCLK_AUDIO1 156
#define CLK_SCLK_AUDIO2 157
#define CLK_SCLK_SPDIF 158
#define CLK_SCLK_SPI0 159
#define CLK_SCLK_SPI1 160
#define CLK_SCLK_SPI2 161
#define CLK_SCLK_SLIMBUS 162
#define CLK_SCLK_FIMD1 163 /* Exynos4210 only */
#define CLK_SCLK_MIPI1 164 /* Exynos4210 only */
#define CLK_SCLK_PCM1 165
#define CLK_SCLK_PCM2 166
#define CLK_SCLK_I2S1 167
#define CLK_SCLK_I2S2 168
#define CLK_SCLK_MIPIHSI 169 /* Exynos4412 only */
#define CLK_SCLK_MFC 170
#define CLK_SCLK_PCM0 171
#define CLK_SCLK_G3D 172
#define CLK_SCLK_PWM_ISP 173 /* Exynos4x12 only */
#define CLK_SCLK_SPI0_ISP 174 /* Exynos4x12 only */
#define CLK_SCLK_SPI1_ISP 175 /* Exynos4x12 only */
#define CLK_SCLK_UART_ISP 176 /* Exynos4x12 only */
#define CLK_SCLK_FIMG2D 177
/* gate clocks */
#define CLK_FIMC0 256
#define CLK_FIMC1 257
#define CLK_FIMC2 258
#define CLK_FIMC3 259
#define CLK_CSIS0 260
#define CLK_CSIS1 261
#define CLK_JPEG 262
#define CLK_SMMU_FIMC0 263
#define CLK_SMMU_FIMC1 264
#define CLK_SMMU_FIMC2 265
#define CLK_SMMU_FIMC3 266
#define CLK_SMMU_JPEG 267
#define CLK_VP 268
#define CLK_MIXER 269
#define CLK_TVENC 270 /* Exynos4210 only */
#define CLK_HDMI 271
#define CLK_SMMU_TV 272
#define CLK_MFC 273
#define CLK_SMMU_MFCL 274
#define CLK_SMMU_MFCR 275
#define CLK_G3D 276
#define CLK_G2D 277
#define CLK_ROTATOR 278 /* Exynos4210 only */
#define CLK_MDMA 279 /* Exynos4210 only */
#define CLK_SMMU_G2D 280 /* Exynos4210 only */
#define CLK_SMMU_ROTATOR 281 /* Exynos4210 only */
#define CLK_SMMU_MDMA 282 /* Exynos4210 only */
#define CLK_FIMD0 283
#define CLK_MIE0 284
#define CLK_MDNIE0 285 /* Exynos4412 only */
#define CLK_DSIM0 286
#define CLK_SMMU_FIMD0 287
#define CLK_FIMD1 288 /* Exynos4210 only */
#define CLK_MIE1 289 /* Exynos4210 only */
#define CLK_DSIM1 290 /* Exynos4210 only */
#define CLK_SMMU_FIMD1 291 /* Exynos4210 only */
#define CLK_PDMA0 292
#define CLK_PDMA1 293
#define CLK_PCIE_PHY 294
#define CLK_SATA_PHY 295 /* Exynos4210 only */
#define CLK_TSI 296
#define CLK_SDMMC0 297
#define CLK_SDMMC1 298
#define CLK_SDMMC2 299
#define CLK_SDMMC3 300
#define CLK_SDMMC4 301
#define CLK_SATA 302 /* Exynos4210 only */
#define CLK_SROMC 303
#define CLK_USB_HOST 304
#define CLK_USB_DEVICE 305
#define CLK_PCIE 306
#define CLK_ONENAND 307
#define CLK_NFCON 308
#define CLK_SMMU_PCIE 309
#define CLK_GPS 310
#define CLK_SMMU_GPS 311
#define CLK_UART0 312
#define CLK_UART1 313
#define CLK_UART2 314
#define CLK_UART3 315
#define CLK_UART4 316
#define CLK_I2C0 317
#define CLK_I2C1 318
#define CLK_I2C2 319
#define CLK_I2C3 320
#define CLK_I2C4 321
#define CLK_I2C5 322
#define CLK_I2C6 323
#define CLK_I2C7 324
#define CLK_I2C_HDMI 325
#define CLK_TSADC 326
#define CLK_SPI0 327
#define CLK_SPI1 328
#define CLK_SPI2 329
#define CLK_I2S1 330
#define CLK_I2S2 331
#define CLK_PCM0 332
#define CLK_I2S0 333
#define CLK_PCM1 334
#define CLK_PCM2 335
#define CLK_PWM 336
#define CLK_SLIMBUS 337
#define CLK_SPDIF 338
#define CLK_AC97 339
#define CLK_MODEMIF 340
#define CLK_CHIPID 341
#define CLK_SYSREG 342
#define CLK_HDMI_CEC 343
#define CLK_MCT 344
#define CLK_WDT 345
#define CLK_RTC 346
#define CLK_KEYIF 347
#define CLK_AUDSS 348
#define CLK_MIPI_HSI 349 /* Exynos4210 only */
#define CLK_MDMA2 350 /* Exynos4210 only */
#define CLK_PIXELASYNCM0 351
#define CLK_PIXELASYNCM1 352
#define CLK_FIMC_LITE0 353 /* Exynos4x12 only */
#define CLK_FIMC_LITE1 354 /* Exynos4x12 only */
#define CLK_PPMUISPX 355 /* Exynos4x12 only */
#define CLK_PPMUISPMX 356 /* Exynos4x12 only */
#define CLK_FIMC_ISP 357 /* Exynos4x12 only */
#define CLK_FIMC_DRC 358 /* Exynos4x12 only */
#define CLK_FIMC_FD 359 /* Exynos4x12 only */
#define CLK_MCUISP 360 /* Exynos4x12 only */
#define CLK_GICISP 361 /* Exynos4x12 only */
#define CLK_SMMU_ISP 362 /* Exynos4x12 only */
#define CLK_SMMU_DRC 363 /* Exynos4x12 only */
#define CLK_SMMU_FD 364 /* Exynos4x12 only */
#define CLK_SMMU_LITE0 365 /* Exynos4x12 only */
#define CLK_SMMU_LITE1 366 /* Exynos4x12 only */
#define CLK_MCUCTL_ISP 367 /* Exynos4x12 only */
#define CLK_MPWM_ISP 368 /* Exynos4x12 only */
#define CLK_I2C0_ISP 369 /* Exynos4x12 only */
#define CLK_I2C1_ISP 370 /* Exynos4x12 only */
#define CLK_MTCADC_ISP 371 /* Exynos4x12 only */
#define CLK_PWM_ISP 372 /* Exynos4x12 only */
#define CLK_WDT_ISP 373 /* Exynos4x12 only */
#define CLK_UART_ISP 374 /* Exynos4x12 only */
#define CLK_ASYNCAXIM 375 /* Exynos4x12 only */
#define CLK_SMMU_ISPCX 376 /* Exynos4x12 only */
#define CLK_SPI0_ISP 377 /* Exynos4x12 only */
#define CLK_SPI1_ISP 378 /* Exynos4x12 only */
#define CLK_PWM_ISP_SCLK 379 /* Exynos4x12 only */
#define CLK_SPI0_ISP_SCLK 380 /* Exynos4x12 only */
#define CLK_SPI1_ISP_SCLK 381 /* Exynos4x12 only */
#define CLK_UART_ISP_SCLK 382 /* Exynos4x12 only */
#define CLK_TMU_APBIF 383
/* mux clocks */
#define CLK_MOUT_FIMC0 384
#define CLK_MOUT_FIMC1 385
#define CLK_MOUT_FIMC2 386
#define CLK_MOUT_FIMC3 387
#define CLK_MOUT_CAM0 388
#define CLK_MOUT_CAM1 389
#define CLK_MOUT_CSIS0 390
#define CLK_MOUT_CSIS1 391
#define CLK_MOUT_G3D0 392
#define CLK_MOUT_G3D1 393
#define CLK_MOUT_G3D 394
#define CLK_ACLK400_MCUISP 395 /* Exynos4x12 only */
/* div clocks */
#define CLK_DIV_ISP0 450 /* Exynos4x12 only */
#define CLK_DIV_ISP1 451 /* Exynos4x12 only */
#define CLK_DIV_MCUISP0 452 /* Exynos4x12 only */
#define CLK_DIV_MCUISP1 453 /* Exynos4x12 only */
#define CLK_DIV_ACLK200 454 /* Exynos4x12 only */
#define CLK_DIV_ACLK400_MCUISP 455 /* Exynos4x12 only */
/* must be greater than maximal clock id */
#define CLK_NR_CLKS 456
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_4_H */

Просмотреть файл

@ -0,0 +1,160 @@
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* Author: Andrzej Haja <a.hajda@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Device Tree binding constants for Exynos5250 clock controller.
*/
#ifndef _DT_BINDINGS_CLOCK_EXYNOS_5250_H
#define _DT_BINDINGS_CLOCK_EXYNOS_5250_H
/* core clocks */
#define CLK_FIN_PLL 1
#define CLK_FOUT_APLL 2
#define CLK_FOUT_MPLL 3
#define CLK_FOUT_BPLL 4
#define CLK_FOUT_GPLL 5
#define CLK_FOUT_CPLL 6
#define CLK_FOUT_EPLL 7
#define CLK_FOUT_VPLL 8
/* gate for special clocks (sclk) */
#define CLK_SCLK_CAM_BAYER 128
#define CLK_SCLK_CAM0 129
#define CLK_SCLK_CAM1 130
#define CLK_SCLK_GSCL_WA 131
#define CLK_SCLK_GSCL_WB 132
#define CLK_SCLK_FIMD1 133
#define CLK_SCLK_MIPI1 134
#define CLK_SCLK_DP 135
#define CLK_SCLK_HDMI 136
#define CLK_SCLK_PIXEL 137
#define CLK_SCLK_AUDIO0 138
#define CLK_SCLK_MMC0 139
#define CLK_SCLK_MMC1 140
#define CLK_SCLK_MMC2 141
#define CLK_SCLK_MMC3 142
#define CLK_SCLK_SATA 143
#define CLK_SCLK_USB3 144
#define CLK_SCLK_JPEG 145
#define CLK_SCLK_UART0 146
#define CLK_SCLK_UART1 147
#define CLK_SCLK_UART2 148
#define CLK_SCLK_UART3 149
#define CLK_SCLK_PWM 150
#define CLK_SCLK_AUDIO1 151
#define CLK_SCLK_AUDIO2 152
#define CLK_SCLK_SPDIF 153
#define CLK_SCLK_SPI0 154
#define CLK_SCLK_SPI1 155
#define CLK_SCLK_SPI2 156
#define CLK_DIV_I2S1 157
#define CLK_DIV_I2S2 158
#define CLK_SCLK_HDMIPHY 159
#define CLK_DIV_PCM0 160
/* gate clocks */
#define CLK_GSCL0 256
#define CLK_GSCL1 257
#define CLK_GSCL2 258
#define CLK_GSCL3 259
#define CLK_GSCL_WA 260
#define CLK_GSCL_WB 261
#define CLK_SMMU_GSCL0 262
#define CLK_SMMU_GSCL1 263
#define CLK_SMMU_GSCL2 264
#define CLK_SMMU_GSCL3 265
#define CLK_MFC 266
#define CLK_SMMU_MFCL 267
#define CLK_SMMU_MFCR 268
#define CLK_ROTATOR 269
#define CLK_JPEG 270
#define CLK_MDMA1 271
#define CLK_SMMU_ROTATOR 272
#define CLK_SMMU_JPEG 273
#define CLK_SMMU_MDMA1 274
#define CLK_PDMA0 275
#define CLK_PDMA1 276
#define CLK_SATA 277
#define CLK_USBOTG 278
#define CLK_MIPI_HSI 279
#define CLK_SDMMC0 280
#define CLK_SDMMC1 281
#define CLK_SDMMC2 282
#define CLK_SDMMC3 283
#define CLK_SROMC 284
#define CLK_USB2 285
#define CLK_USB3 286
#define CLK_SATA_PHYCTRL 287
#define CLK_SATA_PHYI2C 288
#define CLK_UART0 289
#define CLK_UART1 290
#define CLK_UART2 291
#define CLK_UART3 292
#define CLK_UART4 293
#define CLK_I2C0 294
#define CLK_I2C1 295
#define CLK_I2C2 296
#define CLK_I2C3 297
#define CLK_I2C4 298
#define CLK_I2C5 299
#define CLK_I2C6 300
#define CLK_I2C7 301
#define CLK_I2C_HDMI 302
#define CLK_ADC 303
#define CLK_SPI0 304
#define CLK_SPI1 305
#define CLK_SPI2 306
#define CLK_I2S1 307
#define CLK_I2S2 308
#define CLK_PCM1 309
#define CLK_PCM2 310
#define CLK_PWM 311
#define CLK_SPDIF 312
#define CLK_AC97 313
#define CLK_HSI2C0 314
#define CLK_HSI2C1 315
#define CLK_HSI2C2 316
#define CLK_HSI2C3 317
#define CLK_CHIPID 318
#define CLK_SYSREG 319
#define CLK_PMU 320
#define CLK_CMU_TOP 321
#define CLK_CMU_CORE 322
#define CLK_CMU_MEM 323
#define CLK_TZPC0 324
#define CLK_TZPC1 325
#define CLK_TZPC2 326
#define CLK_TZPC3 327
#define CLK_TZPC4 328
#define CLK_TZPC5 329
#define CLK_TZPC6 330
#define CLK_TZPC7 331
#define CLK_TZPC8 332
#define CLK_TZPC9 333
#define CLK_HDMI_CEC 334
#define CLK_MCT 335
#define CLK_WDT 336
#define CLK_RTC 337
#define CLK_TMU 338
#define CLK_FIMD1 339
#define CLK_MIE1 340
#define CLK_DSIM0 341
#define CLK_DP 342
#define CLK_MIXER 343
#define CLK_HDMI 344
#define CLK_G2D 345
#define CLK_MDMA0 346
#define CLK_SMMU_MDMA0 347
/* mux clocks */
#define CLK_MOUT_HDMI 1024
/* must be greater than maximal clock id */
#define CLK_NR_CLKS 1025
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5250_H */

Просмотреть файл

@ -0,0 +1,188 @@
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* Author: Andrzej Haja <a.hajda@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Device Tree binding constants for Exynos5420 clock controller.
*/
#ifndef _DT_BINDINGS_CLOCK_EXYNOS_5420_H
#define _DT_BINDINGS_CLOCK_EXYNOS_5420_H
/* core clocks */
#define CLK_FIN_PLL 1
#define CLK_FOUT_APLL 2
#define CLK_FOUT_CPLL 3
#define CLK_FOUT_DPLL 4
#define CLK_FOUT_EPLL 5
#define CLK_FOUT_RPLL 6
#define CLK_FOUT_IPLL 7
#define CLK_FOUT_SPLL 8
#define CLK_FOUT_VPLL 9
#define CLK_FOUT_MPLL 10
#define CLK_FOUT_BPLL 11
#define CLK_FOUT_KPLL 12
/* gate for special clocks (sclk) */
#define CLK_SCLK_UART0 128
#define CLK_SCLK_UART1 129
#define CLK_SCLK_UART2 130
#define CLK_SCLK_UART3 131
#define CLK_SCLK_MMC0 132
#define CLK_SCLK_MMC1 133
#define CLK_SCLK_MMC2 134
#define CLK_SCLK_SPI0 135
#define CLK_SCLK_SPI1 136
#define CLK_SCLK_SPI2 137
#define CLK_SCLK_I2S1 138
#define CLK_SCLK_I2S2 139
#define CLK_SCLK_PCM1 140
#define CLK_SCLK_PCM2 141
#define CLK_SCLK_SPDIF 142
#define CLK_SCLK_HDMI 143
#define CLK_SCLK_PIXEL 144
#define CLK_SCLK_DP1 145
#define CLK_SCLK_MIPI1 146
#define CLK_SCLK_FIMD1 147
#define CLK_SCLK_MAUDIO0 148
#define CLK_SCLK_MAUPCM0 149
#define CLK_SCLK_USBD300 150
#define CLK_SCLK_USBD301 151
#define CLK_SCLK_USBPHY300 152
#define CLK_SCLK_USBPHY301 153
#define CLK_SCLK_UNIPRO 154
#define CLK_SCLK_PWM 155
#define CLK_SCLK_GSCL_WA 156
#define CLK_SCLK_GSCL_WB 157
#define CLK_SCLK_HDMIPHY 158
/* gate clocks */
#define CLK_ACLK66_PERIC 256
#define CLK_UART0 257
#define CLK_UART1 258
#define CLK_UART2 259
#define CLK_UART3 260
#define CLK_I2C0 261
#define CLK_I2C1 262
#define CLK_I2C2 263
#define CLK_I2C3 264
#define CLK_I2C4 265
#define CLK_I2C5 266
#define CLK_I2C6 267
#define CLK_I2C7 268
#define CLK_I2C_HDMI 269
#define CLK_TSADC 270
#define CLK_SPI0 271
#define CLK_SPI1 272
#define CLK_SPI2 273
#define CLK_KEYIF 274
#define CLK_I2S1 275
#define CLK_I2S2 276
#define CLK_PCM1 277
#define CLK_PCM2 278
#define CLK_PWM 279
#define CLK_SPDIF 280
#define CLK_I2C8 281
#define CLK_I2C9 282
#define CLK_I2C10 283
#define CLK_ACLK66_PSGEN 300
#define CLK_CHIPID 301
#define CLK_SYSREG 302
#define CLK_TZPC0 303
#define CLK_TZPC1 304
#define CLK_TZPC2 305
#define CLK_TZPC3 306
#define CLK_TZPC4 307
#define CLK_TZPC5 308
#define CLK_TZPC6 309
#define CLK_TZPC7 310
#define CLK_TZPC8 311
#define CLK_TZPC9 312
#define CLK_HDMI_CEC 313
#define CLK_SECKEY 314
#define CLK_MCT 315
#define CLK_WDT 316
#define CLK_RTC 317
#define CLK_TMU 318
#define CLK_TMU_GPU 319
#define CLK_PCLK66_GPIO 330
#define CLK_ACLK200_FSYS2 350
#define CLK_MMC0 351
#define CLK_MMC1 352
#define CLK_MMC2 353
#define CLK_SROMC 354
#define CLK_UFS 355
#define CLK_ACLK200_FSYS 360
#define CLK_TSI 361
#define CLK_PDMA0 362
#define CLK_PDMA1 363
#define CLK_RTIC 364
#define CLK_USBH20 365
#define CLK_USBD300 366
#define CLK_USBD301 367
#define CLK_ACLK400_MSCL 380
#define CLK_MSCL0 381
#define CLK_MSCL1 382
#define CLK_MSCL2 383
#define CLK_SMMU_MSCL0 384
#define CLK_SMMU_MSCL1 385
#define CLK_SMMU_MSCL2 386
#define CLK_ACLK333 400
#define CLK_MFC 401
#define CLK_SMMU_MFCL 402
#define CLK_SMMU_MFCR 403
#define CLK_ACLK200_DISP1 410
#define CLK_DSIM1 411
#define CLK_DP1 412
#define CLK_HDMI 413
#define CLK_ACLK300_DISP1 420
#define CLK_FIMD1 421
#define CLK_SMMU_FIMD1 422
#define CLK_ACLK166 430
#define CLK_MIXER 431
#define CLK_ACLK266 440
#define CLK_ROTATOR 441
#define CLK_MDMA1 442
#define CLK_SMMU_ROTATOR 443
#define CLK_SMMU_MDMA1 444
#define CLK_ACLK300_JPEG 450
#define CLK_JPEG 451
#define CLK_JPEG2 452
#define CLK_SMMU_JPEG 453
#define CLK_ACLK300_GSCL 460
#define CLK_SMMU_GSCL0 461
#define CLK_SMMU_GSCL1 462
#define CLK_GSCL_WA 463
#define CLK_GSCL_WB 464
#define CLK_GSCL0 465
#define CLK_GSCL1 466
#define CLK_CLK_3AA 467
#define CLK_ACLK266_G2D 470
#define CLK_SSS 471
#define CLK_SLIM_SSS 472
#define CLK_MDMA0 473
#define CLK_ACLK333_G2D 480
#define CLK_G2D 481
#define CLK_ACLK333_432_GSCL 490
#define CLK_SMMU_3AA 491
#define CLK_SMMU_FIMCL0 492
#define CLK_SMMU_FIMCL1 493
#define CLK_SMMU_FIMCL3 494
#define CLK_FIMC_LITE3 495
#define CLK_ACLK_G3D 500
#define CLK_G3D 501
#define CLK_SMMU_MIXER 502
/* mux clocks */
#define CLK_MOUT_HDMI 640
/* divider clocks */
#define CLK_DOUT_PIXEL 768
/* must be greater than maximal clock id */
#define CLK_NR_CLKS 769
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */

Просмотреть файл

@ -0,0 +1,42 @@
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* Author: Andrzej Haja <a.hajda-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Device Tree binding constants for Exynos5440 clock controller.
*/
#ifndef _DT_BINDINGS_CLOCK_EXYNOS_5440_H
#define _DT_BINDINGS_CLOCK_EXYNOS_5440_H
#define CLK_XTAL 1
#define CLK_ARM_CLK 2
#define CLK_SPI_BAUD 16
#define CLK_PB0_250 17
#define CLK_PR0_250 18
#define CLK_PR1_250 19
#define CLK_B_250 20
#define CLK_B_125 21
#define CLK_B_200 22
#define CLK_SATA 23
#define CLK_USB 24
#define CLK_GMAC0 25
#define CLK_CS250 26
#define CLK_PB0_250_O 27
#define CLK_PR0_250_O 28
#define CLK_PR1_250_O 29
#define CLK_B_250_O 30
#define CLK_B_125_O 31
#define CLK_B_200_O 32
#define CLK_SATA_O 33
#define CLK_USB_O 34
#define CLK_GMAC0_O 35
#define CLK_CS250_O 36
/* must be greater than maximal clock id */
#define CLK_NR_CLKS 37
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_5440_H */

Просмотреть файл

@ -0,0 +1,152 @@
/*
* Copyright (c) 2012-2013 Hisilicon Limited.
* Copyright (c) 2012-2013 Linaro Limited.
*
* Author: Haojian Zhuang <haojian.zhuang@linaro.org>
* Xin Li <li.xin@linaro.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef __DTS_HI3620_CLOCK_H
#define __DTS_HI3620_CLOCK_H
#define HI3620_NONE_CLOCK 0
/* fixed rate & fixed factor clocks */
#define HI3620_OSC32K 1
#define HI3620_OSC26M 2
#define HI3620_PCLK 3
#define HI3620_PLL_ARM0 4
#define HI3620_PLL_ARM1 5
#define HI3620_PLL_PERI 6
#define HI3620_PLL_USB 7
#define HI3620_PLL_HDMI 8
#define HI3620_PLL_GPU 9
#define HI3620_RCLK_TCXO 10
#define HI3620_RCLK_CFGAXI 11
#define HI3620_RCLK_PICO 12
/* mux clocks */
#define HI3620_TIMER0_MUX 32
#define HI3620_TIMER1_MUX 33
#define HI3620_TIMER2_MUX 34
#define HI3620_TIMER3_MUX 35
#define HI3620_TIMER4_MUX 36
#define HI3620_TIMER5_MUX 37
#define HI3620_TIMER6_MUX 38
#define HI3620_TIMER7_MUX 39
#define HI3620_TIMER8_MUX 40
#define HI3620_TIMER9_MUX 41
#define HI3620_UART0_MUX 42
#define HI3620_UART1_MUX 43
#define HI3620_UART2_MUX 44
#define HI3620_UART3_MUX 45
#define HI3620_UART4_MUX 46
#define HI3620_SPI0_MUX 47
#define HI3620_SPI1_MUX 48
#define HI3620_SPI2_MUX 49
#define HI3620_SAXI_MUX 50
#define HI3620_PWM0_MUX 51
#define HI3620_PWM1_MUX 52
#define HI3620_SD_MUX 53
#define HI3620_MMC1_MUX 54
#define HI3620_MMC1_MUX2 55
#define HI3620_G2D_MUX 56
#define HI3620_VENC_MUX 57
#define HI3620_VDEC_MUX 58
#define HI3620_VPP_MUX 59
#define HI3620_EDC0_MUX 60
#define HI3620_LDI0_MUX 61
#define HI3620_EDC1_MUX 62
#define HI3620_LDI1_MUX 63
#define HI3620_RCLK_HSIC 64
#define HI3620_MMC2_MUX 65
#define HI3620_MMC3_MUX 66
/* divider clocks */
#define HI3620_SHAREAXI_DIV 128
#define HI3620_CFGAXI_DIV 129
#define HI3620_SD_DIV 130
#define HI3620_MMC1_DIV 131
#define HI3620_HSIC_DIV 132
#define HI3620_MMC2_DIV 133
#define HI3620_MMC3_DIV 134
/* gate clocks */
#define HI3620_TIMERCLK01 160
#define HI3620_TIMER_RCLK01 161
#define HI3620_TIMERCLK23 162
#define HI3620_TIMER_RCLK23 163
#define HI3620_TIMERCLK45 164
#define HI3620_TIMERCLK67 165
#define HI3620_TIMERCLK89 166
#define HI3620_RTCCLK 167
#define HI3620_KPC_CLK 168
#define HI3620_GPIOCLK0 169
#define HI3620_GPIOCLK1 170
#define HI3620_GPIOCLK2 171
#define HI3620_GPIOCLK3 172
#define HI3620_GPIOCLK4 173
#define HI3620_GPIOCLK5 174
#define HI3620_GPIOCLK6 175
#define HI3620_GPIOCLK7 176
#define HI3620_GPIOCLK8 177
#define HI3620_GPIOCLK9 178
#define HI3620_GPIOCLK10 179
#define HI3620_GPIOCLK11 180
#define HI3620_GPIOCLK12 181
#define HI3620_GPIOCLK13 182
#define HI3620_GPIOCLK14 183
#define HI3620_GPIOCLK15 184
#define HI3620_GPIOCLK16 185
#define HI3620_GPIOCLK17 186
#define HI3620_GPIOCLK18 187
#define HI3620_GPIOCLK19 188
#define HI3620_GPIOCLK20 189
#define HI3620_GPIOCLK21 190
#define HI3620_DPHY0_CLK 191
#define HI3620_DPHY1_CLK 192
#define HI3620_DPHY2_CLK 193
#define HI3620_USBPHY_CLK 194
#define HI3620_ACP_CLK 195
#define HI3620_PWMCLK0 196
#define HI3620_PWMCLK1 197
#define HI3620_UARTCLK0 198
#define HI3620_UARTCLK1 199
#define HI3620_UARTCLK2 200
#define HI3620_UARTCLK3 201
#define HI3620_UARTCLK4 202
#define HI3620_SPICLK0 203
#define HI3620_SPICLK1 204
#define HI3620_SPICLK2 205
#define HI3620_I2CCLK0 206
#define HI3620_I2CCLK1 207
#define HI3620_I2CCLK2 208
#define HI3620_I2CCLK3 209
#define HI3620_SCI_CLK 210
#define HI3620_DDRC_PER_CLK 211
#define HI3620_DMAC_CLK 212
#define HI3620_USB2DVC_CLK 213
#define HI3620_SD_CLK 214
#define HI3620_MMC_CLK1 215
#define HI3620_MMC_CLK2 216
#define HI3620_MMC_CLK3 217
#define HI3620_MCU_CLK 218
#define HI3620_NR_CLKS 219
#endif /* __DTS_HI3620_CLOCK_H */

Просмотреть файл

@ -0,0 +1,276 @@
/*
* Copyright (c) 2013, 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 _DT_BINDINGS_CLK_MSM_GCC_8660_H
#define _DT_BINDINGS_CLK_MSM_GCC_8660_H
#define AFAB_CLK_SRC 0
#define AFAB_CORE_CLK 1
#define SCSS_A_CLK 2
#define SCSS_H_CLK 3
#define SCSS_XO_SRC_CLK 4
#define AFAB_EBI1_CH0_A_CLK 5
#define AFAB_EBI1_CH1_A_CLK 6
#define AFAB_AXI_S0_FCLK 7
#define AFAB_AXI_S1_FCLK 8
#define AFAB_AXI_S2_FCLK 9
#define AFAB_AXI_S3_FCLK 10
#define AFAB_AXI_S4_FCLK 11
#define SFAB_CORE_CLK 12
#define SFAB_AXI_S0_FCLK 13
#define SFAB_AXI_S1_FCLK 14
#define SFAB_AXI_S2_FCLK 15
#define SFAB_AXI_S3_FCLK 16
#define SFAB_AXI_S4_FCLK 17
#define SFAB_AHB_S0_FCLK 18
#define SFAB_AHB_S1_FCLK 19
#define SFAB_AHB_S2_FCLK 20
#define SFAB_AHB_S3_FCLK 21
#define SFAB_AHB_S4_FCLK 22
#define SFAB_AHB_S5_FCLK 23
#define SFAB_AHB_S6_FCLK 24
#define SFAB_ADM0_M0_A_CLK 25
#define SFAB_ADM0_M1_A_CLK 26
#define SFAB_ADM0_M2_A_CLK 27
#define ADM0_CLK 28
#define ADM0_PBUS_CLK 29
#define SFAB_ADM1_M0_A_CLK 30
#define SFAB_ADM1_M1_A_CLK 31
#define SFAB_ADM1_M2_A_CLK 32
#define MMFAB_ADM1_M3_A_CLK 33
#define ADM1_CLK 34
#define ADM1_PBUS_CLK 35
#define IMEM0_A_CLK 36
#define MAHB0_CLK 37
#define SFAB_LPASS_Q6_A_CLK 38
#define SFAB_AFAB_M_A_CLK 39
#define AFAB_SFAB_M0_A_CLK 40
#define AFAB_SFAB_M1_A_CLK 41
#define DFAB_CLK_SRC 42
#define DFAB_CLK 43
#define DFAB_CORE_CLK 44
#define SFAB_DFAB_M_A_CLK 45
#define DFAB_SFAB_M_A_CLK 46
#define DFAB_SWAY0_H_CLK 47
#define DFAB_SWAY1_H_CLK 48
#define DFAB_ARB0_H_CLK 49
#define DFAB_ARB1_H_CLK 50
#define PPSS_H_CLK 51
#define PPSS_PROC_CLK 52
#define PPSS_TIMER0_CLK 53
#define PPSS_TIMER1_CLK 54
#define PMEM_A_CLK 55
#define DMA_BAM_H_CLK 56
#define SIC_H_CLK 57
#define SPS_TIC_H_CLK 58
#define SLIMBUS_H_CLK 59
#define SLIMBUS_XO_SRC_CLK 60
#define CFPB_2X_CLK_SRC 61
#define CFPB_CLK 62
#define CFPB0_H_CLK 63
#define CFPB1_H_CLK 64
#define CFPB2_H_CLK 65
#define EBI2_2X_CLK 66
#define EBI2_CLK 67
#define SFAB_CFPB_M_H_CLK 68
#define CFPB_MASTER_H_CLK 69
#define SFAB_CFPB_S_HCLK 70
#define CFPB_SPLITTER_H_CLK 71
#define TSIF_H_CLK 72
#define TSIF_INACTIVITY_TIMERS_CLK 73
#define TSIF_REF_SRC 74
#define TSIF_REF_CLK 75
#define CE1_H_CLK 76
#define CE2_H_CLK 77
#define SFPB_H_CLK_SRC 78
#define SFPB_H_CLK 79
#define SFAB_SFPB_M_H_CLK 80
#define SFAB_SFPB_S_H_CLK 81
#define RPM_PROC_CLK 82
#define RPM_BUS_H_CLK 83
#define RPM_SLEEP_CLK 84
#define RPM_TIMER_CLK 85
#define MODEM_AHB1_H_CLK 86
#define MODEM_AHB2_H_CLK 87
#define RPM_MSG_RAM_H_CLK 88
#define SC_H_CLK 89
#define SC_A_CLK 90
#define PMIC_ARB0_H_CLK 91
#define PMIC_ARB1_H_CLK 92
#define PMIC_SSBI2_SRC 93
#define PMIC_SSBI2_CLK 94
#define SDC1_H_CLK 95
#define SDC2_H_CLK 96
#define SDC3_H_CLK 97
#define SDC4_H_CLK 98
#define SDC5_H_CLK 99
#define SDC1_SRC 100
#define SDC2_SRC 101
#define SDC3_SRC 102
#define SDC4_SRC 103
#define SDC5_SRC 104
#define SDC1_CLK 105
#define SDC2_CLK 106
#define SDC3_CLK 107
#define SDC4_CLK 108
#define SDC5_CLK 109
#define USB_HS1_H_CLK 110
#define USB_HS1_XCVR_SRC 111
#define USB_HS1_XCVR_CLK 112
#define USB_HS2_H_CLK 113
#define USB_HS2_XCVR_SRC 114
#define USB_HS2_XCVR_CLK 115
#define USB_FS1_H_CLK 116
#define USB_FS1_XCVR_FS_SRC 117
#define USB_FS1_XCVR_FS_CLK 118
#define USB_FS1_SYSTEM_CLK 119
#define USB_FS2_H_CLK 120
#define USB_FS2_XCVR_FS_SRC 121
#define USB_FS2_XCVR_FS_CLK 122
#define USB_FS2_SYSTEM_CLK 123
#define GSBI_COMMON_SIM_SRC 124
#define GSBI1_H_CLK 125
#define GSBI2_H_CLK 126
#define GSBI3_H_CLK 127
#define GSBI4_H_CLK 128
#define GSBI5_H_CLK 129
#define GSBI6_H_CLK 130
#define GSBI7_H_CLK 131
#define GSBI8_H_CLK 132
#define GSBI9_H_CLK 133
#define GSBI10_H_CLK 134
#define GSBI11_H_CLK 135
#define GSBI12_H_CLK 136
#define GSBI1_UART_SRC 137
#define GSBI1_UART_CLK 138
#define GSBI2_UART_SRC 139
#define GSBI2_UART_CLK 140
#define GSBI3_UART_SRC 141
#define GSBI3_UART_CLK 142
#define GSBI4_UART_SRC 143
#define GSBI4_UART_CLK 144
#define GSBI5_UART_SRC 145
#define GSBI5_UART_CLK 146
#define GSBI6_UART_SRC 147
#define GSBI6_UART_CLK 148
#define GSBI7_UART_SRC 149
#define GSBI7_UART_CLK 150
#define GSBI8_UART_SRC 151
#define GSBI8_UART_CLK 152
#define GSBI9_UART_SRC 153
#define GSBI9_UART_CLK 154
#define GSBI10_UART_SRC 155
#define GSBI10_UART_CLK 156
#define GSBI11_UART_SRC 157
#define GSBI11_UART_CLK 158
#define GSBI12_UART_SRC 159
#define GSBI12_UART_CLK 160
#define GSBI1_QUP_SRC 161
#define GSBI1_QUP_CLK 162
#define GSBI2_QUP_SRC 163
#define GSBI2_QUP_CLK 164
#define GSBI3_QUP_SRC 165
#define GSBI3_QUP_CLK 166
#define GSBI4_QUP_SRC 167
#define GSBI4_QUP_CLK 168
#define GSBI5_QUP_SRC 169
#define GSBI5_QUP_CLK 170
#define GSBI6_QUP_SRC 171
#define GSBI6_QUP_CLK 172
#define GSBI7_QUP_SRC 173
#define GSBI7_QUP_CLK 174
#define GSBI8_QUP_SRC 175
#define GSBI8_QUP_CLK 176
#define GSBI9_QUP_SRC 177
#define GSBI9_QUP_CLK 178
#define GSBI10_QUP_SRC 179
#define GSBI10_QUP_CLK 180
#define GSBI11_QUP_SRC 181
#define GSBI11_QUP_CLK 182
#define GSBI12_QUP_SRC 183
#define GSBI12_QUP_CLK 184
#define GSBI1_SIM_CLK 185
#define GSBI2_SIM_CLK 186
#define GSBI3_SIM_CLK 187
#define GSBI4_SIM_CLK 188
#define GSBI5_SIM_CLK 189
#define GSBI6_SIM_CLK 190
#define GSBI7_SIM_CLK 191
#define GSBI8_SIM_CLK 192
#define GSBI9_SIM_CLK 193
#define GSBI10_SIM_CLK 194
#define GSBI11_SIM_CLK 195
#define GSBI12_SIM_CLK 196
#define SPDM_CFG_H_CLK 197
#define SPDM_MSTR_H_CLK 198
#define SPDM_FF_CLK_SRC 199
#define SPDM_FF_CLK 200
#define SEC_CTRL_CLK 201
#define SEC_CTRL_ACC_CLK_SRC 202
#define SEC_CTRL_ACC_CLK 203
#define TLMM_H_CLK 204
#define TLMM_CLK 205
#define MARM_CLK_SRC 206
#define MARM_CLK 207
#define MAHB1_SRC 208
#define MAHB1_CLK 209
#define SFAB_MSS_S_H_CLK 210
#define MAHB2_SRC 211
#define MAHB2_CLK 212
#define MSS_MODEM_CLK_SRC 213
#define MSS_MODEM_CXO_CLK 214
#define MSS_SLP_CLK 215
#define MSS_SYS_REF_CLK 216
#define TSSC_CLK_SRC 217
#define TSSC_CLK 218
#define PDM_SRC 219
#define PDM_CLK 220
#define GP0_SRC 221
#define GP0_CLK 222
#define GP1_SRC 223
#define GP1_CLK 224
#define GP2_SRC 225
#define GP2_CLK 226
#define PMEM_CLK 227
#define MPM_CLK 228
#define EBI1_ASFAB_SRC 229
#define EBI1_CLK_SRC 230
#define EBI1_CH0_CLK 231
#define EBI1_CH1_CLK 232
#define SFAB_SMPSS_S_H_CLK 233
#define PRNG_SRC 234
#define PRNG_CLK 235
#define PXO_SRC 236
#define LPASS_CXO_CLK 237
#define LPASS_PXO_CLK 238
#define SPDM_CY_PORT0_CLK 239
#define SPDM_CY_PORT1_CLK 240
#define SPDM_CY_PORT2_CLK 241
#define SPDM_CY_PORT3_CLK 242
#define SPDM_CY_PORT4_CLK 243
#define SPDM_CY_PORT5_CLK 244
#define SPDM_CY_PORT6_CLK 245
#define SPDM_CY_PORT7_CLK 246
#define PLL0 247
#define PLL0_VOTE 248
#define PLL5 249
#define PLL6 250
#define PLL6_VOTE 251
#define PLL8 252
#define PLL8_VOTE 253
#define PLL9 254
#define PLL10 255
#define PLL11 256
#define PLL12 257
#endif

Просмотреть файл

@ -0,0 +1,313 @@
/*
* Copyright (c) 2013, 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 _DT_BINDINGS_CLK_MSM_GCC_8960_H
#define _DT_BINDINGS_CLK_MSM_GCC_8960_H
#define AFAB_CLK_SRC 0
#define AFAB_CORE_CLK 1
#define SFAB_MSS_Q6_SW_A_CLK 2
#define SFAB_MSS_Q6_FW_A_CLK 3
#define QDSS_STM_CLK 4
#define SCSS_A_CLK 5
#define SCSS_H_CLK 6
#define SCSS_XO_SRC_CLK 7
#define AFAB_EBI1_CH0_A_CLK 8
#define AFAB_EBI1_CH1_A_CLK 9
#define AFAB_AXI_S0_FCLK 10
#define AFAB_AXI_S1_FCLK 11
#define AFAB_AXI_S2_FCLK 12
#define AFAB_AXI_S3_FCLK 13
#define AFAB_AXI_S4_FCLK 14
#define SFAB_CORE_CLK 15
#define SFAB_AXI_S0_FCLK 16
#define SFAB_AXI_S1_FCLK 17
#define SFAB_AXI_S2_FCLK 18
#define SFAB_AXI_S3_FCLK 19
#define SFAB_AXI_S4_FCLK 20
#define SFAB_AHB_S0_FCLK 21
#define SFAB_AHB_S1_FCLK 22
#define SFAB_AHB_S2_FCLK 23
#define SFAB_AHB_S3_FCLK 24
#define SFAB_AHB_S4_FCLK 25
#define SFAB_AHB_S5_FCLK 26
#define SFAB_AHB_S6_FCLK 27
#define SFAB_AHB_S7_FCLK 28
#define QDSS_AT_CLK_SRC 29
#define QDSS_AT_CLK 30
#define QDSS_TRACECLKIN_CLK_SRC 31
#define QDSS_TRACECLKIN_CLK 32
#define QDSS_TSCTR_CLK_SRC 33
#define QDSS_TSCTR_CLK 34
#define SFAB_ADM0_M0_A_CLK 35
#define SFAB_ADM0_M1_A_CLK 36
#define SFAB_ADM0_M2_A_CLK 37
#define ADM0_CLK 38
#define ADM0_PBUS_CLK 39
#define MSS_XPU_CLK 40
#define IMEM0_A_CLK 41
#define QDSS_H_CLK 42
#define PCIE_A_CLK 43
#define PCIE_AUX_CLK 44
#define PCIE_PHY_REF_CLK 45
#define PCIE_H_CLK 46
#define SFAB_CLK_SRC 47
#define MAHB0_CLK 48
#define Q6SW_CLK_SRC 49
#define Q6SW_CLK 50
#define Q6FW_CLK_SRC 51
#define Q6FW_CLK 52
#define SFAB_MSS_M_A_CLK 53
#define SFAB_USB3_M_A_CLK 54
#define SFAB_LPASS_Q6_A_CLK 55
#define SFAB_AFAB_M_A_CLK 56
#define AFAB_SFAB_M0_A_CLK 57
#define AFAB_SFAB_M1_A_CLK 58
#define SFAB_SATA_S_H_CLK 59
#define DFAB_CLK_SRC 60
#define DFAB_CLK 61
#define SFAB_DFAB_M_A_CLK 62
#define DFAB_SFAB_M_A_CLK 63
#define DFAB_SWAY0_H_CLK 64
#define DFAB_SWAY1_H_CLK 65
#define DFAB_ARB0_H_CLK 66
#define DFAB_ARB1_H_CLK 67
#define PPSS_H_CLK 68
#define PPSS_PROC_CLK 69
#define PPSS_TIMER0_CLK 70
#define PPSS_TIMER1_CLK 71
#define PMEM_A_CLK 72
#define DMA_BAM_H_CLK 73
#define SIC_H_CLK 74
#define SPS_TIC_H_CLK 75
#define SLIMBUS_H_CLK 76
#define SLIMBUS_XO_SRC_CLK 77
#define CFPB_2X_CLK_SRC 78
#define CFPB_CLK 79
#define CFPB0_H_CLK 80
#define CFPB1_H_CLK 81
#define CFPB2_H_CLK 82
#define SFAB_CFPB_M_H_CLK 83
#define CFPB_MASTER_H_CLK 84
#define SFAB_CFPB_S_HCLK 85
#define CFPB_SPLITTER_H_CLK 86
#define TSIF_H_CLK 87
#define TSIF_INACTIVITY_TIMERS_CLK 88
#define TSIF_REF_SRC 89
#define TSIF_REF_CLK 90
#define CE1_H_CLK 91
#define CE1_CORE_CLK 92
#define CE1_SLEEP_CLK 93
#define CE2_H_CLK 94
#define CE2_CORE_CLK 95
#define CE2_SLEEP_CLK 96
#define SFPB_H_CLK_SRC 97
#define SFPB_H_CLK 98
#define SFAB_SFPB_M_H_CLK 99
#define SFAB_SFPB_S_H_CLK 100
#define RPM_PROC_CLK 101
#define RPM_BUS_H_CLK 102
#define RPM_SLEEP_CLK 103
#define RPM_TIMER_CLK 104
#define RPM_MSG_RAM_H_CLK 105
#define PMIC_ARB0_H_CLK 106
#define PMIC_ARB1_H_CLK 107
#define PMIC_SSBI2_SRC 108
#define PMIC_SSBI2_CLK 109
#define SDC1_H_CLK 110
#define SDC2_H_CLK 111
#define SDC3_H_CLK 112
#define SDC4_H_CLK 113
#define SDC5_H_CLK 114
#define SDC1_SRC 115
#define SDC2_SRC 116
#define SDC3_SRC 117
#define SDC4_SRC 118
#define SDC5_SRC 119
#define SDC1_CLK 120
#define SDC2_CLK 121
#define SDC3_CLK 122
#define SDC4_CLK 123
#define SDC5_CLK 124
#define DFAB_A2_H_CLK 125
#define USB_HS1_H_CLK 126
#define USB_HS1_XCVR_SRC 127
#define USB_HS1_XCVR_CLK 128
#define USB_HSIC_H_CLK 129
#define USB_HSIC_XCVR_FS_SRC 130
#define USB_HSIC_XCVR_FS_CLK 131
#define USB_HSIC_SYSTEM_CLK_SRC 132
#define USB_HSIC_SYSTEM_CLK 133
#define CFPB0_C0_H_CLK 134
#define CFPB0_C1_H_CLK 135
#define CFPB0_D0_H_CLK 136
#define CFPB0_D1_H_CLK 137
#define USB_FS1_H_CLK 138
#define USB_FS1_XCVR_FS_SRC 139
#define USB_FS1_XCVR_FS_CLK 140
#define USB_FS1_SYSTEM_CLK 141
#define USB_FS2_H_CLK 142
#define USB_FS2_XCVR_FS_SRC 143
#define USB_FS2_XCVR_FS_CLK 144
#define USB_FS2_SYSTEM_CLK 145
#define GSBI_COMMON_SIM_SRC 146
#define GSBI1_H_CLK 147
#define GSBI2_H_CLK 148
#define GSBI3_H_CLK 149
#define GSBI4_H_CLK 150
#define GSBI5_H_CLK 151
#define GSBI6_H_CLK 152
#define GSBI7_H_CLK 153
#define GSBI8_H_CLK 154
#define GSBI9_H_CLK 155
#define GSBI10_H_CLK 156
#define GSBI11_H_CLK 157
#define GSBI12_H_CLK 158
#define GSBI1_UART_SRC 159
#define GSBI1_UART_CLK 160
#define GSBI2_UART_SRC 161
#define GSBI2_UART_CLK 162
#define GSBI3_UART_SRC 163
#define GSBI3_UART_CLK 164
#define GSBI4_UART_SRC 165
#define GSBI4_UART_CLK 166
#define GSBI5_UART_SRC 167
#define GSBI5_UART_CLK 168
#define GSBI6_UART_SRC 169
#define GSBI6_UART_CLK 170
#define GSBI7_UART_SRC 171
#define GSBI7_UART_CLK 172
#define GSBI8_UART_SRC 173
#define GSBI8_UART_CLK 174
#define GSBI9_UART_SRC 175
#define GSBI9_UART_CLK 176
#define GSBI10_UART_SRC 177
#define GSBI10_UART_CLK 178
#define GSBI11_UART_SRC 179
#define GSBI11_UART_CLK 180
#define GSBI12_UART_SRC 181
#define GSBI12_UART_CLK 182
#define GSBI1_QUP_SRC 183
#define GSBI1_QUP_CLK 184
#define GSBI2_QUP_SRC 185
#define GSBI2_QUP_CLK 186
#define GSBI3_QUP_SRC 187
#define GSBI3_QUP_CLK 188
#define GSBI4_QUP_SRC 189
#define GSBI4_QUP_CLK 190
#define GSBI5_QUP_SRC 191
#define GSBI5_QUP_CLK 192
#define GSBI6_QUP_SRC 193
#define GSBI6_QUP_CLK 194
#define GSBI7_QUP_SRC 195
#define GSBI7_QUP_CLK 196
#define GSBI8_QUP_SRC 197
#define GSBI8_QUP_CLK 198
#define GSBI9_QUP_SRC 199
#define GSBI9_QUP_CLK 200
#define GSBI10_QUP_SRC 201
#define GSBI10_QUP_CLK 202
#define GSBI11_QUP_SRC 203
#define GSBI11_QUP_CLK 204
#define GSBI12_QUP_SRC 205
#define GSBI12_QUP_CLK 206
#define GSBI1_SIM_CLK 207
#define GSBI2_SIM_CLK 208
#define GSBI3_SIM_CLK 209
#define GSBI4_SIM_CLK 210
#define GSBI5_SIM_CLK 211
#define GSBI6_SIM_CLK 212
#define GSBI7_SIM_CLK 213
#define GSBI8_SIM_CLK 214
#define GSBI9_SIM_CLK 215
#define GSBI10_SIM_CLK 216
#define GSBI11_SIM_CLK 217
#define GSBI12_SIM_CLK 218
#define USB_HSIC_HSIC_CLK_SRC 219
#define USB_HSIC_HSIC_CLK 220
#define USB_HSIC_HSIO_CAL_CLK 221
#define SPDM_CFG_H_CLK 222
#define SPDM_MSTR_H_CLK 223
#define SPDM_FF_CLK_SRC 224
#define SPDM_FF_CLK 225
#define SEC_CTRL_CLK 226
#define SEC_CTRL_ACC_CLK_SRC 227
#define SEC_CTRL_ACC_CLK 228
#define TLMM_H_CLK 229
#define TLMM_CLK 230
#define SFAB_MSS_S_H_CLK 231
#define MSS_SLP_CLK 232
#define MSS_Q6SW_JTAG_CLK 233
#define MSS_Q6FW_JTAG_CLK 234
#define MSS_S_H_CLK 235
#define MSS_CXO_SRC_CLK 236
#define SATA_H_CLK 237
#define SATA_SRC_CLK 238
#define SATA_RXOOB_CLK 239
#define SATA_PMALIVE_CLK 240
#define SATA_PHY_REF_CLK 241
#define TSSC_CLK_SRC 242
#define TSSC_CLK 243
#define PDM_SRC 244
#define PDM_CLK 245
#define GP0_SRC 246
#define GP0_CLK 247
#define GP1_SRC 248
#define GP1_CLK 249
#define GP2_SRC 250
#define GP2_CLK 251
#define MPM_CLK 252
#define EBI1_CLK_SRC 253
#define EBI1_CH0_CLK 254
#define EBI1_CH1_CLK 255
#define EBI1_2X_CLK 256
#define EBI1_CH0_DQ_CLK 257
#define EBI1_CH1_DQ_CLK 258
#define EBI1_CH0_CA_CLK 259
#define EBI1_CH1_CA_CLK 260
#define EBI1_XO_CLK 261
#define SFAB_SMPSS_S_H_CLK 262
#define PRNG_SRC 263
#define PRNG_CLK 264
#define PXO_SRC 265
#define LPASS_CXO_CLK 266
#define LPASS_PXO_CLK 267
#define SPDM_CY_PORT0_CLK 268
#define SPDM_CY_PORT1_CLK 269
#define SPDM_CY_PORT2_CLK 270
#define SPDM_CY_PORT3_CLK 271
#define SPDM_CY_PORT4_CLK 272
#define SPDM_CY_PORT5_CLK 273
#define SPDM_CY_PORT6_CLK 274
#define SPDM_CY_PORT7_CLK 275
#define PLL0 276
#define PLL0_VOTE 277
#define PLL3 278
#define PLL3_VOTE 279
#define PLL4_VOTE 280
#define PLL5 281
#define PLL5_VOTE 282
#define PLL6 283
#define PLL6_VOTE 284
#define PLL7_VOTE 285
#define PLL8 286
#define PLL8_VOTE 287
#define PLL9 288
#define PLL10 289
#define PLL11 290
#define PLL12 291
#define PLL13 292
#define PLL14 293
#define PLL14_VOTE 294
#endif

Просмотреть файл

@ -0,0 +1,320 @@
/*
* Copyright (c) 2013, 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 _DT_BINDINGS_CLK_MSM_GCC_8974_H
#define _DT_BINDINGS_CLK_MSM_GCC_8974_H
#define GPLL0 0
#define GPLL0_VOTE 1
#define CONFIG_NOC_CLK_SRC 2
#define GPLL2 3
#define GPLL2_VOTE 4
#define GPLL3 5
#define GPLL3_VOTE 6
#define PERIPH_NOC_CLK_SRC 7
#define BLSP_UART_SIM_CLK_SRC 8
#define QDSS_TSCTR_CLK_SRC 9
#define BIMC_DDR_CLK_SRC 10
#define SYSTEM_NOC_CLK_SRC 11
#define GPLL1 12
#define GPLL1_VOTE 13
#define RPM_CLK_SRC 14
#define GCC_BIMC_CLK 15
#define BIMC_DDR_CPLL0_ROOT_CLK_SRC 16
#define KPSS_AHB_CLK_SRC 17
#define QDSS_AT_CLK_SRC 18
#define USB30_MASTER_CLK_SRC 19
#define BIMC_DDR_CPLL1_ROOT_CLK_SRC 20
#define QDSS_STM_CLK_SRC 21
#define ACC_CLK_SRC 22
#define SEC_CTRL_CLK_SRC 23
#define BLSP1_QUP1_I2C_APPS_CLK_SRC 24
#define BLSP1_QUP1_SPI_APPS_CLK_SRC 25
#define BLSP1_QUP2_I2C_APPS_CLK_SRC 26
#define BLSP1_QUP2_SPI_APPS_CLK_SRC 27
#define BLSP1_QUP3_I2C_APPS_CLK_SRC 28
#define BLSP1_QUP3_SPI_APPS_CLK_SRC 29
#define BLSP1_QUP4_I2C_APPS_CLK_SRC 30
#define BLSP1_QUP4_SPI_APPS_CLK_SRC 31
#define BLSP1_QUP5_I2C_APPS_CLK_SRC 32
#define BLSP1_QUP5_SPI_APPS_CLK_SRC 33
#define BLSP1_QUP6_I2C_APPS_CLK_SRC 34
#define BLSP1_QUP6_SPI_APPS_CLK_SRC 35
#define BLSP1_UART1_APPS_CLK_SRC 36
#define BLSP1_UART2_APPS_CLK_SRC 37
#define BLSP1_UART3_APPS_CLK_SRC 38
#define BLSP1_UART4_APPS_CLK_SRC 39
#define BLSP1_UART5_APPS_CLK_SRC 40
#define BLSP1_UART6_APPS_CLK_SRC 41
#define BLSP2_QUP1_I2C_APPS_CLK_SRC 42
#define BLSP2_QUP1_SPI_APPS_CLK_SRC 43
#define BLSP2_QUP2_I2C_APPS_CLK_SRC 44
#define BLSP2_QUP2_SPI_APPS_CLK_SRC 45
#define BLSP2_QUP3_I2C_APPS_CLK_SRC 46
#define BLSP2_QUP3_SPI_APPS_CLK_SRC 47
#define BLSP2_QUP4_I2C_APPS_CLK_SRC 48
#define BLSP2_QUP4_SPI_APPS_CLK_SRC 49
#define BLSP2_QUP5_I2C_APPS_CLK_SRC 50
#define BLSP2_QUP5_SPI_APPS_CLK_SRC 51
#define BLSP2_QUP6_I2C_APPS_CLK_SRC 52
#define BLSP2_QUP6_SPI_APPS_CLK_SRC 53
#define BLSP2_UART1_APPS_CLK_SRC 54
#define BLSP2_UART2_APPS_CLK_SRC 55
#define BLSP2_UART3_APPS_CLK_SRC 56
#define BLSP2_UART4_APPS_CLK_SRC 57
#define BLSP2_UART5_APPS_CLK_SRC 58
#define BLSP2_UART6_APPS_CLK_SRC 59
#define CE1_CLK_SRC 60
#define CE2_CLK_SRC 61
#define GP1_CLK_SRC 62
#define GP2_CLK_SRC 63
#define GP3_CLK_SRC 64
#define PDM2_CLK_SRC 65
#define QDSS_TRACECLKIN_CLK_SRC 66
#define RBCPR_CLK_SRC 67
#define SDCC1_APPS_CLK_SRC 68
#define SDCC2_APPS_CLK_SRC 69
#define SDCC3_APPS_CLK_SRC 70
#define SDCC4_APPS_CLK_SRC 71
#define SPMI_AHB_CLK_SRC 72
#define SPMI_SER_CLK_SRC 73
#define TSIF_REF_CLK_SRC 74
#define USB30_MOCK_UTMI_CLK_SRC 75
#define USB_HS_SYSTEM_CLK_SRC 76
#define USB_HSIC_CLK_SRC 77
#define USB_HSIC_IO_CAL_CLK_SRC 78
#define USB_HSIC_SYSTEM_CLK_SRC 79
#define GCC_BAM_DMA_AHB_CLK 80
#define GCC_BAM_DMA_INACTIVITY_TIMERS_CLK 81
#define GCC_BIMC_CFG_AHB_CLK 82
#define GCC_BIMC_KPSS_AXI_CLK 83
#define GCC_BIMC_SLEEP_CLK 84
#define GCC_BIMC_SYSNOC_AXI_CLK 85
#define GCC_BIMC_XO_CLK 86
#define GCC_BLSP1_AHB_CLK 87
#define GCC_BLSP1_SLEEP_CLK 88
#define GCC_BLSP1_QUP1_I2C_APPS_CLK 89
#define GCC_BLSP1_QUP1_SPI_APPS_CLK 90
#define GCC_BLSP1_QUP2_I2C_APPS_CLK 91
#define GCC_BLSP1_QUP2_SPI_APPS_CLK 92
#define GCC_BLSP1_QUP3_I2C_APPS_CLK 93
#define GCC_BLSP1_QUP3_SPI_APPS_CLK 94
#define GCC_BLSP1_QUP4_I2C_APPS_CLK 95
#define GCC_BLSP1_QUP4_SPI_APPS_CLK 96
#define GCC_BLSP1_QUP5_I2C_APPS_CLK 97
#define GCC_BLSP1_QUP5_SPI_APPS_CLK 98
#define GCC_BLSP1_QUP6_I2C_APPS_CLK 99
#define GCC_BLSP1_QUP6_SPI_APPS_CLK 100
#define GCC_BLSP1_UART1_APPS_CLK 101
#define GCC_BLSP1_UART1_SIM_CLK 102
#define GCC_BLSP1_UART2_APPS_CLK 103
#define GCC_BLSP1_UART2_SIM_CLK 104
#define GCC_BLSP1_UART3_APPS_CLK 105
#define GCC_BLSP1_UART3_SIM_CLK 106
#define GCC_BLSP1_UART4_APPS_CLK 107
#define GCC_BLSP1_UART4_SIM_CLK 108
#define GCC_BLSP1_UART5_APPS_CLK 109
#define GCC_BLSP1_UART5_SIM_CLK 110
#define GCC_BLSP1_UART6_APPS_CLK 111
#define GCC_BLSP1_UART6_SIM_CLK 112
#define GCC_BLSP2_AHB_CLK 113
#define GCC_BLSP2_SLEEP_CLK 114
#define GCC_BLSP2_QUP1_I2C_APPS_CLK 115
#define GCC_BLSP2_QUP1_SPI_APPS_CLK 116
#define GCC_BLSP2_QUP2_I2C_APPS_CLK 117
#define GCC_BLSP2_QUP2_SPI_APPS_CLK 118
#define GCC_BLSP2_QUP3_I2C_APPS_CLK 119
#define GCC_BLSP2_QUP3_SPI_APPS_CLK 120
#define GCC_BLSP2_QUP4_I2C_APPS_CLK 121
#define GCC_BLSP2_QUP4_SPI_APPS_CLK 122
#define GCC_BLSP2_QUP5_I2C_APPS_CLK 123
#define GCC_BLSP2_QUP5_SPI_APPS_CLK 124
#define GCC_BLSP2_QUP6_I2C_APPS_CLK 125
#define GCC_BLSP2_QUP6_SPI_APPS_CLK 126
#define GCC_BLSP2_UART1_APPS_CLK 127
#define GCC_BLSP2_UART1_SIM_CLK 128
#define GCC_BLSP2_UART2_APPS_CLK 129
#define GCC_BLSP2_UART2_SIM_CLK 130
#define GCC_BLSP2_UART3_APPS_CLK 131
#define GCC_BLSP2_UART3_SIM_CLK 132
#define GCC_BLSP2_UART4_APPS_CLK 133
#define GCC_BLSP2_UART4_SIM_CLK 134
#define GCC_BLSP2_UART5_APPS_CLK 135
#define GCC_BLSP2_UART5_SIM_CLK 136
#define GCC_BLSP2_UART6_APPS_CLK 137
#define GCC_BLSP2_UART6_SIM_CLK 138
#define GCC_BOOT_ROM_AHB_CLK 139
#define GCC_CE1_AHB_CLK 140
#define GCC_CE1_AXI_CLK 141
#define GCC_CE1_CLK 142
#define GCC_CE2_AHB_CLK 143
#define GCC_CE2_AXI_CLK 144
#define GCC_CE2_CLK 145
#define GCC_CNOC_BUS_TIMEOUT0_AHB_CLK 146
#define GCC_CNOC_BUS_TIMEOUT1_AHB_CLK 147
#define GCC_CNOC_BUS_TIMEOUT2_AHB_CLK 148
#define GCC_CNOC_BUS_TIMEOUT3_AHB_CLK 149
#define GCC_CNOC_BUS_TIMEOUT4_AHB_CLK 150
#define GCC_CNOC_BUS_TIMEOUT5_AHB_CLK 151
#define GCC_CNOC_BUS_TIMEOUT6_AHB_CLK 152
#define GCC_CFG_NOC_AHB_CLK 153
#define GCC_CFG_NOC_DDR_CFG_CLK 154
#define GCC_CFG_NOC_RPM_AHB_CLK 155
#define GCC_BIMC_DDR_CPLL0_CLK 156
#define GCC_BIMC_DDR_CPLL1_CLK 157
#define GCC_DDR_DIM_CFG_CLK 158
#define GCC_DDR_DIM_SLEEP_CLK 159
#define GCC_DEHR_CLK 160
#define GCC_AHB_CLK 161
#define GCC_IM_SLEEP_CLK 162
#define GCC_XO_CLK 163
#define GCC_XO_DIV4_CLK 164
#define GCC_GP1_CLK 165
#define GCC_GP2_CLK 166
#define GCC_GP3_CLK 167
#define GCC_IMEM_AXI_CLK 168
#define GCC_IMEM_CFG_AHB_CLK 169
#define GCC_KPSS_AHB_CLK 170
#define GCC_KPSS_AXI_CLK 171
#define GCC_LPASS_Q6_AXI_CLK 172
#define GCC_MMSS_NOC_AT_CLK 173
#define GCC_MMSS_NOC_CFG_AHB_CLK 174
#define GCC_OCMEM_NOC_CFG_AHB_CLK 175
#define GCC_OCMEM_SYS_NOC_AXI_CLK 176
#define GCC_MPM_AHB_CLK 177
#define GCC_MSG_RAM_AHB_CLK 178
#define GCC_MSS_CFG_AHB_CLK 179
#define GCC_MSS_Q6_BIMC_AXI_CLK 180
#define GCC_NOC_CONF_XPU_AHB_CLK 181
#define GCC_PDM2_CLK 182
#define GCC_PDM_AHB_CLK 183
#define GCC_PDM_XO4_CLK 184
#define GCC_PERIPH_NOC_AHB_CLK 185
#define GCC_PERIPH_NOC_AT_CLK 186
#define GCC_PERIPH_NOC_CFG_AHB_CLK 187
#define GCC_PERIPH_NOC_MPU_CFG_AHB_CLK 188
#define GCC_PERIPH_XPU_AHB_CLK 189
#define GCC_PNOC_BUS_TIMEOUT0_AHB_CLK 190
#define GCC_PNOC_BUS_TIMEOUT1_AHB_CLK 191
#define GCC_PNOC_BUS_TIMEOUT2_AHB_CLK 192
#define GCC_PNOC_BUS_TIMEOUT3_AHB_CLK 193
#define GCC_PNOC_BUS_TIMEOUT4_AHB_CLK 194
#define GCC_PRNG_AHB_CLK 195
#define GCC_QDSS_AT_CLK 196
#define GCC_QDSS_CFG_AHB_CLK 197
#define GCC_QDSS_DAP_AHB_CLK 198
#define GCC_QDSS_DAP_CLK 199
#define GCC_QDSS_ETR_USB_CLK 200
#define GCC_QDSS_STM_CLK 201
#define GCC_QDSS_TRACECLKIN_CLK 202
#define GCC_QDSS_TSCTR_DIV16_CLK 203
#define GCC_QDSS_TSCTR_DIV2_CLK 204
#define GCC_QDSS_TSCTR_DIV3_CLK 205
#define GCC_QDSS_TSCTR_DIV4_CLK 206
#define GCC_QDSS_TSCTR_DIV8_CLK 207
#define GCC_QDSS_RBCPR_XPU_AHB_CLK 208
#define GCC_RBCPR_AHB_CLK 209
#define GCC_RBCPR_CLK 210
#define GCC_RPM_BUS_AHB_CLK 211
#define GCC_RPM_PROC_HCLK 212
#define GCC_RPM_SLEEP_CLK 213
#define GCC_RPM_TIMER_CLK 214
#define GCC_SDCC1_AHB_CLK 215
#define GCC_SDCC1_APPS_CLK 216
#define GCC_SDCC1_INACTIVITY_TIMERS_CLK 217
#define GCC_SDCC2_AHB_CLK 218
#define GCC_SDCC2_APPS_CLK 219
#define GCC_SDCC2_INACTIVITY_TIMERS_CLK 220
#define GCC_SDCC3_AHB_CLK 221
#define GCC_SDCC3_APPS_CLK 222
#define GCC_SDCC3_INACTIVITY_TIMERS_CLK 223
#define GCC_SDCC4_AHB_CLK 224
#define GCC_SDCC4_APPS_CLK 225
#define GCC_SDCC4_INACTIVITY_TIMERS_CLK 226
#define GCC_SEC_CTRL_ACC_CLK 227
#define GCC_SEC_CTRL_AHB_CLK 228
#define GCC_SEC_CTRL_BOOT_ROM_PATCH_CLK 229
#define GCC_SEC_CTRL_CLK 230
#define GCC_SEC_CTRL_SENSE_CLK 231
#define GCC_SNOC_BUS_TIMEOUT0_AHB_CLK 232
#define GCC_SNOC_BUS_TIMEOUT2_AHB_CLK 233
#define GCC_SPDM_BIMC_CY_CLK 234
#define GCC_SPDM_CFG_AHB_CLK 235
#define GCC_SPDM_DEBUG_CY_CLK 236
#define GCC_SPDM_FF_CLK 237
#define GCC_SPDM_MSTR_AHB_CLK 238
#define GCC_SPDM_PNOC_CY_CLK 239
#define GCC_SPDM_RPM_CY_CLK 240
#define GCC_SPDM_SNOC_CY_CLK 241
#define GCC_SPMI_AHB_CLK 242
#define GCC_SPMI_CNOC_AHB_CLK 243
#define GCC_SPMI_SER_CLK 244
#define GCC_SNOC_CNOC_AHB_CLK 245
#define GCC_SNOC_PNOC_AHB_CLK 246
#define GCC_SYS_NOC_AT_CLK 247
#define GCC_SYS_NOC_AXI_CLK 248
#define GCC_SYS_NOC_KPSS_AHB_CLK 249
#define GCC_SYS_NOC_QDSS_STM_AXI_CLK 250
#define GCC_SYS_NOC_USB3_AXI_CLK 251
#define GCC_TCSR_AHB_CLK 252
#define GCC_TLMM_AHB_CLK 253
#define GCC_TLMM_CLK 254
#define GCC_TSIF_AHB_CLK 255
#define GCC_TSIF_INACTIVITY_TIMERS_CLK 256
#define GCC_TSIF_REF_CLK 257
#define GCC_USB2A_PHY_SLEEP_CLK 258
#define GCC_USB2B_PHY_SLEEP_CLK 259
#define GCC_USB30_MASTER_CLK 260
#define GCC_USB30_MOCK_UTMI_CLK 261
#define GCC_USB30_SLEEP_CLK 262
#define GCC_USB_HS_AHB_CLK 263
#define GCC_USB_HS_INACTIVITY_TIMERS_CLK 264
#define GCC_USB_HS_SYSTEM_CLK 265
#define GCC_USB_HSIC_AHB_CLK 266
#define GCC_USB_HSIC_CLK 267
#define GCC_USB_HSIC_IO_CAL_CLK 268
#define GCC_USB_HSIC_IO_CAL_SLEEP_CLK 269
#define GCC_USB_HSIC_SYSTEM_CLK 270
#define GCC_WCSS_GPLL1_CLK_SRC 271
#define GCC_MMSS_GPLL0_CLK_SRC 272
#define GCC_LPASS_GPLL0_CLK_SRC 273
#define GCC_WCSS_GPLL1_CLK_SRC_SLEEP_ENA 274
#define GCC_MMSS_GPLL0_CLK_SRC_SLEEP_ENA 275
#define GCC_LPASS_GPLL0_CLK_SRC_SLEEP_ENA 276
#define GCC_IMEM_AXI_CLK_SLEEP_ENA 277
#define GCC_SYS_NOC_KPSS_AHB_CLK_SLEEP_ENA 278
#define GCC_BIMC_KPSS_AXI_CLK_SLEEP_ENA 279
#define GCC_KPSS_AHB_CLK_SLEEP_ENA 280
#define GCC_KPSS_AXI_CLK_SLEEP_ENA 281
#define GCC_MPM_AHB_CLK_SLEEP_ENA 282
#define GCC_OCMEM_SYS_NOC_AXI_CLK_SLEEP_ENA 283
#define GCC_BLSP1_AHB_CLK_SLEEP_ENA 284
#define GCC_BLSP1_SLEEP_CLK_SLEEP_ENA 285
#define GCC_BLSP2_AHB_CLK_SLEEP_ENA 286
#define GCC_BLSP2_SLEEP_CLK_SLEEP_ENA 287
#define GCC_PRNG_AHB_CLK_SLEEP_ENA 288
#define GCC_BAM_DMA_AHB_CLK_SLEEP_ENA 289
#define GCC_BAM_DMA_INACTIVITY_TIMERS_CLK_SLEEP_ENA 290
#define GCC_BOOT_ROM_AHB_CLK_SLEEP_ENA 291
#define GCC_MSG_RAM_AHB_CLK_SLEEP_ENA 292
#define GCC_TLMM_AHB_CLK_SLEEP_ENA 293
#define GCC_TLMM_CLK_SLEEP_ENA 294
#define GCC_SPMI_CNOC_AHB_CLK_SLEEP_ENA 295
#define GCC_CE1_CLK_SLEEP_ENA 296
#define GCC_CE1_AXI_CLK_SLEEP_ENA 297
#define GCC_CE1_AHB_CLK_SLEEP_ENA 298
#define GCC_CE2_CLK_SLEEP_ENA 299
#define GCC_CE2_AXI_CLK_SLEEP_ENA 300
#define GCC_CE2_AHB_CLK_SLEEP_ENA 301
#endif

Просмотреть файл

@ -0,0 +1,137 @@
/*
* Copyright (c) 2013, 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 _DT_BINDINGS_CLK_MSM_MMCC_8960_H
#define _DT_BINDINGS_CLK_MSM_MMCC_8960_H
#define MMSS_AHB_SRC 0
#define FAB_AHB_CLK 1
#define APU_AHB_CLK 2
#define TV_ENC_AHB_CLK 3
#define AMP_AHB_CLK 4
#define DSI2_S_AHB_CLK 5
#define JPEGD_AHB_CLK 6
#define GFX2D0_AHB_CLK 7
#define DSI_S_AHB_CLK 8
#define DSI2_M_AHB_CLK 9
#define VPE_AHB_CLK 10
#define SMMU_AHB_CLK 11
#define HDMI_M_AHB_CLK 12
#define VFE_AHB_CLK 13
#define ROT_AHB_CLK 14
#define VCODEC_AHB_CLK 15
#define MDP_AHB_CLK 16
#define DSI_M_AHB_CLK 17
#define CSI_AHB_CLK 18
#define MMSS_IMEM_AHB_CLK 19
#define IJPEG_AHB_CLK 20
#define HDMI_S_AHB_CLK 21
#define GFX3D_AHB_CLK 22
#define GFX2D1_AHB_CLK 23
#define MMSS_FPB_CLK 24
#define MMSS_AXI_SRC 25
#define MMSS_FAB_CORE 26
#define FAB_MSP_AXI_CLK 27
#define JPEGD_AXI_CLK 28
#define GMEM_AXI_CLK 29
#define MDP_AXI_CLK 30
#define MMSS_IMEM_AXI_CLK 31
#define IJPEG_AXI_CLK 32
#define GFX3D_AXI_CLK 33
#define VCODEC_AXI_CLK 34
#define VFE_AXI_CLK 35
#define VPE_AXI_CLK 36
#define ROT_AXI_CLK 37
#define VCODEC_AXI_A_CLK 38
#define VCODEC_AXI_B_CLK 39
#define MM_AXI_S3_FCLK 40
#define MM_AXI_S2_FCLK 41
#define MM_AXI_S1_FCLK 42
#define MM_AXI_S0_FCLK 43
#define MM_AXI_S2_CLK 44
#define MM_AXI_S1_CLK 45
#define MM_AXI_S0_CLK 46
#define CSI0_SRC 47
#define CSI0_CLK 48
#define CSI0_PHY_CLK 49
#define CSI1_SRC 50
#define CSI1_CLK 51
#define CSI1_PHY_CLK 52
#define CSI2_SRC 53
#define CSI2_CLK 54
#define CSI2_PHY_CLK 55
#define DSI_SRC 56
#define DSI_CLK 57
#define CSI_PIX_CLK 58
#define CSI_RDI_CLK 59
#define MDP_VSYNC_CLK 60
#define HDMI_DIV_CLK 61
#define HDMI_APP_CLK 62
#define CSI_PIX1_CLK 63
#define CSI_RDI2_CLK 64
#define CSI_RDI1_CLK 65
#define GFX2D0_SRC 66
#define GFX2D0_CLK 67
#define GFX2D1_SRC 68
#define GFX2D1_CLK 69
#define GFX3D_SRC 70
#define GFX3D_CLK 71
#define IJPEG_SRC 72
#define IJPEG_CLK 73
#define JPEGD_SRC 74
#define JPEGD_CLK 75
#define MDP_SRC 76
#define MDP_CLK 77
#define MDP_LUT_CLK 78
#define DSI2_PIXEL_SRC 79
#define DSI2_PIXEL_CLK 80
#define DSI2_SRC 81
#define DSI2_CLK 82
#define DSI1_BYTE_SRC 83
#define DSI1_BYTE_CLK 84
#define DSI2_BYTE_SRC 85
#define DSI2_BYTE_CLK 86
#define DSI1_ESC_SRC 87
#define DSI1_ESC_CLK 88
#define DSI2_ESC_SRC 89
#define DSI2_ESC_CLK 90
#define ROT_SRC 91
#define ROT_CLK 92
#define TV_ENC_CLK 93
#define TV_DAC_CLK 94
#define HDMI_TV_CLK 95
#define MDP_TV_CLK 96
#define TV_SRC 97
#define VCODEC_SRC 98
#define VCODEC_CLK 99
#define VFE_SRC 100
#define VFE_CLK 101
#define VFE_CSI_CLK 102
#define VPE_SRC 103
#define VPE_CLK 104
#define DSI_PIXEL_SRC 105
#define DSI_PIXEL_CLK 106
#define CAMCLK0_SRC 107
#define CAMCLK0_CLK 108
#define CAMCLK1_SRC 109
#define CAMCLK1_CLK 110
#define CAMCLK2_SRC 111
#define CAMCLK2_CLK 112
#define CSIPHYTIMER_SRC 113
#define CSIPHY2_TIMER_CLK 114
#define CSIPHY1_TIMER_CLK 115
#define CSIPHY0_TIMER_CLK 116
#define PLL1 117
#define PLL2 118
#endif

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше