The common clk framework changes for 3.12 are dominated by clock driver
patches, both new drivers and fixes to existing. A high percentage of these are for Samsung platforms like Exynos. Core framework fixes and some new features like automagical clock re-parenting round out the patches. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJSLkImAAoJEDqPOy9afJhJOjsP/Ri26AW7XB9pPWJRSU9REBZA 31wxcFo2T+PNir9duwDwjFBFycC3MisaKFlg7D134M+7txbYqm1TRvfu9OEDxpSP 4b/Yl6TarN4dhCN2R+BREO8PnxCBVpspDcsdh6Esuwuet2xUom3UtN8yvSjhPP/u qGNmXQYXyQy4fom5r+GsDVW+HIhLkaX9b0fYc9EN/bqfgv94PMZAxAxsK9CroAGZ 0m0g9ZXw9iSvVfz+iQEqPINtvpTLHk0FGyimoSR7kvW4o4o47tVtLEWp7VjG6mr5 zvBsycaQq6NgxPu96iUWWhsO9Uj2I7/7JgidXF7r+wvEFs1mcgZtkkirSA/n4zUN C8a87rvQrZRLr+xXhVuqiVHCgCY8vXoHqkWg6SrZ62ORL8C7uYRpog5SEe2ZzLJX l5uGAsDM6el+Uc/YviCPoZbeFr3h3CQvvFo8+i2eN0v/Phf30rq4lotBvpQj894G ngEIMj+D8wshdYSF2dNJ0rLnkLHTgCbiA28L6Cl5TRzRMj3Uaj9aT3cmoLUnimZu 7F7nWU4Iu/vzQKCTQ+eTvwxXJqIlE0JeVbJilqH1f2a68JdXP1LOId+2w/CP8gqQ i2odj6JHMgBzM9rNs+y0Ir9X/bXIVi6F341c19Nl15srEiLLl8xQIpcPDaI/Kvzs pefYgF2yS5AZAW3ac90r =5GfA -----END PGP SIGNATURE----- Merge tag 'clk-for-linus-3.12' of git://git.linaro.org/people/mturquette/linux Pull clock framework changes from Michael Turquette: "The common clk framework changes for 3.12 are dominated by clock driver patches, both new drivers and fixes to existing. A high percentage of these are for Samsung platforms like Exynos. Core framework fixes and some new features like automagical clock re-parenting round out the patches" * tag 'clk-for-linus-3.12' of git://git.linaro.org/people/mturquette/linux: (102 commits) clk: only call get_parent if there is one clk: samsung: exynos5250: Simplify registration of PLL rate tables clk: samsung: exynos4: Register PLL rate tables for Exynos4x12 clk: samsung: exynos4: Register PLL rate tables for Exynos4210 clk: samsung: exynos4: Reorder registration of mout_vpllsrc clk: samsung: pll: Add support for rate configuration of PLL46xx clk: samsung: pll: Use new registration method for PLL46xx clk: samsung: pll: Add support for rate configuration of PLL45xx clk: samsung: pll: Use new registration method for PLL45xx clk: samsung: exynos4: Rename exynos4_plls to exynos4x12_plls clk: samsung: exynos4: Remove checks for DT node clk: samsung: exynos4: Remove unused static clkdev aliases clk: samsung: Modify _get_rate() helper to use __clk_lookup() clk: samsung: exynos4: Use separate aliases for cpufreq related clocks clocksource: samsung_pwm_timer: Get clock from device tree ARM: dts: exynos4: Specify PWM clocks in PWM node pwm: samsung: Update DT bindings documentation to cover clocks clk: Move symbol export to proper location clk: fix new_parent dereference before null check clk: wm831x: Initialise wm831x pointer on init ...
This commit is contained in:
commit
bef4a0ab98
|
@ -70,6 +70,10 @@ the operations defined in clk.h:
|
|||
unsigned long parent_rate);
|
||||
long (*round_rate)(struct clk_hw *hw, unsigned long,
|
||||
unsigned long *);
|
||||
long (*determine_rate)(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long *best_parent_rate,
|
||||
struct clk **best_parent_clk);
|
||||
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);
|
||||
|
@ -191,7 +195,8 @@ optional or must be evaluated on a case-by-case basis.
|
|||
.is_enabled | y | | | | |
|
||||
| | | | | |
|
||||
.recalc_rate | | y | | | |
|
||||
.round_rate | | y | | | |
|
||||
.round_rate | | y [1] | | | |
|
||||
.determine_rate | | y [1] | | | |
|
||||
.set_rate | | y | | | |
|
||||
| | | | | |
|
||||
.set_parent | | | n | y | n |
|
||||
|
@ -199,6 +204,7 @@ optional or must be evaluated on a case-by-case basis.
|
|||
| | | | | |
|
||||
.init | | | | | |
|
||||
-----------------------------------------------------------
|
||||
[1] either one of round_rate or determine_rate is required.
|
||||
|
||||
Finally, register your clock at run-time with a hardware-specific
|
||||
registration function. This function simply populates struct clk_foo's
|
||||
|
|
|
@ -236,6 +236,7 @@ Exynos4 SoC and this is specified where applicable.
|
|||
spi0_isp_sclk 380 Exynos4x12
|
||||
spi1_isp_sclk 381 Exynos4x12
|
||||
uart_isp_sclk 382 Exynos4x12
|
||||
tmu_apbif 383
|
||||
|
||||
[Mux Clocks]
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ clock which they consume.
|
|||
sclk_spi0 154
|
||||
sclk_spi1 155
|
||||
sclk_spi2 156
|
||||
div_i2s1 157
|
||||
div_i2s2 158
|
||||
sclk_hdmiphy 159
|
||||
|
||||
|
||||
[Peripheral Clock Gates]
|
||||
|
@ -154,7 +157,16 @@ clock which they consume.
|
|||
dsim0 341
|
||||
dp 342
|
||||
mixer 343
|
||||
hdmi 345
|
||||
hdmi 344
|
||||
g2d 345
|
||||
|
||||
|
||||
[Clock Muxes]
|
||||
|
||||
Clock ID
|
||||
----------------------------
|
||||
mout_hdmi 1024
|
||||
|
||||
|
||||
Example 1: An example of a clock controller node is listed below.
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ clock which they consume.
|
|||
sclk_pwm 155
|
||||
sclk_gscl_wa 156
|
||||
sclk_gscl_wb 157
|
||||
sclk_hdmiphy 158
|
||||
|
||||
[Peripheral Clock Gates]
|
||||
|
||||
|
@ -179,6 +180,17 @@ clock which they consume.
|
|||
fimc_lite3 495
|
||||
aclk_g3d 500
|
||||
g3d 501
|
||||
smmu_mixer 502
|
||||
|
||||
Mux ID
|
||||
----------------------------
|
||||
|
||||
mout_hdmi 640
|
||||
|
||||
Divider ID
|
||||
----------------------------
|
||||
|
||||
dout_pixel 768
|
||||
|
||||
Example 1: An example of a clock controller node is listed below.
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
* Samsung S3C64xx Clock Controller
|
||||
|
||||
The S3C64xx clock controller generates and supplies clock to various controllers
|
||||
within the SoC. The clock binding described here is applicable to all SoCs in
|
||||
the S3C64xx family.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be one of the following.
|
||||
- "samsung,s3c6400-clock" - controller compatible with S3C6400 SoC.
|
||||
- "samsung,s3c6410-clock" - controller compatible with S3C6410 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 can use this identifier
|
||||
to specify the clock which they consume. Some of the clocks are available only
|
||||
on a particular S3C64xx SoC and this is specified where applicable.
|
||||
|
||||
All available clocks are defined as preprocessor macros in
|
||||
dt-bindings/clock/samsung,s3c64xx-clock.h header and can be used in device
|
||||
tree sources.
|
||||
|
||||
External clocks:
|
||||
|
||||
There are several clocks that are generated outside the SoC. It is expected
|
||||
that they are defined using standard clock bindings with following
|
||||
clock-output-names:
|
||||
- "fin_pll" - PLL input clock (xtal/extclk) - required,
|
||||
- "xusbxti" - USB xtal - required,
|
||||
- "iiscdclk0" - I2S0 codec clock - optional,
|
||||
- "iiscdclk1" - I2S1 codec clock - optional,
|
||||
- "iiscdclk2" - I2S2 codec clock - optional,
|
||||
- "pcmcdclk0" - PCM0 codec clock - optional,
|
||||
- "pcmcdclk1" - PCM1 codec clock - optional, only S3C6410.
|
||||
|
||||
Example: Clock controller node:
|
||||
|
||||
clock: clock-controller@7e00f000 {
|
||||
compatible = "samsung,s3c6410-clock";
|
||||
reg = <0x7e00f000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
Example: Required external clocks:
|
||||
|
||||
fin_pll: clock-fin-pll {
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "fin_pll";
|
||||
clock-frequency = <12000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
xusbxti: clock-xusbxti {
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "xusbxti";
|
||||
clock-frequency = <48000000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
Example: UART controller node that consumes the clock generated by the clock
|
||||
controller (refer to the standard clock bindings for information about
|
||||
"clocks" and "clock-names" properties):
|
||||
|
||||
uart0: serial@7f005000 {
|
||||
compatible = "samsung,s3c6400-uart";
|
||||
reg = <0x7f005000 0x100>;
|
||||
interrupt-parent = <&vic1>;
|
||||
interrupts = <5>;
|
||||
clock-names = "uart", "clk_uart_baud2",
|
||||
"clk_uart_baud3";
|
||||
clocks = <&clock PCLK_UART0>, <&clocks PCLK_UART0>,
|
||||
<&clock SCLK_UART>;
|
||||
status = "disabled";
|
||||
};
|
|
@ -8,19 +8,31 @@ 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,sun6i-a31-pll1-clk" - for the main PLL clock on A31
|
||||
"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
|
||||
"allwinner,sun4i-ahb-clk" - for the AHB clock
|
||||
"allwinner,sun4i-ahb-gates-clk" - for the AHB gates on A10
|
||||
"allwinner,sun5i-a13-ahb-gates-clk" - for the AHB gates on A13
|
||||
"allwinner,sun5i-a10s-ahb-gates-clk" - for the AHB gates on A10s
|
||||
"allwinner,sun7i-a20-ahb-gates-clk" - for the AHB gates on A20
|
||||
"allwinner,sun6i-a31-ahb1-mux-clk" - for the AHB1 multiplexer on A31
|
||||
"allwinner,sun6i-a31-ahb1-gates-clk" - for the AHB1 gates on A31
|
||||
"allwinner,sun4i-apb0-clk" - for the APB0 clock
|
||||
"allwinner,sun4i-apb0-gates-clk" - for the APB0 gates on A10
|
||||
"allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13
|
||||
"allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s
|
||||
"allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20
|
||||
"allwinner,sun4i-apb1-clk" - for the APB1 clock
|
||||
"allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
|
||||
"allwinner,sun4i-apb1-gates-clk" - for the APB1 gates on A10
|
||||
"allwinner,sun5i-a13-apb1-gates-clk" - for the APB1 gates on A13
|
||||
"allwinner,sun5i-a10s-apb1-gates-clk" - for the APB1 gates on A10s
|
||||
"allwinner,sun6i-a31-apb1-gates-clk" - for the APB1 gates on A31
|
||||
"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
|
||||
|
||||
Required properties for all clocks:
|
||||
- reg : shall be the control register address for the clock.
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
Gate clock outputs
|
||||
------------------
|
||||
|
||||
* AXI gates ("allwinner,sun4i-axi-gates-clk")
|
||||
|
||||
DRAM 0
|
||||
|
||||
* AHB gates ("allwinner,sun5i-a10s-ahb-gates-clk")
|
||||
|
||||
USB0 0
|
||||
EHCI0 1
|
||||
OHCI0 2
|
||||
|
||||
SS 5
|
||||
DMA 6
|
||||
BIST 7
|
||||
MMC0 8
|
||||
MMC1 9
|
||||
MMC2 10
|
||||
|
||||
NAND 13
|
||||
SDRAM 14
|
||||
|
||||
EMAC 17
|
||||
TS 18
|
||||
|
||||
SPI0 20
|
||||
SPI1 21
|
||||
SPI2 22
|
||||
|
||||
GPS 26
|
||||
|
||||
HSTIMER 28
|
||||
|
||||
VE 32
|
||||
|
||||
TVE 34
|
||||
|
||||
LCD 36
|
||||
|
||||
CSI 40
|
||||
|
||||
HDMI 43
|
||||
DE_BE 44
|
||||
|
||||
DE_FE 46
|
||||
|
||||
IEP 51
|
||||
MALI400 52
|
||||
|
||||
* APB0 gates ("allwinner,sun5i-a10s-apb0-gates-clk")
|
||||
|
||||
CODEC 0
|
||||
|
||||
IIS 3
|
||||
|
||||
PIO 5
|
||||
IR 6
|
||||
|
||||
KEYPAD 10
|
||||
|
||||
* APB1 gates ("allwinner,sun5i-a10s-apb1-gates-clk")
|
||||
|
||||
I2C0 0
|
||||
I2C1 1
|
||||
I2C2 2
|
||||
|
||||
UART0 16
|
||||
UART1 17
|
||||
UART2 18
|
||||
UART3 19
|
||||
|
||||
Notation:
|
||||
[*]: The datasheet didn't mention these, but they are present on AW code
|
||||
[**]: The datasheet had this marked as "NC" but they are used on AW code
|
|
@ -0,0 +1,83 @@
|
|||
Gate clock outputs
|
||||
------------------
|
||||
|
||||
* AHB1 gates ("allwinner,sun6i-a31-ahb1-gates-clk")
|
||||
|
||||
MIPI DSI 1
|
||||
|
||||
SS 5
|
||||
DMA 6
|
||||
|
||||
MMC0 8
|
||||
MMC1 9
|
||||
MMC2 10
|
||||
MMC3 11
|
||||
|
||||
NAND1 12
|
||||
NAND0 13
|
||||
SDRAM 14
|
||||
|
||||
GMAC 17
|
||||
TS 18
|
||||
HSTIMER 19
|
||||
SPI0 20
|
||||
SPI1 21
|
||||
SPI2 22
|
||||
SPI3 23
|
||||
USB_OTG 24
|
||||
|
||||
EHCI0 26
|
||||
EHCI1 27
|
||||
|
||||
OHCI0 29
|
||||
OHCI1 30
|
||||
OHCI2 31
|
||||
VE 32
|
||||
|
||||
LCD0 36
|
||||
LCD1 37
|
||||
|
||||
CSI 40
|
||||
|
||||
HDMI 43
|
||||
DE_BE0 44
|
||||
DE_BE1 45
|
||||
DE_FE1 46
|
||||
DE_FE1 47
|
||||
|
||||
MP 50
|
||||
|
||||
GPU 52
|
||||
|
||||
DEU0 55
|
||||
DEU1 56
|
||||
DRC0 57
|
||||
DRC1 58
|
||||
|
||||
* APB1 gates ("allwinner,sun6i-a31-apb1-gates-clk")
|
||||
|
||||
CODEC 0
|
||||
|
||||
DIGITAL MIC 4
|
||||
PIO 5
|
||||
|
||||
DAUDIO0 12
|
||||
DAUDIO1 13
|
||||
|
||||
* APB2 gates ("allwinner,sun6i-a31-apb2-gates-clk")
|
||||
|
||||
I2C0 0
|
||||
I2C1 1
|
||||
I2C2 2
|
||||
I2C3 3
|
||||
|
||||
UART0 16
|
||||
UART1 17
|
||||
UART2 18
|
||||
UART3 19
|
||||
UART4 20
|
||||
UART5 21
|
||||
|
||||
Notation:
|
||||
[*]: The datasheet didn't mention these, but they are present on AW code
|
||||
[**]: The datasheet had this marked as "NC" but they are used on AW code
|
|
@ -0,0 +1,98 @@
|
|||
Gate clock outputs
|
||||
------------------
|
||||
|
||||
* AXI gates ("allwinner,sun4i-axi-gates-clk")
|
||||
|
||||
DRAM 0
|
||||
|
||||
* AHB gates ("allwinner,sun7i-a20-ahb-gates-clk")
|
||||
|
||||
USB0 0
|
||||
EHCI0 1
|
||||
OHCI0 2
|
||||
EHCI1 3
|
||||
OHCI1 4
|
||||
SS 5
|
||||
DMA 6
|
||||
BIST 7
|
||||
MMC0 8
|
||||
MMC1 9
|
||||
MMC2 10
|
||||
MMC3 11
|
||||
MS 12
|
||||
NAND 13
|
||||
SDRAM 14
|
||||
|
||||
ACE 16
|
||||
EMAC 17
|
||||
TS 18
|
||||
|
||||
SPI0 20
|
||||
SPI1 21
|
||||
SPI2 22
|
||||
SPI3 23
|
||||
|
||||
SATA 25
|
||||
|
||||
HSTIMER 28
|
||||
|
||||
VE 32
|
||||
TVD 33
|
||||
TVE0 34
|
||||
TVE1 35
|
||||
LCD0 36
|
||||
LCD1 37
|
||||
|
||||
CSI0 40
|
||||
CSI1 41
|
||||
|
||||
HDMI1 42
|
||||
HDMI0 43
|
||||
DE_BE0 44
|
||||
DE_BE1 45
|
||||
DE_FE1 46
|
||||
DE_FE1 47
|
||||
|
||||
GMAC 49
|
||||
MP 50
|
||||
|
||||
MALI400 52
|
||||
|
||||
* APB0 gates ("allwinner,sun7i-a20-apb0-gates-clk")
|
||||
|
||||
CODEC 0
|
||||
SPDIF 1
|
||||
AC97 2
|
||||
IIS0 3
|
||||
IIS1 4
|
||||
PIO 5
|
||||
IR0 6
|
||||
IR1 7
|
||||
IIS2 8
|
||||
|
||||
KEYPAD 10
|
||||
|
||||
* APB1 gates ("allwinner,sun7i-a20-apb1-gates-clk")
|
||||
|
||||
I2C0 0
|
||||
I2C1 1
|
||||
I2C2 2
|
||||
I2C3 3
|
||||
CAN 4
|
||||
SCR 5
|
||||
PS20 6
|
||||
PS21 7
|
||||
|
||||
I2C4 15
|
||||
UART0 16
|
||||
UART1 17
|
||||
UART2 18
|
||||
UART3 19
|
||||
UART4 20
|
||||
UART5 21
|
||||
UART6 22
|
||||
UART7 23
|
||||
|
||||
Notation:
|
||||
[*]: The datasheet didn't mention these, but they are present on AW code
|
||||
[**]: The datasheet had this marked as "NC" but they are used on AW code
|
|
@ -11,8 +11,11 @@ Required properties:
|
|||
|
||||
- interrupts : G2D interrupt number to the CPU.
|
||||
- clocks : from common clock binding: handle to G2D clocks.
|
||||
- clock-names : from common clock binding: must contain "sclk_fimg2d" and
|
||||
"fimg2d", corresponding to entries in the clocks property.
|
||||
- clock-names : names of clocks listed in clocks property, in the same
|
||||
order, depending on SoC type:
|
||||
- for S5PV210 and Exynos4 based SoCs: "fimg2d" and
|
||||
"sclk_fimg2d"
|
||||
- for Exynos5250 SoC: "fimg2d".
|
||||
|
||||
Example:
|
||||
g2d@12800000 {
|
||||
|
|
|
@ -19,6 +19,16 @@ Required properties:
|
|||
- reg: base address and size of register area
|
||||
- interrupts: list of timer interrupts (one interrupt per timer, starting at
|
||||
timer 0)
|
||||
- clock-names: should contain all following required clock names:
|
||||
- "timers" - PWM base clock used to generate PWM signals,
|
||||
and any subset of following optional clock names:
|
||||
- "pwm-tclk0" - first external PWM clock source,
|
||||
- "pwm-tclk1" - second external PWM clock source.
|
||||
Note that not all IP variants allow using all external clock sources.
|
||||
Refer to SoC documentation to learn which clock source configurations
|
||||
are available.
|
||||
- clocks: should contain clock specifiers of all clocks, which input names
|
||||
have been specified in clock-names property, in same order.
|
||||
- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
|
||||
the cells format. The only third cell flag supported by this binding is
|
||||
PWM_POLARITY_INVERTED.
|
||||
|
@ -34,6 +44,8 @@ Example:
|
|||
reg = <0x7f006000 0x1000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <23>, <24>, <25>, <27>, <28>;
|
||||
clocks = <&clock 67>;
|
||||
clock-names = "timers";
|
||||
samsung,pwm-outputs = <0>, <1>;
|
||||
#pwm-cells = <3>;
|
||||
}
|
||||
|
|
|
@ -448,6 +448,8 @@
|
|||
compatible = "samsung,exynos4210-pwm";
|
||||
reg = <0x139D0000 0x1000>;
|
||||
interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
|
||||
clocks = <&clock 336>;
|
||||
clock-names = "timers";
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -89,7 +89,8 @@ static inline struct clk *imx_clk_gate(const char *name, const char *parent,
|
|||
static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char **parents, int num_parents)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents, 0, reg, shift,
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT, reg, shift,
|
||||
width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
|
@ -98,7 +99,7 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
|
|||
int num_parents, unsigned long flags)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
flags, reg, shift, width, 0,
|
||||
flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 0,
|
||||
&imx_ccm_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ config COMMON_CLK_DEBUG
|
|||
bool "DebugFS representation of clock tree"
|
||||
select DEBUG_FS
|
||||
---help---
|
||||
Creates a directory hierchy in debugfs for visualizing the clk
|
||||
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 &
|
||||
|
@ -64,6 +64,12 @@ config COMMON_CLK_SI5351
|
|||
This driver supports Silicon Labs 5351A/B/C programmable clock
|
||||
generators.
|
||||
|
||||
config COMMON_CLK_S2MPS11
|
||||
tristate "Clock driver for S2MPS11 MFD"
|
||||
depends on MFD_SEC_CORE
|
||||
---help---
|
||||
This driver supports S2MPS11 crystal oscillator clock.
|
||||
|
||||
config CLK_TWL6040
|
||||
tristate "External McPDM functional clock from twl6040"
|
||||
depends on TWL6040_CORE
|
||||
|
|
|
@ -40,5 +40,6 @@ 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_S2MPS11) += clk-s2mps11.o
|
||||
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
|
||||
obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
static const __initconst struct of_device_id clk_match[] = {
|
||||
static const struct of_device_id clk_match[] __initconst = {
|
||||
{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -104,7 +104,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
|
|||
struct clk_divider *divider = to_clk_divider(hw);
|
||||
unsigned int div, val;
|
||||
|
||||
val = readl(divider->reg) >> divider->shift;
|
||||
val = clk_readl(divider->reg) >> divider->shift;
|
||||
val &= div_mask(divider);
|
||||
|
||||
div = _get_div(divider, val);
|
||||
|
@ -230,11 +230,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
|
||||
val = div_mask(divider) << (divider->shift + 16);
|
||||
} else {
|
||||
val = readl(divider->reg);
|
||||
val = clk_readl(divider->reg);
|
||||
val &= ~(div_mask(divider) << divider->shift);
|
||||
}
|
||||
val |= value << divider->shift;
|
||||
writel(val, divider->reg);
|
||||
clk_writel(val, divider->reg);
|
||||
|
||||
if (divider->lock)
|
||||
spin_unlock_irqrestore(divider->lock, flags);
|
||||
|
@ -317,6 +317,7 @@ struct clk *clk_register_divider(struct device *dev, const char *name,
|
|||
return _register_divider(dev, name, parent_name, flags, reg, shift,
|
||||
width, clk_divider_flags, NULL, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_divider);
|
||||
|
||||
/**
|
||||
* clk_register_divider_table - register a table based divider clock with
|
||||
|
@ -341,3 +342,4 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
|
|||
return _register_divider(dev, name, parent_name, flags, reg, shift,
|
||||
width, clk_divider_flags, table, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_divider_table);
|
||||
|
|
|
@ -97,6 +97,8 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
|
|||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_fixed_factor);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
|
||||
|
|
|
@ -80,6 +80,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
|
|||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
|
|
|
@ -58,7 +58,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
|
|||
if (set)
|
||||
reg |= BIT(gate->bit_idx);
|
||||
} else {
|
||||
reg = readl(gate->reg);
|
||||
reg = clk_readl(gate->reg);
|
||||
|
||||
if (set)
|
||||
reg |= BIT(gate->bit_idx);
|
||||
|
@ -66,7 +66,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
|
|||
reg &= ~BIT(gate->bit_idx);
|
||||
}
|
||||
|
||||
writel(reg, gate->reg);
|
||||
clk_writel(reg, gate->reg);
|
||||
|
||||
if (gate->lock)
|
||||
spin_unlock_irqrestore(gate->lock, flags);
|
||||
|
@ -89,7 +89,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
|
|||
u32 reg;
|
||||
struct clk_gate *gate = to_clk_gate(hw);
|
||||
|
||||
reg = readl(gate->reg);
|
||||
reg = clk_readl(gate->reg);
|
||||
|
||||
/* if a set bit disables this clk, flip it before masking */
|
||||
if (gate->flags & CLK_GATE_SET_TO_DISABLE)
|
||||
|
@ -161,3 +161,4 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
|
|||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_gate);
|
||||
|
|
|
@ -42,7 +42,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
|
|||
* OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
|
||||
* val = 0x4 really means "bit 2, index starts at bit 0"
|
||||
*/
|
||||
val = readl(mux->reg) >> mux->shift;
|
||||
val = clk_readl(mux->reg) >> mux->shift;
|
||||
val &= mux->mask;
|
||||
|
||||
if (mux->table) {
|
||||
|
@ -89,11 +89,11 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
|||
if (mux->flags & CLK_MUX_HIWORD_MASK) {
|
||||
val = mux->mask << (mux->shift + 16);
|
||||
} else {
|
||||
val = readl(mux->reg);
|
||||
val = clk_readl(mux->reg);
|
||||
val &= ~(mux->mask << mux->shift);
|
||||
}
|
||||
val |= index << mux->shift;
|
||||
writel(val, mux->reg);
|
||||
clk_writel(val, mux->reg);
|
||||
|
||||
if (mux->lock)
|
||||
spin_unlock_irqrestore(mux->lock, flags);
|
||||
|
@ -104,9 +104,15 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
|||
const struct clk_ops clk_mux_ops = {
|
||||
.get_parent = clk_mux_get_parent,
|
||||
.set_parent = clk_mux_set_parent,
|
||||
.determine_rate = __clk_mux_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_mux_ops);
|
||||
|
||||
const struct clk_ops clk_mux_ro_ops = {
|
||||
.get_parent = clk_mux_get_parent,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
|
||||
|
||||
struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
||||
const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u32 mask,
|
||||
|
@ -133,6 +139,9 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
|||
}
|
||||
|
||||
init.name = name;
|
||||
if (clk_mux_flags & CLK_MUX_READ_ONLY)
|
||||
init.ops = &clk_mux_ro_ops;
|
||||
else
|
||||
init.ops = &clk_mux_ops;
|
||||
init.flags = flags | CLK_IS_BASIC;
|
||||
init.parent_names = parent_names;
|
||||
|
@ -154,6 +163,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
|||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_mux_table);
|
||||
|
||||
struct clk *clk_register_mux(struct device *dev, const char *name,
|
||||
const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
|
@ -166,3 +176,4 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
|
|||
flags, reg, shift, mask, clk_mux_flags,
|
||||
NULL, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_mux);
|
||||
|
|
|
@ -479,12 +479,12 @@ static void __init of_nomadik_src_clk_setup(struct device_node *np)
|
|||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
}
|
||||
|
||||
static const __initconst struct of_device_id nomadik_src_match[] = {
|
||||
static const struct of_device_id nomadik_src_match[] __initconst = {
|
||||
{ .compatible = "stericsson,nomadik-src" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const __initconst struct of_device_id nomadik_src_clk_match[] = {
|
||||
static const struct of_device_id nomadik_src_clk_match[] __initconst = {
|
||||
{
|
||||
.compatible = "fixed-clock",
|
||||
.data = of_fixed_clk_setup,
|
||||
|
|
|
@ -1034,7 +1034,7 @@ enum prima2_clk_index {
|
|||
usb0, usb1, maxclk,
|
||||
};
|
||||
|
||||
static __initdata struct clk_hw* prima2_clk_hw_array[maxclk] = {
|
||||
static struct clk_hw *prima2_clk_hw_array[maxclk] __initdata = {
|
||||
NULL, /* dummy */
|
||||
NULL,
|
||||
&clk_pll1.hw,
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* clk-s2mps11.c - Clock driver for S2MPS11.
|
||||
*
|
||||
* Copyright (C) 2013 Samsung Electornics
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/core.h>
|
||||
|
||||
#define s2mps11_name(a) (a->hw.init->name)
|
||||
|
||||
static struct clk **clk_table;
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
enum {
|
||||
S2MPS11_CLK_AP = 0,
|
||||
S2MPS11_CLK_CP,
|
||||
S2MPS11_CLK_BT,
|
||||
S2MPS11_CLKS_NUM,
|
||||
};
|
||||
|
||||
struct s2mps11_clk {
|
||||
struct sec_pmic_dev *iodev;
|
||||
struct clk_hw hw;
|
||||
struct clk *clk;
|
||||
struct clk_lookup *lookup;
|
||||
u32 mask;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct s2mps11_clk, hw);
|
||||
}
|
||||
|
||||
static int s2mps11_clk_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(s2mps11->iodev->regmap,
|
||||
S2MPS11_REG_RTC_CTRL,
|
||||
s2mps11->mask, s2mps11->mask);
|
||||
if (!ret)
|
||||
s2mps11->enabled = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void s2mps11_clk_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(s2mps11->iodev->regmap, S2MPS11_REG_RTC_CTRL,
|
||||
s2mps11->mask, ~s2mps11->mask);
|
||||
|
||||
if (!ret)
|
||||
s2mps11->enabled = false;
|
||||
}
|
||||
|
||||
static int s2mps11_clk_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
|
||||
|
||||
return s2mps11->enabled;
|
||||
}
|
||||
|
||||
static unsigned long s2mps11_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
|
||||
if (s2mps11->enabled)
|
||||
return 32768;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_ops s2mps11_clk_ops = {
|
||||
.prepare = s2mps11_clk_prepare,
|
||||
.unprepare = s2mps11_clk_unprepare,
|
||||
.is_enabled = s2mps11_clk_is_enabled,
|
||||
.recalc_rate = s2mps11_clk_recalc_rate,
|
||||
};
|
||||
|
||||
static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = {
|
||||
[S2MPS11_CLK_AP] = {
|
||||
.name = "s2mps11_ap",
|
||||
.ops = &s2mps11_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[S2MPS11_CLK_CP] = {
|
||||
.name = "s2mps11_cp",
|
||||
.ops = &s2mps11_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
[S2MPS11_CLK_BT] = {
|
||||
.name = "s2mps11_bt",
|
||||
.ops = &s2mps11_clk_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device_node *clk_np;
|
||||
int i;
|
||||
|
||||
if (!iodev->dev->of_node)
|
||||
return NULL;
|
||||
|
||||
clk_np = of_find_node_by_name(iodev->dev->of_node, "clocks");
|
||||
if (!clk_np) {
|
||||
dev_err(&pdev->dev, "could not find clock sub-node\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
clk_table = devm_kzalloc(&pdev->dev, sizeof(struct clk *) *
|
||||
S2MPS11_CLKS_NUM, GFP_KERNEL);
|
||||
if (!clk_table)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < S2MPS11_CLKS_NUM; i++)
|
||||
of_property_read_string_index(clk_np, "clock-output-names", i,
|
||||
&s2mps11_clks_init[i].name);
|
||||
|
||||
return clk_np;
|
||||
}
|
||||
|
||||
static int s2mps11_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct s2mps11_clk *s2mps11_clks, *s2mps11_clk;
|
||||
struct device_node *clk_np = NULL;
|
||||
int i, ret = 0;
|
||||
u32 val;
|
||||
|
||||
s2mps11_clks = devm_kzalloc(&pdev->dev, sizeof(*s2mps11_clk) *
|
||||
S2MPS11_CLKS_NUM, GFP_KERNEL);
|
||||
if (!s2mps11_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
s2mps11_clk = s2mps11_clks;
|
||||
|
||||
clk_np = s2mps11_clk_parse_dt(pdev);
|
||||
if (IS_ERR(clk_np))
|
||||
return PTR_ERR(clk_np);
|
||||
|
||||
for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) {
|
||||
s2mps11_clk->iodev = iodev;
|
||||
s2mps11_clk->hw.init = &s2mps11_clks_init[i];
|
||||
s2mps11_clk->mask = 1 << i;
|
||||
|
||||
ret = regmap_read(s2mps11_clk->iodev->regmap,
|
||||
S2MPS11_REG_RTC_CTRL, &val);
|
||||
if (ret < 0)
|
||||
goto err_reg;
|
||||
|
||||
s2mps11_clk->enabled = val & s2mps11_clk->mask;
|
||||
|
||||
s2mps11_clk->clk = devm_clk_register(&pdev->dev,
|
||||
&s2mps11_clk->hw);
|
||||
if (IS_ERR(s2mps11_clk->clk)) {
|
||||
dev_err(&pdev->dev, "Fail to register : %s\n",
|
||||
s2mps11_name(s2mps11_clk));
|
||||
ret = PTR_ERR(s2mps11_clk->clk);
|
||||
goto err_reg;
|
||||
}
|
||||
|
||||
s2mps11_clk->lookup = devm_kzalloc(&pdev->dev,
|
||||
sizeof(struct clk_lookup), GFP_KERNEL);
|
||||
if (!s2mps11_clk->lookup) {
|
||||
ret = -ENOMEM;
|
||||
goto err_lup;
|
||||
}
|
||||
|
||||
s2mps11_clk->lookup->con_id = s2mps11_name(s2mps11_clk);
|
||||
s2mps11_clk->lookup->clk = s2mps11_clk->clk;
|
||||
|
||||
clkdev_add(s2mps11_clk->lookup);
|
||||
}
|
||||
|
||||
if (clk_table) {
|
||||
for (i = 0; i < S2MPS11_CLKS_NUM; i++)
|
||||
clk_table[i] = s2mps11_clks[i].clk;
|
||||
|
||||
clk_data.clks = clk_table;
|
||||
clk_data.clk_num = S2MPS11_CLKS_NUM;
|
||||
of_clk_add_provider(clk_np, of_clk_src_onecell_get, &clk_data);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, s2mps11_clks);
|
||||
|
||||
return ret;
|
||||
err_lup:
|
||||
devm_clk_unregister(&pdev->dev, s2mps11_clk->clk);
|
||||
err_reg:
|
||||
while (s2mps11_clk > s2mps11_clks) {
|
||||
if (s2mps11_clk->lookup) {
|
||||
clkdev_drop(s2mps11_clk->lookup);
|
||||
devm_clk_unregister(&pdev->dev, s2mps11_clk->clk);
|
||||
}
|
||||
s2mps11_clk--;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s2mps11_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct s2mps11_clk *s2mps11_clks = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < S2MPS11_CLKS_NUM; i++)
|
||||
clkdev_drop(s2mps11_clks[i].lookup);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id s2mps11_clk_id[] = {
|
||||
{ "s2mps11-clk", 0},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
|
||||
|
||||
static struct platform_driver s2mps11_clk_driver = {
|
||||
.driver = {
|
||||
.name = "s2mps11-clk",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = s2mps11_clk_probe,
|
||||
.remove = s2mps11_clk_remove,
|
||||
.id_table = s2mps11_clk_id,
|
||||
};
|
||||
|
||||
static int __init s2mps11_clk_init(void)
|
||||
{
|
||||
return platform_driver_register(&s2mps11_clk_driver);
|
||||
}
|
||||
subsys_initcall(s2mps11_clk_init);
|
||||
|
||||
static void __init s2mps11_clk_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&s2mps11_clk_driver);
|
||||
}
|
||||
module_exit(s2mps11_clk_cleanup);
|
||||
|
||||
MODULE_DESCRIPTION("S2MPS11 Clock Driver");
|
||||
MODULE_AUTHOR("Yadwinder Singh Brar <yadi.brar@samsung.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -746,7 +746,7 @@ struct u300_clock {
|
|||
u16 clk_val;
|
||||
};
|
||||
|
||||
struct u300_clock const __initconst u300_clk_lookup[] = {
|
||||
static struct u300_clock const u300_clk_lookup[] __initconst = {
|
||||
{
|
||||
.type = U300_CLK_TYPE_REST,
|
||||
.id = 3,
|
||||
|
@ -1151,7 +1151,7 @@ static void __init of_u300_syscon_mclk_init(struct device_node *np)
|
|||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
}
|
||||
|
||||
static const __initconst struct of_device_id u300_clk_match[] = {
|
||||
static const struct of_device_id u300_clk_match[] __initconst = {
|
||||
{
|
||||
.compatible = "fixed-clock",
|
||||
.data = of_fixed_clk_setup,
|
||||
|
|
|
@ -31,7 +31,7 @@ struct wm831x_clk {
|
|||
bool xtal_ena;
|
||||
};
|
||||
|
||||
static int wm831x_xtal_is_enabled(struct clk_hw *hw)
|
||||
static int wm831x_xtal_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
|
||||
xtal_hw);
|
||||
|
@ -52,7 +52,7 @@ static unsigned long wm831x_xtal_recalc_rate(struct clk_hw *hw,
|
|||
}
|
||||
|
||||
static const struct clk_ops wm831x_xtal_ops = {
|
||||
.is_enabled = wm831x_xtal_is_enabled,
|
||||
.is_prepared = wm831x_xtal_is_prepared,
|
||||
.recalc_rate = wm831x_xtal_recalc_rate,
|
||||
};
|
||||
|
||||
|
@ -73,7 +73,7 @@ static const unsigned long wm831x_fll_auto_rates[] = {
|
|||
24576000,
|
||||
};
|
||||
|
||||
static int wm831x_fll_is_enabled(struct clk_hw *hw)
|
||||
static int wm831x_fll_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
|
||||
fll_hw);
|
||||
|
@ -170,7 +170,7 @@ static int wm831x_fll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
if (i == ARRAY_SIZE(wm831x_fll_auto_rates))
|
||||
return -EINVAL;
|
||||
|
||||
if (wm831x_fll_is_enabled(hw))
|
||||
if (wm831x_fll_is_prepared(hw))
|
||||
return -EPERM;
|
||||
|
||||
return wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_2,
|
||||
|
@ -220,7 +220,7 @@ static u8 wm831x_fll_get_parent(struct clk_hw *hw)
|
|||
}
|
||||
|
||||
static const struct clk_ops wm831x_fll_ops = {
|
||||
.is_enabled = wm831x_fll_is_enabled,
|
||||
.is_prepared = wm831x_fll_is_prepared,
|
||||
.prepare = wm831x_fll_prepare,
|
||||
.unprepare = wm831x_fll_unprepare,
|
||||
.round_rate = wm831x_fll_round_rate,
|
||||
|
@ -237,7 +237,7 @@ static struct clk_init_data wm831x_fll_init = {
|
|||
.flags = CLK_SET_RATE_GATE,
|
||||
};
|
||||
|
||||
static int wm831x_clkout_is_enabled(struct clk_hw *hw)
|
||||
static int wm831x_clkout_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
|
||||
clkout_hw);
|
||||
|
@ -335,7 +335,7 @@ static int wm831x_clkout_set_parent(struct clk_hw *hw, u8 parent)
|
|||
}
|
||||
|
||||
static const struct clk_ops wm831x_clkout_ops = {
|
||||
.is_enabled = wm831x_clkout_is_enabled,
|
||||
.is_prepared = wm831x_clkout_is_prepared,
|
||||
.prepare = wm831x_clkout_prepare,
|
||||
.unprepare = wm831x_clkout_unprepare,
|
||||
.get_parent = wm831x_clkout_get_parent,
|
||||
|
@ -360,6 +360,8 @@ static int wm831x_clk_probe(struct platform_device *pdev)
|
|||
if (!clkdata)
|
||||
return -ENOMEM;
|
||||
|
||||
clkdata->wm831x = wm831x;
|
||||
|
||||
/* XTAL_ENA can only be set via OTP/InstantConfig so just read once */
|
||||
ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
|
||||
if (ret < 0) {
|
||||
|
|
|
@ -458,7 +458,6 @@ static void clk_unprepare_unused_subtree(struct clk *clk)
|
|||
clk->ops->unprepare(clk->hw);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__clk_get_flags);
|
||||
|
||||
/* caller must hold prepare_lock */
|
||||
static void clk_disable_unused_subtree(struct clk *clk)
|
||||
|
@ -559,6 +558,19 @@ struct clk *__clk_get_parent(struct clk *clk)
|
|||
return !clk ? NULL : clk->parent;
|
||||
}
|
||||
|
||||
struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
|
||||
{
|
||||
if (!clk || index >= clk->num_parents)
|
||||
return NULL;
|
||||
else if (!clk->parents)
|
||||
return __clk_lookup(clk->parent_names[index]);
|
||||
else if (!clk->parents[index])
|
||||
return clk->parents[index] =
|
||||
__clk_lookup(clk->parent_names[index]);
|
||||
else
|
||||
return clk->parents[index];
|
||||
}
|
||||
|
||||
unsigned int __clk_get_enable_count(struct clk *clk)
|
||||
{
|
||||
return !clk ? 0 : clk->enable_count;
|
||||
|
@ -594,6 +606,7 @@ unsigned long __clk_get_flags(struct clk *clk)
|
|||
{
|
||||
return !clk ? 0 : clk->flags;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__clk_get_flags);
|
||||
|
||||
bool __clk_is_prepared(struct clk *clk)
|
||||
{
|
||||
|
@ -679,6 +692,55 @@ struct clk *__clk_lookup(const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper for finding best parent to provide a given frequency. This can be used
|
||||
* directly as a determine_rate callback (e.g. for a mux), or from a more
|
||||
* complex clock that may combine a mux with other operations.
|
||||
*/
|
||||
long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *best_parent_rate,
|
||||
struct clk **best_parent_p)
|
||||
{
|
||||
struct clk *clk = hw->clk, *parent, *best_parent = NULL;
|
||||
int i, num_parents;
|
||||
unsigned long parent_rate, best = 0;
|
||||
|
||||
/* if NO_REPARENT flag set, pass through to current parent */
|
||||
if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
|
||||
parent = clk->parent;
|
||||
if (clk->flags & CLK_SET_RATE_PARENT)
|
||||
best = __clk_round_rate(parent, rate);
|
||||
else if (parent)
|
||||
best = __clk_get_rate(parent);
|
||||
else
|
||||
best = __clk_get_rate(clk);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find the parent that can provide the fastest rate <= rate */
|
||||
num_parents = clk->num_parents;
|
||||
for (i = 0; i < num_parents; i++) {
|
||||
parent = clk_get_parent_by_index(clk, i);
|
||||
if (!parent)
|
||||
continue;
|
||||
if (clk->flags & CLK_SET_RATE_PARENT)
|
||||
parent_rate = __clk_round_rate(parent, rate);
|
||||
else
|
||||
parent_rate = __clk_get_rate(parent);
|
||||
if (parent_rate <= rate && parent_rate > best) {
|
||||
best_parent = parent;
|
||||
best = parent_rate;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (best_parent)
|
||||
*best_parent_p = best_parent;
|
||||
*best_parent_rate = best;
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
/*** clk api ***/
|
||||
|
||||
void __clk_unprepare(struct clk *clk)
|
||||
|
@ -702,7 +764,7 @@ void __clk_unprepare(struct clk *clk)
|
|||
|
||||
/**
|
||||
* clk_unprepare - undo preparation of a clock source
|
||||
* @clk: the clk being unprepare
|
||||
* @clk: the clk being unprepared
|
||||
*
|
||||
* clk_unprepare may sleep, which differentiates it from clk_disable. In a
|
||||
* simple case, clk_unprepare can be used instead of clk_disable to gate a clk
|
||||
|
@ -869,29 +931,33 @@ EXPORT_SYMBOL_GPL(clk_enable);
|
|||
/**
|
||||
* __clk_round_rate - round the given rate for a clk
|
||||
* @clk: round the rate of this clock
|
||||
* @rate: the rate which is to be rounded
|
||||
*
|
||||
* Caller must hold prepare_lock. Useful for clk_ops such as .set_rate
|
||||
*/
|
||||
unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned long parent_rate = 0;
|
||||
struct clk *parent;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
if (!clk->ops->round_rate) {
|
||||
if (clk->flags & CLK_SET_RATE_PARENT)
|
||||
parent = clk->parent;
|
||||
if (parent)
|
||||
parent_rate = parent->rate;
|
||||
|
||||
if (clk->ops->determine_rate)
|
||||
return clk->ops->determine_rate(clk->hw, rate, &parent_rate,
|
||||
&parent);
|
||||
else if (clk->ops->round_rate)
|
||||
return clk->ops->round_rate(clk->hw, rate, &parent_rate);
|
||||
else if (clk->flags & CLK_SET_RATE_PARENT)
|
||||
return __clk_round_rate(clk->parent, rate);
|
||||
else
|
||||
return clk->rate;
|
||||
}
|
||||
|
||||
if (clk->parent)
|
||||
parent_rate = clk->parent->rate;
|
||||
|
||||
return clk->ops->round_rate(clk->hw, rate, &parent_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_round_rate - round the given rate for a clk
|
||||
* @clk: the clk for which we are rounding a rate
|
||||
|
@ -956,7 +1022,7 @@ static int __clk_notify(struct clk *clk, unsigned long msg,
|
|||
*
|
||||
* Walks the subtree of clks starting with clk and recalculates rates as it
|
||||
* goes. Note that if a clk does not implement the .recalc_rate callback then
|
||||
* it is assumed that the clock will take on the rate of it's parent.
|
||||
* it is assumed that the clock will take on the rate of its parent.
|
||||
*
|
||||
* clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
|
||||
* if necessary.
|
||||
|
@ -1014,6 +1080,115 @@ unsigned long clk_get_rate(struct clk *clk)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(clk_get_rate);
|
||||
|
||||
static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
if (!clk->parents)
|
||||
clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
|
||||
GFP_KERNEL);
|
||||
|
||||
/*
|
||||
* find index of new parent clock using cached parent ptrs,
|
||||
* or if not yet cached, use string name comparison and cache
|
||||
* them now to avoid future calls to __clk_lookup.
|
||||
*/
|
||||
for (i = 0; i < clk->num_parents; i++) {
|
||||
if (clk->parents && clk->parents[i] == parent)
|
||||
break;
|
||||
else if (!strcmp(clk->parent_names[i], parent->name)) {
|
||||
if (clk->parents)
|
||||
clk->parents[i] = __clk_lookup(parent->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void clk_reparent(struct clk *clk, struct clk *new_parent)
|
||||
{
|
||||
hlist_del(&clk->child_node);
|
||||
|
||||
if (new_parent) {
|
||||
/* avoid duplicate POST_RATE_CHANGE notifications */
|
||||
if (new_parent->new_child == clk)
|
||||
new_parent->new_child = NULL;
|
||||
|
||||
hlist_add_head(&clk->child_node, &new_parent->children);
|
||||
} else {
|
||||
hlist_add_head(&clk->child_node, &clk_orphan_list);
|
||||
}
|
||||
|
||||
clk->parent = new_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 = clk->parent;
|
||||
|
||||
/*
|
||||
* Migrate prepare state between parents and prevent race with
|
||||
* clk_enable().
|
||||
*
|
||||
* If the clock is not prepared, then a race with
|
||||
* clk_enable/disable() is impossible since we already have the
|
||||
* prepare lock (future calls to clk_enable() need to be preceded by
|
||||
* a clk_prepare()).
|
||||
*
|
||||
* If the clock is prepared, migrate the prepared state to the new
|
||||
* parent and also protect against a race with clk_enable() by
|
||||
* forcing the clock and the new parent on. This ensures that all
|
||||
* future calls to clk_enable() are practically NOPs with respect to
|
||||
* hardware and software states.
|
||||
*
|
||||
* See also: Comment for clk_set_parent() below.
|
||||
*/
|
||||
if (clk->prepare_count) {
|
||||
__clk_prepare(parent);
|
||||
clk_enable(parent);
|
||||
clk_enable(clk);
|
||||
}
|
||||
|
||||
/* update the clk tree topology */
|
||||
flags = clk_enable_lock();
|
||||
clk_reparent(clk, parent);
|
||||
clk_enable_unlock(flags);
|
||||
|
||||
/* change clock input source */
|
||||
if (parent && clk->ops->set_parent)
|
||||
ret = clk->ops->set_parent(clk->hw, p_index);
|
||||
|
||||
if (ret) {
|
||||
flags = clk_enable_lock();
|
||||
clk_reparent(clk, old_parent);
|
||||
clk_enable_unlock(flags);
|
||||
|
||||
if (clk->prepare_count) {
|
||||
clk_disable(clk);
|
||||
clk_disable(parent);
|
||||
__clk_unprepare(parent);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* update debugfs with new clk tree topology */
|
||||
clk_debug_reparent(clk, parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* __clk_speculate_rates
|
||||
* @clk: first clk in the subtree
|
||||
|
@ -1026,7 +1201,7 @@ EXPORT_SYMBOL_GPL(clk_get_rate);
|
|||
* pre-rate change notifications and returns early if no clks in the
|
||||
* subtree have subscribed to the notifications. Note that if a clk does not
|
||||
* implement the .recalc_rate callback then it is assumed that the clock will
|
||||
* take on the rate of it's parent.
|
||||
* take on the rate of its parent.
|
||||
*
|
||||
* Caller must hold prepare_lock.
|
||||
*/
|
||||
|
@ -1058,18 +1233,25 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void clk_calc_subtree(struct clk *clk, unsigned long new_rate)
|
||||
static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
|
||||
struct clk *new_parent, u8 p_index)
|
||||
{
|
||||
struct clk *child;
|
||||
|
||||
clk->new_rate = new_rate;
|
||||
clk->new_parent = new_parent;
|
||||
clk->new_parent_index = p_index;
|
||||
/* include clk in new parent's PRE_RATE_CHANGE notifications */
|
||||
clk->new_child = NULL;
|
||||
if (new_parent && new_parent != clk->parent)
|
||||
new_parent->new_child = clk;
|
||||
|
||||
hlist_for_each_entry(child, &clk->children, child_node) {
|
||||
if (child->ops->recalc_rate)
|
||||
child->new_rate = child->ops->recalc_rate(child->hw, new_rate);
|
||||
else
|
||||
child->new_rate = new_rate;
|
||||
clk_calc_subtree(child, child->new_rate);
|
||||
clk_calc_subtree(child, child->new_rate, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1080,50 +1262,63 @@ static void clk_calc_subtree(struct clk *clk, unsigned long new_rate)
|
|||
static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
struct clk *top = clk;
|
||||
struct clk *old_parent, *parent;
|
||||
unsigned long best_parent_rate = 0;
|
||||
unsigned long new_rate;
|
||||
u8 p_index = 0;
|
||||
|
||||
/* sanity */
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
return NULL;
|
||||
|
||||
/* save parent rate, if it exists */
|
||||
if (clk->parent)
|
||||
best_parent_rate = clk->parent->rate;
|
||||
parent = old_parent = clk->parent;
|
||||
if (parent)
|
||||
best_parent_rate = parent->rate;
|
||||
|
||||
/* never propagate up to the parent */
|
||||
if (!(clk->flags & CLK_SET_RATE_PARENT)) {
|
||||
if (!clk->ops->round_rate) {
|
||||
/* find the closest rate and parent clk/rate */
|
||||
if (clk->ops->determine_rate) {
|
||||
new_rate = clk->ops->determine_rate(clk->hw, rate,
|
||||
&best_parent_rate,
|
||||
&parent);
|
||||
} else if (clk->ops->round_rate) {
|
||||
new_rate = clk->ops->round_rate(clk->hw, rate,
|
||||
&best_parent_rate);
|
||||
} else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
|
||||
/* pass-through clock without adjustable parent */
|
||||
clk->new_rate = clk->rate;
|
||||
return NULL;
|
||||
}
|
||||
new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
|
||||
} else {
|
||||
/* pass-through clock with adjustable parent */
|
||||
top = clk_calc_new_rates(parent, rate);
|
||||
new_rate = parent->new_rate;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* need clk->parent from here on out */
|
||||
if (!clk->parent) {
|
||||
pr_debug("%s: %s has NULL parent\n", __func__, clk->name);
|
||||
/* some clocks must be gated to change parent */
|
||||
if (parent != old_parent &&
|
||||
(clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) {
|
||||
pr_debug("%s: %s not gated but wants to reparent\n",
|
||||
__func__, clk->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!clk->ops->round_rate) {
|
||||
top = clk_calc_new_rates(clk->parent, rate);
|
||||
new_rate = clk->parent->new_rate;
|
||||
|
||||
goto out;
|
||||
/* try finding the new parent index */
|
||||
if (parent) {
|
||||
p_index = clk_fetch_parent_index(clk, parent);
|
||||
if (p_index == clk->num_parents) {
|
||||
pr_debug("%s: clk %s can not be parent of clk %s\n",
|
||||
__func__, parent->name, clk->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
|
||||
|
||||
if (best_parent_rate != clk->parent->rate) {
|
||||
top = clk_calc_new_rates(clk->parent, best_parent_rate);
|
||||
|
||||
goto out;
|
||||
}
|
||||
if ((clk->flags & CLK_SET_RATE_PARENT) && parent &&
|
||||
best_parent_rate != parent->rate)
|
||||
top = clk_calc_new_rates(parent, best_parent_rate);
|
||||
|
||||
out:
|
||||
clk_calc_subtree(clk, new_rate);
|
||||
clk_calc_subtree(clk, new_rate, parent, p_index);
|
||||
|
||||
return top;
|
||||
}
|
||||
|
@ -1135,7 +1330,7 @@ out:
|
|||
*/
|
||||
static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
|
||||
{
|
||||
struct clk *child, *fail_clk = NULL;
|
||||
struct clk *child, *tmp_clk, *fail_clk = NULL;
|
||||
int ret = NOTIFY_DONE;
|
||||
|
||||
if (clk->rate == clk->new_rate)
|
||||
|
@ -1148,9 +1343,19 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even
|
|||
}
|
||||
|
||||
hlist_for_each_entry(child, &clk->children, child_node) {
|
||||
clk = clk_propagate_rate_change(child, event);
|
||||
if (clk)
|
||||
fail_clk = clk;
|
||||
/* Skip children who will be reparented to another clock */
|
||||
if (child->new_parent && child->new_parent != clk)
|
||||
continue;
|
||||
tmp_clk = clk_propagate_rate_change(child, event);
|
||||
if (tmp_clk)
|
||||
fail_clk = tmp_clk;
|
||||
}
|
||||
|
||||
/* handle the new child who might not be in clk->children yet */
|
||||
if (clk->new_child) {
|
||||
tmp_clk = clk_propagate_rate_change(clk->new_child, event);
|
||||
if (tmp_clk)
|
||||
fail_clk = tmp_clk;
|
||||
}
|
||||
|
||||
return fail_clk;
|
||||
|
@ -1168,6 +1373,10 @@ static void clk_change_rate(struct clk *clk)
|
|||
|
||||
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)
|
||||
best_parent_rate = clk->parent->rate;
|
||||
|
||||
|
@ -1182,10 +1391,18 @@ static void clk_change_rate(struct clk *clk)
|
|||
if (clk->notifier_count && old_rate != clk->rate)
|
||||
__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
|
||||
|
||||
hlist_for_each_entry(child, &clk->children, child_node)
|
||||
hlist_for_each_entry(child, &clk->children, child_node) {
|
||||
/* Skip children who will be reparented to another clock */
|
||||
if (child->new_parent && child->new_parent != clk)
|
||||
continue;
|
||||
clk_change_rate(child);
|
||||
}
|
||||
|
||||
/* handle the new child who might not be in clk->children yet */
|
||||
if (clk->new_child)
|
||||
clk_change_rate(clk->new_child);
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_set_rate - specify a new rate for clk
|
||||
* @clk: the clk whose rate is being changed
|
||||
|
@ -1198,7 +1415,7 @@ static void clk_change_rate(struct clk *clk)
|
|||
* outcome of clk's .round_rate implementation. If *parent_rate is unchanged
|
||||
* after calling .round_rate then upstream parent propagation is ignored. If
|
||||
* *parent_rate comes back with a new rate for clk's parent then we propagate
|
||||
* up to clk's parent and set it's rate. Upward propagation will continue
|
||||
* up to clk's parent and set its rate. Upward propagation will continue
|
||||
* until either a clk does not support the CLK_SET_RATE_PARENT flag or
|
||||
* .round_rate stops requesting changes to clk's parent_rate.
|
||||
*
|
||||
|
@ -1212,6 +1429,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
|||
struct clk *top, *fail_clk;
|
||||
int ret = 0;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
/* prevent racing with updates to the clock topology */
|
||||
clk_prepare_lock();
|
||||
|
||||
|
@ -1315,30 +1535,12 @@ static struct clk *__clk_init_parent(struct clk *clk)
|
|||
kzalloc((sizeof(struct clk*) * clk->num_parents),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!clk->parents)
|
||||
ret = __clk_lookup(clk->parent_names[index]);
|
||||
else if (!clk->parents[index])
|
||||
ret = clk->parents[index] =
|
||||
__clk_lookup(clk->parent_names[index]);
|
||||
else
|
||||
ret = clk->parents[index];
|
||||
ret = clk_get_parent_by_index(clk, index);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void clk_reparent(struct clk *clk, struct clk *new_parent)
|
||||
{
|
||||
hlist_del(&clk->child_node);
|
||||
|
||||
if (new_parent)
|
||||
hlist_add_head(&clk->child_node, &new_parent->children);
|
||||
else
|
||||
hlist_add_head(&clk->child_node, &clk_orphan_list);
|
||||
|
||||
clk->parent = new_parent;
|
||||
}
|
||||
|
||||
void __clk_reparent(struct clk *clk, struct clk *new_parent)
|
||||
{
|
||||
clk_reparent(clk, new_parent);
|
||||
|
@ -1346,98 +1548,6 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent)
|
|||
__clk_recalc_rates(clk, POST_RATE_CHANGE);
|
||||
}
|
||||
|
||||
static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
if (!clk->parents)
|
||||
clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
|
||||
GFP_KERNEL);
|
||||
|
||||
/*
|
||||
* find index of new parent clock using cached parent ptrs,
|
||||
* or if not yet cached, use string name comparison and cache
|
||||
* them now to avoid future calls to __clk_lookup.
|
||||
*/
|
||||
for (i = 0; i < clk->num_parents; i++) {
|
||||
if (clk->parents && clk->parents[i] == parent)
|
||||
break;
|
||||
else if (!strcmp(clk->parent_names[i], parent->name)) {
|
||||
if (clk->parents)
|
||||
clk->parents[i] = __clk_lookup(parent->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
struct clk *old_parent = clk->parent;
|
||||
|
||||
/*
|
||||
* Migrate prepare state between parents and prevent race with
|
||||
* clk_enable().
|
||||
*
|
||||
* If the clock is not prepared, then a race with
|
||||
* clk_enable/disable() is impossible since we already have the
|
||||
* prepare lock (future calls to clk_enable() need to be preceded by
|
||||
* a clk_prepare()).
|
||||
*
|
||||
* If the clock is prepared, migrate the prepared state to the new
|
||||
* parent and also protect against a race with clk_enable() by
|
||||
* forcing the clock and the new parent on. This ensures that all
|
||||
* future calls to clk_enable() are practically NOPs with respect to
|
||||
* hardware and software states.
|
||||
*
|
||||
* See also: Comment for clk_set_parent() below.
|
||||
*/
|
||||
if (clk->prepare_count) {
|
||||
__clk_prepare(parent);
|
||||
clk_enable(parent);
|
||||
clk_enable(clk);
|
||||
}
|
||||
|
||||
/* update the clk tree topology */
|
||||
flags = clk_enable_lock();
|
||||
clk_reparent(clk, parent);
|
||||
clk_enable_unlock(flags);
|
||||
|
||||
/* change clock input source */
|
||||
if (parent && clk->ops->set_parent)
|
||||
ret = clk->ops->set_parent(clk->hw, p_index);
|
||||
|
||||
if (ret) {
|
||||
flags = clk_enable_lock();
|
||||
clk_reparent(clk, old_parent);
|
||||
clk_enable_unlock(flags);
|
||||
|
||||
if (clk->prepare_count) {
|
||||
clk_disable(clk);
|
||||
clk_disable(parent);
|
||||
__clk_unprepare(parent);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* update debugfs with new clk tree topology */
|
||||
clk_debug_reparent(clk, parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_set_parent - switch the parent of a mux clk
|
||||
* @clk: the mux clk whose input we are switching
|
||||
|
@ -1461,7 +1571,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
|
|||
u8 p_index = 0;
|
||||
unsigned long p_rate = 0;
|
||||
|
||||
if (!clk || !clk->ops)
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
if (!clk->ops)
|
||||
return -EINVAL;
|
||||
|
||||
/* verify ops for for multi-parent clks */
|
||||
|
@ -1544,8 +1657,9 @@ int __clk_init(struct device *dev, struct clk *clk)
|
|||
|
||||
/* check that clk_ops are sane. See Documentation/clk.txt */
|
||||
if (clk->ops->set_rate &&
|
||||
!(clk->ops->round_rate && clk->ops->recalc_rate)) {
|
||||
pr_warning("%s: %s must implement .round_rate & .recalc_rate\n",
|
||||
!((clk->ops->round_rate || clk->ops->determine_rate) &&
|
||||
clk->ops->recalc_rate)) {
|
||||
pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
|
||||
__func__, clk->name);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
@ -1628,7 +1742,7 @@ int __clk_init(struct device *dev, struct clk *clk)
|
|||
* this clock
|
||||
*/
|
||||
hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
|
||||
if (orphan->ops->get_parent) {
|
||||
if (orphan->num_parents && orphan->ops->get_parent) {
|
||||
i = orphan->ops->get_parent(orphan->hw);
|
||||
if (!strcmp(clk->name, orphan->parent_names[i]))
|
||||
__clk_reparent(orphan, clk);
|
||||
|
@ -1648,7 +1762,7 @@ int __clk_init(struct device *dev, struct clk *clk)
|
|||
* The .init callback is not used by any of the basic clock types, but
|
||||
* exists for weird hardware that must perform initialization magic.
|
||||
* Please consider other ways of solving initialization problems before
|
||||
* using this callback, as it's use is discouraged.
|
||||
* using this callback, as its use is discouraged.
|
||||
*/
|
||||
if (clk->ops->init)
|
||||
clk->ops->init(clk->hw);
|
||||
|
@ -1675,7 +1789,7 @@ out:
|
|||
* very large numbers of clocks that need to be statically initialized. It is
|
||||
* a layering violation to include clk-private.h from any code which implements
|
||||
* a clock's .ops; as such any statically initialized clock data MUST be in a
|
||||
* separate C file from the logic that implements it's operations. Returns 0
|
||||
* separate C file from the logic that implements its operations. Returns 0
|
||||
* on success, otherwise an error code.
|
||||
*/
|
||||
struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
|
||||
|
@ -2115,13 +2229,13 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
|
|||
*/
|
||||
void __init of_clk_init(const struct of_device_id *matches)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device_node *np;
|
||||
|
||||
if (!matches)
|
||||
matches = __clk_of_table;
|
||||
|
||||
for_each_matching_node(np, matches) {
|
||||
const struct of_device_id *match = of_match_node(matches, np);
|
||||
for_each_matching_node_and_match(np, matches, &match) {
|
||||
of_clk_init_cb_t clk_init_cb = match->data;
|
||||
clk_init_cb(np);
|
||||
}
|
||||
|
|
|
@ -248,7 +248,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp2-pwm.3");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, vctcxo);
|
||||
clk_register_clkdev(clk, "uart_mux.0", NULL);
|
||||
|
@ -258,7 +259,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, vctcxo);
|
||||
clk_register_clkdev(clk, "uart_mux.1", NULL);
|
||||
|
@ -268,7 +270,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART2, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, vctcxo);
|
||||
clk_register_clkdev(clk, "uart_mux.2", NULL);
|
||||
|
@ -278,7 +281,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart3_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART3, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, vctcxo);
|
||||
clk_register_clkdev(clk, "uart_mux.3", NULL);
|
||||
|
@ -288,7 +292,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.3");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "uart_mux.0", NULL);
|
||||
|
||||
|
@ -297,7 +302,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.1", NULL);
|
||||
|
||||
|
@ -306,7 +312,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.1");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp2_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP2, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.2", NULL);
|
||||
|
||||
|
@ -315,7 +322,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.2");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp3_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP3, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.3", NULL);
|
||||
|
||||
|
@ -324,7 +332,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.3");
|
||||
|
||||
clk = clk_register_mux(NULL, "sdh_mux", sdh_parent,
|
||||
ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(sdh_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_SDH0, 8, 2, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "sdh_mux", NULL);
|
||||
|
||||
|
@ -354,7 +363,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, "usb_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "disp0_mux", disp_parent,
|
||||
ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(disp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_DISP0, 6, 2, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "disp_mux.0", NULL);
|
||||
|
||||
|
@ -376,7 +386,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, "disp_sphy.0", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "disp1_mux", disp_parent,
|
||||
ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(disp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_DISP1, 6, 2, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "disp_mux.1", NULL);
|
||||
|
||||
|
@ -394,7 +405,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, "ccic_arbiter", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent,
|
||||
ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ccic_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_CCIC0, 6, 2, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ccic_mux.0", NULL);
|
||||
|
||||
|
@ -421,7 +433,8 @@ void __init mmp2_clk_init(void)
|
|||
clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "ccic1_mux", ccic_parent,
|
||||
ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ccic_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_CCIC1, 6, 2, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ccic_mux.1", NULL);
|
||||
|
||||
|
|
|
@ -199,7 +199,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa168-pwm.3");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, uart_pll);
|
||||
clk_register_clkdev(clk, "uart_mux.0", NULL);
|
||||
|
@ -209,7 +210,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, uart_pll);
|
||||
clk_register_clkdev(clk, "uart_mux.1", NULL);
|
||||
|
@ -219,7 +221,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART2, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, uart_pll);
|
||||
clk_register_clkdev(clk, "uart_mux.2", NULL);
|
||||
|
@ -229,7 +232,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "uart_mux.0", NULL);
|
||||
|
||||
|
@ -238,7 +242,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.1", NULL);
|
||||
|
||||
|
@ -247,7 +252,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.1");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp2_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP2, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.2", NULL);
|
||||
|
||||
|
@ -256,7 +262,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.2");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp3_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP3, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.3", NULL);
|
||||
|
||||
|
@ -265,7 +272,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.3");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp4_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP4, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.4", NULL);
|
||||
|
||||
|
@ -278,7 +286,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa3xx-nand.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "sdh0_mux", sdh_parent,
|
||||
ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(sdh_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_SDH0, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "sdh0_mux", NULL);
|
||||
|
||||
|
@ -287,7 +296,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "sdhci-pxa.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "sdh1_mux", sdh_parent,
|
||||
ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(sdh_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_SDH1, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "sdh1_mux", NULL);
|
||||
|
||||
|
@ -304,7 +314,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, "sph_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "disp0_mux", disp_parent,
|
||||
ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(disp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_DISP0, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "disp_mux.0", NULL);
|
||||
|
||||
|
@ -317,7 +328,8 @@ void __init pxa168_clk_init(void)
|
|||
clk_register_clkdev(clk, "hclk", "mmp-disp.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent,
|
||||
ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ccic_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_CCIC0, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ccic_mux.0", NULL);
|
||||
|
||||
|
@ -327,8 +339,8 @@ void __init pxa168_clk_init(void)
|
|||
|
||||
clk = clk_register_mux(NULL, "ccic0_phy_mux", ccic_phy_parent,
|
||||
ARRAY_SIZE(ccic_phy_parent),
|
||||
CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
|
||||
7, 1, 0, &clk_lock);
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_CCIC0, 7, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ccic_phy_mux.0", NULL);
|
||||
|
||||
clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_phy_mux",
|
||||
|
|
|
@ -204,7 +204,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa910-pwm.3");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart0_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART0, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, uart_pll);
|
||||
clk_register_clkdev(clk, "uart_mux.0", NULL);
|
||||
|
@ -214,7 +215,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart1_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_UART1, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, uart_pll);
|
||||
clk_register_clkdev(clk, "uart_mux.1", NULL);
|
||||
|
@ -224,7 +226,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.1");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart2_mux", uart_parent,
|
||||
ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbcp_base + APBCP_UART2, 4, 3, 0, &clk_lock);
|
||||
clk_set_parent(clk, uart_pll);
|
||||
clk_register_clkdev(clk, "uart_mux.2", NULL);
|
||||
|
@ -234,7 +237,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa2xx-uart.2");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "uart_mux.0", NULL);
|
||||
|
||||
|
@ -243,7 +247,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-ssp.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent,
|
||||
ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ssp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ssp_mux.1", NULL);
|
||||
|
||||
|
@ -256,7 +261,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "pxa3xx-nand.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "sdh0_mux", sdh_parent,
|
||||
ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(sdh_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_SDH0, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "sdh0_mux", NULL);
|
||||
|
||||
|
@ -265,7 +271,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "sdhci-pxa.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "sdh1_mux", sdh_parent,
|
||||
ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(sdh_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_SDH1, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "sdh1_mux", NULL);
|
||||
|
||||
|
@ -282,7 +289,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, "sph_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "disp0_mux", disp_parent,
|
||||
ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(disp_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_DISP0, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "disp_mux.0", NULL);
|
||||
|
||||
|
@ -291,7 +299,8 @@ void __init pxa910_clk_init(void)
|
|||
clk_register_clkdev(clk, NULL, "mmp-disp.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent,
|
||||
ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(ccic_parent),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_CCIC0, 6, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ccic_mux.0", NULL);
|
||||
|
||||
|
@ -301,8 +310,8 @@ void __init pxa910_clk_init(void)
|
|||
|
||||
clk = clk_register_mux(NULL, "ccic0_phy_mux", ccic_phy_parent,
|
||||
ARRAY_SIZE(ccic_phy_parent),
|
||||
CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0,
|
||||
7, 1, 0, &clk_lock);
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
apmu_base + APMU_CCIC0, 7, 1, 0, &clk_lock);
|
||||
clk_register_clkdev(clk, "ccic_phy_mux.0", NULL);
|
||||
|
||||
clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_phy_mux",
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
|
||||
enum { A370_CPU_TO_NBCLK, A370_CPU_TO_HCLK, A370_CPU_TO_DRAMCLK };
|
||||
|
||||
static const struct coreclk_ratio __initconst a370_coreclk_ratios[] = {
|
||||
static const struct coreclk_ratio a370_coreclk_ratios[] __initconst = {
|
||||
{ .id = A370_CPU_TO_NBCLK, .name = "nbclk" },
|
||||
{ .id = A370_CPU_TO_HCLK, .name = "hclk" },
|
||||
{ .id = A370_CPU_TO_DRAMCLK, .name = "dramclk" },
|
||||
};
|
||||
|
||||
static const u32 __initconst a370_tclk_freqs[] = {
|
||||
static const u32 a370_tclk_freqs[] __initconst = {
|
||||
16600000,
|
||||
20000000,
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ static u32 __init a370_get_tclk_freq(void __iomem *sar)
|
|||
return a370_tclk_freqs[tclk_freq_select];
|
||||
}
|
||||
|
||||
static const u32 __initconst a370_cpu_freqs[] = {
|
||||
static const u32 a370_cpu_freqs[] __initconst = {
|
||||
400000000,
|
||||
533000000,
|
||||
667000000,
|
||||
|
@ -78,7 +78,7 @@ static u32 __init a370_get_cpu_freq(void __iomem *sar)
|
|||
return cpu_freq;
|
||||
}
|
||||
|
||||
static const int __initconst a370_nbclk_ratios[32][2] = {
|
||||
static const int a370_nbclk_ratios[32][2] __initconst = {
|
||||
{0, 1}, {1, 2}, {2, 2}, {2, 2},
|
||||
{1, 2}, {1, 2}, {1, 1}, {2, 3},
|
||||
{0, 1}, {1, 2}, {2, 4}, {0, 1},
|
||||
|
@ -89,7 +89,7 @@ static const int __initconst a370_nbclk_ratios[32][2] = {
|
|||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
};
|
||||
|
||||
static const int __initconst a370_hclk_ratios[32][2] = {
|
||||
static const int a370_hclk_ratios[32][2] __initconst = {
|
||||
{0, 1}, {1, 2}, {2, 6}, {2, 3},
|
||||
{1, 3}, {1, 4}, {1, 2}, {2, 6},
|
||||
{0, 1}, {1, 6}, {2, 10}, {0, 1},
|
||||
|
@ -100,7 +100,7 @@ static const int __initconst a370_hclk_ratios[32][2] = {
|
|||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
};
|
||||
|
||||
static const int __initconst a370_dramclk_ratios[32][2] = {
|
||||
static const int a370_dramclk_ratios[32][2] __initconst = {
|
||||
{0, 1}, {1, 2}, {2, 3}, {2, 3},
|
||||
{1, 3}, {1, 2}, {1, 2}, {2, 6},
|
||||
{0, 1}, {1, 3}, {2, 5}, {0, 1},
|
||||
|
@ -152,7 +152,7 @@ CLK_OF_DECLARE(a370_core_clk, "marvell,armada-370-core-clock",
|
|||
* Clock Gating Control
|
||||
*/
|
||||
|
||||
static const struct clk_gating_soc_desc __initconst a370_gating_desc[] = {
|
||||
static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = {
|
||||
{ "audio", NULL, 0, 0 },
|
||||
{ "pex0_en", NULL, 1, 0 },
|
||||
{ "pex1_en", NULL, 2, 0 },
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
enum { AXP_CPU_TO_NBCLK, AXP_CPU_TO_HCLK, AXP_CPU_TO_DRAMCLK };
|
||||
|
||||
static const struct coreclk_ratio __initconst axp_coreclk_ratios[] = {
|
||||
static const struct coreclk_ratio axp_coreclk_ratios[] __initconst = {
|
||||
{ .id = AXP_CPU_TO_NBCLK, .name = "nbclk" },
|
||||
{ .id = AXP_CPU_TO_HCLK, .name = "hclk" },
|
||||
{ .id = AXP_CPU_TO_DRAMCLK, .name = "dramclk" },
|
||||
|
@ -52,7 +52,7 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar)
|
|||
return 250000000;
|
||||
}
|
||||
|
||||
static const u32 __initconst axp_cpu_freqs[] = {
|
||||
static const u32 axp_cpu_freqs[] __initconst = {
|
||||
1000000000,
|
||||
1066000000,
|
||||
1200000000,
|
||||
|
@ -89,7 +89,7 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar)
|
|||
return cpu_freq;
|
||||
}
|
||||
|
||||
static const int __initconst axp_nbclk_ratios[32][2] = {
|
||||
static const int axp_nbclk_ratios[32][2] __initconst = {
|
||||
{0, 1}, {1, 2}, {2, 2}, {2, 2},
|
||||
{1, 2}, {1, 2}, {1, 1}, {2, 3},
|
||||
{0, 1}, {1, 2}, {2, 4}, {0, 1},
|
||||
|
@ -100,7 +100,7 @@ static const int __initconst axp_nbclk_ratios[32][2] = {
|
|||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
};
|
||||
|
||||
static const int __initconst axp_hclk_ratios[32][2] = {
|
||||
static const int axp_hclk_ratios[32][2] __initconst = {
|
||||
{0, 1}, {1, 2}, {2, 6}, {2, 3},
|
||||
{1, 3}, {1, 4}, {1, 2}, {2, 6},
|
||||
{0, 1}, {1, 6}, {2, 10}, {0, 1},
|
||||
|
@ -111,7 +111,7 @@ static const int __initconst axp_hclk_ratios[32][2] = {
|
|||
{0, 1}, {0, 1}, {0, 1}, {0, 1},
|
||||
};
|
||||
|
||||
static const int __initconst axp_dramclk_ratios[32][2] = {
|
||||
static const int axp_dramclk_ratios[32][2] __initconst = {
|
||||
{0, 1}, {1, 2}, {2, 3}, {2, 3},
|
||||
{1, 3}, {1, 2}, {1, 2}, {2, 6},
|
||||
{0, 1}, {1, 3}, {2, 5}, {0, 1},
|
||||
|
@ -169,7 +169,7 @@ CLK_OF_DECLARE(axp_core_clk, "marvell,armada-xp-core-clock",
|
|||
* Clock Gating Control
|
||||
*/
|
||||
|
||||
static const struct clk_gating_soc_desc __initconst axp_gating_desc[] = {
|
||||
static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = {
|
||||
{ "audio", NULL, 0, 0 },
|
||||
{ "ge3", NULL, 1, 0 },
|
||||
{ "ge2", NULL, 2, 0 },
|
||||
|
|
|
@ -119,7 +119,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
|
|||
|
||||
cpuclk = kzalloc(ncpus * sizeof(*cpuclk), GFP_KERNEL);
|
||||
if (WARN_ON(!cpuclk))
|
||||
return;
|
||||
goto cpuclk_out;
|
||||
|
||||
clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
|
||||
if (WARN_ON(!clks))
|
||||
|
@ -170,6 +170,8 @@ bail_out:
|
|||
kfree(cpuclk[ncpus].clk_name);
|
||||
clks_out:
|
||||
kfree(cpuclk);
|
||||
cpuclk_out:
|
||||
iounmap(clock_complex_base);
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock",
|
||||
|
|
|
@ -45,8 +45,10 @@ void __init mvebu_coreclk_setup(struct device_node *np,
|
|||
clk_data.clk_num = 2 + desc->num_ratios;
|
||||
clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
|
||||
GFP_KERNEL);
|
||||
if (WARN_ON(!clk_data.clks))
|
||||
if (WARN_ON(!clk_data.clks)) {
|
||||
iounmap(base);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Register TCLK */
|
||||
of_property_read_string_index(np, "clock-output-names", 0,
|
||||
|
@ -134,7 +136,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
|
|||
|
||||
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
|
||||
if (WARN_ON(!ctrl))
|
||||
return;
|
||||
goto ctrl_out;
|
||||
|
||||
spin_lock_init(&ctrl->lock);
|
||||
|
||||
|
@ -145,10 +147,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
|
|||
ctrl->num_gates = n;
|
||||
ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
|
||||
GFP_KERNEL);
|
||||
if (WARN_ON(!ctrl->gates)) {
|
||||
kfree(ctrl);
|
||||
return;
|
||||
}
|
||||
if (WARN_ON(!ctrl->gates))
|
||||
goto gates_out;
|
||||
|
||||
for (n = 0; n < ctrl->num_gates; n++) {
|
||||
const char *parent =
|
||||
|
@ -160,4 +160,10 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
|
|||
}
|
||||
|
||||
of_clk_add_provider(np, clk_gating_get_src, ctrl);
|
||||
|
||||
return;
|
||||
gates_out:
|
||||
kfree(ctrl);
|
||||
ctrl_out:
|
||||
iounmap(base);
|
||||
}
|
||||
|
|
|
@ -74,12 +74,12 @@
|
|||
|
||||
enum { DOVE_CPU_TO_L2, DOVE_CPU_TO_DDR };
|
||||
|
||||
static const struct coreclk_ratio __initconst dove_coreclk_ratios[] = {
|
||||
static const struct coreclk_ratio dove_coreclk_ratios[] __initconst = {
|
||||
{ .id = DOVE_CPU_TO_L2, .name = "l2clk", },
|
||||
{ .id = DOVE_CPU_TO_DDR, .name = "ddrclk", }
|
||||
};
|
||||
|
||||
static const u32 __initconst dove_tclk_freqs[] = {
|
||||
static const u32 dove_tclk_freqs[] __initconst = {
|
||||
166666667,
|
||||
125000000,
|
||||
0, 0
|
||||
|
@ -92,7 +92,7 @@ static u32 __init dove_get_tclk_freq(void __iomem *sar)
|
|||
return dove_tclk_freqs[opt];
|
||||
}
|
||||
|
||||
static const u32 __initconst dove_cpu_freqs[] = {
|
||||
static const u32 dove_cpu_freqs[] __initconst = {
|
||||
0, 0, 0, 0, 0,
|
||||
1000000000,
|
||||
933333333, 933333333,
|
||||
|
@ -111,12 +111,12 @@ static u32 __init dove_get_cpu_freq(void __iomem *sar)
|
|||
return dove_cpu_freqs[opt];
|
||||
}
|
||||
|
||||
static const int __initconst dove_cpu_l2_ratios[8][2] = {
|
||||
static const int dove_cpu_l2_ratios[8][2] __initconst = {
|
||||
{ 1, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
|
||||
{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 }
|
||||
};
|
||||
|
||||
static const int __initconst dove_cpu_ddr_ratios[16][2] = {
|
||||
static const int dove_cpu_ddr_ratios[16][2] __initconst = {
|
||||
{ 1, 1 }, { 0, 1 }, { 1, 2 }, { 2, 5 },
|
||||
{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 0, 1 },
|
||||
{ 1, 5 }, { 0, 1 }, { 1, 6 }, { 0, 1 },
|
||||
|
@ -164,7 +164,7 @@ CLK_OF_DECLARE(dove_core_clk, "marvell,dove-core-clock", dove_coreclk_init);
|
|||
* Clock Gating Control
|
||||
*/
|
||||
|
||||
static const struct clk_gating_soc_desc __initconst dove_gating_desc[] = {
|
||||
static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = {
|
||||
{ "usb0", NULL, 0, 0 },
|
||||
{ "usb1", NULL, 1, 0 },
|
||||
{ "ge", "gephy", 2, 0 },
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
enum { KIRKWOOD_CPU_TO_L2, KIRKWOOD_CPU_TO_DDR };
|
||||
|
||||
static const struct coreclk_ratio __initconst kirkwood_coreclk_ratios[] = {
|
||||
static const struct coreclk_ratio kirkwood_coreclk_ratios[] __initconst = {
|
||||
{ .id = KIRKWOOD_CPU_TO_L2, .name = "l2clk", },
|
||||
{ .id = KIRKWOOD_CPU_TO_DDR, .name = "ddrclk", }
|
||||
};
|
||||
|
@ -90,7 +90,7 @@ static u32 __init kirkwood_get_tclk_freq(void __iomem *sar)
|
|||
return (opt) ? 166666667 : 200000000;
|
||||
}
|
||||
|
||||
static const u32 __initconst kirkwood_cpu_freqs[] = {
|
||||
static const u32 kirkwood_cpu_freqs[] __initconst = {
|
||||
0, 0, 0, 0,
|
||||
600000000,
|
||||
0,
|
||||
|
@ -111,12 +111,12 @@ static u32 __init kirkwood_get_cpu_freq(void __iomem *sar)
|
|||
return kirkwood_cpu_freqs[opt];
|
||||
}
|
||||
|
||||
static const int __initconst kirkwood_cpu_l2_ratios[8][2] = {
|
||||
static const int kirkwood_cpu_l2_ratios[8][2] __initconst = {
|
||||
{ 0, 1 }, { 1, 2 }, { 0, 1 }, { 1, 3 },
|
||||
{ 0, 1 }, { 1, 4 }, { 0, 1 }, { 0, 1 }
|
||||
};
|
||||
|
||||
static const int __initconst kirkwood_cpu_ddr_ratios[16][2] = {
|
||||
static const int kirkwood_cpu_ddr_ratios[16][2] __initconst = {
|
||||
{ 0, 1 }, { 0, 1 }, { 1, 2 }, { 0, 1 },
|
||||
{ 1, 3 }, { 0, 1 }, { 1, 4 }, { 2, 9 },
|
||||
{ 1, 5 }, { 1, 6 }, { 0, 1 }, { 0, 1 },
|
||||
|
@ -145,7 +145,7 @@ static void __init kirkwood_get_clk_ratio(
|
|||
}
|
||||
}
|
||||
|
||||
static const u32 __initconst mv88f6180_cpu_freqs[] = {
|
||||
static const u32 mv88f6180_cpu_freqs[] __initconst = {
|
||||
0, 0, 0, 0, 0,
|
||||
600000000,
|
||||
800000000,
|
||||
|
@ -158,7 +158,7 @@ static u32 __init mv88f6180_get_cpu_freq(void __iomem *sar)
|
|||
return mv88f6180_cpu_freqs[opt];
|
||||
}
|
||||
|
||||
static const int __initconst mv88f6180_cpu_ddr_ratios[8][2] = {
|
||||
static const int mv88f6180_cpu_ddr_ratios[8][2] __initconst = {
|
||||
{ 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 },
|
||||
{ 0, 1 }, { 1, 3 }, { 1, 4 }, { 1, 5 }
|
||||
};
|
||||
|
@ -219,7 +219,7 @@ CLK_OF_DECLARE(mv88f6180_core_clk, "marvell,mv88f6180-core-clock",
|
|||
* Clock Gating Control
|
||||
*/
|
||||
|
||||
static const struct clk_gating_soc_desc __initconst kirkwood_gating_desc[] = {
|
||||
static const struct clk_gating_soc_desc kirkwood_gating_desc[] __initconst = {
|
||||
{ "ge0", NULL, 0, 0 },
|
||||
{ "pex0", NULL, 2, 0 },
|
||||
{ "usb0", NULL, 3, 0 },
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk/mxs.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
|
|
|
@ -52,8 +52,8 @@ static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
|
|||
u8 shift, u8 width, const char **parent_names, int num_parents)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parent_names, num_parents,
|
||||
CLK_SET_RATE_PARENT, reg, shift, width,
|
||||
0, &mxs_lock);
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
reg, shift, width, 0, &mxs_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *mxs_clk_fixed_factor(const char *name,
|
||||
|
|
|
@ -8,3 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
|
|||
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
|
||||
ifdef CONFIG_COMMON_CLK
|
||||
obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
|
||||
endif
|
||||
|
|
|
@ -62,7 +62,7 @@ static struct syscore_ops exynos_audss_clk_syscore_ops = {
|
|||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
/* register exynos_audss clocks */
|
||||
void __init exynos_audss_clk_init(struct device_node *np)
|
||||
static void __init exynos_audss_clk_init(struct device_node *np)
|
||||
{
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
|
@ -82,11 +82,13 @@ void __init exynos_audss_clk_init(struct device_node *np)
|
|||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
|
||||
clk_table[EXYNOS_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
|
||||
mout_audss_p, ARRAY_SIZE(mout_audss_p), 0,
|
||||
mout_audss_p, ARRAY_SIZE(mout_audss_p),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
reg_base + ASS_CLK_SRC, 0, 1, 0, &lock);
|
||||
|
||||
clk_table[EXYNOS_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s",
|
||||
mout_i2s_p, ARRAY_SIZE(mout_i2s_p), 0,
|
||||
mout_i2s_p, ARRAY_SIZE(mout_i2s_p),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
reg_base + ASS_CLK_SRC, 2, 2, 0, &lock);
|
||||
|
||||
clk_table[EXYNOS_DOUT_SRP] = clk_register_divider(NULL, "dout_srp",
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <linux/of_address.h>
|
||||
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
/* Exynos4 clock controller register offsets */
|
||||
#define SRC_LEFTBUS 0x4200
|
||||
|
@ -97,12 +96,15 @@
|
|||
#define GATE_IP_PERIL 0xc950
|
||||
#define E4210_GATE_IP_PERIR 0xc960
|
||||
#define GATE_BLOCK 0xc970
|
||||
#define E4X12_MPLL_LOCK 0x10008
|
||||
#define E4X12_MPLL_CON0 0x10108
|
||||
#define SRC_DMC 0x10200
|
||||
#define SRC_MASK_DMC 0x10300
|
||||
#define DIV_DMC0 0x10500
|
||||
#define DIV_DMC1 0x10504
|
||||
#define GATE_IP_DMC 0x10900
|
||||
#define APLL_LOCK 0x14000
|
||||
#define E4210_MPLL_LOCK 0x14008
|
||||
#define APLL_CON0 0x14100
|
||||
#define E4210_MPLL_CON0 0x14108
|
||||
#define SRC_CPU 0x14200
|
||||
|
@ -121,6 +123,12 @@ enum exynos4_soc {
|
|||
EXYNOS4X12,
|
||||
};
|
||||
|
||||
/* list of PLLs to be registered */
|
||||
enum exynos4_plls {
|
||||
apll, mpll, epll, vpll,
|
||||
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
|
||||
|
@ -169,7 +177,7 @@ enum exynos4_clks {
|
|||
gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp,
|
||||
mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp,
|
||||
asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk,
|
||||
spi1_isp_sclk, uart_isp_sclk,
|
||||
spi1_isp_sclk, uart_isp_sclk, tmu_apbif,
|
||||
|
||||
/* mux clocks */
|
||||
mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0,
|
||||
|
@ -187,7 +195,7 @@ enum exynos4_clks {
|
|||
* list of controller registers to be saved and restored during a
|
||||
* suspend/resume cycle.
|
||||
*/
|
||||
static __initdata unsigned long exynos4210_clk_save[] = {
|
||||
static unsigned long exynos4210_clk_save[] __initdata = {
|
||||
E4210_SRC_IMAGE,
|
||||
E4210_SRC_LCD1,
|
||||
E4210_SRC_MASK_LCD1,
|
||||
|
@ -198,7 +206,7 @@ static __initdata unsigned long exynos4210_clk_save[] = {
|
|||
E4210_MPLL_CON0,
|
||||
};
|
||||
|
||||
static __initdata unsigned long exynos4x12_clk_save[] = {
|
||||
static unsigned long exynos4x12_clk_save[] __initdata = {
|
||||
E4X12_GATE_IP_IMAGE,
|
||||
E4X12_GATE_IP_PERIR,
|
||||
E4X12_SRC_CAM1,
|
||||
|
@ -207,7 +215,7 @@ static __initdata unsigned long exynos4x12_clk_save[] = {
|
|||
E4X12_MPLL_CON0,
|
||||
};
|
||||
|
||||
static __initdata unsigned long exynos4_clk_regs[] = {
|
||||
static unsigned long exynos4_clk_regs[] __initdata = {
|
||||
SRC_LEFTBUS,
|
||||
DIV_LEFTBUS,
|
||||
GATE_IP_LEFTBUS,
|
||||
|
@ -338,24 +346,24 @@ PNAME(mout_user_aclk200_p4x12) = {"fin_pll", "div_aclk200", };
|
|||
PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", };
|
||||
|
||||
/* fixed rate clocks generated outside the soc */
|
||||
struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
|
||||
static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
|
||||
FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
|
||||
FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
|
||||
static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
|
||||
FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
|
||||
FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
|
||||
FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
|
||||
};
|
||||
|
||||
struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = {
|
||||
static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = {
|
||||
FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
|
||||
};
|
||||
|
||||
/* list of mux clocks supported in all exynos4 soc's */
|
||||
struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
|
||||
static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
|
||||
MUX_FA(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
|
||||
CLK_SET_RATE_PARENT, 0, "mout_apll"),
|
||||
MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
|
||||
|
@ -367,17 +375,20 @@ struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
|
|||
CLK_SET_RATE_PARENT, 0),
|
||||
MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2),
|
||||
MUX(none, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1),
|
||||
MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"),
|
||||
MUX(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1),
|
||||
MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1),
|
||||
};
|
||||
|
||||
/* list of mux clocks supported in exynos4210 soc */
|
||||
struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
|
||||
static struct samsung_mux_clock exynos4210_mux_early[] __initdata = {
|
||||
MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
|
||||
MUX(none, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1),
|
||||
MUX(none, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1),
|
||||
MUX(none, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1),
|
||||
MUX(none, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1),
|
||||
MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
|
||||
MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1),
|
||||
MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1),
|
||||
MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1),
|
||||
|
@ -385,11 +396,9 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
|
|||
MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1),
|
||||
MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4),
|
||||
MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4),
|
||||
MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "mout_mpll"),
|
||||
MUX_A(mout_core, "mout_core", mout_core_p4210,
|
||||
SRC_CPU, 16, 1, "moutcore"),
|
||||
MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210,
|
||||
SRC_TOP0, 8, 1, "sclk_vpll"),
|
||||
MUX(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1),
|
||||
MUX(mout_core, "mout_core", mout_core_p4210, SRC_CPU, 16, 1),
|
||||
MUX(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1),
|
||||
MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
|
||||
MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4),
|
||||
MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4),
|
||||
|
@ -423,9 +432,9 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
|
|||
};
|
||||
|
||||
/* list of mux clocks supported in exynos4x12 soc */
|
||||
struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
|
||||
MUX_A(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12,
|
||||
SRC_CPU, 24, 1, "mout_mpll"),
|
||||
static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
|
||||
MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12,
|
||||
SRC_CPU, 24, 1),
|
||||
MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
|
||||
MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1),
|
||||
MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12,
|
||||
|
@ -445,12 +454,9 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
|
|||
MUX(none, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1),
|
||||
MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1),
|
||||
MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1),
|
||||
MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p,
|
||||
SRC_DMC, 12, 1, "sclk_mpll"),
|
||||
MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p,
|
||||
SRC_TOP0, 8, 1, "sclk_vpll"),
|
||||
MUX_A(mout_core, "mout_core", mout_core_p4x12,
|
||||
SRC_CPU, 16, 1, "moutcore"),
|
||||
MUX(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_DMC, 12, 1),
|
||||
MUX(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1),
|
||||
MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
|
||||
MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
|
||||
MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
|
||||
MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
|
||||
|
@ -491,7 +497,7 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
|
|||
};
|
||||
|
||||
/* list of divider clocks supported in all exynos4 soc's */
|
||||
struct samsung_div_clock exynos4_div_clks[] __initdata = {
|
||||
static struct samsung_div_clock exynos4_div_clks[] __initdata = {
|
||||
DIV(none, "div_core", "mout_core", DIV_CPU0, 0, 3),
|
||||
DIV(none, "div_core2", "div_core", DIV_CPU0, 28, 3),
|
||||
DIV(none, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
|
||||
|
@ -538,9 +544,8 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
|
|||
DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8),
|
||||
DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
|
||||
DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
|
||||
DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "armclk"),
|
||||
DIV_A(sclk_apll, "sclk_apll", "mout_apll",
|
||||
DIV_CPU0, 24, 3, "sclk_apll"),
|
||||
DIV(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3),
|
||||
DIV(sclk_apll, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
|
||||
DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8,
|
||||
|
@ -554,7 +559,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = {
|
|||
};
|
||||
|
||||
/* list of divider clocks supported in exynos4210 soc */
|
||||
struct samsung_div_clock exynos4210_div_clks[] __initdata = {
|
||||
static struct samsung_div_clock exynos4210_div_clks[] __initdata = {
|
||||
DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3),
|
||||
DIV(sclk_fimg2d, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4),
|
||||
DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4),
|
||||
|
@ -565,7 +570,7 @@ struct samsung_div_clock exynos4210_div_clks[] __initdata = {
|
|||
};
|
||||
|
||||
/* list of divider clocks supported in exynos4x12 soc */
|
||||
struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
|
||||
static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
|
||||
DIV(none, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4),
|
||||
DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4),
|
||||
DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4),
|
||||
|
@ -594,7 +599,7 @@ struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
|
|||
};
|
||||
|
||||
/* list of gate clocks supported in all exynos4 soc's */
|
||||
struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
|
||||
static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
|
||||
/*
|
||||
* After all Exynos4 based platforms are migrated to use device tree,
|
||||
* the device name and clock alias names specified below for some
|
||||
|
@ -629,164 +634,151 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
|
|||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_audio1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE_D(vp, "s5p-mixer", "vp", "aclk160", GATE_IP_TV, 0, 0, 0),
|
||||
GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", GATE_IP_TV, 1, 0, 0),
|
||||
GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0),
|
||||
GATE_A(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0, "timers"),
|
||||
GATE_A(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0, "biu"),
|
||||
GATE_A(usb_host, "usb_host", "aclk133",
|
||||
GATE_IP_FSYS, 12, 0, 0, "usbhost"),
|
||||
GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
|
||||
SRC_MASK_CAM, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
|
||||
GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
|
||||
SRC_MASK_CAM, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
|
||||
GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
|
||||
SRC_MASK_CAM, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
|
||||
GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
|
||||
SRC_MASK_CAM, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
|
||||
GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
|
||||
SRC_MASK_CAM, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
|
||||
GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
|
||||
SRC_MASK_CAM, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
|
||||
GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
|
||||
SRC_MASK_LCD0, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
|
||||
GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc_pre0",
|
||||
SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0,
|
||||
"mmc_busclk.2"),
|
||||
GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc_pre1",
|
||||
SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0,
|
||||
"mmc_busclk.2"),
|
||||
GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc_pre2",
|
||||
SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0,
|
||||
"mmc_busclk.2"),
|
||||
GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc_pre3",
|
||||
SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0,
|
||||
"mmc_busclk.2"),
|
||||
GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc_pre4",
|
||||
SRC_MASK_FSYS, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
|
||||
GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
|
||||
SRC_MASK_PERIL0, 0, CLK_SET_RATE_PARENT,
|
||||
0, "clk_uart_baud0"),
|
||||
GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
|
||||
SRC_MASK_PERIL0, 4, CLK_SET_RATE_PARENT,
|
||||
0, "clk_uart_baud0"),
|
||||
GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
|
||||
SRC_MASK_PERIL0, 8, CLK_SET_RATE_PARENT,
|
||||
0, "clk_uart_baud0"),
|
||||
GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
|
||||
SRC_MASK_PERIL0, 12, CLK_SET_RATE_PARENT,
|
||||
0, "clk_uart_baud0"),
|
||||
GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
|
||||
SRC_MASK_PERIL0, 16, CLK_SET_RATE_PARENT,
|
||||
0, "clk_uart_baud0"),
|
||||
GATE(vp, "vp", "aclk160", GATE_IP_TV, 0, 0, 0),
|
||||
GATE(mixer, "mixer", "aclk160", GATE_IP_TV, 1, 0, 0),
|
||||
GATE(hdmi, "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0),
|
||||
GATE(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0),
|
||||
GATE(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0),
|
||||
GATE(usb_host, "usb_host", "aclk133", GATE_IP_FSYS, 12, 0, 0),
|
||||
GATE(sclk_fimc0, "sclk_fimc0", "div_fimc0", SRC_MASK_CAM, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_fimc1, "sclk_fimc1", "div_fimc1", SRC_MASK_CAM, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_fimc2, "sclk_fimc2", "div_fimc2", SRC_MASK_CAM, 8,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_fimc3, "sclk_fimc3", "div_fimc3", SRC_MASK_CAM, 12,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_csis0, "sclk_csis0", "div_csis0", SRC_MASK_CAM, 24,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_csis1, "sclk_csis1", "div_csis1", SRC_MASK_CAM, 28,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_fimd0, "sclk_fimd0", "div_fimd0", SRC_MASK_LCD0, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_mmc0, "sclk_mmc0", "div_mmc_pre0", SRC_MASK_FSYS, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_mmc1, "sclk_mmc1", "div_mmc_pre1", SRC_MASK_FSYS, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_mmc2, "sclk_mmc2", "div_mmc_pre2", SRC_MASK_FSYS, 8,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_mmc3, "sclk_mmc3", "div_mmc_pre3", SRC_MASK_FSYS, 12,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_mmc4, "sclk_mmc4", "div_mmc_pre4", SRC_MASK_FSYS, 16,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_uart0, "uclk0", "div_uart0", SRC_MASK_PERIL0, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_uart1, "uclk1", "div_uart1", SRC_MASK_PERIL0, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_uart2, "uclk2", "div_uart2", SRC_MASK_PERIL0, 8,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_uart3, "uclk3", "div_uart3", SRC_MASK_PERIL0, 12,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_uart4, "uclk4", "div_uart4", SRC_MASK_PERIL0, 16,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_audio2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0",
|
||||
SRC_MASK_PERIL1, 16, CLK_SET_RATE_PARENT,
|
||||
0, "spi_busclk0"),
|
||||
GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
|
||||
SRC_MASK_PERIL1, 20, CLK_SET_RATE_PARENT,
|
||||
0, "spi_busclk0"),
|
||||
GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
|
||||
SRC_MASK_PERIL1, 24, CLK_SET_RATE_PARENT,
|
||||
0, "spi_busclk0"),
|
||||
GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160",
|
||||
GATE_IP_CAM, 0, 0, 0, "fimc"),
|
||||
GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
|
||||
GATE_IP_CAM, 1, 0, 0, "fimc"),
|
||||
GATE_DA(fimc2, "exynos4-fimc.2", "fimc2", "aclk160",
|
||||
GATE_IP_CAM, 2, 0, 0, "fimc"),
|
||||
GATE_DA(fimc3, "exynos4-fimc.3", "fimc3", "aclk160",
|
||||
GATE_IP_CAM, 3, 0, 0, "fimc"),
|
||||
GATE_DA(csis0, "s5p-mipi-csis.0", "csis0", "aclk160",
|
||||
GATE_IP_CAM, 4, 0, 0, "fimc"),
|
||||
GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160",
|
||||
GATE_IP_CAM, 5, 0, 0, "fimc"),
|
||||
GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
|
||||
GATE_IP_CAM, 7, 0, 0, "sysmmu"),
|
||||
GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
|
||||
GATE_IP_CAM, 8, 0, 0, "sysmmu"),
|
||||
GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
|
||||
GATE_IP_CAM, 9, 0, 0, "sysmmu"),
|
||||
GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
|
||||
GATE_IP_CAM, 10, 0, 0, "sysmmu"),
|
||||
GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
|
||||
GATE_IP_CAM, 11, 0, 0, "sysmmu"),
|
||||
GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0", SRC_MASK_PERIL1, 16,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1", SRC_MASK_PERIL1, 20,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2", SRC_MASK_PERIL1, 24,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(fimc0, "fimc0", "aclk160", GATE_IP_CAM, 0,
|
||||
0, 0),
|
||||
GATE(fimc1, "fimc1", "aclk160", GATE_IP_CAM, 1,
|
||||
0, 0),
|
||||
GATE(fimc2, "fimc2", "aclk160", GATE_IP_CAM, 2,
|
||||
0, 0),
|
||||
GATE(fimc3, "fimc3", "aclk160", GATE_IP_CAM, 3,
|
||||
0, 0),
|
||||
GATE(csis0, "csis0", "aclk160", GATE_IP_CAM, 4,
|
||||
0, 0),
|
||||
GATE(csis1, "csis1", "aclk160", GATE_IP_CAM, 5,
|
||||
0, 0),
|
||||
GATE(smmu_fimc0, "smmu_fimc0", "aclk160", GATE_IP_CAM, 7,
|
||||
0, 0),
|
||||
GATE(smmu_fimc1, "smmu_fimc1", "aclk160", GATE_IP_CAM, 8,
|
||||
0, 0),
|
||||
GATE(smmu_fimc2, "smmu_fimc2", "aclk160", GATE_IP_CAM, 9,
|
||||
0, 0),
|
||||
GATE(smmu_fimc3, "smmu_fimc3", "aclk160", GATE_IP_CAM, 10,
|
||||
0, 0),
|
||||
GATE(smmu_jpeg, "smmu_jpeg", "aclk160", GATE_IP_CAM, 11,
|
||||
0, 0),
|
||||
GATE(pixelasyncm0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0),
|
||||
GATE(pixelasyncm1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0),
|
||||
GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160",
|
||||
GATE_IP_TV, 4, 0, 0, "sysmmu"),
|
||||
GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0, "mfc"),
|
||||
GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl", "aclk100",
|
||||
GATE_IP_MFC, 1, 0, 0, "sysmmu"),
|
||||
GATE_DA(smmu_mfcr, "exynos-sysmmu.1", "smmu_mfcr", "aclk100",
|
||||
GATE_IP_MFC, 2, 0, 0, "sysmmu"),
|
||||
GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160",
|
||||
GATE_IP_LCD0, 0, 0, 0, "fimd"),
|
||||
GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
|
||||
GATE_IP_LCD0, 4, 0, 0, "sysmmu"),
|
||||
GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133",
|
||||
GATE_IP_FSYS, 0, 0, 0, "dma"),
|
||||
GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133",
|
||||
GATE_IP_FSYS, 1, 0, 0, "dma"),
|
||||
GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133",
|
||||
GATE_IP_FSYS, 5, 0, 0, "hsmmc"),
|
||||
GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
|
||||
GATE_IP_FSYS, 6, 0, 0, "hsmmc"),
|
||||
GATE_DA(sdmmc2, "exynos4-sdhci.2", "sdmmc2", "aclk133",
|
||||
GATE_IP_FSYS, 7, 0, 0, "hsmmc"),
|
||||
GATE_DA(sdmmc3, "exynos4-sdhci.3", "sdmmc3", "aclk133",
|
||||
GATE_IP_FSYS, 8, 0, 0, "hsmmc"),
|
||||
GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100",
|
||||
GATE_IP_PERIL, 0, 0, 0, "uart"),
|
||||
GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
|
||||
GATE_IP_PERIL, 1, 0, 0, "uart"),
|
||||
GATE_DA(uart2, "exynos4210-uart.2", "uart2", "aclk100",
|
||||
GATE_IP_PERIL, 2, 0, 0, "uart"),
|
||||
GATE_DA(uart3, "exynos4210-uart.3", "uart3", "aclk100",
|
||||
GATE_IP_PERIL, 3, 0, 0, "uart"),
|
||||
GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100",
|
||||
GATE_IP_PERIL, 4, 0, 0, "uart"),
|
||||
GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100",
|
||||
GATE_IP_PERIL, 6, 0, 0, "i2c"),
|
||||
GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
|
||||
GATE_IP_PERIL, 7, 0, 0, "i2c"),
|
||||
GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2", "aclk100",
|
||||
GATE_IP_PERIL, 8, 0, 0, "i2c"),
|
||||
GATE_DA(i2c3, "s3c2440-i2c.3", "i2c3", "aclk100",
|
||||
GATE_IP_PERIL, 9, 0, 0, "i2c"),
|
||||
GATE_DA(i2c4, "s3c2440-i2c.4", "i2c4", "aclk100",
|
||||
GATE_IP_PERIL, 10, 0, 0, "i2c"),
|
||||
GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100",
|
||||
GATE_IP_PERIL, 11, 0, 0, "i2c"),
|
||||
GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100",
|
||||
GATE_IP_PERIL, 12, 0, 0, "i2c"),
|
||||
GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
|
||||
GATE_IP_PERIL, 13, 0, 0, "i2c"),
|
||||
GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c", "i2c-hdmi", "aclk100",
|
||||
GATE_IP_PERIL, 14, 0, 0, "i2c"),
|
||||
GATE_DA(spi0, "exynos4210-spi.0", "spi0", "aclk100",
|
||||
GATE_IP_PERIL, 16, 0, 0, "spi"),
|
||||
GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100",
|
||||
GATE_IP_PERIL, 17, 0, 0, "spi"),
|
||||
GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
|
||||
GATE_IP_PERIL, 18, 0, 0, "spi"),
|
||||
GATE_DA(i2s1, "samsung-i2s.1", "i2s1", "aclk100",
|
||||
GATE_IP_PERIL, 20, 0, 0, "iis"),
|
||||
GATE_DA(i2s2, "samsung-i2s.2", "i2s2", "aclk100",
|
||||
GATE_IP_PERIL, 21, 0, 0, "iis"),
|
||||
GATE_DA(pcm1, "samsung-pcm.1", "pcm1", "aclk100",
|
||||
GATE_IP_PERIL, 22, 0, 0, "pcm"),
|
||||
GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100",
|
||||
GATE_IP_PERIL, 23, 0, 0, "pcm"),
|
||||
GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100",
|
||||
GATE_IP_PERIL, 26, 0, 0, "spdif"),
|
||||
GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100",
|
||||
GATE_IP_PERIL, 27, 0, 0, "ac97"),
|
||||
GATE(smmu_tv, "smmu_tv", "aclk160", GATE_IP_TV, 4,
|
||||
0, 0),
|
||||
GATE(mfc, "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0),
|
||||
GATE(smmu_mfcl, "smmu_mfcl", "aclk100", GATE_IP_MFC, 1,
|
||||
0, 0),
|
||||
GATE(smmu_mfcr, "smmu_mfcr", "aclk100", GATE_IP_MFC, 2,
|
||||
0, 0),
|
||||
GATE(fimd0, "fimd0", "aclk160", GATE_IP_LCD0, 0,
|
||||
0, 0),
|
||||
GATE(smmu_fimd0, "smmu_fimd0", "aclk160", GATE_IP_LCD0, 4,
|
||||
0, 0),
|
||||
GATE(pdma0, "pdma0", "aclk133", GATE_IP_FSYS, 0,
|
||||
0, 0),
|
||||
GATE(pdma1, "pdma1", "aclk133", GATE_IP_FSYS, 1,
|
||||
0, 0),
|
||||
GATE(sdmmc0, "sdmmc0", "aclk133", GATE_IP_FSYS, 5,
|
||||
0, 0),
|
||||
GATE(sdmmc1, "sdmmc1", "aclk133", GATE_IP_FSYS, 6,
|
||||
0, 0),
|
||||
GATE(sdmmc2, "sdmmc2", "aclk133", GATE_IP_FSYS, 7,
|
||||
0, 0),
|
||||
GATE(sdmmc3, "sdmmc3", "aclk133", GATE_IP_FSYS, 8,
|
||||
0, 0),
|
||||
GATE(uart0, "uart0", "aclk100", GATE_IP_PERIL, 0,
|
||||
0, 0),
|
||||
GATE(uart1, "uart1", "aclk100", GATE_IP_PERIL, 1,
|
||||
0, 0),
|
||||
GATE(uart2, "uart2", "aclk100", GATE_IP_PERIL, 2,
|
||||
0, 0),
|
||||
GATE(uart3, "uart3", "aclk100", GATE_IP_PERIL, 3,
|
||||
0, 0),
|
||||
GATE(uart4, "uart4", "aclk100", GATE_IP_PERIL, 4,
|
||||
0, 0),
|
||||
GATE(i2c0, "i2c0", "aclk100", GATE_IP_PERIL, 6,
|
||||
0, 0),
|
||||
GATE(i2c1, "i2c1", "aclk100", GATE_IP_PERIL, 7,
|
||||
0, 0),
|
||||
GATE(i2c2, "i2c2", "aclk100", GATE_IP_PERIL, 8,
|
||||
0, 0),
|
||||
GATE(i2c3, "i2c3", "aclk100", GATE_IP_PERIL, 9,
|
||||
0, 0),
|
||||
GATE(i2c4, "i2c4", "aclk100", GATE_IP_PERIL, 10,
|
||||
0, 0),
|
||||
GATE(i2c5, "i2c5", "aclk100", GATE_IP_PERIL, 11,
|
||||
0, 0),
|
||||
GATE(i2c6, "i2c6", "aclk100", GATE_IP_PERIL, 12,
|
||||
0, 0),
|
||||
GATE(i2c7, "i2c7", "aclk100", GATE_IP_PERIL, 13,
|
||||
0, 0),
|
||||
GATE(i2c_hdmi, "i2c-hdmi", "aclk100", GATE_IP_PERIL, 14,
|
||||
0, 0),
|
||||
GATE(spi0, "spi0", "aclk100", GATE_IP_PERIL, 16,
|
||||
0, 0),
|
||||
GATE(spi1, "spi1", "aclk100", GATE_IP_PERIL, 17,
|
||||
0, 0),
|
||||
GATE(spi2, "spi2", "aclk100", GATE_IP_PERIL, 18,
|
||||
0, 0),
|
||||
GATE(i2s1, "i2s1", "aclk100", GATE_IP_PERIL, 20,
|
||||
0, 0),
|
||||
GATE(i2s2, "i2s2", "aclk100", GATE_IP_PERIL, 21,
|
||||
0, 0),
|
||||
GATE(pcm1, "pcm1", "aclk100", GATE_IP_PERIL, 22,
|
||||
0, 0),
|
||||
GATE(pcm2, "pcm2", "aclk100", GATE_IP_PERIL, 23,
|
||||
0, 0),
|
||||
GATE(spdif, "spdif", "aclk100", GATE_IP_PERIL, 26,
|
||||
0, 0),
|
||||
GATE(ac97, "ac97", "aclk100", GATE_IP_PERIL, 27,
|
||||
0, 0),
|
||||
};
|
||||
|
||||
/* list of gate clocks supported in exynos4210 soc */
|
||||
struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
|
||||
static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
|
||||
GATE(tvenc, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0),
|
||||
GATE(g2d, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0),
|
||||
GATE(rotator, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0),
|
||||
|
@ -811,17 +803,23 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
|
|||
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0),
|
||||
GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0),
|
||||
GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"),
|
||||
GATE_A(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, 0, 0, "mct"),
|
||||
GATE_A(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
|
||||
GATE_A(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15, 0, 0, "rtc"),
|
||||
GATE_A(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, 0, 0, "keypad"),
|
||||
GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
|
||||
E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
|
||||
GATE(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15,
|
||||
0, 0),
|
||||
GATE(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13,
|
||||
0, 0),
|
||||
GATE(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14,
|
||||
0, 0),
|
||||
GATE(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15,
|
||||
0, 0),
|
||||
GATE(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16,
|
||||
0, 0),
|
||||
GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1", E4210_SRC_MASK_LCD1, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(tmu_apbif, "tmu_apbif", "aclk100", E4210_GATE_IP_PERIR, 17, 0, 0),
|
||||
};
|
||||
|
||||
/* list of gate clocks supported in exynos4x12 soc */
|
||||
struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
||||
static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
||||
GATE(audss, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0),
|
||||
GATE(mdnie0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0),
|
||||
GATE(rotator, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0),
|
||||
|
@ -840,10 +838,11 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
|||
SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(smmu_rotator, "smmu_rotator", "aclk200",
|
||||
E4X12_GATE_IP_IMAGE, 4, 0, 0),
|
||||
GATE_A(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13, 0, 0, "mct"),
|
||||
GATE_A(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0, "rtc"),
|
||||
GATE_A(keyif, "keyif", "aclk100",
|
||||
E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"),
|
||||
GATE(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13,
|
||||
0, 0),
|
||||
GATE(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15,
|
||||
0, 0),
|
||||
GATE(keyif, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0),
|
||||
GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp",
|
||||
E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre",
|
||||
|
@ -860,12 +859,11 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
|||
E4X12_GATE_IP_ISP, 2, 0, 0),
|
||||
GATE(uart_isp_sclk, "uart_isp_sclk", "sclk_uart_isp",
|
||||
E4X12_GATE_IP_ISP, 3, 0, 0),
|
||||
GATE_A(wdt, "watchdog", "aclk100",
|
||||
E4X12_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
|
||||
GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100",
|
||||
E4X12_GATE_IP_MAUDIO, 2, 0, 0, "pcm"),
|
||||
GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100",
|
||||
E4X12_GATE_IP_MAUDIO, 3, 0, 0, "iis"),
|
||||
GATE(wdt, "watchdog", "aclk100", E4X12_GATE_IP_PERIR, 14, 0, 0),
|
||||
GATE(pcm0, "pcm0", "aclk100", E4X12_GATE_IP_MAUDIO, 2,
|
||||
0, 0),
|
||||
GATE(i2s0, "i2s0", "aclk100", E4X12_GATE_IP_MAUDIO, 3,
|
||||
0, 0),
|
||||
GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
|
||||
CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
|
||||
GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
|
||||
|
@ -919,6 +917,21 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
|||
GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
|
||||
CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
|
||||
GATE(g2d, "g2d", "aclk200", GATE_IP_DMC, 23, 0, 0),
|
||||
GATE(tmu_apbif, "tmu_apbif", "aclk100", E4X12_GATE_IP_PERIR, 17, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_clock_alias exynos4_aliases[] __initdata = {
|
||||
ALIAS(mout_core, NULL, "moutcore"),
|
||||
ALIAS(arm_clk, NULL, "armclk"),
|
||||
ALIAS(sclk_apll, NULL, "mout_apll"),
|
||||
};
|
||||
|
||||
static struct samsung_clock_alias exynos4210_aliases[] __initdata = {
|
||||
ALIAS(sclk_mpll, NULL, "mout_mpll"),
|
||||
};
|
||||
|
||||
static struct samsung_clock_alias exynos4x12_aliases[] __initdata = {
|
||||
ALIAS(mout_mpll_user_c, NULL, "mout_mpll"),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -973,36 +986,116 @@ static void __init exynos4_clk_register_finpll(unsigned long xom)
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* This function allows non-dt platforms to specify the clock speed of the
|
||||
* xxti and xusbxti clocks. These clocks are then registered with the specified
|
||||
* clock speed.
|
||||
*/
|
||||
void __init exynos4_clk_register_fixed_ext(unsigned long xxti_f,
|
||||
unsigned long xusbxti_f)
|
||||
{
|
||||
exynos4_fixed_rate_ext_clks[0].fixed_rate = xxti_f;
|
||||
exynos4_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
|
||||
samsung_clk_register_fixed_rate(exynos4_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos4_fixed_rate_ext_clks));
|
||||
}
|
||||
|
||||
static __initdata struct of_device_id ext_clk_match[] = {
|
||||
static struct of_device_id ext_clk_match[] __initdata = {
|
||||
{ .compatible = "samsung,clock-xxti", .data = (void *)0, },
|
||||
{ .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
|
||||
{},
|
||||
};
|
||||
|
||||
/* register exynos4 clocks */
|
||||
void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom)
|
||||
{
|
||||
struct clk *apll, *mpll, *epll, *vpll;
|
||||
/* PLLs PMS values */
|
||||
static struct samsung_pll_rate_table exynos4210_apll_rates[] __initdata = {
|
||||
PLL_45XX_RATE(1200000000, 150, 3, 1, 28),
|
||||
PLL_45XX_RATE(1000000000, 250, 6, 1, 28),
|
||||
PLL_45XX_RATE( 800000000, 200, 6, 1, 28),
|
||||
PLL_45XX_RATE( 666857142, 389, 14, 1, 13),
|
||||
PLL_45XX_RATE( 600000000, 100, 4, 1, 13),
|
||||
PLL_45XX_RATE( 533000000, 533, 24, 1, 5),
|
||||
PLL_45XX_RATE( 500000000, 250, 6, 2, 28),
|
||||
PLL_45XX_RATE( 400000000, 200, 6, 2, 28),
|
||||
PLL_45XX_RATE( 200000000, 200, 6, 3, 28),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
if (np) {
|
||||
static struct samsung_pll_rate_table exynos4210_epll_rates[] __initdata = {
|
||||
PLL_4600_RATE(192000000, 48, 3, 1, 0, 0),
|
||||
PLL_4600_RATE(180633605, 45, 3, 1, 10381, 0),
|
||||
PLL_4600_RATE(180000000, 45, 3, 1, 0, 0),
|
||||
PLL_4600_RATE( 73727996, 73, 3, 3, 47710, 1),
|
||||
PLL_4600_RATE( 67737602, 90, 4, 3, 20762, 1),
|
||||
PLL_4600_RATE( 49151992, 49, 3, 3, 9961, 0),
|
||||
PLL_4600_RATE( 45158401, 45, 3, 3, 10381, 0),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4210_vpll_rates[] __initdata = {
|
||||
PLL_4650_RATE(360000000, 44, 3, 0, 1024, 0, 14, 0),
|
||||
PLL_4650_RATE(324000000, 53, 2, 1, 1024, 1, 1, 1),
|
||||
PLL_4650_RATE(259617187, 63, 3, 1, 1950, 0, 20, 1),
|
||||
PLL_4650_RATE(110000000, 53, 3, 2, 2048, 0, 17, 0),
|
||||
PLL_4650_RATE( 55360351, 53, 3, 3, 2417, 0, 17, 0),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4x12_apll_rates[] __initdata = {
|
||||
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),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4x12_epll_rates[] __initdata = {
|
||||
PLL_36XX_RATE(192000000, 48, 3, 1, 0),
|
||||
PLL_36XX_RATE(180633605, 45, 3, 1, 10381),
|
||||
PLL_36XX_RATE(180000000, 45, 3, 1, 0),
|
||||
PLL_36XX_RATE( 73727996, 73, 3, 3, 47710),
|
||||
PLL_36XX_RATE( 67737602, 90, 4, 3, 20762),
|
||||
PLL_36XX_RATE( 49151992, 49, 3, 3, 9961),
|
||||
PLL_36XX_RATE( 45158401, 45, 3, 3, 10381),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initdata = {
|
||||
PLL_36XX_RATE(533000000, 133, 3, 1, 16384),
|
||||
PLL_36XX_RATE(440000000, 110, 3, 1, 0),
|
||||
PLL_36XX_RATE(350000000, 175, 3, 2, 0),
|
||||
PLL_36XX_RATE(266000000, 133, 3, 2, 0),
|
||||
PLL_36XX_RATE(160000000, 160, 3, 3, 0),
|
||||
PLL_36XX_RATE(106031250, 53, 3, 2, 1024),
|
||||
PLL_36XX_RATE( 53015625, 53, 3, 3, 1024),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos4210_plls[nr_plls] __initdata = {
|
||||
[apll] = PLL_A(pll_4508, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
|
||||
APLL_CON0, "fout_apll", NULL),
|
||||
[mpll] = PLL_A(pll_4508, fout_mpll, "fout_mpll", "fin_pll",
|
||||
E4210_MPLL_LOCK, E4210_MPLL_CON0, "fout_mpll", NULL),
|
||||
[epll] = PLL_A(pll_4600, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
||||
EPLL_CON0, "fout_epll", NULL),
|
||||
[vpll] = PLL_A(pll_4650c, fout_vpll, "fout_vpll", "mout_vpllsrc",
|
||||
VPLL_LOCK, VPLL_CON0, "fout_vpll", NULL),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
|
||||
[apll] = PLL(pll_35xx, fout_apll, "fout_apll", "fin_pll",
|
||||
APLL_LOCK, APLL_CON0, NULL),
|
||||
[mpll] = PLL(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
|
||||
E4X12_MPLL_LOCK, E4X12_MPLL_CON0, NULL),
|
||||
[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll",
|
||||
EPLL_LOCK, EPLL_CON0, NULL),
|
||||
[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll",
|
||||
VPLL_LOCK, VPLL_CON0, NULL),
|
||||
};
|
||||
|
||||
/* register exynos4 clocks */
|
||||
static void __init exynos4_clk_init(struct device_node *np,
|
||||
enum exynos4_soc exynos4_soc,
|
||||
void __iomem *reg_base, unsigned long xom)
|
||||
{
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base)
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
}
|
||||
|
||||
if (exynos4_soc == EXYNOS4210)
|
||||
samsung_clk_init(np, reg_base, nr_clks,
|
||||
|
@ -1013,7 +1106,6 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
|
|||
exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
|
||||
exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save));
|
||||
|
||||
if (np)
|
||||
samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
|
||||
ext_clk_match);
|
||||
|
@ -1021,29 +1113,35 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
|
|||
exynos4_clk_register_finpll(xom);
|
||||
|
||||
if (exynos4_soc == EXYNOS4210) {
|
||||
apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll",
|
||||
reg_base + APLL_CON0, pll_4508);
|
||||
mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll",
|
||||
reg_base + E4210_MPLL_CON0, pll_4508);
|
||||
epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll",
|
||||
reg_base + EPLL_CON0, pll_4600);
|
||||
vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
|
||||
reg_base + VPLL_CON0, pll_4650c);
|
||||
} else {
|
||||
apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
|
||||
reg_base + APLL_CON0);
|
||||
mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
|
||||
reg_base + E4X12_MPLL_CON0);
|
||||
epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
|
||||
reg_base + EPLL_CON0);
|
||||
vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
|
||||
reg_base + VPLL_CON0);
|
||||
samsung_clk_register_mux(exynos4210_mux_early,
|
||||
ARRAY_SIZE(exynos4210_mux_early));
|
||||
|
||||
if (_get_rate("fin_pll") == 24000000) {
|
||||
exynos4210_plls[apll].rate_table =
|
||||
exynos4210_apll_rates;
|
||||
exynos4210_plls[epll].rate_table =
|
||||
exynos4210_epll_rates;
|
||||
}
|
||||
|
||||
samsung_clk_add_lookup(apll, fout_apll);
|
||||
samsung_clk_add_lookup(mpll, fout_mpll);
|
||||
samsung_clk_add_lookup(epll, fout_epll);
|
||||
samsung_clk_add_lookup(vpll, fout_vpll);
|
||||
if (_get_rate("mout_vpllsrc") == 24000000)
|
||||
exynos4210_plls[vpll].rate_table =
|
||||
exynos4210_vpll_rates;
|
||||
|
||||
samsung_clk_register_pll(exynos4210_plls,
|
||||
ARRAY_SIZE(exynos4210_plls), reg_base);
|
||||
} else {
|
||||
if (_get_rate("fin_pll") == 24000000) {
|
||||
exynos4x12_plls[apll].rate_table =
|
||||
exynos4x12_apll_rates;
|
||||
exynos4x12_plls[epll].rate_table =
|
||||
exynos4x12_epll_rates;
|
||||
exynos4x12_plls[vpll].rate_table =
|
||||
exynos4x12_vpll_rates;
|
||||
}
|
||||
|
||||
samsung_clk_register_pll(exynos4x12_plls,
|
||||
ARRAY_SIZE(exynos4x12_plls), reg_base);
|
||||
}
|
||||
|
||||
samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
|
||||
ARRAY_SIZE(exynos4_fixed_rate_clks));
|
||||
|
@ -1063,6 +1161,8 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
|
|||
ARRAY_SIZE(exynos4210_div_clks));
|
||||
samsung_clk_register_gate(exynos4210_gate_clks,
|
||||
ARRAY_SIZE(exynos4210_gate_clks));
|
||||
samsung_clk_register_alias(exynos4210_aliases,
|
||||
ARRAY_SIZE(exynos4210_aliases));
|
||||
} else {
|
||||
samsung_clk_register_mux(exynos4x12_mux_clks,
|
||||
ARRAY_SIZE(exynos4x12_mux_clks));
|
||||
|
@ -1070,14 +1170,19 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
|
|||
ARRAY_SIZE(exynos4x12_div_clks));
|
||||
samsung_clk_register_gate(exynos4x12_gate_clks,
|
||||
ARRAY_SIZE(exynos4x12_gate_clks));
|
||||
samsung_clk_register_alias(exynos4x12_aliases,
|
||||
ARRAY_SIZE(exynos4x12_aliases));
|
||||
}
|
||||
|
||||
samsung_clk_register_alias(exynos4_aliases,
|
||||
ARRAY_SIZE(exynos4_aliases));
|
||||
|
||||
pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
|
||||
"\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
|
||||
exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
|
||||
_get_rate("sclk_apll"), _get_rate("mout_mpll"),
|
||||
_get_rate("sclk_apll"), _get_rate("sclk_mpll"),
|
||||
_get_rate("sclk_epll"), _get_rate("sclk_vpll"),
|
||||
_get_rate("armclk"));
|
||||
_get_rate("arm_clk"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,11 +17,22 @@
|
|||
#include <linux/of_address.h>
|
||||
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#define APLL_LOCK 0x0
|
||||
#define APLL_CON0 0x100
|
||||
#define SRC_CPU 0x200
|
||||
#define DIV_CPU0 0x500
|
||||
#define MPLL_LOCK 0x4000
|
||||
#define MPLL_CON0 0x4100
|
||||
#define SRC_CORE1 0x4204
|
||||
#define CPLL_LOCK 0x10020
|
||||
#define EPLL_LOCK 0x10030
|
||||
#define VPLL_LOCK 0x10040
|
||||
#define GPLL_LOCK 0x10050
|
||||
#define CPLL_CON0 0x10120
|
||||
#define EPLL_CON0 0x10130
|
||||
#define VPLL_CON0 0x10140
|
||||
#define GPLL_CON0 0x10150
|
||||
#define SRC_TOP0 0x10210
|
||||
#define SRC_TOP2 0x10218
|
||||
#define SRC_GSCL 0x10220
|
||||
|
@ -59,9 +70,18 @@
|
|||
#define GATE_IP_FSYS 0x10944
|
||||
#define GATE_IP_PERIC 0x10950
|
||||
#define GATE_IP_PERIS 0x10960
|
||||
#define BPLL_LOCK 0x20010
|
||||
#define BPLL_CON0 0x20110
|
||||
#define SRC_CDREX 0x20200
|
||||
#define PLL_DIV2_SEL 0x20a24
|
||||
#define GATE_IP_DISP1 0x10928
|
||||
#define GATE_IP_ACP 0x10000
|
||||
|
||||
/* list of PLLs to be registered */
|
||||
enum exynos5250_plls {
|
||||
apll, mpll, cpll, epll, vpll, gpll, bpll,
|
||||
nr_plls /* number of PLLs */
|
||||
};
|
||||
|
||||
/*
|
||||
* Let each supported clock get a unique id. This id is used to lookup the clock
|
||||
|
@ -79,7 +99,8 @@ enum exynos5250_clks {
|
|||
none,
|
||||
|
||||
/* core clocks */
|
||||
fin_pll,
|
||||
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,
|
||||
|
@ -87,7 +108,7 @@ enum exynos5250_clks {
|
|||
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,
|
||||
div_i2s1, div_i2s2, sclk_hdmiphy,
|
||||
|
||||
/* gate clocks */
|
||||
gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0,
|
||||
|
@ -99,7 +120,10 @@ enum exynos5250_clks {
|
|||
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,
|
||||
wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi, g2d,
|
||||
|
||||
/* mux clocks */
|
||||
mout_hdmi = 1024,
|
||||
|
||||
nr_clks,
|
||||
};
|
||||
|
@ -108,7 +132,7 @@ enum exynos5250_clks {
|
|||
* list of controller registers to be saved and restored during a
|
||||
* suspend/resume cycle.
|
||||
*/
|
||||
static __initdata unsigned long exynos5250_clk_regs[] = {
|
||||
static unsigned long exynos5250_clk_regs[] __initdata = {
|
||||
SRC_CPU,
|
||||
DIV_CPU0,
|
||||
SRC_CORE1,
|
||||
|
@ -152,6 +176,7 @@ static __initdata unsigned long exynos5250_clk_regs[] = {
|
|||
SRC_CDREX,
|
||||
PLL_DIV2_SEL,
|
||||
GATE_IP_DISP1,
|
||||
GATE_IP_ACP,
|
||||
};
|
||||
|
||||
/* list of all parent clock list */
|
||||
|
@ -191,31 +216,34 @@ PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
|
|||
"spdif_extclk" };
|
||||
|
||||
/* fixed rate clocks generated outside the soc */
|
||||
struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = {
|
||||
static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = {
|
||||
FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = {
|
||||
FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
|
||||
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),
|
||||
};
|
||||
|
||||
struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
|
||||
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),
|
||||
};
|
||||
|
||||
struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
|
||||
static struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
|
||||
MUX(none, "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, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 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),
|
||||
|
@ -232,7 +260,7 @@ struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
|
|||
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(none, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),
|
||||
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),
|
||||
|
@ -254,7 +282,7 @@ struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
|
|||
MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4),
|
||||
};
|
||||
|
||||
struct samsung_div_clock exynos5250_div_clks[] __initdata = {
|
||||
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),
|
||||
|
@ -314,7 +342,7 @@ struct samsung_div_clock exynos5250_div_clks[] __initdata = {
|
|||
DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
|
||||
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),
|
||||
|
@ -461,20 +489,60 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
|
|||
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", "aclk200", GATE_IP_DISP1, 5, 0, 0),
|
||||
GATE(hdmi, "hdmi", "aclk200", GATE_IP_DISP1, 6, 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),
|
||||
};
|
||||
|
||||
static __initdata struct of_device_id ext_clk_match[] = {
|
||||
static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = {
|
||||
/* sorted in descending order */
|
||||
/* PLL_36XX_RATE(rate, m, p, s, k) */
|
||||
PLL_36XX_RATE(266000000, 266, 3, 3, 0),
|
||||
/* Not in UM, but need for eDP on snow */
|
||||
PLL_36XX_RATE(70500000, 94, 2, 4, 0),
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = {
|
||||
/* sorted in descending order */
|
||||
/* PLL_36XX_RATE(rate, m, p, s, k) */
|
||||
PLL_36XX_RATE(192000000, 64, 2, 2, 0),
|
||||
PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
|
||||
PLL_36XX_RATE(180000000, 90, 3, 2, 0),
|
||||
PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
|
||||
PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
|
||||
PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
|
||||
PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
|
||||
PLL_36XX_RATE(32768000, 131, 3, 5, 4719),
|
||||
{ },
|
||||
};
|
||||
|
||||
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,
|
||||
BPLL_CON0, NULL),
|
||||
[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
|
||||
GPLL_CON0, NULL),
|
||||
[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
|
||||
CPLL_CON0, NULL),
|
||||
[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
||||
EPLL_CON0, NULL),
|
||||
[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
|
||||
VPLL_LOCK, VPLL_CON0, NULL),
|
||||
};
|
||||
|
||||
static struct of_device_id ext_clk_match[] __initdata = {
|
||||
{ .compatible = "samsung,clock-xxti", .data = (void *)0, },
|
||||
{ },
|
||||
};
|
||||
|
||||
/* register exynox5250 clocks */
|
||||
void __init exynos5250_clk_init(struct device_node *np)
|
||||
static void __init exynos5250_clk_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
|
||||
|
||||
if (np) {
|
||||
reg_base = of_iomap(np, 0);
|
||||
|
@ -490,22 +558,17 @@ void __init exynos5250_clk_init(struct device_node *np)
|
|||
samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
|
||||
ext_clk_match);
|
||||
samsung_clk_register_mux(exynos5250_pll_pmux_clks,
|
||||
ARRAY_SIZE(exynos5250_pll_pmux_clks));
|
||||
|
||||
apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
|
||||
reg_base + 0x100);
|
||||
mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
|
||||
reg_base + 0x4100);
|
||||
bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
|
||||
reg_base + 0x20110);
|
||||
gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
|
||||
reg_base + 0x10150);
|
||||
cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
|
||||
reg_base + 0x10120);
|
||||
epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
|
||||
reg_base + 0x10130);
|
||||
vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
|
||||
reg_base + 0x10140);
|
||||
if (_get_rate("fin_pll") == 24 * MHZ)
|
||||
exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
|
||||
|
||||
if (_get_rate("mout_vpllsrc") == 24 * MHZ)
|
||||
exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl;
|
||||
|
||||
samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
|
||||
reg_base);
|
||||
samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
|
||||
ARRAY_SIZE(exynos5250_fixed_rate_clks));
|
||||
samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
|
||||
|
|
|
@ -17,13 +17,30 @@
|
|||
#include <linux/of_address.h>
|
||||
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#define APLL_LOCK 0x0
|
||||
#define APLL_CON0 0x100
|
||||
#define SRC_CPU 0x200
|
||||
#define DIV_CPU0 0x500
|
||||
#define DIV_CPU1 0x504
|
||||
#define GATE_BUS_CPU 0x700
|
||||
#define GATE_SCLK_CPU 0x800
|
||||
#define CPLL_LOCK 0x10020
|
||||
#define DPLL_LOCK 0x10030
|
||||
#define EPLL_LOCK 0x10040
|
||||
#define RPLL_LOCK 0x10050
|
||||
#define IPLL_LOCK 0x10060
|
||||
#define SPLL_LOCK 0x10070
|
||||
#define VPLL_LOCK 0x10070
|
||||
#define MPLL_LOCK 0x10090
|
||||
#define CPLL_CON0 0x10120
|
||||
#define DPLL_CON0 0x10128
|
||||
#define EPLL_CON0 0x10130
|
||||
#define RPLL_CON0 0x10140
|
||||
#define IPLL_CON0 0x10150
|
||||
#define SPLL_CON0 0x10160
|
||||
#define VPLL_CON0 0x10170
|
||||
#define MPLL_CON0 0x10180
|
||||
#define SRC_TOP0 0x10200
|
||||
#define SRC_TOP1 0x10204
|
||||
#define SRC_TOP2 0x10208
|
||||
|
@ -75,15 +92,27 @@
|
|||
#define GATE_TOP_SCLK_MAU 0x1083c
|
||||
#define GATE_TOP_SCLK_FSYS 0x10840
|
||||
#define GATE_TOP_SCLK_PERIC 0x10850
|
||||
#define BPLL_LOCK 0x20010
|
||||
#define BPLL_CON0 0x20110
|
||||
#define SRC_CDREX 0x20200
|
||||
#define KPLL_LOCK 0x28000
|
||||
#define KPLL_CON0 0x28100
|
||||
#define SRC_KFC 0x28200
|
||||
#define DIV_KFC0 0x28500
|
||||
|
||||
/* list of PLLs */
|
||||
enum exynos5420_plls {
|
||||
apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll,
|
||||
bpll, kpll,
|
||||
nr_plls /* number of PLLs */
|
||||
};
|
||||
|
||||
enum exynos5420_clks {
|
||||
none,
|
||||
|
||||
/* core clocks */
|
||||
fin_pll,
|
||||
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,
|
||||
|
@ -91,7 +120,7 @@ enum exynos5420_clks {
|
|||
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_pwm, sclk_gscl_wa, sclk_gscl_wb, sclk_hdmiphy,
|
||||
|
||||
/* gate clocks */
|
||||
aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3,
|
||||
|
@ -109,7 +138,13 @@ enum exynos5420_clks {
|
|||
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_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d, smmu_mixer,
|
||||
|
||||
/* mux clocks */
|
||||
mout_hdmi = 640,
|
||||
|
||||
/* divider clocks */
|
||||
dout_pixel = 768,
|
||||
|
||||
nr_clks,
|
||||
};
|
||||
|
@ -118,7 +153,7 @@ enum exynos5420_clks {
|
|||
* list of controller registers to be saved and restored during a
|
||||
* suspend/resume cycle.
|
||||
*/
|
||||
static __initdata unsigned long exynos5420_clk_regs[] = {
|
||||
static unsigned long exynos5420_clk_regs[] __initdata = {
|
||||
SRC_CPU,
|
||||
DIV_CPU0,
|
||||
DIV_CPU1,
|
||||
|
@ -257,29 +292,29 @@ PNAME(audio2_p) = { "fin_pll", "cdclk2", "sclk_dpll", "sclk_mpll",
|
|||
"sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
|
||||
PNAME(spdif_p) = { "fin_pll", "dout_audio0", "dout_audio1", "dout_audio2",
|
||||
"spdif_extclk", "sclk_ipll", "sclk_epll", "sclk_rpll" };
|
||||
PNAME(hdmi_p) = { "sclk_hdmiphy", "dout_hdmi_pixel" };
|
||||
PNAME(hdmi_p) = { "dout_hdmi_pixel", "sclk_hdmiphy" };
|
||||
PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll",
|
||||
"sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" };
|
||||
|
||||
/* fixed rate clocks generated outside the soc */
|
||||
struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = {
|
||||
static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = {
|
||||
FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = {
|
||||
FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
|
||||
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),
|
||||
};
|
||||
|
||||
struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = {
|
||||
static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = {
|
||||
FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0),
|
||||
};
|
||||
|
||||
struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
|
||||
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),
|
||||
|
@ -371,7 +406,7 @@ struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
|
|||
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(none, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1),
|
||||
MUX(mout_hdmi, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1),
|
||||
|
||||
/* MAU Block */
|
||||
MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3),
|
||||
|
@ -399,7 +434,7 @@ struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
|
|||
MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3),
|
||||
};
|
||||
|
||||
struct samsung_div_clock exynos5420_div_clks[] __initdata = {
|
||||
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),
|
||||
|
@ -431,7 +466,7 @@ struct samsung_div_clock exynos5420_div_clks[] __initdata = {
|
|||
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(none, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
|
||||
DIV(dout_pixel, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4),
|
||||
|
||||
/* Audio Block */
|
||||
DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
|
||||
|
@ -479,7 +514,7 @@ struct samsung_div_clock exynos5420_div_clks[] __initdata = {
|
|||
DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8),
|
||||
};
|
||||
|
||||
struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
|
||||
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"),
|
||||
|
||||
|
@ -696,19 +731,43 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
|
|||
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),
|
||||
};
|
||||
|
||||
static __initdata struct of_device_id ext_clk_match[] = {
|
||||
static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = {
|
||||
[apll] = PLL(pll_2550, 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,
|
||||
DPLL_CON0, NULL),
|
||||
[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
|
||||
EPLL_CON0, NULL),
|
||||
[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
|
||||
RPLL_CON0, NULL),
|
||||
[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
|
||||
IPLL_CON0, NULL),
|
||||
[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
|
||||
SPLL_CON0, NULL),
|
||||
[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
|
||||
VPLL_CON0, NULL),
|
||||
[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
|
||||
MPLL_CON0, NULL),
|
||||
[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
|
||||
BPLL_CON0, NULL),
|
||||
[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
|
||||
KPLL_CON0, NULL),
|
||||
};
|
||||
|
||||
static struct of_device_id ext_clk_match[] __initdata = {
|
||||
{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
|
||||
{ },
|
||||
};
|
||||
|
||||
/* register exynos5420 clocks */
|
||||
void __init exynos5420_clk_init(struct device_node *np)
|
||||
static void __init exynos5420_clk_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
|
||||
struct clk *rpll, *spll, *vpll;
|
||||
|
||||
if (np) {
|
||||
reg_base = of_iomap(np, 0);
|
||||
|
@ -724,30 +783,8 @@ void __init exynos5420_clk_init(struct device_node *np)
|
|||
samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
|
||||
ext_clk_match);
|
||||
|
||||
apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
|
||||
reg_base + 0x100);
|
||||
bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
|
||||
reg_base + 0x20110);
|
||||
cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
|
||||
reg_base + 0x10120);
|
||||
dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
|
||||
reg_base + 0x10128);
|
||||
epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
|
||||
reg_base + 0x10130);
|
||||
ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
|
||||
reg_base + 0x10150);
|
||||
kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
|
||||
reg_base + 0x28100);
|
||||
mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
|
||||
reg_base + 0x10180);
|
||||
rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
|
||||
reg_base + 0x10140);
|
||||
spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
|
||||
reg_base + 0x10160);
|
||||
vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
|
||||
reg_base + 0x10170);
|
||||
|
||||
samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
|
||||
reg_base);
|
||||
samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
|
||||
ARRAY_SIZE(exynos5420_fixed_rate_clks));
|
||||
samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
|
||||
|
|
|
@ -41,12 +41,12 @@ PNAME(mout_armclk_p) = { "cplla", "cpllb" };
|
|||
PNAME(mout_spi_p) = { "div125", "div200" };
|
||||
|
||||
/* fixed rate clocks generated outside the soc */
|
||||
struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = {
|
||||
static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = {
|
||||
FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0),
|
||||
};
|
||||
|
||||
/* fixed rate clocks */
|
||||
struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
|
||||
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),
|
||||
|
@ -55,26 +55,26 @@ struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
|
|||
};
|
||||
|
||||
/* fixed factor clocks */
|
||||
struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = {
|
||||
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),
|
||||
};
|
||||
|
||||
/* mux clocks */
|
||||
struct samsung_mux_clock exynos5440_mux_clks[] __initdata = {
|
||||
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,
|
||||
CPU_CLK_STATUS, 0, 1, "armclk"),
|
||||
};
|
||||
|
||||
/* divider clocks */
|
||||
struct samsung_div_clock exynos5440_div_clks[] __initdata = {
|
||||
static struct samsung_div_clock exynos5440_div_clks[] __initdata = {
|
||||
DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
|
||||
};
|
||||
|
||||
/* gate clocks */
|
||||
struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
|
||||
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),
|
||||
|
@ -97,13 +97,13 @@ struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
|
|||
GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
|
||||
};
|
||||
|
||||
static __initdata struct of_device_id ext_clk_match[] = {
|
||||
static struct of_device_id ext_clk_match[] __initdata = {
|
||||
{ .compatible = "samsung,clock-xtal", .data = (void *)0, },
|
||||
{},
|
||||
};
|
||||
|
||||
/* register exynos5440 clocks */
|
||||
void __init exynos5440_clk_init(struct device_node *np)
|
||||
static void __init exynos5440_clk_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
|
||||
|
@ -132,7 +132,7 @@ void __init exynos5440_clk_init(struct device_node *np)
|
|||
samsung_clk_register_gate(exynos5440_gate_clks,
|
||||
ARRAY_SIZE(exynos5440_gate_clks));
|
||||
|
||||
pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("armclk"));
|
||||
pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk"));
|
||||
pr_info("exynos5440 clock initialization complete\n");
|
||||
}
|
||||
CLK_OF_DECLARE(exynos5440_clk, "samsung,exynos5440-clock", exynos5440_clk_init);
|
||||
|
|
|
@ -10,31 +10,73 @@
|
|||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#define PLL_TIMEOUT_MS 10
|
||||
|
||||
struct samsung_clk_pll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *lock_reg;
|
||||
void __iomem *con_reg;
|
||||
enum samsung_pll_type type;
|
||||
unsigned int rate_count;
|
||||
const struct samsung_pll_rate_table *rate_table;
|
||||
};
|
||||
|
||||
#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
|
||||
|
||||
static const struct samsung_pll_rate_table *samsung_get_pll_settings(
|
||||
struct samsung_clk_pll *pll, unsigned long rate)
|
||||
{
|
||||
const struct samsung_pll_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
if (rate == rate_table[i].rate)
|
||||
return &rate_table[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static long samsung_pll_round_rate(struct clk_hw *hw,
|
||||
unsigned long drate, unsigned long *prate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
const struct samsung_pll_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
/* Assumming rate_table is in descending order */
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
if (drate >= rate_table[i].rate)
|
||||
return rate_table[i].rate;
|
||||
}
|
||||
|
||||
/* return minimum supported value */
|
||||
return rate_table[i - 1].rate;
|
||||
}
|
||||
|
||||
/*
|
||||
* PLL35xx Clock Type
|
||||
*/
|
||||
/* Maximum lock time can be 270 * PDIV cycles */
|
||||
#define PLL35XX_LOCK_FACTOR (270)
|
||||
|
||||
#define PLL35XX_MDIV_MASK (0x3FF)
|
||||
#define PLL35XX_PDIV_MASK (0x3F)
|
||||
#define PLL35XX_SDIV_MASK (0x7)
|
||||
#define PLL35XX_LOCK_STAT_MASK (0x1)
|
||||
#define PLL35XX_MDIV_SHIFT (16)
|
||||
#define PLL35XX_PDIV_SHIFT (8)
|
||||
#define PLL35XX_SDIV_SHIFT (0)
|
||||
|
||||
struct samsung_clk_pll35xx {
|
||||
struct clk_hw hw;
|
||||
const void __iomem *con_reg;
|
||||
};
|
||||
|
||||
#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
|
||||
#define PLL35XX_LOCK_STAT_SHIFT (29)
|
||||
|
||||
static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
|
@ -49,48 +91,80 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
|
|||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static inline bool samsung_pll35xx_mp_change(
|
||||
const struct samsung_pll_rate_table *rate, u32 pll_con)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv;
|
||||
|
||||
old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
|
||||
old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
|
||||
|
||||
return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
|
||||
}
|
||||
|
||||
static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
u32 tmp;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, __clk_get_name(hw->clk));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
|
||||
if (!(samsung_pll35xx_mp_change(rate, tmp))) {
|
||||
/* If only s change, change just s value only*/
|
||||
tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
|
||||
tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
|
||||
pll->lock_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
|
||||
(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
|
||||
(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
|
||||
tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL35XX_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL35XX_SDIV_SHIFT);
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
|
||||
/* wait_lock_time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
|
||||
<< PLL35XX_LOCK_STAT_SHIFT)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll35xx_clk_ops = {
|
||||
.recalc_rate = samsung_pll35xx_recalc_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.set_rate = samsung_pll35xx_set_rate,
|
||||
};
|
||||
|
||||
struct clk * __init samsung_clk_register_pll35xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg)
|
||||
{
|
||||
struct samsung_clk_pll35xx *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll) {
|
||||
pr_err("%s: could not allocate pll clk %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
init.name = name;
|
||||
init.ops = &samsung_pll35xx_clk_ops;
|
||||
init.flags = CLK_GET_RATE_NOCACHE;
|
||||
init.parent_names = &pname;
|
||||
init.num_parents = 1;
|
||||
|
||||
pll->hw.init = &init;
|
||||
pll->con_reg = con_reg;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll clock %s\n", __func__,
|
||||
name);
|
||||
kfree(pll);
|
||||
}
|
||||
|
||||
if (clk_register_clkdev(clk, name, NULL))
|
||||
pr_err("%s: failed to register lookup for %s", __func__, name);
|
||||
|
||||
return clk;
|
||||
}
|
||||
static const struct clk_ops samsung_pll35xx_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll35xx_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL36xx Clock Type
|
||||
*/
|
||||
/* Maximum lock time can be 3000 * PDIV cycles */
|
||||
#define PLL36XX_LOCK_FACTOR (3000)
|
||||
|
||||
#define PLL36XX_KDIV_MASK (0xFFFF)
|
||||
#define PLL36XX_MDIV_MASK (0x1FF)
|
||||
|
@ -99,18 +173,13 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
|
|||
#define PLL36XX_MDIV_SHIFT (16)
|
||||
#define PLL36XX_PDIV_SHIFT (8)
|
||||
#define PLL36XX_SDIV_SHIFT (0)
|
||||
|
||||
struct samsung_clk_pll36xx {
|
||||
struct clk_hw hw;
|
||||
const void __iomem *con_reg;
|
||||
};
|
||||
|
||||
#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
|
||||
#define PLL36XX_KDIV_SHIFT (0)
|
||||
#define PLL36XX_LOCK_STAT_SHIFT (29)
|
||||
|
||||
static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
|
||||
s16 kdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
@ -129,68 +198,102 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
|
|||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static inline bool samsung_pll36xx_mpk_change(
|
||||
const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv, old_kdiv;
|
||||
|
||||
old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
|
||||
old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
|
||||
old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
|
||||
|
||||
return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
|
||||
rate->kdiv != old_kdiv);
|
||||
}
|
||||
|
||||
static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 tmp, pll_con0, pll_con1;
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, __clk_get_name(hw->clk));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con1 = __raw_readl(pll->con_reg + 4);
|
||||
|
||||
if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
|
||||
/* If only s change, change just s value only*/
|
||||
pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
|
||||
pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
|
||||
__raw_writel(pll_con0, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
|
||||
(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
|
||||
(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
|
||||
pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL36XX_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL36XX_SDIV_SHIFT);
|
||||
__raw_writel(pll_con0, pll->con_reg);
|
||||
|
||||
pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
|
||||
pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
|
||||
__raw_writel(pll_con1, pll->con_reg + 4);
|
||||
|
||||
/* wait_lock_time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll36xx_clk_ops = {
|
||||
.recalc_rate = samsung_pll36xx_recalc_rate,
|
||||
.set_rate = samsung_pll36xx_set_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
};
|
||||
|
||||
struct clk * __init samsung_clk_register_pll36xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg)
|
||||
{
|
||||
struct samsung_clk_pll36xx *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll) {
|
||||
pr_err("%s: could not allocate pll clk %s\n", __func__, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
init.name = name;
|
||||
init.ops = &samsung_pll36xx_clk_ops;
|
||||
init.flags = CLK_GET_RATE_NOCACHE;
|
||||
init.parent_names = &pname;
|
||||
init.num_parents = 1;
|
||||
|
||||
pll->hw.init = &init;
|
||||
pll->con_reg = con_reg;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll clock %s\n", __func__,
|
||||
name);
|
||||
kfree(pll);
|
||||
}
|
||||
|
||||
if (clk_register_clkdev(clk, name, NULL))
|
||||
pr_err("%s: failed to register lookup for %s", __func__, name);
|
||||
|
||||
return clk;
|
||||
}
|
||||
static const struct clk_ops samsung_pll36xx_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll36xx_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL45xx Clock Type
|
||||
*/
|
||||
#define PLL4502_LOCK_FACTOR 400
|
||||
#define PLL4508_LOCK_FACTOR 240
|
||||
|
||||
#define PLL45XX_MDIV_MASK (0x3FF)
|
||||
#define PLL45XX_PDIV_MASK (0x3F)
|
||||
#define PLL45XX_SDIV_MASK (0x7)
|
||||
#define PLL45XX_AFC_MASK (0x1F)
|
||||
#define PLL45XX_MDIV_SHIFT (16)
|
||||
#define PLL45XX_PDIV_SHIFT (8)
|
||||
#define PLL45XX_SDIV_SHIFT (0)
|
||||
#define PLL45XX_AFC_SHIFT (0)
|
||||
|
||||
struct samsung_clk_pll45xx {
|
||||
struct clk_hw hw;
|
||||
enum pll45xx_type type;
|
||||
const void __iomem *con_reg;
|
||||
};
|
||||
|
||||
#define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
|
||||
#define PLL45XX_ENABLE BIT(31)
|
||||
#define PLL45XX_LOCKED BIT(29)
|
||||
|
||||
static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
|
@ -208,54 +311,113 @@ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
|
|||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll45xx_clk_ops = {
|
||||
.recalc_rate = samsung_pll45xx_recalc_rate,
|
||||
static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
|
||||
const struct samsung_pll_rate_table *rate)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv, old_afc;
|
||||
|
||||
old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
|
||||
old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
|
||||
old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
|
||||
|
||||
return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
|
||||
|| old_afc != rate->afc);
|
||||
}
|
||||
|
||||
static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
u32 con0, con1;
|
||||
ktime_t start;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, __clk_get_name(hw->clk));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
con0 = __raw_readl(pll->con_reg);
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
|
||||
if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
|
||||
/* If only s change, change just s value only*/
|
||||
con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
|
||||
con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL PMS values. */
|
||||
con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
|
||||
(PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
|
||||
(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
|
||||
con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL45XX_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL45XX_SDIV_SHIFT);
|
||||
|
||||
/* Set PLL AFC value. */
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
|
||||
con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
|
||||
|
||||
/* Set PLL lock time. */
|
||||
switch (pll->type) {
|
||||
case pll_4502:
|
||||
__raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
|
||||
break;
|
||||
case pll_4508:
|
||||
__raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
struct clk * __init samsung_clk_register_pll45xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg,
|
||||
enum pll45xx_type type)
|
||||
{
|
||||
struct samsung_clk_pll45xx *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
/* Set new configuration. */
|
||||
__raw_writel(con1, pll->con_reg + 0x4);
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll) {
|
||||
pr_err("%s: could not allocate pll clk %s\n", __func__, name);
|
||||
return NULL;
|
||||
/* Wait for locking. */
|
||||
start = ktime_get();
|
||||
while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
|
||||
ktime_t delta = ktime_sub(ktime_get(), start);
|
||||
|
||||
if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
|
||||
pr_err("%s: could not lock PLL %s\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
init.name = name;
|
||||
init.ops = &samsung_pll45xx_clk_ops;
|
||||
init.flags = CLK_GET_RATE_NOCACHE;
|
||||
init.parent_names = &pname;
|
||||
init.num_parents = 1;
|
||||
|
||||
pll->hw.init = &init;
|
||||
pll->con_reg = con_reg;
|
||||
pll->type = type;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll clock %s\n", __func__,
|
||||
name);
|
||||
kfree(pll);
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
if (clk_register_clkdev(clk, name, NULL))
|
||||
pr_err("%s: failed to register lookup for %s", __func__, name);
|
||||
|
||||
return clk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll45xx_clk_ops = {
|
||||
.recalc_rate = samsung_pll45xx_recalc_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.set_rate = samsung_pll45xx_set_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops samsung_pll45xx_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll45xx_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL46xx Clock Type
|
||||
*/
|
||||
#define PLL46XX_LOCK_FACTOR 3000
|
||||
|
||||
#define PLL46XX_VSEL_MASK (1)
|
||||
#define PLL46XX_MDIV_MASK (0x1FF)
|
||||
#define PLL46XX_PDIV_MASK (0x3F)
|
||||
#define PLL46XX_SDIV_MASK (0x7)
|
||||
#define PLL46XX_VSEL_SHIFT (27)
|
||||
#define PLL46XX_MDIV_SHIFT (16)
|
||||
#define PLL46XX_PDIV_SHIFT (8)
|
||||
#define PLL46XX_SDIV_SHIFT (0)
|
||||
|
@ -263,19 +425,20 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
|
|||
#define PLL46XX_KDIV_MASK (0xFFFF)
|
||||
#define PLL4650C_KDIV_MASK (0xFFF)
|
||||
#define PLL46XX_KDIV_SHIFT (0)
|
||||
#define PLL46XX_MFR_MASK (0x3F)
|
||||
#define PLL46XX_MRR_MASK (0x1F)
|
||||
#define PLL46XX_KDIV_SHIFT (0)
|
||||
#define PLL46XX_MFR_SHIFT (16)
|
||||
#define PLL46XX_MRR_SHIFT (24)
|
||||
|
||||
struct samsung_clk_pll46xx {
|
||||
struct clk_hw hw;
|
||||
enum pll46xx_type type;
|
||||
const void __iomem *con_reg;
|
||||
};
|
||||
|
||||
#define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
|
||||
#define PLL46XX_ENABLE BIT(31)
|
||||
#define PLL46XX_LOCKED BIT(29)
|
||||
#define PLL46XX_VSEL BIT(27)
|
||||
|
||||
static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
|
@ -295,46 +458,174 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
|
|||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
|
||||
const struct samsung_pll_rate_table *rate)
|
||||
{
|
||||
u32 old_mdiv, old_pdiv, old_kdiv;
|
||||
|
||||
old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
|
||||
old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
|
||||
old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
|
||||
|
||||
return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
|
||||
|| old_kdiv != rate->kdiv);
|
||||
}
|
||||
|
||||
static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
u32 con0, con1, lock;
|
||||
ktime_t start;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, __clk_get_name(hw->clk));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
con0 = __raw_readl(pll->con_reg);
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
|
||||
if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
|
||||
/* If only s change, change just s value only*/
|
||||
con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
|
||||
con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
|
||||
if (lock > 0xffff)
|
||||
/* Maximum lock time bitfield is 16-bit. */
|
||||
lock = 0xffff;
|
||||
|
||||
/* Set PLL PMS and VSEL values. */
|
||||
con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
|
||||
(PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
|
||||
(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
|
||||
(PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
|
||||
con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL46XX_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL46XX_SDIV_SHIFT) |
|
||||
(rate->vsel << PLL46XX_VSEL_SHIFT);
|
||||
|
||||
/* Set PLL K, MFR and MRR values. */
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
|
||||
(PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
|
||||
(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
|
||||
con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
|
||||
(rate->mfr << PLL46XX_MFR_SHIFT) |
|
||||
(rate->mrr << PLL46XX_MRR_SHIFT);
|
||||
|
||||
/* Write configuration to PLL */
|
||||
__raw_writel(lock, pll->lock_reg);
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
__raw_writel(con1, pll->con_reg + 0x4);
|
||||
|
||||
/* Wait for locking. */
|
||||
start = ktime_get();
|
||||
while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
|
||||
ktime_t delta = ktime_sub(ktime_get(), start);
|
||||
|
||||
if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
|
||||
pr_err("%s: could not lock PLL %s\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll46xx_clk_ops = {
|
||||
.recalc_rate = samsung_pll46xx_recalc_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.set_rate = samsung_pll46xx_set_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops samsung_pll46xx_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll46xx_recalc_rate,
|
||||
};
|
||||
|
||||
struct clk * __init samsung_clk_register_pll46xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg,
|
||||
enum pll46xx_type type)
|
||||
/*
|
||||
* PLL6552 Clock Type
|
||||
*/
|
||||
|
||||
#define PLL6552_MDIV_MASK 0x3ff
|
||||
#define PLL6552_PDIV_MASK 0x3f
|
||||
#define PLL6552_SDIV_MASK 0x7
|
||||
#define PLL6552_MDIV_SHIFT 16
|
||||
#define PLL6552_PDIV_SHIFT 8
|
||||
#define PLL6552_SDIV_SHIFT 0
|
||||
|
||||
static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll46xx *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll) {
|
||||
pr_err("%s: could not allocate pll clk %s\n", __func__, name);
|
||||
return NULL;
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
|
||||
|
||||
fvco *= mdiv;
|
||||
do_div(fvco, (pdiv << sdiv));
|
||||
|
||||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
init.name = name;
|
||||
init.ops = &samsung_pll46xx_clk_ops;
|
||||
init.flags = CLK_GET_RATE_NOCACHE;
|
||||
init.parent_names = &pname;
|
||||
init.num_parents = 1;
|
||||
static const struct clk_ops samsung_pll6552_clk_ops = {
|
||||
.recalc_rate = samsung_pll6552_recalc_rate,
|
||||
};
|
||||
|
||||
pll->hw.init = &init;
|
||||
pll->con_reg = con_reg;
|
||||
pll->type = type;
|
||||
/*
|
||||
* PLL6553 Clock Type
|
||||
*/
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll clock %s\n", __func__,
|
||||
name);
|
||||
kfree(pll);
|
||||
#define PLL6553_MDIV_MASK 0xff
|
||||
#define PLL6553_PDIV_MASK 0x3f
|
||||
#define PLL6553_SDIV_MASK 0x7
|
||||
#define PLL6553_KDIV_MASK 0xffff
|
||||
#define PLL6553_MDIV_SHIFT 16
|
||||
#define PLL6553_PDIV_SHIFT 8
|
||||
#define PLL6553_SDIV_SHIFT 0
|
||||
#define PLL6553_KDIV_SHIFT 0
|
||||
|
||||
static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
|
||||
pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
|
||||
sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
|
||||
kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
|
||||
|
||||
fvco *= (mdiv << 16) + kdiv;
|
||||
do_div(fvco, (pdiv << sdiv));
|
||||
fvco >>= 16;
|
||||
|
||||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
if (clk_register_clkdev(clk, name, NULL))
|
||||
pr_err("%s: failed to register lookup for %s", __func__, name);
|
||||
|
||||
return clk;
|
||||
}
|
||||
static const struct clk_ops samsung_pll6553_clk_ops = {
|
||||
.recalc_rate = samsung_pll6553_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL2550x Clock Type
|
||||
|
@ -418,3 +709,117 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
|
|||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
|
||||
void __iomem *base)
|
||||
{
|
||||
struct samsung_clk_pll *pll;
|
||||
struct clk *clk;
|
||||
struct clk_init_data init;
|
||||
int ret, len;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll) {
|
||||
pr_err("%s: could not allocate pll clk %s\n",
|
||||
__func__, pll_clk->name);
|
||||
return;
|
||||
}
|
||||
|
||||
init.name = pll_clk->name;
|
||||
init.flags = pll_clk->flags;
|
||||
init.parent_names = &pll_clk->parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
if (pll_clk->rate_table) {
|
||||
/* find count of rates in rate_table */
|
||||
for (len = 0; pll_clk->rate_table[len].rate != 0; )
|
||||
len++;
|
||||
|
||||
pll->rate_count = len;
|
||||
pll->rate_table = kmemdup(pll_clk->rate_table,
|
||||
pll->rate_count *
|
||||
sizeof(struct samsung_pll_rate_table),
|
||||
GFP_KERNEL);
|
||||
WARN(!pll->rate_table,
|
||||
"%s: could not allocate rate table for %s\n",
|
||||
__func__, pll_clk->name);
|
||||
}
|
||||
|
||||
switch (pll_clk->type) {
|
||||
/* clk_ops for 35xx and 2550 are similar */
|
||||
case pll_35xx:
|
||||
case pll_2550:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll35xx_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll35xx_clk_ops;
|
||||
break;
|
||||
case pll_4500:
|
||||
init.ops = &samsung_pll45xx_clk_min_ops;
|
||||
break;
|
||||
case pll_4502:
|
||||
case pll_4508:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll45xx_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll45xx_clk_ops;
|
||||
break;
|
||||
/* clk_ops for 36xx and 2650 are similar */
|
||||
case pll_36xx:
|
||||
case pll_2650:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll36xx_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll36xx_clk_ops;
|
||||
break;
|
||||
case pll_6552:
|
||||
init.ops = &samsung_pll6552_clk_ops;
|
||||
break;
|
||||
case pll_6553:
|
||||
init.ops = &samsung_pll6553_clk_ops;
|
||||
break;
|
||||
case pll_4600:
|
||||
case pll_4650:
|
||||
case pll_4650c:
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll46xx_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll46xx_clk_ops;
|
||||
break;
|
||||
default:
|
||||
pr_warn("%s: Unknown pll type for pll clk %s\n",
|
||||
__func__, pll_clk->name);
|
||||
}
|
||||
|
||||
pll->hw.init = &init;
|
||||
pll->type = pll_clk->type;
|
||||
pll->lock_reg = base + pll_clk->lock_offset;
|
||||
pll->con_reg = base + pll_clk->con_offset;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll clock %s : %ld\n",
|
||||
__func__, pll_clk->name, PTR_ERR(clk));
|
||||
kfree(pll);
|
||||
return;
|
||||
}
|
||||
|
||||
samsung_clk_add_lookup(clk, pll_clk->id);
|
||||
|
||||
if (!pll_clk->alias)
|
||||
return;
|
||||
|
||||
ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
|
||||
if (ret)
|
||||
pr_err("%s: failed to register lookup for %s : %d",
|
||||
__func__, pll_clk->name, ret);
|
||||
}
|
||||
|
||||
void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
|
||||
unsigned int nr_pll, void __iomem *base)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
for (cnt = 0; cnt < nr_pll; cnt++)
|
||||
_samsung_clk_register_pll(&pll_list[cnt], base);
|
||||
}
|
||||
|
|
|
@ -12,28 +12,83 @@
|
|||
#ifndef __SAMSUNG_CLK_PLL_H
|
||||
#define __SAMSUNG_CLK_PLL_H
|
||||
|
||||
enum pll45xx_type {
|
||||
enum samsung_pll_type {
|
||||
pll_35xx,
|
||||
pll_36xx,
|
||||
pll_2550,
|
||||
pll_2650,
|
||||
pll_4500,
|
||||
pll_4502,
|
||||
pll_4508
|
||||
};
|
||||
|
||||
enum pll46xx_type {
|
||||
pll_4508,
|
||||
pll_4600,
|
||||
pll_4650,
|
||||
pll_4650c,
|
||||
pll_6552,
|
||||
pll_6553,
|
||||
};
|
||||
|
||||
#define PLL_35XX_RATE(_rate, _m, _p, _s) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
}
|
||||
|
||||
#define PLL_36XX_RATE(_rate, _m, _p, _s, _k) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
.kdiv = (_k), \
|
||||
}
|
||||
|
||||
#define PLL_45XX_RATE(_rate, _m, _p, _s, _afc) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
.afc = (_afc), \
|
||||
}
|
||||
|
||||
#define PLL_4600_RATE(_rate, _m, _p, _s, _k, _vsel) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
.kdiv = (_k), \
|
||||
.vsel = (_vsel), \
|
||||
}
|
||||
|
||||
#define PLL_4650_RATE(_rate, _m, _p, _s, _k, _mfr, _mrr, _vsel) \
|
||||
{ \
|
||||
.rate = (_rate), \
|
||||
.mdiv = (_m), \
|
||||
.pdiv = (_p), \
|
||||
.sdiv = (_s), \
|
||||
.kdiv = (_k), \
|
||||
.mfr = (_mfr), \
|
||||
.mrr = (_mrr), \
|
||||
.vsel = (_vsel), \
|
||||
}
|
||||
|
||||
/* NOTE: Rate table should be kept sorted in descending order. */
|
||||
|
||||
struct samsung_pll_rate_table {
|
||||
unsigned int rate;
|
||||
unsigned int pdiv;
|
||||
unsigned int mdiv;
|
||||
unsigned int sdiv;
|
||||
unsigned int kdiv;
|
||||
unsigned int afc;
|
||||
unsigned int mfr;
|
||||
unsigned int mrr;
|
||||
unsigned int vsel;
|
||||
};
|
||||
|
||||
extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg);
|
||||
extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg);
|
||||
extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg,
|
||||
enum pll45xx_type type);
|
||||
extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
|
||||
const char *pname, const void __iomem *con_reg,
|
||||
enum pll46xx_type type);
|
||||
extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
|
||||
const char *pname, const void __iomem *reg_base,
|
||||
const unsigned long offset);
|
||||
|
|
|
@ -0,0 +1,473 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Tomasz Figa <tomasz.figa at gmail.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.
|
||||
*
|
||||
* Common Clock Framework support for all S3C64xx SoCs.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
|
||||
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
/* S3C64xx clock controller register offsets. */
|
||||
#define APLL_LOCK 0x000
|
||||
#define MPLL_LOCK 0x004
|
||||
#define EPLL_LOCK 0x008
|
||||
#define APLL_CON 0x00c
|
||||
#define MPLL_CON 0x010
|
||||
#define EPLL_CON0 0x014
|
||||
#define EPLL_CON1 0x018
|
||||
#define CLK_SRC 0x01c
|
||||
#define CLK_DIV0 0x020
|
||||
#define CLK_DIV1 0x024
|
||||
#define CLK_DIV2 0x028
|
||||
#define HCLK_GATE 0x030
|
||||
#define PCLK_GATE 0x034
|
||||
#define SCLK_GATE 0x038
|
||||
#define MEM0_GATE 0x03c
|
||||
#define CLK_SRC2 0x10c
|
||||
#define OTHERS 0x900
|
||||
|
||||
/* Helper macros to define clock arrays. */
|
||||
#define FIXED_RATE_CLOCKS(name) \
|
||||
static struct samsung_fixed_rate_clock name[]
|
||||
#define MUX_CLOCKS(name) \
|
||||
static struct samsung_mux_clock name[]
|
||||
#define DIV_CLOCKS(name) \
|
||||
static struct samsung_div_clock name[]
|
||||
#define GATE_CLOCKS(name) \
|
||||
static struct samsung_gate_clock name[]
|
||||
|
||||
/* Helper macros for gate types present on S3C64xx. */
|
||||
#define GATE_BUS(_id, cname, pname, o, b) \
|
||||
GATE(_id, cname, pname, o, b, 0, 0)
|
||||
#define GATE_SCLK(_id, cname, pname, o, b) \
|
||||
GATE(_id, cname, pname, o, b, CLK_SET_RATE_PARENT, 0)
|
||||
#define GATE_ON(_id, cname, pname, o, b) \
|
||||
GATE(_id, cname, pname, o, b, CLK_IGNORE_UNUSED, 0)
|
||||
|
||||
/* list of PLLs to be registered */
|
||||
enum s3c64xx_plls {
|
||||
apll, mpll, epll,
|
||||
};
|
||||
|
||||
/*
|
||||
* List of controller registers to be saved and restored during
|
||||
* a suspend/resume cycle.
|
||||
*/
|
||||
static unsigned long s3c64xx_clk_regs[] __initdata = {
|
||||
APLL_LOCK,
|
||||
MPLL_LOCK,
|
||||
EPLL_LOCK,
|
||||
APLL_CON,
|
||||
MPLL_CON,
|
||||
EPLL_CON0,
|
||||
EPLL_CON1,
|
||||
CLK_SRC,
|
||||
CLK_DIV0,
|
||||
CLK_DIV1,
|
||||
CLK_DIV2,
|
||||
HCLK_GATE,
|
||||
PCLK_GATE,
|
||||
SCLK_GATE,
|
||||
};
|
||||
|
||||
static unsigned long s3c6410_clk_regs[] __initdata = {
|
||||
CLK_SRC2,
|
||||
MEM0_GATE,
|
||||
};
|
||||
|
||||
/* List of parent clocks common for all S3C64xx SoCs. */
|
||||
PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
|
||||
PNAME(uart_p) = { "mout_epll", "dout_mpll" };
|
||||
PNAME(audio0_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk0",
|
||||
"pcmcdclk0", "none", "none", "none" };
|
||||
PNAME(audio1_p) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk1",
|
||||
"pcmcdclk0", "none", "none", "none" };
|
||||
PNAME(mfc_p) = { "hclkx2", "mout_epll" };
|
||||
PNAME(apll_p) = { "fin_pll", "fout_apll" };
|
||||
PNAME(mpll_p) = { "fin_pll", "fout_mpll" };
|
||||
PNAME(epll_p) = { "fin_pll", "fout_epll" };
|
||||
PNAME(hclkx2_p) = { "mout_mpll", "mout_apll" };
|
||||
|
||||
/* S3C6400-specific parent clocks. */
|
||||
PNAME(scaler_lcd_p6400) = { "mout_epll", "dout_mpll", "none", "none" };
|
||||
PNAME(irda_p6400) = { "mout_epll", "dout_mpll", "none", "clk48m" };
|
||||
PNAME(uhost_p6400) = { "clk48m", "mout_epll", "dout_mpll", "none" };
|
||||
|
||||
/* S3C6410-specific parent clocks. */
|
||||
PNAME(clk27_p6410) = { "clk27m", "fin_pll" };
|
||||
PNAME(scaler_lcd_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "none" };
|
||||
PNAME(irda_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "clk48m" };
|
||||
PNAME(uhost_p6410) = { "clk48m", "mout_epll", "dout_mpll", "fin_pll" };
|
||||
PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2",
|
||||
"pcmcdclk1", "none", "none", "none" };
|
||||
|
||||
/* Fixed rate clocks generated outside the SoC. */
|
||||
FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = {
|
||||
FRATE(0, "fin_pll", NULL, CLK_IS_ROOT, 0),
|
||||
FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0),
|
||||
};
|
||||
|
||||
/* Fixed rate clocks generated inside the SoC. */
|
||||
FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = {
|
||||
FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000),
|
||||
FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000),
|
||||
};
|
||||
|
||||
/* List of clock muxes present on all S3C64xx SoCs. */
|
||||
MUX_CLOCKS(s3c64xx_mux_clks) __initdata = {
|
||||
MUX_F(0, "mout_syncmux", hclkx2_p, OTHERS, 6, 1, 0, CLK_MUX_READ_ONLY),
|
||||
MUX(MOUT_APLL, "mout_apll", apll_p, CLK_SRC, 0, 1),
|
||||
MUX(MOUT_MPLL, "mout_mpll", mpll_p, CLK_SRC, 1, 1),
|
||||
MUX(MOUT_EPLL, "mout_epll", epll_p, CLK_SRC, 2, 1),
|
||||
MUX(MOUT_MFC, "mout_mfc", mfc_p, CLK_SRC, 4, 1),
|
||||
MUX(MOUT_AUDIO0, "mout_audio0", audio0_p, CLK_SRC, 7, 3),
|
||||
MUX(MOUT_AUDIO1, "mout_audio1", audio1_p, CLK_SRC, 10, 3),
|
||||
MUX(MOUT_UART, "mout_uart", uart_p, CLK_SRC, 13, 1),
|
||||
MUX(MOUT_SPI0, "mout_spi0", spi_mmc_p, CLK_SRC, 14, 2),
|
||||
MUX(MOUT_SPI1, "mout_spi1", spi_mmc_p, CLK_SRC, 16, 2),
|
||||
MUX(MOUT_MMC0, "mout_mmc0", spi_mmc_p, CLK_SRC, 18, 2),
|
||||
MUX(MOUT_MMC1, "mout_mmc1", spi_mmc_p, CLK_SRC, 20, 2),
|
||||
MUX(MOUT_MMC2, "mout_mmc2", spi_mmc_p, CLK_SRC, 22, 2),
|
||||
};
|
||||
|
||||
/* List of clock muxes present on S3C6400. */
|
||||
MUX_CLOCKS(s3c6400_mux_clks) __initdata = {
|
||||
MUX(MOUT_UHOST, "mout_uhost", uhost_p6400, CLK_SRC, 5, 2),
|
||||
MUX(MOUT_IRDA, "mout_irda", irda_p6400, CLK_SRC, 24, 2),
|
||||
MUX(MOUT_LCD, "mout_lcd", scaler_lcd_p6400, CLK_SRC, 26, 2),
|
||||
MUX(MOUT_SCALER, "mout_scaler", scaler_lcd_p6400, CLK_SRC, 28, 2),
|
||||
};
|
||||
|
||||
/* List of clock muxes present on S3C6410. */
|
||||
MUX_CLOCKS(s3c6410_mux_clks) __initdata = {
|
||||
MUX(MOUT_UHOST, "mout_uhost", uhost_p6410, CLK_SRC, 5, 2),
|
||||
MUX(MOUT_IRDA, "mout_irda", irda_p6410, CLK_SRC, 24, 2),
|
||||
MUX(MOUT_LCD, "mout_lcd", scaler_lcd_p6410, CLK_SRC, 26, 2),
|
||||
MUX(MOUT_SCALER, "mout_scaler", scaler_lcd_p6410, CLK_SRC, 28, 2),
|
||||
MUX(MOUT_DAC27, "mout_dac27", clk27_p6410, CLK_SRC, 30, 1),
|
||||
MUX(MOUT_TV27, "mout_tv27", clk27_p6410, CLK_SRC, 31, 1),
|
||||
MUX(MOUT_AUDIO2, "mout_audio2", audio2_p6410, CLK_SRC2, 0, 3),
|
||||
};
|
||||
|
||||
/* List of clock dividers present on all S3C64xx SoCs. */
|
||||
DIV_CLOCKS(s3c64xx_div_clks) __initdata = {
|
||||
DIV(DOUT_MPLL, "dout_mpll", "mout_mpll", CLK_DIV0, 4, 1),
|
||||
DIV(HCLKX2, "hclkx2", "mout_syncmux", CLK_DIV0, 9, 3),
|
||||
DIV(HCLK, "hclk", "hclkx2", CLK_DIV0, 8, 1),
|
||||
DIV(PCLK, "pclk", "hclkx2", CLK_DIV0, 12, 4),
|
||||
DIV(DOUT_SECUR, "dout_secur", "hclkx2", CLK_DIV0, 18, 2),
|
||||
DIV(DOUT_CAM, "dout_cam", "hclkx2", CLK_DIV0, 20, 4),
|
||||
DIV(DOUT_JPEG, "dout_jpeg", "hclkx2", CLK_DIV0, 24, 4),
|
||||
DIV(DOUT_MFC, "dout_mfc", "mout_mfc", CLK_DIV0, 28, 4),
|
||||
DIV(DOUT_MMC0, "dout_mmc0", "mout_mmc0", CLK_DIV1, 0, 4),
|
||||
DIV(DOUT_MMC1, "dout_mmc1", "mout_mmc1", CLK_DIV1, 4, 4),
|
||||
DIV(DOUT_MMC2, "dout_mmc2", "mout_mmc2", CLK_DIV1, 8, 4),
|
||||
DIV(DOUT_LCD, "dout_lcd", "mout_lcd", CLK_DIV1, 12, 4),
|
||||
DIV(DOUT_SCALER, "dout_scaler", "mout_scaler", CLK_DIV1, 16, 4),
|
||||
DIV(DOUT_UHOST, "dout_uhost", "mout_uhost", CLK_DIV1, 20, 4),
|
||||
DIV(DOUT_SPI0, "dout_spi0", "mout_spi0", CLK_DIV2, 0, 4),
|
||||
DIV(DOUT_SPI1, "dout_spi1", "mout_spi1", CLK_DIV2, 4, 4),
|
||||
DIV(DOUT_AUDIO0, "dout_audio0", "mout_audio0", CLK_DIV2, 8, 4),
|
||||
DIV(DOUT_AUDIO1, "dout_audio1", "mout_audio1", CLK_DIV2, 12, 4),
|
||||
DIV(DOUT_UART, "dout_uart", "mout_uart", CLK_DIV2, 16, 4),
|
||||
DIV(DOUT_IRDA, "dout_irda", "mout_irda", CLK_DIV2, 20, 4),
|
||||
};
|
||||
|
||||
/* List of clock dividers present on S3C6400. */
|
||||
DIV_CLOCKS(s3c6400_div_clks) __initdata = {
|
||||
DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 3),
|
||||
};
|
||||
|
||||
/* List of clock dividers present on S3C6410. */
|
||||
DIV_CLOCKS(s3c6410_div_clks) __initdata = {
|
||||
DIV(ARMCLK, "armclk", "mout_apll", CLK_DIV0, 0, 4),
|
||||
DIV(DOUT_FIMC, "dout_fimc", "hclk", CLK_DIV1, 24, 4),
|
||||
DIV(DOUT_AUDIO2, "dout_audio2", "mout_audio2", CLK_DIV2, 24, 4),
|
||||
};
|
||||
|
||||
/* List of clock gates present on all S3C64xx SoCs. */
|
||||
GATE_CLOCKS(s3c64xx_gate_clks) __initdata = {
|
||||
GATE_BUS(HCLK_UHOST, "hclk_uhost", "hclk", HCLK_GATE, 29),
|
||||
GATE_BUS(HCLK_SECUR, "hclk_secur", "hclk", HCLK_GATE, 28),
|
||||
GATE_BUS(HCLK_SDMA1, "hclk_sdma1", "hclk", HCLK_GATE, 27),
|
||||
GATE_BUS(HCLK_SDMA0, "hclk_sdma0", "hclk", HCLK_GATE, 26),
|
||||
GATE_ON(HCLK_DDR1, "hclk_ddr1", "hclk", HCLK_GATE, 24),
|
||||
GATE_BUS(HCLK_USB, "hclk_usb", "hclk", HCLK_GATE, 20),
|
||||
GATE_BUS(HCLK_HSMMC2, "hclk_hsmmc2", "hclk", HCLK_GATE, 19),
|
||||
GATE_BUS(HCLK_HSMMC1, "hclk_hsmmc1", "hclk", HCLK_GATE, 18),
|
||||
GATE_BUS(HCLK_HSMMC0, "hclk_hsmmc0", "hclk", HCLK_GATE, 17),
|
||||
GATE_BUS(HCLK_MDP, "hclk_mdp", "hclk", HCLK_GATE, 16),
|
||||
GATE_BUS(HCLK_DHOST, "hclk_dhost", "hclk", HCLK_GATE, 15),
|
||||
GATE_BUS(HCLK_IHOST, "hclk_ihost", "hclk", HCLK_GATE, 14),
|
||||
GATE_BUS(HCLK_DMA1, "hclk_dma1", "hclk", HCLK_GATE, 13),
|
||||
GATE_BUS(HCLK_DMA0, "hclk_dma0", "hclk", HCLK_GATE, 12),
|
||||
GATE_BUS(HCLK_JPEG, "hclk_jpeg", "hclk", HCLK_GATE, 11),
|
||||
GATE_BUS(HCLK_CAMIF, "hclk_camif", "hclk", HCLK_GATE, 10),
|
||||
GATE_BUS(HCLK_SCALER, "hclk_scaler", "hclk", HCLK_GATE, 9),
|
||||
GATE_BUS(HCLK_2D, "hclk_2d", "hclk", HCLK_GATE, 8),
|
||||
GATE_BUS(HCLK_TV, "hclk_tv", "hclk", HCLK_GATE, 7),
|
||||
GATE_BUS(HCLK_POST0, "hclk_post0", "hclk", HCLK_GATE, 5),
|
||||
GATE_BUS(HCLK_ROT, "hclk_rot", "hclk", HCLK_GATE, 4),
|
||||
GATE_BUS(HCLK_LCD, "hclk_lcd", "hclk", HCLK_GATE, 3),
|
||||
GATE_BUS(HCLK_TZIC, "hclk_tzic", "hclk", HCLK_GATE, 2),
|
||||
GATE_ON(HCLK_INTC, "hclk_intc", "hclk", HCLK_GATE, 1),
|
||||
GATE_ON(PCLK_SKEY, "pclk_skey", "pclk", PCLK_GATE, 24),
|
||||
GATE_ON(PCLK_CHIPID, "pclk_chipid", "pclk", PCLK_GATE, 23),
|
||||
GATE_BUS(PCLK_SPI1, "pclk_spi1", "pclk", PCLK_GATE, 22),
|
||||
GATE_BUS(PCLK_SPI0, "pclk_spi0", "pclk", PCLK_GATE, 21),
|
||||
GATE_BUS(PCLK_HSIRX, "pclk_hsirx", "pclk", PCLK_GATE, 20),
|
||||
GATE_BUS(PCLK_HSITX, "pclk_hsitx", "pclk", PCLK_GATE, 19),
|
||||
GATE_ON(PCLK_GPIO, "pclk_gpio", "pclk", PCLK_GATE, 18),
|
||||
GATE_BUS(PCLK_IIC0, "pclk_iic0", "pclk", PCLK_GATE, 17),
|
||||
GATE_BUS(PCLK_IIS1, "pclk_iis1", "pclk", PCLK_GATE, 16),
|
||||
GATE_BUS(PCLK_IIS0, "pclk_iis0", "pclk", PCLK_GATE, 15),
|
||||
GATE_BUS(PCLK_AC97, "pclk_ac97", "pclk", PCLK_GATE, 14),
|
||||
GATE_BUS(PCLK_TZPC, "pclk_tzpc", "pclk", PCLK_GATE, 13),
|
||||
GATE_BUS(PCLK_TSADC, "pclk_tsadc", "pclk", PCLK_GATE, 12),
|
||||
GATE_BUS(PCLK_KEYPAD, "pclk_keypad", "pclk", PCLK_GATE, 11),
|
||||
GATE_BUS(PCLK_IRDA, "pclk_irda", "pclk", PCLK_GATE, 10),
|
||||
GATE_BUS(PCLK_PCM1, "pclk_pcm1", "pclk", PCLK_GATE, 9),
|
||||
GATE_BUS(PCLK_PCM0, "pclk_pcm0", "pclk", PCLK_GATE, 8),
|
||||
GATE_BUS(PCLK_PWM, "pclk_pwm", "pclk", PCLK_GATE, 7),
|
||||
GATE_BUS(PCLK_RTC, "pclk_rtc", "pclk", PCLK_GATE, 6),
|
||||
GATE_BUS(PCLK_WDT, "pclk_wdt", "pclk", PCLK_GATE, 5),
|
||||
GATE_BUS(PCLK_UART3, "pclk_uart3", "pclk", PCLK_GATE, 4),
|
||||
GATE_BUS(PCLK_UART2, "pclk_uart2", "pclk", PCLK_GATE, 3),
|
||||
GATE_BUS(PCLK_UART1, "pclk_uart1", "pclk", PCLK_GATE, 2),
|
||||
GATE_BUS(PCLK_UART0, "pclk_uart0", "pclk", PCLK_GATE, 1),
|
||||
GATE_BUS(PCLK_MFC, "pclk_mfc", "pclk", PCLK_GATE, 0),
|
||||
GATE_SCLK(SCLK_UHOST, "sclk_uhost", "dout_uhost", SCLK_GATE, 30),
|
||||
GATE_SCLK(SCLK_MMC2_48, "sclk_mmc2_48", "clk48m", SCLK_GATE, 29),
|
||||
GATE_SCLK(SCLK_MMC1_48, "sclk_mmc1_48", "clk48m", SCLK_GATE, 28),
|
||||
GATE_SCLK(SCLK_MMC0_48, "sclk_mmc0_48", "clk48m", SCLK_GATE, 27),
|
||||
GATE_SCLK(SCLK_MMC2, "sclk_mmc2", "dout_mmc2", SCLK_GATE, 26),
|
||||
GATE_SCLK(SCLK_MMC1, "sclk_mmc1", "dout_mmc1", SCLK_GATE, 25),
|
||||
GATE_SCLK(SCLK_MMC0, "sclk_mmc0", "dout_mmc0", SCLK_GATE, 24),
|
||||
GATE_SCLK(SCLK_SPI1_48, "sclk_spi1_48", "clk48m", SCLK_GATE, 23),
|
||||
GATE_SCLK(SCLK_SPI0_48, "sclk_spi0_48", "clk48m", SCLK_GATE, 22),
|
||||
GATE_SCLK(SCLK_SPI1, "sclk_spi1", "dout_spi1", SCLK_GATE, 21),
|
||||
GATE_SCLK(SCLK_SPI0, "sclk_spi0", "dout_spi0", SCLK_GATE, 20),
|
||||
GATE_SCLK(SCLK_DAC27, "sclk_dac27", "mout_dac27", SCLK_GATE, 19),
|
||||
GATE_SCLK(SCLK_TV27, "sclk_tv27", "mout_tv27", SCLK_GATE, 18),
|
||||
GATE_SCLK(SCLK_SCALER27, "sclk_scaler27", "clk27m", SCLK_GATE, 17),
|
||||
GATE_SCLK(SCLK_SCALER, "sclk_scaler", "dout_scaler", SCLK_GATE, 16),
|
||||
GATE_SCLK(SCLK_LCD27, "sclk_lcd27", "clk27m", SCLK_GATE, 15),
|
||||
GATE_SCLK(SCLK_LCD, "sclk_lcd", "dout_lcd", SCLK_GATE, 14),
|
||||
GATE_SCLK(SCLK_POST0_27, "sclk_post0_27", "clk27m", SCLK_GATE, 12),
|
||||
GATE_SCLK(SCLK_POST0, "sclk_post0", "dout_lcd", SCLK_GATE, 10),
|
||||
GATE_SCLK(SCLK_AUDIO1, "sclk_audio1", "dout_audio1", SCLK_GATE, 9),
|
||||
GATE_SCLK(SCLK_AUDIO0, "sclk_audio0", "dout_audio0", SCLK_GATE, 8),
|
||||
GATE_SCLK(SCLK_SECUR, "sclk_secur", "dout_secur", SCLK_GATE, 7),
|
||||
GATE_SCLK(SCLK_IRDA, "sclk_irda", "dout_irda", SCLK_GATE, 6),
|
||||
GATE_SCLK(SCLK_UART, "sclk_uart", "dout_uart", SCLK_GATE, 5),
|
||||
GATE_SCLK(SCLK_MFC, "sclk_mfc", "dout_mfc", SCLK_GATE, 3),
|
||||
GATE_SCLK(SCLK_CAM, "sclk_cam", "dout_cam", SCLK_GATE, 2),
|
||||
GATE_SCLK(SCLK_JPEG, "sclk_jpeg", "dout_jpeg", SCLK_GATE, 1),
|
||||
};
|
||||
|
||||
/* List of clock gates present on S3C6400. */
|
||||
GATE_CLOCKS(s3c6400_gate_clks) __initdata = {
|
||||
GATE_ON(HCLK_DDR0, "hclk_ddr0", "hclk", HCLK_GATE, 23),
|
||||
GATE_SCLK(SCLK_ONENAND, "sclk_onenand", "parent", SCLK_GATE, 4),
|
||||
};
|
||||
|
||||
/* List of clock gates present on S3C6410. */
|
||||
GATE_CLOCKS(s3c6410_gate_clks) __initdata = {
|
||||
GATE_BUS(HCLK_3DSE, "hclk_3dse", "hclk", HCLK_GATE, 31),
|
||||
GATE_ON(HCLK_IROM, "hclk_irom", "hclk", HCLK_GATE, 25),
|
||||
GATE_ON(HCLK_MEM1, "hclk_mem1", "hclk", HCLK_GATE, 22),
|
||||
GATE_ON(HCLK_MEM0, "hclk_mem0", "hclk", HCLK_GATE, 21),
|
||||
GATE_BUS(HCLK_MFC, "hclk_mfc", "hclk", HCLK_GATE, 0),
|
||||
GATE_BUS(PCLK_IIC1, "pclk_iic1", "pclk", PCLK_GATE, 27),
|
||||
GATE_BUS(PCLK_IIS2, "pclk_iis2", "pclk", PCLK_GATE, 26),
|
||||
GATE_SCLK(SCLK_FIMC, "sclk_fimc", "dout_fimc", SCLK_GATE, 13),
|
||||
GATE_SCLK(SCLK_AUDIO2, "sclk_audio2", "dout_audio2", SCLK_GATE, 11),
|
||||
GATE_BUS(MEM0_CFCON, "mem0_cfcon", "hclk_mem0", MEM0_GATE, 5),
|
||||
GATE_BUS(MEM0_ONENAND1, "mem0_onenand1", "hclk_mem0", MEM0_GATE, 4),
|
||||
GATE_BUS(MEM0_ONENAND0, "mem0_onenand0", "hclk_mem0", MEM0_GATE, 3),
|
||||
GATE_BUS(MEM0_NFCON, "mem0_nfcon", "hclk_mem0", MEM0_GATE, 2),
|
||||
GATE_ON(MEM0_SROM, "mem0_srom", "hclk_mem0", MEM0_GATE, 1),
|
||||
};
|
||||
|
||||
/* List of PLL clocks. */
|
||||
static struct samsung_pll_clock s3c64xx_pll_clks[] __initdata = {
|
||||
[apll] = PLL(pll_6552, FOUT_APLL, "fout_apll", "fin_pll",
|
||||
APLL_LOCK, APLL_CON, NULL),
|
||||
[mpll] = PLL(pll_6552, FOUT_MPLL, "fout_mpll", "fin_pll",
|
||||
MPLL_LOCK, MPLL_CON, NULL),
|
||||
[epll] = PLL(pll_6553, FOUT_EPLL, "fout_epll", "fin_pll",
|
||||
EPLL_LOCK, EPLL_CON0, NULL),
|
||||
};
|
||||
|
||||
/* Aliases for common s3c64xx clocks. */
|
||||
static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
|
||||
ALIAS(FOUT_APLL, NULL, "fout_apll"),
|
||||
ALIAS(FOUT_MPLL, NULL, "fout_mpll"),
|
||||
ALIAS(FOUT_EPLL, NULL, "fout_epll"),
|
||||
ALIAS(MOUT_EPLL, NULL, "mout_epll"),
|
||||
ALIAS(DOUT_MPLL, NULL, "dout_mpll"),
|
||||
ALIAS(HCLKX2, NULL, "hclk2"),
|
||||
ALIAS(HCLK, NULL, "hclk"),
|
||||
ALIAS(PCLK, NULL, "pclk"),
|
||||
ALIAS(PCLK, NULL, "clk_uart_baud2"),
|
||||
ALIAS(ARMCLK, NULL, "armclk"),
|
||||
ALIAS(HCLK_UHOST, "s3c2410-ohci", "usb-host"),
|
||||
ALIAS(HCLK_USB, "s3c-hsotg", "otg"),
|
||||
ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "hsmmc"),
|
||||
ALIAS(HCLK_HSMMC2, "s3c-sdhci.2", "mmc_busclk.0"),
|
||||
ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
|
||||
ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
|
||||
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
|
||||
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
|
||||
ALIAS(HCLK_DMA1, NULL, "dma1"),
|
||||
ALIAS(HCLK_DMA0, NULL, "dma0"),
|
||||
ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
|
||||
ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
|
||||
ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
|
||||
ALIAS(PCLK_SPI0, "s3c6410-spi.0", "spi"),
|
||||
ALIAS(PCLK_IIC0, "s3c2440-i2c.0", "i2c"),
|
||||
ALIAS(PCLK_IIS1, "samsung-i2s.1", "iis"),
|
||||
ALIAS(PCLK_IIS0, "samsung-i2s.0", "iis"),
|
||||
ALIAS(PCLK_AC97, "samsung-ac97", "ac97"),
|
||||
ALIAS(PCLK_TSADC, "s3c64xx-adc", "adc"),
|
||||
ALIAS(PCLK_KEYPAD, "samsung-keypad", "keypad"),
|
||||
ALIAS(PCLK_PCM1, "samsung-pcm.1", "pcm"),
|
||||
ALIAS(PCLK_PCM0, "samsung-pcm.0", "pcm"),
|
||||
ALIAS(PCLK_PWM, NULL, "timers"),
|
||||
ALIAS(PCLK_RTC, "s3c64xx-rtc", "rtc"),
|
||||
ALIAS(PCLK_WDT, NULL, "watchdog"),
|
||||
ALIAS(PCLK_UART3, "s3c6400-uart.3", "uart"),
|
||||
ALIAS(PCLK_UART2, "s3c6400-uart.2", "uart"),
|
||||
ALIAS(PCLK_UART1, "s3c6400-uart.1", "uart"),
|
||||
ALIAS(PCLK_UART0, "s3c6400-uart.0", "uart"),
|
||||
ALIAS(SCLK_UHOST, "s3c2410-ohci", "usb-bus-host"),
|
||||
ALIAS(SCLK_MMC2, "s3c-sdhci.2", "mmc_busclk.2"),
|
||||
ALIAS(SCLK_MMC1, "s3c-sdhci.1", "mmc_busclk.2"),
|
||||
ALIAS(SCLK_MMC0, "s3c-sdhci.0", "mmc_busclk.2"),
|
||||
ALIAS(SCLK_SPI1, "s3c6410-spi.1", "spi-bus"),
|
||||
ALIAS(SCLK_SPI0, "s3c6410-spi.0", "spi-bus"),
|
||||
ALIAS(SCLK_AUDIO1, "samsung-pcm.1", "audio-bus"),
|
||||
ALIAS(SCLK_AUDIO1, "samsung-i2s.1", "audio-bus"),
|
||||
ALIAS(SCLK_AUDIO0, "samsung-pcm.0", "audio-bus"),
|
||||
ALIAS(SCLK_AUDIO0, "samsung-i2s.0", "audio-bus"),
|
||||
ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
|
||||
ALIAS(SCLK_CAM, "s3c-camif", "camera"),
|
||||
};
|
||||
|
||||
/* Aliases for s3c6400-specific clocks. */
|
||||
static struct samsung_clock_alias s3c6400_clock_aliases[] = {
|
||||
/* Nothing to place here yet. */
|
||||
};
|
||||
|
||||
/* Aliases for s3c6410-specific clocks. */
|
||||
static struct samsung_clock_alias s3c6410_clock_aliases[] = {
|
||||
ALIAS(PCLK_IIC1, "s3c2440-i2c.1", "i2c"),
|
||||
ALIAS(PCLK_IIS2, "samsung-i2s.2", "iis"),
|
||||
ALIAS(SCLK_FIMC, "s3c-camif", "fimc"),
|
||||
ALIAS(SCLK_AUDIO2, "samsung-i2s.2", "audio-bus"),
|
||||
ALIAS(MEM0_SROM, NULL, "srom"),
|
||||
};
|
||||
|
||||
static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f,
|
||||
unsigned long xusbxti_f)
|
||||
{
|
||||
s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f;
|
||||
s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
|
||||
samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks));
|
||||
}
|
||||
|
||||
/* Register s3c64xx clocks. */
|
||||
void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
|
||||
unsigned long xusbxti_f, bool is_s3c6400,
|
||||
void __iomem *reg_base)
|
||||
{
|
||||
unsigned long *soc_regs = NULL;
|
||||
unsigned long nr_soc_regs = 0;
|
||||
|
||||
if (np) {
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base)
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
}
|
||||
|
||||
if (!is_s3c6400) {
|
||||
soc_regs = s3c6410_clk_regs;
|
||||
nr_soc_regs = ARRAY_SIZE(s3c6410_clk_regs);
|
||||
}
|
||||
|
||||
samsung_clk_init(np, reg_base, NR_CLKS, s3c64xx_clk_regs,
|
||||
ARRAY_SIZE(s3c64xx_clk_regs), soc_regs, nr_soc_regs);
|
||||
|
||||
/* Register external clocks. */
|
||||
if (!np)
|
||||
s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f);
|
||||
|
||||
/* Register PLLs. */
|
||||
samsung_clk_register_pll(s3c64xx_pll_clks,
|
||||
ARRAY_SIZE(s3c64xx_pll_clks), reg_base);
|
||||
|
||||
/* Register common internal clocks. */
|
||||
samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks,
|
||||
ARRAY_SIZE(s3c64xx_fixed_rate_clks));
|
||||
samsung_clk_register_mux(s3c64xx_mux_clks,
|
||||
ARRAY_SIZE(s3c64xx_mux_clks));
|
||||
samsung_clk_register_div(s3c64xx_div_clks,
|
||||
ARRAY_SIZE(s3c64xx_div_clks));
|
||||
samsung_clk_register_gate(s3c64xx_gate_clks,
|
||||
ARRAY_SIZE(s3c64xx_gate_clks));
|
||||
|
||||
/* Register SoC-specific clocks. */
|
||||
if (is_s3c6400) {
|
||||
samsung_clk_register_mux(s3c6400_mux_clks,
|
||||
ARRAY_SIZE(s3c6400_mux_clks));
|
||||
samsung_clk_register_div(s3c6400_div_clks,
|
||||
ARRAY_SIZE(s3c6400_div_clks));
|
||||
samsung_clk_register_gate(s3c6400_gate_clks,
|
||||
ARRAY_SIZE(s3c6400_gate_clks));
|
||||
samsung_clk_register_alias(s3c6400_clock_aliases,
|
||||
ARRAY_SIZE(s3c6400_clock_aliases));
|
||||
} else {
|
||||
samsung_clk_register_mux(s3c6410_mux_clks,
|
||||
ARRAY_SIZE(s3c6410_mux_clks));
|
||||
samsung_clk_register_div(s3c6410_div_clks,
|
||||
ARRAY_SIZE(s3c6410_div_clks));
|
||||
samsung_clk_register_gate(s3c6410_gate_clks,
|
||||
ARRAY_SIZE(s3c6410_gate_clks));
|
||||
samsung_clk_register_alias(s3c6410_clock_aliases,
|
||||
ARRAY_SIZE(s3c6410_clock_aliases));
|
||||
}
|
||||
|
||||
samsung_clk_register_alias(s3c64xx_clock_aliases,
|
||||
ARRAY_SIZE(s3c64xx_clock_aliases));
|
||||
|
||||
pr_info("%s clocks: apll = %lu, mpll = %lu\n"
|
||||
"\tepll = %lu, arm_clk = %lu\n",
|
||||
is_s3c6400 ? "S3C6400" : "S3C6410",
|
||||
_get_rate("fout_apll"), _get_rate("fout_mpll"),
|
||||
_get_rate("fout_epll"), _get_rate("armclk"));
|
||||
}
|
||||
|
||||
static void __init s3c6400_clk_init(struct device_node *np)
|
||||
{
|
||||
s3c64xx_clk_init(np, 0, 0, true, NULL);
|
||||
}
|
||||
CLK_OF_DECLARE(s3c6400_clk, "samsung,s3c6400-clock", s3c6400_clk_init);
|
||||
|
||||
static void __init s3c6410_clk_init(struct device_node *np)
|
||||
{
|
||||
s3c64xx_clk_init(np, 0, 0, false, NULL);
|
||||
}
|
||||
CLK_OF_DECLARE(s3c6410_clk, "samsung,s3c6410-clock", s3c6410_clk_init);
|
|
@ -307,14 +307,12 @@ void __init samsung_clk_of_register_fixed_ext(
|
|||
unsigned long _get_rate(const char *clk_name)
|
||||
{
|
||||
struct clk *clk;
|
||||
unsigned long rate;
|
||||
|
||||
clk = clk_get(NULL, clk_name);
|
||||
if (IS_ERR(clk)) {
|
||||
clk = __clk_lookup(clk_name);
|
||||
if (!clk) {
|
||||
pr_err("%s: could not find clock %s\n", __func__, clk_name);
|
||||
return 0;
|
||||
}
|
||||
rate = clk_get_rate(clk);
|
||||
clk_put(clk);
|
||||
return rate;
|
||||
|
||||
return clk_get_rate(clk);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include "clk-pll.h"
|
||||
|
||||
/**
|
||||
* struct samsung_clock_alias: information about mux clock
|
||||
|
@ -39,6 +40,8 @@ struct samsung_clock_alias {
|
|||
.alias = a, \
|
||||
}
|
||||
|
||||
#define MHZ (1000 * 1000)
|
||||
|
||||
/**
|
||||
* struct samsung_fixed_rate_clock: information about fixed-rate clock
|
||||
* @id: platform specific id of the clock.
|
||||
|
@ -127,7 +130,7 @@ struct samsung_mux_clock {
|
|||
.name = cname, \
|
||||
.parent_names = pnames, \
|
||||
.num_parents = ARRAY_SIZE(pnames), \
|
||||
.flags = f, \
|
||||
.flags = (f) | CLK_SET_RATE_NO_REPARENT, \
|
||||
.offset = o, \
|
||||
.shift = s, \
|
||||
.width = w, \
|
||||
|
@ -261,6 +264,54 @@ struct samsung_clk_reg_dump {
|
|||
u32 value;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct samsung_pll_clock: information about pll clock
|
||||
* @id: platform specific id of the clock.
|
||||
* @dev_name: name of the device to which this clock belongs.
|
||||
* @name: name of this pll clock.
|
||||
* @parent_name: name of the parent clock.
|
||||
* @flags: optional flags for basic clock.
|
||||
* @con_offset: offset of the register for configuring the PLL.
|
||||
* @lock_offset: offset of the register for locking the PLL.
|
||||
* @type: Type of PLL to be registered.
|
||||
* @alias: optional clock alias name to be assigned to this clock.
|
||||
*/
|
||||
struct samsung_pll_clock {
|
||||
unsigned int id;
|
||||
const char *dev_name;
|
||||
const char *name;
|
||||
const char *parent_name;
|
||||
unsigned long flags;
|
||||
int con_offset;
|
||||
int lock_offset;
|
||||
enum samsung_pll_type type;
|
||||
const struct samsung_pll_rate_table *rate_table;
|
||||
const char *alias;
|
||||
};
|
||||
|
||||
#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, \
|
||||
_rtable, _alias) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.type = _typ, \
|
||||
.dev_name = _dname, \
|
||||
.name = _name, \
|
||||
.parent_name = _pname, \
|
||||
.flags = CLK_GET_RATE_NOCACHE, \
|
||||
.con_offset = _con, \
|
||||
.lock_offset = _lock, \
|
||||
.rate_table = _rtable, \
|
||||
.alias = _alias, \
|
||||
}
|
||||
|
||||
#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable) \
|
||||
__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
|
||||
_lock, _con, _rtable, _name)
|
||||
|
||||
#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
|
||||
__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \
|
||||
_lock, _con, _rtable, _alias)
|
||||
|
||||
extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
|
||||
unsigned long nr_clks, unsigned long *rdump,
|
||||
unsigned long nr_rdump, unsigned long *soc_rdump,
|
||||
|
@ -284,6 +335,8 @@ extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
|
|||
unsigned int nr_clk);
|
||||
extern void __init samsung_clk_register_gate(
|
||||
struct samsung_gate_clock *clk_list, unsigned int nr_clk);
|
||||
extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list,
|
||||
unsigned int nr_clk, void __iomem *base);
|
||||
|
||||
extern unsigned long _get_rate(const char *clk_name);
|
||||
|
||||
|
|
|
@ -416,9 +416,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
/* clock derived from 24 or 25 MHz osc clk */
|
||||
/* vco-pll */
|
||||
clk = clk_register_mux(NULL, "vco1_mclk", vco_parents,
|
||||
ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG,
|
||||
SPEAR1310_PLL1_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(vco_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PLL_CFG, SPEAR1310_PLL1_CLK_SHIFT,
|
||||
SPEAR1310_PLL_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "vco1_mclk", NULL);
|
||||
clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mclk",
|
||||
0, SPEAR1310_PLL1_CTR, SPEAR1310_PLL1_FRQ, pll_rtbl,
|
||||
|
@ -427,9 +427,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk1, "pll1_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "vco2_mclk", vco_parents,
|
||||
ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG,
|
||||
SPEAR1310_PLL2_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(vco_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PLL_CFG, SPEAR1310_PLL2_CLK_SHIFT,
|
||||
SPEAR1310_PLL_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "vco2_mclk", NULL);
|
||||
clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mclk",
|
||||
0, SPEAR1310_PLL2_CTR, SPEAR1310_PLL2_FRQ, pll_rtbl,
|
||||
|
@ -438,9 +438,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk1, "pll2_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "vco3_mclk", vco_parents,
|
||||
ARRAY_SIZE(vco_parents), 0, SPEAR1310_PLL_CFG,
|
||||
SPEAR1310_PLL3_CLK_SHIFT, SPEAR1310_PLL_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(vco_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PLL_CFG, SPEAR1310_PLL3_CLK_SHIFT,
|
||||
SPEAR1310_PLL_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "vco3_mclk", NULL);
|
||||
clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mclk",
|
||||
0, SPEAR1310_PLL3_CTR, SPEAR1310_PLL3_FRQ, pll_rtbl,
|
||||
|
@ -515,9 +515,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
|
||||
/* gpt clocks */
|
||||
clk = clk_register_mux(NULL, "gpt0_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG,
|
||||
SPEAR1310_GPT0_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT0_CLK_SHIFT,
|
||||
SPEAR1310_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt0_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mclk", 0,
|
||||
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT0_CLK_ENB, 0,
|
||||
|
@ -525,9 +525,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "gpt0");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt1_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG,
|
||||
SPEAR1310_GPT1_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT1_CLK_SHIFT,
|
||||
SPEAR1310_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt1_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0,
|
||||
SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_GPT1_CLK_ENB, 0,
|
||||
|
@ -535,9 +535,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "gpt1");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt2_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG,
|
||||
SPEAR1310_GPT2_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT2_CLK_SHIFT,
|
||||
SPEAR1310_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt2_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0,
|
||||
SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT2_CLK_ENB, 0,
|
||||
|
@ -545,9 +545,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "gpt2");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt3_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1310_PERIP_CLK_CFG,
|
||||
SPEAR1310_GPT3_CLK_SHIFT, SPEAR1310_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GPT3_CLK_SHIFT,
|
||||
SPEAR1310_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt3_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0,
|
||||
SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_GPT3_CLK_ENB, 0,
|
||||
|
@ -562,7 +562,8 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk1, "uart_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents,
|
||||
ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart0_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_UART_CLK_SHIFT,
|
||||
SPEAR1310_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart0_mclk", NULL);
|
||||
|
@ -602,7 +603,8 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk1, "c3_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "c3_mclk", c3_parents,
|
||||
ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(c3_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_C3_CLK_SHIFT,
|
||||
SPEAR1310_C3_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "c3_mclk", NULL);
|
||||
|
@ -614,8 +616,8 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
|
||||
/* gmac */
|
||||
clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents,
|
||||
ARRAY_SIZE(gmac_phy_input_parents), 0,
|
||||
SPEAR1310_GMAC_CLK_CFG,
|
||||
ARRAY_SIZE(gmac_phy_input_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1310_GMAC_CLK_CFG,
|
||||
SPEAR1310_GMAC_PHY_INPUT_CLK_SHIFT,
|
||||
SPEAR1310_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "phy_input_mclk", NULL);
|
||||
|
@ -627,15 +629,16 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk1, "phy_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "phy_mclk", gmac_phy_parents,
|
||||
ARRAY_SIZE(gmac_phy_parents), 0,
|
||||
ARRAY_SIZE(gmac_phy_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT,
|
||||
SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "stmmacphy.0", NULL);
|
||||
|
||||
/* clcd */
|
||||
clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents,
|
||||
ARRAY_SIZE(clcd_synth_parents), 0,
|
||||
SPEAR1310_CLCD_CLK_SYNT, SPEAR1310_CLCD_SYNT_CLK_SHIFT,
|
||||
ARRAY_SIZE(clcd_synth_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1310_CLCD_CLK_SYNT,
|
||||
SPEAR1310_CLCD_SYNT_CLK_SHIFT,
|
||||
SPEAR1310_CLCD_SYNT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "clcd_syn_mclk", NULL);
|
||||
|
||||
|
@ -645,7 +648,8 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, "clcd_syn_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents,
|
||||
ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(clcd_pixel_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT,
|
||||
SPEAR1310_CLCD_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "clcd_pixel_mclk", NULL);
|
||||
|
@ -657,9 +661,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
|
||||
/* i2s */
|
||||
clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents,
|
||||
ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG,
|
||||
SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(i2s_src_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_SRC_CLK_SHIFT,
|
||||
SPEAR1310_I2S_SRC_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2s_src_mclk", NULL);
|
||||
|
||||
clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0,
|
||||
|
@ -668,7 +672,8 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, "i2s_prs1_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents,
|
||||
ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(i2s_ref_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_REF_SHIFT,
|
||||
SPEAR1310_I2S_REF_SEL_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2s_ref_mclk", NULL);
|
||||
|
@ -806,13 +811,15 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
|
||||
/* RAS clks */
|
||||
clk = clk_register_mux(NULL, "gen_syn0_1_mclk", gen_synth0_1_parents,
|
||||
ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1310_PLL_CFG,
|
||||
ARRAY_SIZE(gen_synth0_1_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1310_PLL_CFG,
|
||||
SPEAR1310_RAS_SYNT0_1_CLK_SHIFT,
|
||||
SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gen_syn0_1_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents,
|
||||
ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1310_PLL_CFG,
|
||||
ARRAY_SIZE(gen_synth2_3_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1310_PLL_CFG,
|
||||
SPEAR1310_RAS_SYNT2_3_CLK_SHIFT,
|
||||
SPEAR1310_RAS_SYNT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gen_syn2_3_clk", NULL);
|
||||
|
@ -929,8 +936,8 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
|
||||
clk = clk_register_mux(NULL, "smii_rgmii_phy_mclk",
|
||||
smii_rgmii_phy_parents,
|
||||
ARRAY_SIZE(smii_rgmii_phy_parents), 0,
|
||||
SPEAR1310_RAS_CTRL_REG1,
|
||||
ARRAY_SIZE(smii_rgmii_phy_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1310_RAS_CTRL_REG1,
|
||||
SPEAR1310_SMII_RGMII_PHY_CLK_SHIFT,
|
||||
SPEAR1310_PHY_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "stmmacphy.1", NULL);
|
||||
|
@ -938,15 +945,15 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, "stmmacphy.4", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "rmii_phy_mclk", rmii_phy_parents,
|
||||
ARRAY_SIZE(rmii_phy_parents), 0,
|
||||
ARRAY_SIZE(rmii_phy_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT,
|
||||
SPEAR1310_PHY_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "stmmacphy.3", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "uart1_mclk", uart_parents,
|
||||
ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_UART1_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(uart_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART1_CLK_SHIFT,
|
||||
SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart1_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart1_clk", "uart1_mclk", 0,
|
||||
|
@ -955,9 +962,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5c800000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart2_mclk", uart_parents,
|
||||
ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_UART2_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(uart_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART2_CLK_SHIFT,
|
||||
SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart2_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart2_clk", "uart2_mclk", 0,
|
||||
|
@ -966,9 +973,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5c900000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart3_mclk", uart_parents,
|
||||
ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_UART3_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(uart_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART3_CLK_SHIFT,
|
||||
SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart3_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart3_clk", "uart3_mclk", 0,
|
||||
|
@ -977,9 +984,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5ca00000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart4_mclk", uart_parents,
|
||||
ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_UART4_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(uart_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART4_CLK_SHIFT,
|
||||
SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart4_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart4_clk", "uart4_mclk", 0,
|
||||
|
@ -988,9 +995,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5cb00000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart5_mclk", uart_parents,
|
||||
ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_UART5_CLK_SHIFT, SPEAR1310_RAS_UART_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(uart_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_UART5_CLK_SHIFT,
|
||||
SPEAR1310_RAS_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart5_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart5_clk", "uart5_mclk", 0,
|
||||
|
@ -999,9 +1006,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5cc00000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c1_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C1_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C1_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c1_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c1_clk", "i2c1_mclk", 0,
|
||||
|
@ -1010,9 +1017,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5cd00000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c2_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C2_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C2_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c2_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c2_clk", "i2c2_mclk", 0,
|
||||
|
@ -1021,9 +1028,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5ce00000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c3_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C3_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C3_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c3_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c3_clk", "i2c3_mclk", 0,
|
||||
|
@ -1032,9 +1039,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5cf00000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c4_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C4_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C4_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c4_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c4_clk", "i2c4_mclk", 0,
|
||||
|
@ -1043,9 +1050,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5d000000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c5_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C5_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C5_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c5_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c5_clk", "i2c5_mclk", 0,
|
||||
|
@ -1054,9 +1061,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5d100000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c6_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C6_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C6_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c6_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c6_clk", "i2c6_mclk", 0,
|
||||
|
@ -1065,9 +1072,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5d200000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2c7_mclk", i2c_parents,
|
||||
ARRAY_SIZE(i2c_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_I2C7_CLK_SHIFT, SPEAR1310_I2C_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(i2c_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_I2C7_CLK_SHIFT,
|
||||
SPEAR1310_I2C_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2c7_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "i2c7_clk", "i2c7_mclk", 0,
|
||||
|
@ -1076,9 +1083,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5d300000.i2c");
|
||||
|
||||
clk = clk_register_mux(NULL, "ssp1_mclk", ssp1_parents,
|
||||
ARRAY_SIZE(ssp1_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_SSP1_CLK_SHIFT, SPEAR1310_SSP1_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(ssp1_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_SSP1_CLK_SHIFT,
|
||||
SPEAR1310_SSP1_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "ssp1_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "ssp1_clk", "ssp1_mclk", 0,
|
||||
|
@ -1087,9 +1094,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "5d400000.spi");
|
||||
|
||||
clk = clk_register_mux(NULL, "pci_mclk", pci_parents,
|
||||
ARRAY_SIZE(pci_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_PCI_CLK_SHIFT, SPEAR1310_PCI_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(pci_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_PCI_CLK_SHIFT,
|
||||
SPEAR1310_PCI_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "pci_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "pci_clk", "pci_mclk", 0,
|
||||
|
@ -1098,9 +1105,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "pci");
|
||||
|
||||
clk = clk_register_mux(NULL, "tdm1_mclk", tdm_parents,
|
||||
ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_TDM1_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(tdm_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_TDM1_CLK_SHIFT,
|
||||
SPEAR1310_TDM_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "tdm1_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "tdm1_clk", "tdm1_mclk", 0,
|
||||
|
@ -1109,9 +1116,9 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base)
|
|||
clk_register_clkdev(clk, NULL, "tdm_hdlc.0");
|
||||
|
||||
clk = clk_register_mux(NULL, "tdm2_mclk", tdm_parents,
|
||||
ARRAY_SIZE(tdm_parents), 0, SPEAR1310_RAS_CTRL_REG0,
|
||||
SPEAR1310_TDM2_CLK_SHIFT, SPEAR1310_TDM_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(tdm_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1310_RAS_CTRL_REG0, SPEAR1310_TDM2_CLK_SHIFT,
|
||||
SPEAR1310_TDM_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "tdm2_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "tdm2_clk", "tdm2_mclk", 0,
|
||||
|
|
|
@ -473,9 +473,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
/* clock derived from 24 or 25 MHz osc clk */
|
||||
/* vco-pll */
|
||||
clk = clk_register_mux(NULL, "vco1_mclk", vco_parents,
|
||||
ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG,
|
||||
SPEAR1340_PLL1_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(vco_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PLL_CFG, SPEAR1340_PLL1_CLK_SHIFT,
|
||||
SPEAR1340_PLL_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "vco1_mclk", NULL);
|
||||
clk = clk_register_vco_pll("vco1_clk", "pll1_clk", NULL, "vco1_mclk", 0,
|
||||
SPEAR1340_PLL1_CTR, SPEAR1340_PLL1_FRQ, pll_rtbl,
|
||||
|
@ -484,9 +484,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "pll1_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "vco2_mclk", vco_parents,
|
||||
ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG,
|
||||
SPEAR1340_PLL2_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(vco_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PLL_CFG, SPEAR1340_PLL2_CLK_SHIFT,
|
||||
SPEAR1340_PLL_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "vco2_mclk", NULL);
|
||||
clk = clk_register_vco_pll("vco2_clk", "pll2_clk", NULL, "vco2_mclk", 0,
|
||||
SPEAR1340_PLL2_CTR, SPEAR1340_PLL2_FRQ, pll_rtbl,
|
||||
|
@ -495,9 +495,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "pll2_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "vco3_mclk", vco_parents,
|
||||
ARRAY_SIZE(vco_parents), 0, SPEAR1340_PLL_CFG,
|
||||
SPEAR1340_PLL3_CLK_SHIFT, SPEAR1340_PLL_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(vco_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PLL_CFG, SPEAR1340_PLL3_CLK_SHIFT,
|
||||
SPEAR1340_PLL_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "vco3_mclk", NULL);
|
||||
clk = clk_register_vco_pll("vco3_clk", "pll3_clk", NULL, "vco3_mclk", 0,
|
||||
SPEAR1340_PLL3_CTR, SPEAR1340_PLL3_FRQ, pll_rtbl,
|
||||
|
@ -561,8 +561,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "amba_syn_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "sys_mclk", sys_parents,
|
||||
ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL,
|
||||
SPEAR1340_SCLK_SRC_SEL_SHIFT,
|
||||
ARRAY_SIZE(sys_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_SYS_CLK_CTRL, SPEAR1340_SCLK_SRC_SEL_SHIFT,
|
||||
SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "sys_mclk", NULL);
|
||||
|
||||
|
@ -583,8 +583,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, NULL, "smp_twd");
|
||||
|
||||
clk = clk_register_mux(NULL, "ahb_clk", ahb_parents,
|
||||
ARRAY_SIZE(ahb_parents), 0, SPEAR1340_SYS_CLK_CTRL,
|
||||
SPEAR1340_HCLK_SRC_SEL_SHIFT,
|
||||
ARRAY_SIZE(ahb_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_SYS_CLK_CTRL, SPEAR1340_HCLK_SRC_SEL_SHIFT,
|
||||
SPEAR1340_HCLK_SRC_SEL_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "ahb_clk", NULL);
|
||||
|
||||
|
@ -594,9 +594,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
|
||||
/* gpt clocks */
|
||||
clk = clk_register_mux(NULL, "gpt0_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG,
|
||||
SPEAR1340_GPT0_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT0_CLK_SHIFT,
|
||||
SPEAR1340_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt0_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt0_clk", "gpt0_mclk", 0,
|
||||
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT0_CLK_ENB, 0,
|
||||
|
@ -604,9 +604,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, NULL, "gpt0");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt1_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG,
|
||||
SPEAR1340_GPT1_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT1_CLK_SHIFT,
|
||||
SPEAR1340_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt1_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0,
|
||||
SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_GPT1_CLK_ENB, 0,
|
||||
|
@ -614,9 +614,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, NULL, "gpt1");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt2_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG,
|
||||
SPEAR1340_GPT2_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT2_CLK_SHIFT,
|
||||
SPEAR1340_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt2_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0,
|
||||
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT2_CLK_ENB, 0,
|
||||
|
@ -624,9 +624,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, NULL, "gpt2");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt3_mclk", gpt_parents,
|
||||
ARRAY_SIZE(gpt_parents), 0, SPEAR1340_PERIP_CLK_CFG,
|
||||
SPEAR1340_GPT3_CLK_SHIFT, SPEAR1340_GPT_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gpt_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GPT3_CLK_SHIFT,
|
||||
SPEAR1340_GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt3_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0,
|
||||
SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_GPT3_CLK_ENB, 0,
|
||||
|
@ -641,7 +641,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "uart0_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents,
|
||||
ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart0_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART0_CLK_SHIFT,
|
||||
SPEAR1340_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart0_mclk", NULL);
|
||||
|
@ -658,9 +659,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "uart1_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "uart1_mclk", uart1_parents,
|
||||
ARRAY_SIZE(uart1_parents), 0, SPEAR1340_PERIP_CLK_CFG,
|
||||
SPEAR1340_UART1_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(uart1_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART1_CLK_SHIFT,
|
||||
SPEAR1340_UART_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "uart1_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart1_clk", "uart1_mclk", 0,
|
||||
|
@ -698,7 +699,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "c3_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "c3_mclk", c3_parents,
|
||||
ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(c3_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_C3_CLK_SHIFT,
|
||||
SPEAR1340_C3_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "c3_mclk", NULL);
|
||||
|
@ -710,8 +712,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
|
||||
/* gmac */
|
||||
clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents,
|
||||
ARRAY_SIZE(gmac_phy_input_parents), 0,
|
||||
SPEAR1340_GMAC_CLK_CFG,
|
||||
ARRAY_SIZE(gmac_phy_input_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1340_GMAC_CLK_CFG,
|
||||
SPEAR1340_GMAC_PHY_INPUT_CLK_SHIFT,
|
||||
SPEAR1340_GMAC_PHY_INPUT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "phy_input_mclk", NULL);
|
||||
|
@ -723,15 +725,16 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "phy_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "phy_mclk", gmac_phy_parents,
|
||||
ARRAY_SIZE(gmac_phy_parents), 0,
|
||||
ARRAY_SIZE(gmac_phy_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT,
|
||||
SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "stmmacphy.0", NULL);
|
||||
|
||||
/* clcd */
|
||||
clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents,
|
||||
ARRAY_SIZE(clcd_synth_parents), 0,
|
||||
SPEAR1340_CLCD_CLK_SYNT, SPEAR1340_CLCD_SYNT_CLK_SHIFT,
|
||||
ARRAY_SIZE(clcd_synth_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1340_CLCD_CLK_SYNT,
|
||||
SPEAR1340_CLCD_SYNT_CLK_SHIFT,
|
||||
SPEAR1340_CLCD_SYNT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "clcd_syn_mclk", NULL);
|
||||
|
||||
|
@ -741,7 +744,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "clcd_syn_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents,
|
||||
ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(clcd_pixel_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT,
|
||||
SPEAR1340_CLCD_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "clcd_pixel_mclk", NULL);
|
||||
|
@ -753,9 +757,9 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
|
||||
/* i2s */
|
||||
clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents,
|
||||
ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG,
|
||||
SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK,
|
||||
0, &_lock);
|
||||
ARRAY_SIZE(i2s_src_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_SRC_CLK_SHIFT,
|
||||
SPEAR1340_I2S_SRC_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2s_src_mclk", NULL);
|
||||
|
||||
clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk",
|
||||
|
@ -765,7 +769,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "i2s_prs1_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents,
|
||||
ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(i2s_ref_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_REF_SHIFT,
|
||||
SPEAR1340_I2S_REF_SEL_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2s_ref_mclk", NULL);
|
||||
|
@ -891,13 +896,15 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
|
||||
/* RAS clks */
|
||||
clk = clk_register_mux(NULL, "gen_syn0_1_mclk", gen_synth0_1_parents,
|
||||
ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1340_PLL_CFG,
|
||||
ARRAY_SIZE(gen_synth0_1_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1340_PLL_CFG,
|
||||
SPEAR1340_GEN_SYNT0_1_CLK_SHIFT,
|
||||
SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gen_syn0_1_mclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents,
|
||||
ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1340_PLL_CFG,
|
||||
ARRAY_SIZE(gen_synth2_3_parents),
|
||||
CLK_SET_RATE_NO_REPARENT, SPEAR1340_PLL_CFG,
|
||||
SPEAR1340_GEN_SYNT2_3_CLK_SHIFT,
|
||||
SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gen_syn2_3_mclk", NULL);
|
||||
|
@ -938,7 +945,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, NULL, "spear_cec.1");
|
||||
|
||||
clk = clk_register_mux(NULL, "spdif_out_mclk", spdif_out_parents,
|
||||
ARRAY_SIZE(spdif_out_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(spdif_out_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT,
|
||||
SPEAR1340_SPDIF_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "spdif_out_mclk", NULL);
|
||||
|
@ -949,7 +957,8 @@ void __init spear1340_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, NULL, "d0000000.spdif-out");
|
||||
|
||||
clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents,
|
||||
ARRAY_SIZE(spdif_in_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(spdif_in_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT,
|
||||
SPEAR1340_SPDIF_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "spdif_in_mclk", NULL);
|
||||
|
|
|
@ -294,7 +294,8 @@ static void __init spear320_clk_init(void __iomem *soc_config_base)
|
|||
clk_register_clkdev(clk, NULL, "a9400000.i2s");
|
||||
|
||||
clk = clk_register_mux(NULL, "i2s_ref_clk", i2s_ref_parents,
|
||||
ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(i2s_ref_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_CONTROL_REG, I2S_REF_PCLK_SHIFT,
|
||||
I2S_REF_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "i2s_ref_clk", NULL);
|
||||
|
@ -313,57 +314,66 @@ static void __init spear320_clk_init(void __iomem *soc_config_base)
|
|||
clk_register_clkdev(clk, "hclk", "ab000000.eth");
|
||||
|
||||
clk = clk_register_mux(NULL, "rs485_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_EXT_CTRL_REG, SPEAR320_RS485_PCLK_SHIFT,
|
||||
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "a9300000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "sdhci_clk", sdhci_parents,
|
||||
ARRAY_SIZE(sdhci_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(sdhci_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_CONTROL_REG, SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK,
|
||||
0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "70000000.sdhci");
|
||||
|
||||
clk = clk_register_mux(NULL, "smii_pclk", smii0_parents,
|
||||
ARRAY_SIZE(smii0_parents), 0, SPEAR320_CONTROL_REG,
|
||||
SMII_PCLK_SHIFT, SMII_PCLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(smii0_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_CONTROL_REG, SMII_PCLK_SHIFT, SMII_PCLK_MASK,
|
||||
0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "smii_pclk");
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "smii_clk", "smii_pclk", 0, 1, 1);
|
||||
clk_register_clkdev(clk, NULL, "smii");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart1_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_CONTROL_REG, UART1_PCLK_SHIFT, UART1_PCLK_MASK,
|
||||
0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "a3000000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart2_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_EXT_CTRL_REG, SPEAR320_UART2_PCLK_SHIFT,
|
||||
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "a4000000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart3_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_EXT_CTRL_REG, SPEAR320_UART3_PCLK_SHIFT,
|
||||
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "a9100000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart4_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_EXT_CTRL_REG, SPEAR320_UART4_PCLK_SHIFT,
|
||||
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "a9200000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart5_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_EXT_CTRL_REG, SPEAR320_UART5_PCLK_SHIFT,
|
||||
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "60000000.serial");
|
||||
|
||||
clk = clk_register_mux(NULL, "uart6_clk", uartx_parents,
|
||||
ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uartx_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SPEAR320_EXT_CTRL_REG, SPEAR320_UART6_PCLK_SHIFT,
|
||||
SPEAR320_UARTX_PCLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "60100000.serial");
|
||||
|
@ -427,7 +437,8 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
|
|||
clk_register_clkdev(clk1, "uart_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents,
|
||||
ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(uart0_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0,
|
||||
&_lock);
|
||||
clk_register_clkdev(clk, "uart0_mclk", NULL);
|
||||
|
@ -444,7 +455,8 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
|
|||
clk_register_clkdev(clk1, "firda_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "firda_mclk", firda_parents,
|
||||
ARRAY_SIZE(firda_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(firda_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0,
|
||||
&_lock);
|
||||
clk_register_clkdev(clk, "firda_mclk", NULL);
|
||||
|
@ -458,14 +470,16 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
|
|||
clk_register_gpt("gpt0_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl,
|
||||
ARRAY_SIZE(gpt_rtbl), &_lock);
|
||||
clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents,
|
||||
ARRAY_SIZE(gpt0_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(gpt0_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "gpt0");
|
||||
|
||||
clk_register_gpt("gpt1_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl,
|
||||
ARRAY_SIZE(gpt_rtbl), &_lock);
|
||||
clk = clk_register_mux(NULL, "gpt1_mclk", gpt1_parents,
|
||||
ARRAY_SIZE(gpt1_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(gpt1_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt1_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk",
|
||||
|
@ -476,7 +490,8 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
|
|||
clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl,
|
||||
ARRAY_SIZE(gpt_rtbl), &_lock);
|
||||
clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents,
|
||||
ARRAY_SIZE(gpt2_parents), CLK_SET_RATE_PARENT,
|
||||
ARRAY_SIZE(gpt2_parents),
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt2_mclk", NULL);
|
||||
clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk",
|
||||
|
@ -498,9 +513,9 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
|
|||
clk_register_clkdev(clk1, "gen1_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "gen2_3_par_clk", gen2_3_parents,
|
||||
ARRAY_SIZE(gen2_3_parents), 0, CORE_CLK_CFG,
|
||||
GEN_SYNTH2_3_CLK_SHIFT, GEN_SYNTH2_3_CLK_MASK, 0,
|
||||
&_lock);
|
||||
ARRAY_SIZE(gen2_3_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
CORE_CLK_CFG, GEN_SYNTH2_3_CLK_SHIFT,
|
||||
GEN_SYNTH2_3_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gen2_3_par_clk", NULL);
|
||||
|
||||
clk = clk_register_aux("gen2_syn_clk", "gen2_syn_gclk",
|
||||
|
@ -540,8 +555,8 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_
|
|||
clk_register_clkdev(clk, "ahbmult2_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "ddr_clk", ddr_parents,
|
||||
ARRAY_SIZE(ddr_parents), 0, PLL_CLK_CFG, MCTR_CLK_SHIFT,
|
||||
MCTR_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(ddr_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PLL_CLK_CFG, MCTR_CLK_SHIFT, MCTR_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "ddr_clk", NULL);
|
||||
|
||||
clk = clk_register_divider(NULL, "apb_clk", "ahb_clk",
|
||||
|
|
|
@ -169,8 +169,9 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "uart_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "uart_mclk", uart_parents,
|
||||
ARRAY_SIZE(uart_parents), 0, PERIP_CLK_CFG,
|
||||
UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(uart_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0,
|
||||
&_lock);
|
||||
clk_register_clkdev(clk, "uart_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "uart0", "uart_mclk", 0, PERIP1_CLK_ENB,
|
||||
|
@ -188,8 +189,9 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "firda_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "firda_mclk", firda_parents,
|
||||
ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG,
|
||||
FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(firda_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0,
|
||||
&_lock);
|
||||
clk_register_clkdev(clk, "firda_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0,
|
||||
|
@ -203,8 +205,9 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk1, "clcd_syn_gclk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "clcd_mclk", clcd_parents,
|
||||
ARRAY_SIZE(clcd_parents), 0, PERIP_CLK_CFG,
|
||||
CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(clcd_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, CLCD_CLK_SHIFT, CLCD_CLK_MASK, 0,
|
||||
&_lock);
|
||||
clk_register_clkdev(clk, "clcd_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "clcd_clk", "clcd_mclk", 0,
|
||||
|
@ -217,13 +220,13 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "gpt0_1_syn_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt0_mclk", gpt0_1_parents,
|
||||
ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG,
|
||||
GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(gpt0_1_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, NULL, "gpt0");
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt1_mclk", gpt0_1_parents,
|
||||
ARRAY_SIZE(gpt0_1_parents), 0, PERIP_CLK_CFG,
|
||||
GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(gpt0_1_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt1_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0,
|
||||
|
@ -235,8 +238,8 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "gpt2_syn_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents,
|
||||
ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG,
|
||||
GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(gpt2_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt2_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0,
|
||||
|
@ -248,8 +251,8 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "gpt3_syn_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "gpt3_mclk", gpt3_parents,
|
||||
ARRAY_SIZE(gpt3_parents), 0, PERIP_CLK_CFG,
|
||||
GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(gpt3_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PERIP_CLK_CFG, GPT3_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "gpt3_mclk", NULL);
|
||||
|
||||
clk = clk_register_gate(NULL, "gpt3_clk", "gpt3_mclk", 0,
|
||||
|
@ -277,8 +280,8 @@ void __init spear6xx_clk_init(void __iomem *misc_base)
|
|||
clk_register_clkdev(clk, "ahbmult2_clk", NULL);
|
||||
|
||||
clk = clk_register_mux(NULL, "ddr_clk", ddr_parents,
|
||||
ARRAY_SIZE(ddr_parents), 0, PLL_CLK_CFG, MCTR_CLK_SHIFT,
|
||||
MCTR_CLK_MASK, 0, &_lock);
|
||||
ARRAY_SIZE(ddr_parents), CLK_SET_RATE_NO_REPARENT,
|
||||
PLL_CLK_CFG, MCTR_CLK_SHIFT, MCTR_CLK_MASK, 0, &_lock);
|
||||
clk_register_clkdev(clk, "ddr_clk", NULL);
|
||||
|
||||
clk = clk_register_divider(NULL, "apb_clk", "ahb_clk",
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
||||
/**
|
||||
* sunxi_osc_clk_setup() - Setup function for gatable oscillator
|
||||
* sun4i_osc_clk_setup() - Setup function for gatable oscillator
|
||||
*/
|
||||
|
||||
#define SUNXI_OSC24M_GATE 0
|
||||
|
||||
static void __init sunxi_osc_clk_setup(struct device_node *node)
|
||||
static void __init sun4i_osc_clk_setup(struct device_node *node)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_fixed_rate *fixed;
|
||||
|
@ -64,22 +64,23 @@ static void __init sunxi_osc_clk_setup(struct device_node *node)
|
|||
&gate->hw, &clk_gate_ops,
|
||||
CLK_IS_ROOT);
|
||||
|
||||
if (clk) {
|
||||
if (!IS_ERR(clk)) {
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
clk_register_clkdev(clk, clk_name, NULL);
|
||||
}
|
||||
}
|
||||
CLK_OF_DECLARE(sun4i_osc, "allwinner,sun4i-osc-clk", sun4i_osc_clk_setup);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1
|
||||
* sun4i_get_pll1_factors() - calculates n, k, m, p factors for PLL1
|
||||
* PLL1 rate is calculated as follows
|
||||
* rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
|
||||
* parent_rate is always 24Mhz
|
||||
*/
|
||||
|
||||
static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate,
|
||||
static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate,
|
||||
u8 *n, u8 *k, u8 *m, u8 *p)
|
||||
{
|
||||
u8 div;
|
||||
|
@ -124,15 +125,97 @@ static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate,
|
|||
*n = div / 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* sun6i_a31_get_pll1_factors() - calculates n, k and m factors for PLL1
|
||||
* PLL1 rate is calculated as follows
|
||||
* rate = parent_rate * (n + 1) * (k + 1) / (m + 1);
|
||||
* parent_rate should always be 24MHz
|
||||
*/
|
||||
static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate,
|
||||
u8 *n, u8 *k, u8 *m, u8 *p)
|
||||
{
|
||||
/*
|
||||
* We can operate only on MHz, this will make our life easier
|
||||
* later.
|
||||
*/
|
||||
u32 freq_mhz = *freq / 1000000;
|
||||
u32 parent_freq_mhz = parent_rate / 1000000;
|
||||
|
||||
/*
|
||||
* Round down the frequency to the closest multiple of either
|
||||
* 6 or 16
|
||||
*/
|
||||
u32 round_freq_6 = round_down(freq_mhz, 6);
|
||||
u32 round_freq_16 = round_down(freq_mhz, 16);
|
||||
|
||||
if (round_freq_6 > round_freq_16)
|
||||
freq_mhz = round_freq_6;
|
||||
else
|
||||
freq_mhz = round_freq_16;
|
||||
|
||||
*freq = freq_mhz * 1000000;
|
||||
|
||||
/*
|
||||
* If the factors pointer are null, we were just called to
|
||||
* round down the frequency.
|
||||
* Exit.
|
||||
*/
|
||||
if (n == NULL)
|
||||
return;
|
||||
|
||||
/* If the frequency is a multiple of 32 MHz, k is always 3 */
|
||||
if (!(freq_mhz % 32))
|
||||
*k = 3;
|
||||
/* If the frequency is a multiple of 9 MHz, k is always 2 */
|
||||
else if (!(freq_mhz % 9))
|
||||
*k = 2;
|
||||
/* If the frequency is a multiple of 8 MHz, k is always 1 */
|
||||
else if (!(freq_mhz % 8))
|
||||
*k = 1;
|
||||
/* Otherwise, we don't use the k factor */
|
||||
else
|
||||
*k = 0;
|
||||
|
||||
/*
|
||||
* If the frequency is a multiple of 2 but not a multiple of
|
||||
* 3, m is 3. This is the first time we use 6 here, yet we
|
||||
* will use it on several other places.
|
||||
* We use this number because it's the lowest frequency we can
|
||||
* generate (with n = 0, k = 0, m = 3), so every other frequency
|
||||
* somehow relates to this frequency.
|
||||
*/
|
||||
if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4)
|
||||
*m = 2;
|
||||
/*
|
||||
* If the frequency is a multiple of 6MHz, but the factor is
|
||||
* odd, m will be 3
|
||||
*/
|
||||
else if ((freq_mhz / 6) & 1)
|
||||
*m = 3;
|
||||
/* Otherwise, we end up with m = 1 */
|
||||
else
|
||||
*m = 1;
|
||||
|
||||
/* Calculate n thanks to the above factors we already got */
|
||||
*n = freq_mhz * (*m + 1) / ((*k + 1) * parent_freq_mhz) - 1;
|
||||
|
||||
/*
|
||||
* If n end up being outbound, and that we can still decrease
|
||||
* m, do it.
|
||||
*/
|
||||
if ((*n + 1) > 31 && (*m + 1) > 1) {
|
||||
*n = (*n + 1) / 2 - 1;
|
||||
*m = (*m + 1) / 2 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* sunxi_get_apb1_factors() - calculates m, p factors for APB1
|
||||
* sun4i_get_apb1_factors() - calculates m, p factors for APB1
|
||||
* APB1 rate is calculated as follows
|
||||
* rate = (parent_rate >> p) / (m + 1);
|
||||
*/
|
||||
|
||||
static void sunxi_get_apb1_factors(u32 *freq, u32 parent_rate,
|
||||
static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate,
|
||||
u8 *n, u8 *k, u8 *m, u8 *p)
|
||||
{
|
||||
u8 calcm, calcp;
|
||||
|
@ -178,7 +261,7 @@ struct factors_data {
|
|||
void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
|
||||
};
|
||||
|
||||
static struct clk_factors_config pll1_config = {
|
||||
static struct clk_factors_config sun4i_pll1_config = {
|
||||
.nshift = 8,
|
||||
.nwidth = 5,
|
||||
.kshift = 4,
|
||||
|
@ -189,21 +272,35 @@ static struct clk_factors_config pll1_config = {
|
|||
.pwidth = 2,
|
||||
};
|
||||
|
||||
static struct clk_factors_config apb1_config = {
|
||||
static struct clk_factors_config sun6i_a31_pll1_config = {
|
||||
.nshift = 8,
|
||||
.nwidth = 5,
|
||||
.kshift = 4,
|
||||
.kwidth = 2,
|
||||
.mshift = 0,
|
||||
.mwidth = 2,
|
||||
};
|
||||
|
||||
static struct clk_factors_config sun4i_apb1_config = {
|
||||
.mshift = 0,
|
||||
.mwidth = 5,
|
||||
.pshift = 16,
|
||||
.pwidth = 2,
|
||||
};
|
||||
|
||||
static const __initconst struct factors_data pll1_data = {
|
||||
.table = &pll1_config,
|
||||
.getter = sunxi_get_pll1_factors,
|
||||
static const struct factors_data sun4i_pll1_data __initconst = {
|
||||
.table = &sun4i_pll1_config,
|
||||
.getter = sun4i_get_pll1_factors,
|
||||
};
|
||||
|
||||
static const __initconst struct factors_data apb1_data = {
|
||||
.table = &apb1_config,
|
||||
.getter = sunxi_get_apb1_factors,
|
||||
static const struct factors_data sun6i_a31_pll1_data __initconst = {
|
||||
.table = &sun6i_a31_pll1_config,
|
||||
.getter = sun6i_a31_get_pll1_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,
|
||||
|
@ -221,7 +318,7 @@ static void __init sunxi_factors_clk_setup(struct device_node *node,
|
|||
clk = clk_register_factors(NULL, clk_name, parent, 0, reg,
|
||||
data->table, data->getter, &clk_lock);
|
||||
|
||||
if (clk) {
|
||||
if (!IS_ERR(clk)) {
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
clk_register_clkdev(clk, clk_name, NULL);
|
||||
}
|
||||
|
@ -239,11 +336,15 @@ struct mux_data {
|
|||
u8 shift;
|
||||
};
|
||||
|
||||
static const __initconst struct mux_data cpu_mux_data = {
|
||||
static const struct mux_data sun4i_cpu_mux_data __initconst = {
|
||||
.shift = 16,
|
||||
};
|
||||
|
||||
static const __initconst struct mux_data apb1_mux_data = {
|
||||
static const struct mux_data sun6i_a31_ahb1_mux_data __initconst = {
|
||||
.shift = 12,
|
||||
};
|
||||
|
||||
static const struct mux_data sun4i_apb1_mux_data __initconst = {
|
||||
.shift = 24,
|
||||
};
|
||||
|
||||
|
@ -261,7 +362,8 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
|
|||
while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
|
||||
i++;
|
||||
|
||||
clk = clk_register_mux(NULL, clk_name, parents, i, 0, reg,
|
||||
clk = clk_register_mux(NULL, clk_name, parents, i,
|
||||
CLK_SET_RATE_NO_REPARENT, reg,
|
||||
data->shift, SUNXI_MUX_GATE_WIDTH,
|
||||
0, &clk_lock);
|
||||
|
||||
|
@ -277,26 +379,34 @@ static void __init sunxi_mux_clk_setup(struct device_node *node,
|
|||
* sunxi_divider_clk_setup() - Setup function for simple divider clocks
|
||||
*/
|
||||
|
||||
#define SUNXI_DIVISOR_WIDTH 2
|
||||
|
||||
struct div_data {
|
||||
u8 shift;
|
||||
u8 pow;
|
||||
u8 width;
|
||||
};
|
||||
|
||||
static const __initconst struct div_data axi_data = {
|
||||
static const struct div_data sun4i_axi_data __initconst = {
|
||||
.shift = 0,
|
||||
.pow = 0,
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static const __initconst struct div_data ahb_data = {
|
||||
static const struct div_data sun4i_ahb_data __initconst = {
|
||||
.shift = 4,
|
||||
.pow = 1,
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static const __initconst struct div_data apb0_data = {
|
||||
static const struct div_data sun4i_apb0_data __initconst = {
|
||||
.shift = 8,
|
||||
.pow = 1,
|
||||
.width = 2,
|
||||
};
|
||||
|
||||
static const struct div_data sun6i_a31_apb2_div_data __initconst = {
|
||||
.shift = 0,
|
||||
.pow = 0,
|
||||
.width = 4,
|
||||
};
|
||||
|
||||
static void __init sunxi_divider_clk_setup(struct device_node *node,
|
||||
|
@ -312,7 +422,7 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
|
|||
clk_parent = of_clk_get_parent_name(node, 0);
|
||||
|
||||
clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
|
||||
reg, data->shift, SUNXI_DIVISOR_WIDTH,
|
||||
reg, data->shift, data->width,
|
||||
data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
|
||||
&clk_lock);
|
||||
if (clk) {
|
||||
|
@ -333,34 +443,70 @@ struct gates_data {
|
|||
DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun4i_axi_gates_data = {
|
||||
static const struct gates_data sun4i_axi_gates_data __initconst = {
|
||||
.mask = {1},
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun4i_ahb_gates_data = {
|
||||
static const struct gates_data sun4i_ahb_gates_data __initconst = {
|
||||
.mask = {0x7F77FFF, 0x14FB3F},
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun5i_a13_ahb_gates_data = {
|
||||
static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
|
||||
.mask = {0x147667e7, 0x185915},
|
||||
};
|
||||
|
||||
static const struct gates_data sun5i_a13_ahb_gates_data __initconst = {
|
||||
.mask = {0x107067e7, 0x185111},
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun4i_apb0_gates_data = {
|
||||
static const struct gates_data sun6i_a31_ahb1_gates_data __initconst = {
|
||||
.mask = {0xEDFE7F62, 0x794F931},
|
||||
};
|
||||
|
||||
static const struct gates_data sun7i_a20_ahb_gates_data __initconst = {
|
||||
.mask = { 0x12f77fff, 0x16ff3f },
|
||||
};
|
||||
|
||||
static const struct gates_data sun4i_apb0_gates_data __initconst = {
|
||||
.mask = {0x4EF},
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun5i_a13_apb0_gates_data = {
|
||||
static const struct gates_data sun5i_a10s_apb0_gates_data __initconst = {
|
||||
.mask = {0x469},
|
||||
};
|
||||
|
||||
static const struct gates_data sun5i_a13_apb0_gates_data __initconst = {
|
||||
.mask = {0x61},
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun4i_apb1_gates_data = {
|
||||
static const struct gates_data sun7i_a20_apb0_gates_data __initconst = {
|
||||
.mask = { 0x4ff },
|
||||
};
|
||||
|
||||
static const struct gates_data sun4i_apb1_gates_data __initconst = {
|
||||
.mask = {0xFF00F7},
|
||||
};
|
||||
|
||||
static const __initconst struct gates_data sun5i_a13_apb1_gates_data = {
|
||||
static const struct gates_data sun5i_a10s_apb1_gates_data __initconst = {
|
||||
.mask = {0xf0007},
|
||||
};
|
||||
|
||||
static const struct gates_data sun5i_a13_apb1_gates_data __initconst = {
|
||||
.mask = {0xa0007},
|
||||
};
|
||||
|
||||
static const struct gates_data sun6i_a31_apb1_gates_data __initconst = {
|
||||
.mask = {0x3031},
|
||||
};
|
||||
|
||||
static const struct gates_data sun6i_a31_apb2_gates_data __initconst = {
|
||||
.mask = {0x3F000F},
|
||||
};
|
||||
|
||||
static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
|
||||
.mask = { 0xff80ff },
|
||||
};
|
||||
|
||||
static void __init sunxi_gates_clk_setup(struct device_node *node,
|
||||
struct gates_data *data)
|
||||
{
|
||||
|
@ -410,43 +556,49 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
|
|||
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
}
|
||||
|
||||
/* Matches for of_clk_init */
|
||||
static const __initconst struct of_device_id clk_match[] = {
|
||||
{.compatible = "allwinner,sun4i-osc-clk", .data = sunxi_osc_clk_setup,},
|
||||
{}
|
||||
};
|
||||
|
||||
/* Matches for factors clocks */
|
||||
static const __initconst struct of_device_id clk_factors_match[] = {
|
||||
{.compatible = "allwinner,sun4i-pll1-clk", .data = &pll1_data,},
|
||||
{.compatible = "allwinner,sun4i-apb1-clk", .data = &apb1_data,},
|
||||
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,},
|
||||
{}
|
||||
};
|
||||
|
||||
/* Matches for divider clocks */
|
||||
static const __initconst struct of_device_id clk_div_match[] = {
|
||||
{.compatible = "allwinner,sun4i-axi-clk", .data = &axi_data,},
|
||||
{.compatible = "allwinner,sun4i-ahb-clk", .data = &ahb_data,},
|
||||
{.compatible = "allwinner,sun4i-apb0-clk", .data = &apb0_data,},
|
||||
static const struct of_device_id clk_div_match[] __initconst = {
|
||||
{.compatible = "allwinner,sun4i-axi-clk", .data = &sun4i_axi_data,},
|
||||
{.compatible = "allwinner,sun4i-ahb-clk", .data = &sun4i_ahb_data,},
|
||||
{.compatible = "allwinner,sun4i-apb0-clk", .data = &sun4i_apb0_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-apb2-div-clk", .data = &sun6i_a31_apb2_div_data,},
|
||||
{}
|
||||
};
|
||||
|
||||
/* Matches for mux clocks */
|
||||
static const __initconst struct of_device_id clk_mux_match[] = {
|
||||
{.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_mux_data,},
|
||||
{.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,},
|
||||
static const struct of_device_id clk_mux_match[] __initconst = {
|
||||
{.compatible = "allwinner,sun4i-cpu-clk", .data = &sun4i_cpu_mux_data,},
|
||||
{.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &sun4i_apb1_mux_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,},
|
||||
{}
|
||||
};
|
||||
|
||||
/* Matches for gate clocks */
|
||||
static const __initconst struct of_device_id clk_gates_match[] = {
|
||||
static const struct of_device_id clk_gates_match[] __initconst = {
|
||||
{.compatible = "allwinner,sun4i-axi-gates-clk", .data = &sun4i_axi_gates_data,},
|
||||
{.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
|
||||
{.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
|
||||
{.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
|
||||
{.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,},
|
||||
{.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &sun4i_apb1_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
|
||||
{.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -467,8 +619,8 @@ static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_mat
|
|||
|
||||
void __init sunxi_init_clocks(void)
|
||||
{
|
||||
/* Register all the simple sunxi clocks on DT */
|
||||
of_clk_init(clk_match);
|
||||
/* Register all the simple and basic clocks on DT */
|
||||
of_clk_init(NULL);
|
||||
|
||||
/* Register factor clocks */
|
||||
of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
|
||||
|
|
|
@ -1566,7 +1566,8 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* audio0 */
|
||||
clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0,
|
||||
NULL);
|
||||
clks[audio0_mux] = clk;
|
||||
|
@ -1578,7 +1579,8 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* audio1 */
|
||||
clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0,
|
||||
NULL);
|
||||
clks[audio1_mux] = clk;
|
||||
|
@ -1590,7 +1592,8 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* audio2 */
|
||||
clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0,
|
||||
NULL);
|
||||
clks[audio2_mux] = clk;
|
||||
|
@ -1602,7 +1605,8 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* audio3 */
|
||||
clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0,
|
||||
NULL);
|
||||
clks[audio3_mux] = clk;
|
||||
|
@ -1614,7 +1618,8 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* audio4 */
|
||||
clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0,
|
||||
NULL);
|
||||
clks[audio4_mux] = clk;
|
||||
|
@ -1626,7 +1631,8 @@ static void __init tegra114_audio_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* spdif */
|
||||
clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0,
|
||||
NULL);
|
||||
clks[spdif_mux] = clk;
|
||||
|
@ -1721,7 +1727,8 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base)
|
|||
|
||||
/* clk_out_1 */
|
||||
clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents,
|
||||
ARRAY_SIZE(clk_out1_parents), 0,
|
||||
ARRAY_SIZE(clk_out1_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0,
|
||||
&clk_out_lock);
|
||||
clks[clk_out_1_mux] = clk;
|
||||
|
@ -1733,7 +1740,8 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base)
|
|||
|
||||
/* clk_out_2 */
|
||||
clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
|
||||
ARRAY_SIZE(clk_out2_parents), 0,
|
||||
ARRAY_SIZE(clk_out2_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
|
||||
&clk_out_lock);
|
||||
clks[clk_out_2_mux] = clk;
|
||||
|
@ -1745,7 +1753,8 @@ static void __init tegra114_pmc_clk_init(void __iomem *pmc_base)
|
|||
|
||||
/* clk_out_3 */
|
||||
clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
|
||||
ARRAY_SIZE(clk_out3_parents), 0,
|
||||
ARRAY_SIZE(clk_out3_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
|
||||
&clk_out_lock);
|
||||
clks[clk_out_3_mux] = clk;
|
||||
|
@ -2063,7 +2072,8 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* dsia */
|
||||
clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,
|
||||
ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
|
||||
ARRAY_SIZE(mux_plld_out0_plld2_out0),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock);
|
||||
clks[dsia_mux] = clk;
|
||||
clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base,
|
||||
|
@ -2073,7 +2083,8 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* dsib */
|
||||
clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0,
|
||||
ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
|
||||
ARRAY_SIZE(mux_plld_out0_plld2_out0),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock);
|
||||
clks[dsib_mux] = clk;
|
||||
clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base,
|
||||
|
@ -2110,7 +2121,8 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base)
|
|||
|
||||
/* emc */
|
||||
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm), 0,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
29, 3, 0, NULL);
|
||||
clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base,
|
||||
|
@ -2194,7 +2206,7 @@ static const struct of_device_id pmc_match[] __initconst = {
|
|||
* dfll_soc/dfll_ref apparently must be kept enabled, otherwise I2C5
|
||||
* breaks
|
||||
*/
|
||||
static __initdata struct tegra_clk_init_table init_table[] = {
|
||||
static struct tegra_clk_init_table init_table[] __initdata = {
|
||||
{uarta, pll_p, 408000000, 0},
|
||||
{uartb, pll_p, 408000000, 0},
|
||||
{uartc, pll_p, 408000000, 0},
|
||||
|
|
|
@ -778,7 +778,8 @@ static void __init tegra20_audio_clk_init(void)
|
|||
|
||||
/* audio */
|
||||
clk = clk_register_mux(NULL, "audio_mux", audio_parents,
|
||||
ARRAY_SIZE(audio_parents), 0,
|
||||
ARRAY_SIZE(audio_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "audio", "audio_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK, 4,
|
||||
|
@ -941,7 +942,8 @@ static void __init tegra20_periph_clk_init(void)
|
|||
|
||||
/* emc */
|
||||
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm), 0,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
30, 2, 0, NULL);
|
||||
clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
|
||||
|
@ -1223,7 +1225,7 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static __initdata struct tegra_clk_init_table init_table[] = {
|
||||
static struct tegra_clk_init_table init_table[] __initdata = {
|
||||
{pll_p, clk_max, 216000000, 1},
|
||||
{pll_p_out1, clk_max, 28800000, 1},
|
||||
{pll_p_out2, clk_max, 48000000, 1},
|
||||
|
|
|
@ -971,7 +971,7 @@ static void __init tegra30_pll_init(void)
|
|||
/* PLLU */
|
||||
clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc_base, 0,
|
||||
0, &pll_u_params, TEGRA_PLLU | TEGRA_PLL_HAS_CPCON |
|
||||
TEGRA_PLL_SET_LFCON | TEGRA_PLL_USE_LOCK,
|
||||
TEGRA_PLL_SET_LFCON,
|
||||
pll_u_freq_table,
|
||||
NULL);
|
||||
clk_register_clkdev(clk, "pll_u", NULL);
|
||||
|
@ -1026,7 +1026,8 @@ static void __init tegra30_pll_init(void)
|
|||
|
||||
/* PLLE */
|
||||
clk = clk_register_mux(NULL, "pll_e_mux", pll_e_parents,
|
||||
ARRAY_SIZE(pll_e_parents), 0,
|
||||
ARRAY_SIZE(pll_e_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + PLLE_AUX, 2, 1, 0, NULL);
|
||||
clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
|
||||
CLK_GET_RATE_NOCACHE, 100000000, &pll_e_params,
|
||||
|
@ -1086,7 +1087,8 @@ static void __init tegra30_audio_clk_init(void)
|
|||
|
||||
/* audio0 */
|
||||
clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S0, 4,
|
||||
|
@ -1096,7 +1098,8 @@ static void __init tegra30_audio_clk_init(void)
|
|||
|
||||
/* audio1 */
|
||||
clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S1, 4,
|
||||
|
@ -1106,7 +1109,8 @@ static void __init tegra30_audio_clk_init(void)
|
|||
|
||||
/* audio2 */
|
||||
clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S2, 4,
|
||||
|
@ -1116,7 +1120,8 @@ static void __init tegra30_audio_clk_init(void)
|
|||
|
||||
/* audio3 */
|
||||
clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S3, 4,
|
||||
|
@ -1126,7 +1131,8 @@ static void __init tegra30_audio_clk_init(void)
|
|||
|
||||
/* audio4 */
|
||||
clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK_I2S4, 4,
|
||||
|
@ -1136,7 +1142,8 @@ static void __init tegra30_audio_clk_init(void)
|
|||
|
||||
/* spdif */
|
||||
clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk,
|
||||
ARRAY_SIZE(mux_audio_sync_clk), 0,
|
||||
ARRAY_SIZE(mux_audio_sync_clk),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0, NULL);
|
||||
clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0,
|
||||
clk_base + AUDIO_SYNC_CLK_SPDIF, 4,
|
||||
|
@ -1229,7 +1236,8 @@ static void __init tegra30_pmc_clk_init(void)
|
|||
|
||||
/* clk_out_1 */
|
||||
clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents,
|
||||
ARRAY_SIZE(clk_out1_parents), 0,
|
||||
ARRAY_SIZE(clk_out1_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0,
|
||||
&clk_out_lock);
|
||||
clks[clk_out_1_mux] = clk;
|
||||
|
@ -1241,7 +1249,8 @@ static void __init tegra30_pmc_clk_init(void)
|
|||
|
||||
/* clk_out_2 */
|
||||
clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
|
||||
ARRAY_SIZE(clk_out2_parents), 0,
|
||||
ARRAY_SIZE(clk_out2_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
|
||||
&clk_out_lock);
|
||||
clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0,
|
||||
|
@ -1252,7 +1261,8 @@ static void __init tegra30_pmc_clk_init(void)
|
|||
|
||||
/* clk_out_3 */
|
||||
clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
|
||||
ARRAY_SIZE(clk_out3_parents), 0,
|
||||
ARRAY_SIZE(clk_out3_parents),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
|
||||
&clk_out_lock);
|
||||
clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0,
|
||||
|
@ -1679,7 +1689,8 @@ static void __init tegra30_periph_clk_init(void)
|
|||
|
||||
/* emc */
|
||||
clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm), 0,
|
||||
ARRAY_SIZE(mux_pllmcp_clkm),
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
clk_base + CLK_SOURCE_EMC,
|
||||
30, 2, 0, NULL);
|
||||
clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base, 0,
|
||||
|
@ -1901,7 +1912,7 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static __initdata struct tegra_clk_init_table init_table[] = {
|
||||
static struct tegra_clk_init_table init_table[] __initdata = {
|
||||
{uarta, pll_p, 408000000, 0},
|
||||
{uartb, pll_p, 408000000, 0},
|
||||
{uartc, pll_p, 408000000, 0},
|
||||
|
|
|
@ -37,8 +37,8 @@ static void __init vexpress_sp810_init(void __iomem *base)
|
|||
snprintf(name, ARRAY_SIZE(name), "timerclken%d", i);
|
||||
|
||||
vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name,
|
||||
parents, 2, 0, base + SCCTRL,
|
||||
SCCTRL_TIMERENnSEL_SHIFT(i), 1,
|
||||
parents, 2, CLK_SET_RATE_NO_REPARENT,
|
||||
base + SCCTRL, SCCTRL_TIMERENnSEL_SHIFT(i), 1,
|
||||
0, &vexpress_sp810_lock);
|
||||
|
||||
if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i])))
|
||||
|
|
|
@ -125,8 +125,9 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
|
|||
div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
|
||||
div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
|
||||
|
||||
clk = clk_register_mux(NULL, mux_name, parents, 4, 0,
|
||||
fclk_ctrl_reg, 4, 2, 0, fclk_lock);
|
||||
clk = clk_register_mux(NULL, mux_name, parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0,
|
||||
fclk_lock);
|
||||
|
||||
clk = clk_register_divider(NULL, div0_name, mux_name,
|
||||
0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED |
|
||||
|
@ -168,8 +169,8 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
|
|||
mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0);
|
||||
div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0);
|
||||
|
||||
clk = clk_register_mux(NULL, mux_name, parents, 4, 0,
|
||||
clk_ctrl, 4, 2, 0, lock);
|
||||
clk = clk_register_mux(NULL, mux_name, parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock);
|
||||
|
||||
clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6,
|
||||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock);
|
||||
|
@ -236,25 +237,26 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL,
|
||||
SLCR_PLL_STATUS, 0, &armpll_lock);
|
||||
clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll],
|
||||
armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0,
|
||||
&armpll_lock);
|
||||
armpll_parents, 2, CLK_SET_RATE_NO_REPARENT,
|
||||
SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock);
|
||||
|
||||
clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL,
|
||||
SLCR_PLL_STATUS, 1, &ddrpll_lock);
|
||||
clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll],
|
||||
ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0,
|
||||
&ddrpll_lock);
|
||||
ddrpll_parents, 2, CLK_SET_RATE_NO_REPARENT,
|
||||
SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock);
|
||||
|
||||
clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL,
|
||||
SLCR_PLL_STATUS, 2, &iopll_lock);
|
||||
clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll],
|
||||
iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0,
|
||||
&iopll_lock);
|
||||
iopll_parents, 2, CLK_SET_RATE_NO_REPARENT,
|
||||
SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock);
|
||||
|
||||
/* CPU clocks */
|
||||
tmp = readl(SLCR_621_TRUE) & 1;
|
||||
clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0,
|
||||
SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock);
|
||||
clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0,
|
||||
&armclk_lock);
|
||||
clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0,
|
||||
SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
|
||||
CLK_DIVIDER_ALLOW_ZERO, &armclk_lock);
|
||||
|
@ -293,8 +295,9 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
swdt_ext_clk_mux_parents[i + 1] = dummy_nm;
|
||||
}
|
||||
clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt],
|
||||
swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT,
|
||||
SLCR_SWDT_CLK_SEL, 0, 1, 0, &swdtclk_lock);
|
||||
swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT |
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0,
|
||||
&swdtclk_lock);
|
||||
|
||||
/* DDR clocks */
|
||||
clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0,
|
||||
|
@ -356,8 +359,9 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
gem0_mux_parents[i + 1] = of_clk_get_parent_name(np,
|
||||
idx);
|
||||
}
|
||||
clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0,
|
||||
SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock);
|
||||
clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 4, 2, 0,
|
||||
&gem0clk_lock);
|
||||
clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0,
|
||||
SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
|
||||
CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock);
|
||||
|
@ -366,7 +370,8 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
&gem0clk_lock);
|
||||
clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2,
|
||||
CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0,
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SLCR_GEM0_CLK_CTRL, 6, 1, 0,
|
||||
&gem0clk_lock);
|
||||
clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0],
|
||||
"gem0_emio_mux", CLK_SET_RATE_PARENT,
|
||||
|
@ -379,8 +384,9 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
gem1_mux_parents[i + 1] = of_clk_get_parent_name(np,
|
||||
idx);
|
||||
}
|
||||
clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0,
|
||||
SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock);
|
||||
clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 4, 2, 0,
|
||||
&gem1clk_lock);
|
||||
clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0,
|
||||
SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
|
||||
CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock);
|
||||
|
@ -389,7 +395,8 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
&gem1clk_lock);
|
||||
clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2,
|
||||
CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0,
|
||||
CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
SLCR_GEM1_CLK_CTRL, 6, 1, 0,
|
||||
&gem1clk_lock);
|
||||
clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1],
|
||||
"gem1_emio_mux", CLK_SET_RATE_PARENT,
|
||||
|
@ -409,8 +416,9 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
can_mio_mux_parents[i] = dummy_nm;
|
||||
}
|
||||
kfree(clk_name);
|
||||
clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0,
|
||||
SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock);
|
||||
clk = clk_register_mux(NULL, "can_mux", periph_parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0,
|
||||
&canclk_lock);
|
||||
clk = clk_register_divider(NULL, "can_div0", "can_mux", 0,
|
||||
SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
|
||||
CLK_DIVIDER_ALLOW_ZERO, &canclk_lock);
|
||||
|
@ -425,17 +433,21 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0,
|
||||
&canclk_lock);
|
||||
clk = clk_register_mux(NULL, "can0_mio_mux",
|
||||
can_mio_mux_parents, 54, CLK_SET_RATE_PARENT,
|
||||
SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock);
|
||||
can_mio_mux_parents, 54, CLK_SET_RATE_PARENT |
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0,
|
||||
&canmioclk_lock);
|
||||
clk = clk_register_mux(NULL, "can1_mio_mux",
|
||||
can_mio_mux_parents, 54, CLK_SET_RATE_PARENT,
|
||||
SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock);
|
||||
can_mio_mux_parents, 54, CLK_SET_RATE_PARENT |
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6,
|
||||
0, &canmioclk_lock);
|
||||
clks[can0] = clk_register_mux(NULL, clk_output_name[can0],
|
||||
can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT,
|
||||
SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock);
|
||||
can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT |
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0,
|
||||
&canmioclk_lock);
|
||||
clks[can1] = clk_register_mux(NULL, clk_output_name[can1],
|
||||
can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT,
|
||||
SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock);
|
||||
can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT |
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1,
|
||||
0, &canmioclk_lock);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) {
|
||||
int idx = of_property_match_string(np, "clock-names",
|
||||
|
@ -444,13 +456,15 @@ static void __init zynq_clk_setup(struct device_node *np)
|
|||
dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np,
|
||||
idx);
|
||||
}
|
||||
clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0,
|
||||
SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock);
|
||||
clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4,
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 4, 2, 0,
|
||||
&dbgclk_lock);
|
||||
clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0,
|
||||
SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
|
||||
CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock);
|
||||
clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0,
|
||||
SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock);
|
||||
clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2,
|
||||
CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 6, 1, 0,
|
||||
&dbgclk_lock);
|
||||
clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc],
|
||||
"dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL,
|
||||
0, 0, &dbgclk_lock);
|
||||
|
|
|
@ -50,6 +50,9 @@ struct zynq_pll {
|
|||
#define PLLCTRL_RESET_MASK 1
|
||||
#define PLLCTRL_RESET_SHIFT 0
|
||||
|
||||
#define PLL_FBDIV_MIN 13
|
||||
#define PLL_FBDIV_MAX 66
|
||||
|
||||
/**
|
||||
* zynq_pll_round_rate() - Round a clock frequency
|
||||
* @hw: Handle between common and hardware-specific interfaces
|
||||
|
@ -63,10 +66,10 @@ static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
u32 fbdiv;
|
||||
|
||||
fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
|
||||
if (fbdiv < 13)
|
||||
fbdiv = 13;
|
||||
else if (fbdiv > 66)
|
||||
fbdiv = 66;
|
||||
if (fbdiv < PLL_FBDIV_MIN)
|
||||
fbdiv = PLL_FBDIV_MIN;
|
||||
else if (fbdiv > PLL_FBDIV_MAX)
|
||||
fbdiv = PLL_FBDIV_MAX;
|
||||
|
||||
return *prate * fbdiv;
|
||||
}
|
||||
|
@ -182,7 +185,13 @@ static const struct clk_ops zynq_pll_ops = {
|
|||
|
||||
/**
|
||||
* clk_register_zynq_pll() - Register PLL with the clock framework
|
||||
* @np Pointer to the DT device node
|
||||
* @name PLL name
|
||||
* @parent Parent clock name
|
||||
* @pll_ctrl Pointer to PLL control register
|
||||
* @pll_status Pointer to PLL status register
|
||||
* @lock_index Bit index to this PLL's lock status bit in @pll_status
|
||||
* @lock Register lock
|
||||
* Returns handle to the registered clock.
|
||||
*/
|
||||
struct clk *clk_register_zynq_pll(const char *name, const char *parent,
|
||||
void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
|
||||
|
|
|
@ -368,10 +368,6 @@ static void __init samsung_clocksource_init(void)
|
|||
|
||||
static void __init samsung_timer_resources(void)
|
||||
{
|
||||
pwm.timerclk = clk_get(NULL, "timers");
|
||||
if (IS_ERR(pwm.timerclk))
|
||||
panic("failed to get timers clock for timer");
|
||||
|
||||
clk_prepare_enable(pwm.timerclk);
|
||||
|
||||
pwm.tcnt_max = (1UL << pwm.variant.bits) - 1;
|
||||
|
@ -416,6 +412,10 @@ void __init samsung_pwm_clocksource_init(void __iomem *base,
|
|||
memcpy(&pwm.variant, variant, sizeof(pwm.variant));
|
||||
memcpy(pwm.irq, irqs, SAMSUNG_PWM_NUM * sizeof(*irqs));
|
||||
|
||||
pwm.timerclk = clk_get(NULL, "timers");
|
||||
if (IS_ERR(pwm.timerclk))
|
||||
panic("failed to get timers clock for timer");
|
||||
|
||||
_samsung_pwm_clocksource_init();
|
||||
}
|
||||
|
||||
|
@ -447,6 +447,10 @@ static void __init samsung_pwm_alloc(struct device_node *np,
|
|||
return;
|
||||
}
|
||||
|
||||
pwm.timerclk = of_clk_get_by_name(np, "timers");
|
||||
if (IS_ERR(pwm.timerclk))
|
||||
panic("failed to get timers clock for timer");
|
||||
|
||||
_samsung_pwm_clocksource_init();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Tomasz Figa <tomasz.figa at gmail.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 Samsung S3C64xx clock controller.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
|
||||
#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H
|
||||
|
||||
/*
|
||||
* Let each exported clock get a unique index, which is used on DT-enabled
|
||||
* platforms to lookup the clock from a clock specifier. These indices are
|
||||
* therefore considered an ABI and so must not be changed. This implies
|
||||
* that new clocks should be added either in free spaces between clock groups
|
||||
* or at the end.
|
||||
*/
|
||||
|
||||
/* Core clocks. */
|
||||
#define CLK27M 1
|
||||
#define CLK48M 2
|
||||
#define FOUT_APLL 3
|
||||
#define FOUT_MPLL 4
|
||||
#define FOUT_EPLL 5
|
||||
#define ARMCLK 6
|
||||
#define HCLKX2 7
|
||||
#define HCLK 8
|
||||
#define PCLK 9
|
||||
|
||||
/* HCLK bus clocks. */
|
||||
#define HCLK_3DSE 16
|
||||
#define HCLK_UHOST 17
|
||||
#define HCLK_SECUR 18
|
||||
#define HCLK_SDMA1 19
|
||||
#define HCLK_SDMA0 20
|
||||
#define HCLK_IROM 21
|
||||
#define HCLK_DDR1 22
|
||||
#define HCLK_MEM1 23
|
||||
#define HCLK_MEM0 24
|
||||
#define HCLK_USB 25
|
||||
#define HCLK_HSMMC2 26
|
||||
#define HCLK_HSMMC1 27
|
||||
#define HCLK_HSMMC0 28
|
||||
#define HCLK_MDP 29
|
||||
#define HCLK_DHOST 30
|
||||
#define HCLK_IHOST 31
|
||||
#define HCLK_DMA1 32
|
||||
#define HCLK_DMA0 33
|
||||
#define HCLK_JPEG 34
|
||||
#define HCLK_CAMIF 35
|
||||
#define HCLK_SCALER 36
|
||||
#define HCLK_2D 37
|
||||
#define HCLK_TV 38
|
||||
#define HCLK_POST0 39
|
||||
#define HCLK_ROT 40
|
||||
#define HCLK_LCD 41
|
||||
#define HCLK_TZIC 42
|
||||
#define HCLK_INTC 43
|
||||
#define HCLK_MFC 44
|
||||
#define HCLK_DDR0 45
|
||||
|
||||
/* PCLK bus clocks. */
|
||||
#define PCLK_IIC1 48
|
||||
#define PCLK_IIS2 49
|
||||
#define PCLK_SKEY 50
|
||||
#define PCLK_CHIPID 51
|
||||
#define PCLK_SPI1 52
|
||||
#define PCLK_SPI0 53
|
||||
#define PCLK_HSIRX 54
|
||||
#define PCLK_HSITX 55
|
||||
#define PCLK_GPIO 56
|
||||
#define PCLK_IIC0 57
|
||||
#define PCLK_IIS1 58
|
||||
#define PCLK_IIS0 59
|
||||
#define PCLK_AC97 60
|
||||
#define PCLK_TZPC 61
|
||||
#define PCLK_TSADC 62
|
||||
#define PCLK_KEYPAD 63
|
||||
#define PCLK_IRDA 64
|
||||
#define PCLK_PCM1 65
|
||||
#define PCLK_PCM0 66
|
||||
#define PCLK_PWM 67
|
||||
#define PCLK_RTC 68
|
||||
#define PCLK_WDT 69
|
||||
#define PCLK_UART3 70
|
||||
#define PCLK_UART2 71
|
||||
#define PCLK_UART1 72
|
||||
#define PCLK_UART0 73
|
||||
#define PCLK_MFC 74
|
||||
|
||||
/* Special clocks. */
|
||||
#define SCLK_UHOST 80
|
||||
#define SCLK_MMC2_48 81
|
||||
#define SCLK_MMC1_48 82
|
||||
#define SCLK_MMC0_48 83
|
||||
#define SCLK_MMC2 84
|
||||
#define SCLK_MMC1 85
|
||||
#define SCLK_MMC0 86
|
||||
#define SCLK_SPI1_48 87
|
||||
#define SCLK_SPI0_48 88
|
||||
#define SCLK_SPI1 89
|
||||
#define SCLK_SPI0 90
|
||||
#define SCLK_DAC27 91
|
||||
#define SCLK_TV27 92
|
||||
#define SCLK_SCALER27 93
|
||||
#define SCLK_SCALER 94
|
||||
#define SCLK_LCD27 95
|
||||
#define SCLK_LCD 96
|
||||
#define SCLK_FIMC 97
|
||||
#define SCLK_POST0_27 98
|
||||
#define SCLK_AUDIO2 99
|
||||
#define SCLK_POST0 100
|
||||
#define SCLK_AUDIO1 101
|
||||
#define SCLK_AUDIO0 102
|
||||
#define SCLK_SECUR 103
|
||||
#define SCLK_IRDA 104
|
||||
#define SCLK_UART 105
|
||||
#define SCLK_MFC 106
|
||||
#define SCLK_CAM 107
|
||||
#define SCLK_JPEG 108
|
||||
#define SCLK_ONENAND 109
|
||||
|
||||
/* MEM0 bus clocks - S3C6410-specific. */
|
||||
#define MEM0_CFCON 112
|
||||
#define MEM0_ONENAND1 113
|
||||
#define MEM0_ONENAND0 114
|
||||
#define MEM0_NFCON 115
|
||||
#define MEM0_SROM 116
|
||||
|
||||
/* Muxes. */
|
||||
#define MOUT_APLL 128
|
||||
#define MOUT_MPLL 129
|
||||
#define MOUT_EPLL 130
|
||||
#define MOUT_MFC 131
|
||||
#define MOUT_AUDIO0 132
|
||||
#define MOUT_AUDIO1 133
|
||||
#define MOUT_UART 134
|
||||
#define MOUT_SPI0 135
|
||||
#define MOUT_SPI1 136
|
||||
#define MOUT_MMC0 137
|
||||
#define MOUT_MMC1 138
|
||||
#define MOUT_MMC2 139
|
||||
#define MOUT_UHOST 140
|
||||
#define MOUT_IRDA 141
|
||||
#define MOUT_LCD 142
|
||||
#define MOUT_SCALER 143
|
||||
#define MOUT_DAC27 144
|
||||
#define MOUT_TV27 145
|
||||
#define MOUT_AUDIO2 146
|
||||
|
||||
/* Dividers. */
|
||||
#define DOUT_MPLL 160
|
||||
#define DOUT_SECUR 161
|
||||
#define DOUT_CAM 162
|
||||
#define DOUT_JPEG 163
|
||||
#define DOUT_MFC 164
|
||||
#define DOUT_MMC0 165
|
||||
#define DOUT_MMC1 166
|
||||
#define DOUT_MMC2 167
|
||||
#define DOUT_LCD 168
|
||||
#define DOUT_SCALER 169
|
||||
#define DOUT_UHOST 170
|
||||
#define DOUT_SPI0 171
|
||||
#define DOUT_SPI1 172
|
||||
#define DOUT_AUDIO0 173
|
||||
#define DOUT_AUDIO1 174
|
||||
#define DOUT_UART 175
|
||||
#define DOUT_IRDA 176
|
||||
#define DOUT_FIMC 177
|
||||
#define DOUT_AUDIO2 178
|
||||
|
||||
/* Total number of clocks. */
|
||||
#define NR_CLKS (DOUT_AUDIO2 + 1)
|
||||
|
||||
#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H */
|
|
@ -33,8 +33,11 @@ struct clk {
|
|||
const char **parent_names;
|
||||
struct clk **parents;
|
||||
u8 num_parents;
|
||||
u8 new_parent_index;
|
||||
unsigned long rate;
|
||||
unsigned long new_rate;
|
||||
struct clk *new_parent;
|
||||
struct clk *new_child;
|
||||
unsigned long flags;
|
||||
unsigned int enable_count;
|
||||
unsigned int prepare_count;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define __LINUX_CLK_PROVIDER_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
|
||||
|
@ -27,6 +28,7 @@
|
|||
#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */
|
||||
#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
|
||||
#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
|
||||
#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
|
||||
|
||||
struct clk_hw;
|
||||
|
||||
|
@ -79,6 +81,10 @@ struct clk_hw;
|
|||
* @round_rate: Given a target rate as input, returns the closest rate actually
|
||||
* supported by the clock.
|
||||
*
|
||||
* @determine_rate: Given a target rate as input, returns the closest rate
|
||||
* actually supported by the clock, and optionally the parent clock
|
||||
* that should be used to provide the clock rate.
|
||||
*
|
||||
* @get_parent: Queries the hardware to determine the parent of a clock. The
|
||||
* return value is a u8 which specifies the index corresponding to
|
||||
* the parent clock. This index can be applied to either the
|
||||
|
@ -126,6 +132,9 @@ struct clk_ops {
|
|||
unsigned long parent_rate);
|
||||
long (*round_rate)(struct clk_hw *hw, unsigned long,
|
||||
unsigned long *);
|
||||
long (*determine_rate)(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *best_parent_rate,
|
||||
struct clk **best_parent_clk);
|
||||
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,
|
||||
|
@ -327,8 +336,10 @@ struct clk_mux {
|
|||
#define CLK_MUX_INDEX_ONE BIT(0)
|
||||
#define CLK_MUX_INDEX_BIT BIT(1)
|
||||
#define CLK_MUX_HIWORD_MASK BIT(2)
|
||||
#define CLK_MUX_READ_ONLY BIT(3) /* mux setting cannot be changed */
|
||||
|
||||
extern const struct clk_ops clk_mux_ops;
|
||||
extern const struct clk_ops clk_mux_ro_ops;
|
||||
|
||||
struct clk *clk_register_mux(struct device *dev, const char *name,
|
||||
const char **parent_names, u8 num_parents, unsigned long flags,
|
||||
|
@ -418,6 +429,7 @@ const char *__clk_get_name(struct clk *clk);
|
|||
struct clk_hw *__clk_get_hw(struct clk *clk);
|
||||
u8 __clk_get_num_parents(struct clk *clk);
|
||||
struct clk *__clk_get_parent(struct clk *clk);
|
||||
struct clk *clk_get_parent_by_index(struct clk *clk, u8 index);
|
||||
unsigned int __clk_get_enable_count(struct clk *clk);
|
||||
unsigned int __clk_get_prepare_count(struct clk *clk);
|
||||
unsigned long __clk_get_rate(struct clk *clk);
|
||||
|
@ -425,6 +437,9 @@ unsigned long __clk_get_flags(struct clk *clk);
|
|||
bool __clk_is_prepared(struct clk *clk);
|
||||
bool __clk_is_enabled(struct clk *clk);
|
||||
struct clk *__clk_lookup(const char *name);
|
||||
long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *best_parent_rate,
|
||||
struct clk **best_parent_p);
|
||||
|
||||
/*
|
||||
* FIXME clock api without lock protection
|
||||
|
@ -490,5 +505,21 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
|
|||
#define of_clk_init(matches) \
|
||||
{ while (0); }
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
/*
|
||||
* wrap access to peripherals in accessor routines
|
||||
* for improved portability across platforms
|
||||
*/
|
||||
|
||||
static inline u32 clk_readl(u32 __iomem *reg)
|
||||
{
|
||||
return readl(reg);
|
||||
}
|
||||
|
||||
static inline void clk_writel(u32 val, u32 __iomem *reg)
|
||||
{
|
||||
writel(val, reg);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_COMMON_CLK */
|
||||
#endif /* CLK_PROVIDER_H */
|
||||
|
|
Loading…
Reference in New Issue