forked from Minki/linux
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:
commit
7e21774db5
@ -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.
|
||||
|
||||
|
98
Documentation/devicetree/bindings/clock/emev2-clock.txt
Normal file
98
Documentation/devicetree/bindings/clock/emev2-clock.txt
Normal file
@ -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>;
|
||||
};
|
||||
|
19
Documentation/devicetree/bindings/clock/hi3620-clock.txt
Normal file
19
Documentation/devicetree/bindings/clock/hi3620-clock.txt
Normal file
@ -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:
|
||||
|
38
Documentation/devicetree/bindings/clock/maxim,max77686.txt
Normal file
38
Documentation/devicetree/bindings/clock/maxim,max77686.txt
Normal file
@ -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>;
|
||||
};
|
21
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Normal file
21
Documentation/devicetree/bindings/clock/qcom,gcc.txt
Normal file
@ -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>;
|
||||
};
|
21
Documentation/devicetree/bindings/clock/qcom,mmcc.txt
Normal file
21
Documentation/devicetree/bindings/clock/qcom,mmcc.txt
Normal file
@ -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>;
|
||||
};
|
39
Documentation/devicetree/bindings/clock/silabs,si570.txt
Normal file
39
Documentation/devicetree/bindings/clock/silabs,si570.txt
Normal file
@ -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.
|
||||
|
14
MAINTAINERS
14
MAINTAINERS
@ -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
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
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;
|
||||
}
|
||||
|
||||
|
5
drivers/clk/hisilicon/Makefile
Normal file
5
drivers/clk/hisilicon/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Hisilicon Clock specific Makefile
|
||||
#
|
||||
|
||||
obj-y += clk.o clkgate-separated.o clk-hi3620.o
|
242
drivers/clk/hisilicon/clk-hi3620.c
Normal file
242
drivers/clk/hisilicon/clk-hi3620.c
Normal file
@ -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
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
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 */
|
130
drivers/clk/hisilicon/clkgate-separated.c
Normal file
130
drivers/clk/hisilicon/clkgate-separated.c
Normal file
@ -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
|
||||
|
223
drivers/clk/mvebu/clk-corediv.c
Normal file
223
drivers/clk/mvebu/clk-corediv.c
Normal file
@ -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
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
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
|
159
drivers/clk/qcom/clk-branch.c
Normal file
159
drivers/clk/qcom/clk-branch.c
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.
|
||||
*/
|
||||
|
||||
#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);
|
56
drivers/clk/qcom/clk-branch.h
Normal file
56
drivers/clk/qcom/clk-branch.h
Normal file
@ -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
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);
|
66
drivers/clk/qcom/clk-pll.h
Normal file
66
drivers/clk/qcom/clk-pll.h
Normal file
@ -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
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, ®);
|
||||
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
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
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);
|
114
drivers/clk/qcom/clk-regmap.c
Normal file
114
drivers/clk/qcom/clk-regmap.c
Normal file
@ -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);
|
45
drivers/clk/qcom/clk-regmap.h
Normal file
45
drivers/clk/qcom/clk-regmap.h
Normal file
@ -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
|
2819
drivers/clk/qcom/gcc-msm8660.c
Normal file
2819
drivers/clk/qcom/gcc-msm8660.c
Normal file
File diff suppressed because it is too large
Load Diff
2993
drivers/clk/qcom/gcc-msm8960.c
Normal file
2993
drivers/clk/qcom/gcc-msm8960.c
Normal file
File diff suppressed because it is too large
Load Diff
2694
drivers/clk/qcom/gcc-msm8974.c
Normal file
2694
drivers/clk/qcom/gcc-msm8974.c
Normal file
File diff suppressed because it is too large
Load Diff
2321
drivers/clk/qcom/mmcc-msm8960.c
Normal file
2321
drivers/clk/qcom/mmcc-msm8960.c
Normal file
File diff suppressed because it is too large
Load Diff
2625
drivers/clk/qcom/mmcc-msm8974.c
Normal file
2625
drivers/clk/qcom/mmcc-msm8974.c
Normal file
File diff suppressed because it is too large
Load Diff
63
drivers/clk/qcom/reset.c
Normal file
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
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");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
104
drivers/clk/shmobile/clk-emev2.c
Normal file
104
drivers/clk/shmobile/clk-emev2.c
Normal file
@ -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
|
||||
|
5
drivers/clk/sirf/Makefile
Normal file
5
drivers/clk/sirf/Makefile
Normal file
@ -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
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)
|
152
drivers/clk/sirf/clk-atlas6.c
Normal file
152
drivers/clk/sirf/clk-atlas6.c
Normal file
@ -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);
|
151
drivers/clk/sirf/clk-prima2.c
Normal file
151
drivers/clk/sirf/clk-prima2.c
Normal file
@ -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
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", ®);
|
||||
if (WARN_ON(rc))
|
||||
return NULL;
|
||||
of_property_read_u32(node, "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 = ÷r->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
|
||||
|
244
include/dt-bindings/clock/exynos4.h
Normal file
244
include/dt-bindings/clock/exynos4.h
Normal file
@ -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 */
|
160
include/dt-bindings/clock/exynos5250.h
Normal file
160
include/dt-bindings/clock/exynos5250.h
Normal file
@ -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 */
|
188
include/dt-bindings/clock/exynos5420.h
Normal file
188
include/dt-bindings/clock/exynos5420.h
Normal file
@ -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 */
|
42
include/dt-bindings/clock/exynos5440.h
Normal file
42
include/dt-bindings/clock/exynos5440.h
Normal file
@ -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 */
|
152
include/dt-bindings/clock/hi3620-clock.h
Normal file
152
include/dt-bindings/clock/hi3620-clock.h
Normal file
@ -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 */
|
276
include/dt-bindings/clock/qcom,gcc-msm8660.h
Normal file
276
include/dt-bindings/clock/qcom,gcc-msm8660.h
Normal file
@ -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
|
313
include/dt-bindings/clock/qcom,gcc-msm8960.h
Normal file
313
include/dt-bindings/clock/qcom,gcc-msm8960.h
Normal file
@ -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
|
320
include/dt-bindings/clock/qcom,gcc-msm8974.h
Normal file
320
include/dt-bindings/clock/qcom,gcc-msm8974.h
Normal file
@ -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
|
137
include/dt-bindings/clock/qcom,mmcc-msm8960.h
Normal file
137
include/dt-bindings/clock/qcom,mmcc-msm8960.h
Normal file
@ -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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user