diff options
48 files changed, 4518 insertions, 304 deletions
diff --git a/Documentation/arm/sunxi/clocks.txt b/Documentation/arm/sunxi/clocks.txt new file mode 100644 index 000000000000..e09a88aa3136 --- /dev/null +++ b/Documentation/arm/sunxi/clocks.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | Frequently asked questions about the sunxi clock system | ||
2 | ======================================================= | ||
3 | |||
4 | This document contains useful bits of information that people tend to ask | ||
5 | about the sunxi clock system, as well as accompanying ASCII art when adequate. | ||
6 | |||
7 | Q: Why is the main 24MHz oscillator gatable? Wouldn't that break the | ||
8 | system? | ||
9 | |||
10 | A: The 24MHz oscillator allows gating to save power. Indeed, if gated | ||
11 | carelessly the system would stop functioning, but with the right | ||
12 | steps, one can gate it and keep the system running. Consider this | ||
13 | simplified suspend example: | ||
14 | |||
15 | While the system is operational, you would see something like | ||
16 | |||
17 | 24MHz 32kHz | ||
18 | | | ||
19 | PLL1 | ||
20 | \ | ||
21 | \_ CPU Mux | ||
22 | | | ||
23 | [CPU] | ||
24 | |||
25 | When you are about to suspend, you switch the CPU Mux to the 32kHz | ||
26 | oscillator: | ||
27 | |||
28 | 24Mhz 32kHz | ||
29 | | | | ||
30 | PLL1 | | ||
31 | / | ||
32 | CPU Mux _/ | ||
33 | | | ||
34 | [CPU] | ||
35 | |||
36 | Finally you can gate the main oscillator | ||
37 | |||
38 | 32kHz | ||
39 | | | ||
40 | | | ||
41 | / | ||
42 | CPU Mux _/ | ||
43 | | | ||
44 | [CPU] | ||
45 | |||
46 | Q: Were can I learn more about the sunxi clocks? | ||
47 | |||
48 | A: The linux-sunxi wiki contains a page documenting the clock registers, | ||
49 | you can find it at | ||
50 | |||
51 | http://linux-sunxi.org/A10/CCM | ||
52 | |||
53 | The authoritative source for information at this time is the ccmu driver | ||
54 | released by Allwinner, you can find it at | ||
55 | |||
56 | https://github.com/linux-sunxi/linux-sunxi/tree/sunxi-3.0/arch/arm/mach-sun4i/clock/ccmu | ||
diff --git a/Documentation/clk.txt b/Documentation/clk.txt index 1943fae014fd..b9911c27f496 100644 --- a/Documentation/clk.txt +++ b/Documentation/clk.txt | |||
@@ -174,9 +174,9 @@ int clk_foo_enable(struct clk_hw *hw) | |||
174 | }; | 174 | }; |
175 | 175 | ||
176 | Below is a matrix detailing which clk_ops are mandatory based upon the | 176 | Below is a matrix detailing which clk_ops are mandatory based upon the |
177 | hardware capbilities of that clock. A cell marked as "y" means | 177 | hardware capabilities of that clock. A cell marked as "y" means |
178 | mandatory, a cell marked as "n" implies that either including that | 178 | mandatory, a cell marked as "n" implies that either including that |
179 | callback is invalid or otherwise uneccesary. Empty cells are either | 179 | callback is invalid or otherwise unnecessary. Empty cells are either |
180 | optional or must be evaluated on a case-by-case basis. | 180 | optional or must be evaluated on a case-by-case basis. |
181 | 181 | ||
182 | clock hardware characteristics | 182 | clock hardware characteristics |
@@ -231,3 +231,14 @@ To better enforce this policy, always follow this simple rule: any | |||
231 | statically initialized clock data MUST be defined in a separate file | 231 | statically initialized clock data MUST be defined in a separate file |
232 | from the logic that implements its ops. Basically separate the logic | 232 | from the logic that implements its ops. Basically separate the logic |
233 | from the data and all is well. | 233 | from the data and all is well. |
234 | |||
235 | Part 6 - Disabling clock gating of unused clocks | ||
236 | |||
237 | Sometimes during development it can be useful to be able to bypass the | ||
238 | default disabling of unused clocks. For example, if drivers aren't enabling | ||
239 | clocks properly but rely on them being on from the bootloader, bypassing | ||
240 | the disabling means that the driver will remain functional while the issues | ||
241 | are sorted out. | ||
242 | |||
243 | To bypass this disabling, include "clk_ignore_unused" in the bootargs to the | ||
244 | kernel. | ||
diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt new file mode 100644 index 000000000000..028b493e97ff --- /dev/null +++ b/Documentation/devicetree/bindings/clock/axi-clkgen.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Binding for the axi-clkgen clock generator | ||
2 | |||
3 | This binding uses the common clock binding[1]. | ||
4 | |||
5 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
6 | |||
7 | Required properties: | ||
8 | - compatible : shall be "adi,axi-clkgen". | ||
9 | - #clock-cells : from common clock binding; Should always be set to 0. | ||
10 | - reg : Address and length of the axi-clkgen register set. | ||
11 | - clocks : Phandle and clock specifier for the parent clock. | ||
12 | |||
13 | Optional properties: | ||
14 | - clock-output-names : From common clock binding. | ||
15 | |||
16 | Example: | ||
17 | clock@0xff000000 { | ||
18 | compatible = "adi,axi-clkgen"; | ||
19 | #clock-cells = <0>; | ||
20 | reg = <0xff000000 0x1000>; | ||
21 | clocks = <&osc 1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt b/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt new file mode 100644 index 000000000000..5757f9abfc26 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/fixed-factor-clock.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | Binding for simple fixed factor rate clock sources. | ||
2 | |||
3 | This binding uses the common clock binding[1]. | ||
4 | |||
5 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
6 | |||
7 | Required properties: | ||
8 | - compatible : shall be "fixed-factor-clock". | ||
9 | - #clock-cells : from common clock binding; shall be set to 0. | ||
10 | - clock-div: fixed divider. | ||
11 | - clock-mult: fixed multiplier. | ||
12 | - clocks: parent clock. | ||
13 | |||
14 | Optional properties: | ||
15 | - clock-output-names : From common clock binding. | ||
16 | |||
17 | Example: | ||
18 | clock { | ||
19 | compatible = "fixed-factor-clock"; | ||
20 | clocks = <&parentclk>; | ||
21 | #clock-cells = <0>; | ||
22 | div = <2>; | ||
23 | mult = <1>; | ||
24 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt new file mode 100644 index 000000000000..cc374651662c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt | |||
@@ -0,0 +1,114 @@ | |||
1 | Binding for Silicon Labs Si5351a/b/c programmable i2c clock generator. | ||
2 | |||
3 | Reference | ||
4 | [1] Si5351A/B/C Data Sheet | ||
5 | http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf | ||
6 | |||
7 | The Si5351a/b/c are programmable i2c clock generators with upto 8 output | ||
8 | clocks. Si5351a also has a reduced pin-count package (MSOP10) where only | ||
9 | 3 output clocks are accessible. The internal structure of the clock | ||
10 | generators can be found in [1]. | ||
11 | |||
12 | ==I2C device node== | ||
13 | |||
14 | Required properties: | ||
15 | - compatible: shall be one of "silabs,si5351{a,a-msop,b,c}". | ||
16 | - reg: i2c device address, shall be 0x60 or 0x61. | ||
17 | - #clock-cells: from common clock binding; shall be set to 1. | ||
18 | - clocks: from common clock binding; list of parent clock | ||
19 | handles, shall be xtal reference clock or xtal and clkin for | ||
20 | si5351c only. | ||
21 | - #address-cells: shall be set to 1. | ||
22 | - #size-cells: shall be set to 0. | ||
23 | |||
24 | Optional properties: | ||
25 | - silabs,pll-source: pair of (number, source) for each pll. Allows | ||
26 | to overwrite clock source of pll A (number=0) or B (number=1). | ||
27 | |||
28 | ==Child nodes== | ||
29 | |||
30 | Each of the clock outputs can be overwritten individually by | ||
31 | using a child node to the I2C device node. If a child node for a clock | ||
32 | output is not set, the eeprom configuration is not overwritten. | ||
33 | |||
34 | Required child node properties: | ||
35 | - reg: number of clock output. | ||
36 | |||
37 | Optional child node properties: | ||
38 | - silabs,clock-source: source clock of the output divider stage N, shall be | ||
39 | 0 = multisynth N | ||
40 | 1 = multisynth 0 for output clocks 0-3, else multisynth4 | ||
41 | 2 = xtal | ||
42 | 3 = clkin (si5351c only) | ||
43 | - silabs,drive-strength: output drive strength in mA, shall be one of {2,4,6,8}. | ||
44 | - silabs,multisynth-source: source pll A(0) or B(1) of corresponding multisynth | ||
45 | divider. | ||
46 | - silabs,pll-master: boolean, multisynth can change pll frequency. | ||
47 | |||
48 | ==Example== | ||
49 | |||
50 | /* 25MHz reference crystal */ | ||
51 | ref25: ref25M { | ||
52 | compatible = "fixed-clock"; | ||
53 | #clock-cells = <0>; | ||
54 | clock-frequency = <25000000>; | ||
55 | }; | ||
56 | |||
57 | i2c-master-node { | ||
58 | |||
59 | /* Si5351a msop10 i2c clock generator */ | ||
60 | si5351a: clock-generator@60 { | ||
61 | compatible = "silabs,si5351a-msop"; | ||
62 | reg = <0x60>; | ||
63 | #address-cells = <1>; | ||
64 | #size-cells = <0>; | ||
65 | #clock-cells = <1>; | ||
66 | |||
67 | /* connect xtal input to 25MHz reference */ | ||
68 | clocks = <&ref25>; | ||
69 | |||
70 | /* connect xtal input as source of pll0 and pll1 */ | ||
71 | silabs,pll-source = <0 0>, <1 0>; | ||
72 | |||
73 | /* | ||
74 | * overwrite clkout0 configuration with: | ||
75 | * - 8mA output drive strength | ||
76 | * - pll0 as clock source of multisynth0 | ||
77 | * - multisynth0 as clock source of output divider | ||
78 | * - multisynth0 can change pll0 | ||
79 | * - set initial clock frequency of 74.25MHz | ||
80 | */ | ||
81 | clkout0 { | ||
82 | reg = <0>; | ||
83 | silabs,drive-strength = <8>; | ||
84 | silabs,multisynth-source = <0>; | ||
85 | silabs,clock-source = <0>; | ||
86 | silabs,pll-master; | ||
87 | clock-frequency = <74250000>; | ||
88 | }; | ||
89 | |||
90 | /* | ||
91 | * overwrite clkout1 configuration with: | ||
92 | * - 4mA output drive strength | ||
93 | * - pll1 as clock source of multisynth1 | ||
94 | * - multisynth1 as clock source of output divider | ||
95 | * - multisynth1 can change pll1 | ||
96 | */ | ||
97 | clkout1 { | ||
98 | reg = <1>; | ||
99 | silabs,drive-strength = <4>; | ||
100 | silabs,multisynth-source = <1>; | ||
101 | silabs,clock-source = <0>; | ||
102 | pll-master; | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * overwrite clkout2 configuration with: | ||
107 | * - xtal as clock source of output divider | ||
108 | */ | ||
109 | clkout2 { | ||
110 | reg = <2>; | ||
111 | silabs,clock-source = <2>; | ||
112 | }; | ||
113 | }; | ||
114 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt new file mode 100644 index 000000000000..729f52426fe1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/sunxi.txt | |||
@@ -0,0 +1,151 @@ | |||
1 | Device Tree Clock bindings for arch-sunxi | ||
2 | |||
3 | This binding uses the common clock binding[1]. | ||
4 | |||
5 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
6 | |||
7 | Required properties: | ||
8 | - compatible : shall be one of the following: | ||
9 | "allwinner,sun4i-osc-clk" - for a gatable oscillator | ||
10 | "allwinner,sun4i-pll1-clk" - for the main PLL clock | ||
11 | "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock | ||
12 | "allwinner,sun4i-axi-clk" - for the AXI clock | ||
13 | "allwinner,sun4i-axi-gates-clk" - for the AXI gates | ||
14 | "allwinner,sun4i-ahb-clk" - for the AHB clock | ||
15 | "allwinner,sun4i-ahb-gates-clk" - for the AHB gates | ||
16 | "allwinner,sun4i-apb0-clk" - for the APB0 clock | ||
17 | "allwinner,sun4i-apb0-gates-clk" - for the APB0 gates | ||
18 | "allwinner,sun4i-apb1-clk" - for the APB1 clock | ||
19 | "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing | ||
20 | "allwinner,sun4i-apb1-gates-clk" - for the APB1 gates | ||
21 | |||
22 | Required properties for all clocks: | ||
23 | - reg : shall be the control register address for the clock. | ||
24 | - clocks : shall be the input parent clock(s) phandle for the clock | ||
25 | - #clock-cells : from common clock binding; shall be set to 0 except for | ||
26 | "allwinner,sun4i-*-gates-clk" where it shall be set to 1 | ||
27 | |||
28 | Additionally, "allwinner,sun4i-*-gates-clk" clocks require: | ||
29 | - clock-output-names : the corresponding gate names that the clock controls | ||
30 | |||
31 | For example: | ||
32 | |||
33 | osc24M: osc24M@01c20050 { | ||
34 | #clock-cells = <0>; | ||
35 | compatible = "allwinner,sun4i-osc-clk"; | ||
36 | reg = <0x01c20050 0x4>; | ||
37 | clocks = <&osc24M_fixed>; | ||
38 | }; | ||
39 | |||
40 | pll1: pll1@01c20000 { | ||
41 | #clock-cells = <0>; | ||
42 | compatible = "allwinner,sun4i-pll1-clk"; | ||
43 | reg = <0x01c20000 0x4>; | ||
44 | clocks = <&osc24M>; | ||
45 | }; | ||
46 | |||
47 | cpu: cpu@01c20054 { | ||
48 | #clock-cells = <0>; | ||
49 | compatible = "allwinner,sun4i-cpu-clk"; | ||
50 | reg = <0x01c20054 0x4>; | ||
51 | clocks = <&osc32k>, <&osc24M>, <&pll1>; | ||
52 | }; | ||
53 | |||
54 | |||
55 | |||
56 | Gate clock outputs | ||
57 | |||
58 | The "allwinner,sun4i-*-gates-clk" clocks provide several gatable outputs; | ||
59 | their corresponding offsets as present on sun4i are listed below. Note that | ||
60 | some of these gates are not present on sun5i. | ||
61 | |||
62 | * AXI gates ("allwinner,sun4i-axi-gates-clk") | ||
63 | |||
64 | DRAM 0 | ||
65 | |||
66 | * AHB gates ("allwinner,sun4i-ahb-gates-clk") | ||
67 | |||
68 | USB0 0 | ||
69 | EHCI0 1 | ||
70 | OHCI0 2* | ||
71 | EHCI1 3 | ||
72 | OHCI1 4* | ||
73 | SS 5 | ||
74 | DMA 6 | ||
75 | BIST 7 | ||
76 | MMC0 8 | ||
77 | MMC1 9 | ||
78 | MMC2 10 | ||
79 | MMC3 11 | ||
80 | MS 12** | ||
81 | NAND 13 | ||
82 | SDRAM 14 | ||
83 | |||
84 | ACE 16 | ||
85 | EMAC 17 | ||
86 | TS 18 | ||
87 | |||
88 | SPI0 20 | ||
89 | SPI1 21 | ||
90 | SPI2 22 | ||
91 | SPI3 23 | ||
92 | PATA 24 | ||
93 | SATA 25** | ||
94 | GPS 26* | ||
95 | |||
96 | VE 32 | ||
97 | TVD 33 | ||
98 | TVE0 34 | ||
99 | TVE1 35 | ||
100 | LCD0 36 | ||
101 | LCD1 37 | ||
102 | |||
103 | CSI0 40 | ||
104 | CSI1 41 | ||
105 | |||
106 | HDMI 43 | ||
107 | DE_BE0 44 | ||
108 | DE_BE1 45 | ||
109 | DE_FE0 46 | ||
110 | DE_FE1 47 | ||
111 | |||
112 | MP 50 | ||
113 | |||
114 | MALI400 52 | ||
115 | |||
116 | * APB0 gates ("allwinner,sun4i-apb0-gates-clk") | ||
117 | |||
118 | CODEC 0 | ||
119 | SPDIF 1* | ||
120 | AC97 2 | ||
121 | IIS 3 | ||
122 | |||
123 | PIO 5 | ||
124 | IR0 6 | ||
125 | IR1 7 | ||
126 | |||
127 | KEYPAD 10 | ||
128 | |||
129 | * APB1 gates ("allwinner,sun4i-apb1-gates-clk") | ||
130 | |||
131 | I2C0 0 | ||
132 | I2C1 1 | ||
133 | I2C2 2 | ||
134 | |||
135 | CAN 4 | ||
136 | SCR 5 | ||
137 | PS20 6 | ||
138 | PS21 7 | ||
139 | |||
140 | UART0 16 | ||
141 | UART1 17 | ||
142 | UART2 18 | ||
143 | UART3 19 | ||
144 | UART4 20 | ||
145 | UART5 21 | ||
146 | UART6 22 | ||
147 | UART7 23 | ||
148 | |||
149 | Notation: | ||
150 | [*]: The datasheet didn't mention these, but they are present on AW code | ||
151 | [**]: The datasheet had this marked as "NC" but they are used on AW code | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 3b3b0194adfe..4d1919bf2332 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -49,6 +49,7 @@ samsung Samsung Semiconductor | |||
49 | sbs Smart Battery System | 49 | sbs Smart Battery System |
50 | schindler Schindler | 50 | schindler Schindler |
51 | sil Silicon Image | 51 | sil Silicon Image |
52 | silabs Silicon Laboratories | ||
52 | simtek | 53 | simtek |
53 | sirf SiRF Technology, Inc. | 54 | sirf SiRF Technology, Inc. |
54 | snps Synopsys, Inc. | 55 | snps Synopsys, Inc. |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 5abc09a93bc2..365f7bd40eeb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -44,6 +44,7 @@ parameter is applicable: | |||
44 | AVR32 AVR32 architecture is enabled. | 44 | AVR32 AVR32 architecture is enabled. |
45 | AX25 Appropriate AX.25 support is enabled. | 45 | AX25 Appropriate AX.25 support is enabled. |
46 | BLACKFIN Blackfin architecture is enabled. | 46 | BLACKFIN Blackfin architecture is enabled. |
47 | CLK Common clock infrastructure is enabled. | ||
47 | DRM Direct Rendering Management support is enabled. | 48 | DRM Direct Rendering Management support is enabled. |
48 | DYNAMIC_DEBUG Build in debug messages and enable them at runtime | 49 | DYNAMIC_DEBUG Build in debug messages and enable them at runtime |
49 | EDD BIOS Enhanced Disk Drive Services (EDD) is enabled | 50 | EDD BIOS Enhanced Disk Drive Services (EDD) is enabled |
@@ -472,6 +473,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
472 | 473 | ||
473 | cio_ignore= [S390] | 474 | cio_ignore= [S390] |
474 | See Documentation/s390/CommonIO for details. | 475 | See Documentation/s390/CommonIO for details. |
476 | clk_ignore_unused | ||
477 | [CLK] | ||
478 | Keep all clocks already enabled by bootloader on, | ||
479 | even if no driver has claimed them. This is useful | ||
480 | for debug and development, but should not be | ||
481 | needed on a platform with proper driver support. | ||
482 | For more information, see Documentation/clk.txt. | ||
475 | 483 | ||
476 | clock= [BUGS=X86-32, HW] gettimeofday clocksource override. | 484 | clock= [BUGS=X86-32, HW] gettimeofday clocksource override. |
477 | [Deprecated] | 485 | [Deprecated] |
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c index 1ab91b5209e6..85b728cc27ab 100644 --- a/arch/arm/mach-imx/clk-busy.c +++ b/arch/arm/mach-imx/clk-busy.c | |||
@@ -169,7 +169,7 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, | |||
169 | 169 | ||
170 | busy->mux.reg = reg; | 170 | busy->mux.reg = reg; |
171 | busy->mux.shift = shift; | 171 | busy->mux.shift = shift; |
172 | busy->mux.width = width; | 172 | busy->mux.mask = BIT(width) - 1; |
173 | busy->mux.lock = &imx_ccm_lock; | 173 | busy->mux.lock = &imx_ccm_lock; |
174 | busy->mux_ops = &clk_mux_ops; | 174 | busy->mux_ops = &clk_mux_ops; |
175 | 175 | ||
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 915683cb67d6..c5e20b52e3b7 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/regulator/fixed.h> | 21 | #include <linux/regulator/fixed.h> |
22 | #include <linux/regulator/machine.h> | 22 | #include <linux/regulator/machine.h> |
23 | #include <linux/vexpress.h> | 23 | #include <linux/vexpress.h> |
24 | #include <linux/clk-provider.h> | ||
25 | #include <linux/clkdev.h> | ||
24 | 26 | ||
25 | #include <asm/arch_timer.h> | 27 | #include <asm/arch_timer.h> |
26 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
@@ -433,7 +435,7 @@ static void __init v2m_dt_timer_init(void) | |||
433 | { | 435 | { |
434 | struct device_node *node = NULL; | 436 | struct device_node *node = NULL; |
435 | 437 | ||
436 | vexpress_clk_of_init(); | 438 | of_clk_init(NULL); |
437 | 439 | ||
438 | do { | 440 | do { |
439 | node = of_find_compatible_node(node, NULL, "arm,sp804"); | 441 | node = of_find_compatible_node(node, NULL, "arm,sp804"); |
@@ -441,6 +443,10 @@ static void __init v2m_dt_timer_init(void) | |||
441 | if (node) { | 443 | if (node) { |
442 | pr_info("Using SP804 '%s' as a clock & events source\n", | 444 | pr_info("Using SP804 '%s' as a clock & events source\n", |
443 | node->full_name); | 445 | node->full_name); |
446 | WARN_ON(clk_register_clkdev(of_clk_get_by_name(node, | ||
447 | "timclken1"), "v2m-timer0", "sp804")); | ||
448 | WARN_ON(clk_register_clkdev(of_clk_get_by_name(node, | ||
449 | "timclken2"), "v2m-timer1", "sp804")); | ||
444 | v2m_sp804_init(of_iomap(node, 0), | 450 | v2m_sp804_init(of_iomap(node, 0), |
445 | irq_of_parse_and_map(node, 0)); | 451 | irq_of_parse_and_map(node, 0)); |
446 | } | 452 | } |
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index a47e6ee98b8c..0357ac44638b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -55,6 +55,16 @@ config COMMON_CLK_MAX77686 | |||
55 | ---help--- | 55 | ---help--- |
56 | This driver supports Maxim 77686 crystal oscillator clock. | 56 | This driver supports Maxim 77686 crystal oscillator clock. |
57 | 57 | ||
58 | config COMMON_CLK_SI5351 | ||
59 | tristate "Clock driver for SiLabs 5351A/B/C" | ||
60 | depends on I2C | ||
61 | depends on OF | ||
62 | select REGMAP_I2C | ||
63 | select RATIONAL | ||
64 | ---help--- | ||
65 | This driver supports Silicon Labs 5351A/B/C programmable clock | ||
66 | generators. | ||
67 | |||
58 | config CLK_TWL6040 | 68 | config CLK_TWL6040 |
59 | tristate "External McPDM functional clock from twl6040" | 69 | tristate "External McPDM functional clock from twl6040" |
60 | depends on TWL6040_CORE | 70 | depends on TWL6040_CORE |
@@ -63,6 +73,14 @@ config CLK_TWL6040 | |||
63 | McPDM. McPDM module is using the external bit clock on the McPDM bus | 73 | McPDM. McPDM module is using the external bit clock on the McPDM bus |
64 | as functional clock. | 74 | as functional clock. |
65 | 75 | ||
76 | config COMMON_CLK_AXI_CLKGEN | ||
77 | tristate "AXI clkgen driver" | ||
78 | depends on ARCH_ZYNQ || MICROBLAZE | ||
79 | help | ||
80 | ---help--- | ||
81 | Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx | ||
82 | FPGAs. It is commonly used in Analog Devices' reference designs. | ||
83 | |||
66 | endmenu | 84 | endmenu |
67 | 85 | ||
68 | source "drivers/clk/mvebu/Kconfig" | 86 | source "drivers/clk/mvebu/Kconfig" |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 300d4775d926..e7f7fe9b2f09 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o | |||
7 | obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o | 7 | obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o |
8 | obj-$(CONFIG_COMMON_CLK) += clk-gate.o | 8 | obj-$(CONFIG_COMMON_CLK) += clk-gate.o |
9 | obj-$(CONFIG_COMMON_CLK) += clk-mux.o | 9 | obj-$(CONFIG_COMMON_CLK) += clk-mux.o |
10 | obj-$(CONFIG_COMMON_CLK) += clk-composite.o | ||
10 | 11 | ||
11 | # SoCs specific | 12 | # SoCs specific |
12 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | 13 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o |
@@ -23,6 +24,7 @@ ifeq ($(CONFIG_COMMON_CLK), y) | |||
23 | obj-$(CONFIG_ARCH_MMP) += mmp/ | 24 | obj-$(CONFIG_ARCH_MMP) += mmp/ |
24 | endif | 25 | endif |
25 | obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o | 26 | obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o |
27 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ | ||
26 | obj-$(CONFIG_ARCH_U8500) += ux500/ | 28 | obj-$(CONFIG_ARCH_U8500) += ux500/ |
27 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o | 29 | obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o |
28 | obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o | 30 | obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o |
@@ -31,6 +33,8 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ | |||
31 | obj-$(CONFIG_X86) += x86/ | 33 | obj-$(CONFIG_X86) += x86/ |
32 | 34 | ||
33 | # Chip specific | 35 | # Chip specific |
36 | obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o | ||
34 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | 37 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o |
35 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o | 38 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o |
39 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | ||
36 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o | 40 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o |
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c new file mode 100644 index 000000000000..8137327847c3 --- /dev/null +++ b/drivers/clk/clk-axi-clkgen.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | * AXI clkgen driver | ||
3 | * | ||
4 | * Copyright 2012-2013 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2. | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/err.h> | ||
19 | |||
20 | #define AXI_CLKGEN_REG_UPDATE_ENABLE 0x04 | ||
21 | #define AXI_CLKGEN_REG_CLK_OUT1 0x08 | ||
22 | #define AXI_CLKGEN_REG_CLK_OUT2 0x0c | ||
23 | #define AXI_CLKGEN_REG_CLK_DIV 0x10 | ||
24 | #define AXI_CLKGEN_REG_CLK_FB1 0x14 | ||
25 | #define AXI_CLKGEN_REG_CLK_FB2 0x18 | ||
26 | #define AXI_CLKGEN_REG_LOCK1 0x1c | ||
27 | #define AXI_CLKGEN_REG_LOCK2 0x20 | ||
28 | #define AXI_CLKGEN_REG_LOCK3 0x24 | ||
29 | #define AXI_CLKGEN_REG_FILTER1 0x28 | ||
30 | #define AXI_CLKGEN_REG_FILTER2 0x2c | ||
31 | |||
32 | struct axi_clkgen { | ||
33 | void __iomem *base; | ||
34 | struct clk_hw clk_hw; | ||
35 | }; | ||
36 | |||
37 | static uint32_t axi_clkgen_lookup_filter(unsigned int m) | ||
38 | { | ||
39 | switch (m) { | ||
40 | case 0: | ||
41 | return 0x01001990; | ||
42 | case 1: | ||
43 | return 0x01001190; | ||
44 | case 2: | ||
45 | return 0x01009890; | ||
46 | case 3: | ||
47 | return 0x01001890; | ||
48 | case 4: | ||
49 | return 0x01008890; | ||
50 | case 5 ... 8: | ||
51 | return 0x01009090; | ||
52 | case 9 ... 11: | ||
53 | return 0x01000890; | ||
54 | case 12: | ||
55 | return 0x08009090; | ||
56 | case 13 ... 22: | ||
57 | return 0x01001090; | ||
58 | case 23 ... 36: | ||
59 | return 0x01008090; | ||
60 | case 37 ... 46: | ||
61 | return 0x08001090; | ||
62 | default: | ||
63 | return 0x08008090; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static const uint32_t axi_clkgen_lock_table[] = { | ||
68 | 0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8, | ||
69 | 0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8, | ||
70 | 0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339, | ||
71 | 0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271, | ||
72 | 0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4, | ||
73 | 0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190, | ||
74 | 0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e, | ||
75 | 0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c, | ||
76 | 0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113, | ||
77 | }; | ||
78 | |||
79 | static uint32_t axi_clkgen_lookup_lock(unsigned int m) | ||
80 | { | ||
81 | if (m < ARRAY_SIZE(axi_clkgen_lock_table)) | ||
82 | return axi_clkgen_lock_table[m]; | ||
83 | return 0x1f1f00fa; | ||
84 | } | ||
85 | |||
86 | static const unsigned int fpfd_min = 10000; | ||
87 | static const unsigned int fpfd_max = 300000; | ||
88 | static const unsigned int fvco_min = 600000; | ||
89 | static const unsigned int fvco_max = 1200000; | ||
90 | |||
91 | static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout, | ||
92 | unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout) | ||
93 | { | ||
94 | unsigned long d, d_min, d_max, _d_min, _d_max; | ||
95 | unsigned long m, m_min, m_max; | ||
96 | unsigned long f, dout, best_f, fvco; | ||
97 | |||
98 | fin /= 1000; | ||
99 | fout /= 1000; | ||
100 | |||
101 | best_f = ULONG_MAX; | ||
102 | *best_d = 0; | ||
103 | *best_m = 0; | ||
104 | *best_dout = 0; | ||
105 | |||
106 | d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1); | ||
107 | d_max = min_t(unsigned long, fin / fpfd_min, 80); | ||
108 | |||
109 | m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1); | ||
110 | m_max = min_t(unsigned long, fvco_max * d_max / fin, 64); | ||
111 | |||
112 | for (m = m_min; m <= m_max; m++) { | ||
113 | _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max)); | ||
114 | _d_max = min(d_max, fin * m / fvco_min); | ||
115 | |||
116 | for (d = _d_min; d <= _d_max; d++) { | ||
117 | fvco = fin * m / d; | ||
118 | |||
119 | dout = DIV_ROUND_CLOSEST(fvco, fout); | ||
120 | dout = clamp_t(unsigned long, dout, 1, 128); | ||
121 | f = fvco / dout; | ||
122 | if (abs(f - fout) < abs(best_f - fout)) { | ||
123 | best_f = f; | ||
124 | *best_d = d; | ||
125 | *best_m = m; | ||
126 | *best_dout = dout; | ||
127 | if (best_f == fout) | ||
128 | return; | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low, | ||
135 | unsigned int *high, unsigned int *edge, unsigned int *nocount) | ||
136 | { | ||
137 | if (divider == 1) | ||
138 | *nocount = 1; | ||
139 | else | ||
140 | *nocount = 0; | ||
141 | |||
142 | *high = divider / 2; | ||
143 | *edge = divider % 2; | ||
144 | *low = divider - *high; | ||
145 | } | ||
146 | |||
147 | static void axi_clkgen_write(struct axi_clkgen *axi_clkgen, | ||
148 | unsigned int reg, unsigned int val) | ||
149 | { | ||
150 | writel(val, axi_clkgen->base + reg); | ||
151 | } | ||
152 | |||
153 | static void axi_clkgen_read(struct axi_clkgen *axi_clkgen, | ||
154 | unsigned int reg, unsigned int *val) | ||
155 | { | ||
156 | *val = readl(axi_clkgen->base + reg); | ||
157 | } | ||
158 | |||
159 | static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) | ||
160 | { | ||
161 | return container_of(clk_hw, struct axi_clkgen, clk_hw); | ||
162 | } | ||
163 | |||
164 | static int axi_clkgen_set_rate(struct clk_hw *clk_hw, | ||
165 | unsigned long rate, unsigned long parent_rate) | ||
166 | { | ||
167 | struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); | ||
168 | unsigned int d, m, dout; | ||
169 | unsigned int nocount; | ||
170 | unsigned int high; | ||
171 | unsigned int edge; | ||
172 | unsigned int low; | ||
173 | uint32_t filter; | ||
174 | uint32_t lock; | ||
175 | |||
176 | if (parent_rate == 0 || rate == 0) | ||
177 | return -EINVAL; | ||
178 | |||
179 | axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout); | ||
180 | |||
181 | if (d == 0 || dout == 0 || m == 0) | ||
182 | return -EINVAL; | ||
183 | |||
184 | filter = axi_clkgen_lookup_filter(m - 1); | ||
185 | lock = axi_clkgen_lookup_lock(m - 1); | ||
186 | |||
187 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0); | ||
188 | |||
189 | axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount); | ||
190 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, | ||
191 | (high << 6) | low); | ||
192 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2, | ||
193 | (edge << 7) | (nocount << 6)); | ||
194 | |||
195 | axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount); | ||
196 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, | ||
197 | (edge << 13) | (nocount << 12) | (high << 6) | low); | ||
198 | |||
199 | axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount); | ||
200 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, | ||
201 | (high << 6) | low); | ||
202 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2, | ||
203 | (edge << 7) | (nocount << 6)); | ||
204 | |||
205 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff); | ||
206 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2, | ||
207 | (((lock >> 16) & 0x1f) << 10) | 0x1); | ||
208 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3, | ||
209 | (((lock >> 24) & 0x1f) << 10) | 0x3e9); | ||
210 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16); | ||
211 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter); | ||
212 | |||
213 | axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate, | ||
219 | unsigned long *parent_rate) | ||
220 | { | ||
221 | unsigned int d, m, dout; | ||
222 | |||
223 | axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout); | ||
224 | |||
225 | if (d == 0 || dout == 0 || m == 0) | ||
226 | return -EINVAL; | ||
227 | |||
228 | return *parent_rate / d * m / dout; | ||
229 | } | ||
230 | |||
231 | static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, | ||
232 | unsigned long parent_rate) | ||
233 | { | ||
234 | struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); | ||
235 | unsigned int d, m, dout; | ||
236 | unsigned int reg; | ||
237 | unsigned long long tmp; | ||
238 | |||
239 | axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, ®); | ||
240 | dout = (reg & 0x3f) + ((reg >> 6) & 0x3f); | ||
241 | axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, ®); | ||
242 | d = (reg & 0x3f) + ((reg >> 6) & 0x3f); | ||
243 | axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, ®); | ||
244 | m = (reg & 0x3f) + ((reg >> 6) & 0x3f); | ||
245 | |||
246 | if (d == 0 || dout == 0) | ||
247 | return 0; | ||
248 | |||
249 | tmp = (unsigned long long)(parent_rate / d) * m; | ||
250 | do_div(tmp, dout); | ||
251 | |||
252 | if (tmp > ULONG_MAX) | ||
253 | return ULONG_MAX; | ||
254 | |||
255 | return tmp; | ||
256 | } | ||
257 | |||
258 | static const struct clk_ops axi_clkgen_ops = { | ||
259 | .recalc_rate = axi_clkgen_recalc_rate, | ||
260 | .round_rate = axi_clkgen_round_rate, | ||
261 | .set_rate = axi_clkgen_set_rate, | ||
262 | }; | ||
263 | |||
264 | static int axi_clkgen_probe(struct platform_device *pdev) | ||
265 | { | ||
266 | struct axi_clkgen *axi_clkgen; | ||
267 | struct clk_init_data init; | ||
268 | const char *parent_name; | ||
269 | const char *clk_name; | ||
270 | struct resource *mem; | ||
271 | struct clk *clk; | ||
272 | |||
273 | axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL); | ||
274 | if (!axi_clkgen) | ||
275 | return -ENOMEM; | ||
276 | |||
277 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
278 | axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); | ||
279 | if (IS_ERR(axi_clkgen->base)) | ||
280 | return PTR_ERR(axi_clkgen->base); | ||
281 | |||
282 | parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); | ||
283 | if (!parent_name) | ||
284 | return -EINVAL; | ||
285 | |||
286 | clk_name = pdev->dev.of_node->name; | ||
287 | of_property_read_string(pdev->dev.of_node, "clock-output-names", | ||
288 | &clk_name); | ||
289 | |||
290 | init.name = clk_name; | ||
291 | init.ops = &axi_clkgen_ops; | ||
292 | init.flags = 0; | ||
293 | init.parent_names = &parent_name; | ||
294 | init.num_parents = 1; | ||
295 | |||
296 | axi_clkgen->clk_hw.init = &init; | ||
297 | clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw); | ||
298 | if (IS_ERR(clk)) | ||
299 | return PTR_ERR(clk); | ||
300 | |||
301 | return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, | ||
302 | clk); | ||
303 | } | ||
304 | |||
305 | static int axi_clkgen_remove(struct platform_device *pdev) | ||
306 | { | ||
307 | of_clk_del_provider(pdev->dev.of_node); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static const struct of_device_id axi_clkgen_ids[] = { | ||
313 | { .compatible = "adi,axi-clkgen-1.00.a" }, | ||
314 | { }, | ||
315 | }; | ||
316 | MODULE_DEVICE_TABLE(of, axi_clkgen_ids); | ||
317 | |||
318 | static struct platform_driver axi_clkgen_driver = { | ||
319 | .driver = { | ||
320 | .name = "adi-axi-clkgen", | ||
321 | .owner = THIS_MODULE, | ||
322 | .of_match_table = axi_clkgen_ids, | ||
323 | }, | ||
324 | .probe = axi_clkgen_probe, | ||
325 | .remove = axi_clkgen_remove, | ||
326 | }; | ||
327 | module_platform_driver(axi_clkgen_driver); | ||
328 | |||
329 | MODULE_LICENSE("GPL v2"); | ||
330 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
331 | MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator"); | ||
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c new file mode 100644 index 000000000000..a33f46f20a41 --- /dev/null +++ b/drivers/clk/clk-composite.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013 NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk.h> | ||
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/err.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) | ||
23 | |||
24 | static u8 clk_composite_get_parent(struct clk_hw *hw) | ||
25 | { | ||
26 | struct clk_composite *composite = to_clk_composite(hw); | ||
27 | const struct clk_ops *mux_ops = composite->mux_ops; | ||
28 | struct clk_hw *mux_hw = composite->mux_hw; | ||
29 | |||
30 | mux_hw->clk = hw->clk; | ||
31 | |||
32 | return mux_ops->get_parent(mux_hw); | ||
33 | } | ||
34 | |||
35 | static int clk_composite_set_parent(struct clk_hw *hw, u8 index) | ||
36 | { | ||
37 | struct clk_composite *composite = to_clk_composite(hw); | ||
38 | const struct clk_ops *mux_ops = composite->mux_ops; | ||
39 | struct clk_hw *mux_hw = composite->mux_hw; | ||
40 | |||
41 | mux_hw->clk = hw->clk; | ||
42 | |||
43 | return mux_ops->set_parent(mux_hw, index); | ||
44 | } | ||
45 | |||
46 | static unsigned long clk_composite_recalc_rate(struct clk_hw *hw, | ||
47 | unsigned long parent_rate) | ||
48 | { | ||
49 | struct clk_composite *composite = to_clk_composite(hw); | ||
50 | const struct clk_ops *rate_ops = composite->rate_ops; | ||
51 | struct clk_hw *rate_hw = composite->rate_hw; | ||
52 | |||
53 | rate_hw->clk = hw->clk; | ||
54 | |||
55 | return rate_ops->recalc_rate(rate_hw, parent_rate); | ||
56 | } | ||
57 | |||
58 | static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate, | ||
59 | unsigned long *prate) | ||
60 | { | ||
61 | struct clk_composite *composite = to_clk_composite(hw); | ||
62 | const struct clk_ops *rate_ops = composite->rate_ops; | ||
63 | struct clk_hw *rate_hw = composite->rate_hw; | ||
64 | |||
65 | rate_hw->clk = hw->clk; | ||
66 | |||
67 | return rate_ops->round_rate(rate_hw, rate, prate); | ||
68 | } | ||
69 | |||
70 | static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate, | ||
71 | unsigned long parent_rate) | ||
72 | { | ||
73 | struct clk_composite *composite = to_clk_composite(hw); | ||
74 | const struct clk_ops *rate_ops = composite->rate_ops; | ||
75 | struct clk_hw *rate_hw = composite->rate_hw; | ||
76 | |||
77 | rate_hw->clk = hw->clk; | ||
78 | |||
79 | return rate_ops->set_rate(rate_hw, rate, parent_rate); | ||
80 | } | ||
81 | |||
82 | static int clk_composite_is_enabled(struct clk_hw *hw) | ||
83 | { | ||
84 | struct clk_composite *composite = to_clk_composite(hw); | ||
85 | const struct clk_ops *gate_ops = composite->gate_ops; | ||
86 | struct clk_hw *gate_hw = composite->gate_hw; | ||
87 | |||
88 | gate_hw->clk = hw->clk; | ||
89 | |||
90 | return gate_ops->is_enabled(gate_hw); | ||
91 | } | ||
92 | |||
93 | static int clk_composite_enable(struct clk_hw *hw) | ||
94 | { | ||
95 | struct clk_composite *composite = to_clk_composite(hw); | ||
96 | const struct clk_ops *gate_ops = composite->gate_ops; | ||
97 | struct clk_hw *gate_hw = composite->gate_hw; | ||
98 | |||
99 | gate_hw->clk = hw->clk; | ||
100 | |||
101 | return gate_ops->enable(gate_hw); | ||
102 | } | ||
103 | |||
104 | static void clk_composite_disable(struct clk_hw *hw) | ||
105 | { | ||
106 | struct clk_composite *composite = to_clk_composite(hw); | ||
107 | const struct clk_ops *gate_ops = composite->gate_ops; | ||
108 | struct clk_hw *gate_hw = composite->gate_hw; | ||
109 | |||
110 | gate_hw->clk = hw->clk; | ||
111 | |||
112 | gate_ops->disable(gate_hw); | ||
113 | } | ||
114 | |||
115 | struct clk *clk_register_composite(struct device *dev, const char *name, | ||
116 | const char **parent_names, int num_parents, | ||
117 | struct clk_hw *mux_hw, const struct clk_ops *mux_ops, | ||
118 | struct clk_hw *rate_hw, const struct clk_ops *rate_ops, | ||
119 | struct clk_hw *gate_hw, const struct clk_ops *gate_ops, | ||
120 | unsigned long flags) | ||
121 | { | ||
122 | struct clk *clk; | ||
123 | struct clk_init_data init; | ||
124 | struct clk_composite *composite; | ||
125 | struct clk_ops *clk_composite_ops; | ||
126 | |||
127 | composite = kzalloc(sizeof(*composite), GFP_KERNEL); | ||
128 | if (!composite) { | ||
129 | pr_err("%s: could not allocate composite clk\n", __func__); | ||
130 | return ERR_PTR(-ENOMEM); | ||
131 | } | ||
132 | |||
133 | init.name = name; | ||
134 | init.flags = flags | CLK_IS_BASIC; | ||
135 | init.parent_names = parent_names; | ||
136 | init.num_parents = num_parents; | ||
137 | |||
138 | clk_composite_ops = &composite->ops; | ||
139 | |||
140 | if (mux_hw && mux_ops) { | ||
141 | if (!mux_ops->get_parent || !mux_ops->set_parent) { | ||
142 | clk = ERR_PTR(-EINVAL); | ||
143 | goto err; | ||
144 | } | ||
145 | |||
146 | composite->mux_hw = mux_hw; | ||
147 | composite->mux_ops = mux_ops; | ||
148 | clk_composite_ops->get_parent = clk_composite_get_parent; | ||
149 | clk_composite_ops->set_parent = clk_composite_set_parent; | ||
150 | } | ||
151 | |||
152 | if (rate_hw && rate_ops) { | ||
153 | if (!rate_ops->recalc_rate) { | ||
154 | clk = ERR_PTR(-EINVAL); | ||
155 | goto err; | ||
156 | } | ||
157 | |||
158 | /* .round_rate is a prerequisite for .set_rate */ | ||
159 | if (rate_ops->round_rate) { | ||
160 | clk_composite_ops->round_rate = clk_composite_round_rate; | ||
161 | if (rate_ops->set_rate) { | ||
162 | clk_composite_ops->set_rate = clk_composite_set_rate; | ||
163 | } | ||
164 | } else { | ||
165 | WARN(rate_ops->set_rate, | ||
166 | "%s: missing round_rate op is required\n", | ||
167 | __func__); | ||
168 | } | ||
169 | |||
170 | composite->rate_hw = rate_hw; | ||
171 | composite->rate_ops = rate_ops; | ||
172 | clk_composite_ops->recalc_rate = clk_composite_recalc_rate; | ||
173 | } | ||
174 | |||
175 | if (gate_hw && gate_ops) { | ||
176 | if (!gate_ops->is_enabled || !gate_ops->enable || | ||
177 | !gate_ops->disable) { | ||
178 | clk = ERR_PTR(-EINVAL); | ||
179 | goto err; | ||
180 | } | ||
181 | |||
182 | composite->gate_hw = gate_hw; | ||
183 | composite->gate_ops = gate_ops; | ||
184 | clk_composite_ops->is_enabled = clk_composite_is_enabled; | ||
185 | clk_composite_ops->enable = clk_composite_enable; | ||
186 | clk_composite_ops->disable = clk_composite_disable; | ||
187 | } | ||
188 | |||
189 | init.ops = clk_composite_ops; | ||
190 | composite->hw.init = &init; | ||
191 | |||
192 | clk = clk_register(dev, &composite->hw); | ||
193 | if (IS_ERR(clk)) | ||
194 | goto err; | ||
195 | |||
196 | if (composite->mux_hw) | ||
197 | composite->mux_hw->clk = clk; | ||
198 | |||
199 | if (composite->rate_hw) | ||
200 | composite->rate_hw->clk = clk; | ||
201 | |||
202 | if (composite->gate_hw) | ||
203 | composite->gate_hw->clk = clk; | ||
204 | |||
205 | return clk; | ||
206 | |||
207 | err: | ||
208 | kfree(composite); | ||
209 | return clk; | ||
210 | } | ||
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 68b402101170..6d9674160430 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -109,8 +109,9 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, | |||
109 | 109 | ||
110 | div = _get_div(divider, val); | 110 | div = _get_div(divider, val); |
111 | if (!div) { | 111 | if (!div) { |
112 | WARN(1, "%s: Invalid divisor for clock %s\n", __func__, | 112 | WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO), |
113 | __clk_get_name(hw->clk)); | 113 | "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", |
114 | __clk_get_name(hw->clk)); | ||
114 | return parent_rate; | 115 | return parent_rate; |
115 | } | 116 | } |
116 | 117 | ||
diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 1ef271e47594..9ff7d510faa3 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/clk-provider.h> | 11 | #include <linux/clk-provider.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/of.h> | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * DOC: basic fixed multiplier and divider clock that cannot gate | 17 | * DOC: basic fixed multiplier and divider clock that cannot gate |
@@ -96,3 +97,38 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, | |||
96 | 97 | ||
97 | return clk; | 98 | return clk; |
98 | } | 99 | } |
100 | #ifdef CONFIG_OF | ||
101 | /** | ||
102 | * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock | ||
103 | */ | ||
104 | void __init of_fixed_factor_clk_setup(struct device_node *node) | ||
105 | { | ||
106 | struct clk *clk; | ||
107 | const char *clk_name = node->name; | ||
108 | const char *parent_name; | ||
109 | u32 div, mult; | ||
110 | |||
111 | if (of_property_read_u32(node, "clock-div", &div)) { | ||
112 | pr_err("%s Fixed factor clock <%s> must have a clock-div property\n", | ||
113 | __func__, node->name); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | if (of_property_read_u32(node, "clock-mult", &mult)) { | ||
118 | pr_err("%s Fixed factor clock <%s> must have a clokc-mult property\n", | ||
119 | __func__, node->name); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
124 | parent_name = of_clk_get_parent_name(node, 0); | ||
125 | |||
126 | clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, | ||
127 | mult, div); | ||
128 | if (!IS_ERR(clk)) | ||
129 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
130 | } | ||
131 | EXPORT_SYMBOL_GPL(of_fixed_factor_clk_setup); | ||
132 | CLK_OF_DECLARE(fixed_factor_clk, "fixed-factor-clock", | ||
133 | of_fixed_factor_clk_setup); | ||
134 | #endif | ||
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 508c032edce4..25b1734560d0 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c | |||
@@ -32,6 +32,7 @@ | |||
32 | static u8 clk_mux_get_parent(struct clk_hw *hw) | 32 | static u8 clk_mux_get_parent(struct clk_hw *hw) |
33 | { | 33 | { |
34 | struct clk_mux *mux = to_clk_mux(hw); | 34 | struct clk_mux *mux = to_clk_mux(hw); |
35 | int num_parents = __clk_get_num_parents(hw->clk); | ||
35 | u32 val; | 36 | u32 val; |
36 | 37 | ||
37 | /* | 38 | /* |
@@ -42,7 +43,16 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) | |||
42 | * val = 0x4 really means "bit 2, index starts at bit 0" | 43 | * val = 0x4 really means "bit 2, index starts at bit 0" |
43 | */ | 44 | */ |
44 | val = readl(mux->reg) >> mux->shift; | 45 | val = readl(mux->reg) >> mux->shift; |
45 | val &= (1 << mux->width) - 1; | 46 | val &= mux->mask; |
47 | |||
48 | if (mux->table) { | ||
49 | int i; | ||
50 | |||
51 | for (i = 0; i < num_parents; i++) | ||
52 | if (mux->table[i] == val) | ||
53 | return i; | ||
54 | return -EINVAL; | ||
55 | } | ||
46 | 56 | ||
47 | if (val && (mux->flags & CLK_MUX_INDEX_BIT)) | 57 | if (val && (mux->flags & CLK_MUX_INDEX_BIT)) |
48 | val = ffs(val) - 1; | 58 | val = ffs(val) - 1; |
@@ -50,7 +60,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw) | |||
50 | if (val && (mux->flags & CLK_MUX_INDEX_ONE)) | 60 | if (val && (mux->flags & CLK_MUX_INDEX_ONE)) |
51 | val--; | 61 | val--; |
52 | 62 | ||
53 | if (val >= __clk_get_num_parents(hw->clk)) | 63 | if (val >= num_parents) |
54 | return -EINVAL; | 64 | return -EINVAL; |
55 | 65 | ||
56 | return val; | 66 | return val; |
@@ -62,17 +72,22 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index) | |||
62 | u32 val; | 72 | u32 val; |
63 | unsigned long flags = 0; | 73 | unsigned long flags = 0; |
64 | 74 | ||
65 | if (mux->flags & CLK_MUX_INDEX_BIT) | 75 | if (mux->table) |
66 | index = (1 << ffs(index)); | 76 | index = mux->table[index]; |
67 | 77 | ||
68 | if (mux->flags & CLK_MUX_INDEX_ONE) | 78 | else { |
69 | index++; | 79 | if (mux->flags & CLK_MUX_INDEX_BIT) |
80 | index = (1 << ffs(index)); | ||
81 | |||
82 | if (mux->flags & CLK_MUX_INDEX_ONE) | ||
83 | index++; | ||
84 | } | ||
70 | 85 | ||
71 | if (mux->lock) | 86 | if (mux->lock) |
72 | spin_lock_irqsave(mux->lock, flags); | 87 | spin_lock_irqsave(mux->lock, flags); |
73 | 88 | ||
74 | val = readl(mux->reg); | 89 | val = readl(mux->reg); |
75 | val &= ~(((1 << mux->width) - 1) << mux->shift); | 90 | val &= ~(mux->mask << mux->shift); |
76 | val |= index << mux->shift; | 91 | val |= index << mux->shift; |
77 | writel(val, mux->reg); | 92 | writel(val, mux->reg); |
78 | 93 | ||
@@ -88,10 +103,10 @@ const struct clk_ops clk_mux_ops = { | |||
88 | }; | 103 | }; |
89 | EXPORT_SYMBOL_GPL(clk_mux_ops); | 104 | EXPORT_SYMBOL_GPL(clk_mux_ops); |
90 | 105 | ||
91 | struct clk *clk_register_mux(struct device *dev, const char *name, | 106 | struct clk *clk_register_mux_table(struct device *dev, const char *name, |
92 | const char **parent_names, u8 num_parents, unsigned long flags, | 107 | const char **parent_names, u8 num_parents, unsigned long flags, |
93 | void __iomem *reg, u8 shift, u8 width, | 108 | void __iomem *reg, u8 shift, u32 mask, |
94 | u8 clk_mux_flags, spinlock_t *lock) | 109 | u8 clk_mux_flags, u32 *table, spinlock_t *lock) |
95 | { | 110 | { |
96 | struct clk_mux *mux; | 111 | struct clk_mux *mux; |
97 | struct clk *clk; | 112 | struct clk *clk; |
@@ -113,9 +128,10 @@ struct clk *clk_register_mux(struct device *dev, const char *name, | |||
113 | /* struct clk_mux assignments */ | 128 | /* struct clk_mux assignments */ |
114 | mux->reg = reg; | 129 | mux->reg = reg; |
115 | mux->shift = shift; | 130 | mux->shift = shift; |
116 | mux->width = width; | 131 | mux->mask = mask; |
117 | mux->flags = clk_mux_flags; | 132 | mux->flags = clk_mux_flags; |
118 | mux->lock = lock; | 133 | mux->lock = lock; |
134 | mux->table = table; | ||
119 | mux->hw.init = &init; | 135 | mux->hw.init = &init; |
120 | 136 | ||
121 | clk = clk_register(dev, &mux->hw); | 137 | clk = clk_register(dev, &mux->hw); |
@@ -125,3 +141,15 @@ struct clk *clk_register_mux(struct device *dev, const char *name, | |||
125 | 141 | ||
126 | return clk; | 142 | return clk; |
127 | } | 143 | } |
144 | |||
145 | struct clk *clk_register_mux(struct device *dev, const char *name, | ||
146 | const char **parent_names, u8 num_parents, unsigned long flags, | ||
147 | void __iomem *reg, u8 shift, u8 width, | ||
148 | u8 clk_mux_flags, spinlock_t *lock) | ||
149 | { | ||
150 | u32 mask = BIT(width) - 1; | ||
151 | |||
152 | return clk_register_mux_table(dev, name, parent_names, num_parents, | ||
153 | flags, reg, shift, mask, clk_mux_flags, | ||
154 | NULL, lock); | ||
155 | } | ||
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c index f8e9d0c27be2..643ca653fef0 100644 --- a/drivers/clk/clk-prima2.c +++ b/drivers/clk/clk-prima2.c | |||
@@ -1113,7 +1113,7 @@ void __init sirfsoc_of_clk_init(void) | |||
1113 | 1113 | ||
1114 | for (i = pll1; i < maxclk; i++) { | 1114 | for (i = pll1; i < maxclk; i++) { |
1115 | prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]); | 1115 | prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]); |
1116 | BUG_ON(!prima2_clks[i]); | 1116 | BUG_ON(IS_ERR(prima2_clks[i])); |
1117 | } | 1117 | } |
1118 | clk_register_clkdev(prima2_clks[cpu], NULL, "cpu"); | 1118 | clk_register_clkdev(prima2_clks[cpu], NULL, "cpu"); |
1119 | clk_register_clkdev(prima2_clks[io], NULL, "io"); | 1119 | clk_register_clkdev(prima2_clks[io], NULL, "io"); |
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c new file mode 100644 index 000000000000..892728412e9d --- /dev/null +++ b/drivers/clk/clk-si5351.c | |||
@@ -0,0 +1,1510 @@ | |||
1 | /* | ||
2 | * clk-si5351.c: Silicon Laboratories Si5351A/B/C I2C Clock Generator | ||
3 | * | ||
4 | * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * Rabeeh Khoury <rabeeh@solid-run.com> | ||
6 | * | ||
7 | * References: | ||
8 | * [1] "Si5351A/B/C Data Sheet" | ||
9 | * http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf | ||
10 | * [2] "Manually Generating an Si5351 Register Map" | ||
11 | * http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the | ||
15 | * Free Software Foundation; either version 2 of the License, or (at your | ||
16 | * option) any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | #include <linux/clk-provider.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/rational.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/platform_data/si5351.h> | ||
30 | #include <linux/regmap.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <asm/div64.h> | ||
34 | |||
35 | #include "clk-si5351.h" | ||
36 | |||
37 | struct si5351_driver_data; | ||
38 | |||
39 | struct si5351_parameters { | ||
40 | unsigned long p1; | ||
41 | unsigned long p2; | ||
42 | unsigned long p3; | ||
43 | int valid; | ||
44 | }; | ||
45 | |||
46 | struct si5351_hw_data { | ||
47 | struct clk_hw hw; | ||
48 | struct si5351_driver_data *drvdata; | ||
49 | struct si5351_parameters params; | ||
50 | unsigned char num; | ||
51 | }; | ||
52 | |||
53 | struct si5351_driver_data { | ||
54 | enum si5351_variant variant; | ||
55 | struct i2c_client *client; | ||
56 | struct regmap *regmap; | ||
57 | struct clk_onecell_data onecell; | ||
58 | |||
59 | struct clk *pxtal; | ||
60 | const char *pxtal_name; | ||
61 | struct clk_hw xtal; | ||
62 | struct clk *pclkin; | ||
63 | const char *pclkin_name; | ||
64 | struct clk_hw clkin; | ||
65 | |||
66 | struct si5351_hw_data pll[2]; | ||
67 | struct si5351_hw_data *msynth; | ||
68 | struct si5351_hw_data *clkout; | ||
69 | }; | ||
70 | |||
71 | static const char const *si5351_input_names[] = { | ||
72 | "xtal", "clkin" | ||
73 | }; | ||
74 | static const char const *si5351_pll_names[] = { | ||
75 | "plla", "pllb", "vxco" | ||
76 | }; | ||
77 | static const char const *si5351_msynth_names[] = { | ||
78 | "ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7" | ||
79 | }; | ||
80 | static const char const *si5351_clkout_names[] = { | ||
81 | "clk0", "clk1", "clk2", "clk3", "clk4", "clk5", "clk6", "clk7" | ||
82 | }; | ||
83 | |||
84 | /* | ||
85 | * Si5351 i2c regmap | ||
86 | */ | ||
87 | static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg) | ||
88 | { | ||
89 | u32 val; | ||
90 | int ret; | ||
91 | |||
92 | ret = regmap_read(drvdata->regmap, reg, &val); | ||
93 | if (ret) { | ||
94 | dev_err(&drvdata->client->dev, | ||
95 | "unable to read from reg%02x\n", reg); | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | return (u8)val; | ||
100 | } | ||
101 | |||
102 | static inline int si5351_bulk_read(struct si5351_driver_data *drvdata, | ||
103 | u8 reg, u8 count, u8 *buf) | ||
104 | { | ||
105 | return regmap_bulk_read(drvdata->regmap, reg, buf, count); | ||
106 | } | ||
107 | |||
108 | static inline int si5351_reg_write(struct si5351_driver_data *drvdata, | ||
109 | u8 reg, u8 val) | ||
110 | { | ||
111 | return regmap_write(drvdata->regmap, reg, val); | ||
112 | } | ||
113 | |||
114 | static inline int si5351_bulk_write(struct si5351_driver_data *drvdata, | ||
115 | u8 reg, u8 count, const u8 *buf) | ||
116 | { | ||
117 | return regmap_raw_write(drvdata->regmap, reg, buf, count); | ||
118 | } | ||
119 | |||
120 | static inline int si5351_set_bits(struct si5351_driver_data *drvdata, | ||
121 | u8 reg, u8 mask, u8 val) | ||
122 | { | ||
123 | return regmap_update_bits(drvdata->regmap, reg, mask, val); | ||
124 | } | ||
125 | |||
126 | static inline u8 si5351_msynth_params_address(int num) | ||
127 | { | ||
128 | if (num > 5) | ||
129 | return SI5351_CLK6_PARAMETERS + (num - 6); | ||
130 | return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num); | ||
131 | } | ||
132 | |||
133 | static void si5351_read_parameters(struct si5351_driver_data *drvdata, | ||
134 | u8 reg, struct si5351_parameters *params) | ||
135 | { | ||
136 | u8 buf[SI5351_PARAMETERS_LENGTH]; | ||
137 | |||
138 | switch (reg) { | ||
139 | case SI5351_CLK6_PARAMETERS: | ||
140 | case SI5351_CLK7_PARAMETERS: | ||
141 | buf[0] = si5351_reg_read(drvdata, reg); | ||
142 | params->p1 = buf[0]; | ||
143 | params->p2 = 0; | ||
144 | params->p3 = 1; | ||
145 | break; | ||
146 | default: | ||
147 | si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf); | ||
148 | params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4]; | ||
149 | params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7]; | ||
150 | params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1]; | ||
151 | } | ||
152 | params->valid = 1; | ||
153 | } | ||
154 | |||
155 | static void si5351_write_parameters(struct si5351_driver_data *drvdata, | ||
156 | u8 reg, struct si5351_parameters *params) | ||
157 | { | ||
158 | u8 buf[SI5351_PARAMETERS_LENGTH]; | ||
159 | |||
160 | switch (reg) { | ||
161 | case SI5351_CLK6_PARAMETERS: | ||
162 | case SI5351_CLK7_PARAMETERS: | ||
163 | buf[0] = params->p1 & 0xff; | ||
164 | si5351_reg_write(drvdata, reg, buf[0]); | ||
165 | break; | ||
166 | default: | ||
167 | buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff; | ||
168 | buf[1] = params->p3 & 0xff; | ||
169 | /* save rdiv and divby4 */ | ||
170 | buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03; | ||
171 | buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03; | ||
172 | buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff; | ||
173 | buf[4] = params->p1 & 0xff; | ||
174 | buf[5] = ((params->p3 & 0xf0000) >> 12) | | ||
175 | ((params->p2 & 0xf0000) >> 16); | ||
176 | buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff; | ||
177 | buf[7] = params->p2 & 0xff; | ||
178 | si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg) | ||
183 | { | ||
184 | switch (reg) { | ||
185 | case SI5351_DEVICE_STATUS: | ||
186 | case SI5351_INTERRUPT_STATUS: | ||
187 | case SI5351_PLL_RESET: | ||
188 | return true; | ||
189 | } | ||
190 | return false; | ||
191 | } | ||
192 | |||
193 | static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg) | ||
194 | { | ||
195 | /* reserved registers */ | ||
196 | if (reg >= 4 && reg <= 8) | ||
197 | return false; | ||
198 | if (reg >= 10 && reg <= 14) | ||
199 | return false; | ||
200 | if (reg >= 173 && reg <= 176) | ||
201 | return false; | ||
202 | if (reg >= 178 && reg <= 182) | ||
203 | return false; | ||
204 | /* read-only */ | ||
205 | if (reg == SI5351_DEVICE_STATUS) | ||
206 | return false; | ||
207 | return true; | ||
208 | } | ||
209 | |||
210 | static struct regmap_config si5351_regmap_config = { | ||
211 | .reg_bits = 8, | ||
212 | .val_bits = 8, | ||
213 | .cache_type = REGCACHE_RBTREE, | ||
214 | .max_register = 187, | ||
215 | .writeable_reg = si5351_regmap_is_writeable, | ||
216 | .volatile_reg = si5351_regmap_is_volatile, | ||
217 | }; | ||
218 | |||
219 | /* | ||
220 | * Si5351 xtal clock input | ||
221 | */ | ||
222 | static int si5351_xtal_prepare(struct clk_hw *hw) | ||
223 | { | ||
224 | struct si5351_driver_data *drvdata = | ||
225 | container_of(hw, struct si5351_driver_data, xtal); | ||
226 | si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE, | ||
227 | SI5351_XTAL_ENABLE, SI5351_XTAL_ENABLE); | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void si5351_xtal_unprepare(struct clk_hw *hw) | ||
232 | { | ||
233 | struct si5351_driver_data *drvdata = | ||
234 | container_of(hw, struct si5351_driver_data, xtal); | ||
235 | si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE, | ||
236 | SI5351_XTAL_ENABLE, 0); | ||
237 | } | ||
238 | |||
239 | static const struct clk_ops si5351_xtal_ops = { | ||
240 | .prepare = si5351_xtal_prepare, | ||
241 | .unprepare = si5351_xtal_unprepare, | ||
242 | }; | ||
243 | |||
244 | /* | ||
245 | * Si5351 clkin clock input (Si5351C only) | ||
246 | */ | ||
247 | static int si5351_clkin_prepare(struct clk_hw *hw) | ||
248 | { | ||
249 | struct si5351_driver_data *drvdata = | ||
250 | container_of(hw, struct si5351_driver_data, clkin); | ||
251 | si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE, | ||
252 | SI5351_CLKIN_ENABLE, SI5351_CLKIN_ENABLE); | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static void si5351_clkin_unprepare(struct clk_hw *hw) | ||
257 | { | ||
258 | struct si5351_driver_data *drvdata = | ||
259 | container_of(hw, struct si5351_driver_data, clkin); | ||
260 | si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE, | ||
261 | SI5351_CLKIN_ENABLE, 0); | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * CMOS clock source constraints: | ||
266 | * The input frequency range of the PLL is 10Mhz to 40MHz. | ||
267 | * If CLKIN is >40MHz, the input divider must be used. | ||
268 | */ | ||
269 | static unsigned long si5351_clkin_recalc_rate(struct clk_hw *hw, | ||
270 | unsigned long parent_rate) | ||
271 | { | ||
272 | struct si5351_driver_data *drvdata = | ||
273 | container_of(hw, struct si5351_driver_data, clkin); | ||
274 | unsigned long rate; | ||
275 | unsigned char idiv; | ||
276 | |||
277 | rate = parent_rate; | ||
278 | if (parent_rate > 160000000) { | ||
279 | idiv = SI5351_CLKIN_DIV_8; | ||
280 | rate /= 8; | ||
281 | } else if (parent_rate > 80000000) { | ||
282 | idiv = SI5351_CLKIN_DIV_4; | ||
283 | rate /= 4; | ||
284 | } else if (parent_rate > 40000000) { | ||
285 | idiv = SI5351_CLKIN_DIV_2; | ||
286 | rate /= 2; | ||
287 | } else { | ||
288 | idiv = SI5351_CLKIN_DIV_1; | ||
289 | } | ||
290 | |||
291 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, | ||
292 | SI5351_CLKIN_DIV_MASK, idiv); | ||
293 | |||
294 | dev_dbg(&drvdata->client->dev, "%s - clkin div = %d, rate = %lu\n", | ||
295 | __func__, (1 << (idiv >> 6)), rate); | ||
296 | |||
297 | return rate; | ||
298 | } | ||
299 | |||
300 | static const struct clk_ops si5351_clkin_ops = { | ||
301 | .prepare = si5351_clkin_prepare, | ||
302 | .unprepare = si5351_clkin_unprepare, | ||
303 | .recalc_rate = si5351_clkin_recalc_rate, | ||
304 | }; | ||
305 | |||
306 | /* | ||
307 | * Si5351 vxco clock input (Si5351B only) | ||
308 | */ | ||
309 | |||
310 | static int si5351_vxco_prepare(struct clk_hw *hw) | ||
311 | { | ||
312 | struct si5351_hw_data *hwdata = | ||
313 | container_of(hw, struct si5351_hw_data, hw); | ||
314 | |||
315 | dev_warn(&hwdata->drvdata->client->dev, "VXCO currently unsupported\n"); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static void si5351_vxco_unprepare(struct clk_hw *hw) | ||
321 | { | ||
322 | } | ||
323 | |||
324 | static unsigned long si5351_vxco_recalc_rate(struct clk_hw *hw, | ||
325 | unsigned long parent_rate) | ||
326 | { | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int si5351_vxco_set_rate(struct clk_hw *hw, unsigned long rate, | ||
331 | unsigned long parent) | ||
332 | { | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static const struct clk_ops si5351_vxco_ops = { | ||
337 | .prepare = si5351_vxco_prepare, | ||
338 | .unprepare = si5351_vxco_unprepare, | ||
339 | .recalc_rate = si5351_vxco_recalc_rate, | ||
340 | .set_rate = si5351_vxco_set_rate, | ||
341 | }; | ||
342 | |||
343 | /* | ||
344 | * Si5351 pll a/b | ||
345 | * | ||
346 | * Feedback Multisynth Divider Equations [2] | ||
347 | * | ||
348 | * fVCO = fIN * (a + b/c) | ||
349 | * | ||
350 | * with 15 + 0/1048575 <= (a + b/c) <= 90 + 0/1048575 and | ||
351 | * fIN = fXTAL or fIN = fCLKIN/CLKIN_DIV | ||
352 | * | ||
353 | * Feedback Multisynth Register Equations | ||
354 | * | ||
355 | * (1) MSNx_P1[17:0] = 128 * a + floor(128 * b/c) - 512 | ||
356 | * (2) MSNx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c | ||
357 | * (3) MSNx_P3[19:0] = c | ||
358 | * | ||
359 | * Transposing (2) yields: (4) floor(128 * b/c) = (128 * b / MSNx_P2)/c | ||
360 | * | ||
361 | * Using (4) on (1) yields: | ||
362 | * MSNx_P1 = 128 * a + (128 * b/MSNx_P2)/c - 512 | ||
363 | * MSNx_P1 + 512 + MSNx_P2/c = 128 * a + 128 * b/c | ||
364 | * | ||
365 | * a + b/c = (MSNx_P1 + MSNx_P2/MSNx_P3 + 512)/128 | ||
366 | * = (MSNx_P1*MSNx_P3 + MSNx_P2 + 512*MSNx_P3)/(128*MSNx_P3) | ||
367 | * | ||
368 | */ | ||
369 | static int _si5351_pll_reparent(struct si5351_driver_data *drvdata, | ||
370 | int num, enum si5351_pll_src parent) | ||
371 | { | ||
372 | u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE; | ||
373 | |||
374 | if (parent == SI5351_PLL_SRC_DEFAULT) | ||
375 | return 0; | ||
376 | |||
377 | if (num > 2) | ||
378 | return -EINVAL; | ||
379 | |||
380 | if (drvdata->variant != SI5351_VARIANT_C && | ||
381 | parent != SI5351_PLL_SRC_XTAL) | ||
382 | return -EINVAL; | ||
383 | |||
384 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask, | ||
385 | (parent == SI5351_PLL_SRC_XTAL) ? 0 : mask); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static unsigned char si5351_pll_get_parent(struct clk_hw *hw) | ||
390 | { | ||
391 | struct si5351_hw_data *hwdata = | ||
392 | container_of(hw, struct si5351_hw_data, hw); | ||
393 | u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE; | ||
394 | u8 val; | ||
395 | |||
396 | val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE); | ||
397 | |||
398 | return (val & mask) ? 1 : 0; | ||
399 | } | ||
400 | |||
401 | static int si5351_pll_set_parent(struct clk_hw *hw, u8 index) | ||
402 | { | ||
403 | struct si5351_hw_data *hwdata = | ||
404 | container_of(hw, struct si5351_hw_data, hw); | ||
405 | |||
406 | if (hwdata->drvdata->variant != SI5351_VARIANT_C && | ||
407 | index > 0) | ||
408 | return -EPERM; | ||
409 | |||
410 | if (index > 1) | ||
411 | return -EINVAL; | ||
412 | |||
413 | return _si5351_pll_reparent(hwdata->drvdata, hwdata->num, | ||
414 | (index == 0) ? SI5351_PLL_SRC_XTAL : | ||
415 | SI5351_PLL_SRC_CLKIN); | ||
416 | } | ||
417 | |||
418 | static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw, | ||
419 | unsigned long parent_rate) | ||
420 | { | ||
421 | struct si5351_hw_data *hwdata = | ||
422 | container_of(hw, struct si5351_hw_data, hw); | ||
423 | u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS : | ||
424 | SI5351_PLLB_PARAMETERS; | ||
425 | unsigned long long rate; | ||
426 | |||
427 | if (!hwdata->params.valid) | ||
428 | si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params); | ||
429 | |||
430 | if (hwdata->params.p3 == 0) | ||
431 | return parent_rate; | ||
432 | |||
433 | /* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */ | ||
434 | rate = hwdata->params.p1 * hwdata->params.p3; | ||
435 | rate += 512 * hwdata->params.p3; | ||
436 | rate += hwdata->params.p2; | ||
437 | rate *= parent_rate; | ||
438 | do_div(rate, 128 * hwdata->params.p3); | ||
439 | |||
440 | dev_dbg(&hwdata->drvdata->client->dev, | ||
441 | "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", | ||
442 | __func__, __clk_get_name(hwdata->hw.clk), | ||
443 | hwdata->params.p1, hwdata->params.p2, hwdata->params.p3, | ||
444 | parent_rate, (unsigned long)rate); | ||
445 | |||
446 | return (unsigned long)rate; | ||
447 | } | ||
448 | |||
449 | static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
450 | unsigned long *parent_rate) | ||
451 | { | ||
452 | struct si5351_hw_data *hwdata = | ||
453 | container_of(hw, struct si5351_hw_data, hw); | ||
454 | unsigned long rfrac, denom, a, b, c; | ||
455 | unsigned long long lltmp; | ||
456 | |||
457 | if (rate < SI5351_PLL_VCO_MIN) | ||
458 | rate = SI5351_PLL_VCO_MIN; | ||
459 | if (rate > SI5351_PLL_VCO_MAX) | ||
460 | rate = SI5351_PLL_VCO_MAX; | ||
461 | |||
462 | /* determine integer part of feedback equation */ | ||
463 | a = rate / *parent_rate; | ||
464 | |||
465 | if (a < SI5351_PLL_A_MIN) | ||
466 | rate = *parent_rate * SI5351_PLL_A_MIN; | ||
467 | if (a > SI5351_PLL_A_MAX) | ||
468 | rate = *parent_rate * SI5351_PLL_A_MAX; | ||
469 | |||
470 | /* find best approximation for b/c = fVCO mod fIN */ | ||
471 | denom = 1000 * 1000; | ||
472 | lltmp = rate % (*parent_rate); | ||
473 | lltmp *= denom; | ||
474 | do_div(lltmp, *parent_rate); | ||
475 | rfrac = (unsigned long)lltmp; | ||
476 | |||
477 | b = 0; | ||
478 | c = 1; | ||
479 | if (rfrac) | ||
480 | rational_best_approximation(rfrac, denom, | ||
481 | SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c); | ||
482 | |||
483 | /* calculate parameters */ | ||
484 | hwdata->params.p3 = c; | ||
485 | hwdata->params.p2 = (128 * b) % c; | ||
486 | hwdata->params.p1 = 128 * a; | ||
487 | hwdata->params.p1 += (128 * b / c); | ||
488 | hwdata->params.p1 -= 512; | ||
489 | |||
490 | /* recalculate rate by fIN * (a + b/c) */ | ||
491 | lltmp = *parent_rate; | ||
492 | lltmp *= b; | ||
493 | do_div(lltmp, c); | ||
494 | |||
495 | rate = (unsigned long)lltmp; | ||
496 | rate += *parent_rate * a; | ||
497 | |||
498 | dev_dbg(&hwdata->drvdata->client->dev, | ||
499 | "%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n", | ||
500 | __func__, __clk_get_name(hwdata->hw.clk), a, b, c, | ||
501 | *parent_rate, rate); | ||
502 | |||
503 | return rate; | ||
504 | } | ||
505 | |||
506 | static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
507 | unsigned long parent_rate) | ||
508 | { | ||
509 | struct si5351_hw_data *hwdata = | ||
510 | container_of(hw, struct si5351_hw_data, hw); | ||
511 | u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS : | ||
512 | SI5351_PLLB_PARAMETERS; | ||
513 | |||
514 | /* write multisynth parameters */ | ||
515 | si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params); | ||
516 | |||
517 | /* plla/pllb ctrl is in clk6/clk7 ctrl registers */ | ||
518 | si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num, | ||
519 | SI5351_CLK_INTEGER_MODE, | ||
520 | (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); | ||
521 | |||
522 | dev_dbg(&hwdata->drvdata->client->dev, | ||
523 | "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", | ||
524 | __func__, __clk_get_name(hwdata->hw.clk), | ||
525 | hwdata->params.p1, hwdata->params.p2, hwdata->params.p3, | ||
526 | parent_rate, rate); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static const struct clk_ops si5351_pll_ops = { | ||
532 | .set_parent = si5351_pll_set_parent, | ||
533 | .get_parent = si5351_pll_get_parent, | ||
534 | .recalc_rate = si5351_pll_recalc_rate, | ||
535 | .round_rate = si5351_pll_round_rate, | ||
536 | .set_rate = si5351_pll_set_rate, | ||
537 | }; | ||
538 | |||
539 | /* | ||
540 | * Si5351 multisync divider | ||
541 | * | ||
542 | * for fOUT <= 150 MHz: | ||
543 | * | ||
544 | * fOUT = (fIN * (a + b/c)) / CLKOUTDIV | ||
545 | * | ||
546 | * with 6 + 0/1048575 <= (a + b/c) <= 1800 + 0/1048575 and | ||
547 | * fIN = fVCO0, fVCO1 | ||
548 | * | ||
549 | * Output Clock Multisynth Register Equations | ||
550 | * | ||
551 | * MSx_P1[17:0] = 128 * a + floor(128 * b/c) - 512 | ||
552 | * MSx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c | ||
553 | * MSx_P3[19:0] = c | ||
554 | * | ||
555 | * MS[6,7] are integer (P1) divide only, P2 = 0, P3 = 0 | ||
556 | * | ||
557 | * for 150MHz < fOUT <= 160MHz: | ||
558 | * | ||
559 | * MSx_P1 = 0, MSx_P2 = 0, MSx_P3 = 1, MSx_INT = 1, MSx_DIVBY4 = 11b | ||
560 | */ | ||
561 | static int _si5351_msynth_reparent(struct si5351_driver_data *drvdata, | ||
562 | int num, enum si5351_multisynth_src parent) | ||
563 | { | ||
564 | if (parent == SI5351_MULTISYNTH_SRC_DEFAULT) | ||
565 | return 0; | ||
566 | |||
567 | if (num > 8) | ||
568 | return -EINVAL; | ||
569 | |||
570 | si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT, | ||
571 | (parent == SI5351_MULTISYNTH_SRC_VCO0) ? 0 : | ||
572 | SI5351_CLK_PLL_SELECT); | ||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static unsigned char si5351_msynth_get_parent(struct clk_hw *hw) | ||
577 | { | ||
578 | struct si5351_hw_data *hwdata = | ||
579 | container_of(hw, struct si5351_hw_data, hw); | ||
580 | u8 val; | ||
581 | |||
582 | val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num); | ||
583 | |||
584 | return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0; | ||
585 | } | ||
586 | |||
587 | static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index) | ||
588 | { | ||
589 | struct si5351_hw_data *hwdata = | ||
590 | container_of(hw, struct si5351_hw_data, hw); | ||
591 | |||
592 | return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num, | ||
593 | (index == 0) ? SI5351_MULTISYNTH_SRC_VCO0 : | ||
594 | SI5351_MULTISYNTH_SRC_VCO1); | ||
595 | } | ||
596 | |||
597 | static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw, | ||
598 | unsigned long parent_rate) | ||
599 | { | ||
600 | struct si5351_hw_data *hwdata = | ||
601 | container_of(hw, struct si5351_hw_data, hw); | ||
602 | u8 reg = si5351_msynth_params_address(hwdata->num); | ||
603 | unsigned long long rate; | ||
604 | unsigned long m; | ||
605 | |||
606 | if (!hwdata->params.valid) | ||
607 | si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params); | ||
608 | |||
609 | if (hwdata->params.p3 == 0) | ||
610 | return parent_rate; | ||
611 | |||
612 | /* | ||
613 | * multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3) | ||
614 | * multisync6-7: fOUT = fIN / P1 | ||
615 | */ | ||
616 | rate = parent_rate; | ||
617 | if (hwdata->num > 5) { | ||
618 | m = hwdata->params.p1; | ||
619 | } else if ((si5351_reg_read(hwdata->drvdata, reg + 2) & | ||
620 | SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) { | ||
621 | m = 4; | ||
622 | } else { | ||
623 | rate *= 128 * hwdata->params.p3; | ||
624 | m = hwdata->params.p1 * hwdata->params.p3; | ||
625 | m += hwdata->params.p2; | ||
626 | m += 512 * hwdata->params.p3; | ||
627 | } | ||
628 | |||
629 | if (m == 0) | ||
630 | return 0; | ||
631 | do_div(rate, m); | ||
632 | |||
633 | dev_dbg(&hwdata->drvdata->client->dev, | ||
634 | "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, m = %lu, parent_rate = %lu, rate = %lu\n", | ||
635 | __func__, __clk_get_name(hwdata->hw.clk), | ||
636 | hwdata->params.p1, hwdata->params.p2, hwdata->params.p3, | ||
637 | m, parent_rate, (unsigned long)rate); | ||
638 | |||
639 | return (unsigned long)rate; | ||
640 | } | ||
641 | |||
642 | static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate, | ||
643 | unsigned long *parent_rate) | ||
644 | { | ||
645 | struct si5351_hw_data *hwdata = | ||
646 | container_of(hw, struct si5351_hw_data, hw); | ||
647 | unsigned long long lltmp; | ||
648 | unsigned long a, b, c; | ||
649 | int divby4; | ||
650 | |||
651 | /* multisync6-7 can only handle freqencies < 150MHz */ | ||
652 | if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ) | ||
653 | rate = SI5351_MULTISYNTH67_MAX_FREQ; | ||
654 | |||
655 | /* multisync frequency is 1MHz .. 160MHz */ | ||
656 | if (rate > SI5351_MULTISYNTH_MAX_FREQ) | ||
657 | rate = SI5351_MULTISYNTH_MAX_FREQ; | ||
658 | if (rate < SI5351_MULTISYNTH_MIN_FREQ) | ||
659 | rate = SI5351_MULTISYNTH_MIN_FREQ; | ||
660 | |||
661 | divby4 = 0; | ||
662 | if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ) | ||
663 | divby4 = 1; | ||
664 | |||
665 | /* multisync can set pll */ | ||
666 | if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) { | ||
667 | /* | ||
668 | * find largest integer divider for max | ||
669 | * vco frequency and given target rate | ||
670 | */ | ||
671 | if (divby4 == 0) { | ||
672 | lltmp = SI5351_PLL_VCO_MAX; | ||
673 | do_div(lltmp, rate); | ||
674 | a = (unsigned long)lltmp; | ||
675 | } else | ||
676 | a = 4; | ||
677 | |||
678 | b = 0; | ||
679 | c = 1; | ||
680 | |||
681 | *parent_rate = a * rate; | ||
682 | } else { | ||
683 | unsigned long rfrac, denom; | ||
684 | |||
685 | /* disable divby4 */ | ||
686 | if (divby4) { | ||
687 | rate = SI5351_MULTISYNTH_DIVBY4_FREQ; | ||
688 | divby4 = 0; | ||
689 | } | ||
690 | |||
691 | /* determine integer part of divider equation */ | ||
692 | a = *parent_rate / rate; | ||
693 | if (a < SI5351_MULTISYNTH_A_MIN) | ||
694 | a = SI5351_MULTISYNTH_A_MIN; | ||
695 | if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX) | ||
696 | a = SI5351_MULTISYNTH67_A_MAX; | ||
697 | else if (a > SI5351_MULTISYNTH_A_MAX) | ||
698 | a = SI5351_MULTISYNTH_A_MAX; | ||
699 | |||
700 | /* find best approximation for b/c = fVCO mod fOUT */ | ||
701 | denom = 1000 * 1000; | ||
702 | lltmp = (*parent_rate) % rate; | ||
703 | lltmp *= denom; | ||
704 | do_div(lltmp, rate); | ||
705 | rfrac = (unsigned long)lltmp; | ||
706 | |||
707 | b = 0; | ||
708 | c = 1; | ||
709 | if (rfrac) | ||
710 | rational_best_approximation(rfrac, denom, | ||
711 | SI5351_MULTISYNTH_B_MAX, SI5351_MULTISYNTH_C_MAX, | ||
712 | &b, &c); | ||
713 | } | ||
714 | |||
715 | /* recalculate rate by fOUT = fIN / (a + b/c) */ | ||
716 | lltmp = *parent_rate; | ||
717 | lltmp *= c; | ||
718 | do_div(lltmp, a * c + b); | ||
719 | rate = (unsigned long)lltmp; | ||
720 | |||
721 | /* calculate parameters */ | ||
722 | if (divby4) { | ||
723 | hwdata->params.p3 = 1; | ||
724 | hwdata->params.p2 = 0; | ||
725 | hwdata->params.p1 = 0; | ||
726 | } else { | ||
727 | hwdata->params.p3 = c; | ||
728 | hwdata->params.p2 = (128 * b) % c; | ||
729 | hwdata->params.p1 = 128 * a; | ||
730 | hwdata->params.p1 += (128 * b / c); | ||
731 | hwdata->params.p1 -= 512; | ||
732 | } | ||
733 | |||
734 | dev_dbg(&hwdata->drvdata->client->dev, | ||
735 | "%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n", | ||
736 | __func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4, | ||
737 | *parent_rate, rate); | ||
738 | |||
739 | return rate; | ||
740 | } | ||
741 | |||
742 | static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate, | ||
743 | unsigned long parent_rate) | ||
744 | { | ||
745 | struct si5351_hw_data *hwdata = | ||
746 | container_of(hw, struct si5351_hw_data, hw); | ||
747 | u8 reg = si5351_msynth_params_address(hwdata->num); | ||
748 | int divby4 = 0; | ||
749 | |||
750 | /* write multisynth parameters */ | ||
751 | si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params); | ||
752 | |||
753 | if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ) | ||
754 | divby4 = 1; | ||
755 | |||
756 | /* enable/disable integer mode and divby4 on multisynth0-5 */ | ||
757 | if (hwdata->num < 6) { | ||
758 | si5351_set_bits(hwdata->drvdata, reg + 2, | ||
759 | SI5351_OUTPUT_CLK_DIVBY4, | ||
760 | (divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0); | ||
761 | si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, | ||
762 | SI5351_CLK_INTEGER_MODE, | ||
763 | (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); | ||
764 | } | ||
765 | |||
766 | dev_dbg(&hwdata->drvdata->client->dev, | ||
767 | "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n", | ||
768 | __func__, __clk_get_name(hwdata->hw.clk), | ||
769 | hwdata->params.p1, hwdata->params.p2, hwdata->params.p3, | ||
770 | divby4, parent_rate, rate); | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static const struct clk_ops si5351_msynth_ops = { | ||
776 | .set_parent = si5351_msynth_set_parent, | ||
777 | .get_parent = si5351_msynth_get_parent, | ||
778 | .recalc_rate = si5351_msynth_recalc_rate, | ||
779 | .round_rate = si5351_msynth_round_rate, | ||
780 | .set_rate = si5351_msynth_set_rate, | ||
781 | }; | ||
782 | |||
783 | /* | ||
784 | * Si5351 clkout divider | ||
785 | */ | ||
786 | static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata, | ||
787 | int num, enum si5351_clkout_src parent) | ||
788 | { | ||
789 | u8 val; | ||
790 | |||
791 | if (num > 8) | ||
792 | return -EINVAL; | ||
793 | |||
794 | switch (parent) { | ||
795 | case SI5351_CLKOUT_SRC_MSYNTH_N: | ||
796 | val = SI5351_CLK_INPUT_MULTISYNTH_N; | ||
797 | break; | ||
798 | case SI5351_CLKOUT_SRC_MSYNTH_0_4: | ||
799 | /* clk0/clk4 can only connect to its own multisync */ | ||
800 | if (num == 0 || num == 4) | ||
801 | val = SI5351_CLK_INPUT_MULTISYNTH_N; | ||
802 | else | ||
803 | val = SI5351_CLK_INPUT_MULTISYNTH_0_4; | ||
804 | break; | ||
805 | case SI5351_CLKOUT_SRC_XTAL: | ||
806 | val = SI5351_CLK_INPUT_XTAL; | ||
807 | break; | ||
808 | case SI5351_CLKOUT_SRC_CLKIN: | ||
809 | if (drvdata->variant != SI5351_VARIANT_C) | ||
810 | return -EINVAL; | ||
811 | |||
812 | val = SI5351_CLK_INPUT_CLKIN; | ||
813 | break; | ||
814 | default: | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, | ||
819 | SI5351_CLK_INPUT_MASK, val); | ||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | static int _si5351_clkout_set_drive_strength( | ||
824 | struct si5351_driver_data *drvdata, int num, | ||
825 | enum si5351_drive_strength drive) | ||
826 | { | ||
827 | u8 mask; | ||
828 | |||
829 | if (num > 8) | ||
830 | return -EINVAL; | ||
831 | |||
832 | switch (drive) { | ||
833 | case SI5351_DRIVE_2MA: | ||
834 | mask = SI5351_CLK_DRIVE_STRENGTH_2MA; | ||
835 | break; | ||
836 | case SI5351_DRIVE_4MA: | ||
837 | mask = SI5351_CLK_DRIVE_STRENGTH_4MA; | ||
838 | break; | ||
839 | case SI5351_DRIVE_6MA: | ||
840 | mask = SI5351_CLK_DRIVE_STRENGTH_6MA; | ||
841 | break; | ||
842 | case SI5351_DRIVE_8MA: | ||
843 | mask = SI5351_CLK_DRIVE_STRENGTH_8MA; | ||
844 | break; | ||
845 | default: | ||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, | ||
850 | SI5351_CLK_DRIVE_STRENGTH_MASK, mask); | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int si5351_clkout_prepare(struct clk_hw *hw) | ||
855 | { | ||
856 | struct si5351_hw_data *hwdata = | ||
857 | container_of(hw, struct si5351_hw_data, hw); | ||
858 | |||
859 | si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, | ||
860 | SI5351_CLK_POWERDOWN, 0); | ||
861 | si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL, | ||
862 | (1 << hwdata->num), 0); | ||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | static void si5351_clkout_unprepare(struct clk_hw *hw) | ||
867 | { | ||
868 | struct si5351_hw_data *hwdata = | ||
869 | container_of(hw, struct si5351_hw_data, hw); | ||
870 | |||
871 | si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, | ||
872 | SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN); | ||
873 | si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL, | ||
874 | (1 << hwdata->num), (1 << hwdata->num)); | ||
875 | } | ||
876 | |||
877 | static u8 si5351_clkout_get_parent(struct clk_hw *hw) | ||
878 | { | ||
879 | struct si5351_hw_data *hwdata = | ||
880 | container_of(hw, struct si5351_hw_data, hw); | ||
881 | int index = 0; | ||
882 | unsigned char val; | ||
883 | |||
884 | val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num); | ||
885 | switch (val & SI5351_CLK_INPUT_MASK) { | ||
886 | case SI5351_CLK_INPUT_MULTISYNTH_N: | ||
887 | index = 0; | ||
888 | break; | ||
889 | case SI5351_CLK_INPUT_MULTISYNTH_0_4: | ||
890 | index = 1; | ||
891 | break; | ||
892 | case SI5351_CLK_INPUT_XTAL: | ||
893 | index = 2; | ||
894 | break; | ||
895 | case SI5351_CLK_INPUT_CLKIN: | ||
896 | index = 3; | ||
897 | break; | ||
898 | } | ||
899 | |||
900 | return index; | ||
901 | } | ||
902 | |||
903 | static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index) | ||
904 | { | ||
905 | struct si5351_hw_data *hwdata = | ||
906 | container_of(hw, struct si5351_hw_data, hw); | ||
907 | enum si5351_clkout_src parent = SI5351_CLKOUT_SRC_DEFAULT; | ||
908 | |||
909 | switch (index) { | ||
910 | case 0: | ||
911 | parent = SI5351_CLKOUT_SRC_MSYNTH_N; | ||
912 | break; | ||
913 | case 1: | ||
914 | parent = SI5351_CLKOUT_SRC_MSYNTH_0_4; | ||
915 | break; | ||
916 | case 2: | ||
917 | parent = SI5351_CLKOUT_SRC_XTAL; | ||
918 | break; | ||
919 | case 3: | ||
920 | parent = SI5351_CLKOUT_SRC_CLKIN; | ||
921 | break; | ||
922 | } | ||
923 | |||
924 | return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent); | ||
925 | } | ||
926 | |||
927 | static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw, | ||
928 | unsigned long parent_rate) | ||
929 | { | ||
930 | struct si5351_hw_data *hwdata = | ||
931 | container_of(hw, struct si5351_hw_data, hw); | ||
932 | unsigned char reg; | ||
933 | unsigned char rdiv; | ||
934 | |||
935 | if (hwdata->num > 5) | ||
936 | reg = si5351_msynth_params_address(hwdata->num) + 2; | ||
937 | else | ||
938 | reg = SI5351_CLK6_7_OUTPUT_DIVIDER; | ||
939 | |||
940 | rdiv = si5351_reg_read(hwdata->drvdata, reg); | ||
941 | if (hwdata->num == 6) { | ||
942 | rdiv &= SI5351_OUTPUT_CLK6_DIV_MASK; | ||
943 | } else { | ||
944 | rdiv &= SI5351_OUTPUT_CLK_DIV_MASK; | ||
945 | rdiv >>= SI5351_OUTPUT_CLK_DIV_SHIFT; | ||
946 | } | ||
947 | |||
948 | return parent_rate >> rdiv; | ||
949 | } | ||
950 | |||
951 | static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate, | ||
952 | unsigned long *parent_rate) | ||
953 | { | ||
954 | struct si5351_hw_data *hwdata = | ||
955 | container_of(hw, struct si5351_hw_data, hw); | ||
956 | unsigned char rdiv; | ||
957 | |||
958 | /* clkout6/7 can only handle output freqencies < 150MHz */ | ||
959 | if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ) | ||
960 | rate = SI5351_CLKOUT67_MAX_FREQ; | ||
961 | |||
962 | /* clkout freqency is 8kHz - 160MHz */ | ||
963 | if (rate > SI5351_CLKOUT_MAX_FREQ) | ||
964 | rate = SI5351_CLKOUT_MAX_FREQ; | ||
965 | if (rate < SI5351_CLKOUT_MIN_FREQ) | ||
966 | rate = SI5351_CLKOUT_MIN_FREQ; | ||
967 | |||
968 | /* request frequency if multisync master */ | ||
969 | if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) { | ||
970 | /* use r divider for frequencies below 1MHz */ | ||
971 | rdiv = SI5351_OUTPUT_CLK_DIV_1; | ||
972 | while (rate < SI5351_MULTISYNTH_MIN_FREQ && | ||
973 | rdiv < SI5351_OUTPUT_CLK_DIV_128) { | ||
974 | rdiv += 1; | ||
975 | rate *= 2; | ||
976 | } | ||
977 | *parent_rate = rate; | ||
978 | } else { | ||
979 | unsigned long new_rate, new_err, err; | ||
980 | |||
981 | /* round to closed rdiv */ | ||
982 | rdiv = SI5351_OUTPUT_CLK_DIV_1; | ||
983 | new_rate = *parent_rate; | ||
984 | err = abs(new_rate - rate); | ||
985 | do { | ||
986 | new_rate >>= 1; | ||
987 | new_err = abs(new_rate - rate); | ||
988 | if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128) | ||
989 | break; | ||
990 | rdiv++; | ||
991 | err = new_err; | ||
992 | } while (1); | ||
993 | } | ||
994 | rate = *parent_rate >> rdiv; | ||
995 | |||
996 | dev_dbg(&hwdata->drvdata->client->dev, | ||
997 | "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", | ||
998 | __func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv), | ||
999 | *parent_rate, rate); | ||
1000 | |||
1001 | return rate; | ||
1002 | } | ||
1003 | |||
1004 | static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate, | ||
1005 | unsigned long parent_rate) | ||
1006 | { | ||
1007 | struct si5351_hw_data *hwdata = | ||
1008 | container_of(hw, struct si5351_hw_data, hw); | ||
1009 | unsigned long new_rate, new_err, err; | ||
1010 | unsigned char rdiv; | ||
1011 | |||
1012 | /* round to closed rdiv */ | ||
1013 | rdiv = SI5351_OUTPUT_CLK_DIV_1; | ||
1014 | new_rate = parent_rate; | ||
1015 | err = abs(new_rate - rate); | ||
1016 | do { | ||
1017 | new_rate >>= 1; | ||
1018 | new_err = abs(new_rate - rate); | ||
1019 | if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128) | ||
1020 | break; | ||
1021 | rdiv++; | ||
1022 | err = new_err; | ||
1023 | } while (1); | ||
1024 | |||
1025 | /* write output divider */ | ||
1026 | switch (hwdata->num) { | ||
1027 | case 6: | ||
1028 | si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER, | ||
1029 | SI5351_OUTPUT_CLK6_DIV_MASK, rdiv); | ||
1030 | break; | ||
1031 | case 7: | ||
1032 | si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER, | ||
1033 | SI5351_OUTPUT_CLK_DIV_MASK, | ||
1034 | rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT); | ||
1035 | break; | ||
1036 | default: | ||
1037 | si5351_set_bits(hwdata->drvdata, | ||
1038 | si5351_msynth_params_address(hwdata->num) + 2, | ||
1039 | SI5351_OUTPUT_CLK_DIV_MASK, | ||
1040 | rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT); | ||
1041 | } | ||
1042 | |||
1043 | /* powerup clkout */ | ||
1044 | si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, | ||
1045 | SI5351_CLK_POWERDOWN, 0); | ||
1046 | |||
1047 | dev_dbg(&hwdata->drvdata->client->dev, | ||
1048 | "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", | ||
1049 | __func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv), | ||
1050 | parent_rate, rate); | ||
1051 | |||
1052 | return 0; | ||
1053 | } | ||
1054 | |||
1055 | static const struct clk_ops si5351_clkout_ops = { | ||
1056 | .prepare = si5351_clkout_prepare, | ||
1057 | .unprepare = si5351_clkout_unprepare, | ||
1058 | .set_parent = si5351_clkout_set_parent, | ||
1059 | .get_parent = si5351_clkout_get_parent, | ||
1060 | .recalc_rate = si5351_clkout_recalc_rate, | ||
1061 | .round_rate = si5351_clkout_round_rate, | ||
1062 | .set_rate = si5351_clkout_set_rate, | ||
1063 | }; | ||
1064 | |||
1065 | /* | ||
1066 | * Si5351 i2c probe and DT | ||
1067 | */ | ||
1068 | #ifdef CONFIG_OF | ||
1069 | static const struct of_device_id si5351_dt_ids[] = { | ||
1070 | { .compatible = "silabs,si5351a", .data = (void *)SI5351_VARIANT_A, }, | ||
1071 | { .compatible = "silabs,si5351a-msop", | ||
1072 | .data = (void *)SI5351_VARIANT_A3, }, | ||
1073 | { .compatible = "silabs,si5351b", .data = (void *)SI5351_VARIANT_B, }, | ||
1074 | { .compatible = "silabs,si5351c", .data = (void *)SI5351_VARIANT_C, }, | ||
1075 | { } | ||
1076 | }; | ||
1077 | MODULE_DEVICE_TABLE(of, si5351_dt_ids); | ||
1078 | |||
1079 | static int si5351_dt_parse(struct i2c_client *client) | ||
1080 | { | ||
1081 | struct device_node *child, *np = client->dev.of_node; | ||
1082 | struct si5351_platform_data *pdata; | ||
1083 | const struct of_device_id *match; | ||
1084 | struct property *prop; | ||
1085 | const __be32 *p; | ||
1086 | int num = 0; | ||
1087 | u32 val; | ||
1088 | |||
1089 | if (np == NULL) | ||
1090 | return 0; | ||
1091 | |||
1092 | match = of_match_node(si5351_dt_ids, np); | ||
1093 | if (match == NULL) | ||
1094 | return -EINVAL; | ||
1095 | |||
1096 | pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); | ||
1097 | if (!pdata) | ||
1098 | return -ENOMEM; | ||
1099 | |||
1100 | pdata->variant = (enum si5351_variant)match->data; | ||
1101 | pdata->clk_xtal = of_clk_get(np, 0); | ||
1102 | if (!IS_ERR(pdata->clk_xtal)) | ||
1103 | clk_put(pdata->clk_xtal); | ||
1104 | pdata->clk_clkin = of_clk_get(np, 1); | ||
1105 | if (!IS_ERR(pdata->clk_clkin)) | ||
1106 | clk_put(pdata->clk_clkin); | ||
1107 | |||
1108 | /* | ||
1109 | * property silabs,pll-source : <num src>, [<..>] | ||
1110 | * allow to selectively set pll source | ||
1111 | */ | ||
1112 | of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) { | ||
1113 | if (num >= 2) { | ||
1114 | dev_err(&client->dev, | ||
1115 | "invalid pll %d on pll-source prop\n", num); | ||
1116 | return -EINVAL; | ||
1117 | } | ||
1118 | |||
1119 | p = of_prop_next_u32(prop, p, &val); | ||
1120 | if (!p) { | ||
1121 | dev_err(&client->dev, | ||
1122 | "missing pll-source for pll %d\n", num); | ||
1123 | return -EINVAL; | ||
1124 | } | ||
1125 | |||
1126 | switch (val) { | ||
1127 | case 0: | ||
1128 | pdata->pll_src[num] = SI5351_PLL_SRC_XTAL; | ||
1129 | break; | ||
1130 | case 1: | ||
1131 | if (pdata->variant != SI5351_VARIANT_C) { | ||
1132 | dev_err(&client->dev, | ||
1133 | "invalid parent %d for pll %d\n", | ||
1134 | val, num); | ||
1135 | return -EINVAL; | ||
1136 | } | ||
1137 | pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN; | ||
1138 | break; | ||
1139 | default: | ||
1140 | dev_err(&client->dev, | ||
1141 | "invalid parent %d for pll %d\n", val, num); | ||
1142 | return -EINVAL; | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | /* per clkout properties */ | ||
1147 | for_each_child_of_node(np, child) { | ||
1148 | if (of_property_read_u32(child, "reg", &num)) { | ||
1149 | dev_err(&client->dev, "missing reg property of %s\n", | ||
1150 | child->name); | ||
1151 | return -EINVAL; | ||
1152 | } | ||
1153 | |||
1154 | if (num >= 8 || | ||
1155 | (pdata->variant == SI5351_VARIANT_A3 && num >= 3)) { | ||
1156 | dev_err(&client->dev, "invalid clkout %d\n", num); | ||
1157 | return -EINVAL; | ||
1158 | } | ||
1159 | |||
1160 | if (!of_property_read_u32(child, "silabs,multisynth-source", | ||
1161 | &val)) { | ||
1162 | switch (val) { | ||
1163 | case 0: | ||
1164 | pdata->clkout[num].multisynth_src = | ||
1165 | SI5351_MULTISYNTH_SRC_VCO0; | ||
1166 | break; | ||
1167 | case 1: | ||
1168 | pdata->clkout[num].multisynth_src = | ||
1169 | SI5351_MULTISYNTH_SRC_VCO1; | ||
1170 | break; | ||
1171 | default: | ||
1172 | dev_err(&client->dev, | ||
1173 | "invalid parent %d for multisynth %d\n", | ||
1174 | val, num); | ||
1175 | return -EINVAL; | ||
1176 | } | ||
1177 | } | ||
1178 | |||
1179 | if (!of_property_read_u32(child, "silabs,clock-source", &val)) { | ||
1180 | switch (val) { | ||
1181 | case 0: | ||
1182 | pdata->clkout[num].clkout_src = | ||
1183 | SI5351_CLKOUT_SRC_MSYNTH_N; | ||
1184 | break; | ||
1185 | case 1: | ||
1186 | pdata->clkout[num].clkout_src = | ||
1187 | SI5351_CLKOUT_SRC_MSYNTH_0_4; | ||
1188 | break; | ||
1189 | case 2: | ||
1190 | pdata->clkout[num].clkout_src = | ||
1191 | SI5351_CLKOUT_SRC_XTAL; | ||
1192 | break; | ||
1193 | case 3: | ||
1194 | if (pdata->variant != SI5351_VARIANT_C) { | ||
1195 | dev_err(&client->dev, | ||
1196 | "invalid parent %d for clkout %d\n", | ||
1197 | val, num); | ||
1198 | return -EINVAL; | ||
1199 | } | ||
1200 | pdata->clkout[num].clkout_src = | ||
1201 | SI5351_CLKOUT_SRC_CLKIN; | ||
1202 | break; | ||
1203 | default: | ||
1204 | dev_err(&client->dev, | ||
1205 | "invalid parent %d for clkout %d\n", | ||
1206 | val, num); | ||
1207 | return -EINVAL; | ||
1208 | } | ||
1209 | } | ||
1210 | |||
1211 | if (!of_property_read_u32(child, "silabs,drive-strength", | ||
1212 | &val)) { | ||
1213 | switch (val) { | ||
1214 | case SI5351_DRIVE_2MA: | ||
1215 | case SI5351_DRIVE_4MA: | ||
1216 | case SI5351_DRIVE_6MA: | ||
1217 | case SI5351_DRIVE_8MA: | ||
1218 | pdata->clkout[num].drive = val; | ||
1219 | break; | ||
1220 | default: | ||
1221 | dev_err(&client->dev, | ||
1222 | "invalid drive strength %d for clkout %d\n", | ||
1223 | val, num); | ||
1224 | return -EINVAL; | ||
1225 | } | ||
1226 | } | ||
1227 | |||
1228 | if (!of_property_read_u32(child, "clock-frequency", &val)) | ||
1229 | pdata->clkout[num].rate = val; | ||
1230 | |||
1231 | pdata->clkout[num].pll_master = | ||
1232 | of_property_read_bool(child, "silabs,pll-master"); | ||
1233 | } | ||
1234 | client->dev.platform_data = pdata; | ||
1235 | |||
1236 | return 0; | ||
1237 | } | ||
1238 | #else | ||
1239 | static int si5351_dt_parse(struct i2c_client *client) | ||
1240 | { | ||
1241 | return 0; | ||
1242 | } | ||
1243 | #endif /* CONFIG_OF */ | ||
1244 | |||
1245 | static int si5351_i2c_probe(struct i2c_client *client, | ||
1246 | const struct i2c_device_id *id) | ||
1247 | { | ||
1248 | struct si5351_platform_data *pdata; | ||
1249 | struct si5351_driver_data *drvdata; | ||
1250 | struct clk_init_data init; | ||
1251 | struct clk *clk; | ||
1252 | const char *parent_names[4]; | ||
1253 | u8 num_parents, num_clocks; | ||
1254 | int ret, n; | ||
1255 | |||
1256 | ret = si5351_dt_parse(client); | ||
1257 | if (ret) | ||
1258 | return ret; | ||
1259 | |||
1260 | pdata = client->dev.platform_data; | ||
1261 | if (!pdata) | ||
1262 | return -EINVAL; | ||
1263 | |||
1264 | drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL); | ||
1265 | if (drvdata == NULL) { | ||
1266 | dev_err(&client->dev, "unable to allocate driver data\n"); | ||
1267 | return -ENOMEM; | ||
1268 | } | ||
1269 | |||
1270 | i2c_set_clientdata(client, drvdata); | ||
1271 | drvdata->client = client; | ||
1272 | drvdata->variant = pdata->variant; | ||
1273 | drvdata->pxtal = pdata->clk_xtal; | ||
1274 | drvdata->pclkin = pdata->clk_clkin; | ||
1275 | |||
1276 | drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config); | ||
1277 | if (IS_ERR(drvdata->regmap)) { | ||
1278 | dev_err(&client->dev, "failed to allocate register map\n"); | ||
1279 | return PTR_ERR(drvdata->regmap); | ||
1280 | } | ||
1281 | |||
1282 | /* Disable interrupts */ | ||
1283 | si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0); | ||
1284 | /* Set disabled output drivers to drive low */ | ||
1285 | si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00); | ||
1286 | si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00); | ||
1287 | /* Ensure pll select is on XTAL for Si5351A/B */ | ||
1288 | if (drvdata->variant != SI5351_VARIANT_C) | ||
1289 | si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, | ||
1290 | SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0); | ||
1291 | |||
1292 | /* setup clock configuration */ | ||
1293 | for (n = 0; n < 2; n++) { | ||
1294 | ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]); | ||
1295 | if (ret) { | ||
1296 | dev_err(&client->dev, | ||
1297 | "failed to reparent pll %d to %d\n", | ||
1298 | n, pdata->pll_src[n]); | ||
1299 | return ret; | ||
1300 | } | ||
1301 | } | ||
1302 | |||
1303 | for (n = 0; n < 8; n++) { | ||
1304 | ret = _si5351_msynth_reparent(drvdata, n, | ||
1305 | pdata->clkout[n].multisynth_src); | ||
1306 | if (ret) { | ||
1307 | dev_err(&client->dev, | ||
1308 | "failed to reparent multisynth %d to %d\n", | ||
1309 | n, pdata->clkout[n].multisynth_src); | ||
1310 | return ret; | ||
1311 | } | ||
1312 | |||
1313 | ret = _si5351_clkout_reparent(drvdata, n, | ||
1314 | pdata->clkout[n].clkout_src); | ||
1315 | if (ret) { | ||
1316 | dev_err(&client->dev, | ||
1317 | "failed to reparent clkout %d to %d\n", | ||
1318 | n, pdata->clkout[n].clkout_src); | ||
1319 | return ret; | ||
1320 | } | ||
1321 | |||
1322 | ret = _si5351_clkout_set_drive_strength(drvdata, n, | ||
1323 | pdata->clkout[n].drive); | ||
1324 | if (ret) { | ||
1325 | dev_err(&client->dev, | ||
1326 | "failed set drive strength of clkout%d to %d\n", | ||
1327 | n, pdata->clkout[n].drive); | ||
1328 | return ret; | ||
1329 | } | ||
1330 | } | ||
1331 | |||
1332 | /* register xtal input clock gate */ | ||
1333 | memset(&init, 0, sizeof(init)); | ||
1334 | init.name = si5351_input_names[0]; | ||
1335 | init.ops = &si5351_xtal_ops; | ||
1336 | init.flags = 0; | ||
1337 | if (!IS_ERR(drvdata->pxtal)) { | ||
1338 | drvdata->pxtal_name = __clk_get_name(drvdata->pxtal); | ||
1339 | init.parent_names = &drvdata->pxtal_name; | ||
1340 | init.num_parents = 1; | ||
1341 | } | ||
1342 | drvdata->xtal.init = &init; | ||
1343 | clk = devm_clk_register(&client->dev, &drvdata->xtal); | ||
1344 | if (IS_ERR(clk)) { | ||
1345 | dev_err(&client->dev, "unable to register %s\n", init.name); | ||
1346 | return PTR_ERR(clk); | ||
1347 | } | ||
1348 | |||
1349 | /* register clkin input clock gate */ | ||
1350 | if (drvdata->variant == SI5351_VARIANT_C) { | ||
1351 | memset(&init, 0, sizeof(init)); | ||
1352 | init.name = si5351_input_names[1]; | ||
1353 | init.ops = &si5351_clkin_ops; | ||
1354 | if (!IS_ERR(drvdata->pclkin)) { | ||
1355 | drvdata->pclkin_name = __clk_get_name(drvdata->pclkin); | ||
1356 | init.parent_names = &drvdata->pclkin_name; | ||
1357 | init.num_parents = 1; | ||
1358 | } | ||
1359 | drvdata->clkin.init = &init; | ||
1360 | clk = devm_clk_register(&client->dev, &drvdata->clkin); | ||
1361 | if (IS_ERR(clk)) { | ||
1362 | dev_err(&client->dev, "unable to register %s\n", | ||
1363 | init.name); | ||
1364 | return PTR_ERR(clk); | ||
1365 | } | ||
1366 | } | ||
1367 | |||
1368 | /* Si5351C allows to mux either xtal or clkin to PLL input */ | ||
1369 | num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1; | ||
1370 | parent_names[0] = si5351_input_names[0]; | ||
1371 | parent_names[1] = si5351_input_names[1]; | ||
1372 | |||
1373 | /* register PLLA */ | ||
1374 | drvdata->pll[0].num = 0; | ||
1375 | drvdata->pll[0].drvdata = drvdata; | ||
1376 | drvdata->pll[0].hw.init = &init; | ||
1377 | memset(&init, 0, sizeof(init)); | ||
1378 | init.name = si5351_pll_names[0]; | ||
1379 | init.ops = &si5351_pll_ops; | ||
1380 | init.flags = 0; | ||
1381 | init.parent_names = parent_names; | ||
1382 | init.num_parents = num_parents; | ||
1383 | clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw); | ||
1384 | if (IS_ERR(clk)) { | ||
1385 | dev_err(&client->dev, "unable to register %s\n", init.name); | ||
1386 | return -EINVAL; | ||
1387 | } | ||
1388 | |||
1389 | /* register PLLB or VXCO (Si5351B) */ | ||
1390 | drvdata->pll[1].num = 1; | ||
1391 | drvdata->pll[1].drvdata = drvdata; | ||
1392 | drvdata->pll[1].hw.init = &init; | ||
1393 | memset(&init, 0, sizeof(init)); | ||
1394 | if (drvdata->variant == SI5351_VARIANT_B) { | ||
1395 | init.name = si5351_pll_names[2]; | ||
1396 | init.ops = &si5351_vxco_ops; | ||
1397 | init.flags = CLK_IS_ROOT; | ||
1398 | init.parent_names = NULL; | ||
1399 | init.num_parents = 0; | ||
1400 | } else { | ||
1401 | init.name = si5351_pll_names[1]; | ||
1402 | init.ops = &si5351_pll_ops; | ||
1403 | init.flags = 0; | ||
1404 | init.parent_names = parent_names; | ||
1405 | init.num_parents = num_parents; | ||
1406 | } | ||
1407 | clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw); | ||
1408 | if (IS_ERR(clk)) { | ||
1409 | dev_err(&client->dev, "unable to register %s\n", init.name); | ||
1410 | return -EINVAL; | ||
1411 | } | ||
1412 | |||
1413 | /* register clk multisync and clk out divider */ | ||
1414 | num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8; | ||
1415 | parent_names[0] = si5351_pll_names[0]; | ||
1416 | if (drvdata->variant == SI5351_VARIANT_B) | ||
1417 | parent_names[1] = si5351_pll_names[2]; | ||
1418 | else | ||
1419 | parent_names[1] = si5351_pll_names[1]; | ||
1420 | |||
1421 | drvdata->msynth = devm_kzalloc(&client->dev, num_clocks * | ||
1422 | sizeof(*drvdata->msynth), GFP_KERNEL); | ||
1423 | drvdata->clkout = devm_kzalloc(&client->dev, num_clocks * | ||
1424 | sizeof(*drvdata->clkout), GFP_KERNEL); | ||
1425 | |||
1426 | drvdata->onecell.clk_num = num_clocks; | ||
1427 | drvdata->onecell.clks = devm_kzalloc(&client->dev, | ||
1428 | num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL); | ||
1429 | |||
1430 | if (WARN_ON(!drvdata->msynth || !drvdata->clkout || | ||
1431 | !drvdata->onecell.clks)) | ||
1432 | return -ENOMEM; | ||
1433 | |||
1434 | for (n = 0; n < num_clocks; n++) { | ||
1435 | drvdata->msynth[n].num = n; | ||
1436 | drvdata->msynth[n].drvdata = drvdata; | ||
1437 | drvdata->msynth[n].hw.init = &init; | ||
1438 | memset(&init, 0, sizeof(init)); | ||
1439 | init.name = si5351_msynth_names[n]; | ||
1440 | init.ops = &si5351_msynth_ops; | ||
1441 | init.flags = 0; | ||
1442 | if (pdata->clkout[n].pll_master) | ||
1443 | init.flags |= CLK_SET_RATE_PARENT; | ||
1444 | init.parent_names = parent_names; | ||
1445 | init.num_parents = 2; | ||
1446 | clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw); | ||
1447 | if (IS_ERR(clk)) { | ||
1448 | dev_err(&client->dev, "unable to register %s\n", | ||
1449 | init.name); | ||
1450 | return -EINVAL; | ||
1451 | } | ||
1452 | } | ||
1453 | |||
1454 | num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3; | ||
1455 | parent_names[2] = si5351_input_names[0]; | ||
1456 | parent_names[3] = si5351_input_names[1]; | ||
1457 | for (n = 0; n < num_clocks; n++) { | ||
1458 | parent_names[0] = si5351_msynth_names[n]; | ||
1459 | parent_names[1] = (n < 4) ? si5351_msynth_names[0] : | ||
1460 | si5351_msynth_names[4]; | ||
1461 | |||
1462 | drvdata->clkout[n].num = n; | ||
1463 | drvdata->clkout[n].drvdata = drvdata; | ||
1464 | drvdata->clkout[n].hw.init = &init; | ||
1465 | memset(&init, 0, sizeof(init)); | ||
1466 | init.name = si5351_clkout_names[n]; | ||
1467 | init.ops = &si5351_clkout_ops; | ||
1468 | init.flags = 0; | ||
1469 | if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N) | ||
1470 | init.flags |= CLK_SET_RATE_PARENT; | ||
1471 | init.parent_names = parent_names; | ||
1472 | init.num_parents = num_parents; | ||
1473 | clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw); | ||
1474 | if (IS_ERR(clk)) { | ||
1475 | dev_err(&client->dev, "unable to register %s\n", | ||
1476 | init.name); | ||
1477 | return -EINVAL; | ||
1478 | } | ||
1479 | drvdata->onecell.clks[n] = clk; | ||
1480 | } | ||
1481 | |||
1482 | ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get, | ||
1483 | &drvdata->onecell); | ||
1484 | if (ret) { | ||
1485 | dev_err(&client->dev, "unable to add clk provider\n"); | ||
1486 | return ret; | ||
1487 | } | ||
1488 | |||
1489 | return 0; | ||
1490 | } | ||
1491 | |||
1492 | static const struct i2c_device_id si5351_i2c_ids[] = { | ||
1493 | { "silabs,si5351", 0 }, | ||
1494 | { } | ||
1495 | }; | ||
1496 | MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids); | ||
1497 | |||
1498 | static struct i2c_driver si5351_driver = { | ||
1499 | .driver = { | ||
1500 | .name = "si5351", | ||
1501 | .of_match_table = of_match_ptr(si5351_dt_ids), | ||
1502 | }, | ||
1503 | .probe = si5351_i2c_probe, | ||
1504 | .id_table = si5351_i2c_ids, | ||
1505 | }; | ||
1506 | module_i2c_driver(si5351_driver); | ||
1507 | |||
1508 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com"); | ||
1509 | MODULE_DESCRIPTION("Silicon Labs Si5351A/B/C clock generator driver"); | ||
1510 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/clk/clk-si5351.h b/drivers/clk/clk-si5351.h new file mode 100644 index 000000000000..af41b5080f43 --- /dev/null +++ b/drivers/clk/clk-si5351.h | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * clk-si5351.h: Silicon Laboratories Si5351A/B/C I2C Clock Generator | ||
3 | * | ||
4 | * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * Rabeeh Khoury <rabeeh@solid-run.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _CLK_SI5351_H_ | ||
14 | #define _CLK_SI5351_H_ | ||
15 | |||
16 | #define SI5351_BUS_BASE_ADDR 0x60 | ||
17 | |||
18 | #define SI5351_PLL_VCO_MIN 600000000 | ||
19 | #define SI5351_PLL_VCO_MAX 900000000 | ||
20 | #define SI5351_MULTISYNTH_MIN_FREQ 1000000 | ||
21 | #define SI5351_MULTISYNTH_DIVBY4_FREQ 150000000 | ||
22 | #define SI5351_MULTISYNTH_MAX_FREQ 160000000 | ||
23 | #define SI5351_MULTISYNTH67_MAX_FREQ SI5351_MULTISYNTH_DIVBY4_FREQ | ||
24 | #define SI5351_CLKOUT_MIN_FREQ 8000 | ||
25 | #define SI5351_CLKOUT_MAX_FREQ SI5351_MULTISYNTH_MAX_FREQ | ||
26 | #define SI5351_CLKOUT67_MAX_FREQ SI5351_MULTISYNTH67_MAX_FREQ | ||
27 | |||
28 | #define SI5351_PLL_A_MIN 15 | ||
29 | #define SI5351_PLL_A_MAX 90 | ||
30 | #define SI5351_PLL_B_MAX (SI5351_PLL_C_MAX-1) | ||
31 | #define SI5351_PLL_C_MAX 1048575 | ||
32 | #define SI5351_MULTISYNTH_A_MIN 6 | ||
33 | #define SI5351_MULTISYNTH_A_MAX 1800 | ||
34 | #define SI5351_MULTISYNTH67_A_MAX 254 | ||
35 | #define SI5351_MULTISYNTH_B_MAX (SI5351_MULTISYNTH_C_MAX-1) | ||
36 | #define SI5351_MULTISYNTH_C_MAX 1048575 | ||
37 | #define SI5351_MULTISYNTH_P1_MAX ((1<<18)-1) | ||
38 | #define SI5351_MULTISYNTH_P2_MAX ((1<<20)-1) | ||
39 | #define SI5351_MULTISYNTH_P3_MAX ((1<<20)-1) | ||
40 | |||
41 | #define SI5351_DEVICE_STATUS 0 | ||
42 | #define SI5351_INTERRUPT_STATUS 1 | ||
43 | #define SI5351_INTERRUPT_MASK 2 | ||
44 | #define SI5351_STATUS_SYS_INIT (1<<7) | ||
45 | #define SI5351_STATUS_LOL_B (1<<6) | ||
46 | #define SI5351_STATUS_LOL_A (1<<5) | ||
47 | #define SI5351_STATUS_LOS (1<<4) | ||
48 | #define SI5351_OUTPUT_ENABLE_CTRL 3 | ||
49 | #define SI5351_OEB_PIN_ENABLE_CTRL 9 | ||
50 | #define SI5351_PLL_INPUT_SOURCE 15 | ||
51 | #define SI5351_CLKIN_DIV_MASK (3<<6) | ||
52 | #define SI5351_CLKIN_DIV_1 (0<<6) | ||
53 | #define SI5351_CLKIN_DIV_2 (1<<6) | ||
54 | #define SI5351_CLKIN_DIV_4 (2<<6) | ||
55 | #define SI5351_CLKIN_DIV_8 (3<<6) | ||
56 | #define SI5351_PLLB_SOURCE (1<<3) | ||
57 | #define SI5351_PLLA_SOURCE (1<<2) | ||
58 | |||
59 | #define SI5351_CLK0_CTRL 16 | ||
60 | #define SI5351_CLK1_CTRL 17 | ||
61 | #define SI5351_CLK2_CTRL 18 | ||
62 | #define SI5351_CLK3_CTRL 19 | ||
63 | #define SI5351_CLK4_CTRL 20 | ||
64 | #define SI5351_CLK5_CTRL 21 | ||
65 | #define SI5351_CLK6_CTRL 22 | ||
66 | #define SI5351_CLK7_CTRL 23 | ||
67 | #define SI5351_CLK_POWERDOWN (1<<7) | ||
68 | #define SI5351_CLK_INTEGER_MODE (1<<6) | ||
69 | #define SI5351_CLK_PLL_SELECT (1<<5) | ||
70 | #define SI5351_CLK_INVERT (1<<4) | ||
71 | #define SI5351_CLK_INPUT_MASK (3<<2) | ||
72 | #define SI5351_CLK_INPUT_XTAL (0<<2) | ||
73 | #define SI5351_CLK_INPUT_CLKIN (1<<2) | ||
74 | #define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2) | ||
75 | #define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2) | ||
76 | #define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0) | ||
77 | #define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0) | ||
78 | #define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0) | ||
79 | #define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0) | ||
80 | #define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0) | ||
81 | |||
82 | #define SI5351_CLK3_0_DISABLE_STATE 24 | ||
83 | #define SI5351_CLK7_4_DISABLE_STATE 25 | ||
84 | #define SI5351_CLK_DISABLE_STATE_LOW 0 | ||
85 | #define SI5351_CLK_DISABLE_STATE_HIGH 1 | ||
86 | #define SI5351_CLK_DISABLE_STATE_FLOAT 2 | ||
87 | #define SI5351_CLK_DISABLE_STATE_NEVER 3 | ||
88 | |||
89 | #define SI5351_PARAMETERS_LENGTH 8 | ||
90 | #define SI5351_PLLA_PARAMETERS 26 | ||
91 | #define SI5351_PLLB_PARAMETERS 34 | ||
92 | #define SI5351_CLK0_PARAMETERS 42 | ||
93 | #define SI5351_CLK1_PARAMETERS 50 | ||
94 | #define SI5351_CLK2_PARAMETERS 58 | ||
95 | #define SI5351_CLK3_PARAMETERS 66 | ||
96 | #define SI5351_CLK4_PARAMETERS 74 | ||
97 | #define SI5351_CLK5_PARAMETERS 82 | ||
98 | #define SI5351_CLK6_PARAMETERS 90 | ||
99 | #define SI5351_CLK7_PARAMETERS 91 | ||
100 | #define SI5351_CLK6_7_OUTPUT_DIVIDER 92 | ||
101 | #define SI5351_OUTPUT_CLK_DIV_MASK (7 << 4) | ||
102 | #define SI5351_OUTPUT_CLK6_DIV_MASK (7 << 0) | ||
103 | #define SI5351_OUTPUT_CLK_DIV_SHIFT 4 | ||
104 | #define SI5351_OUTPUT_CLK_DIV6_SHIFT 0 | ||
105 | #define SI5351_OUTPUT_CLK_DIV_1 0 | ||
106 | #define SI5351_OUTPUT_CLK_DIV_2 1 | ||
107 | #define SI5351_OUTPUT_CLK_DIV_4 2 | ||
108 | #define SI5351_OUTPUT_CLK_DIV_8 3 | ||
109 | #define SI5351_OUTPUT_CLK_DIV_16 4 | ||
110 | #define SI5351_OUTPUT_CLK_DIV_32 5 | ||
111 | #define SI5351_OUTPUT_CLK_DIV_64 6 | ||
112 | #define SI5351_OUTPUT_CLK_DIV_128 7 | ||
113 | #define SI5351_OUTPUT_CLK_DIVBY4 (3<<2) | ||
114 | |||
115 | #define SI5351_SSC_PARAM0 149 | ||
116 | #define SI5351_SSC_PARAM1 150 | ||
117 | #define SI5351_SSC_PARAM2 151 | ||
118 | #define SI5351_SSC_PARAM3 152 | ||
119 | #define SI5351_SSC_PARAM4 153 | ||
120 | #define SI5351_SSC_PARAM5 154 | ||
121 | #define SI5351_SSC_PARAM6 155 | ||
122 | #define SI5351_SSC_PARAM7 156 | ||
123 | #define SI5351_SSC_PARAM8 157 | ||
124 | #define SI5351_SSC_PARAM9 158 | ||
125 | #define SI5351_SSC_PARAM10 159 | ||
126 | #define SI5351_SSC_PARAM11 160 | ||
127 | #define SI5351_SSC_PARAM12 161 | ||
128 | |||
129 | #define SI5351_VXCO_PARAMETERS_LOW 162 | ||
130 | #define SI5351_VXCO_PARAMETERS_MID 163 | ||
131 | #define SI5351_VXCO_PARAMETERS_HIGH 164 | ||
132 | |||
133 | #define SI5351_CLK0_PHASE_OFFSET 165 | ||
134 | #define SI5351_CLK1_PHASE_OFFSET 166 | ||
135 | #define SI5351_CLK2_PHASE_OFFSET 167 | ||
136 | #define SI5351_CLK3_PHASE_OFFSET 168 | ||
137 | #define SI5351_CLK4_PHASE_OFFSET 169 | ||
138 | #define SI5351_CLK5_PHASE_OFFSET 170 | ||
139 | |||
140 | #define SI5351_PLL_RESET 177 | ||
141 | #define SI5351_PLL_RESET_B (1<<7) | ||
142 | #define SI5351_PLL_RESET_A (1<<5) | ||
143 | |||
144 | #define SI5351_CRYSTAL_LOAD 183 | ||
145 | #define SI5351_CRYSTAL_LOAD_MASK (3<<6) | ||
146 | #define SI5351_CRYSTAL_LOAD_6PF (1<<6) | ||
147 | #define SI5351_CRYSTAL_LOAD_8PF (2<<6) | ||
148 | #define SI5351_CRYSTAL_LOAD_10PF (3<<6) | ||
149 | |||
150 | #define SI5351_FANOUT_ENABLE 187 | ||
151 | #define SI5351_CLKIN_ENABLE (1<<7) | ||
152 | #define SI5351_XTAL_ENABLE (1<<6) | ||
153 | #define SI5351_MULTISYNTH_ENABLE (1<<4) | ||
154 | |||
155 | #endif | ||
diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 09c63315e579..debf688afa8e 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c | |||
@@ -488,6 +488,7 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
488 | case PLL_TYPE_WM8750: | 488 | case PLL_TYPE_WM8750: |
489 | wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); | 489 | wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); |
490 | pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); | 490 | pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); |
491 | break; | ||
491 | default: | 492 | default: |
492 | pr_err("%s: invalid pll type\n", __func__); | 493 | pr_err("%s: invalid pll type\n", __func__); |
493 | return 0; | 494 | return 0; |
@@ -523,6 +524,7 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, | |||
523 | case PLL_TYPE_WM8750: | 524 | case PLL_TYPE_WM8750: |
524 | wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); | 525 | wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); |
525 | round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); | 526 | round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); |
527 | break; | ||
526 | default: | 528 | default: |
527 | round_rate = 0; | 529 | round_rate = 0; |
528 | } | 530 | } |
diff --git a/drivers/clk/clk-zynq.c b/drivers/clk/clk-zynq.c index b14a25f39255..32062977f453 100644 --- a/drivers/clk/clk-zynq.c +++ b/drivers/clk/clk-zynq.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/clk-provider.h> | 22 | #include <linux/clk-provider.h> |
23 | #include <linux/clk/zynq.h> | ||
23 | 24 | ||
24 | static void __iomem *slcr_base; | 25 | static void __iomem *slcr_base; |
25 | 26 | ||
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index ed87b2405806..934cfd18f72d 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -19,14 +19,77 @@ | |||
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/sched.h> | ||
22 | 23 | ||
23 | static DEFINE_SPINLOCK(enable_lock); | 24 | static DEFINE_SPINLOCK(enable_lock); |
24 | static DEFINE_MUTEX(prepare_lock); | 25 | static DEFINE_MUTEX(prepare_lock); |
25 | 26 | ||
27 | static struct task_struct *prepare_owner; | ||
28 | static struct task_struct *enable_owner; | ||
29 | |||
30 | static int prepare_refcnt; | ||
31 | static int enable_refcnt; | ||
32 | |||
26 | static HLIST_HEAD(clk_root_list); | 33 | static HLIST_HEAD(clk_root_list); |
27 | static HLIST_HEAD(clk_orphan_list); | 34 | static HLIST_HEAD(clk_orphan_list); |
28 | static LIST_HEAD(clk_notifier_list); | 35 | static LIST_HEAD(clk_notifier_list); |
29 | 36 | ||
37 | /*** locking ***/ | ||
38 | static void clk_prepare_lock(void) | ||
39 | { | ||
40 | if (!mutex_trylock(&prepare_lock)) { | ||
41 | if (prepare_owner == current) { | ||
42 | prepare_refcnt++; | ||
43 | return; | ||
44 | } | ||
45 | mutex_lock(&prepare_lock); | ||
46 | } | ||
47 | WARN_ON_ONCE(prepare_owner != NULL); | ||
48 | WARN_ON_ONCE(prepare_refcnt != 0); | ||
49 | prepare_owner = current; | ||
50 | prepare_refcnt = 1; | ||
51 | } | ||
52 | |||
53 | static void clk_prepare_unlock(void) | ||
54 | { | ||
55 | WARN_ON_ONCE(prepare_owner != current); | ||
56 | WARN_ON_ONCE(prepare_refcnt == 0); | ||
57 | |||
58 | if (--prepare_refcnt) | ||
59 | return; | ||
60 | prepare_owner = NULL; | ||
61 | mutex_unlock(&prepare_lock); | ||
62 | } | ||
63 | |||
64 | static unsigned long clk_enable_lock(void) | ||
65 | { | ||
66 | unsigned long flags; | ||
67 | |||
68 | if (!spin_trylock_irqsave(&enable_lock, flags)) { | ||
69 | if (enable_owner == current) { | ||
70 | enable_refcnt++; | ||
71 | return flags; | ||
72 | } | ||
73 | spin_lock_irqsave(&enable_lock, flags); | ||
74 | } | ||
75 | WARN_ON_ONCE(enable_owner != NULL); | ||
76 | WARN_ON_ONCE(enable_refcnt != 0); | ||
77 | enable_owner = current; | ||
78 | enable_refcnt = 1; | ||
79 | return flags; | ||
80 | } | ||
81 | |||
82 | static void clk_enable_unlock(unsigned long flags) | ||
83 | { | ||
84 | WARN_ON_ONCE(enable_owner != current); | ||
85 | WARN_ON_ONCE(enable_refcnt == 0); | ||
86 | |||
87 | if (--enable_refcnt) | ||
88 | return; | ||
89 | enable_owner = NULL; | ||
90 | spin_unlock_irqrestore(&enable_lock, flags); | ||
91 | } | ||
92 | |||
30 | /*** debugfs support ***/ | 93 | /*** debugfs support ***/ |
31 | 94 | ||
32 | #ifdef CONFIG_COMMON_CLK_DEBUG | 95 | #ifdef CONFIG_COMMON_CLK_DEBUG |
@@ -69,7 +132,7 @@ static int clk_summary_show(struct seq_file *s, void *data) | |||
69 | seq_printf(s, " clock enable_cnt prepare_cnt rate\n"); | 132 | seq_printf(s, " clock enable_cnt prepare_cnt rate\n"); |
70 | seq_printf(s, "---------------------------------------------------------------------\n"); | 133 | seq_printf(s, "---------------------------------------------------------------------\n"); |
71 | 134 | ||
72 | mutex_lock(&prepare_lock); | 135 | clk_prepare_lock(); |
73 | 136 | ||
74 | hlist_for_each_entry(c, &clk_root_list, child_node) | 137 | hlist_for_each_entry(c, &clk_root_list, child_node) |
75 | clk_summary_show_subtree(s, c, 0); | 138 | clk_summary_show_subtree(s, c, 0); |
@@ -77,7 +140,7 @@ static int clk_summary_show(struct seq_file *s, void *data) | |||
77 | hlist_for_each_entry(c, &clk_orphan_list, child_node) | 140 | hlist_for_each_entry(c, &clk_orphan_list, child_node) |
78 | clk_summary_show_subtree(s, c, 0); | 141 | clk_summary_show_subtree(s, c, 0); |
79 | 142 | ||
80 | mutex_unlock(&prepare_lock); | 143 | clk_prepare_unlock(); |
81 | 144 | ||
82 | return 0; | 145 | return 0; |
83 | } | 146 | } |
@@ -130,7 +193,7 @@ static int clk_dump(struct seq_file *s, void *data) | |||
130 | 193 | ||
131 | seq_printf(s, "{"); | 194 | seq_printf(s, "{"); |
132 | 195 | ||
133 | mutex_lock(&prepare_lock); | 196 | clk_prepare_lock(); |
134 | 197 | ||
135 | hlist_for_each_entry(c, &clk_root_list, child_node) { | 198 | hlist_for_each_entry(c, &clk_root_list, child_node) { |
136 | if (!first_node) | 199 | if (!first_node) |
@@ -144,7 +207,7 @@ static int clk_dump(struct seq_file *s, void *data) | |||
144 | clk_dump_subtree(s, c, 0); | 207 | clk_dump_subtree(s, c, 0); |
145 | } | 208 | } |
146 | 209 | ||
147 | mutex_unlock(&prepare_lock); | 210 | clk_prepare_unlock(); |
148 | 211 | ||
149 | seq_printf(s, "}"); | 212 | seq_printf(s, "}"); |
150 | return 0; | 213 | return 0; |
@@ -280,6 +343,39 @@ out: | |||
280 | } | 343 | } |
281 | 344 | ||
282 | /** | 345 | /** |
346 | * clk_debug_reparent - reparent clk node in the debugfs clk tree | ||
347 | * @clk: the clk being reparented | ||
348 | * @new_parent: the new clk parent, may be NULL | ||
349 | * | ||
350 | * Rename clk entry in the debugfs clk tree if debugfs has been | ||
351 | * initialized. Otherwise it bails out early since the debugfs clk tree | ||
352 | * will be created lazily by clk_debug_init as part of a late_initcall. | ||
353 | * | ||
354 | * Caller must hold prepare_lock. | ||
355 | */ | ||
356 | static void clk_debug_reparent(struct clk *clk, struct clk *new_parent) | ||
357 | { | ||
358 | struct dentry *d; | ||
359 | struct dentry *new_parent_d; | ||
360 | |||
361 | if (!inited) | ||
362 | return; | ||
363 | |||
364 | if (new_parent) | ||
365 | new_parent_d = new_parent->dentry; | ||
366 | else | ||
367 | new_parent_d = orphandir; | ||
368 | |||
369 | d = debugfs_rename(clk->dentry->d_parent, clk->dentry, | ||
370 | new_parent_d, clk->name); | ||
371 | if (d) | ||
372 | clk->dentry = d; | ||
373 | else | ||
374 | pr_debug("%s: failed to rename debugfs entry for %s\n", | ||
375 | __func__, clk->name); | ||
376 | } | ||
377 | |||
378 | /** | ||
283 | * clk_debug_init - lazily create the debugfs clk tree visualization | 379 | * clk_debug_init - lazily create the debugfs clk tree visualization |
284 | * | 380 | * |
285 | * clks are often initialized very early during boot before memory can | 381 | * clks are often initialized very early during boot before memory can |
@@ -316,7 +412,7 @@ static int __init clk_debug_init(void) | |||
316 | if (!orphandir) | 412 | if (!orphandir) |
317 | return -ENOMEM; | 413 | return -ENOMEM; |
318 | 414 | ||
319 | mutex_lock(&prepare_lock); | 415 | clk_prepare_lock(); |
320 | 416 | ||
321 | hlist_for_each_entry(clk, &clk_root_list, child_node) | 417 | hlist_for_each_entry(clk, &clk_root_list, child_node) |
322 | clk_debug_create_subtree(clk, rootdir); | 418 | clk_debug_create_subtree(clk, rootdir); |
@@ -326,16 +422,45 @@ static int __init clk_debug_init(void) | |||
326 | 422 | ||
327 | inited = 1; | 423 | inited = 1; |
328 | 424 | ||
329 | mutex_unlock(&prepare_lock); | 425 | clk_prepare_unlock(); |
330 | 426 | ||
331 | return 0; | 427 | return 0; |
332 | } | 428 | } |
333 | late_initcall(clk_debug_init); | 429 | late_initcall(clk_debug_init); |
334 | #else | 430 | #else |
335 | static inline int clk_debug_register(struct clk *clk) { return 0; } | 431 | static inline int clk_debug_register(struct clk *clk) { return 0; } |
432 | static inline void clk_debug_reparent(struct clk *clk, struct clk *new_parent) | ||
433 | { | ||
434 | } | ||
336 | #endif | 435 | #endif |
337 | 436 | ||
338 | /* caller must hold prepare_lock */ | 437 | /* caller must hold prepare_lock */ |
438 | static void clk_unprepare_unused_subtree(struct clk *clk) | ||
439 | { | ||
440 | struct clk *child; | ||
441 | |||
442 | if (!clk) | ||
443 | return; | ||
444 | |||
445 | hlist_for_each_entry(child, &clk->children, child_node) | ||
446 | clk_unprepare_unused_subtree(child); | ||
447 | |||
448 | if (clk->prepare_count) | ||
449 | return; | ||
450 | |||
451 | if (clk->flags & CLK_IGNORE_UNUSED) | ||
452 | return; | ||
453 | |||
454 | if (__clk_is_prepared(clk)) { | ||
455 | if (clk->ops->unprepare_unused) | ||
456 | clk->ops->unprepare_unused(clk->hw); | ||
457 | else if (clk->ops->unprepare) | ||
458 | clk->ops->unprepare(clk->hw); | ||
459 | } | ||
460 | } | ||
461 | EXPORT_SYMBOL_GPL(__clk_get_flags); | ||
462 | |||
463 | /* caller must hold prepare_lock */ | ||
339 | static void clk_disable_unused_subtree(struct clk *clk) | 464 | static void clk_disable_unused_subtree(struct clk *clk) |
340 | { | 465 | { |
341 | struct clk *child; | 466 | struct clk *child; |
@@ -347,7 +472,7 @@ static void clk_disable_unused_subtree(struct clk *clk) | |||
347 | hlist_for_each_entry(child, &clk->children, child_node) | 472 | hlist_for_each_entry(child, &clk->children, child_node) |
348 | clk_disable_unused_subtree(child); | 473 | clk_disable_unused_subtree(child); |
349 | 474 | ||
350 | spin_lock_irqsave(&enable_lock, flags); | 475 | flags = clk_enable_lock(); |
351 | 476 | ||
352 | if (clk->enable_count) | 477 | if (clk->enable_count) |
353 | goto unlock_out; | 478 | goto unlock_out; |
@@ -368,17 +493,30 @@ static void clk_disable_unused_subtree(struct clk *clk) | |||
368 | } | 493 | } |
369 | 494 | ||
370 | unlock_out: | 495 | unlock_out: |
371 | spin_unlock_irqrestore(&enable_lock, flags); | 496 | clk_enable_unlock(flags); |
372 | 497 | ||
373 | out: | 498 | out: |
374 | return; | 499 | return; |
375 | } | 500 | } |
376 | 501 | ||
502 | static bool clk_ignore_unused; | ||
503 | static int __init clk_ignore_unused_setup(char *__unused) | ||
504 | { | ||
505 | clk_ignore_unused = true; | ||
506 | return 1; | ||
507 | } | ||
508 | __setup("clk_ignore_unused", clk_ignore_unused_setup); | ||
509 | |||
377 | static int clk_disable_unused(void) | 510 | static int clk_disable_unused(void) |
378 | { | 511 | { |
379 | struct clk *clk; | 512 | struct clk *clk; |
380 | 513 | ||
381 | mutex_lock(&prepare_lock); | 514 | if (clk_ignore_unused) { |
515 | pr_warn("clk: Not disabling unused clocks\n"); | ||
516 | return 0; | ||
517 | } | ||
518 | |||
519 | clk_prepare_lock(); | ||
382 | 520 | ||
383 | hlist_for_each_entry(clk, &clk_root_list, child_node) | 521 | hlist_for_each_entry(clk, &clk_root_list, child_node) |
384 | clk_disable_unused_subtree(clk); | 522 | clk_disable_unused_subtree(clk); |
@@ -386,7 +524,13 @@ static int clk_disable_unused(void) | |||
386 | hlist_for_each_entry(clk, &clk_orphan_list, child_node) | 524 | hlist_for_each_entry(clk, &clk_orphan_list, child_node) |
387 | clk_disable_unused_subtree(clk); | 525 | clk_disable_unused_subtree(clk); |
388 | 526 | ||
389 | mutex_unlock(&prepare_lock); | 527 | hlist_for_each_entry(clk, &clk_root_list, child_node) |
528 | clk_unprepare_unused_subtree(clk); | ||
529 | |||
530 | hlist_for_each_entry(clk, &clk_orphan_list, child_node) | ||
531 | clk_unprepare_unused_subtree(clk); | ||
532 | |||
533 | clk_prepare_unlock(); | ||
390 | 534 | ||
391 | return 0; | 535 | return 0; |
392 | } | 536 | } |
@@ -451,6 +595,27 @@ unsigned long __clk_get_flags(struct clk *clk) | |||
451 | return !clk ? 0 : clk->flags; | 595 | return !clk ? 0 : clk->flags; |
452 | } | 596 | } |
453 | 597 | ||
598 | bool __clk_is_prepared(struct clk *clk) | ||
599 | { | ||
600 | int ret; | ||
601 | |||
602 | if (!clk) | ||
603 | return false; | ||
604 | |||
605 | /* | ||
606 | * .is_prepared is optional for clocks that can prepare | ||
607 | * fall back to software usage counter if it is missing | ||
608 | */ | ||
609 | if (!clk->ops->is_prepared) { | ||
610 | ret = clk->prepare_count ? 1 : 0; | ||
611 | goto out; | ||
612 | } | ||
613 | |||
614 | ret = clk->ops->is_prepared(clk->hw); | ||
615 | out: | ||
616 | return !!ret; | ||
617 | } | ||
618 | |||
454 | bool __clk_is_enabled(struct clk *clk) | 619 | bool __clk_is_enabled(struct clk *clk) |
455 | { | 620 | { |
456 | int ret; | 621 | int ret; |
@@ -548,9 +713,9 @@ void __clk_unprepare(struct clk *clk) | |||
548 | */ | 713 | */ |
549 | void clk_unprepare(struct clk *clk) | 714 | void clk_unprepare(struct clk *clk) |
550 | { | 715 | { |
551 | mutex_lock(&prepare_lock); | 716 | clk_prepare_lock(); |
552 | __clk_unprepare(clk); | 717 | __clk_unprepare(clk); |
553 | mutex_unlock(&prepare_lock); | 718 | clk_prepare_unlock(); |
554 | } | 719 | } |
555 | EXPORT_SYMBOL_GPL(clk_unprepare); | 720 | EXPORT_SYMBOL_GPL(clk_unprepare); |
556 | 721 | ||
@@ -596,9 +761,9 @@ int clk_prepare(struct clk *clk) | |||
596 | { | 761 | { |
597 | int ret; | 762 | int ret; |
598 | 763 | ||
599 | mutex_lock(&prepare_lock); | 764 | clk_prepare_lock(); |
600 | ret = __clk_prepare(clk); | 765 | ret = __clk_prepare(clk); |
601 | mutex_unlock(&prepare_lock); | 766 | clk_prepare_unlock(); |
602 | 767 | ||
603 | return ret; | 768 | return ret; |
604 | } | 769 | } |
@@ -640,9 +805,9 @@ void clk_disable(struct clk *clk) | |||
640 | { | 805 | { |
641 | unsigned long flags; | 806 | unsigned long flags; |
642 | 807 | ||
643 | spin_lock_irqsave(&enable_lock, flags); | 808 | flags = clk_enable_lock(); |
644 | __clk_disable(clk); | 809 | __clk_disable(clk); |
645 | spin_unlock_irqrestore(&enable_lock, flags); | 810 | clk_enable_unlock(flags); |
646 | } | 811 | } |
647 | EXPORT_SYMBOL_GPL(clk_disable); | 812 | EXPORT_SYMBOL_GPL(clk_disable); |
648 | 813 | ||
@@ -693,9 +858,9 @@ int clk_enable(struct clk *clk) | |||
693 | unsigned long flags; | 858 | unsigned long flags; |
694 | int ret; | 859 | int ret; |
695 | 860 | ||
696 | spin_lock_irqsave(&enable_lock, flags); | 861 | flags = clk_enable_lock(); |
697 | ret = __clk_enable(clk); | 862 | ret = __clk_enable(clk); |
698 | spin_unlock_irqrestore(&enable_lock, flags); | 863 | clk_enable_unlock(flags); |
699 | 864 | ||
700 | return ret; | 865 | return ret; |
701 | } | 866 | } |
@@ -740,9 +905,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
740 | { | 905 | { |
741 | unsigned long ret; | 906 | unsigned long ret; |
742 | 907 | ||
743 | mutex_lock(&prepare_lock); | 908 | clk_prepare_lock(); |
744 | ret = __clk_round_rate(clk, rate); | 909 | ret = __clk_round_rate(clk, rate); |
745 | mutex_unlock(&prepare_lock); | 910 | clk_prepare_unlock(); |
746 | 911 | ||
747 | return ret; | 912 | return ret; |
748 | } | 913 | } |
@@ -837,13 +1002,13 @@ unsigned long clk_get_rate(struct clk *clk) | |||
837 | { | 1002 | { |
838 | unsigned long rate; | 1003 | unsigned long rate; |
839 | 1004 | ||
840 | mutex_lock(&prepare_lock); | 1005 | clk_prepare_lock(); |
841 | 1006 | ||
842 | if (clk && (clk->flags & CLK_GET_RATE_NOCACHE)) | 1007 | if (clk && (clk->flags & CLK_GET_RATE_NOCACHE)) |
843 | __clk_recalc_rates(clk, 0); | 1008 | __clk_recalc_rates(clk, 0); |
844 | 1009 | ||
845 | rate = __clk_get_rate(clk); | 1010 | rate = __clk_get_rate(clk); |
846 | mutex_unlock(&prepare_lock); | 1011 | clk_prepare_unlock(); |
847 | 1012 | ||
848 | return rate; | 1013 | return rate; |
849 | } | 1014 | } |
@@ -876,16 +1041,16 @@ static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate) | |||
876 | else | 1041 | else |
877 | new_rate = parent_rate; | 1042 | new_rate = parent_rate; |
878 | 1043 | ||
879 | /* abort the rate change if a driver returns NOTIFY_BAD */ | 1044 | /* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */ |
880 | if (clk->notifier_count) | 1045 | if (clk->notifier_count) |
881 | ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); | 1046 | ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); |
882 | 1047 | ||
883 | if (ret == NOTIFY_BAD) | 1048 | if (ret & NOTIFY_STOP_MASK) |
884 | goto out; | 1049 | goto out; |
885 | 1050 | ||
886 | hlist_for_each_entry(child, &clk->children, child_node) { | 1051 | hlist_for_each_entry(child, &clk->children, child_node) { |
887 | ret = __clk_speculate_rates(child, new_rate); | 1052 | ret = __clk_speculate_rates(child, new_rate); |
888 | if (ret == NOTIFY_BAD) | 1053 | if (ret & NOTIFY_STOP_MASK) |
889 | break; | 1054 | break; |
890 | } | 1055 | } |
891 | 1056 | ||
@@ -974,11 +1139,11 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even | |||
974 | int ret = NOTIFY_DONE; | 1139 | int ret = NOTIFY_DONE; |
975 | 1140 | ||
976 | if (clk->rate == clk->new_rate) | 1141 | if (clk->rate == clk->new_rate) |
977 | return 0; | 1142 | return NULL; |
978 | 1143 | ||
979 | if (clk->notifier_count) { | 1144 | if (clk->notifier_count) { |
980 | ret = __clk_notify(clk, event, clk->rate, clk->new_rate); | 1145 | ret = __clk_notify(clk, event, clk->rate, clk->new_rate); |
981 | if (ret == NOTIFY_BAD) | 1146 | if (ret & NOTIFY_STOP_MASK) |
982 | fail_clk = clk; | 1147 | fail_clk = clk; |
983 | } | 1148 | } |
984 | 1149 | ||
@@ -1048,7 +1213,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
1048 | int ret = 0; | 1213 | int ret = 0; |
1049 | 1214 | ||
1050 | /* prevent racing with updates to the clock topology */ | 1215 | /* prevent racing with updates to the clock topology */ |
1051 | mutex_lock(&prepare_lock); | 1216 | clk_prepare_lock(); |
1052 | 1217 | ||
1053 | /* bail early if nothing to do */ | 1218 | /* bail early if nothing to do */ |
1054 | if (rate == clk->rate) | 1219 | if (rate == clk->rate) |
@@ -1080,7 +1245,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
1080 | clk_change_rate(top); | 1245 | clk_change_rate(top); |
1081 | 1246 | ||
1082 | out: | 1247 | out: |
1083 | mutex_unlock(&prepare_lock); | 1248 | clk_prepare_unlock(); |
1084 | 1249 | ||
1085 | return ret; | 1250 | return ret; |
1086 | } | 1251 | } |
@@ -1096,9 +1261,9 @@ struct clk *clk_get_parent(struct clk *clk) | |||
1096 | { | 1261 | { |
1097 | struct clk *parent; | 1262 | struct clk *parent; |
1098 | 1263 | ||
1099 | mutex_lock(&prepare_lock); | 1264 | clk_prepare_lock(); |
1100 | parent = __clk_get_parent(clk); | 1265 | parent = __clk_get_parent(clk); |
1101 | mutex_unlock(&prepare_lock); | 1266 | clk_prepare_unlock(); |
1102 | 1267 | ||
1103 | return parent; | 1268 | return parent; |
1104 | } | 1269 | } |
@@ -1162,16 +1327,8 @@ out: | |||
1162 | return ret; | 1327 | return ret; |
1163 | } | 1328 | } |
1164 | 1329 | ||
1165 | void __clk_reparent(struct clk *clk, struct clk *new_parent) | 1330 | static void clk_reparent(struct clk *clk, struct clk *new_parent) |
1166 | { | 1331 | { |
1167 | #ifdef CONFIG_COMMON_CLK_DEBUG | ||
1168 | struct dentry *d; | ||
1169 | struct dentry *new_parent_d; | ||
1170 | #endif | ||
1171 | |||
1172 | if (!clk || !new_parent) | ||
1173 | return; | ||
1174 | |||
1175 | hlist_del(&clk->child_node); | 1332 | hlist_del(&clk->child_node); |
1176 | 1333 | ||
1177 | if (new_parent) | 1334 | if (new_parent) |
@@ -1179,39 +1336,20 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent) | |||
1179 | else | 1336 | else |
1180 | hlist_add_head(&clk->child_node, &clk_orphan_list); | 1337 | hlist_add_head(&clk->child_node, &clk_orphan_list); |
1181 | 1338 | ||
1182 | #ifdef CONFIG_COMMON_CLK_DEBUG | ||
1183 | if (!inited) | ||
1184 | goto out; | ||
1185 | |||
1186 | if (new_parent) | ||
1187 | new_parent_d = new_parent->dentry; | ||
1188 | else | ||
1189 | new_parent_d = orphandir; | ||
1190 | |||
1191 | d = debugfs_rename(clk->dentry->d_parent, clk->dentry, | ||
1192 | new_parent_d, clk->name); | ||
1193 | if (d) | ||
1194 | clk->dentry = d; | ||
1195 | else | ||
1196 | pr_debug("%s: failed to rename debugfs entry for %s\n", | ||
1197 | __func__, clk->name); | ||
1198 | out: | ||
1199 | #endif | ||
1200 | |||
1201 | clk->parent = new_parent; | 1339 | clk->parent = new_parent; |
1340 | } | ||
1202 | 1341 | ||
1342 | void __clk_reparent(struct clk *clk, struct clk *new_parent) | ||
1343 | { | ||
1344 | clk_reparent(clk, new_parent); | ||
1345 | clk_debug_reparent(clk, new_parent); | ||
1203 | __clk_recalc_rates(clk, POST_RATE_CHANGE); | 1346 | __clk_recalc_rates(clk, POST_RATE_CHANGE); |
1204 | } | 1347 | } |
1205 | 1348 | ||
1206 | static int __clk_set_parent(struct clk *clk, struct clk *parent) | 1349 | static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent) |
1207 | { | 1350 | { |
1208 | struct clk *old_parent; | ||
1209 | unsigned long flags; | ||
1210 | int ret = -EINVAL; | ||
1211 | u8 i; | 1351 | u8 i; |
1212 | 1352 | ||
1213 | old_parent = clk->parent; | ||
1214 | |||
1215 | if (!clk->parents) | 1353 | if (!clk->parents) |
1216 | clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), | 1354 | clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), |
1217 | GFP_KERNEL); | 1355 | GFP_KERNEL); |
@@ -1231,36 +1369,79 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) | |||
1231 | } | 1369 | } |
1232 | } | 1370 | } |
1233 | 1371 | ||
1234 | if (i == clk->num_parents) { | 1372 | return i; |
1235 | pr_debug("%s: clock %s is not a possible parent of clock %s\n", | 1373 | } |
1236 | __func__, parent->name, clk->name); | ||
1237 | goto out; | ||
1238 | } | ||
1239 | 1374 | ||
1240 | /* migrate prepare and enable */ | 1375 | static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index) |
1376 | { | ||
1377 | unsigned long flags; | ||
1378 | int ret = 0; | ||
1379 | struct clk *old_parent = clk->parent; | ||
1380 | bool migrated_enable = false; | ||
1381 | |||
1382 | /* migrate prepare */ | ||
1241 | if (clk->prepare_count) | 1383 | if (clk->prepare_count) |
1242 | __clk_prepare(parent); | 1384 | __clk_prepare(parent); |
1243 | 1385 | ||
1244 | /* FIXME replace with clk_is_enabled(clk) someday */ | 1386 | flags = clk_enable_lock(); |
1245 | spin_lock_irqsave(&enable_lock, flags); | 1387 | |
1246 | if (clk->enable_count) | 1388 | /* migrate enable */ |
1389 | if (clk->enable_count) { | ||
1247 | __clk_enable(parent); | 1390 | __clk_enable(parent); |
1248 | spin_unlock_irqrestore(&enable_lock, flags); | 1391 | migrated_enable = true; |
1392 | } | ||
1393 | |||
1394 | /* update the clk tree topology */ | ||
1395 | clk_reparent(clk, parent); | ||
1396 | |||
1397 | clk_enable_unlock(flags); | ||
1249 | 1398 | ||
1250 | /* change clock input source */ | 1399 | /* change clock input source */ |
1251 | ret = clk->ops->set_parent(clk->hw, i); | 1400 | if (parent && clk->ops->set_parent) |
1401 | ret = clk->ops->set_parent(clk->hw, p_index); | ||
1252 | 1402 | ||
1253 | /* clean up old prepare and enable */ | 1403 | if (ret) { |
1254 | spin_lock_irqsave(&enable_lock, flags); | 1404 | /* |
1255 | if (clk->enable_count) | 1405 | * The error handling is tricky due to that we need to release |
1406 | * the spinlock while issuing the .set_parent callback. This | ||
1407 | * means the new parent might have been enabled/disabled in | ||
1408 | * between, which must be considered when doing rollback. | ||
1409 | */ | ||
1410 | flags = clk_enable_lock(); | ||
1411 | |||
1412 | clk_reparent(clk, old_parent); | ||
1413 | |||
1414 | if (migrated_enable && clk->enable_count) { | ||
1415 | __clk_disable(parent); | ||
1416 | } else if (migrated_enable && (clk->enable_count == 0)) { | ||
1417 | __clk_disable(old_parent); | ||
1418 | } else if (!migrated_enable && clk->enable_count) { | ||
1419 | __clk_disable(parent); | ||
1420 | __clk_enable(old_parent); | ||
1421 | } | ||
1422 | |||
1423 | clk_enable_unlock(flags); | ||
1424 | |||
1425 | if (clk->prepare_count) | ||
1426 | __clk_unprepare(parent); | ||
1427 | |||
1428 | return ret; | ||
1429 | } | ||
1430 | |||
1431 | /* clean up enable for old parent if migration was done */ | ||
1432 | if (migrated_enable) { | ||
1433 | flags = clk_enable_lock(); | ||
1256 | __clk_disable(old_parent); | 1434 | __clk_disable(old_parent); |
1257 | spin_unlock_irqrestore(&enable_lock, flags); | 1435 | clk_enable_unlock(flags); |
1436 | } | ||
1258 | 1437 | ||
1438 | /* clean up prepare for old parent if migration was done */ | ||
1259 | if (clk->prepare_count) | 1439 | if (clk->prepare_count) |
1260 | __clk_unprepare(old_parent); | 1440 | __clk_unprepare(old_parent); |
1261 | 1441 | ||
1262 | out: | 1442 | /* update debugfs with new clk tree topology */ |
1263 | return ret; | 1443 | clk_debug_reparent(clk, parent); |
1444 | return 0; | ||
1264 | } | 1445 | } |
1265 | 1446 | ||
1266 | /** | 1447 | /** |
@@ -1278,44 +1459,59 @@ out: | |||
1278 | int clk_set_parent(struct clk *clk, struct clk *parent) | 1459 | int clk_set_parent(struct clk *clk, struct clk *parent) |
1279 | { | 1460 | { |
1280 | int ret = 0; | 1461 | int ret = 0; |
1462 | u8 p_index = 0; | ||
1463 | unsigned long p_rate = 0; | ||
1281 | 1464 | ||
1282 | if (!clk || !clk->ops) | 1465 | if (!clk || !clk->ops) |
1283 | return -EINVAL; | 1466 | return -EINVAL; |
1284 | 1467 | ||
1285 | if (!clk->ops->set_parent) | 1468 | /* verify ops for for multi-parent clks */ |
1469 | if ((clk->num_parents > 1) && (!clk->ops->set_parent)) | ||
1286 | return -ENOSYS; | 1470 | return -ENOSYS; |
1287 | 1471 | ||
1288 | /* prevent racing with updates to the clock topology */ | 1472 | /* prevent racing with updates to the clock topology */ |
1289 | mutex_lock(&prepare_lock); | 1473 | clk_prepare_lock(); |
1290 | 1474 | ||
1291 | if (clk->parent == parent) | 1475 | if (clk->parent == parent) |
1292 | goto out; | 1476 | goto out; |
1293 | 1477 | ||
1478 | /* check that we are allowed to re-parent if the clock is in use */ | ||
1479 | if ((clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) { | ||
1480 | ret = -EBUSY; | ||
1481 | goto out; | ||
1482 | } | ||
1483 | |||
1484 | /* try finding the new parent index */ | ||
1485 | if (parent) { | ||
1486 | p_index = clk_fetch_parent_index(clk, parent); | ||
1487 | p_rate = parent->rate; | ||
1488 | if (p_index == clk->num_parents) { | ||
1489 | pr_debug("%s: clk %s can not be parent of clk %s\n", | ||
1490 | __func__, parent->name, clk->name); | ||
1491 | ret = -EINVAL; | ||
1492 | goto out; | ||
1493 | } | ||
1494 | } | ||
1495 | |||
1294 | /* propagate PRE_RATE_CHANGE notifications */ | 1496 | /* propagate PRE_RATE_CHANGE notifications */ |
1295 | if (clk->notifier_count) | 1497 | if (clk->notifier_count) |
1296 | ret = __clk_speculate_rates(clk, parent->rate); | 1498 | ret = __clk_speculate_rates(clk, p_rate); |
1297 | 1499 | ||
1298 | /* abort if a driver objects */ | 1500 | /* abort if a driver objects */ |
1299 | if (ret == NOTIFY_STOP) | 1501 | if (ret & NOTIFY_STOP_MASK) |
1300 | goto out; | 1502 | goto out; |
1301 | 1503 | ||
1302 | /* only re-parent if the clock is not in use */ | 1504 | /* do the re-parent */ |
1303 | if ((clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) | 1505 | ret = __clk_set_parent(clk, parent, p_index); |
1304 | ret = -EBUSY; | ||
1305 | else | ||
1306 | ret = __clk_set_parent(clk, parent); | ||
1307 | 1506 | ||
1308 | /* propagate ABORT_RATE_CHANGE if .set_parent failed */ | 1507 | /* propagate rate recalculation accordingly */ |
1309 | if (ret) { | 1508 | if (ret) |
1310 | __clk_recalc_rates(clk, ABORT_RATE_CHANGE); | 1509 | __clk_recalc_rates(clk, ABORT_RATE_CHANGE); |
1311 | goto out; | 1510 | else |
1312 | } | 1511 | __clk_recalc_rates(clk, POST_RATE_CHANGE); |
1313 | |||
1314 | /* propagate rate recalculation downstream */ | ||
1315 | __clk_reparent(clk, parent); | ||
1316 | 1512 | ||
1317 | out: | 1513 | out: |
1318 | mutex_unlock(&prepare_lock); | 1514 | clk_prepare_unlock(); |
1319 | 1515 | ||
1320 | return ret; | 1516 | return ret; |
1321 | } | 1517 | } |
@@ -1338,7 +1534,7 @@ int __clk_init(struct device *dev, struct clk *clk) | |||
1338 | if (!clk) | 1534 | if (!clk) |
1339 | return -EINVAL; | 1535 | return -EINVAL; |
1340 | 1536 | ||
1341 | mutex_lock(&prepare_lock); | 1537 | clk_prepare_lock(); |
1342 | 1538 | ||
1343 | /* check to see if a clock with this name is already registered */ | 1539 | /* check to see if a clock with this name is already registered */ |
1344 | if (__clk_lookup(clk->name)) { | 1540 | if (__clk_lookup(clk->name)) { |
@@ -1462,7 +1658,7 @@ int __clk_init(struct device *dev, struct clk *clk) | |||
1462 | clk_debug_register(clk); | 1658 | clk_debug_register(clk); |
1463 | 1659 | ||
1464 | out: | 1660 | out: |
1465 | mutex_unlock(&prepare_lock); | 1661 | clk_prepare_unlock(); |
1466 | 1662 | ||
1467 | return ret; | 1663 | return ret; |
1468 | } | 1664 | } |
@@ -1696,7 +1892,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb) | |||
1696 | if (!clk || !nb) | 1892 | if (!clk || !nb) |
1697 | return -EINVAL; | 1893 | return -EINVAL; |
1698 | 1894 | ||
1699 | mutex_lock(&prepare_lock); | 1895 | clk_prepare_lock(); |
1700 | 1896 | ||
1701 | /* search the list of notifiers for this clk */ | 1897 | /* search the list of notifiers for this clk */ |
1702 | list_for_each_entry(cn, &clk_notifier_list, node) | 1898 | list_for_each_entry(cn, &clk_notifier_list, node) |
@@ -1720,7 +1916,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb) | |||
1720 | clk->notifier_count++; | 1916 | clk->notifier_count++; |
1721 | 1917 | ||
1722 | out: | 1918 | out: |
1723 | mutex_unlock(&prepare_lock); | 1919 | clk_prepare_unlock(); |
1724 | 1920 | ||
1725 | return ret; | 1921 | return ret; |
1726 | } | 1922 | } |
@@ -1745,7 +1941,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) | |||
1745 | if (!clk || !nb) | 1941 | if (!clk || !nb) |
1746 | return -EINVAL; | 1942 | return -EINVAL; |
1747 | 1943 | ||
1748 | mutex_lock(&prepare_lock); | 1944 | clk_prepare_lock(); |
1749 | 1945 | ||
1750 | list_for_each_entry(cn, &clk_notifier_list, node) | 1946 | list_for_each_entry(cn, &clk_notifier_list, node) |
1751 | if (cn->clk == clk) | 1947 | if (cn->clk == clk) |
@@ -1766,7 +1962,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) | |||
1766 | ret = -ENOENT; | 1962 | ret = -ENOENT; |
1767 | } | 1963 | } |
1768 | 1964 | ||
1769 | mutex_unlock(&prepare_lock); | 1965 | clk_prepare_unlock(); |
1770 | 1966 | ||
1771 | return ret; | 1967 | return ret; |
1772 | } | 1968 | } |
diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c index 69056a7479e8..2628610c1929 100644 --- a/drivers/clk/mvebu/clk-core.c +++ b/drivers/clk/mvebu/clk-core.c | |||
@@ -156,7 +156,7 @@ static u32 __init armada_370_get_cpu_freq(void __iomem *sar) | |||
156 | 156 | ||
157 | cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) & | 157 | cpu_freq_select = ((readl(sar) >> SARL_A370_PCLK_FREQ_OPT) & |
158 | SARL_A370_PCLK_FREQ_OPT_MASK); | 158 | SARL_A370_PCLK_FREQ_OPT_MASK); |
159 | if (cpu_freq_select > ARRAY_SIZE(armada_370_cpu_frequencies)) { | 159 | if (cpu_freq_select >= ARRAY_SIZE(armada_370_cpu_frequencies)) { |
160 | pr_err("CPU freq select unsuported %d\n", cpu_freq_select); | 160 | pr_err("CPU freq select unsuported %d\n", cpu_freq_select); |
161 | cpu_freq = 0; | 161 | cpu_freq = 0; |
162 | } else | 162 | } else |
@@ -278,7 +278,7 @@ static u32 __init armada_xp_get_cpu_freq(void __iomem *sar) | |||
278 | cpu_freq_select |= (((readl(sar+4) >> SARH_AXP_PCLK_FREQ_OPT) & | 278 | cpu_freq_select |= (((readl(sar+4) >> SARH_AXP_PCLK_FREQ_OPT) & |
279 | SARH_AXP_PCLK_FREQ_OPT_MASK) | 279 | SARH_AXP_PCLK_FREQ_OPT_MASK) |
280 | << SARH_AXP_PCLK_FREQ_OPT_SHIFT); | 280 | << SARH_AXP_PCLK_FREQ_OPT_SHIFT); |
281 | if (cpu_freq_select > ARRAY_SIZE(armada_xp_cpu_frequencies)) { | 281 | if (cpu_freq_select >= ARRAY_SIZE(armada_xp_cpu_frequencies)) { |
282 | pr_err("CPU freq select unsuported: %d\n", cpu_freq_select); | 282 | pr_err("CPU freq select unsuported: %d\n", cpu_freq_select); |
283 | cpu_freq = 0; | 283 | cpu_freq = 0; |
284 | } else | 284 | } else |
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 9dd2551a0a41..b0fbc0715491 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include "clk-cpu.h" | ||
20 | 19 | ||
21 | #define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0 | 20 | #define SYS_CTRL_CLK_DIVIDER_CTRL_OFFSET 0x0 |
22 | #define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC | 21 | #define SYS_CTRL_CLK_DIVIDER_VALUE_OFFSET 0xC |
@@ -173,17 +172,5 @@ clks_out: | |||
173 | kfree(cpuclk); | 172 | kfree(cpuclk); |
174 | } | 173 | } |
175 | 174 | ||
176 | static const __initconst struct of_device_id clk_cpu_match[] = { | 175 | CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock", |
177 | { | 176 | of_cpu_clk_setup); |
178 | .compatible = "marvell,armada-xp-cpu-clock", | ||
179 | .data = of_cpu_clk_setup, | ||
180 | }, | ||
181 | { | ||
182 | /* sentinel */ | ||
183 | }, | ||
184 | }; | ||
185 | |||
186 | void __init mvebu_cpu_clk_init(void) | ||
187 | { | ||
188 | of_clk_init(clk_cpu_match); | ||
189 | } | ||
diff --git a/drivers/clk/mvebu/clk-cpu.h b/drivers/clk/mvebu/clk-cpu.h deleted file mode 100644 index 08e2affba4e6..000000000000 --- a/drivers/clk/mvebu/clk-cpu.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Marvell MVEBU CPU clock handling. | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #ifndef __MVEBU_CLK_CPU_H | ||
14 | #define __MVEBU_CLK_CPU_H | ||
15 | |||
16 | #ifdef CONFIG_MVEBU_CLK_CPU | ||
17 | void __init mvebu_cpu_clk_init(void); | ||
18 | #else | ||
19 | static inline void mvebu_cpu_clk_init(void) {} | ||
20 | #endif | ||
21 | |||
22 | #endif | ||
diff --git a/drivers/clk/mvebu/clk.c b/drivers/clk/mvebu/clk.c index 855681b8a9dc..29f10fb3006c 100644 --- a/drivers/clk/mvebu/clk.c +++ b/drivers/clk/mvebu/clk.c | |||
@@ -10,18 +10,14 @@ | |||
10 | * warranty of any kind, whether express or implied. | 10 | * warranty of any kind, whether express or implied. |
11 | */ | 11 | */ |
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/clk.h> | ||
14 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
15 | #include <linux/of_address.h> | ||
16 | #include <linux/clk/mvebu.h> | ||
17 | #include <linux/of.h> | 14 | #include <linux/of.h> |
18 | #include "clk-core.h" | 15 | #include "clk-core.h" |
19 | #include "clk-cpu.h" | ||
20 | #include "clk-gating-ctrl.h" | 16 | #include "clk-gating-ctrl.h" |
21 | 17 | ||
22 | void __init mvebu_clocks_init(void) | 18 | void __init mvebu_clocks_init(void) |
23 | { | 19 | { |
24 | mvebu_core_clk_init(); | 20 | mvebu_core_clk_init(); |
25 | mvebu_gating_clk_init(); | 21 | mvebu_gating_clk_init(); |
26 | mvebu_cpu_clk_init(); | 22 | of_clk_init(NULL); |
27 | } | 23 | } |
diff --git a/drivers/clk/mxs/clk.c b/drivers/clk/mxs/clk.c index b24d56067c80..5301bce8957b 100644 --- a/drivers/clk/mxs/clk.c +++ b/drivers/clk/mxs/clk.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/jiffies.h> | 14 | #include <linux/jiffies.h> |
15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
16 | #include "clk.h" | ||
16 | 17 | ||
17 | DEFINE_SPINLOCK(mxs_lock); | 18 | DEFINE_SPINLOCK(mxs_lock); |
18 | 19 | ||
diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 82abea366b78..35e7e2698e10 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c | |||
@@ -960,47 +960,47 @@ void __init spear1340_clk_init(void) | |||
960 | SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock); | 960 | SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock); |
961 | clk_register_clkdev(clk, NULL, "d0100000.spdif-in"); | 961 | clk_register_clkdev(clk, NULL, "d0100000.spdif-in"); |
962 | 962 | ||
963 | clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0, | 963 | clk = clk_register_gate(NULL, "acp_clk", "ahb_clk", 0, |
964 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, | 964 | SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, |
965 | &_lock); | 965 | &_lock); |
966 | clk_register_clkdev(clk, NULL, "acp_clk"); | 966 | clk_register_clkdev(clk, NULL, "acp_clk"); |
967 | 967 | ||
968 | clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0, | 968 | clk = clk_register_gate(NULL, "plgpio_clk", "ahb_clk", 0, |
969 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, | 969 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, |
970 | &_lock); | 970 | &_lock); |
971 | clk_register_clkdev(clk, NULL, "e2800000.gpio"); | 971 | clk_register_clkdev(clk, NULL, "e2800000.gpio"); |
972 | 972 | ||
973 | clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0, | 973 | clk = clk_register_gate(NULL, "video_dec_clk", "ahb_clk", 0, |
974 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, | 974 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, |
975 | 0, &_lock); | 975 | 0, &_lock); |
976 | clk_register_clkdev(clk, NULL, "video_dec"); | 976 | clk_register_clkdev(clk, NULL, "video_dec"); |
977 | 977 | ||
978 | clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mclk", 0, | 978 | clk = clk_register_gate(NULL, "video_enc_clk", "ahb_clk", 0, |
979 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB, | 979 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB, |
980 | 0, &_lock); | 980 | 0, &_lock); |
981 | clk_register_clkdev(clk, NULL, "video_enc"); | 981 | clk_register_clkdev(clk, NULL, "video_enc"); |
982 | 982 | ||
983 | clk = clk_register_gate(NULL, "video_in_clk", "video_in_mclk", 0, | 983 | clk = clk_register_gate(NULL, "video_in_clk", "ahb_clk", 0, |
984 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0, | 984 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0, |
985 | &_lock); | 985 | &_lock); |
986 | clk_register_clkdev(clk, NULL, "spear_vip"); | 986 | clk_register_clkdev(clk, NULL, "spear_vip"); |
987 | 987 | ||
988 | clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0, | 988 | clk = clk_register_gate(NULL, "cam0_clk", "ahb_clk", 0, |
989 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, | 989 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, |
990 | &_lock); | 990 | &_lock); |
991 | clk_register_clkdev(clk, NULL, "d0200000.cam0"); | 991 | clk_register_clkdev(clk, NULL, "d0200000.cam0"); |
992 | 992 | ||
993 | clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0, | 993 | clk = clk_register_gate(NULL, "cam1_clk", "ahb_clk", 0, |
994 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, | 994 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, |
995 | &_lock); | 995 | &_lock); |
996 | clk_register_clkdev(clk, NULL, "d0300000.cam1"); | 996 | clk_register_clkdev(clk, NULL, "d0300000.cam1"); |
997 | 997 | ||
998 | clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0, | 998 | clk = clk_register_gate(NULL, "cam2_clk", "ahb_clk", 0, |
999 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, | 999 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, |
1000 | &_lock); | 1000 | &_lock); |
1001 | clk_register_clkdev(clk, NULL, "d0400000.cam2"); | 1001 | clk_register_clkdev(clk, NULL, "d0400000.cam2"); |
1002 | 1002 | ||
1003 | clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0, | 1003 | clk = clk_register_gate(NULL, "cam3_clk", "ahb_clk", 0, |
1004 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, | 1004 | SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, |
1005 | &_lock); | 1005 | &_lock); |
1006 | clk_register_clkdev(clk, NULL, "d0500000.cam3"); | 1006 | clk_register_clkdev(clk, NULL, "d0500000.cam3"); |
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile new file mode 100644 index 000000000000..b5bac917612c --- /dev/null +++ b/drivers/clk/sunxi/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for sunxi specific clk | ||
3 | # | ||
4 | |||
5 | obj-y += clk-sunxi.o clk-factors.o | ||
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c new file mode 100644 index 000000000000..88523f91d9b7 --- /dev/null +++ b/drivers/clk/sunxi/clk-factors.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Emilio López <emilio@elopez.com.ar> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * Adjustable factor-based clock implementation | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/string.h> | ||
17 | |||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #include "clk-factors.h" | ||
21 | |||
22 | /* | ||
23 | * DOC: basic adjustable factor-based clock that cannot gate | ||
24 | * | ||
25 | * Traits of this clock: | ||
26 | * prepare - clk_prepare only ensures that parents are prepared | ||
27 | * enable - clk_enable only ensures that parents are enabled | ||
28 | * rate - rate is adjustable. | ||
29 | * clk->rate = (parent->rate * N * (K + 1) >> P) / (M + 1) | ||
30 | * parent - fixed parent. No clk_set_parent support | ||
31 | */ | ||
32 | |||
33 | struct clk_factors { | ||
34 | struct clk_hw hw; | ||
35 | void __iomem *reg; | ||
36 | struct clk_factors_config *config; | ||
37 | void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); | ||
38 | spinlock_t *lock; | ||
39 | }; | ||
40 | |||
41 | #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) | ||
42 | |||
43 | #define SETMASK(len, pos) (((-1U) >> (31-len)) << (pos)) | ||
44 | #define CLRMASK(len, pos) (~(SETMASK(len, pos))) | ||
45 | #define FACTOR_GET(bit, len, reg) (((reg) & SETMASK(len, bit)) >> (bit)) | ||
46 | |||
47 | #define FACTOR_SET(bit, len, reg, val) \ | ||
48 | (((reg) & CLRMASK(len, bit)) | (val << (bit))) | ||
49 | |||
50 | static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, | ||
51 | unsigned long parent_rate) | ||
52 | { | ||
53 | u8 n = 1, k = 0, p = 0, m = 0; | ||
54 | u32 reg; | ||
55 | unsigned long rate; | ||
56 | struct clk_factors *factors = to_clk_factors(hw); | ||
57 | struct clk_factors_config *config = factors->config; | ||
58 | |||
59 | /* Fetch the register value */ | ||
60 | reg = readl(factors->reg); | ||
61 | |||
62 | /* Get each individual factor if applicable */ | ||
63 | if (config->nwidth != SUNXI_FACTORS_NOT_APPLICABLE) | ||
64 | n = FACTOR_GET(config->nshift, config->nwidth, reg); | ||
65 | if (config->kwidth != SUNXI_FACTORS_NOT_APPLICABLE) | ||
66 | k = FACTOR_GET(config->kshift, config->kwidth, reg); | ||
67 | if (config->mwidth != SUNXI_FACTORS_NOT_APPLICABLE) | ||
68 | m = FACTOR_GET(config->mshift, config->mwidth, reg); | ||
69 | if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE) | ||
70 | p = FACTOR_GET(config->pshift, config->pwidth, reg); | ||
71 | |||
72 | /* Calculate the rate */ | ||
73 | rate = (parent_rate * n * (k + 1) >> p) / (m + 1); | ||
74 | |||
75 | return rate; | ||
76 | } | ||
77 | |||
78 | static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, | ||
79 | unsigned long *parent_rate) | ||
80 | { | ||
81 | struct clk_factors *factors = to_clk_factors(hw); | ||
82 | factors->get_factors((u32 *)&rate, (u32)*parent_rate, | ||
83 | NULL, NULL, NULL, NULL); | ||
84 | |||
85 | return rate; | ||
86 | } | ||
87 | |||
88 | static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, | ||
89 | unsigned long parent_rate) | ||
90 | { | ||
91 | u8 n, k, m, p; | ||
92 | u32 reg; | ||
93 | struct clk_factors *factors = to_clk_factors(hw); | ||
94 | struct clk_factors_config *config = factors->config; | ||
95 | unsigned long flags = 0; | ||
96 | |||
97 | factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); | ||
98 | |||
99 | if (factors->lock) | ||
100 | spin_lock_irqsave(factors->lock, flags); | ||
101 | |||
102 | /* Fetch the register value */ | ||
103 | reg = readl(factors->reg); | ||
104 | |||
105 | /* Set up the new factors - macros do not do anything if width is 0 */ | ||
106 | reg = FACTOR_SET(config->nshift, config->nwidth, reg, n); | ||
107 | reg = FACTOR_SET(config->kshift, config->kwidth, reg, k); | ||
108 | reg = FACTOR_SET(config->mshift, config->mwidth, reg, m); | ||
109 | reg = FACTOR_SET(config->pshift, config->pwidth, reg, p); | ||
110 | |||
111 | /* Apply them now */ | ||
112 | writel(reg, factors->reg); | ||
113 | |||
114 | /* delay 500us so pll stabilizes */ | ||
115 | __delay((rate >> 20) * 500 / 2); | ||
116 | |||
117 | if (factors->lock) | ||
118 | spin_unlock_irqrestore(factors->lock, flags); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static const struct clk_ops clk_factors_ops = { | ||
124 | .recalc_rate = clk_factors_recalc_rate, | ||
125 | .round_rate = clk_factors_round_rate, | ||
126 | .set_rate = clk_factors_set_rate, | ||
127 | }; | ||
128 | |||
129 | /** | ||
130 | * clk_register_factors - register a factors clock with | ||
131 | * the clock framework | ||
132 | * @dev: device registering this clock | ||
133 | * @name: name of this clock | ||
134 | * @parent_name: name of clock's parent | ||
135 | * @flags: framework-specific flags | ||
136 | * @reg: register address to adjust factors | ||
137 | * @config: shift and width of factors n, k, m and p | ||
138 | * @get_factors: function to calculate the factors for a given frequency | ||
139 | * @lock: shared register lock for this clock | ||
140 | */ | ||
141 | struct clk *clk_register_factors(struct device *dev, const char *name, | ||
142 | const char *parent_name, | ||
143 | unsigned long flags, void __iomem *reg, | ||
144 | struct clk_factors_config *config, | ||
145 | void (*get_factors)(u32 *rate, u32 parent, | ||
146 | u8 *n, u8 *k, u8 *m, u8 *p), | ||
147 | spinlock_t *lock) | ||
148 | { | ||
149 | struct clk_factors *factors; | ||
150 | struct clk *clk; | ||
151 | struct clk_init_data init; | ||
152 | |||
153 | /* allocate the factors */ | ||
154 | factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); | ||
155 | if (!factors) { | ||
156 | pr_err("%s: could not allocate factors clk\n", __func__); | ||
157 | return ERR_PTR(-ENOMEM); | ||
158 | } | ||
159 | |||
160 | init.name = name; | ||
161 | init.ops = &clk_factors_ops; | ||
162 | init.flags = flags; | ||
163 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
164 | init.num_parents = (parent_name ? 1 : 0); | ||
165 | |||
166 | /* struct clk_factors assignments */ | ||
167 | factors->reg = reg; | ||
168 | factors->config = config; | ||
169 | factors->lock = lock; | ||
170 | factors->hw.init = &init; | ||
171 | factors->get_factors = get_factors; | ||
172 | |||
173 | /* register the clock */ | ||
174 | clk = clk_register(dev, &factors->hw); | ||
175 | |||
176 | if (IS_ERR(clk)) | ||
177 | kfree(factors); | ||
178 | |||
179 | return clk; | ||
180 | } | ||
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h new file mode 100644 index 000000000000..f49851cc4380 --- /dev/null +++ b/drivers/clk/sunxi/clk-factors.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef __MACH_SUNXI_CLK_FACTORS_H | ||
2 | #define __MACH_SUNXI_CLK_FACTORS_H | ||
3 | |||
4 | #include <linux/clk-provider.h> | ||
5 | #include <linux/clkdev.h> | ||
6 | |||
7 | #define SUNXI_FACTORS_NOT_APPLICABLE (0) | ||
8 | |||
9 | struct clk_factors_config { | ||
10 | u8 nshift; | ||
11 | u8 nwidth; | ||
12 | u8 kshift; | ||
13 | u8 kwidth; | ||
14 | u8 mshift; | ||
15 | u8 mwidth; | ||
16 | u8 pshift; | ||
17 | u8 pwidth; | ||
18 | }; | ||
19 | |||
20 | struct clk *clk_register_factors(struct device *dev, const char *name, | ||
21 | const char *parent_name, | ||
22 | unsigned long flags, void __iomem *reg, | ||
23 | struct clk_factors_config *config, | ||
24 | void (*get_factors) (u32 *rate, u32 parent_rate, | ||
25 | u8 *n, u8 *k, u8 *m, u8 *p), | ||
26 | spinlock_t *lock); | ||
27 | #endif | ||
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c new file mode 100644 index 000000000000..8492ad1d5360 --- /dev/null +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -0,0 +1,469 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Emilio López | ||
3 | * | ||
4 | * Emilio López <emilio@elopez.com.ar> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/clk-provider.h> | ||
18 | #include <linux/clkdev.h> | ||
19 | #include <linux/clk/sunxi.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | |||
23 | #include "clk-factors.h" | ||
24 | |||
25 | static DEFINE_SPINLOCK(clk_lock); | ||
26 | |||
27 | /** | ||
28 | * sunxi_osc_clk_setup() - Setup function for gatable oscillator | ||
29 | */ | ||
30 | |||
31 | #define SUNXI_OSC24M_GATE 0 | ||
32 | |||
33 | static void __init sunxi_osc_clk_setup(struct device_node *node) | ||
34 | { | ||
35 | struct clk *clk; | ||
36 | struct clk_fixed_rate *fixed; | ||
37 | struct clk_gate *gate; | ||
38 | const char *clk_name = node->name; | ||
39 | u32 rate; | ||
40 | |||
41 | /* allocate fixed-rate and gate clock structs */ | ||
42 | fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); | ||
43 | if (!fixed) | ||
44 | return; | ||
45 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | ||
46 | if (!gate) { | ||
47 | kfree(fixed); | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | if (of_property_read_u32(node, "clock-frequency", &rate)) | ||
52 | return; | ||
53 | |||
54 | /* set up gate and fixed rate properties */ | ||
55 | gate->reg = of_iomap(node, 0); | ||
56 | gate->bit_idx = SUNXI_OSC24M_GATE; | ||
57 | gate->lock = &clk_lock; | ||
58 | fixed->fixed_rate = rate; | ||
59 | |||
60 | clk = clk_register_composite(NULL, clk_name, | ||
61 | NULL, 0, | ||
62 | NULL, NULL, | ||
63 | &fixed->hw, &clk_fixed_rate_ops, | ||
64 | &gate->hw, &clk_gate_ops, | ||
65 | CLK_IS_ROOT); | ||
66 | |||
67 | if (clk) { | ||
68 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
69 | clk_register_clkdev(clk, clk_name, NULL); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | |||
74 | |||
75 | /** | ||
76 | * sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1 | ||
77 | * PLL1 rate is calculated as follows | ||
78 | * rate = (parent_rate * n * (k + 1) >> p) / (m + 1); | ||
79 | * parent_rate is always 24Mhz | ||
80 | */ | ||
81 | |||
82 | static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate, | ||
83 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
84 | { | ||
85 | u8 div; | ||
86 | |||
87 | /* Normalize value to a 6M multiple */ | ||
88 | div = *freq / 6000000; | ||
89 | *freq = 6000000 * div; | ||
90 | |||
91 | /* we were called to round the frequency, we can now return */ | ||
92 | if (n == NULL) | ||
93 | return; | ||
94 | |||
95 | /* m is always zero for pll1 */ | ||
96 | *m = 0; | ||
97 | |||
98 | /* k is 1 only on these cases */ | ||
99 | if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) | ||
100 | *k = 1; | ||
101 | else | ||
102 | *k = 0; | ||
103 | |||
104 | /* p will be 3 for divs under 10 */ | ||
105 | if (div < 10) | ||
106 | *p = 3; | ||
107 | |||
108 | /* p will be 2 for divs between 10 - 20 and odd divs under 32 */ | ||
109 | else if (div < 20 || (div < 32 && (div & 1))) | ||
110 | *p = 2; | ||
111 | |||
112 | /* p will be 1 for even divs under 32, divs under 40 and odd pairs | ||
113 | * of divs between 40-62 */ | ||
114 | else if (div < 40 || (div < 64 && (div & 2))) | ||
115 | *p = 1; | ||
116 | |||
117 | /* any other entries have p = 0 */ | ||
118 | else | ||
119 | *p = 0; | ||
120 | |||
121 | /* calculate a suitable n based on k and p */ | ||
122 | div <<= *p; | ||
123 | div /= (*k + 1); | ||
124 | *n = div / 4; | ||
125 | } | ||
126 | |||
127 | |||
128 | |||
129 | /** | ||
130 | * sunxi_get_apb1_factors() - calculates m, p factors for APB1 | ||
131 | * APB1 rate is calculated as follows | ||
132 | * rate = (parent_rate >> p) / (m + 1); | ||
133 | */ | ||
134 | |||
135 | static void sunxi_get_apb1_factors(u32 *freq, u32 parent_rate, | ||
136 | u8 *n, u8 *k, u8 *m, u8 *p) | ||
137 | { | ||
138 | u8 calcm, calcp; | ||
139 | |||
140 | if (parent_rate < *freq) | ||
141 | *freq = parent_rate; | ||
142 | |||
143 | parent_rate = (parent_rate + (*freq - 1)) / *freq; | ||
144 | |||
145 | /* Invalid rate! */ | ||
146 | if (parent_rate > 32) | ||
147 | return; | ||
148 | |||
149 | if (parent_rate <= 4) | ||
150 | calcp = 0; | ||
151 | else if (parent_rate <= 8) | ||
152 | calcp = 1; | ||
153 | else if (parent_rate <= 16) | ||
154 | calcp = 2; | ||
155 | else | ||
156 | calcp = 3; | ||
157 | |||
158 | calcm = (parent_rate >> calcp) - 1; | ||
159 | |||
160 | *freq = (parent_rate >> calcp) / (calcm + 1); | ||
161 | |||
162 | /* we were called to round the frequency, we can now return */ | ||
163 | if (n == NULL) | ||
164 | return; | ||
165 | |||
166 | *m = calcm; | ||
167 | *p = calcp; | ||
168 | } | ||
169 | |||
170 | |||
171 | |||
172 | /** | ||
173 | * sunxi_factors_clk_setup() - Setup function for factor clocks | ||
174 | */ | ||
175 | |||
176 | struct factors_data { | ||
177 | struct clk_factors_config *table; | ||
178 | void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); | ||
179 | }; | ||
180 | |||
181 | static struct clk_factors_config pll1_config = { | ||
182 | .nshift = 8, | ||
183 | .nwidth = 5, | ||
184 | .kshift = 4, | ||
185 | .kwidth = 2, | ||
186 | .mshift = 0, | ||
187 | .mwidth = 2, | ||
188 | .pshift = 16, | ||
189 | .pwidth = 2, | ||
190 | }; | ||
191 | |||
192 | static struct clk_factors_config apb1_config = { | ||
193 | .mshift = 0, | ||
194 | .mwidth = 5, | ||
195 | .pshift = 16, | ||
196 | .pwidth = 2, | ||
197 | }; | ||
198 | |||
199 | static const __initconst struct factors_data pll1_data = { | ||
200 | .table = &pll1_config, | ||
201 | .getter = sunxi_get_pll1_factors, | ||
202 | }; | ||
203 | |||
204 | static const __initconst struct factors_data apb1_data = { | ||
205 | .table = &apb1_config, | ||
206 | .getter = sunxi_get_apb1_factors, | ||
207 | }; | ||
208 | |||
209 | static void __init sunxi_factors_clk_setup(struct device_node *node, | ||
210 | struct factors_data *data) | ||
211 | { | ||
212 | struct clk *clk; | ||
213 | const char *clk_name = node->name; | ||
214 | const char *parent; | ||
215 | void *reg; | ||
216 | |||
217 | reg = of_iomap(node, 0); | ||
218 | |||
219 | parent = of_clk_get_parent_name(node, 0); | ||
220 | |||
221 | clk = clk_register_factors(NULL, clk_name, parent, 0, reg, | ||
222 | data->table, data->getter, &clk_lock); | ||
223 | |||
224 | if (clk) { | ||
225 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
226 | clk_register_clkdev(clk, clk_name, NULL); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | |||
231 | |||
232 | /** | ||
233 | * sunxi_mux_clk_setup() - Setup function for muxes | ||
234 | */ | ||
235 | |||
236 | #define SUNXI_MUX_GATE_WIDTH 2 | ||
237 | |||
238 | struct mux_data { | ||
239 | u8 shift; | ||
240 | }; | ||
241 | |||
242 | static const __initconst struct mux_data cpu_data = { | ||
243 | .shift = 16, | ||
244 | }; | ||
245 | |||
246 | static const __initconst struct mux_data apb1_mux_data = { | ||
247 | .shift = 24, | ||
248 | }; | ||
249 | |||
250 | static void __init sunxi_mux_clk_setup(struct device_node *node, | ||
251 | struct mux_data *data) | ||
252 | { | ||
253 | struct clk *clk; | ||
254 | const char *clk_name = node->name; | ||
255 | const char *parents[5]; | ||
256 | void *reg; | ||
257 | int i = 0; | ||
258 | |||
259 | reg = of_iomap(node, 0); | ||
260 | |||
261 | while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL) | ||
262 | i++; | ||
263 | |||
264 | clk = clk_register_mux(NULL, clk_name, parents, i, 0, reg, | ||
265 | data->shift, SUNXI_MUX_GATE_WIDTH, | ||
266 | 0, &clk_lock); | ||
267 | |||
268 | if (clk) { | ||
269 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
270 | clk_register_clkdev(clk, clk_name, NULL); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | |||
275 | |||
276 | /** | ||
277 | * sunxi_divider_clk_setup() - Setup function for simple divider clocks | ||
278 | */ | ||
279 | |||
280 | #define SUNXI_DIVISOR_WIDTH 2 | ||
281 | |||
282 | struct div_data { | ||
283 | u8 shift; | ||
284 | u8 pow; | ||
285 | }; | ||
286 | |||
287 | static const __initconst struct div_data axi_data = { | ||
288 | .shift = 0, | ||
289 | .pow = 0, | ||
290 | }; | ||
291 | |||
292 | static const __initconst struct div_data ahb_data = { | ||
293 | .shift = 4, | ||
294 | .pow = 1, | ||
295 | }; | ||
296 | |||
297 | static const __initconst struct div_data apb0_data = { | ||
298 | .shift = 8, | ||
299 | .pow = 1, | ||
300 | }; | ||
301 | |||
302 | static void __init sunxi_divider_clk_setup(struct device_node *node, | ||
303 | struct div_data *data) | ||
304 | { | ||
305 | struct clk *clk; | ||
306 | const char *clk_name = node->name; | ||
307 | const char *clk_parent; | ||
308 | void *reg; | ||
309 | |||
310 | reg = of_iomap(node, 0); | ||
311 | |||
312 | clk_parent = of_clk_get_parent_name(node, 0); | ||
313 | |||
314 | clk = clk_register_divider(NULL, clk_name, clk_parent, 0, | ||
315 | reg, data->shift, SUNXI_DIVISOR_WIDTH, | ||
316 | data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, | ||
317 | &clk_lock); | ||
318 | if (clk) { | ||
319 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
320 | clk_register_clkdev(clk, clk_name, NULL); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | |||
325 | |||
326 | /** | ||
327 | * sunxi_gates_clk_setup() - Setup function for leaf gates on clocks | ||
328 | */ | ||
329 | |||
330 | #define SUNXI_GATES_MAX_SIZE 64 | ||
331 | |||
332 | struct gates_data { | ||
333 | DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE); | ||
334 | }; | ||
335 | |||
336 | static const __initconst struct gates_data axi_gates_data = { | ||
337 | .mask = {1}, | ||
338 | }; | ||
339 | |||
340 | static const __initconst struct gates_data ahb_gates_data = { | ||
341 | .mask = {0x7F77FFF, 0x14FB3F}, | ||
342 | }; | ||
343 | |||
344 | static const __initconst struct gates_data apb0_gates_data = { | ||
345 | .mask = {0x4EF}, | ||
346 | }; | ||
347 | |||
348 | static const __initconst struct gates_data apb1_gates_data = { | ||
349 | .mask = {0xFF00F7}, | ||
350 | }; | ||
351 | |||
352 | static void __init sunxi_gates_clk_setup(struct device_node *node, | ||
353 | struct gates_data *data) | ||
354 | { | ||
355 | struct clk_onecell_data *clk_data; | ||
356 | const char *clk_parent; | ||
357 | const char *clk_name; | ||
358 | void *reg; | ||
359 | int qty; | ||
360 | int i = 0; | ||
361 | int j = 0; | ||
362 | int ignore; | ||
363 | |||
364 | reg = of_iomap(node, 0); | ||
365 | |||
366 | clk_parent = of_clk_get_parent_name(node, 0); | ||
367 | |||
368 | /* Worst-case size approximation and memory allocation */ | ||
369 | qty = find_last_bit(data->mask, SUNXI_GATES_MAX_SIZE); | ||
370 | clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); | ||
371 | if (!clk_data) | ||
372 | return; | ||
373 | clk_data->clks = kzalloc((qty+1) * sizeof(struct clk *), GFP_KERNEL); | ||
374 | if (!clk_data->clks) { | ||
375 | kfree(clk_data); | ||
376 | return; | ||
377 | } | ||
378 | |||
379 | for_each_set_bit(i, data->mask, SUNXI_GATES_MAX_SIZE) { | ||
380 | of_property_read_string_index(node, "clock-output-names", | ||
381 | j, &clk_name); | ||
382 | |||
383 | /* No driver claims this clock, but it should remain gated */ | ||
384 | ignore = !strcmp("ahb_sdram", clk_name) ? CLK_IGNORE_UNUSED : 0; | ||
385 | |||
386 | clk_data->clks[i] = clk_register_gate(NULL, clk_name, | ||
387 | clk_parent, ignore, | ||
388 | reg + 4 * (i/32), i % 32, | ||
389 | 0, &clk_lock); | ||
390 | WARN_ON(IS_ERR(clk_data->clks[i])); | ||
391 | |||
392 | j++; | ||
393 | } | ||
394 | |||
395 | /* Adjust to the real max */ | ||
396 | clk_data->clk_num = i; | ||
397 | |||
398 | of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
399 | } | ||
400 | |||
401 | /* Matches for of_clk_init */ | ||
402 | static const __initconst struct of_device_id clk_match[] = { | ||
403 | {.compatible = "allwinner,sun4i-osc-clk", .data = sunxi_osc_clk_setup,}, | ||
404 | {} | ||
405 | }; | ||
406 | |||
407 | /* Matches for factors clocks */ | ||
408 | static const __initconst struct of_device_id clk_factors_match[] = { | ||
409 | {.compatible = "allwinner,sun4i-pll1-clk", .data = &pll1_data,}, | ||
410 | {.compatible = "allwinner,sun4i-apb1-clk", .data = &apb1_data,}, | ||
411 | {} | ||
412 | }; | ||
413 | |||
414 | /* Matches for divider clocks */ | ||
415 | static const __initconst struct of_device_id clk_div_match[] = { | ||
416 | {.compatible = "allwinner,sun4i-axi-clk", .data = &axi_data,}, | ||
417 | {.compatible = "allwinner,sun4i-ahb-clk", .data = &ahb_data,}, | ||
418 | {.compatible = "allwinner,sun4i-apb0-clk", .data = &apb0_data,}, | ||
419 | {} | ||
420 | }; | ||
421 | |||
422 | /* Matches for mux clocks */ | ||
423 | static const __initconst struct of_device_id clk_mux_match[] = { | ||
424 | {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_data,}, | ||
425 | {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,}, | ||
426 | {} | ||
427 | }; | ||
428 | |||
429 | /* Matches for gate clocks */ | ||
430 | static const __initconst struct of_device_id clk_gates_match[] = { | ||
431 | {.compatible = "allwinner,sun4i-axi-gates-clk", .data = &axi_gates_data,}, | ||
432 | {.compatible = "allwinner,sun4i-ahb-gates-clk", .data = &ahb_gates_data,}, | ||
433 | {.compatible = "allwinner,sun4i-apb0-gates-clk", .data = &apb0_gates_data,}, | ||
434 | {.compatible = "allwinner,sun4i-apb1-gates-clk", .data = &apb1_gates_data,}, | ||
435 | {} | ||
436 | }; | ||
437 | |||
438 | static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match, | ||
439 | void *function) | ||
440 | { | ||
441 | struct device_node *np; | ||
442 | const struct div_data *data; | ||
443 | const struct of_device_id *match; | ||
444 | void (*setup_function)(struct device_node *, const void *) = function; | ||
445 | |||
446 | for_each_matching_node(np, clk_match) { | ||
447 | match = of_match_node(clk_match, np); | ||
448 | data = match->data; | ||
449 | setup_function(np, data); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | void __init sunxi_init_clocks(void) | ||
454 | { | ||
455 | /* Register all the simple sunxi clocks on DT */ | ||
456 | of_clk_init(clk_match); | ||
457 | |||
458 | /* Register factor clocks */ | ||
459 | of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); | ||
460 | |||
461 | /* Register divider clocks */ | ||
462 | of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup); | ||
463 | |||
464 | /* Register mux clocks */ | ||
465 | of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup); | ||
466 | |||
467 | /* Register gate clocks */ | ||
468 | of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup); | ||
469 | } | ||
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 0744731c6229..a09d7dcaf183 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
@@ -355,15 +355,16 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name, | |||
355 | struct tegra_clk_periph *periph, void __iomem *clk_base, | 355 | struct tegra_clk_periph *periph, void __iomem *clk_base, |
356 | u32 offset); | 356 | u32 offset); |
357 | 357 | ||
358 | #define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags, \ | 358 | #define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags, \ |
359 | _div_shift, _div_width, _div_frac_width, \ | 359 | _div_shift, _div_width, _div_frac_width, \ |
360 | _div_flags, _clk_num, _enb_refcnt, _regs, \ | 360 | _div_flags, _clk_num, _enb_refcnt, _regs, \ |
361 | _gate_flags) \ | 361 | _gate_flags, _table) \ |
362 | { \ | 362 | { \ |
363 | .mux = { \ | 363 | .mux = { \ |
364 | .flags = _mux_flags, \ | 364 | .flags = _mux_flags, \ |
365 | .shift = _mux_shift, \ | 365 | .shift = _mux_shift, \ |
366 | .width = _mux_width, \ | 366 | .mask = _mux_mask, \ |
367 | .table = _table, \ | ||
367 | }, \ | 368 | }, \ |
368 | .divider = { \ | 369 | .divider = { \ |
369 | .flags = _div_flags, \ | 370 | .flags = _div_flags, \ |
@@ -393,26 +394,36 @@ struct tegra_periph_init_data { | |||
393 | const char *dev_id; | 394 | const char *dev_id; |
394 | }; | 395 | }; |
395 | 396 | ||
396 | #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \ | 397 | #define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ |
397 | _mux_shift, _mux_width, _mux_flags, _div_shift, \ | 398 | _mux_shift, _mux_mask, _mux_flags, _div_shift, \ |
398 | _div_width, _div_frac_width, _div_flags, _regs, \ | 399 | _div_width, _div_frac_width, _div_flags, _regs, \ |
399 | _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ | 400 | _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table) \ |
400 | { \ | 401 | { \ |
401 | .name = _name, \ | 402 | .name = _name, \ |
402 | .clk_id = _clk_id, \ | 403 | .clk_id = _clk_id, \ |
403 | .parent_names = _parent_names, \ | 404 | .parent_names = _parent_names, \ |
404 | .num_parents = ARRAY_SIZE(_parent_names), \ | 405 | .num_parents = ARRAY_SIZE(_parent_names), \ |
405 | .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width, \ | 406 | .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, \ |
406 | _mux_flags, _div_shift, \ | 407 | _mux_flags, _div_shift, \ |
407 | _div_width, _div_frac_width, \ | 408 | _div_width, _div_frac_width, \ |
408 | _div_flags, _clk_num, \ | 409 | _div_flags, _clk_num, \ |
409 | _enb_refcnt, _regs, \ | 410 | _enb_refcnt, _regs, \ |
410 | _gate_flags), \ | 411 | _gate_flags, _table), \ |
411 | .offset = _offset, \ | 412 | .offset = _offset, \ |
412 | .con_id = _con_id, \ | 413 | .con_id = _con_id, \ |
413 | .dev_id = _dev_id, \ | 414 | .dev_id = _dev_id, \ |
414 | } | 415 | } |
415 | 416 | ||
417 | #define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\ | ||
418 | _mux_shift, _mux_width, _mux_flags, _div_shift, \ | ||
419 | _div_width, _div_frac_width, _div_flags, _regs, \ | ||
420 | _clk_num, _enb_refcnt, _gate_flags, _clk_id) \ | ||
421 | TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\ | ||
422 | _mux_shift, BIT(_mux_width) - 1, _mux_flags, \ | ||
423 | _div_shift, _div_width, _div_frac_width, _div_flags, \ | ||
424 | _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\ | ||
425 | NULL) | ||
426 | |||
416 | /** | 427 | /** |
417 | * struct clk_super_mux - super clock | 428 | * struct clk_super_mux - super clock |
418 | * | 429 | * |
diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile index bcc0c11a507c..c6a806ed0e8c 100644 --- a/drivers/clk/ux500/Makefile +++ b/drivers/clk/ux500/Makefile | |||
@@ -5,6 +5,7 @@ | |||
5 | # Clock types | 5 | # Clock types |
6 | obj-y += clk-prcc.o | 6 | obj-y += clk-prcc.o |
7 | obj-y += clk-prcmu.o | 7 | obj-y += clk-prcmu.o |
8 | obj-y += clk-sysctrl.o | ||
8 | 9 | ||
9 | # Clock definitions | 10 | # Clock definitions |
10 | obj-y += u8500_clk.o | 11 | obj-y += u8500_clk.o |
diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index 9f7400d74fa7..a0fca004abc1 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c | |||
@@ -12,13 +12,78 @@ | |||
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/mfd/abx500/ab8500.h> | 14 | #include <linux/mfd/abx500/ab8500.h> |
15 | 15 | #include <linux/mfd/abx500/ab8500-sysctrl.h> | |
16 | /* TODO: Add clock implementations here */ | 16 | #include <linux/clk.h> |
17 | 17 | #include <linux/clkdev.h> | |
18 | #include <linux/clk-provider.h> | ||
19 | #include <linux/mfd/dbx500-prcmu.h> | ||
20 | #include "clk.h" | ||
18 | 21 | ||
19 | /* Clock definitions for ab8500 */ | 22 | /* Clock definitions for ab8500 */ |
20 | static int ab8500_reg_clks(struct device *dev) | 23 | static int ab8500_reg_clks(struct device *dev) |
21 | { | 24 | { |
25 | int ret; | ||
26 | struct clk *clk; | ||
27 | |||
28 | const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"}; | ||
29 | u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1}; | ||
30 | u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK}; | ||
31 | u8 intclk_reg_bits[] = { | ||
32 | 0 , | ||
33 | (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT) | ||
34 | }; | ||
35 | |||
36 | dev_info(dev, "register clocks for ab850x\n"); | ||
37 | |||
38 | /* Enable SWAT */ | ||
39 | ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); | ||
40 | if (ret) | ||
41 | return ret; | ||
42 | |||
43 | /* ab8500_sysclk */ | ||
44 | clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, | ||
45 | CLK_IS_ROOT); | ||
46 | clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); | ||
47 | clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); | ||
48 | clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0"); | ||
49 | clk_register_clkdev(clk, "sysclk", "shrm_bus"); | ||
50 | |||
51 | /* ab8500_sysclk2 */ | ||
52 | clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk", | ||
53 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, | ||
54 | AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0); | ||
55 | clk_register_clkdev(clk, "sysclk", "0-0070"); | ||
56 | |||
57 | /* ab8500_sysclk3 */ | ||
58 | clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk", | ||
59 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, | ||
60 | AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0); | ||
61 | clk_register_clkdev(clk, "sysclk", "cg1960_core.0"); | ||
62 | |||
63 | /* ab8500_sysclk4 */ | ||
64 | clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk", | ||
65 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, | ||
66 | AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0); | ||
67 | |||
68 | /* ab_ulpclk */ | ||
69 | clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, | ||
70 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, | ||
71 | AB8500_SYSULPCLKCTRL1_ULPCLKREQ, | ||
72 | 38400000, 9000, CLK_IS_ROOT); | ||
73 | clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0"); | ||
74 | |||
75 | /* ab8500_intclk */ | ||
76 | clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, | ||
77 | intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); | ||
78 | clk_register_clkdev(clk, "intclk", "ab85xx-codec.0"); | ||
79 | clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); | ||
80 | |||
81 | /* ab8500_audioclk */ | ||
82 | clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", | ||
83 | AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, | ||
84 | AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); | ||
85 | clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0"); | ||
86 | |||
22 | return 0; | 87 | return 0; |
23 | } | 88 | } |
24 | 89 | ||
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 74faa7e3cf59..293a28854417 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c | |||
@@ -20,15 +20,23 @@ | |||
20 | struct clk_prcmu { | 20 | struct clk_prcmu { |
21 | struct clk_hw hw; | 21 | struct clk_hw hw; |
22 | u8 cg_sel; | 22 | u8 cg_sel; |
23 | int is_prepared; | ||
23 | int is_enabled; | 24 | int is_enabled; |
25 | int opp_requested; | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | /* PRCMU clock operations. */ | 28 | /* PRCMU clock operations. */ |
27 | 29 | ||
28 | static int clk_prcmu_prepare(struct clk_hw *hw) | 30 | static int clk_prcmu_prepare(struct clk_hw *hw) |
29 | { | 31 | { |
32 | int ret; | ||
30 | struct clk_prcmu *clk = to_clk_prcmu(hw); | 33 | struct clk_prcmu *clk = to_clk_prcmu(hw); |
31 | return prcmu_request_clock(clk->cg_sel, true); | 34 | |
35 | ret = prcmu_request_clock(clk->cg_sel, true); | ||
36 | if (!ret) | ||
37 | clk->is_prepared = 1; | ||
38 | |||
39 | return ret;; | ||
32 | } | 40 | } |
33 | 41 | ||
34 | static void clk_prcmu_unprepare(struct clk_hw *hw) | 42 | static void clk_prcmu_unprepare(struct clk_hw *hw) |
@@ -36,7 +44,15 @@ static void clk_prcmu_unprepare(struct clk_hw *hw) | |||
36 | struct clk_prcmu *clk = to_clk_prcmu(hw); | 44 | struct clk_prcmu *clk = to_clk_prcmu(hw); |
37 | if (prcmu_request_clock(clk->cg_sel, false)) | 45 | if (prcmu_request_clock(clk->cg_sel, false)) |
38 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, | 46 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, |
39 | hw->init->name); | 47 | __clk_get_name(hw->clk)); |
48 | else | ||
49 | clk->is_prepared = 0; | ||
50 | } | ||
51 | |||
52 | static int clk_prcmu_is_prepared(struct clk_hw *hw) | ||
53 | { | ||
54 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
55 | return clk->is_prepared; | ||
40 | } | 56 | } |
41 | 57 | ||
42 | static int clk_prcmu_enable(struct clk_hw *hw) | 58 | static int clk_prcmu_enable(struct clk_hw *hw) |
@@ -79,58 +95,52 @@ static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate, | |||
79 | return prcmu_set_clock_rate(clk->cg_sel, rate); | 95 | return prcmu_set_clock_rate(clk->cg_sel, rate); |
80 | } | 96 | } |
81 | 97 | ||
82 | static int request_ape_opp100(bool enable) | ||
83 | { | ||
84 | static int reqs; | ||
85 | int err = 0; | ||
86 | |||
87 | if (enable) { | ||
88 | if (!reqs) | ||
89 | err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, | ||
90 | "clock", 100); | ||
91 | if (!err) | ||
92 | reqs++; | ||
93 | } else { | ||
94 | reqs--; | ||
95 | if (!reqs) | ||
96 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, | ||
97 | "clock"); | ||
98 | } | ||
99 | return err; | ||
100 | } | ||
101 | |||
102 | static int clk_prcmu_opp_prepare(struct clk_hw *hw) | 98 | static int clk_prcmu_opp_prepare(struct clk_hw *hw) |
103 | { | 99 | { |
104 | int err; | 100 | int err; |
105 | struct clk_prcmu *clk = to_clk_prcmu(hw); | 101 | struct clk_prcmu *clk = to_clk_prcmu(hw); |
106 | 102 | ||
107 | err = request_ape_opp100(true); | 103 | if (!clk->opp_requested) { |
108 | if (err) { | 104 | err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, |
109 | pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n", | 105 | (char *)__clk_get_name(hw->clk), |
110 | __func__, hw->init->name); | 106 | 100); |
111 | return err; | 107 | if (err) { |
108 | pr_err("clk_prcmu: %s fail req APE OPP for %s.\n", | ||
109 | __func__, __clk_get_name(hw->clk)); | ||
110 | return err; | ||
111 | } | ||
112 | clk->opp_requested = 1; | ||
112 | } | 113 | } |
113 | 114 | ||
114 | err = prcmu_request_clock(clk->cg_sel, true); | 115 | err = prcmu_request_clock(clk->cg_sel, true); |
115 | if (err) | 116 | if (err) { |
116 | request_ape_opp100(false); | 117 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, |
118 | (char *)__clk_get_name(hw->clk)); | ||
119 | clk->opp_requested = 0; | ||
120 | return err; | ||
121 | } | ||
117 | 122 | ||
118 | return err; | 123 | clk->is_prepared = 1; |
124 | return 0; | ||
119 | } | 125 | } |
120 | 126 | ||
121 | static void clk_prcmu_opp_unprepare(struct clk_hw *hw) | 127 | static void clk_prcmu_opp_unprepare(struct clk_hw *hw) |
122 | { | 128 | { |
123 | struct clk_prcmu *clk = to_clk_prcmu(hw); | 129 | struct clk_prcmu *clk = to_clk_prcmu(hw); |
124 | 130 | ||
125 | if (prcmu_request_clock(clk->cg_sel, false)) | 131 | if (prcmu_request_clock(clk->cg_sel, false)) { |
126 | goto out_error; | 132 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, |
127 | if (request_ape_opp100(false)) | 133 | __clk_get_name(hw->clk)); |
128 | goto out_error; | 134 | return; |
129 | return; | 135 | } |
130 | 136 | ||
131 | out_error: | 137 | if (clk->opp_requested) { |
132 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, | 138 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, |
133 | hw->init->name); | 139 | (char *)__clk_get_name(hw->clk)); |
140 | clk->opp_requested = 0; | ||
141 | } | ||
142 | |||
143 | clk->is_prepared = 0; | ||
134 | } | 144 | } |
135 | 145 | ||
136 | static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) | 146 | static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) |
@@ -138,38 +148,49 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) | |||
138 | int err; | 148 | int err; |
139 | struct clk_prcmu *clk = to_clk_prcmu(hw); | 149 | struct clk_prcmu *clk = to_clk_prcmu(hw); |
140 | 150 | ||
141 | err = prcmu_request_ape_opp_100_voltage(true); | 151 | if (!clk->opp_requested) { |
142 | if (err) { | 152 | err = prcmu_request_ape_opp_100_voltage(true); |
143 | pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n", | 153 | if (err) { |
144 | __func__, hw->init->name); | 154 | pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n", |
145 | return err; | 155 | __func__, __clk_get_name(hw->clk)); |
156 | return err; | ||
157 | } | ||
158 | clk->opp_requested = 1; | ||
146 | } | 159 | } |
147 | 160 | ||
148 | err = prcmu_request_clock(clk->cg_sel, true); | 161 | err = prcmu_request_clock(clk->cg_sel, true); |
149 | if (err) | 162 | if (err) { |
150 | prcmu_request_ape_opp_100_voltage(false); | 163 | prcmu_request_ape_opp_100_voltage(false); |
164 | clk->opp_requested = 0; | ||
165 | return err; | ||
166 | } | ||
151 | 167 | ||
152 | return err; | 168 | clk->is_prepared = 1; |
169 | return 0; | ||
153 | } | 170 | } |
154 | 171 | ||
155 | static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) | 172 | static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) |
156 | { | 173 | { |
157 | struct clk_prcmu *clk = to_clk_prcmu(hw); | 174 | struct clk_prcmu *clk = to_clk_prcmu(hw); |
158 | 175 | ||
159 | if (prcmu_request_clock(clk->cg_sel, false)) | 176 | if (prcmu_request_clock(clk->cg_sel, false)) { |
160 | goto out_error; | 177 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, |
161 | if (prcmu_request_ape_opp_100_voltage(false)) | 178 | __clk_get_name(hw->clk)); |
162 | goto out_error; | 179 | return; |
163 | return; | 180 | } |
164 | 181 | ||
165 | out_error: | 182 | if (clk->opp_requested) { |
166 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, | 183 | prcmu_request_ape_opp_100_voltage(false); |
167 | hw->init->name); | 184 | clk->opp_requested = 0; |
185 | } | ||
186 | |||
187 | clk->is_prepared = 0; | ||
168 | } | 188 | } |
169 | 189 | ||
170 | static struct clk_ops clk_prcmu_scalable_ops = { | 190 | static struct clk_ops clk_prcmu_scalable_ops = { |
171 | .prepare = clk_prcmu_prepare, | 191 | .prepare = clk_prcmu_prepare, |
172 | .unprepare = clk_prcmu_unprepare, | 192 | .unprepare = clk_prcmu_unprepare, |
193 | .is_prepared = clk_prcmu_is_prepared, | ||
173 | .enable = clk_prcmu_enable, | 194 | .enable = clk_prcmu_enable, |
174 | .disable = clk_prcmu_disable, | 195 | .disable = clk_prcmu_disable, |
175 | .is_enabled = clk_prcmu_is_enabled, | 196 | .is_enabled = clk_prcmu_is_enabled, |
@@ -181,6 +202,7 @@ static struct clk_ops clk_prcmu_scalable_ops = { | |||
181 | static struct clk_ops clk_prcmu_gate_ops = { | 202 | static struct clk_ops clk_prcmu_gate_ops = { |
182 | .prepare = clk_prcmu_prepare, | 203 | .prepare = clk_prcmu_prepare, |
183 | .unprepare = clk_prcmu_unprepare, | 204 | .unprepare = clk_prcmu_unprepare, |
205 | .is_prepared = clk_prcmu_is_prepared, | ||
184 | .enable = clk_prcmu_enable, | 206 | .enable = clk_prcmu_enable, |
185 | .disable = clk_prcmu_disable, | 207 | .disable = clk_prcmu_disable, |
186 | .is_enabled = clk_prcmu_is_enabled, | 208 | .is_enabled = clk_prcmu_is_enabled, |
@@ -202,6 +224,7 @@ static struct clk_ops clk_prcmu_rate_ops = { | |||
202 | static struct clk_ops clk_prcmu_opp_gate_ops = { | 224 | static struct clk_ops clk_prcmu_opp_gate_ops = { |
203 | .prepare = clk_prcmu_opp_prepare, | 225 | .prepare = clk_prcmu_opp_prepare, |
204 | .unprepare = clk_prcmu_opp_unprepare, | 226 | .unprepare = clk_prcmu_opp_unprepare, |
227 | .is_prepared = clk_prcmu_is_prepared, | ||
205 | .enable = clk_prcmu_enable, | 228 | .enable = clk_prcmu_enable, |
206 | .disable = clk_prcmu_disable, | 229 | .disable = clk_prcmu_disable, |
207 | .is_enabled = clk_prcmu_is_enabled, | 230 | .is_enabled = clk_prcmu_is_enabled, |
@@ -211,6 +234,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { | |||
211 | static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { | 234 | static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { |
212 | .prepare = clk_prcmu_opp_volt_prepare, | 235 | .prepare = clk_prcmu_opp_volt_prepare, |
213 | .unprepare = clk_prcmu_opp_volt_unprepare, | 236 | .unprepare = clk_prcmu_opp_volt_unprepare, |
237 | .is_prepared = clk_prcmu_is_prepared, | ||
214 | .enable = clk_prcmu_enable, | 238 | .enable = clk_prcmu_enable, |
215 | .disable = clk_prcmu_disable, | 239 | .disable = clk_prcmu_disable, |
216 | .is_enabled = clk_prcmu_is_enabled, | 240 | .is_enabled = clk_prcmu_is_enabled, |
@@ -242,7 +266,9 @@ static struct clk *clk_reg_prcmu(const char *name, | |||
242 | } | 266 | } |
243 | 267 | ||
244 | clk->cg_sel = cg_sel; | 268 | clk->cg_sel = cg_sel; |
269 | clk->is_prepared = 1; | ||
245 | clk->is_enabled = 1; | 270 | clk->is_enabled = 1; |
271 | clk->opp_requested = 0; | ||
246 | /* "rate" can be used for changing the initial frequency */ | 272 | /* "rate" can be used for changing the initial frequency */ |
247 | if (rate) | 273 | if (rate) |
248 | prcmu_set_clock_rate(cg_sel, rate); | 274 | prcmu_set_clock_rate(cg_sel, rate); |
diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c new file mode 100644 index 000000000000..bc7e9bde792b --- /dev/null +++ b/drivers/clk/ux500/clk-sysctrl.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Sysctrl clock implementation for ux500 platform. | ||
3 | * | ||
4 | * Copyright (C) 2013 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk-provider.h> | ||
11 | #include <linux/mfd/abx500/ab8500-sysctrl.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/err.h> | ||
17 | #include "clk.h" | ||
18 | |||
19 | #define SYSCTRL_MAX_NUM_PARENTS 4 | ||
20 | |||
21 | #define to_clk_sysctrl(_hw) container_of(_hw, struct clk_sysctrl, hw) | ||
22 | |||
23 | struct clk_sysctrl { | ||
24 | struct clk_hw hw; | ||
25 | struct device *dev; | ||
26 | u8 parent_index; | ||
27 | u16 reg_sel[SYSCTRL_MAX_NUM_PARENTS]; | ||
28 | u8 reg_mask[SYSCTRL_MAX_NUM_PARENTS]; | ||
29 | u8 reg_bits[SYSCTRL_MAX_NUM_PARENTS]; | ||
30 | unsigned long rate; | ||
31 | unsigned long enable_delay_us; | ||
32 | }; | ||
33 | |||
34 | /* Sysctrl clock operations. */ | ||
35 | |||
36 | static int clk_sysctrl_prepare(struct clk_hw *hw) | ||
37 | { | ||
38 | int ret; | ||
39 | struct clk_sysctrl *clk = to_clk_sysctrl(hw); | ||
40 | |||
41 | ret = ab8500_sysctrl_write(clk->reg_sel[0], clk->reg_mask[0], | ||
42 | clk->reg_bits[0]); | ||
43 | |||
44 | if (!ret && clk->enable_delay_us) | ||
45 | usleep_range(clk->enable_delay_us, clk->enable_delay_us); | ||
46 | |||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static void clk_sysctrl_unprepare(struct clk_hw *hw) | ||
51 | { | ||
52 | struct clk_sysctrl *clk = to_clk_sysctrl(hw); | ||
53 | if (ab8500_sysctrl_clear(clk->reg_sel[0], clk->reg_mask[0])) | ||
54 | dev_err(clk->dev, "clk_sysctrl: %s fail to clear %s.\n", | ||
55 | __func__, __clk_get_name(hw->clk)); | ||
56 | } | ||
57 | |||
58 | static unsigned long clk_sysctrl_recalc_rate(struct clk_hw *hw, | ||
59 | unsigned long parent_rate) | ||
60 | { | ||
61 | struct clk_sysctrl *clk = to_clk_sysctrl(hw); | ||
62 | return clk->rate; | ||
63 | } | ||
64 | |||
65 | static int clk_sysctrl_set_parent(struct clk_hw *hw, u8 index) | ||
66 | { | ||
67 | struct clk_sysctrl *clk = to_clk_sysctrl(hw); | ||
68 | u8 old_index = clk->parent_index; | ||
69 | int ret = 0; | ||
70 | |||
71 | if (clk->reg_sel[old_index]) { | ||
72 | ret = ab8500_sysctrl_clear(clk->reg_sel[old_index], | ||
73 | clk->reg_mask[old_index]); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | if (clk->reg_sel[index]) { | ||
79 | ret = ab8500_sysctrl_write(clk->reg_sel[index], | ||
80 | clk->reg_mask[index], | ||
81 | clk->reg_bits[index]); | ||
82 | if (ret) { | ||
83 | if (clk->reg_sel[old_index]) | ||
84 | ab8500_sysctrl_write(clk->reg_sel[old_index], | ||
85 | clk->reg_mask[old_index], | ||
86 | clk->reg_bits[old_index]); | ||
87 | return ret; | ||
88 | } | ||
89 | } | ||
90 | clk->parent_index = index; | ||
91 | |||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | static u8 clk_sysctrl_get_parent(struct clk_hw *hw) | ||
96 | { | ||
97 | struct clk_sysctrl *clk = to_clk_sysctrl(hw); | ||
98 | return clk->parent_index; | ||
99 | } | ||
100 | |||
101 | static struct clk_ops clk_sysctrl_gate_ops = { | ||
102 | .prepare = clk_sysctrl_prepare, | ||
103 | .unprepare = clk_sysctrl_unprepare, | ||
104 | }; | ||
105 | |||
106 | static struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { | ||
107 | .prepare = clk_sysctrl_prepare, | ||
108 | .unprepare = clk_sysctrl_unprepare, | ||
109 | .recalc_rate = clk_sysctrl_recalc_rate, | ||
110 | }; | ||
111 | |||
112 | static struct clk_ops clk_sysctrl_set_parent_ops = { | ||
113 | .set_parent = clk_sysctrl_set_parent, | ||
114 | .get_parent = clk_sysctrl_get_parent, | ||
115 | }; | ||
116 | |||
117 | static struct clk *clk_reg_sysctrl(struct device *dev, | ||
118 | const char *name, | ||
119 | const char **parent_names, | ||
120 | u8 num_parents, | ||
121 | u16 *reg_sel, | ||
122 | u8 *reg_mask, | ||
123 | u8 *reg_bits, | ||
124 | unsigned long rate, | ||
125 | unsigned long enable_delay_us, | ||
126 | unsigned long flags, | ||
127 | struct clk_ops *clk_sysctrl_ops) | ||
128 | { | ||
129 | struct clk_sysctrl *clk; | ||
130 | struct clk_init_data clk_sysctrl_init; | ||
131 | struct clk *clk_reg; | ||
132 | int i; | ||
133 | |||
134 | if (!dev) | ||
135 | return ERR_PTR(-EINVAL); | ||
136 | |||
137 | if (!name || (num_parents > SYSCTRL_MAX_NUM_PARENTS)) { | ||
138 | dev_err(dev, "clk_sysctrl: invalid arguments passed\n"); | ||
139 | return ERR_PTR(-EINVAL); | ||
140 | } | ||
141 | |||
142 | clk = devm_kzalloc(dev, sizeof(struct clk_sysctrl), GFP_KERNEL); | ||
143 | if (!clk) { | ||
144 | dev_err(dev, "clk_sysctrl: could not allocate clk\n"); | ||
145 | return ERR_PTR(-ENOMEM); | ||
146 | } | ||
147 | |||
148 | for (i = 0; i < num_parents; i++) { | ||
149 | clk->reg_sel[i] = reg_sel[i]; | ||
150 | clk->reg_bits[i] = reg_bits[i]; | ||
151 | clk->reg_mask[i] = reg_mask[i]; | ||
152 | } | ||
153 | |||
154 | clk->parent_index = 0; | ||
155 | clk->rate = rate; | ||
156 | clk->enable_delay_us = enable_delay_us; | ||
157 | clk->dev = dev; | ||
158 | |||
159 | clk_sysctrl_init.name = name; | ||
160 | clk_sysctrl_init.ops = clk_sysctrl_ops; | ||
161 | clk_sysctrl_init.flags = flags; | ||
162 | clk_sysctrl_init.parent_names = parent_names; | ||
163 | clk_sysctrl_init.num_parents = num_parents; | ||
164 | clk->hw.init = &clk_sysctrl_init; | ||
165 | |||
166 | clk_reg = devm_clk_register(clk->dev, &clk->hw); | ||
167 | if (IS_ERR(clk_reg)) | ||
168 | dev_err(dev, "clk_sysctrl: clk_register failed\n"); | ||
169 | |||
170 | return clk_reg; | ||
171 | } | ||
172 | |||
173 | struct clk *clk_reg_sysctrl_gate(struct device *dev, | ||
174 | const char *name, | ||
175 | const char *parent_name, | ||
176 | u16 reg_sel, | ||
177 | u8 reg_mask, | ||
178 | u8 reg_bits, | ||
179 | unsigned long enable_delay_us, | ||
180 | unsigned long flags) | ||
181 | { | ||
182 | const char **parent_names = (parent_name ? &parent_name : NULL); | ||
183 | u8 num_parents = (parent_name ? 1 : 0); | ||
184 | |||
185 | return clk_reg_sysctrl(dev, name, parent_names, num_parents, | ||
186 | ®_sel, ®_mask, ®_bits, 0, enable_delay_us, | ||
187 | flags, &clk_sysctrl_gate_ops); | ||
188 | } | ||
189 | |||
190 | struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev, | ||
191 | const char *name, | ||
192 | const char *parent_name, | ||
193 | u16 reg_sel, | ||
194 | u8 reg_mask, | ||
195 | u8 reg_bits, | ||
196 | unsigned long rate, | ||
197 | unsigned long enable_delay_us, | ||
198 | unsigned long flags) | ||
199 | { | ||
200 | const char **parent_names = (parent_name ? &parent_name : NULL); | ||
201 | u8 num_parents = (parent_name ? 1 : 0); | ||
202 | |||
203 | return clk_reg_sysctrl(dev, name, parent_names, num_parents, | ||
204 | ®_sel, ®_mask, ®_bits, | ||
205 | rate, enable_delay_us, flags, | ||
206 | &clk_sysctrl_gate_fixed_rate_ops); | ||
207 | } | ||
208 | |||
209 | struct clk *clk_reg_sysctrl_set_parent(struct device *dev, | ||
210 | const char *name, | ||
211 | const char **parent_names, | ||
212 | u8 num_parents, | ||
213 | u16 *reg_sel, | ||
214 | u8 *reg_mask, | ||
215 | u8 *reg_bits, | ||
216 | unsigned long flags) | ||
217 | { | ||
218 | return clk_reg_sysctrl(dev, name, parent_names, num_parents, | ||
219 | reg_sel, reg_mask, reg_bits, 0, 0, flags, | ||
220 | &clk_sysctrl_set_parent_ops); | ||
221 | } | ||
diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h index c3e449169a83..a2bb92d85ee0 100644 --- a/drivers/clk/ux500/clk.h +++ b/drivers/clk/ux500/clk.h | |||
@@ -11,16 +11,18 @@ | |||
11 | #define __UX500_CLK_H | 11 | #define __UX500_CLK_H |
12 | 12 | ||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/device.h> | ||
15 | #include <linux/types.h> | ||
14 | 16 | ||
15 | struct clk *clk_reg_prcc_pclk(const char *name, | 17 | struct clk *clk_reg_prcc_pclk(const char *name, |
16 | const char *parent_name, | 18 | const char *parent_name, |
17 | unsigned int phy_base, | 19 | resource_size_t phy_base, |
18 | u32 cg_sel, | 20 | u32 cg_sel, |
19 | unsigned long flags); | 21 | unsigned long flags); |
20 | 22 | ||
21 | struct clk *clk_reg_prcc_kclk(const char *name, | 23 | struct clk *clk_reg_prcc_kclk(const char *name, |
22 | const char *parent_name, | 24 | const char *parent_name, |
23 | unsigned int phy_base, | 25 | resource_size_t phy_base, |
24 | u32 cg_sel, | 26 | u32 cg_sel, |
25 | unsigned long flags); | 27 | unsigned long flags); |
26 | 28 | ||
@@ -57,4 +59,32 @@ struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, | |||
57 | unsigned long rate, | 59 | unsigned long rate, |
58 | unsigned long flags); | 60 | unsigned long flags); |
59 | 61 | ||
62 | struct clk *clk_reg_sysctrl_gate(struct device *dev, | ||
63 | const char *name, | ||
64 | const char *parent_name, | ||
65 | u16 reg_sel, | ||
66 | u8 reg_mask, | ||
67 | u8 reg_bits, | ||
68 | unsigned long enable_delay_us, | ||
69 | unsigned long flags); | ||
70 | |||
71 | struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev, | ||
72 | const char *name, | ||
73 | const char *parent_name, | ||
74 | u16 reg_sel, | ||
75 | u8 reg_mask, | ||
76 | u8 reg_bits, | ||
77 | unsigned long rate, | ||
78 | unsigned long enable_delay_us, | ||
79 | unsigned long flags); | ||
80 | |||
81 | struct clk *clk_reg_sysctrl_set_parent(struct device *dev, | ||
82 | const char *name, | ||
83 | const char **parent_names, | ||
84 | u8 num_parents, | ||
85 | u16 *reg_sel, | ||
86 | u8 *reg_mask, | ||
87 | u8 *reg_bits, | ||
88 | unsigned long flags); | ||
89 | |||
60 | #endif /* __UX500_CLK_H */ | 90 | #endif /* __UX500_CLK_H */ |
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index ec3b88fe3e6d..c16ca787170a 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile | |||
@@ -3,5 +3,5 @@ obj-$(CONFIG_ICST) += clk-icst.o | |||
3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o | 3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o |
4 | obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o | 4 | obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o |
5 | obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o | 5 | obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o |
6 | obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o | 6 | obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o clk-sp810.o |
7 | obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o | 7 | obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o |
diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c new file mode 100644 index 000000000000..bf9b15a585e1 --- /dev/null +++ b/drivers/clk/versatile/clk-sp810.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2013 ARM Limited | ||
12 | */ | ||
13 | |||
14 | #include <linux/amba/sp810.h> | ||
15 | #include <linux/clkdev.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #define to_clk_sp810_timerclken(_hw) \ | ||
22 | container_of(_hw, struct clk_sp810_timerclken, hw) | ||
23 | |||
24 | struct clk_sp810; | ||
25 | |||
26 | struct clk_sp810_timerclken { | ||
27 | struct clk_hw hw; | ||
28 | struct clk *clk; | ||
29 | struct clk_sp810 *sp810; | ||
30 | int channel; | ||
31 | }; | ||
32 | |||
33 | struct clk_sp810 { | ||
34 | struct device_node *node; | ||
35 | int refclk_index, timclk_index; | ||
36 | void __iomem *base; | ||
37 | spinlock_t lock; | ||
38 | struct clk_sp810_timerclken timerclken[4]; | ||
39 | struct clk *refclk; | ||
40 | struct clk *timclk; | ||
41 | }; | ||
42 | |||
43 | static u8 clk_sp810_timerclken_get_parent(struct clk_hw *hw) | ||
44 | { | ||
45 | struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw); | ||
46 | u32 val = readl(timerclken->sp810->base + SCCTRL); | ||
47 | |||
48 | return !!(val & (1 << SCCTRL_TIMERENnSEL_SHIFT(timerclken->channel))); | ||
49 | } | ||
50 | |||
51 | static int clk_sp810_timerclken_set_parent(struct clk_hw *hw, u8 index) | ||
52 | { | ||
53 | struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw); | ||
54 | struct clk_sp810 *sp810 = timerclken->sp810; | ||
55 | u32 val, shift = SCCTRL_TIMERENnSEL_SHIFT(timerclken->channel); | ||
56 | unsigned long flags = 0; | ||
57 | |||
58 | if (WARN_ON(index > 1)) | ||
59 | return -EINVAL; | ||
60 | |||
61 | spin_lock_irqsave(&sp810->lock, flags); | ||
62 | |||
63 | val = readl(sp810->base + SCCTRL); | ||
64 | val &= ~(1 << shift); | ||
65 | val |= index << shift; | ||
66 | writel(val, sp810->base + SCCTRL); | ||
67 | |||
68 | spin_unlock_irqrestore(&sp810->lock, flags); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * FIXME - setting the parent every time .prepare is invoked is inefficient. | ||
75 | * This is better handled by a dedicated clock tree configuration mechanism at | ||
76 | * init-time. Revisit this later when such a mechanism exists | ||
77 | */ | ||
78 | static int clk_sp810_timerclken_prepare(struct clk_hw *hw) | ||
79 | { | ||
80 | struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw); | ||
81 | struct clk_sp810 *sp810 = timerclken->sp810; | ||
82 | struct clk *old_parent = __clk_get_parent(hw->clk); | ||
83 | struct clk *new_parent; | ||
84 | |||
85 | if (!sp810->refclk) | ||
86 | sp810->refclk = of_clk_get(sp810->node, sp810->refclk_index); | ||
87 | |||
88 | if (!sp810->timclk) | ||
89 | sp810->timclk = of_clk_get(sp810->node, sp810->timclk_index); | ||
90 | |||
91 | if (WARN_ON(IS_ERR(sp810->refclk) || IS_ERR(sp810->timclk))) | ||
92 | return -ENOENT; | ||
93 | |||
94 | /* Select fastest parent */ | ||
95 | if (clk_get_rate(sp810->refclk) > clk_get_rate(sp810->timclk)) | ||
96 | new_parent = sp810->refclk; | ||
97 | else | ||
98 | new_parent = sp810->timclk; | ||
99 | |||
100 | /* Switch the parent if necessary */ | ||
101 | if (old_parent != new_parent) { | ||
102 | clk_prepare(new_parent); | ||
103 | clk_set_parent(hw->clk, new_parent); | ||
104 | clk_unprepare(old_parent); | ||
105 | } | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void clk_sp810_timerclken_unprepare(struct clk_hw *hw) | ||
111 | { | ||
112 | struct clk_sp810_timerclken *timerclken = to_clk_sp810_timerclken(hw); | ||
113 | struct clk_sp810 *sp810 = timerclken->sp810; | ||
114 | |||
115 | clk_put(sp810->timclk); | ||
116 | clk_put(sp810->refclk); | ||
117 | } | ||
118 | |||
119 | static const struct clk_ops clk_sp810_timerclken_ops = { | ||
120 | .prepare = clk_sp810_timerclken_prepare, | ||
121 | .unprepare = clk_sp810_timerclken_unprepare, | ||
122 | .get_parent = clk_sp810_timerclken_get_parent, | ||
123 | .set_parent = clk_sp810_timerclken_set_parent, | ||
124 | }; | ||
125 | |||
126 | struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec, | ||
127 | void *data) | ||
128 | { | ||
129 | struct clk_sp810 *sp810 = data; | ||
130 | |||
131 | if (WARN_ON(clkspec->args_count != 1 || clkspec->args[0] > | ||
132 | ARRAY_SIZE(sp810->timerclken))) | ||
133 | return NULL; | ||
134 | |||
135 | return sp810->timerclken[clkspec->args[0]].clk; | ||
136 | } | ||
137 | |||
138 | void __init clk_sp810_of_setup(struct device_node *node) | ||
139 | { | ||
140 | struct clk_sp810 *sp810 = kzalloc(sizeof(*sp810), GFP_KERNEL); | ||
141 | const char *parent_names[2]; | ||
142 | char name[12]; | ||
143 | struct clk_init_data init; | ||
144 | int i; | ||
145 | |||
146 | if (!sp810) { | ||
147 | pr_err("Failed to allocate memory for SP810!\n"); | ||
148 | return; | ||
149 | } | ||
150 | |||
151 | sp810->refclk_index = of_property_match_string(node, "clock-names", | ||
152 | "refclk"); | ||
153 | parent_names[0] = of_clk_get_parent_name(node, sp810->refclk_index); | ||
154 | |||
155 | sp810->timclk_index = of_property_match_string(node, "clock-names", | ||
156 | "timclk"); | ||
157 | parent_names[1] = of_clk_get_parent_name(node, sp810->timclk_index); | ||
158 | |||
159 | if (parent_names[0] <= 0 || parent_names[1] <= 0) { | ||
160 | pr_warn("Failed to obtain parent clocks for SP810!\n"); | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | sp810->node = node; | ||
165 | sp810->base = of_iomap(node, 0); | ||
166 | spin_lock_init(&sp810->lock); | ||
167 | |||
168 | init.name = name; | ||
169 | init.ops = &clk_sp810_timerclken_ops; | ||
170 | init.flags = CLK_IS_BASIC; | ||
171 | init.parent_names = parent_names; | ||
172 | init.num_parents = ARRAY_SIZE(parent_names); | ||
173 | |||
174 | for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) { | ||
175 | snprintf(name, ARRAY_SIZE(name), "timerclken%d", i); | ||
176 | |||
177 | sp810->timerclken[i].sp810 = sp810; | ||
178 | sp810->timerclken[i].channel = i; | ||
179 | sp810->timerclken[i].hw.init = &init; | ||
180 | |||
181 | sp810->timerclken[i].clk = clk_register(NULL, | ||
182 | &sp810->timerclken[i].hw); | ||
183 | WARN_ON(IS_ERR(sp810->timerclken[i].clk)); | ||
184 | } | ||
185 | |||
186 | of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810); | ||
187 | } | ||
188 | CLK_OF_DECLARE(sp810, "arm,sp810", clk_sp810_of_setup); | ||
diff --git a/drivers/clk/versatile/clk-vexpress.c b/drivers/clk/versatile/clk-vexpress.c index 82b45aad8ccf..a4a728d05092 100644 --- a/drivers/clk/versatile/clk-vexpress.c +++ b/drivers/clk/versatile/clk-vexpress.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <linux/clkdev.h> | 15 | #include <linux/clkdev.h> |
16 | #include <linux/clk-provider.h> | 16 | #include <linux/clk-provider.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/vexpress.h> | 18 | #include <linux/vexpress.h> |
21 | 19 | ||
22 | static struct clk *vexpress_sp810_timerclken[4]; | 20 | static struct clk *vexpress_sp810_timerclken[4]; |
@@ -86,50 +84,3 @@ void __init vexpress_clk_init(void __iomem *sp810_base) | |||
86 | WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], | 84 | WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], |
87 | "v2m-timer1", "sp804")); | 85 | "v2m-timer1", "sp804")); |
88 | } | 86 | } |
89 | |||
90 | #if defined(CONFIG_OF) | ||
91 | |||
92 | struct clk *vexpress_sp810_of_get(struct of_phandle_args *clkspec, void *data) | ||
93 | { | ||
94 | if (WARN_ON(clkspec->args_count != 1 || clkspec->args[0] > | ||
95 | ARRAY_SIZE(vexpress_sp810_timerclken))) | ||
96 | return NULL; | ||
97 | |||
98 | return vexpress_sp810_timerclken[clkspec->args[0]]; | ||
99 | } | ||
100 | |||
101 | void __init vexpress_clk_of_init(void) | ||
102 | { | ||
103 | struct device_node *node; | ||
104 | struct clk *clk; | ||
105 | struct clk *refclk, *timclk; | ||
106 | |||
107 | of_clk_init(NULL); | ||
108 | |||
109 | node = of_find_compatible_node(NULL, NULL, "arm,sp810"); | ||
110 | vexpress_sp810_init(of_iomap(node, 0)); | ||
111 | of_clk_add_provider(node, vexpress_sp810_of_get, NULL); | ||
112 | |||
113 | /* Select "better" (faster) parent for SP804 timers */ | ||
114 | refclk = of_clk_get_by_name(node, "refclk"); | ||
115 | timclk = of_clk_get_by_name(node, "timclk"); | ||
116 | if (!WARN_ON(IS_ERR(refclk) || IS_ERR(timclk))) { | ||
117 | int i = 0; | ||
118 | |||
119 | if (clk_get_rate(refclk) > clk_get_rate(timclk)) | ||
120 | clk = refclk; | ||
121 | else | ||
122 | clk = timclk; | ||
123 | |||
124 | for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) | ||
125 | WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], | ||
126 | clk)); | ||
127 | } | ||
128 | |||
129 | WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0], | ||
130 | "v2m-timer0", "sp804")); | ||
131 | WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], | ||
132 | "v2m-timer1", "sp804")); | ||
133 | } | ||
134 | |||
135 | #endif | ||
diff --git a/drivers/clocksource/sunxi_timer.c b/drivers/clocksource/sunxi_timer.c index 4086b9167159..0ce85e29769b 100644 --- a/drivers/clocksource/sunxi_timer.c +++ b/drivers/clocksource/sunxi_timer.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/of_address.h> | 23 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
25 | #include <linux/sunxi_timer.h> | 25 | #include <linux/sunxi_timer.h> |
26 | #include <linux/clk-provider.h> | 26 | #include <linux/clk/sunxi.h> |
27 | 27 | ||
28 | #define TIMER_CTL_REG 0x00 | 28 | #define TIMER_CTL_REG 0x00 |
29 | #define TIMER_CTL_ENABLE (1 << 0) | 29 | #define TIMER_CTL_ENABLE (1 << 0) |
@@ -123,7 +123,7 @@ void __init sunxi_timer_init(void) | |||
123 | if (irq <= 0) | 123 | if (irq <= 0) |
124 | panic("Can't parse IRQ"); | 124 | panic("Can't parse IRQ"); |
125 | 125 | ||
126 | of_clk_init(NULL); | 126 | sunxi_init_clocks(); |
127 | 127 | ||
128 | clk = of_clk_get(node, 0); | 128 | clk = of_clk_get(node, 0); |
129 | if (IS_ERR(clk)) | 129 | if (IS_ERR(clk)) |
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h index 9c7f5807824b..dd7adff76e81 100644 --- a/include/linux/clk-private.h +++ b/include/linux/clk-private.h | |||
@@ -152,7 +152,7 @@ struct clk { | |||
152 | }, \ | 152 | }, \ |
153 | .reg = _reg, \ | 153 | .reg = _reg, \ |
154 | .shift = _shift, \ | 154 | .shift = _shift, \ |
155 | .width = _width, \ | 155 | .mask = BIT(_width) - 1, \ |
156 | .flags = _mux_flags, \ | 156 | .flags = _mux_flags, \ |
157 | .lock = _lock, \ | 157 | .lock = _lock, \ |
158 | }; \ | 158 | }; \ |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7f197d7addb0..11860985fecb 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -45,6 +45,14 @@ struct clk_hw; | |||
45 | * undo any work done in the @prepare callback. Called with | 45 | * undo any work done in the @prepare callback. Called with |
46 | * prepare_lock held. | 46 | * prepare_lock held. |
47 | * | 47 | * |
48 | * @is_prepared: Queries the hardware to determine if the clock is prepared. | ||
49 | * This function is allowed to sleep. Optional, if this op is not | ||
50 | * set then the prepare count will be used. | ||
51 | * | ||
52 | * @unprepare_unused: Unprepare the clock atomically. Only called from | ||
53 | * clk_disable_unused for prepare clocks with special needs. | ||
54 | * Called with prepare mutex held. This function may sleep. | ||
55 | * | ||
48 | * @enable: Enable the clock atomically. This must not return until the | 56 | * @enable: Enable the clock atomically. This must not return until the |
49 | * clock is generating a valid clock signal, usable by consumer | 57 | * clock is generating a valid clock signal, usable by consumer |
50 | * devices. Called with enable_lock held. This function must not | 58 | * devices. Called with enable_lock held. This function must not |
@@ -108,6 +116,8 @@ struct clk_hw; | |||
108 | struct clk_ops { | 116 | struct clk_ops { |
109 | int (*prepare)(struct clk_hw *hw); | 117 | int (*prepare)(struct clk_hw *hw); |
110 | void (*unprepare)(struct clk_hw *hw); | 118 | void (*unprepare)(struct clk_hw *hw); |
119 | int (*is_prepared)(struct clk_hw *hw); | ||
120 | void (*unprepare_unused)(struct clk_hw *hw); | ||
111 | int (*enable)(struct clk_hw *hw); | 121 | int (*enable)(struct clk_hw *hw); |
112 | void (*disable)(struct clk_hw *hw); | 122 | void (*disable)(struct clk_hw *hw); |
113 | int (*is_enabled)(struct clk_hw *hw); | 123 | int (*is_enabled)(struct clk_hw *hw); |
@@ -239,9 +249,14 @@ struct clk_div_table { | |||
239 | * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the | 249 | * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the |
240 | * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is | 250 | * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is |
241 | * the raw value read from the register, with the value of zero considered | 251 | * the raw value read from the register, with the value of zero considered |
242 | * invalid | 252 | * invalid, unless CLK_DIVIDER_ALLOW_ZERO is set. |
243 | * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from | 253 | * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from |
244 | * the hardware register | 254 | * the hardware register |
255 | * CLK_DIVIDER_ALLOW_ZERO - Allow zero divisors. For dividers which have | ||
256 | * CLK_DIVIDER_ONE_BASED set, it is possible to end up with a zero divisor. | ||
257 | * Some hardware implementations gracefully handle this case and allow a | ||
258 | * zero divisor by not modifying their input clock | ||
259 | * (divide by one / bypass). | ||
245 | */ | 260 | */ |
246 | struct clk_divider { | 261 | struct clk_divider { |
247 | struct clk_hw hw; | 262 | struct clk_hw hw; |
@@ -255,6 +270,7 @@ struct clk_divider { | |||
255 | 270 | ||
256 | #define CLK_DIVIDER_ONE_BASED BIT(0) | 271 | #define CLK_DIVIDER_ONE_BASED BIT(0) |
257 | #define CLK_DIVIDER_POWER_OF_TWO BIT(1) | 272 | #define CLK_DIVIDER_POWER_OF_TWO BIT(1) |
273 | #define CLK_DIVIDER_ALLOW_ZERO BIT(2) | ||
258 | 274 | ||
259 | extern const struct clk_ops clk_divider_ops; | 275 | extern const struct clk_ops clk_divider_ops; |
260 | struct clk *clk_register_divider(struct device *dev, const char *name, | 276 | struct clk *clk_register_divider(struct device *dev, const char *name, |
@@ -274,7 +290,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, | |||
274 | * @reg: register controlling multiplexer | 290 | * @reg: register controlling multiplexer |
275 | * @shift: shift to multiplexer bit field | 291 | * @shift: shift to multiplexer bit field |
276 | * @width: width of mutliplexer bit field | 292 | * @width: width of mutliplexer bit field |
277 | * @num_clks: number of parent clocks | 293 | * @flags: hardware-specific flags |
278 | * @lock: register lock | 294 | * @lock: register lock |
279 | * | 295 | * |
280 | * Clock with multiple selectable parents. Implements .get_parent, .set_parent | 296 | * Clock with multiple selectable parents. Implements .get_parent, .set_parent |
@@ -287,8 +303,9 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name, | |||
287 | struct clk_mux { | 303 | struct clk_mux { |
288 | struct clk_hw hw; | 304 | struct clk_hw hw; |
289 | void __iomem *reg; | 305 | void __iomem *reg; |
306 | u32 *table; | ||
307 | u32 mask; | ||
290 | u8 shift; | 308 | u8 shift; |
291 | u8 width; | ||
292 | u8 flags; | 309 | u8 flags; |
293 | spinlock_t *lock; | 310 | spinlock_t *lock; |
294 | }; | 311 | }; |
@@ -297,11 +314,19 @@ struct clk_mux { | |||
297 | #define CLK_MUX_INDEX_BIT BIT(1) | 314 | #define CLK_MUX_INDEX_BIT BIT(1) |
298 | 315 | ||
299 | extern const struct clk_ops clk_mux_ops; | 316 | extern const struct clk_ops clk_mux_ops; |
317 | |||
300 | struct clk *clk_register_mux(struct device *dev, const char *name, | 318 | struct clk *clk_register_mux(struct device *dev, const char *name, |
301 | const char **parent_names, u8 num_parents, unsigned long flags, | 319 | const char **parent_names, u8 num_parents, unsigned long flags, |
302 | void __iomem *reg, u8 shift, u8 width, | 320 | void __iomem *reg, u8 shift, u8 width, |
303 | u8 clk_mux_flags, spinlock_t *lock); | 321 | u8 clk_mux_flags, spinlock_t *lock); |
304 | 322 | ||
323 | struct clk *clk_register_mux_table(struct device *dev, const char *name, | ||
324 | const char **parent_names, u8 num_parents, unsigned long flags, | ||
325 | void __iomem *reg, u8 shift, u32 mask, | ||
326 | u8 clk_mux_flags, u32 *table, spinlock_t *lock); | ||
327 | |||
328 | void of_fixed_factor_clk_setup(struct device_node *node); | ||
329 | |||
305 | /** | 330 | /** |
306 | * struct clk_fixed_factor - fixed multiplier and divider clock | 331 | * struct clk_fixed_factor - fixed multiplier and divider clock |
307 | * | 332 | * |
@@ -325,6 +350,37 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, | |||
325 | const char *parent_name, unsigned long flags, | 350 | const char *parent_name, unsigned long flags, |
326 | unsigned int mult, unsigned int div); | 351 | unsigned int mult, unsigned int div); |
327 | 352 | ||
353 | /*** | ||
354 | * struct clk_composite - aggregate clock of mux, divider and gate clocks | ||
355 | * | ||
356 | * @hw: handle between common and hardware-specific interfaces | ||
357 | * @mux_hw: handle between composite and hardware-specific mux clock | ||
358 | * @rate_hw: handle between composite and hardware-specific rate clock | ||
359 | * @gate_hw: handle between composite and hardware-specific gate clock | ||
360 | * @mux_ops: clock ops for mux | ||
361 | * @rate_ops: clock ops for rate | ||
362 | * @gate_ops: clock ops for gate | ||
363 | */ | ||
364 | struct clk_composite { | ||
365 | struct clk_hw hw; | ||
366 | struct clk_ops ops; | ||
367 | |||
368 | struct clk_hw *mux_hw; | ||
369 | struct clk_hw *rate_hw; | ||
370 | struct clk_hw *gate_hw; | ||
371 | |||
372 | const struct clk_ops *mux_ops; | ||
373 | const struct clk_ops *rate_ops; | ||
374 | const struct clk_ops *gate_ops; | ||
375 | }; | ||
376 | |||
377 | struct clk *clk_register_composite(struct device *dev, const char *name, | ||
378 | const char **parent_names, int num_parents, | ||
379 | struct clk_hw *mux_hw, const struct clk_ops *mux_ops, | ||
380 | struct clk_hw *rate_hw, const struct clk_ops *rate_ops, | ||
381 | struct clk_hw *gate_hw, const struct clk_ops *gate_ops, | ||
382 | unsigned long flags); | ||
383 | |||
328 | /** | 384 | /** |
329 | * clk_register - allocate a new clock, register it and return an opaque cookie | 385 | * clk_register - allocate a new clock, register it and return an opaque cookie |
330 | * @dev: device that is registering this clock | 386 | * @dev: device that is registering this clock |
@@ -351,6 +407,7 @@ unsigned int __clk_get_enable_count(struct clk *clk); | |||
351 | unsigned int __clk_get_prepare_count(struct clk *clk); | 407 | unsigned int __clk_get_prepare_count(struct clk *clk); |
352 | unsigned long __clk_get_rate(struct clk *clk); | 408 | unsigned long __clk_get_rate(struct clk *clk); |
353 | unsigned long __clk_get_flags(struct clk *clk); | 409 | unsigned long __clk_get_flags(struct clk *clk); |
410 | bool __clk_is_prepared(struct clk *clk); | ||
354 | bool __clk_is_enabled(struct clk *clk); | 411 | bool __clk_is_enabled(struct clk *clk); |
355 | struct clk *__clk_lookup(const char *name); | 412 | struct clk *__clk_lookup(const char *name); |
356 | 413 | ||
diff --git a/include/linux/clk.h b/include/linux/clk.h index b3ac22d0fc1f..9a6d04524b1a 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h | |||
@@ -28,16 +28,16 @@ struct clk; | |||
28 | * PRE_RATE_CHANGE - called immediately before the clk rate is changed, | 28 | * PRE_RATE_CHANGE - called immediately before the clk rate is changed, |
29 | * to indicate that the rate change will proceed. Drivers must | 29 | * to indicate that the rate change will proceed. Drivers must |
30 | * immediately terminate any operations that will be affected by the | 30 | * immediately terminate any operations that will be affected by the |
31 | * rate change. Callbacks may either return NOTIFY_DONE or | 31 | * rate change. Callbacks may either return NOTIFY_DONE, NOTIFY_OK, |
32 | * NOTIFY_STOP. | 32 | * NOTIFY_STOP or NOTIFY_BAD. |
33 | * | 33 | * |
34 | * ABORT_RATE_CHANGE: called if the rate change failed for some reason | 34 | * ABORT_RATE_CHANGE: called if the rate change failed for some reason |
35 | * after PRE_RATE_CHANGE. In this case, all registered notifiers on | 35 | * after PRE_RATE_CHANGE. In this case, all registered notifiers on |
36 | * the clk will be called with ABORT_RATE_CHANGE. Callbacks must | 36 | * the clk will be called with ABORT_RATE_CHANGE. Callbacks must |
37 | * always return NOTIFY_DONE. | 37 | * always return NOTIFY_DONE or NOTIFY_OK. |
38 | * | 38 | * |
39 | * POST_RATE_CHANGE - called after the clk rate change has successfully | 39 | * POST_RATE_CHANGE - called after the clk rate change has successfully |
40 | * completed. Callbacks must always return NOTIFY_DONE. | 40 | * completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK. |
41 | * | 41 | * |
42 | */ | 42 | */ |
43 | #define PRE_RATE_CHANGE BIT(0) | 43 | #define PRE_RATE_CHANGE BIT(0) |
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h new file mode 100644 index 000000000000..e074fdd5a236 --- /dev/null +++ b/include/linux/clk/sunxi.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Maxime Ripard | ||
3 | * | ||
4 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef __LINUX_CLK_SUNXI_H_ | ||
18 | #define __LINUX_CLK_SUNXI_H_ | ||
19 | |||
20 | void __init sunxi_init_clocks(void); | ||
21 | |||
22 | #endif | ||
diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h new file mode 100644 index 000000000000..92dabcaf6499 --- /dev/null +++ b/include/linux/platform_data/si5351.h | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * Si5351A/B/C programmable clock generator platform_data. | ||
3 | */ | ||
4 | |||
5 | #ifndef __LINUX_PLATFORM_DATA_SI5351_H__ | ||
6 | #define __LINUX_PLATFORM_DATA_SI5351_H__ | ||
7 | |||
8 | struct clk; | ||
9 | |||
10 | /** | ||
11 | * enum si5351_variant - SiLabs Si5351 chip variant | ||
12 | * @SI5351_VARIANT_A: Si5351A (8 output clocks, XTAL input) | ||
13 | * @SI5351_VARIANT_A3: Si5351A MSOP10 (3 output clocks, XTAL input) | ||
14 | * @SI5351_VARIANT_B: Si5351B (8 output clocks, XTAL/VXCO input) | ||
15 | * @SI5351_VARIANT_C: Si5351C (8 output clocks, XTAL/CLKIN input) | ||
16 | */ | ||
17 | enum si5351_variant { | ||
18 | SI5351_VARIANT_A = 1, | ||
19 | SI5351_VARIANT_A3 = 2, | ||
20 | SI5351_VARIANT_B = 3, | ||
21 | SI5351_VARIANT_C = 4, | ||
22 | }; | ||
23 | |||
24 | /** | ||
25 | * enum si5351_pll_src - Si5351 pll clock source | ||
26 | * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config | ||
27 | * @SI5351_PLL_SRC_XTAL: pll source clock is XTAL input | ||
28 | * @SI5351_PLL_SRC_CLKIN: pll source clock is CLKIN input (Si5351C only) | ||
29 | */ | ||
30 | enum si5351_pll_src { | ||
31 | SI5351_PLL_SRC_DEFAULT = 0, | ||
32 | SI5351_PLL_SRC_XTAL = 1, | ||
33 | SI5351_PLL_SRC_CLKIN = 2, | ||
34 | }; | ||
35 | |||
36 | /** | ||
37 | * enum si5351_multisynth_src - Si5351 multisynth clock source | ||
38 | * @SI5351_MULTISYNTH_SRC_DEFAULT: default, do not change eeprom config | ||
39 | * @SI5351_MULTISYNTH_SRC_VCO0: multisynth source clock is VCO0 | ||
40 | * @SI5351_MULTISYNTH_SRC_VCO1: multisynth source clock is VCO1/VXCO | ||
41 | */ | ||
42 | enum si5351_multisynth_src { | ||
43 | SI5351_MULTISYNTH_SRC_DEFAULT = 0, | ||
44 | SI5351_MULTISYNTH_SRC_VCO0 = 1, | ||
45 | SI5351_MULTISYNTH_SRC_VCO1 = 2, | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * enum si5351_clkout_src - Si5351 clock output clock source | ||
50 | * @SI5351_CLKOUT_SRC_DEFAULT: default, do not change eeprom config | ||
51 | * @SI5351_CLKOUT_SRC_MSYNTH_N: clkout N source clock is multisynth N | ||
52 | * @SI5351_CLKOUT_SRC_MSYNTH_0_4: clkout N source clock is multisynth 0 (N<4) | ||
53 | * or 4 (N>=4) | ||
54 | * @SI5351_CLKOUT_SRC_XTAL: clkout N source clock is XTAL | ||
55 | * @SI5351_CLKOUT_SRC_CLKIN: clkout N source clock is CLKIN (Si5351C only) | ||
56 | */ | ||
57 | enum si5351_clkout_src { | ||
58 | SI5351_CLKOUT_SRC_DEFAULT = 0, | ||
59 | SI5351_CLKOUT_SRC_MSYNTH_N = 1, | ||
60 | SI5351_CLKOUT_SRC_MSYNTH_0_4 = 2, | ||
61 | SI5351_CLKOUT_SRC_XTAL = 3, | ||
62 | SI5351_CLKOUT_SRC_CLKIN = 4, | ||
63 | }; | ||
64 | |||
65 | /** | ||
66 | * enum si5351_drive_strength - Si5351 clock output drive strength | ||
67 | * @SI5351_DRIVE_DEFAULT: default, do not change eeprom config | ||
68 | * @SI5351_DRIVE_2MA: 2mA clock output drive strength | ||
69 | * @SI5351_DRIVE_4MA: 4mA clock output drive strength | ||
70 | * @SI5351_DRIVE_6MA: 6mA clock output drive strength | ||
71 | * @SI5351_DRIVE_8MA: 8mA clock output drive strength | ||
72 | */ | ||
73 | enum si5351_drive_strength { | ||
74 | SI5351_DRIVE_DEFAULT = 0, | ||
75 | SI5351_DRIVE_2MA = 2, | ||
76 | SI5351_DRIVE_4MA = 4, | ||
77 | SI5351_DRIVE_6MA = 6, | ||
78 | SI5351_DRIVE_8MA = 8, | ||
79 | }; | ||
80 | |||
81 | /** | ||
82 | * struct si5351_clkout_config - Si5351 clock output configuration | ||
83 | * @clkout: clkout number | ||
84 | * @multisynth_src: multisynth source clock | ||
85 | * @clkout_src: clkout source clock | ||
86 | * @pll_master: if true, clkout can also change pll rate | ||
87 | * @drive: output drive strength | ||
88 | * @rate: initial clkout rate, or default if 0 | ||
89 | */ | ||
90 | struct si5351_clkout_config { | ||
91 | enum si5351_multisynth_src multisynth_src; | ||
92 | enum si5351_clkout_src clkout_src; | ||
93 | enum si5351_drive_strength drive; | ||
94 | bool pll_master; | ||
95 | unsigned long rate; | ||
96 | }; | ||
97 | |||
98 | /** | ||
99 | * struct si5351_platform_data - Platform data for the Si5351 clock driver | ||
100 | * @variant: Si5351 chip variant | ||
101 | * @clk_xtal: xtal input clock | ||
102 | * @clk_clkin: clkin input clock | ||
103 | * @pll_src: array of pll source clock setting | ||
104 | * @clkout: array of clkout configuration | ||
105 | */ | ||
106 | struct si5351_platform_data { | ||
107 | enum si5351_variant variant; | ||
108 | struct clk *clk_xtal; | ||
109 | struct clk *clk_clkin; | ||
110 | enum si5351_pll_src pll_src[2]; | ||
111 | struct si5351_clkout_config clkout[8]; | ||
112 | }; | ||
113 | |||
114 | #endif | ||