diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-05 15:59:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-05 15:59:36 -0500 |
commit | f66477a0aeb77f97a7de5f791700dadc42f3f792 (patch) | |
tree | 0a49febcf211c33948be618860eb3d545b7c6608 | |
parent | 400c5bd5a5b1faf3089322ace58b974446a8ddc3 (diff) | |
parent | e5bf1991ea62b4f4fc906d0828f7eed988fc3835 (diff) |
Merge tag 'clk-for-linus-20151104' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd:
"The majority of the changes are driver updates and new device support.
The core framework is mostly unchanged this time around, with only a
couple patches to expose a clk provider API and make getting clk
parent names from DT more robust.
Driver updates:
- Support for clock controllers found on Broadcom Northstar SoCs and
bcm2835 SoC
- Support for Allwinner audio clocks
- A few cleanup patches for Tegra drivers and support for the highest
DFLL frequencies on Tegra124
- Samsung exynos7 fixes and improvements
- i.Mx SoC updates to add a few missing clocks and keep debug uart
clocks on during kernel intialization
- Some mediatek cleanups and support for more subsystem clocks
- Support for msm8916 gpu/audio clocks and qcom's GDSC power domain
controllers
- A new driver for the Silabs si514 clock chip"
* tag 'clk-for-linus-20151104' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (143 commits)
clk: qcom: msm8960: Fix dsi1/2 halt bits
clk: lpc18xx-cgu: fix potential system hang when disabling unused clocks
clk: lpc18xx-ccu: fix potential system hang when disabling unused clocks
clk: Add clk_hw_is_enabled() for use by clk providers
clk: Add stubs for of_clk_*() APIs when CONFIG_OF=n
clk: versatile-icst: fix memory leak
clk: Remove clk_{register,unregister}_multiplier()
clk: iproc: define Broadcom NS2 iProc clock binding
clk: iproc: define Broadcom NSP iProc clock binding
clk: ns2: add clock support for Broadcom Northstar 2 SoC
clk: iproc: Separate status and control variables
clk: iproc: Split off dig_filter
clk: iproc: Add PLL base write function
clk: nsp: add clock support for Broadcom Northstar Plus SoC
clk: iproc: Add PWRCTRL support
clk: cygnus: Convert all macros to all caps
ARM: cygnus: fix link failures when CONFIG_COMMON_CLK_IPROC is disabled
clk: imx31: add missing of_node_put
clk: imx27: add missing of_node_put
clk: si5351: add missing of_node_put
...
144 files changed, 8452 insertions, 1030 deletions
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt new file mode 100644 index 000000000000..b1f2ce17dff8 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Mediatek imgsys controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek imgsys controller provides various clocks to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8173-imgsys", "syscon" | ||
10 | - #clock-cells: Must be 1 | ||
11 | |||
12 | The imgsys controller uses the common clk binding from | ||
13 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
14 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | imgsys: clock-controller@15000000 { | ||
19 | compatible = "mediatek,mt8173-imgsys", "syscon"; | ||
20 | reg = <0 0x15000000 0 0x1000>; | ||
21 | #clock-cells = <1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt new file mode 100644 index 000000000000..4385946eadef --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Mediatek mmsys controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek mmsys controller provides various clocks to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8173-mmsys", "syscon" | ||
10 | - #clock-cells: Must be 1 | ||
11 | |||
12 | The mmsys controller uses the common clk binding from | ||
13 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
14 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | mmsys: clock-controller@14000000 { | ||
19 | compatible = "mediatek,mt8173-mmsys", "syscon"; | ||
20 | reg = <0 0x14000000 0 0x1000>; | ||
21 | #clock-cells = <1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt new file mode 100644 index 000000000000..1faacf1c1b25 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Mediatek vdecsys controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek vdecsys controller provides various clocks to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8173-vdecsys", "syscon" | ||
10 | - #clock-cells: Must be 1 | ||
11 | |||
12 | The vdecsys controller uses the common clk binding from | ||
13 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
14 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | vdecsys: clock-controller@16000000 { | ||
19 | compatible = "mediatek,mt8173-vdecsys", "syscon"; | ||
20 | reg = <0 0x16000000 0 0x1000>; | ||
21 | #clock-cells = <1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt new file mode 100644 index 000000000000..3cc299fd7857 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Mediatek vencltsys controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek vencltsys controller provides various clocks to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8173-vencltsys", "syscon" | ||
10 | - #clock-cells: Must be 1 | ||
11 | |||
12 | The vencltsys controller uses the common clk binding from | ||
13 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
14 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | vencltsys: clock-controller@19000000 { | ||
19 | compatible = "mediatek,mt8173-vencltsys", "syscon"; | ||
20 | reg = <0 0x19000000 0 0x1000>; | ||
21 | #clock-cells = <1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt new file mode 100644 index 000000000000..5bb2866a2b50 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | Mediatek vencsys controller | ||
2 | ============================ | ||
3 | |||
4 | The Mediatek vencsys controller provides various clocks to the system. | ||
5 | |||
6 | Required Properties: | ||
7 | |||
8 | - compatible: Should be: | ||
9 | - "mediatek,mt8173-vencsys", "syscon" | ||
10 | - #clock-cells: Must be 1 | ||
11 | |||
12 | The vencsys controller uses the common clk binding from | ||
13 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
14 | The available clocks are defined in dt-bindings/clock/mt*-clk.h. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | vencsys: clock-controller@18000000 { | ||
19 | compatible = "mediatek,mt8173-vencsys", "syscon"; | ||
20 | reg = <0 0x18000000 0 0x1000>; | ||
21 | #clock-cells = <1>; | ||
22 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index 5ba6450693b9..181bc8ac4e3a 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt | |||
@@ -77,6 +77,9 @@ Required properties: | |||
77 | "atmel,sama5d4-clk-h32mx": | 77 | "atmel,sama5d4-clk-h32mx": |
78 | at91 h32mx clock | 78 | at91 h32mx clock |
79 | 79 | ||
80 | "atmel,sama5d2-clk-generated": | ||
81 | at91 generated clock | ||
82 | |||
80 | Required properties for SCKC node: | 83 | Required properties for SCKC node: |
81 | - reg : defines the IO memory reserved for the SCKC. | 84 | - reg : defines the IO memory reserved for the SCKC. |
82 | - #size-cells : shall be 0 (reg is used to encode clk id). | 85 | - #size-cells : shall be 0 (reg is used to encode clk id). |
@@ -461,3 +464,35 @@ For example: | |||
461 | compatible = "atmel,sama5d4-clk-h32mx"; | 464 | compatible = "atmel,sama5d4-clk-h32mx"; |
462 | clocks = <&mck>; | 465 | clocks = <&mck>; |
463 | }; | 466 | }; |
467 | |||
468 | Required properties for generated clocks: | ||
469 | - #size-cells : shall be 0 (reg is used to encode clk id). | ||
470 | - #address-cells : shall be 1 (reg is used to encode clk id). | ||
471 | - clocks : shall be the generated clock source phandles. | ||
472 | e.g. clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>; | ||
473 | - name: device tree node describing a specific generated clock. | ||
474 | * #clock-cells : from common clock binding; shall be set to 0. | ||
475 | * reg: peripheral id. See Atmel's datasheets to get a full | ||
476 | list of peripheral ids. | ||
477 | * atmel,clk-output-range : minimum and maximum clock frequency | ||
478 | (two u32 fields). | ||
479 | |||
480 | For example: | ||
481 | gck { | ||
482 | compatible = "atmel,sama5d2-clk-generated"; | ||
483 | #address-cells = <1>; | ||
484 | #size-cells = <0>; | ||
485 | clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>; | ||
486 | |||
487 | tcb0_gclk: tcb0_gclk { | ||
488 | #clock-cells = <0>; | ||
489 | reg = <35>; | ||
490 | atmel,clk-output-range = <0 83000000>; | ||
491 | }; | ||
492 | |||
493 | pwm_gclk: pwm_gclk { | ||
494 | #clock-cells = <0>; | ||
495 | reg = <38>; | ||
496 | atmel,clk-output-range = <0 83000000>; | ||
497 | }; | ||
498 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt new file mode 100644 index 000000000000..e56a1df3a9d3 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | Broadcom BCM2835 CPRMAN clocks | ||
2 | |||
3 | This binding uses the common clock binding: | ||
4 | Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
5 | |||
6 | The CPRMAN clock controller generates clocks in the audio power domain | ||
7 | of the BCM2835. There is a level of PLLs deriving from an external | ||
8 | oscillator, a level of PLL dividers that produce channels off of the | ||
9 | few PLLs, and a level of mostly-generic clock generators sourcing from | ||
10 | the PLL channels. Most other hardware components source from the | ||
11 | clock generators, but a few (like the ARM or HDMI) will source from | ||
12 | the PLL dividers directly. | ||
13 | |||
14 | Required properties: | ||
15 | - compatible: Should be "brcm,bcm2835-cprman" | ||
16 | - #clock-cells: Should be <1>. The permitted clock-specifier values can be | ||
17 | found in include/dt-bindings/clock/bcm2835.h | ||
18 | - reg: Specifies base physical address and size of the registers | ||
19 | - clocks: The external oscillator clock phandle | ||
20 | |||
21 | Example: | ||
22 | |||
23 | clk_osc: clock@3 { | ||
24 | compatible = "fixed-clock"; | ||
25 | reg = <3>; | ||
26 | #clock-cells = <0>; | ||
27 | clock-output-names = "osc"; | ||
28 | clock-frequency = <19200000>; | ||
29 | }; | ||
30 | |||
31 | clocks: cprman@7e101000 { | ||
32 | compatible = "brcm,bcm2835-cprman"; | ||
33 | #clock-cells = <1>; | ||
34 | reg = <0x7e101000 0x2000>; | ||
35 | clocks = <&clk_osc>; | ||
36 | }; | ||
37 | |||
38 | i2c0: i2c@7e205000 { | ||
39 | compatible = "brcm,bcm2835-i2c"; | ||
40 | reg = <0x7e205000 0x1000>; | ||
41 | interrupts = <2 21>; | ||
42 | clocks = <&clocks BCM2835_CLOCK_VPU>; | ||
43 | #address-cells = <1>; | ||
44 | #size-cells = <0>; | ||
45 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt index da8d9bb5751c..ede65a55e21b 100644 --- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt +++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt | |||
@@ -130,3 +130,81 @@ These clock IDs are defined in: | |||
130 | ch3_unused mipipll 4 BCM_CYGNUS_MIPIPLL_CH3_UNUSED | 130 | ch3_unused mipipll 4 BCM_CYGNUS_MIPIPLL_CH3_UNUSED |
131 | ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED | 131 | ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED |
132 | ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED | 132 | ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED |
133 | |||
134 | Northstar and Northstar Plus | ||
135 | ------ | ||
136 | PLL and leaf clock compatible strings for Northstar and Northstar Plus are: | ||
137 | "brcm,nsp-armpll" | ||
138 | "brcm,nsp-genpll" | ||
139 | "brcm,nsp-lcpll0" | ||
140 | |||
141 | The following table defines the set of PLL/clock index and ID for Northstar and | ||
142 | Northstar Plus. These clock IDs are defined in: | ||
143 | "include/dt-bindings/clock/bcm-nsp.h" | ||
144 | |||
145 | Clock Source Index ID | ||
146 | --- ----- ----- --------- | ||
147 | crystal N/A N/A N/A | ||
148 | |||
149 | armpll crystal N/A N/A | ||
150 | |||
151 | genpll crystal 0 BCM_NSP_GENPLL | ||
152 | phy genpll 1 BCM_NSP_GENPLL_PHY_CLK | ||
153 | ethernetclk genpll 2 BCM_NSP_GENPLL_ENET_SW_CLK | ||
154 | usbclk genpll 3 BCM_NSP_GENPLL_USB_PHY_REF_CLK | ||
155 | iprocfast genpll 4 BCM_NSP_GENPLL_IPROCFAST_CLK | ||
156 | sata1 genpll 5 BCM_NSP_GENPLL_SATA1_CLK | ||
157 | sata2 genpll 6 BCM_NSP_GENPLL_SATA2_CLK | ||
158 | |||
159 | lcpll0 crystal 0 BCM_NSP_LCPLL0 | ||
160 | pcie_phy lcpll0 1 BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK | ||
161 | sdio lcpll0 2 BCM_NSP_LCPLL0_SDIO_CLK | ||
162 | ddr_phy lcpll0 3 BCM_NSP_LCPLL0_DDR_PHY_CLK | ||
163 | |||
164 | Northstar 2 | ||
165 | ----------- | ||
166 | PLL and leaf clock compatible strings for Northstar 2 are: | ||
167 | "brcm,ns2-genpll-scr" | ||
168 | "brcm,ns2-genpll-sw" | ||
169 | "brcm,ns2-lcpll-ddr" | ||
170 | "brcm,ns2-lcpll-ports" | ||
171 | |||
172 | The following table defines the set of PLL/clock index and ID for Northstar 2. | ||
173 | These clock IDs are defined in: | ||
174 | "include/dt-bindings/clock/bcm-ns2.h" | ||
175 | |||
176 | Clock Source Index ID | ||
177 | --- ----- ----- --------- | ||
178 | crystal N/A N/A N/A | ||
179 | |||
180 | genpll_scr crystal 0 BCM_NS2_GENPLL_SCR | ||
181 | scr genpll_scr 1 BCM_NS2_GENPLL_SCR_SCR_CLK | ||
182 | fs genpll_scr 2 BCM_NS2_GENPLL_SCR_FS_CLK | ||
183 | audio_ref genpll_scr 3 BCM_NS2_GENPLL_SCR_AUDIO_CLK | ||
184 | ch3_unused genpll_scr 4 BCM_NS2_GENPLL_SCR_CH3_UNUSED | ||
185 | ch4_unused genpll_scr 5 BCM_NS2_GENPLL_SCR_CH4_UNUSED | ||
186 | ch5_unused genpll_scr 6 BCM_NS2_GENPLL_SCR_CH5_UNUSED | ||
187 | |||
188 | genpll_sw crystal 0 BCM_NS2_GENPLL_SW | ||
189 | rpe genpll_sw 1 BCM_NS2_GENPLL_SW_RPE_CLK | ||
190 | 250 genpll_sw 2 BCM_NS2_GENPLL_SW_250_CLK | ||
191 | nic genpll_sw 3 BCM_NS2_GENPLL_SW_NIC_CLK | ||
192 | chimp genpll_sw 4 BCM_NS2_GENPLL_SW_CHIMP_CLK | ||
193 | port genpll_sw 5 BCM_NS2_GENPLL_SW_PORT_CLK | ||
194 | sdio genpll_sw 6 BCM_NS2_GENPLL_SW_SDIO_CLK | ||
195 | |||
196 | lcpll_ddr crystal 0 BCM_NS2_LCPLL_DDR | ||
197 | pcie_sata_usb lcpll_ddr 1 BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK | ||
198 | ddr lcpll_ddr 2 BCM_NS2_LCPLL_DDR_DDR_CLK | ||
199 | ch2_unused lcpll_ddr 3 BCM_NS2_LCPLL_DDR_CH2_UNUSED | ||
200 | ch3_unused lcpll_ddr 4 BCM_NS2_LCPLL_DDR_CH3_UNUSED | ||
201 | ch4_unused lcpll_ddr 5 BCM_NS2_LCPLL_DDR_CH4_UNUSED | ||
202 | ch5_unused lcpll_ddr 6 BCM_NS2_LCPLL_DDR_CH5_UNUSED | ||
203 | |||
204 | lcpll_ports crystal 0 BCM_NS2_LCPLL_PORTS | ||
205 | wan lcpll_ports 1 BCM_NS2_LCPLL_PORTS_WAN_CLK | ||
206 | rgmii lcpll_ports 2 BCM_NS2_LCPLL_PORTS_RGMII_CLK | ||
207 | ch2_unused lcpll_ports 3 BCM_NS2_LCPLL_PORTS_CH2_UNUSED | ||
208 | ch3_unused lcpll_ports 4 BCM_NS2_LCPLL_PORTS_CH3_UNUSED | ||
209 | ch4_unused lcpll_ports 5 BCM_NS2_LCPLL_PORTS_CH4_UNUSED | ||
210 | ch5_unused lcpll_ports 6 BCM_NS2_LCPLL_PORTS_CH5_UNUSED | ||
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt index 5ddb68418655..38dcf0370143 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-div6-clocks.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | * Renesas CPG DIV6 Clock | 1 | * Renesas CPG DIV6 Clock |
2 | 2 | ||
3 | The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse | 3 | The CPG DIV6 clocks are variable factor clocks provided by the Clock Pulse |
4 | Generator (CPG). They clock input is divided by a configurable factor from 1 | 4 | Generator (CPG). Their clock input is divided by a configurable factor from 1 |
5 | to 64. | 5 | to 64. |
6 | 6 | ||
7 | Required Properties: | 7 | Required Properties: |
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt new file mode 100644 index 000000000000..59297d34b208 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt | |||
@@ -0,0 +1,69 @@ | |||
1 | * Renesas Clock Pulse Generator / Module Standby and Software Reset | ||
2 | |||
3 | On Renesas ARM SoCs (SH/R-Mobile, R-Car, RZ), the CPG (Clock Pulse Generator) | ||
4 | and MSSR (Module Standby and Software Reset) blocks are intimately connected, | ||
5 | and share the same register block. | ||
6 | |||
7 | They provide the following functionalities: | ||
8 | - The CPG block generates various core clocks, | ||
9 | - The MSSR block provides two functions: | ||
10 | 1. Module Standby, providing a Clock Domain to control the clock supply | ||
11 | to individual SoC devices, | ||
12 | 2. Reset Control, to perform a software reset of individual SoC devices. | ||
13 | |||
14 | Required Properties: | ||
15 | - compatible: Must be one of: | ||
16 | - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC | ||
17 | |||
18 | - reg: Base address and length of the memory resource used by the CPG/MSSR | ||
19 | block | ||
20 | |||
21 | - clocks: References to external parent clocks, one entry for each entry in | ||
22 | clock-names | ||
23 | - clock-names: List of external parent clock names. Valid names are: | ||
24 | - "extal" (r8a7795) | ||
25 | - "extalr" (r8a7795) | ||
26 | |||
27 | - #clock-cells: Must be 2 | ||
28 | - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" | ||
29 | and a core clock reference, as defined in | ||
30 | <dt-bindings/clock/*-cpg-mssr.h>. | ||
31 | - For module clocks, the two clock specifier cells must be "CPG_MOD" and | ||
32 | a module number, as defined in the datasheet. | ||
33 | |||
34 | - #power-domain-cells: Must be 0 | ||
35 | - SoC devices that are part of the CPG/MSSR Clock Domain and can be | ||
36 | power-managed through Module Standby should refer to the CPG device | ||
37 | node in their "power-domains" property, as documented by the generic PM | ||
38 | Domain bindings in | ||
39 | Documentation/devicetree/bindings/power/power_domain.txt. | ||
40 | |||
41 | |||
42 | Examples | ||
43 | -------- | ||
44 | |||
45 | - CPG device node: | ||
46 | |||
47 | cpg: clock-controller@e6150000 { | ||
48 | compatible = "renesas,r8a7795-cpg-mssr"; | ||
49 | reg = <0 0xe6150000 0 0x1000>; | ||
50 | clocks = <&extal_clk>, <&extalr_clk>; | ||
51 | clock-names = "extal", "extalr"; | ||
52 | #clock-cells = <2>; | ||
53 | #power-domain-cells = <0>; | ||
54 | }; | ||
55 | |||
56 | |||
57 | - CPG/MSSR Clock Domain member device node: | ||
58 | |||
59 | scif2: serial@e6e88000 { | ||
60 | compatible = "renesas,scif-r8a7795", "renesas,scif"; | ||
61 | reg = <0 0xe6e88000 0 64>; | ||
62 | interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; | ||
63 | clocks = <&cpg CPG_MOD 310>; | ||
64 | clock-names = "sci_ick"; | ||
65 | dmas = <&dmac1 0x13>, <&dmac1 0x12>; | ||
66 | dma-names = "tx", "rx"; | ||
67 | power-domains = <&cpg>; | ||
68 | status = "disabled"; | ||
69 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/silabs,si514.txt b/Documentation/devicetree/bindings/clock/silabs,si514.txt new file mode 100644 index 000000000000..ea1a9dbc63b6 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/silabs,si514.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | Binding for Silicon Labs 514 programmable I2C clock generator. | ||
2 | |||
3 | Reference | ||
4 | This binding uses the common clock binding[1]. Details about the device can be | ||
5 | found in the datasheet[2]. | ||
6 | |||
7 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
8 | [2] Si514 datasheet | ||
9 | http://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf | ||
10 | |||
11 | Required properties: | ||
12 | - compatible: Shall be "silabs,si514" | ||
13 | - reg: I2C device address. | ||
14 | - #clock-cells: From common clock bindings: Shall be 0. | ||
15 | |||
16 | Optional properties: | ||
17 | - clock-output-names: From common clock bindings. Recommended to be "si514". | ||
18 | |||
19 | Example: | ||
20 | si514: clock-generator@55 { | ||
21 | reg = <0x55>; | ||
22 | #clock-cells = <0>; | ||
23 | compatible = "silabs,si514"; | ||
24 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt index d8b168ebd5f1..844b3a0976bf 100644 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt +++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt | |||
@@ -23,6 +23,7 @@ Required properties: | |||
23 | "st,stih407-plls-c32-a9", "st,clkgen-plls-c32" | 23 | "st,stih407-plls-c32-a9", "st,clkgen-plls-c32" |
24 | "sst,plls-c32-cx_0", "st,clkgen-plls-c32" | 24 | "sst,plls-c32-cx_0", "st,clkgen-plls-c32" |
25 | "sst,plls-c32-cx_1", "st,clkgen-plls-c32" | 25 | "sst,plls-c32-cx_1", "st,clkgen-plls-c32" |
26 | "st,stih418-plls-c28-a9", "st,clkgen-plls-c32" | ||
26 | 27 | ||
27 | "st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32" | 28 | "st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32" |
28 | "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32" | 29 | "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32" |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 89a755b90db2..92673006e55c 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -102,6 +102,9 @@ config HAVE_AT91_SMD | |||
102 | config HAVE_AT91_H32MX | 102 | config HAVE_AT91_H32MX |
103 | bool | 103 | bool |
104 | 104 | ||
105 | config HAVE_AT91_GENERATED_CLK | ||
106 | bool | ||
107 | |||
105 | config SOC_SAM_V4_V5 | 108 | config SOC_SAM_V4_V5 |
106 | bool | 109 | bool |
107 | 110 | ||
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 1319c3c14327..84bd26535ae9 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig | |||
@@ -14,7 +14,7 @@ config ARCH_BCM_IPROC | |||
14 | select HAVE_ARM_SCU if SMP | 14 | select HAVE_ARM_SCU if SMP |
15 | select HAVE_ARM_TWD if SMP | 15 | select HAVE_ARM_TWD if SMP |
16 | select ARM_GLOBAL_TIMER | 16 | select ARM_GLOBAL_TIMER |
17 | 17 | select COMMON_CLK_IPROC | |
18 | select CLKSRC_MMIO | 18 | select CLKSRC_MMIO |
19 | select ARCH_REQUIRE_GPIOLIB | 19 | select ARCH_REQUIRE_GPIOLIB |
20 | select ARM_AMBA | 20 | select ARM_AMBA |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index a7dfdf9f15ba..80e298870388 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -1353,6 +1353,7 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, | |||
1353 | 1353 | ||
1354 | return ret; | 1354 | return ret; |
1355 | } | 1355 | } |
1356 | EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); | ||
1356 | 1357 | ||
1357 | /** | 1358 | /** |
1358 | * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. | 1359 | * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. |
@@ -1400,6 +1401,7 @@ out: | |||
1400 | 1401 | ||
1401 | return ret; | 1402 | return ret; |
1402 | } | 1403 | } |
1404 | EXPORT_SYMBOL_GPL(pm_genpd_remove_subdomain); | ||
1403 | 1405 | ||
1404 | /* Default device callbacks for generic PM domains. */ | 1406 | /* Default device callbacks for generic PM domains. */ |
1405 | 1407 | ||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 42f7120ca9ce..57316528e924 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -14,6 +14,7 @@ config COMMON_CLK | |||
14 | select HAVE_CLK_PREPARE | 14 | select HAVE_CLK_PREPARE |
15 | select CLKDEV_LOOKUP | 15 | select CLKDEV_LOOKUP |
16 | select SRCU | 16 | select SRCU |
17 | select RATIONAL | ||
17 | ---help--- | 18 | ---help--- |
18 | The common clock framework is a single definition of struct | 19 | The common clock framework is a single definition of struct |
19 | clk, useful across many platforms, as well as an | 20 | clk, useful across many platforms, as well as an |
@@ -68,6 +69,16 @@ config COMMON_CLK_SI5351 | |||
68 | This driver supports Silicon Labs 5351A/B/C programmable clock | 69 | This driver supports Silicon Labs 5351A/B/C programmable clock |
69 | generators. | 70 | generators. |
70 | 71 | ||
72 | config COMMON_CLK_SI514 | ||
73 | tristate "Clock driver for SiLabs 514 devices" | ||
74 | depends on I2C | ||
75 | depends on OF | ||
76 | select REGMAP_I2C | ||
77 | help | ||
78 | ---help--- | ||
79 | This driver supports the Silicon Labs 514 programmable clock | ||
80 | generator. | ||
81 | |||
71 | config COMMON_CLK_SI570 | 82 | config COMMON_CLK_SI570 |
72 | tristate "Clock driver for SiLabs 570 and compatible devices" | 83 | tristate "Clock driver for SiLabs 570 and compatible devices" |
73 | depends on I2C | 84 | depends on I2C |
@@ -113,7 +124,7 @@ config CLK_TWL6040 | |||
113 | 124 | ||
114 | config COMMON_CLK_AXI_CLKGEN | 125 | config COMMON_CLK_AXI_CLKGEN |
115 | tristate "AXI clkgen driver" | 126 | tristate "AXI clkgen driver" |
116 | depends on ARCH_ZYNQ || MICROBLAZE | 127 | depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST |
117 | help | 128 | help |
118 | ---help--- | 129 | ---help--- |
119 | Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx | 130 | Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx |
@@ -121,7 +132,7 @@ config COMMON_CLK_AXI_CLKGEN | |||
121 | 132 | ||
122 | config CLK_QORIQ | 133 | config CLK_QORIQ |
123 | bool "Clock driver for Freescale QorIQ platforms" | 134 | bool "Clock driver for Freescale QorIQ platforms" |
124 | depends on (PPC_E500MC || ARM) && OF | 135 | depends on (PPC_E500MC || ARM || COMPILE_TEST) && OF |
125 | ---help--- | 136 | ---help--- |
126 | This adds the clock driver support for Freescale QorIQ platforms | 137 | This adds the clock driver support for Freescale QorIQ platforms |
127 | using common clock framework. | 138 | using common clock framework. |
@@ -129,13 +140,13 @@ config CLK_QORIQ | |||
129 | config COMMON_CLK_XGENE | 140 | config COMMON_CLK_XGENE |
130 | bool "Clock driver for APM XGene SoC" | 141 | bool "Clock driver for APM XGene SoC" |
131 | default y | 142 | default y |
132 | depends on ARM64 | 143 | depends on ARM64 || COMPILE_TEST |
133 | ---help--- | 144 | ---help--- |
134 | Sypport for the APM X-Gene SoC reference, PLL, and device clocks. | 145 | Sypport for the APM X-Gene SoC reference, PLL, and device clocks. |
135 | 146 | ||
136 | config COMMON_CLK_KEYSTONE | 147 | config COMMON_CLK_KEYSTONE |
137 | tristate "Clock drivers for Keystone based SOCs" | 148 | tristate "Clock drivers for Keystone based SOCs" |
138 | depends on ARCH_KEYSTONE && OF | 149 | depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF |
139 | ---help--- | 150 | ---help--- |
140 | Supports clock drivers for Keystone based SOCs. These SOCs have local | 151 | Supports clock drivers for Keystone based SOCs. These SOCs have local |
141 | a power sleep control module that gate the clock to the IPs and PLLs. | 152 | a power sleep control module that gate the clock to the IPs and PLLs. |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index d08b3e5985be..d3e1910eebab 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-divider.o | |||
6 | obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o | 6 | 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-multiplier.o | ||
9 | obj-$(CONFIG_COMMON_CLK) += clk-mux.o | 10 | obj-$(CONFIG_COMMON_CLK) += clk-mux.o |
10 | obj-$(CONFIG_COMMON_CLK) += clk-composite.o | 11 | obj-$(CONFIG_COMMON_CLK) += clk-composite.o |
11 | obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o | 12 | obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o |
@@ -19,7 +20,6 @@ endif | |||
19 | obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o | 20 | obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o |
20 | obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o | 21 | obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o |
21 | obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o | 22 | obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o |
22 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | ||
23 | obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o | 23 | obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o |
24 | obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o | 24 | obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o |
25 | obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o | 25 | obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o |
@@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o | |||
37 | obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o | 37 | obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o |
38 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o | 38 | obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o |
39 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | 39 | obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o |
40 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o | ||
40 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o | 41 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o |
41 | obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o | 42 | obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o |
42 | obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o | 43 | obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o |
@@ -47,7 +48,7 @@ obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | |||
47 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o | 48 | obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o |
48 | obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o | 49 | obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o |
49 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ | 50 | obj-$(CONFIG_COMMON_CLK_AT91) += at91/ |
50 | obj-$(CONFIG_ARCH_BCM) += bcm/ | 51 | obj-y += bcm/ |
51 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ | 52 | obj-$(CONFIG_ARCH_BERLIN) += berlin/ |
52 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ | 53 | obj-$(CONFIG_ARCH_HISI) += hisilicon/ |
53 | obj-$(CONFIG_ARCH_MXC) += imx/ | 54 | obj-$(CONFIG_ARCH_MXC) += imx/ |
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 89a48a7bd5df..13e67bd35cff 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile | |||
@@ -10,3 +10,4 @@ obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o | |||
10 | obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o | 10 | obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o |
11 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o | 11 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o |
12 | obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o | 12 | obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o |
13 | obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o | ||
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c new file mode 100644 index 000000000000..abc80949e1dd --- /dev/null +++ b/drivers/clk/at91/clk-generated.c | |||
@@ -0,0 +1,306 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Atmel Corporation, | ||
3 | * Nicolas Ferre <nicolas.ferre@atmel.com> | ||
4 | * | ||
5 | * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/clkdev.h> | ||
16 | #include <linux/clk/at91_pmc.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/io.h> | ||
20 | |||
21 | #include "pmc.h" | ||
22 | |||
23 | #define PERIPHERAL_MAX 64 | ||
24 | #define PERIPHERAL_ID_MIN 2 | ||
25 | |||
26 | #define GENERATED_SOURCE_MAX 6 | ||
27 | #define GENERATED_MAX_DIV 255 | ||
28 | |||
29 | struct clk_generated { | ||
30 | struct clk_hw hw; | ||
31 | struct at91_pmc *pmc; | ||
32 | struct clk_range range; | ||
33 | u32 id; | ||
34 | u32 gckdiv; | ||
35 | u8 parent_id; | ||
36 | }; | ||
37 | |||
38 | #define to_clk_generated(hw) \ | ||
39 | container_of(hw, struct clk_generated, hw) | ||
40 | |||
41 | static int clk_generated_enable(struct clk_hw *hw) | ||
42 | { | ||
43 | struct clk_generated *gck = to_clk_generated(hw); | ||
44 | struct at91_pmc *pmc = gck->pmc; | ||
45 | u32 tmp; | ||
46 | |||
47 | pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", | ||
48 | __func__, gck->gckdiv, gck->parent_id); | ||
49 | |||
50 | pmc_lock(pmc); | ||
51 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | ||
52 | tmp = pmc_read(pmc, AT91_PMC_PCR) & | ||
53 | ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK); | ||
54 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id) | ||
55 | | AT91_PMC_PCR_CMD | ||
56 | | AT91_PMC_PCR_GCKDIV(gck->gckdiv) | ||
57 | | AT91_PMC_PCR_GCKEN); | ||
58 | pmc_unlock(pmc); | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static void clk_generated_disable(struct clk_hw *hw) | ||
63 | { | ||
64 | struct clk_generated *gck = to_clk_generated(hw); | ||
65 | struct at91_pmc *pmc = gck->pmc; | ||
66 | u32 tmp; | ||
67 | |||
68 | pmc_lock(pmc); | ||
69 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | ||
70 | tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN; | ||
71 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); | ||
72 | pmc_unlock(pmc); | ||
73 | } | ||
74 | |||
75 | static int clk_generated_is_enabled(struct clk_hw *hw) | ||
76 | { | ||
77 | struct clk_generated *gck = to_clk_generated(hw); | ||
78 | struct at91_pmc *pmc = gck->pmc; | ||
79 | int ret; | ||
80 | |||
81 | pmc_lock(pmc); | ||
82 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | ||
83 | ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN); | ||
84 | pmc_unlock(pmc); | ||
85 | |||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static unsigned long | ||
90 | clk_generated_recalc_rate(struct clk_hw *hw, | ||
91 | unsigned long parent_rate) | ||
92 | { | ||
93 | struct clk_generated *gck = to_clk_generated(hw); | ||
94 | |||
95 | return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); | ||
96 | } | ||
97 | |||
98 | static int clk_generated_determine_rate(struct clk_hw *hw, | ||
99 | struct clk_rate_request *req) | ||
100 | { | ||
101 | struct clk_generated *gck = to_clk_generated(hw); | ||
102 | struct clk_hw *parent = NULL; | ||
103 | long best_rate = -EINVAL; | ||
104 | unsigned long tmp_rate, min_rate; | ||
105 | int best_diff = -1; | ||
106 | int tmp_diff; | ||
107 | int i; | ||
108 | |||
109 | for (i = 0; i < clk_hw_get_num_parents(hw); i++) { | ||
110 | u32 div; | ||
111 | unsigned long parent_rate; | ||
112 | |||
113 | parent = clk_hw_get_parent_by_index(hw, i); | ||
114 | if (!parent) | ||
115 | continue; | ||
116 | |||
117 | parent_rate = clk_hw_get_rate(parent); | ||
118 | min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1); | ||
119 | if (!parent_rate || | ||
120 | (gck->range.max && min_rate > gck->range.max)) | ||
121 | continue; | ||
122 | |||
123 | for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { | ||
124 | tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div); | ||
125 | tmp_diff = abs(req->rate - tmp_rate); | ||
126 | |||
127 | if (best_diff < 0 || best_diff > tmp_diff) { | ||
128 | best_rate = tmp_rate; | ||
129 | best_diff = tmp_diff; | ||
130 | req->best_parent_rate = parent_rate; | ||
131 | req->best_parent_hw = parent; | ||
132 | } | ||
133 | |||
134 | if (!best_diff || tmp_rate < req->rate) | ||
135 | break; | ||
136 | } | ||
137 | |||
138 | if (!best_diff) | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", | ||
143 | __func__, best_rate, | ||
144 | __clk_get_name((req->best_parent_hw)->clk), | ||
145 | req->best_parent_rate); | ||
146 | |||
147 | if (best_rate < 0) | ||
148 | return best_rate; | ||
149 | |||
150 | req->rate = best_rate; | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */ | ||
155 | static int clk_generated_set_parent(struct clk_hw *hw, u8 index) | ||
156 | { | ||
157 | struct clk_generated *gck = to_clk_generated(hw); | ||
158 | |||
159 | if (index >= clk_hw_get_num_parents(hw)) | ||
160 | return -EINVAL; | ||
161 | |||
162 | gck->parent_id = index; | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static u8 clk_generated_get_parent(struct clk_hw *hw) | ||
167 | { | ||
168 | struct clk_generated *gck = to_clk_generated(hw); | ||
169 | |||
170 | return gck->parent_id; | ||
171 | } | ||
172 | |||
173 | /* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */ | ||
174 | static int clk_generated_set_rate(struct clk_hw *hw, | ||
175 | unsigned long rate, | ||
176 | unsigned long parent_rate) | ||
177 | { | ||
178 | struct clk_generated *gck = to_clk_generated(hw); | ||
179 | u32 div; | ||
180 | |||
181 | if (!rate) | ||
182 | return -EINVAL; | ||
183 | |||
184 | if (gck->range.max && rate > gck->range.max) | ||
185 | return -EINVAL; | ||
186 | |||
187 | div = DIV_ROUND_CLOSEST(parent_rate, rate); | ||
188 | if (div > GENERATED_MAX_DIV + 1 || !div) | ||
189 | return -EINVAL; | ||
190 | |||
191 | gck->gckdiv = div - 1; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static const struct clk_ops generated_ops = { | ||
196 | .enable = clk_generated_enable, | ||
197 | .disable = clk_generated_disable, | ||
198 | .is_enabled = clk_generated_is_enabled, | ||
199 | .recalc_rate = clk_generated_recalc_rate, | ||
200 | .determine_rate = clk_generated_determine_rate, | ||
201 | .get_parent = clk_generated_get_parent, | ||
202 | .set_parent = clk_generated_set_parent, | ||
203 | .set_rate = clk_generated_set_rate, | ||
204 | }; | ||
205 | |||
206 | /** | ||
207 | * clk_generated_startup - Initialize a given clock to its default parent and | ||
208 | * divisor parameter. | ||
209 | * | ||
210 | * @gck: Generated clock to set the startup parameters for. | ||
211 | * | ||
212 | * Take parameters from the hardware and update local clock configuration | ||
213 | * accordingly. | ||
214 | */ | ||
215 | static void clk_generated_startup(struct clk_generated *gck) | ||
216 | { | ||
217 | struct at91_pmc *pmc = gck->pmc; | ||
218 | u32 tmp; | ||
219 | |||
220 | pmc_lock(pmc); | ||
221 | pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); | ||
222 | tmp = pmc_read(pmc, AT91_PMC_PCR); | ||
223 | pmc_unlock(pmc); | ||
224 | |||
225 | gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) | ||
226 | >> AT91_PMC_PCR_GCKCSS_OFFSET; | ||
227 | gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK) | ||
228 | >> AT91_PMC_PCR_GCKDIV_OFFSET; | ||
229 | } | ||
230 | |||
231 | static struct clk * __init | ||
232 | at91_clk_register_generated(struct at91_pmc *pmc, const char *name, | ||
233 | const char **parent_names, u8 num_parents, | ||
234 | u8 id, const struct clk_range *range) | ||
235 | { | ||
236 | struct clk_generated *gck; | ||
237 | struct clk *clk = NULL; | ||
238 | struct clk_init_data init; | ||
239 | |||
240 | gck = kzalloc(sizeof(*gck), GFP_KERNEL); | ||
241 | if (!gck) | ||
242 | return ERR_PTR(-ENOMEM); | ||
243 | |||
244 | init.name = name; | ||
245 | init.ops = &generated_ops; | ||
246 | init.parent_names = parent_names; | ||
247 | init.num_parents = num_parents; | ||
248 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | ||
249 | |||
250 | gck->id = id; | ||
251 | gck->hw.init = &init; | ||
252 | gck->pmc = pmc; | ||
253 | gck->range = *range; | ||
254 | |||
255 | clk = clk_register(NULL, &gck->hw); | ||
256 | if (IS_ERR(clk)) | ||
257 | kfree(gck); | ||
258 | else | ||
259 | clk_generated_startup(gck); | ||
260 | |||
261 | return clk; | ||
262 | } | ||
263 | |||
264 | void __init of_sama5d2_clk_generated_setup(struct device_node *np, | ||
265 | struct at91_pmc *pmc) | ||
266 | { | ||
267 | int num; | ||
268 | u32 id; | ||
269 | const char *name; | ||
270 | struct clk *clk; | ||
271 | int num_parents; | ||
272 | const char *parent_names[GENERATED_SOURCE_MAX]; | ||
273 | struct device_node *gcknp; | ||
274 | struct clk_range range = CLK_RANGE(0, 0); | ||
275 | |||
276 | num_parents = of_clk_get_parent_count(np); | ||
277 | if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX) | ||
278 | return; | ||
279 | |||
280 | of_clk_parent_fill(np, parent_names, num_parents); | ||
281 | |||
282 | num = of_get_child_count(np); | ||
283 | if (!num || num > PERIPHERAL_MAX) | ||
284 | return; | ||
285 | |||
286 | for_each_child_of_node(np, gcknp) { | ||
287 | if (of_property_read_u32(gcknp, "reg", &id)) | ||
288 | continue; | ||
289 | |||
290 | if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX) | ||
291 | continue; | ||
292 | |||
293 | if (of_property_read_string(np, "clock-output-names", &name)) | ||
294 | name = gcknp->name; | ||
295 | |||
296 | of_at91_get_clk_range(gcknp, "atmel,clk-output-range", | ||
297 | &range); | ||
298 | |||
299 | clk = at91_clk_register_generated(pmc, name, parent_names, | ||
300 | num_parents, id, &range); | ||
301 | if (IS_ERR(clk)) | ||
302 | continue; | ||
303 | |||
304 | of_clk_add_provider(gcknp, of_clk_src_simple_get, clk); | ||
305 | } | ||
306 | } | ||
diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index e4d7b574f1ea..58f3b568e9cb 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c | |||
@@ -161,14 +161,18 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) | |||
161 | { | 161 | { |
162 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | 162 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); |
163 | struct at91_pmc *pmc = periph->pmc; | 163 | struct at91_pmc *pmc = periph->pmc; |
164 | u32 tmp; | ||
164 | 165 | ||
165 | if (periph->id < PERIPHERAL_ID_MIN) | 166 | if (periph->id < PERIPHERAL_ID_MIN) |
166 | return 0; | 167 | return 0; |
167 | 168 | ||
168 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) | | 169 | pmc_lock(pmc); |
169 | AT91_PMC_PCR_CMD | | 170 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); |
170 | AT91_PMC_PCR_DIV(periph->div) | | 171 | tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK; |
171 | AT91_PMC_PCR_EN); | 172 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div) |
173 | | AT91_PMC_PCR_CMD | ||
174 | | AT91_PMC_PCR_EN); | ||
175 | pmc_unlock(pmc); | ||
172 | return 0; | 176 | return 0; |
173 | } | 177 | } |
174 | 178 | ||
@@ -176,12 +180,16 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) | |||
176 | { | 180 | { |
177 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); | 181 | struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); |
178 | struct at91_pmc *pmc = periph->pmc; | 182 | struct at91_pmc *pmc = periph->pmc; |
183 | u32 tmp; | ||
179 | 184 | ||
180 | if (periph->id < PERIPHERAL_ID_MIN) | 185 | if (periph->id < PERIPHERAL_ID_MIN) |
181 | return; | 186 | return; |
182 | 187 | ||
183 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID) | | 188 | pmc_lock(pmc); |
184 | AT91_PMC_PCR_CMD); | 189 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); |
190 | tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN; | ||
191 | pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); | ||
192 | pmc_unlock(pmc); | ||
185 | } | 193 | } |
186 | 194 | ||
187 | static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) | 195 | static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) |
@@ -194,7 +202,7 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) | |||
194 | return 1; | 202 | return 1; |
195 | 203 | ||
196 | pmc_lock(pmc); | 204 | pmc_lock(pmc); |
197 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID)); | 205 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); |
198 | ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN); | 206 | ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN); |
199 | pmc_unlock(pmc); | 207 | pmc_unlock(pmc); |
200 | 208 | ||
@@ -213,7 +221,7 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw, | |||
213 | return parent_rate; | 221 | return parent_rate; |
214 | 222 | ||
215 | pmc_lock(pmc); | 223 | pmc_lock(pmc); |
216 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID)); | 224 | pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); |
217 | tmp = pmc_read(pmc, AT91_PMC_PCR); | 225 | tmp = pmc_read(pmc, AT91_PMC_PCR); |
218 | pmc_unlock(pmc); | 226 | pmc_unlock(pmc); |
219 | 227 | ||
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index 58008b3e8bc1..3f5314344286 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c | |||
@@ -138,7 +138,8 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name, | |||
138 | 138 | ||
139 | clk = clk_register(NULL, &sys->hw); | 139 | clk = clk_register(NULL, &sys->hw); |
140 | if (IS_ERR(clk)) { | 140 | if (IS_ERR(clk)) { |
141 | free_irq(sys->irq, sys); | 141 | if (irq) |
142 | free_irq(sys->irq, sys); | ||
142 | kfree(sys); | 143 | kfree(sys); |
143 | } | 144 | } |
144 | 145 | ||
diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c index 30dd697b1668..ca561e90a60f 100644 --- a/drivers/clk/at91/clk-utmi.c +++ b/drivers/clk/at91/clk-utmi.c | |||
@@ -47,7 +47,7 @@ static int clk_utmi_prepare(struct clk_hw *hw) | |||
47 | { | 47 | { |
48 | struct clk_utmi *utmi = to_clk_utmi(hw); | 48 | struct clk_utmi *utmi = to_clk_utmi(hw); |
49 | struct at91_pmc *pmc = utmi->pmc; | 49 | struct at91_pmc *pmc = utmi->pmc; |
50 | u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN | | 50 | u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN | |
51 | AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN; | 51 | AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN; |
52 | 52 | ||
53 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); | 53 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); |
@@ -73,7 +73,7 @@ static void clk_utmi_unprepare(struct clk_hw *hw) | |||
73 | { | 73 | { |
74 | struct clk_utmi *utmi = to_clk_utmi(hw); | 74 | struct clk_utmi *utmi = to_clk_utmi(hw); |
75 | struct at91_pmc *pmc = utmi->pmc; | 75 | struct at91_pmc *pmc = utmi->pmc; |
76 | u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN; | 76 | u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN; |
77 | 77 | ||
78 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); | 78 | pmc_write(pmc, AT91_CKGR_UCKR, tmp); |
79 | } | 79 | } |
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index d1844f1f3729..8476b570779b 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c | |||
@@ -206,6 +206,14 @@ static const struct at91_pmc_caps at91sam9x5_caps = { | |||
206 | AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, | 206 | AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, |
207 | }; | 207 | }; |
208 | 208 | ||
209 | static const struct at91_pmc_caps sama5d2_caps = { | ||
210 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | ||
211 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | ||
212 | AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | | ||
213 | AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | | ||
214 | AT91_PMC_CFDEV | AT91_PMC_GCKRDY, | ||
215 | }; | ||
216 | |||
209 | static const struct at91_pmc_caps sama5d3_caps = { | 217 | static const struct at91_pmc_caps sama5d3_caps = { |
210 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | | 218 | .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | |
211 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | | 219 | AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | |
@@ -369,6 +377,12 @@ static const struct of_device_id pmc_clk_ids[] __initconst = { | |||
369 | .data = of_sama5d4_clk_h32mx_setup, | 377 | .data = of_sama5d4_clk_h32mx_setup, |
370 | }, | 378 | }, |
371 | #endif | 379 | #endif |
380 | #if defined(CONFIG_HAVE_AT91_GENERATED_CLK) | ||
381 | { | ||
382 | .compatible = "atmel,sama5d2-clk-generated", | ||
383 | .data = of_sama5d2_clk_generated_setup, | ||
384 | }, | ||
385 | #endif | ||
372 | { /*sentinel*/ } | 386 | { /*sentinel*/ } |
373 | }; | 387 | }; |
374 | 388 | ||
@@ -436,6 +450,13 @@ static void __init of_at91sam9x5_pmc_setup(struct device_node *np) | |||
436 | CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", | 450 | CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", |
437 | of_at91sam9x5_pmc_setup); | 451 | of_at91sam9x5_pmc_setup); |
438 | 452 | ||
453 | static void __init of_sama5d2_pmc_setup(struct device_node *np) | ||
454 | { | ||
455 | of_at91_pmc_setup(np, &sama5d2_caps); | ||
456 | } | ||
457 | CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc", | ||
458 | of_sama5d2_pmc_setup); | ||
459 | |||
439 | static void __init of_sama5d3_pmc_setup(struct device_node *np) | 460 | static void __init of_sama5d3_pmc_setup(struct device_node *np) |
440 | { | 461 | { |
441 | of_at91_pmc_setup(np, &sama5d3_caps); | 462 | of_at91_pmc_setup(np, &sama5d3_caps); |
diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 8b87771c69b2..f65739272779 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h | |||
@@ -118,4 +118,7 @@ void of_at91sam9x5_clk_smd_setup(struct device_node *np, | |||
118 | void of_sama5d4_clk_h32mx_setup(struct device_node *np, | 118 | void of_sama5d4_clk_h32mx_setup(struct device_node *np, |
119 | struct at91_pmc *pmc); | 119 | struct at91_pmc *pmc); |
120 | 120 | ||
121 | void of_sama5d2_clk_generated_setup(struct device_node *np, | ||
122 | struct at91_pmc *pmc); | ||
123 | |||
121 | #endif /* __PMC_H_ */ | 124 | #endif /* __PMC_H_ */ |
diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index 88febf53b276..85260fb96b36 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config CLK_BCM_KONA | 1 | config CLK_BCM_KONA |
2 | bool "Broadcom Kona CCU clock support" | 2 | bool "Broadcom Kona CCU clock support" |
3 | depends on ARCH_BCM_MOBILE | 3 | depends on ARCH_BCM_MOBILE || COMPILE_TEST |
4 | depends on COMMON_CLK | 4 | depends on COMMON_CLK |
5 | default y | 5 | default y |
6 | help | 6 | help |
@@ -9,10 +9,8 @@ config CLK_BCM_KONA | |||
9 | in the BCM281xx and BCM21664 families. | 9 | in the BCM281xx and BCM21664 families. |
10 | 10 | ||
11 | config COMMON_CLK_IPROC | 11 | config COMMON_CLK_IPROC |
12 | bool "Broadcom iProc clock support" | 12 | bool |
13 | depends on ARCH_BCM_IPROC | ||
14 | depends on COMMON_CLK | 13 | depends on COMMON_CLK |
15 | default ARCH_BCM_IPROC | ||
16 | help | 14 | help |
17 | Enable common clock framework support for Broadcom SoCs | 15 | Enable common clock framework support for Broadcom SoCs |
18 | based on the iProc architecture | 16 | based on the iProc architecture |
diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 8a7a477862c7..3fc95060d875 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile | |||
@@ -3,4 +3,8 @@ obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o | |||
3 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o | 3 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o |
4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o | 4 | obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm21664.o |
5 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o | 5 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-iproc-armpll.o clk-iproc-pll.o clk-iproc-asiu.o |
6 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | ||
7 | obj-$(CONFIG_COMMON_CLK_IPROC) += clk-ns2.o | ||
6 | obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o | 8 | obj-$(CONFIG_ARCH_BCM_CYGNUS) += clk-cygnus.o |
9 | obj-$(CONFIG_ARCH_BCM_NSP) += clk-nsp.o | ||
10 | obj-$(CONFIG_ARCH_BCM_5301X) += clk-nsp.o | ||
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c new file mode 100644 index 000000000000..39bf5820297e --- /dev/null +++ b/drivers/clk/bcm/clk-bcm2835.c | |||
@@ -0,0 +1,1575 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010,2015 Broadcom | ||
3 | * Copyright (C) 2012 Stephen Warren | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | /** | ||
21 | * DOC: BCM2835 CPRMAN (clock manager for the "audio" domain) | ||
22 | * | ||
23 | * The clock tree on the 2835 has several levels. There's a root | ||
24 | * oscillator running at 19.2Mhz. After the oscillator there are 5 | ||
25 | * PLLs, roughly divided as "camera", "ARM", "core", "DSI displays", | ||
26 | * and "HDMI displays". Those 5 PLLs each can divide their output to | ||
27 | * produce up to 4 channels. Finally, there is the level of clocks to | ||
28 | * be consumed by other hardware components (like "H264" or "HDMI | ||
29 | * state machine"), which divide off of some subset of the PLL | ||
30 | * channels. | ||
31 | * | ||
32 | * All of the clocks in the tree are exposed in the DT, because the DT | ||
33 | * may want to make assignments of the final layer of clocks to the | ||
34 | * PLL channels, and some components of the hardware will actually | ||
35 | * skip layers of the tree (for example, the pixel clock comes | ||
36 | * directly from the PLLH PIX channel without using a CM_*CTL clock | ||
37 | * generator). | ||
38 | */ | ||
39 | |||
40 | #include <linux/clk-provider.h> | ||
41 | #include <linux/clkdev.h> | ||
42 | #include <linux/clk/bcm2835.h> | ||
43 | #include <linux/module.h> | ||
44 | #include <linux/of.h> | ||
45 | #include <linux/platform_device.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <dt-bindings/clock/bcm2835.h> | ||
48 | |||
49 | #define CM_PASSWORD 0x5a000000 | ||
50 | |||
51 | #define CM_GNRICCTL 0x000 | ||
52 | #define CM_GNRICDIV 0x004 | ||
53 | # define CM_DIV_FRAC_BITS 12 | ||
54 | |||
55 | #define CM_VPUCTL 0x008 | ||
56 | #define CM_VPUDIV 0x00c | ||
57 | #define CM_SYSCTL 0x010 | ||
58 | #define CM_SYSDIV 0x014 | ||
59 | #define CM_PERIACTL 0x018 | ||
60 | #define CM_PERIADIV 0x01c | ||
61 | #define CM_PERIICTL 0x020 | ||
62 | #define CM_PERIIDIV 0x024 | ||
63 | #define CM_H264CTL 0x028 | ||
64 | #define CM_H264DIV 0x02c | ||
65 | #define CM_ISPCTL 0x030 | ||
66 | #define CM_ISPDIV 0x034 | ||
67 | #define CM_V3DCTL 0x038 | ||
68 | #define CM_V3DDIV 0x03c | ||
69 | #define CM_CAM0CTL 0x040 | ||
70 | #define CM_CAM0DIV 0x044 | ||
71 | #define CM_CAM1CTL 0x048 | ||
72 | #define CM_CAM1DIV 0x04c | ||
73 | #define CM_CCP2CTL 0x050 | ||
74 | #define CM_CCP2DIV 0x054 | ||
75 | #define CM_DSI0ECTL 0x058 | ||
76 | #define CM_DSI0EDIV 0x05c | ||
77 | #define CM_DSI0PCTL 0x060 | ||
78 | #define CM_DSI0PDIV 0x064 | ||
79 | #define CM_DPICTL 0x068 | ||
80 | #define CM_DPIDIV 0x06c | ||
81 | #define CM_GP0CTL 0x070 | ||
82 | #define CM_GP0DIV 0x074 | ||
83 | #define CM_GP1CTL 0x078 | ||
84 | #define CM_GP1DIV 0x07c | ||
85 | #define CM_GP2CTL 0x080 | ||
86 | #define CM_GP2DIV 0x084 | ||
87 | #define CM_HSMCTL 0x088 | ||
88 | #define CM_HSMDIV 0x08c | ||
89 | #define CM_OTPCTL 0x090 | ||
90 | #define CM_OTPDIV 0x094 | ||
91 | #define CM_PWMCTL 0x0a0 | ||
92 | #define CM_PWMDIV 0x0a4 | ||
93 | #define CM_SMICTL 0x0b0 | ||
94 | #define CM_SMIDIV 0x0b4 | ||
95 | #define CM_TSENSCTL 0x0e0 | ||
96 | #define CM_TSENSDIV 0x0e4 | ||
97 | #define CM_TIMERCTL 0x0e8 | ||
98 | #define CM_TIMERDIV 0x0ec | ||
99 | #define CM_UARTCTL 0x0f0 | ||
100 | #define CM_UARTDIV 0x0f4 | ||
101 | #define CM_VECCTL 0x0f8 | ||
102 | #define CM_VECDIV 0x0fc | ||
103 | #define CM_PULSECTL 0x190 | ||
104 | #define CM_PULSEDIV 0x194 | ||
105 | #define CM_SDCCTL 0x1a8 | ||
106 | #define CM_SDCDIV 0x1ac | ||
107 | #define CM_ARMCTL 0x1b0 | ||
108 | #define CM_EMMCCTL 0x1c0 | ||
109 | #define CM_EMMCDIV 0x1c4 | ||
110 | |||
111 | /* General bits for the CM_*CTL regs */ | ||
112 | # define CM_ENABLE BIT(4) | ||
113 | # define CM_KILL BIT(5) | ||
114 | # define CM_GATE_BIT 6 | ||
115 | # define CM_GATE BIT(CM_GATE_BIT) | ||
116 | # define CM_BUSY BIT(7) | ||
117 | # define CM_BUSYD BIT(8) | ||
118 | # define CM_SRC_SHIFT 0 | ||
119 | # define CM_SRC_BITS 4 | ||
120 | # define CM_SRC_MASK 0xf | ||
121 | # define CM_SRC_GND 0 | ||
122 | # define CM_SRC_OSC 1 | ||
123 | # define CM_SRC_TESTDEBUG0 2 | ||
124 | # define CM_SRC_TESTDEBUG1 3 | ||
125 | # define CM_SRC_PLLA_CORE 4 | ||
126 | # define CM_SRC_PLLA_PER 4 | ||
127 | # define CM_SRC_PLLC_CORE0 5 | ||
128 | # define CM_SRC_PLLC_PER 5 | ||
129 | # define CM_SRC_PLLC_CORE1 8 | ||
130 | # define CM_SRC_PLLD_CORE 6 | ||
131 | # define CM_SRC_PLLD_PER 6 | ||
132 | # define CM_SRC_PLLH_AUX 7 | ||
133 | # define CM_SRC_PLLC_CORE1 8 | ||
134 | # define CM_SRC_PLLC_CORE2 9 | ||
135 | |||
136 | #define CM_OSCCOUNT 0x100 | ||
137 | |||
138 | #define CM_PLLA 0x104 | ||
139 | # define CM_PLL_ANARST BIT(8) | ||
140 | # define CM_PLLA_HOLDPER BIT(7) | ||
141 | # define CM_PLLA_LOADPER BIT(6) | ||
142 | # define CM_PLLA_HOLDCORE BIT(5) | ||
143 | # define CM_PLLA_LOADCORE BIT(4) | ||
144 | # define CM_PLLA_HOLDCCP2 BIT(3) | ||
145 | # define CM_PLLA_LOADCCP2 BIT(2) | ||
146 | # define CM_PLLA_HOLDDSI0 BIT(1) | ||
147 | # define CM_PLLA_LOADDSI0 BIT(0) | ||
148 | |||
149 | #define CM_PLLC 0x108 | ||
150 | # define CM_PLLC_HOLDPER BIT(7) | ||
151 | # define CM_PLLC_LOADPER BIT(6) | ||
152 | # define CM_PLLC_HOLDCORE2 BIT(5) | ||
153 | # define CM_PLLC_LOADCORE2 BIT(4) | ||
154 | # define CM_PLLC_HOLDCORE1 BIT(3) | ||
155 | # define CM_PLLC_LOADCORE1 BIT(2) | ||
156 | # define CM_PLLC_HOLDCORE0 BIT(1) | ||
157 | # define CM_PLLC_LOADCORE0 BIT(0) | ||
158 | |||
159 | #define CM_PLLD 0x10c | ||
160 | # define CM_PLLD_HOLDPER BIT(7) | ||
161 | # define CM_PLLD_LOADPER BIT(6) | ||
162 | # define CM_PLLD_HOLDCORE BIT(5) | ||
163 | # define CM_PLLD_LOADCORE BIT(4) | ||
164 | # define CM_PLLD_HOLDDSI1 BIT(3) | ||
165 | # define CM_PLLD_LOADDSI1 BIT(2) | ||
166 | # define CM_PLLD_HOLDDSI0 BIT(1) | ||
167 | # define CM_PLLD_LOADDSI0 BIT(0) | ||
168 | |||
169 | #define CM_PLLH 0x110 | ||
170 | # define CM_PLLH_LOADRCAL BIT(2) | ||
171 | # define CM_PLLH_LOADAUX BIT(1) | ||
172 | # define CM_PLLH_LOADPIX BIT(0) | ||
173 | |||
174 | #define CM_LOCK 0x114 | ||
175 | # define CM_LOCK_FLOCKH BIT(12) | ||
176 | # define CM_LOCK_FLOCKD BIT(11) | ||
177 | # define CM_LOCK_FLOCKC BIT(10) | ||
178 | # define CM_LOCK_FLOCKB BIT(9) | ||
179 | # define CM_LOCK_FLOCKA BIT(8) | ||
180 | |||
181 | #define CM_EVENT 0x118 | ||
182 | #define CM_DSI1ECTL 0x158 | ||
183 | #define CM_DSI1EDIV 0x15c | ||
184 | #define CM_DSI1PCTL 0x160 | ||
185 | #define CM_DSI1PDIV 0x164 | ||
186 | #define CM_DFTCTL 0x168 | ||
187 | #define CM_DFTDIV 0x16c | ||
188 | |||
189 | #define CM_PLLB 0x170 | ||
190 | # define CM_PLLB_HOLDARM BIT(1) | ||
191 | # define CM_PLLB_LOADARM BIT(0) | ||
192 | |||
193 | #define A2W_PLLA_CTRL 0x1100 | ||
194 | #define A2W_PLLC_CTRL 0x1120 | ||
195 | #define A2W_PLLD_CTRL 0x1140 | ||
196 | #define A2W_PLLH_CTRL 0x1160 | ||
197 | #define A2W_PLLB_CTRL 0x11e0 | ||
198 | # define A2W_PLL_CTRL_PRST_DISABLE BIT(17) | ||
199 | # define A2W_PLL_CTRL_PWRDN BIT(16) | ||
200 | # define A2W_PLL_CTRL_PDIV_MASK 0x000007000 | ||
201 | # define A2W_PLL_CTRL_PDIV_SHIFT 12 | ||
202 | # define A2W_PLL_CTRL_NDIV_MASK 0x0000003ff | ||
203 | # define A2W_PLL_CTRL_NDIV_SHIFT 0 | ||
204 | |||
205 | #define A2W_PLLA_ANA0 0x1010 | ||
206 | #define A2W_PLLC_ANA0 0x1030 | ||
207 | #define A2W_PLLD_ANA0 0x1050 | ||
208 | #define A2W_PLLH_ANA0 0x1070 | ||
209 | #define A2W_PLLB_ANA0 0x10f0 | ||
210 | |||
211 | #define A2W_PLL_KA_SHIFT 7 | ||
212 | #define A2W_PLL_KA_MASK GENMASK(9, 7) | ||
213 | #define A2W_PLL_KI_SHIFT 19 | ||
214 | #define A2W_PLL_KI_MASK GENMASK(21, 19) | ||
215 | #define A2W_PLL_KP_SHIFT 15 | ||
216 | #define A2W_PLL_KP_MASK GENMASK(18, 15) | ||
217 | |||
218 | #define A2W_PLLH_KA_SHIFT 19 | ||
219 | #define A2W_PLLH_KA_MASK GENMASK(21, 19) | ||
220 | #define A2W_PLLH_KI_LOW_SHIFT 22 | ||
221 | #define A2W_PLLH_KI_LOW_MASK GENMASK(23, 22) | ||
222 | #define A2W_PLLH_KI_HIGH_SHIFT 0 | ||
223 | #define A2W_PLLH_KI_HIGH_MASK GENMASK(0, 0) | ||
224 | #define A2W_PLLH_KP_SHIFT 1 | ||
225 | #define A2W_PLLH_KP_MASK GENMASK(4, 1) | ||
226 | |||
227 | #define A2W_XOSC_CTRL 0x1190 | ||
228 | # define A2W_XOSC_CTRL_PLLB_ENABLE BIT(7) | ||
229 | # define A2W_XOSC_CTRL_PLLA_ENABLE BIT(6) | ||
230 | # define A2W_XOSC_CTRL_PLLD_ENABLE BIT(5) | ||
231 | # define A2W_XOSC_CTRL_DDR_ENABLE BIT(4) | ||
232 | # define A2W_XOSC_CTRL_CPR1_ENABLE BIT(3) | ||
233 | # define A2W_XOSC_CTRL_USB_ENABLE BIT(2) | ||
234 | # define A2W_XOSC_CTRL_HDMI_ENABLE BIT(1) | ||
235 | # define A2W_XOSC_CTRL_PLLC_ENABLE BIT(0) | ||
236 | |||
237 | #define A2W_PLLA_FRAC 0x1200 | ||
238 | #define A2W_PLLC_FRAC 0x1220 | ||
239 | #define A2W_PLLD_FRAC 0x1240 | ||
240 | #define A2W_PLLH_FRAC 0x1260 | ||
241 | #define A2W_PLLB_FRAC 0x12e0 | ||
242 | # define A2W_PLL_FRAC_MASK ((1 << A2W_PLL_FRAC_BITS) - 1) | ||
243 | # define A2W_PLL_FRAC_BITS 20 | ||
244 | |||
245 | #define A2W_PLL_CHANNEL_DISABLE BIT(8) | ||
246 | #define A2W_PLL_DIV_BITS 8 | ||
247 | #define A2W_PLL_DIV_SHIFT 0 | ||
248 | |||
249 | #define A2W_PLLA_DSI0 0x1300 | ||
250 | #define A2W_PLLA_CORE 0x1400 | ||
251 | #define A2W_PLLA_PER 0x1500 | ||
252 | #define A2W_PLLA_CCP2 0x1600 | ||
253 | |||
254 | #define A2W_PLLC_CORE2 0x1320 | ||
255 | #define A2W_PLLC_CORE1 0x1420 | ||
256 | #define A2W_PLLC_PER 0x1520 | ||
257 | #define A2W_PLLC_CORE0 0x1620 | ||
258 | |||
259 | #define A2W_PLLD_DSI0 0x1340 | ||
260 | #define A2W_PLLD_CORE 0x1440 | ||
261 | #define A2W_PLLD_PER 0x1540 | ||
262 | #define A2W_PLLD_DSI1 0x1640 | ||
263 | |||
264 | #define A2W_PLLH_AUX 0x1360 | ||
265 | #define A2W_PLLH_RCAL 0x1460 | ||
266 | #define A2W_PLLH_PIX 0x1560 | ||
267 | #define A2W_PLLH_STS 0x1660 | ||
268 | |||
269 | #define A2W_PLLH_CTRLR 0x1960 | ||
270 | #define A2W_PLLH_FRACR 0x1a60 | ||
271 | #define A2W_PLLH_AUXR 0x1b60 | ||
272 | #define A2W_PLLH_RCALR 0x1c60 | ||
273 | #define A2W_PLLH_PIXR 0x1d60 | ||
274 | #define A2W_PLLH_STSR 0x1e60 | ||
275 | |||
276 | #define A2W_PLLB_ARM 0x13e0 | ||
277 | #define A2W_PLLB_SP0 0x14e0 | ||
278 | #define A2W_PLLB_SP1 0x15e0 | ||
279 | #define A2W_PLLB_SP2 0x16e0 | ||
280 | |||
281 | #define LOCK_TIMEOUT_NS 100000000 | ||
282 | #define BCM2835_MAX_FB_RATE 1750000000u | ||
283 | |||
284 | struct bcm2835_cprman { | ||
285 | struct device *dev; | ||
286 | void __iomem *regs; | ||
287 | spinlock_t regs_lock; | ||
288 | const char *osc_name; | ||
289 | |||
290 | struct clk_onecell_data onecell; | ||
291 | struct clk *clks[BCM2835_CLOCK_COUNT]; | ||
292 | }; | ||
293 | |||
294 | static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) | ||
295 | { | ||
296 | writel(CM_PASSWORD | val, cprman->regs + reg); | ||
297 | } | ||
298 | |||
299 | static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg) | ||
300 | { | ||
301 | return readl(cprman->regs + reg); | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * These are fixed clocks. They're probably not all root clocks and it may | ||
306 | * be possible to turn them on and off but until this is mapped out better | ||
307 | * it's the only way they can be used. | ||
308 | */ | ||
309 | void __init bcm2835_init_clocks(void) | ||
310 | { | ||
311 | struct clk *clk; | ||
312 | int ret; | ||
313 | |||
314 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, | ||
315 | 126000000); | ||
316 | if (IS_ERR(clk)) | ||
317 | pr_err("apb_pclk not registered\n"); | ||
318 | |||
319 | clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, | ||
320 | 3000000); | ||
321 | if (IS_ERR(clk)) | ||
322 | pr_err("uart0_pclk not registered\n"); | ||
323 | ret = clk_register_clkdev(clk, NULL, "20201000.uart"); | ||
324 | if (ret) | ||
325 | pr_err("uart0_pclk alias not registered\n"); | ||
326 | |||
327 | clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, | ||
328 | 125000000); | ||
329 | if (IS_ERR(clk)) | ||
330 | pr_err("uart1_pclk not registered\n"); | ||
331 | ret = clk_register_clkdev(clk, NULL, "20215000.uart"); | ||
332 | if (ret) | ||
333 | pr_err("uart1_pclk alias not registered\n"); | ||
334 | } | ||
335 | |||
336 | struct bcm2835_pll_data { | ||
337 | const char *name; | ||
338 | u32 cm_ctrl_reg; | ||
339 | u32 a2w_ctrl_reg; | ||
340 | u32 frac_reg; | ||
341 | u32 ana_reg_base; | ||
342 | u32 reference_enable_mask; | ||
343 | /* Bit in CM_LOCK to indicate when the PLL has locked. */ | ||
344 | u32 lock_mask; | ||
345 | |||
346 | const struct bcm2835_pll_ana_bits *ana; | ||
347 | |||
348 | unsigned long min_rate; | ||
349 | unsigned long max_rate; | ||
350 | /* | ||
351 | * Highest rate for the VCO before we have to use the | ||
352 | * pre-divide-by-2. | ||
353 | */ | ||
354 | unsigned long max_fb_rate; | ||
355 | }; | ||
356 | |||
357 | struct bcm2835_pll_ana_bits { | ||
358 | u32 mask0; | ||
359 | u32 set0; | ||
360 | u32 mask1; | ||
361 | u32 set1; | ||
362 | u32 mask3; | ||
363 | u32 set3; | ||
364 | u32 fb_prediv_mask; | ||
365 | }; | ||
366 | |||
367 | static const struct bcm2835_pll_ana_bits bcm2835_ana_default = { | ||
368 | .mask0 = 0, | ||
369 | .set0 = 0, | ||
370 | .mask1 = ~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK), | ||
371 | .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT), | ||
372 | .mask3 = ~A2W_PLL_KA_MASK, | ||
373 | .set3 = (2 << A2W_PLL_KA_SHIFT), | ||
374 | .fb_prediv_mask = BIT(14), | ||
375 | }; | ||
376 | |||
377 | static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { | ||
378 | .mask0 = ~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK), | ||
379 | .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT), | ||
380 | .mask1 = ~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK), | ||
381 | .set1 = (6 << A2W_PLLH_KP_SHIFT), | ||
382 | .mask3 = 0, | ||
383 | .set3 = 0, | ||
384 | .fb_prediv_mask = BIT(11), | ||
385 | }; | ||
386 | |||
387 | /* | ||
388 | * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera | ||
389 | * Port 2) transmitter clock. | ||
390 | * | ||
391 | * It is in the PX LDO power domain, which is on when the AUDIO domain | ||
392 | * is on. | ||
393 | */ | ||
394 | static const struct bcm2835_pll_data bcm2835_plla_data = { | ||
395 | .name = "plla", | ||
396 | .cm_ctrl_reg = CM_PLLA, | ||
397 | .a2w_ctrl_reg = A2W_PLLA_CTRL, | ||
398 | .frac_reg = A2W_PLLA_FRAC, | ||
399 | .ana_reg_base = A2W_PLLA_ANA0, | ||
400 | .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE, | ||
401 | .lock_mask = CM_LOCK_FLOCKA, | ||
402 | |||
403 | .ana = &bcm2835_ana_default, | ||
404 | |||
405 | .min_rate = 600000000u, | ||
406 | .max_rate = 2400000000u, | ||
407 | .max_fb_rate = BCM2835_MAX_FB_RATE, | ||
408 | }; | ||
409 | |||
410 | /* PLLB is used for the ARM's clock. */ | ||
411 | static const struct bcm2835_pll_data bcm2835_pllb_data = { | ||
412 | .name = "pllb", | ||
413 | .cm_ctrl_reg = CM_PLLB, | ||
414 | .a2w_ctrl_reg = A2W_PLLB_CTRL, | ||
415 | .frac_reg = A2W_PLLB_FRAC, | ||
416 | .ana_reg_base = A2W_PLLB_ANA0, | ||
417 | .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, | ||
418 | .lock_mask = CM_LOCK_FLOCKB, | ||
419 | |||
420 | .ana = &bcm2835_ana_default, | ||
421 | |||
422 | .min_rate = 600000000u, | ||
423 | .max_rate = 3000000000u, | ||
424 | .max_fb_rate = BCM2835_MAX_FB_RATE, | ||
425 | }; | ||
426 | |||
427 | /* | ||
428 | * PLLC is the core PLL, used to drive the core VPU clock. | ||
429 | * | ||
430 | * It is in the PX LDO power domain, which is on when the AUDIO domain | ||
431 | * is on. | ||
432 | */ | ||
433 | static const struct bcm2835_pll_data bcm2835_pllc_data = { | ||
434 | .name = "pllc", | ||
435 | .cm_ctrl_reg = CM_PLLC, | ||
436 | .a2w_ctrl_reg = A2W_PLLC_CTRL, | ||
437 | .frac_reg = A2W_PLLC_FRAC, | ||
438 | .ana_reg_base = A2W_PLLC_ANA0, | ||
439 | .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, | ||
440 | .lock_mask = CM_LOCK_FLOCKC, | ||
441 | |||
442 | .ana = &bcm2835_ana_default, | ||
443 | |||
444 | .min_rate = 600000000u, | ||
445 | .max_rate = 3000000000u, | ||
446 | .max_fb_rate = BCM2835_MAX_FB_RATE, | ||
447 | }; | ||
448 | |||
449 | /* | ||
450 | * PLLD is the display PLL, used to drive DSI display panels. | ||
451 | * | ||
452 | * It is in the PX LDO power domain, which is on when the AUDIO domain | ||
453 | * is on. | ||
454 | */ | ||
455 | static const struct bcm2835_pll_data bcm2835_plld_data = { | ||
456 | .name = "plld", | ||
457 | .cm_ctrl_reg = CM_PLLD, | ||
458 | .a2w_ctrl_reg = A2W_PLLD_CTRL, | ||
459 | .frac_reg = A2W_PLLD_FRAC, | ||
460 | .ana_reg_base = A2W_PLLD_ANA0, | ||
461 | .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE, | ||
462 | .lock_mask = CM_LOCK_FLOCKD, | ||
463 | |||
464 | .ana = &bcm2835_ana_default, | ||
465 | |||
466 | .min_rate = 600000000u, | ||
467 | .max_rate = 2400000000u, | ||
468 | .max_fb_rate = BCM2835_MAX_FB_RATE, | ||
469 | }; | ||
470 | |||
471 | /* | ||
472 | * PLLH is used to supply the pixel clock or the AUX clock for the TV | ||
473 | * encoder. | ||
474 | * | ||
475 | * It is in the HDMI power domain. | ||
476 | */ | ||
477 | static const struct bcm2835_pll_data bcm2835_pllh_data = { | ||
478 | "pllh", | ||
479 | .cm_ctrl_reg = CM_PLLH, | ||
480 | .a2w_ctrl_reg = A2W_PLLH_CTRL, | ||
481 | .frac_reg = A2W_PLLH_FRAC, | ||
482 | .ana_reg_base = A2W_PLLH_ANA0, | ||
483 | .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, | ||
484 | .lock_mask = CM_LOCK_FLOCKH, | ||
485 | |||
486 | .ana = &bcm2835_ana_pllh, | ||
487 | |||
488 | .min_rate = 600000000u, | ||
489 | .max_rate = 3000000000u, | ||
490 | .max_fb_rate = BCM2835_MAX_FB_RATE, | ||
491 | }; | ||
492 | |||
493 | struct bcm2835_pll_divider_data { | ||
494 | const char *name; | ||
495 | const struct bcm2835_pll_data *source_pll; | ||
496 | u32 cm_reg; | ||
497 | u32 a2w_reg; | ||
498 | |||
499 | u32 load_mask; | ||
500 | u32 hold_mask; | ||
501 | u32 fixed_divider; | ||
502 | }; | ||
503 | |||
504 | static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = { | ||
505 | .name = "plla_core", | ||
506 | .source_pll = &bcm2835_plla_data, | ||
507 | .cm_reg = CM_PLLA, | ||
508 | .a2w_reg = A2W_PLLA_CORE, | ||
509 | .load_mask = CM_PLLA_LOADCORE, | ||
510 | .hold_mask = CM_PLLA_HOLDCORE, | ||
511 | .fixed_divider = 1, | ||
512 | }; | ||
513 | |||
514 | static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = { | ||
515 | .name = "plla_per", | ||
516 | .source_pll = &bcm2835_plla_data, | ||
517 | .cm_reg = CM_PLLA, | ||
518 | .a2w_reg = A2W_PLLA_PER, | ||
519 | .load_mask = CM_PLLA_LOADPER, | ||
520 | .hold_mask = CM_PLLA_HOLDPER, | ||
521 | .fixed_divider = 1, | ||
522 | }; | ||
523 | |||
524 | static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = { | ||
525 | .name = "pllb_arm", | ||
526 | .source_pll = &bcm2835_pllb_data, | ||
527 | .cm_reg = CM_PLLB, | ||
528 | .a2w_reg = A2W_PLLB_ARM, | ||
529 | .load_mask = CM_PLLB_LOADARM, | ||
530 | .hold_mask = CM_PLLB_HOLDARM, | ||
531 | .fixed_divider = 1, | ||
532 | }; | ||
533 | |||
534 | static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = { | ||
535 | .name = "pllc_core0", | ||
536 | .source_pll = &bcm2835_pllc_data, | ||
537 | .cm_reg = CM_PLLC, | ||
538 | .a2w_reg = A2W_PLLC_CORE0, | ||
539 | .load_mask = CM_PLLC_LOADCORE0, | ||
540 | .hold_mask = CM_PLLC_HOLDCORE0, | ||
541 | .fixed_divider = 1, | ||
542 | }; | ||
543 | |||
544 | static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = { | ||
545 | .name = "pllc_core1", .source_pll = &bcm2835_pllc_data, | ||
546 | .cm_reg = CM_PLLC, A2W_PLLC_CORE1, | ||
547 | .load_mask = CM_PLLC_LOADCORE1, | ||
548 | .hold_mask = CM_PLLC_HOLDCORE1, | ||
549 | .fixed_divider = 1, | ||
550 | }; | ||
551 | |||
552 | static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = { | ||
553 | .name = "pllc_core2", | ||
554 | .source_pll = &bcm2835_pllc_data, | ||
555 | .cm_reg = CM_PLLC, | ||
556 | .a2w_reg = A2W_PLLC_CORE2, | ||
557 | .load_mask = CM_PLLC_LOADCORE2, | ||
558 | .hold_mask = CM_PLLC_HOLDCORE2, | ||
559 | .fixed_divider = 1, | ||
560 | }; | ||
561 | |||
562 | static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = { | ||
563 | .name = "pllc_per", | ||
564 | .source_pll = &bcm2835_pllc_data, | ||
565 | .cm_reg = CM_PLLC, | ||
566 | .a2w_reg = A2W_PLLC_PER, | ||
567 | .load_mask = CM_PLLC_LOADPER, | ||
568 | .hold_mask = CM_PLLC_HOLDPER, | ||
569 | .fixed_divider = 1, | ||
570 | }; | ||
571 | |||
572 | static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = { | ||
573 | .name = "plld_core", | ||
574 | .source_pll = &bcm2835_plld_data, | ||
575 | .cm_reg = CM_PLLD, | ||
576 | .a2w_reg = A2W_PLLD_CORE, | ||
577 | .load_mask = CM_PLLD_LOADCORE, | ||
578 | .hold_mask = CM_PLLD_HOLDCORE, | ||
579 | .fixed_divider = 1, | ||
580 | }; | ||
581 | |||
582 | static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = { | ||
583 | .name = "plld_per", | ||
584 | .source_pll = &bcm2835_plld_data, | ||
585 | .cm_reg = CM_PLLD, | ||
586 | .a2w_reg = A2W_PLLD_PER, | ||
587 | .load_mask = CM_PLLD_LOADPER, | ||
588 | .hold_mask = CM_PLLD_HOLDPER, | ||
589 | .fixed_divider = 1, | ||
590 | }; | ||
591 | |||
592 | static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = { | ||
593 | .name = "pllh_rcal", | ||
594 | .source_pll = &bcm2835_pllh_data, | ||
595 | .cm_reg = CM_PLLH, | ||
596 | .a2w_reg = A2W_PLLH_RCAL, | ||
597 | .load_mask = CM_PLLH_LOADRCAL, | ||
598 | .hold_mask = 0, | ||
599 | .fixed_divider = 10, | ||
600 | }; | ||
601 | |||
602 | static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = { | ||
603 | .name = "pllh_aux", | ||
604 | .source_pll = &bcm2835_pllh_data, | ||
605 | .cm_reg = CM_PLLH, | ||
606 | .a2w_reg = A2W_PLLH_AUX, | ||
607 | .load_mask = CM_PLLH_LOADAUX, | ||
608 | .hold_mask = 0, | ||
609 | .fixed_divider = 10, | ||
610 | }; | ||
611 | |||
612 | static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = { | ||
613 | .name = "pllh_pix", | ||
614 | .source_pll = &bcm2835_pllh_data, | ||
615 | .cm_reg = CM_PLLH, | ||
616 | .a2w_reg = A2W_PLLH_PIX, | ||
617 | .load_mask = CM_PLLH_LOADPIX, | ||
618 | .hold_mask = 0, | ||
619 | .fixed_divider = 10, | ||
620 | }; | ||
621 | |||
622 | struct bcm2835_clock_data { | ||
623 | const char *name; | ||
624 | |||
625 | const char *const *parents; | ||
626 | int num_mux_parents; | ||
627 | |||
628 | u32 ctl_reg; | ||
629 | u32 div_reg; | ||
630 | |||
631 | /* Number of integer bits in the divider */ | ||
632 | u32 int_bits; | ||
633 | /* Number of fractional bits in the divider */ | ||
634 | u32 frac_bits; | ||
635 | |||
636 | bool is_vpu_clock; | ||
637 | }; | ||
638 | |||
639 | static const char *const bcm2835_clock_per_parents[] = { | ||
640 | "gnd", | ||
641 | "xosc", | ||
642 | "testdebug0", | ||
643 | "testdebug1", | ||
644 | "plla_per", | ||
645 | "pllc_per", | ||
646 | "plld_per", | ||
647 | "pllh_aux", | ||
648 | }; | ||
649 | |||
650 | static const char *const bcm2835_clock_vpu_parents[] = { | ||
651 | "gnd", | ||
652 | "xosc", | ||
653 | "testdebug0", | ||
654 | "testdebug1", | ||
655 | "plla_core", | ||
656 | "pllc_core0", | ||
657 | "plld_core", | ||
658 | "pllh_aux", | ||
659 | "pllc_core1", | ||
660 | "pllc_core2", | ||
661 | }; | ||
662 | |||
663 | static const char *const bcm2835_clock_osc_parents[] = { | ||
664 | "gnd", | ||
665 | "xosc", | ||
666 | "testdebug0", | ||
667 | "testdebug1" | ||
668 | }; | ||
669 | |||
670 | /* | ||
671 | * Used for a 1Mhz clock for the system clocksource, and also used by | ||
672 | * the watchdog timer and the camera pulse generator. | ||
673 | */ | ||
674 | static const struct bcm2835_clock_data bcm2835_clock_timer_data = { | ||
675 | .name = "timer", | ||
676 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), | ||
677 | .parents = bcm2835_clock_osc_parents, | ||
678 | .ctl_reg = CM_TIMERCTL, | ||
679 | .div_reg = CM_TIMERDIV, | ||
680 | .int_bits = 6, | ||
681 | .frac_bits = 12, | ||
682 | }; | ||
683 | |||
684 | /* One Time Programmable Memory clock. Maximum 10Mhz. */ | ||
685 | static const struct bcm2835_clock_data bcm2835_clock_otp_data = { | ||
686 | .name = "otp", | ||
687 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), | ||
688 | .parents = bcm2835_clock_osc_parents, | ||
689 | .ctl_reg = CM_OTPCTL, | ||
690 | .div_reg = CM_OTPDIV, | ||
691 | .int_bits = 4, | ||
692 | .frac_bits = 0, | ||
693 | }; | ||
694 | |||
695 | /* | ||
696 | * VPU clock. This doesn't have an enable bit, since it drives the | ||
697 | * bus for everything else, and is special so it doesn't need to be | ||
698 | * gated for rate changes. It is also known as "clk_audio" in various | ||
699 | * hardware documentation. | ||
700 | */ | ||
701 | static const struct bcm2835_clock_data bcm2835_clock_vpu_data = { | ||
702 | .name = "vpu", | ||
703 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), | ||
704 | .parents = bcm2835_clock_vpu_parents, | ||
705 | .ctl_reg = CM_VPUCTL, | ||
706 | .div_reg = CM_VPUDIV, | ||
707 | .int_bits = 12, | ||
708 | .frac_bits = 8, | ||
709 | .is_vpu_clock = true, | ||
710 | }; | ||
711 | |||
712 | static const struct bcm2835_clock_data bcm2835_clock_v3d_data = { | ||
713 | .name = "v3d", | ||
714 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), | ||
715 | .parents = bcm2835_clock_vpu_parents, | ||
716 | .ctl_reg = CM_V3DCTL, | ||
717 | .div_reg = CM_V3DDIV, | ||
718 | .int_bits = 4, | ||
719 | .frac_bits = 8, | ||
720 | }; | ||
721 | |||
722 | static const struct bcm2835_clock_data bcm2835_clock_isp_data = { | ||
723 | .name = "isp", | ||
724 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), | ||
725 | .parents = bcm2835_clock_vpu_parents, | ||
726 | .ctl_reg = CM_ISPCTL, | ||
727 | .div_reg = CM_ISPDIV, | ||
728 | .int_bits = 4, | ||
729 | .frac_bits = 8, | ||
730 | }; | ||
731 | |||
732 | static const struct bcm2835_clock_data bcm2835_clock_h264_data = { | ||
733 | .name = "h264", | ||
734 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), | ||
735 | .parents = bcm2835_clock_vpu_parents, | ||
736 | .ctl_reg = CM_H264CTL, | ||
737 | .div_reg = CM_H264DIV, | ||
738 | .int_bits = 4, | ||
739 | .frac_bits = 8, | ||
740 | }; | ||
741 | |||
742 | /* TV encoder clock. Only operating frequency is 108Mhz. */ | ||
743 | static const struct bcm2835_clock_data bcm2835_clock_vec_data = { | ||
744 | .name = "vec", | ||
745 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), | ||
746 | .parents = bcm2835_clock_per_parents, | ||
747 | .ctl_reg = CM_VECCTL, | ||
748 | .div_reg = CM_VECDIV, | ||
749 | .int_bits = 4, | ||
750 | .frac_bits = 0, | ||
751 | }; | ||
752 | |||
753 | static const struct bcm2835_clock_data bcm2835_clock_uart_data = { | ||
754 | .name = "uart", | ||
755 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), | ||
756 | .parents = bcm2835_clock_per_parents, | ||
757 | .ctl_reg = CM_UARTCTL, | ||
758 | .div_reg = CM_UARTDIV, | ||
759 | .int_bits = 10, | ||
760 | .frac_bits = 12, | ||
761 | }; | ||
762 | |||
763 | /* HDMI state machine */ | ||
764 | static const struct bcm2835_clock_data bcm2835_clock_hsm_data = { | ||
765 | .name = "hsm", | ||
766 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), | ||
767 | .parents = bcm2835_clock_per_parents, | ||
768 | .ctl_reg = CM_HSMCTL, | ||
769 | .div_reg = CM_HSMDIV, | ||
770 | .int_bits = 4, | ||
771 | .frac_bits = 8, | ||
772 | }; | ||
773 | |||
774 | /* | ||
775 | * Secondary SDRAM clock. Used for low-voltage modes when the PLL in | ||
776 | * the SDRAM controller can't be used. | ||
777 | */ | ||
778 | static const struct bcm2835_clock_data bcm2835_clock_sdram_data = { | ||
779 | .name = "sdram", | ||
780 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), | ||
781 | .parents = bcm2835_clock_vpu_parents, | ||
782 | .ctl_reg = CM_SDCCTL, | ||
783 | .div_reg = CM_SDCDIV, | ||
784 | .int_bits = 6, | ||
785 | .frac_bits = 0, | ||
786 | }; | ||
787 | |||
788 | /* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */ | ||
789 | static const struct bcm2835_clock_data bcm2835_clock_tsens_data = { | ||
790 | .name = "tsens", | ||
791 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), | ||
792 | .parents = bcm2835_clock_osc_parents, | ||
793 | .ctl_reg = CM_TSENSCTL, | ||
794 | .div_reg = CM_TSENSDIV, | ||
795 | .int_bits = 5, | ||
796 | .frac_bits = 0, | ||
797 | }; | ||
798 | |||
799 | /* Arasan EMMC clock */ | ||
800 | static const struct bcm2835_clock_data bcm2835_clock_emmc_data = { | ||
801 | .name = "emmc", | ||
802 | .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), | ||
803 | .parents = bcm2835_clock_per_parents, | ||
804 | .ctl_reg = CM_EMMCCTL, | ||
805 | .div_reg = CM_EMMCDIV, | ||
806 | .int_bits = 4, | ||
807 | .frac_bits = 8, | ||
808 | }; | ||
809 | |||
810 | struct bcm2835_pll { | ||
811 | struct clk_hw hw; | ||
812 | struct bcm2835_cprman *cprman; | ||
813 | const struct bcm2835_pll_data *data; | ||
814 | }; | ||
815 | |||
816 | static int bcm2835_pll_is_on(struct clk_hw *hw) | ||
817 | { | ||
818 | struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); | ||
819 | struct bcm2835_cprman *cprman = pll->cprman; | ||
820 | const struct bcm2835_pll_data *data = pll->data; | ||
821 | |||
822 | return cprman_read(cprman, data->a2w_ctrl_reg) & | ||
823 | A2W_PLL_CTRL_PRST_DISABLE; | ||
824 | } | ||
825 | |||
826 | static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate, | ||
827 | unsigned long parent_rate, | ||
828 | u32 *ndiv, u32 *fdiv) | ||
829 | { | ||
830 | u64 div; | ||
831 | |||
832 | div = (u64)rate << A2W_PLL_FRAC_BITS; | ||
833 | do_div(div, parent_rate); | ||
834 | |||
835 | *ndiv = div >> A2W_PLL_FRAC_BITS; | ||
836 | *fdiv = div & ((1 << A2W_PLL_FRAC_BITS) - 1); | ||
837 | } | ||
838 | |||
839 | static long bcm2835_pll_rate_from_divisors(unsigned long parent_rate, | ||
840 | u32 ndiv, u32 fdiv, u32 pdiv) | ||
841 | { | ||
842 | u64 rate; | ||
843 | |||
844 | if (pdiv == 0) | ||
845 | return 0; | ||
846 | |||
847 | rate = (u64)parent_rate * ((ndiv << A2W_PLL_FRAC_BITS) + fdiv); | ||
848 | do_div(rate, pdiv); | ||
849 | return rate >> A2W_PLL_FRAC_BITS; | ||
850 | } | ||
851 | |||
852 | static long bcm2835_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
853 | unsigned long *parent_rate) | ||
854 | { | ||
855 | u32 ndiv, fdiv; | ||
856 | |||
857 | bcm2835_pll_choose_ndiv_and_fdiv(rate, *parent_rate, &ndiv, &fdiv); | ||
858 | |||
859 | return bcm2835_pll_rate_from_divisors(*parent_rate, ndiv, fdiv, 1); | ||
860 | } | ||
861 | |||
862 | static unsigned long bcm2835_pll_get_rate(struct clk_hw *hw, | ||
863 | unsigned long parent_rate) | ||
864 | { | ||
865 | struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); | ||
866 | struct bcm2835_cprman *cprman = pll->cprman; | ||
867 | const struct bcm2835_pll_data *data = pll->data; | ||
868 | u32 a2wctrl = cprman_read(cprman, data->a2w_ctrl_reg); | ||
869 | u32 ndiv, pdiv, fdiv; | ||
870 | bool using_prediv; | ||
871 | |||
872 | if (parent_rate == 0) | ||
873 | return 0; | ||
874 | |||
875 | fdiv = cprman_read(cprman, data->frac_reg) & A2W_PLL_FRAC_MASK; | ||
876 | ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT; | ||
877 | pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT; | ||
878 | using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & | ||
879 | data->ana->fb_prediv_mask; | ||
880 | |||
881 | if (using_prediv) | ||
882 | ndiv *= 2; | ||
883 | |||
884 | return bcm2835_pll_rate_from_divisors(parent_rate, ndiv, fdiv, pdiv); | ||
885 | } | ||
886 | |||
887 | static void bcm2835_pll_off(struct clk_hw *hw) | ||
888 | { | ||
889 | struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); | ||
890 | struct bcm2835_cprman *cprman = pll->cprman; | ||
891 | const struct bcm2835_pll_data *data = pll->data; | ||
892 | |||
893 | cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); | ||
894 | cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN); | ||
895 | } | ||
896 | |||
897 | static int bcm2835_pll_on(struct clk_hw *hw) | ||
898 | { | ||
899 | struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); | ||
900 | struct bcm2835_cprman *cprman = pll->cprman; | ||
901 | const struct bcm2835_pll_data *data = pll->data; | ||
902 | ktime_t timeout; | ||
903 | |||
904 | /* Take the PLL out of reset. */ | ||
905 | cprman_write(cprman, data->cm_ctrl_reg, | ||
906 | cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST); | ||
907 | |||
908 | /* Wait for the PLL to lock. */ | ||
909 | timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); | ||
910 | while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) { | ||
911 | if (ktime_after(ktime_get(), timeout)) { | ||
912 | dev_err(cprman->dev, "%s: couldn't lock PLL\n", | ||
913 | clk_hw_get_name(hw)); | ||
914 | return -ETIMEDOUT; | ||
915 | } | ||
916 | |||
917 | cpu_relax(); | ||
918 | } | ||
919 | |||
920 | return 0; | ||
921 | } | ||
922 | |||
923 | static void | ||
924 | bcm2835_pll_write_ana(struct bcm2835_cprman *cprman, u32 ana_reg_base, u32 *ana) | ||
925 | { | ||
926 | int i; | ||
927 | |||
928 | /* | ||
929 | * ANA register setup is done as a series of writes to | ||
930 | * ANA3-ANA0, in that order. This lets us write all 4 | ||
931 | * registers as a single cycle of the serdes interface (taking | ||
932 | * 100 xosc clocks), whereas if we were to update ana0, 1, and | ||
933 | * 3 individually through their partial-write registers, each | ||
934 | * would be their own serdes cycle. | ||
935 | */ | ||
936 | for (i = 3; i >= 0; i--) | ||
937 | cprman_write(cprman, ana_reg_base + i * 4, ana[i]); | ||
938 | } | ||
939 | |||
940 | static int bcm2835_pll_set_rate(struct clk_hw *hw, | ||
941 | unsigned long rate, unsigned long parent_rate) | ||
942 | { | ||
943 | struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); | ||
944 | struct bcm2835_cprman *cprman = pll->cprman; | ||
945 | const struct bcm2835_pll_data *data = pll->data; | ||
946 | bool was_using_prediv, use_fb_prediv, do_ana_setup_first; | ||
947 | u32 ndiv, fdiv, a2w_ctl; | ||
948 | u32 ana[4]; | ||
949 | int i; | ||
950 | |||
951 | if (rate < data->min_rate || rate > data->max_rate) { | ||
952 | dev_err(cprman->dev, "%s: rate out of spec: %lu vs (%lu, %lu)\n", | ||
953 | clk_hw_get_name(hw), rate, | ||
954 | data->min_rate, data->max_rate); | ||
955 | return -EINVAL; | ||
956 | } | ||
957 | |||
958 | if (rate > data->max_fb_rate) { | ||
959 | use_fb_prediv = true; | ||
960 | rate /= 2; | ||
961 | } else { | ||
962 | use_fb_prediv = false; | ||
963 | } | ||
964 | |||
965 | bcm2835_pll_choose_ndiv_and_fdiv(rate, parent_rate, &ndiv, &fdiv); | ||
966 | |||
967 | for (i = 3; i >= 0; i--) | ||
968 | ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4); | ||
969 | |||
970 | was_using_prediv = ana[1] & data->ana->fb_prediv_mask; | ||
971 | |||
972 | ana[0] &= ~data->ana->mask0; | ||
973 | ana[0] |= data->ana->set0; | ||
974 | ana[1] &= ~data->ana->mask1; | ||
975 | ana[1] |= data->ana->set1; | ||
976 | ana[3] &= ~data->ana->mask3; | ||
977 | ana[3] |= data->ana->set3; | ||
978 | |||
979 | if (was_using_prediv && !use_fb_prediv) { | ||
980 | ana[1] &= ~data->ana->fb_prediv_mask; | ||
981 | do_ana_setup_first = true; | ||
982 | } else if (!was_using_prediv && use_fb_prediv) { | ||
983 | ana[1] |= data->ana->fb_prediv_mask; | ||
984 | do_ana_setup_first = false; | ||
985 | } else { | ||
986 | do_ana_setup_first = true; | ||
987 | } | ||
988 | |||
989 | /* Unmask the reference clock from the oscillator. */ | ||
990 | cprman_write(cprman, A2W_XOSC_CTRL, | ||
991 | cprman_read(cprman, A2W_XOSC_CTRL) | | ||
992 | data->reference_enable_mask); | ||
993 | |||
994 | if (do_ana_setup_first) | ||
995 | bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana); | ||
996 | |||
997 | /* Set the PLL multiplier from the oscillator. */ | ||
998 | cprman_write(cprman, data->frac_reg, fdiv); | ||
999 | |||
1000 | a2w_ctl = cprman_read(cprman, data->a2w_ctrl_reg); | ||
1001 | a2w_ctl &= ~A2W_PLL_CTRL_NDIV_MASK; | ||
1002 | a2w_ctl |= ndiv << A2W_PLL_CTRL_NDIV_SHIFT; | ||
1003 | a2w_ctl &= ~A2W_PLL_CTRL_PDIV_MASK; | ||
1004 | a2w_ctl |= 1 << A2W_PLL_CTRL_PDIV_SHIFT; | ||
1005 | cprman_write(cprman, data->a2w_ctrl_reg, a2w_ctl); | ||
1006 | |||
1007 | if (!do_ana_setup_first) | ||
1008 | bcm2835_pll_write_ana(cprman, data->ana_reg_base, ana); | ||
1009 | |||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | static const struct clk_ops bcm2835_pll_clk_ops = { | ||
1014 | .is_prepared = bcm2835_pll_is_on, | ||
1015 | .prepare = bcm2835_pll_on, | ||
1016 | .unprepare = bcm2835_pll_off, | ||
1017 | .recalc_rate = bcm2835_pll_get_rate, | ||
1018 | .set_rate = bcm2835_pll_set_rate, | ||
1019 | .round_rate = bcm2835_pll_round_rate, | ||
1020 | }; | ||
1021 | |||
1022 | struct bcm2835_pll_divider { | ||
1023 | struct clk_divider div; | ||
1024 | struct bcm2835_cprman *cprman; | ||
1025 | const struct bcm2835_pll_divider_data *data; | ||
1026 | }; | ||
1027 | |||
1028 | static struct bcm2835_pll_divider * | ||
1029 | bcm2835_pll_divider_from_hw(struct clk_hw *hw) | ||
1030 | { | ||
1031 | return container_of(hw, struct bcm2835_pll_divider, div.hw); | ||
1032 | } | ||
1033 | |||
1034 | static int bcm2835_pll_divider_is_on(struct clk_hw *hw) | ||
1035 | { | ||
1036 | struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); | ||
1037 | struct bcm2835_cprman *cprman = divider->cprman; | ||
1038 | const struct bcm2835_pll_divider_data *data = divider->data; | ||
1039 | |||
1040 | return !(cprman_read(cprman, data->a2w_reg) & A2W_PLL_CHANNEL_DISABLE); | ||
1041 | } | ||
1042 | |||
1043 | static long bcm2835_pll_divider_round_rate(struct clk_hw *hw, | ||
1044 | unsigned long rate, | ||
1045 | unsigned long *parent_rate) | ||
1046 | { | ||
1047 | return clk_divider_ops.round_rate(hw, rate, parent_rate); | ||
1048 | } | ||
1049 | |||
1050 | static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw, | ||
1051 | unsigned long parent_rate) | ||
1052 | { | ||
1053 | struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); | ||
1054 | struct bcm2835_cprman *cprman = divider->cprman; | ||
1055 | const struct bcm2835_pll_divider_data *data = divider->data; | ||
1056 | u32 div = cprman_read(cprman, data->a2w_reg); | ||
1057 | |||
1058 | div &= (1 << A2W_PLL_DIV_BITS) - 1; | ||
1059 | if (div == 0) | ||
1060 | div = 256; | ||
1061 | |||
1062 | return parent_rate / div; | ||
1063 | } | ||
1064 | |||
1065 | static void bcm2835_pll_divider_off(struct clk_hw *hw) | ||
1066 | { | ||
1067 | struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); | ||
1068 | struct bcm2835_cprman *cprman = divider->cprman; | ||
1069 | const struct bcm2835_pll_divider_data *data = divider->data; | ||
1070 | |||
1071 | cprman_write(cprman, data->cm_reg, | ||
1072 | (cprman_read(cprman, data->cm_reg) & | ||
1073 | ~data->load_mask) | data->hold_mask); | ||
1074 | cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); | ||
1075 | } | ||
1076 | |||
1077 | static int bcm2835_pll_divider_on(struct clk_hw *hw) | ||
1078 | { | ||
1079 | struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); | ||
1080 | struct bcm2835_cprman *cprman = divider->cprman; | ||
1081 | const struct bcm2835_pll_divider_data *data = divider->data; | ||
1082 | |||
1083 | cprman_write(cprman, data->a2w_reg, | ||
1084 | cprman_read(cprman, data->a2w_reg) & | ||
1085 | ~A2W_PLL_CHANNEL_DISABLE); | ||
1086 | |||
1087 | cprman_write(cprman, data->cm_reg, | ||
1088 | cprman_read(cprman, data->cm_reg) & ~data->hold_mask); | ||
1089 | |||
1090 | return 0; | ||
1091 | } | ||
1092 | |||
1093 | static int bcm2835_pll_divider_set_rate(struct clk_hw *hw, | ||
1094 | unsigned long rate, | ||
1095 | unsigned long parent_rate) | ||
1096 | { | ||
1097 | struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); | ||
1098 | struct bcm2835_cprman *cprman = divider->cprman; | ||
1099 | const struct bcm2835_pll_divider_data *data = divider->data; | ||
1100 | u32 cm; | ||
1101 | int ret; | ||
1102 | |||
1103 | ret = clk_divider_ops.set_rate(hw, rate, parent_rate); | ||
1104 | if (ret) | ||
1105 | return ret; | ||
1106 | |||
1107 | cm = cprman_read(cprman, data->cm_reg); | ||
1108 | cprman_write(cprman, data->cm_reg, cm | data->load_mask); | ||
1109 | cprman_write(cprman, data->cm_reg, cm & ~data->load_mask); | ||
1110 | |||
1111 | return 0; | ||
1112 | } | ||
1113 | |||
1114 | static const struct clk_ops bcm2835_pll_divider_clk_ops = { | ||
1115 | .is_prepared = bcm2835_pll_divider_is_on, | ||
1116 | .prepare = bcm2835_pll_divider_on, | ||
1117 | .unprepare = bcm2835_pll_divider_off, | ||
1118 | .recalc_rate = bcm2835_pll_divider_get_rate, | ||
1119 | .set_rate = bcm2835_pll_divider_set_rate, | ||
1120 | .round_rate = bcm2835_pll_divider_round_rate, | ||
1121 | }; | ||
1122 | |||
1123 | /* | ||
1124 | * The CM dividers do fixed-point division, so we can't use the | ||
1125 | * generic integer divider code like the PLL dividers do (and we can't | ||
1126 | * fake it by having some fixed shifts preceding it in the clock tree, | ||
1127 | * because we'd run out of bits in a 32-bit unsigned long). | ||
1128 | */ | ||
1129 | struct bcm2835_clock { | ||
1130 | struct clk_hw hw; | ||
1131 | struct bcm2835_cprman *cprman; | ||
1132 | const struct bcm2835_clock_data *data; | ||
1133 | }; | ||
1134 | |||
1135 | static struct bcm2835_clock *bcm2835_clock_from_hw(struct clk_hw *hw) | ||
1136 | { | ||
1137 | return container_of(hw, struct bcm2835_clock, hw); | ||
1138 | } | ||
1139 | |||
1140 | static int bcm2835_clock_is_on(struct clk_hw *hw) | ||
1141 | { | ||
1142 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1143 | struct bcm2835_cprman *cprman = clock->cprman; | ||
1144 | const struct bcm2835_clock_data *data = clock->data; | ||
1145 | |||
1146 | return (cprman_read(cprman, data->ctl_reg) & CM_ENABLE) != 0; | ||
1147 | } | ||
1148 | |||
1149 | static u32 bcm2835_clock_choose_div(struct clk_hw *hw, | ||
1150 | unsigned long rate, | ||
1151 | unsigned long parent_rate) | ||
1152 | { | ||
1153 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1154 | const struct bcm2835_clock_data *data = clock->data; | ||
1155 | u32 unused_frac_mask = GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0); | ||
1156 | u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS; | ||
1157 | u32 div; | ||
1158 | |||
1159 | do_div(temp, rate); | ||
1160 | div = temp; | ||
1161 | |||
1162 | /* Round and mask off the unused bits */ | ||
1163 | if (unused_frac_mask != 0) { | ||
1164 | div += unused_frac_mask >> 1; | ||
1165 | div &= ~unused_frac_mask; | ||
1166 | } | ||
1167 | |||
1168 | /* Clamp to the limits. */ | ||
1169 | div = max(div, unused_frac_mask + 1); | ||
1170 | div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, | ||
1171 | CM_DIV_FRAC_BITS - data->frac_bits)); | ||
1172 | |||
1173 | return div; | ||
1174 | } | ||
1175 | |||
1176 | static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, | ||
1177 | unsigned long parent_rate, | ||
1178 | u32 div) | ||
1179 | { | ||
1180 | const struct bcm2835_clock_data *data = clock->data; | ||
1181 | u64 temp; | ||
1182 | |||
1183 | /* | ||
1184 | * The divisor is a 12.12 fixed point field, but only some of | ||
1185 | * the bits are populated in any given clock. | ||
1186 | */ | ||
1187 | div >>= CM_DIV_FRAC_BITS - data->frac_bits; | ||
1188 | div &= (1 << (data->int_bits + data->frac_bits)) - 1; | ||
1189 | |||
1190 | if (div == 0) | ||
1191 | return 0; | ||
1192 | |||
1193 | temp = (u64)parent_rate << data->frac_bits; | ||
1194 | |||
1195 | do_div(temp, div); | ||
1196 | |||
1197 | return temp; | ||
1198 | } | ||
1199 | |||
1200 | static long bcm2835_clock_round_rate(struct clk_hw *hw, | ||
1201 | unsigned long rate, | ||
1202 | unsigned long *parent_rate) | ||
1203 | { | ||
1204 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1205 | u32 div = bcm2835_clock_choose_div(hw, rate, *parent_rate); | ||
1206 | |||
1207 | return bcm2835_clock_rate_from_divisor(clock, *parent_rate, div); | ||
1208 | } | ||
1209 | |||
1210 | static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, | ||
1211 | unsigned long parent_rate) | ||
1212 | { | ||
1213 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1214 | struct bcm2835_cprman *cprman = clock->cprman; | ||
1215 | const struct bcm2835_clock_data *data = clock->data; | ||
1216 | u32 div = cprman_read(cprman, data->div_reg); | ||
1217 | |||
1218 | return bcm2835_clock_rate_from_divisor(clock, parent_rate, div); | ||
1219 | } | ||
1220 | |||
1221 | static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock) | ||
1222 | { | ||
1223 | struct bcm2835_cprman *cprman = clock->cprman; | ||
1224 | const struct bcm2835_clock_data *data = clock->data; | ||
1225 | ktime_t timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS); | ||
1226 | |||
1227 | while (cprman_read(cprman, data->ctl_reg) & CM_BUSY) { | ||
1228 | if (ktime_after(ktime_get(), timeout)) { | ||
1229 | dev_err(cprman->dev, "%s: couldn't lock PLL\n", | ||
1230 | clk_hw_get_name(&clock->hw)); | ||
1231 | return; | ||
1232 | } | ||
1233 | cpu_relax(); | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | static void bcm2835_clock_off(struct clk_hw *hw) | ||
1238 | { | ||
1239 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1240 | struct bcm2835_cprman *cprman = clock->cprman; | ||
1241 | const struct bcm2835_clock_data *data = clock->data; | ||
1242 | |||
1243 | spin_lock(&cprman->regs_lock); | ||
1244 | cprman_write(cprman, data->ctl_reg, | ||
1245 | cprman_read(cprman, data->ctl_reg) & ~CM_ENABLE); | ||
1246 | spin_unlock(&cprman->regs_lock); | ||
1247 | |||
1248 | /* BUSY will remain high until the divider completes its cycle. */ | ||
1249 | bcm2835_clock_wait_busy(clock); | ||
1250 | } | ||
1251 | |||
1252 | static int bcm2835_clock_on(struct clk_hw *hw) | ||
1253 | { | ||
1254 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1255 | struct bcm2835_cprman *cprman = clock->cprman; | ||
1256 | const struct bcm2835_clock_data *data = clock->data; | ||
1257 | |||
1258 | spin_lock(&cprman->regs_lock); | ||
1259 | cprman_write(cprman, data->ctl_reg, | ||
1260 | cprman_read(cprman, data->ctl_reg) | | ||
1261 | CM_ENABLE | | ||
1262 | CM_GATE); | ||
1263 | spin_unlock(&cprman->regs_lock); | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | static int bcm2835_clock_set_rate(struct clk_hw *hw, | ||
1269 | unsigned long rate, unsigned long parent_rate) | ||
1270 | { | ||
1271 | struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); | ||
1272 | struct bcm2835_cprman *cprman = clock->cprman; | ||
1273 | const struct bcm2835_clock_data *data = clock->data; | ||
1274 | u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate); | ||
1275 | |||
1276 | cprman_write(cprman, data->div_reg, div); | ||
1277 | |||
1278 | return 0; | ||
1279 | } | ||
1280 | |||
1281 | static const struct clk_ops bcm2835_clock_clk_ops = { | ||
1282 | .is_prepared = bcm2835_clock_is_on, | ||
1283 | .prepare = bcm2835_clock_on, | ||
1284 | .unprepare = bcm2835_clock_off, | ||
1285 | .recalc_rate = bcm2835_clock_get_rate, | ||
1286 | .set_rate = bcm2835_clock_set_rate, | ||
1287 | .round_rate = bcm2835_clock_round_rate, | ||
1288 | }; | ||
1289 | |||
1290 | static int bcm2835_vpu_clock_is_on(struct clk_hw *hw) | ||
1291 | { | ||
1292 | return true; | ||
1293 | } | ||
1294 | |||
1295 | /* | ||
1296 | * The VPU clock can never be disabled (it doesn't have an ENABLE | ||
1297 | * bit), so it gets its own set of clock ops. | ||
1298 | */ | ||
1299 | static const struct clk_ops bcm2835_vpu_clock_clk_ops = { | ||
1300 | .is_prepared = bcm2835_vpu_clock_is_on, | ||
1301 | .recalc_rate = bcm2835_clock_get_rate, | ||
1302 | .set_rate = bcm2835_clock_set_rate, | ||
1303 | .round_rate = bcm2835_clock_round_rate, | ||
1304 | }; | ||
1305 | |||
1306 | static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman, | ||
1307 | const struct bcm2835_pll_data *data) | ||
1308 | { | ||
1309 | struct bcm2835_pll *pll; | ||
1310 | struct clk_init_data init; | ||
1311 | |||
1312 | memset(&init, 0, sizeof(init)); | ||
1313 | |||
1314 | /* All of the PLLs derive from the external oscillator. */ | ||
1315 | init.parent_names = &cprman->osc_name; | ||
1316 | init.num_parents = 1; | ||
1317 | init.name = data->name; | ||
1318 | init.ops = &bcm2835_pll_clk_ops; | ||
1319 | init.flags = CLK_IGNORE_UNUSED; | ||
1320 | |||
1321 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); | ||
1322 | if (!pll) | ||
1323 | return NULL; | ||
1324 | |||
1325 | pll->cprman = cprman; | ||
1326 | pll->data = data; | ||
1327 | pll->hw.init = &init; | ||
1328 | |||
1329 | return devm_clk_register(cprman->dev, &pll->hw); | ||
1330 | } | ||
1331 | |||
1332 | static struct clk * | ||
1333 | bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, | ||
1334 | const struct bcm2835_pll_divider_data *data) | ||
1335 | { | ||
1336 | struct bcm2835_pll_divider *divider; | ||
1337 | struct clk_init_data init; | ||
1338 | struct clk *clk; | ||
1339 | const char *divider_name; | ||
1340 | |||
1341 | if (data->fixed_divider != 1) { | ||
1342 | divider_name = devm_kasprintf(cprman->dev, GFP_KERNEL, | ||
1343 | "%s_prediv", data->name); | ||
1344 | if (!divider_name) | ||
1345 | return NULL; | ||
1346 | } else { | ||
1347 | divider_name = data->name; | ||
1348 | } | ||
1349 | |||
1350 | memset(&init, 0, sizeof(init)); | ||
1351 | |||
1352 | init.parent_names = &data->source_pll->name; | ||
1353 | init.num_parents = 1; | ||
1354 | init.name = divider_name; | ||
1355 | init.ops = &bcm2835_pll_divider_clk_ops; | ||
1356 | init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED; | ||
1357 | |||
1358 | divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL); | ||
1359 | if (!divider) | ||
1360 | return NULL; | ||
1361 | |||
1362 | divider->div.reg = cprman->regs + data->a2w_reg; | ||
1363 | divider->div.shift = A2W_PLL_DIV_SHIFT; | ||
1364 | divider->div.width = A2W_PLL_DIV_BITS; | ||
1365 | divider->div.flags = 0; | ||
1366 | divider->div.lock = &cprman->regs_lock; | ||
1367 | divider->div.hw.init = &init; | ||
1368 | divider->div.table = NULL; | ||
1369 | |||
1370 | divider->cprman = cprman; | ||
1371 | divider->data = data; | ||
1372 | |||
1373 | clk = devm_clk_register(cprman->dev, ÷r->div.hw); | ||
1374 | if (IS_ERR(clk)) | ||
1375 | return clk; | ||
1376 | |||
1377 | /* | ||
1378 | * PLLH's channels have a fixed divide by 10 afterwards, which | ||
1379 | * is what our consumers are actually using. | ||
1380 | */ | ||
1381 | if (data->fixed_divider != 1) { | ||
1382 | return clk_register_fixed_factor(cprman->dev, data->name, | ||
1383 | divider_name, | ||
1384 | CLK_SET_RATE_PARENT, | ||
1385 | 1, | ||
1386 | data->fixed_divider); | ||
1387 | } | ||
1388 | |||
1389 | return clk; | ||
1390 | } | ||
1391 | |||
1392 | static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman, | ||
1393 | const struct bcm2835_clock_data *data) | ||
1394 | { | ||
1395 | struct bcm2835_clock *clock; | ||
1396 | struct clk_init_data init; | ||
1397 | const char *parent; | ||
1398 | |||
1399 | /* | ||
1400 | * Most of the clock generators have a mux field, so we | ||
1401 | * instantiate a generic mux as our parent to handle it. | ||
1402 | */ | ||
1403 | if (data->num_mux_parents) { | ||
1404 | const char *parents[1 << CM_SRC_BITS]; | ||
1405 | int i; | ||
1406 | |||
1407 | parent = devm_kasprintf(cprman->dev, GFP_KERNEL, | ||
1408 | "mux_%s", data->name); | ||
1409 | if (!parent) | ||
1410 | return NULL; | ||
1411 | |||
1412 | /* | ||
1413 | * Replace our "xosc" references with the oscillator's | ||
1414 | * actual name. | ||
1415 | */ | ||
1416 | for (i = 0; i < data->num_mux_parents; i++) { | ||
1417 | if (strcmp(data->parents[i], "xosc") == 0) | ||
1418 | parents[i] = cprman->osc_name; | ||
1419 | else | ||
1420 | parents[i] = data->parents[i]; | ||
1421 | } | ||
1422 | |||
1423 | clk_register_mux(cprman->dev, parent, | ||
1424 | parents, data->num_mux_parents, | ||
1425 | CLK_SET_RATE_PARENT, | ||
1426 | cprman->regs + data->ctl_reg, | ||
1427 | CM_SRC_SHIFT, CM_SRC_BITS, | ||
1428 | 0, &cprman->regs_lock); | ||
1429 | } else { | ||
1430 | parent = data->parents[0]; | ||
1431 | } | ||
1432 | |||
1433 | memset(&init, 0, sizeof(init)); | ||
1434 | init.parent_names = &parent; | ||
1435 | init.num_parents = 1; | ||
1436 | init.name = data->name; | ||
1437 | init.flags = CLK_IGNORE_UNUSED; | ||
1438 | |||
1439 | if (data->is_vpu_clock) { | ||
1440 | init.ops = &bcm2835_vpu_clock_clk_ops; | ||
1441 | } else { | ||
1442 | init.ops = &bcm2835_clock_clk_ops; | ||
1443 | init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | ||
1444 | } | ||
1445 | |||
1446 | clock = devm_kzalloc(cprman->dev, sizeof(*clock), GFP_KERNEL); | ||
1447 | if (!clock) | ||
1448 | return NULL; | ||
1449 | |||
1450 | clock->cprman = cprman; | ||
1451 | clock->data = data; | ||
1452 | clock->hw.init = &init; | ||
1453 | |||
1454 | return devm_clk_register(cprman->dev, &clock->hw); | ||
1455 | } | ||
1456 | |||
1457 | static int bcm2835_clk_probe(struct platform_device *pdev) | ||
1458 | { | ||
1459 | struct device *dev = &pdev->dev; | ||
1460 | struct clk **clks; | ||
1461 | struct bcm2835_cprman *cprman; | ||
1462 | struct resource *res; | ||
1463 | |||
1464 | cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL); | ||
1465 | if (!cprman) | ||
1466 | return -ENOMEM; | ||
1467 | |||
1468 | spin_lock_init(&cprman->regs_lock); | ||
1469 | cprman->dev = dev; | ||
1470 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1471 | cprman->regs = devm_ioremap_resource(dev, res); | ||
1472 | if (IS_ERR(cprman->regs)) | ||
1473 | return PTR_ERR(cprman->regs); | ||
1474 | |||
1475 | cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); | ||
1476 | if (!cprman->osc_name) | ||
1477 | return -ENODEV; | ||
1478 | |||
1479 | platform_set_drvdata(pdev, cprman); | ||
1480 | |||
1481 | cprman->onecell.clk_num = BCM2835_CLOCK_COUNT; | ||
1482 | cprman->onecell.clks = cprman->clks; | ||
1483 | clks = cprman->clks; | ||
1484 | |||
1485 | clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data); | ||
1486 | clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data); | ||
1487 | clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data); | ||
1488 | clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data); | ||
1489 | clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data); | ||
1490 | |||
1491 | clks[BCM2835_PLLA_CORE] = | ||
1492 | bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data); | ||
1493 | clks[BCM2835_PLLA_PER] = | ||
1494 | bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data); | ||
1495 | clks[BCM2835_PLLC_CORE0] = | ||
1496 | bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data); | ||
1497 | clks[BCM2835_PLLC_CORE1] = | ||
1498 | bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data); | ||
1499 | clks[BCM2835_PLLC_CORE2] = | ||
1500 | bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data); | ||
1501 | clks[BCM2835_PLLC_PER] = | ||
1502 | bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data); | ||
1503 | clks[BCM2835_PLLD_CORE] = | ||
1504 | bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data); | ||
1505 | clks[BCM2835_PLLD_PER] = | ||
1506 | bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data); | ||
1507 | clks[BCM2835_PLLH_RCAL] = | ||
1508 | bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data); | ||
1509 | clks[BCM2835_PLLH_AUX] = | ||
1510 | bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data); | ||
1511 | clks[BCM2835_PLLH_PIX] = | ||
1512 | bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data); | ||
1513 | |||
1514 | clks[BCM2835_CLOCK_TIMER] = | ||
1515 | bcm2835_register_clock(cprman, &bcm2835_clock_timer_data); | ||
1516 | clks[BCM2835_CLOCK_OTP] = | ||
1517 | bcm2835_register_clock(cprman, &bcm2835_clock_otp_data); | ||
1518 | clks[BCM2835_CLOCK_TSENS] = | ||
1519 | bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data); | ||
1520 | clks[BCM2835_CLOCK_VPU] = | ||
1521 | bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data); | ||
1522 | clks[BCM2835_CLOCK_V3D] = | ||
1523 | bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); | ||
1524 | clks[BCM2835_CLOCK_ISP] = | ||
1525 | bcm2835_register_clock(cprman, &bcm2835_clock_isp_data); | ||
1526 | clks[BCM2835_CLOCK_H264] = | ||
1527 | bcm2835_register_clock(cprman, &bcm2835_clock_h264_data); | ||
1528 | clks[BCM2835_CLOCK_V3D] = | ||
1529 | bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); | ||
1530 | clks[BCM2835_CLOCK_SDRAM] = | ||
1531 | bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data); | ||
1532 | clks[BCM2835_CLOCK_UART] = | ||
1533 | bcm2835_register_clock(cprman, &bcm2835_clock_uart_data); | ||
1534 | clks[BCM2835_CLOCK_VEC] = | ||
1535 | bcm2835_register_clock(cprman, &bcm2835_clock_vec_data); | ||
1536 | clks[BCM2835_CLOCK_HSM] = | ||
1537 | bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data); | ||
1538 | clks[BCM2835_CLOCK_EMMC] = | ||
1539 | bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data); | ||
1540 | |||
1541 | /* | ||
1542 | * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if | ||
1543 | * you have the debug bit set in the power manager, which we | ||
1544 | * don't bother exposing) are individual gates off of the | ||
1545 | * non-stop vpu clock. | ||
1546 | */ | ||
1547 | clks[BCM2835_CLOCK_PERI_IMAGE] = | ||
1548 | clk_register_gate(dev, "peri_image", "vpu", | ||
1549 | CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, | ||
1550 | cprman->regs + CM_PERIICTL, CM_GATE_BIT, | ||
1551 | 0, &cprman->regs_lock); | ||
1552 | |||
1553 | return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, | ||
1554 | &cprman->onecell); | ||
1555 | } | ||
1556 | |||
1557 | static const struct of_device_id bcm2835_clk_of_match[] = { | ||
1558 | { .compatible = "brcm,bcm2835-cprman", }, | ||
1559 | {} | ||
1560 | }; | ||
1561 | MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match); | ||
1562 | |||
1563 | static struct platform_driver bcm2835_clk_driver = { | ||
1564 | .driver = { | ||
1565 | .name = "bcm2835-clk", | ||
1566 | .of_match_table = bcm2835_clk_of_match, | ||
1567 | }, | ||
1568 | .probe = bcm2835_clk_probe, | ||
1569 | }; | ||
1570 | |||
1571 | builtin_platform_driver(bcm2835_clk_driver); | ||
1572 | |||
1573 | MODULE_AUTHOR("Eric Anholt <eric@anholt.net>"); | ||
1574 | MODULE_DESCRIPTION("BCM2835 clock driver"); | ||
1575 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c index 316c60337661..3a228b6d4fee 100644 --- a/drivers/clk/bcm/clk-cygnus.c +++ b/drivers/clk/bcm/clk-cygnus.c | |||
@@ -23,28 +23,30 @@ | |||
23 | #include <dt-bindings/clock/bcm-cygnus.h> | 23 | #include <dt-bindings/clock/bcm-cygnus.h> |
24 | #include "clk-iproc.h" | 24 | #include "clk-iproc.h" |
25 | 25 | ||
26 | #define reg_val(o, s, w) { .offset = o, .shift = s, .width = w, } | 26 | #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } |
27 | 27 | ||
28 | #define aon_val(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ | 28 | #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ |
29 | .pwr_shift = ps, .iso_shift = is } | 29 | .pwr_shift = ps, .iso_shift = is } |
30 | 30 | ||
31 | #define sw_ctrl_val(o, s) { .offset = o, .shift = s, } | 31 | #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, } |
32 | 32 | ||
33 | #define asiu_div_val(o, es, hs, hw, ls, lw) \ | 33 | #define ASIU_DIV_VAL(o, es, hs, hw, ls, lw) \ |
34 | { .offset = o, .en_shift = es, .high_shift = hs, \ | 34 | { .offset = o, .en_shift = es, .high_shift = hs, \ |
35 | .high_width = hw, .low_shift = ls, .low_width = lw } | 35 | .high_width = hw, .low_shift = ls, .low_width = lw } |
36 | 36 | ||
37 | #define reset_val(o, rs, prs, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \ | 37 | #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ |
38 | .reset_shift = rs, .p_reset_shift = prs, .ki_shift = kis, \ | 38 | .p_reset_shift = prs } |
39 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | 39 | |
40 | #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\ | ||
41 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | ||
40 | .ka_width = kaw } | 42 | .ka_width = kaw } |
41 | 43 | ||
42 | #define vco_ctrl_val(uo, lo) { .u_offset = uo, .l_offset = lo } | 44 | #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo } |
43 | 45 | ||
44 | #define enable_val(o, es, hs, bs) { .offset = o, .enable_shift = es, \ | 46 | #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ |
45 | .hold_shift = hs, .bypass_shift = bs } | 47 | .hold_shift = hs, .bypass_shift = bs } |
46 | 48 | ||
47 | #define asiu_gate_val(o, es) { .offset = o, .en_shift = es } | 49 | #define ASIU_GATE_VAL(o, es) { .offset = o, .en_shift = es } |
48 | 50 | ||
49 | static void __init cygnus_armpll_init(struct device_node *node) | 51 | static void __init cygnus_armpll_init(struct device_node *node) |
50 | { | 52 | { |
@@ -55,52 +57,53 @@ CLK_OF_DECLARE(cygnus_armpll, "brcm,cygnus-armpll", cygnus_armpll_init); | |||
55 | static const struct iproc_pll_ctrl genpll = { | 57 | static const struct iproc_pll_ctrl genpll = { |
56 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | | 58 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | |
57 | IPROC_CLK_PLL_NEEDS_SW_CFG, | 59 | IPROC_CLK_PLL_NEEDS_SW_CFG, |
58 | .aon = aon_val(0x0, 2, 1, 0), | 60 | .aon = AON_VAL(0x0, 2, 1, 0), |
59 | .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 3), | 61 | .reset = RESET_VAL(0x0, 11, 10), |
60 | .sw_ctrl = sw_ctrl_val(0x10, 31), | 62 | .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), |
61 | .ndiv_int = reg_val(0x10, 20, 10), | 63 | .sw_ctrl = SW_CTRL_VAL(0x10, 31), |
62 | .ndiv_frac = reg_val(0x10, 0, 20), | 64 | .ndiv_int = REG_VAL(0x10, 20, 10), |
63 | .pdiv = reg_val(0x14, 0, 4), | 65 | .ndiv_frac = REG_VAL(0x10, 0, 20), |
64 | .vco_ctrl = vco_ctrl_val(0x18, 0x1c), | 66 | .pdiv = REG_VAL(0x14, 0, 4), |
65 | .status = reg_val(0x28, 12, 1), | 67 | .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c), |
68 | .status = REG_VAL(0x28, 12, 1), | ||
66 | }; | 69 | }; |
67 | 70 | ||
68 | static const struct iproc_clk_ctrl genpll_clk[] = { | 71 | static const struct iproc_clk_ctrl genpll_clk[] = { |
69 | [BCM_CYGNUS_GENPLL_AXI21_CLK] = { | 72 | [BCM_CYGNUS_GENPLL_AXI21_CLK] = { |
70 | .channel = BCM_CYGNUS_GENPLL_AXI21_CLK, | 73 | .channel = BCM_CYGNUS_GENPLL_AXI21_CLK, |
71 | .flags = IPROC_CLK_AON, | 74 | .flags = IPROC_CLK_AON, |
72 | .enable = enable_val(0x4, 6, 0, 12), | 75 | .enable = ENABLE_VAL(0x4, 6, 0, 12), |
73 | .mdiv = reg_val(0x20, 0, 8), | 76 | .mdiv = REG_VAL(0x20, 0, 8), |
74 | }, | 77 | }, |
75 | [BCM_CYGNUS_GENPLL_250MHZ_CLK] = { | 78 | [BCM_CYGNUS_GENPLL_250MHZ_CLK] = { |
76 | .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK, | 79 | .channel = BCM_CYGNUS_GENPLL_250MHZ_CLK, |
77 | .flags = IPROC_CLK_AON, | 80 | .flags = IPROC_CLK_AON, |
78 | .enable = enable_val(0x4, 7, 1, 13), | 81 | .enable = ENABLE_VAL(0x4, 7, 1, 13), |
79 | .mdiv = reg_val(0x20, 10, 8), | 82 | .mdiv = REG_VAL(0x20, 10, 8), |
80 | }, | 83 | }, |
81 | [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = { | 84 | [BCM_CYGNUS_GENPLL_IHOST_SYS_CLK] = { |
82 | .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK, | 85 | .channel = BCM_CYGNUS_GENPLL_IHOST_SYS_CLK, |
83 | .flags = IPROC_CLK_AON, | 86 | .flags = IPROC_CLK_AON, |
84 | .enable = enable_val(0x4, 8, 2, 14), | 87 | .enable = ENABLE_VAL(0x4, 8, 2, 14), |
85 | .mdiv = reg_val(0x20, 20, 8), | 88 | .mdiv = REG_VAL(0x20, 20, 8), |
86 | }, | 89 | }, |
87 | [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = { | 90 | [BCM_CYGNUS_GENPLL_ENET_SW_CLK] = { |
88 | .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK, | 91 | .channel = BCM_CYGNUS_GENPLL_ENET_SW_CLK, |
89 | .flags = IPROC_CLK_AON, | 92 | .flags = IPROC_CLK_AON, |
90 | .enable = enable_val(0x4, 9, 3, 15), | 93 | .enable = ENABLE_VAL(0x4, 9, 3, 15), |
91 | .mdiv = reg_val(0x24, 0, 8), | 94 | .mdiv = REG_VAL(0x24, 0, 8), |
92 | }, | 95 | }, |
93 | [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = { | 96 | [BCM_CYGNUS_GENPLL_AUDIO_125_CLK] = { |
94 | .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK, | 97 | .channel = BCM_CYGNUS_GENPLL_AUDIO_125_CLK, |
95 | .flags = IPROC_CLK_AON, | 98 | .flags = IPROC_CLK_AON, |
96 | .enable = enable_val(0x4, 10, 4, 16), | 99 | .enable = ENABLE_VAL(0x4, 10, 4, 16), |
97 | .mdiv = reg_val(0x24, 10, 8), | 100 | .mdiv = REG_VAL(0x24, 10, 8), |
98 | }, | 101 | }, |
99 | [BCM_CYGNUS_GENPLL_CAN_CLK] = { | 102 | [BCM_CYGNUS_GENPLL_CAN_CLK] = { |
100 | .channel = BCM_CYGNUS_GENPLL_CAN_CLK, | 103 | .channel = BCM_CYGNUS_GENPLL_CAN_CLK, |
101 | .flags = IPROC_CLK_AON, | 104 | .flags = IPROC_CLK_AON, |
102 | .enable = enable_val(0x4, 11, 5, 17), | 105 | .enable = ENABLE_VAL(0x4, 11, 5, 17), |
103 | .mdiv = reg_val(0x24, 20, 8), | 106 | .mdiv = REG_VAL(0x24, 20, 8), |
104 | }, | 107 | }, |
105 | }; | 108 | }; |
106 | 109 | ||
@@ -113,51 +116,52 @@ CLK_OF_DECLARE(cygnus_genpll, "brcm,cygnus-genpll", cygnus_genpll_clk_init); | |||
113 | 116 | ||
114 | static const struct iproc_pll_ctrl lcpll0 = { | 117 | static const struct iproc_pll_ctrl lcpll0 = { |
115 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, | 118 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, |
116 | .aon = aon_val(0x0, 2, 5, 4), | 119 | .aon = AON_VAL(0x0, 2, 5, 4), |
117 | .reset = reset_val(0x0, 31, 30, 27, 3, 23, 4, 19, 4), | 120 | .reset = RESET_VAL(0x0, 31, 30), |
118 | .sw_ctrl = sw_ctrl_val(0x4, 31), | 121 | .dig_filter = DF_VAL(0x0, 27, 3, 23, 4, 19, 4), |
119 | .ndiv_int = reg_val(0x4, 16, 10), | 122 | .sw_ctrl = SW_CTRL_VAL(0x4, 31), |
120 | .pdiv = reg_val(0x4, 26, 4), | 123 | .ndiv_int = REG_VAL(0x4, 16, 10), |
121 | .vco_ctrl = vco_ctrl_val(0x10, 0x14), | 124 | .pdiv = REG_VAL(0x4, 26, 4), |
122 | .status = reg_val(0x18, 12, 1), | 125 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0x14), |
126 | .status = REG_VAL(0x18, 12, 1), | ||
123 | }; | 127 | }; |
124 | 128 | ||
125 | static const struct iproc_clk_ctrl lcpll0_clk[] = { | 129 | static const struct iproc_clk_ctrl lcpll0_clk[] = { |
126 | [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = { | 130 | [BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK] = { |
127 | .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK, | 131 | .channel = BCM_CYGNUS_LCPLL0_PCIE_PHY_REF_CLK, |
128 | .flags = IPROC_CLK_AON, | 132 | .flags = IPROC_CLK_AON, |
129 | .enable = enable_val(0x0, 7, 1, 13), | 133 | .enable = ENABLE_VAL(0x0, 7, 1, 13), |
130 | .mdiv = reg_val(0x8, 0, 8), | 134 | .mdiv = REG_VAL(0x8, 0, 8), |
131 | }, | 135 | }, |
132 | [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = { | 136 | [BCM_CYGNUS_LCPLL0_DDR_PHY_CLK] = { |
133 | .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK, | 137 | .channel = BCM_CYGNUS_LCPLL0_DDR_PHY_CLK, |
134 | .flags = IPROC_CLK_AON, | 138 | .flags = IPROC_CLK_AON, |
135 | .enable = enable_val(0x0, 8, 2, 14), | 139 | .enable = ENABLE_VAL(0x0, 8, 2, 14), |
136 | .mdiv = reg_val(0x8, 10, 8), | 140 | .mdiv = REG_VAL(0x8, 10, 8), |
137 | }, | 141 | }, |
138 | [BCM_CYGNUS_LCPLL0_SDIO_CLK] = { | 142 | [BCM_CYGNUS_LCPLL0_SDIO_CLK] = { |
139 | .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK, | 143 | .channel = BCM_CYGNUS_LCPLL0_SDIO_CLK, |
140 | .flags = IPROC_CLK_AON, | 144 | .flags = IPROC_CLK_AON, |
141 | .enable = enable_val(0x0, 9, 3, 15), | 145 | .enable = ENABLE_VAL(0x0, 9, 3, 15), |
142 | .mdiv = reg_val(0x8, 20, 8), | 146 | .mdiv = REG_VAL(0x8, 20, 8), |
143 | }, | 147 | }, |
144 | [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = { | 148 | [BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK] = { |
145 | .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK, | 149 | .channel = BCM_CYGNUS_LCPLL0_USB_PHY_REF_CLK, |
146 | .flags = IPROC_CLK_AON, | 150 | .flags = IPROC_CLK_AON, |
147 | .enable = enable_val(0x0, 10, 4, 16), | 151 | .enable = ENABLE_VAL(0x0, 10, 4, 16), |
148 | .mdiv = reg_val(0xc, 0, 8), | 152 | .mdiv = REG_VAL(0xc, 0, 8), |
149 | }, | 153 | }, |
150 | [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = { | 154 | [BCM_CYGNUS_LCPLL0_SMART_CARD_CLK] = { |
151 | .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK, | 155 | .channel = BCM_CYGNUS_LCPLL0_SMART_CARD_CLK, |
152 | .flags = IPROC_CLK_AON, | 156 | .flags = IPROC_CLK_AON, |
153 | .enable = enable_val(0x0, 11, 5, 17), | 157 | .enable = ENABLE_VAL(0x0, 11, 5, 17), |
154 | .mdiv = reg_val(0xc, 10, 8), | 158 | .mdiv = REG_VAL(0xc, 10, 8), |
155 | }, | 159 | }, |
156 | [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = { | 160 | [BCM_CYGNUS_LCPLL0_CH5_UNUSED] = { |
157 | .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED, | 161 | .channel = BCM_CYGNUS_LCPLL0_CH5_UNUSED, |
158 | .flags = IPROC_CLK_AON, | 162 | .flags = IPROC_CLK_AON, |
159 | .enable = enable_val(0x0, 12, 6, 18), | 163 | .enable = ENABLE_VAL(0x0, 12, 6, 18), |
160 | .mdiv = reg_val(0xc, 20, 8), | 164 | .mdiv = REG_VAL(0xc, 20, 8), |
161 | }, | 165 | }, |
162 | }; | 166 | }; |
163 | 167 | ||
@@ -189,52 +193,53 @@ static const struct iproc_pll_vco_param mipipll_vco_params[] = { | |||
189 | static const struct iproc_pll_ctrl mipipll = { | 193 | static const struct iproc_pll_ctrl mipipll = { |
190 | .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC | | 194 | .flags = IPROC_CLK_PLL_ASIU | IPROC_CLK_PLL_HAS_NDIV_FRAC | |
191 | IPROC_CLK_NEEDS_READ_BACK, | 195 | IPROC_CLK_NEEDS_READ_BACK, |
192 | .aon = aon_val(0x0, 4, 17, 16), | 196 | .aon = AON_VAL(0x0, 4, 17, 16), |
193 | .asiu = asiu_gate_val(0x0, 3), | 197 | .asiu = ASIU_GATE_VAL(0x0, 3), |
194 | .reset = reset_val(0x0, 11, 10, 4, 3, 0, 4, 7, 4), | 198 | .reset = RESET_VAL(0x0, 11, 10), |
195 | .ndiv_int = reg_val(0x10, 20, 10), | 199 | .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 4), |
196 | .ndiv_frac = reg_val(0x10, 0, 20), | 200 | .ndiv_int = REG_VAL(0x10, 20, 10), |
197 | .pdiv = reg_val(0x14, 0, 4), | 201 | .ndiv_frac = REG_VAL(0x10, 0, 20), |
198 | .vco_ctrl = vco_ctrl_val(0x18, 0x1c), | 202 | .pdiv = REG_VAL(0x14, 0, 4), |
199 | .status = reg_val(0x28, 12, 1), | 203 | .vco_ctrl = VCO_CTRL_VAL(0x18, 0x1c), |
204 | .status = REG_VAL(0x28, 12, 1), | ||
200 | }; | 205 | }; |
201 | 206 | ||
202 | static const struct iproc_clk_ctrl mipipll_clk[] = { | 207 | static const struct iproc_clk_ctrl mipipll_clk[] = { |
203 | [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = { | 208 | [BCM_CYGNUS_MIPIPLL_CH0_UNUSED] = { |
204 | .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED, | 209 | .channel = BCM_CYGNUS_MIPIPLL_CH0_UNUSED, |
205 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 210 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
206 | .enable = enable_val(0x4, 12, 6, 18), | 211 | .enable = ENABLE_VAL(0x4, 12, 6, 18), |
207 | .mdiv = reg_val(0x20, 0, 8), | 212 | .mdiv = REG_VAL(0x20, 0, 8), |
208 | }, | 213 | }, |
209 | [BCM_CYGNUS_MIPIPLL_CH1_LCD] = { | 214 | [BCM_CYGNUS_MIPIPLL_CH1_LCD] = { |
210 | .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD, | 215 | .channel = BCM_CYGNUS_MIPIPLL_CH1_LCD, |
211 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 216 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
212 | .enable = enable_val(0x4, 13, 7, 19), | 217 | .enable = ENABLE_VAL(0x4, 13, 7, 19), |
213 | .mdiv = reg_val(0x20, 10, 8), | 218 | .mdiv = REG_VAL(0x20, 10, 8), |
214 | }, | 219 | }, |
215 | [BCM_CYGNUS_MIPIPLL_CH2_V3D] = { | 220 | [BCM_CYGNUS_MIPIPLL_CH2_V3D] = { |
216 | .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D, | 221 | .channel = BCM_CYGNUS_MIPIPLL_CH2_V3D, |
217 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 222 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
218 | .enable = enable_val(0x4, 14, 8, 20), | 223 | .enable = ENABLE_VAL(0x4, 14, 8, 20), |
219 | .mdiv = reg_val(0x20, 20, 8), | 224 | .mdiv = REG_VAL(0x20, 20, 8), |
220 | }, | 225 | }, |
221 | [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = { | 226 | [BCM_CYGNUS_MIPIPLL_CH3_UNUSED] = { |
222 | .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED, | 227 | .channel = BCM_CYGNUS_MIPIPLL_CH3_UNUSED, |
223 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 228 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
224 | .enable = enable_val(0x4, 15, 9, 21), | 229 | .enable = ENABLE_VAL(0x4, 15, 9, 21), |
225 | .mdiv = reg_val(0x24, 0, 8), | 230 | .mdiv = REG_VAL(0x24, 0, 8), |
226 | }, | 231 | }, |
227 | [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = { | 232 | [BCM_CYGNUS_MIPIPLL_CH4_UNUSED] = { |
228 | .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED, | 233 | .channel = BCM_CYGNUS_MIPIPLL_CH4_UNUSED, |
229 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 234 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
230 | .enable = enable_val(0x4, 16, 10, 22), | 235 | .enable = ENABLE_VAL(0x4, 16, 10, 22), |
231 | .mdiv = reg_val(0x24, 10, 8), | 236 | .mdiv = REG_VAL(0x24, 10, 8), |
232 | }, | 237 | }, |
233 | [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = { | 238 | [BCM_CYGNUS_MIPIPLL_CH5_UNUSED] = { |
234 | .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED, | 239 | .channel = BCM_CYGNUS_MIPIPLL_CH5_UNUSED, |
235 | .flags = IPROC_CLK_NEEDS_READ_BACK, | 240 | .flags = IPROC_CLK_NEEDS_READ_BACK, |
236 | .enable = enable_val(0x4, 17, 11, 23), | 241 | .enable = ENABLE_VAL(0x4, 17, 11, 23), |
237 | .mdiv = reg_val(0x24, 20, 8), | 242 | .mdiv = REG_VAL(0x24, 20, 8), |
238 | }, | 243 | }, |
239 | }; | 244 | }; |
240 | 245 | ||
@@ -247,15 +252,15 @@ static void __init cygnus_mipipll_clk_init(struct device_node *node) | |||
247 | CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init); | 252 | CLK_OF_DECLARE(cygnus_mipipll, "brcm,cygnus-mipipll", cygnus_mipipll_clk_init); |
248 | 253 | ||
249 | static const struct iproc_asiu_div asiu_div[] = { | 254 | static const struct iproc_asiu_div asiu_div[] = { |
250 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_div_val(0x0, 31, 16, 10, 0, 10), | 255 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_DIV_VAL(0x0, 31, 16, 10, 0, 10), |
251 | [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_div_val(0x4, 31, 16, 10, 0, 10), | 256 | [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_DIV_VAL(0x4, 31, 16, 10, 0, 10), |
252 | [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_div_val(0x8, 31, 16, 10, 0, 10), | 257 | [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_DIV_VAL(0x8, 31, 16, 10, 0, 10), |
253 | }; | 258 | }; |
254 | 259 | ||
255 | static const struct iproc_asiu_gate asiu_gate[] = { | 260 | static const struct iproc_asiu_gate asiu_gate[] = { |
256 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = asiu_gate_val(0x0, 7), | 261 | [BCM_CYGNUS_ASIU_KEYPAD_CLK] = ASIU_GATE_VAL(0x0, 7), |
257 | [BCM_CYGNUS_ASIU_ADC_CLK] = asiu_gate_val(0x0, 9), | 262 | [BCM_CYGNUS_ASIU_ADC_CLK] = ASIU_GATE_VAL(0x0, 9), |
258 | [BCM_CYGNUS_ASIU_PWM_CLK] = asiu_gate_val(IPROC_CLK_INVALID_OFFSET, 0), | 263 | [BCM_CYGNUS_ASIU_PWM_CLK] = ASIU_GATE_VAL(IPROC_CLK_INVALID_OFFSET, 0), |
259 | }; | 264 | }; |
260 | 265 | ||
261 | static void __init cygnus_asiu_init(struct device_node *node) | 266 | static void __init cygnus_asiu_init(struct device_node *node) |
diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index 2dda4e8295a9..afd5891ac9e6 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c | |||
@@ -74,7 +74,8 @@ struct iproc_clk { | |||
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct iproc_pll { | 76 | struct iproc_pll { |
77 | void __iomem *pll_base; | 77 | void __iomem *status_base; |
78 | void __iomem *control_base; | ||
78 | void __iomem *pwr_base; | 79 | void __iomem *pwr_base; |
79 | void __iomem *asiu_base; | 80 | void __iomem *asiu_base; |
80 | 81 | ||
@@ -127,7 +128,7 @@ static int pll_wait_for_lock(struct iproc_pll *pll) | |||
127 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 128 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
128 | 129 | ||
129 | for (i = 0; i < LOCK_DELAY; i++) { | 130 | for (i = 0; i < LOCK_DELAY; i++) { |
130 | u32 val = readl(pll->pll_base + ctrl->status.offset); | 131 | u32 val = readl(pll->status_base + ctrl->status.offset); |
131 | 132 | ||
132 | if (val & (1 << ctrl->status.shift)) | 133 | if (val & (1 << ctrl->status.shift)) |
133 | return 0; | 134 | return 0; |
@@ -137,6 +138,18 @@ static int pll_wait_for_lock(struct iproc_pll *pll) | |||
137 | return -EIO; | 138 | return -EIO; |
138 | } | 139 | } |
139 | 140 | ||
141 | static void iproc_pll_write(const struct iproc_pll *pll, void __iomem *base, | ||
142 | const u32 offset, u32 val) | ||
143 | { | ||
144 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | ||
145 | |||
146 | writel(val, base + offset); | ||
147 | |||
148 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK && | ||
149 | (base == pll->status_base || base == pll->control_base))) | ||
150 | val = readl(base + offset); | ||
151 | } | ||
152 | |||
140 | static void __pll_disable(struct iproc_pll *pll) | 153 | static void __pll_disable(struct iproc_pll *pll) |
141 | { | 154 | { |
142 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 155 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
@@ -145,17 +158,25 @@ static void __pll_disable(struct iproc_pll *pll) | |||
145 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { | 158 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { |
146 | val = readl(pll->asiu_base + ctrl->asiu.offset); | 159 | val = readl(pll->asiu_base + ctrl->asiu.offset); |
147 | val &= ~(1 << ctrl->asiu.en_shift); | 160 | val &= ~(1 << ctrl->asiu.en_shift); |
148 | writel(val, pll->asiu_base + ctrl->asiu.offset); | 161 | iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val); |
162 | } | ||
163 | |||
164 | if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) { | ||
165 | val = readl(pll->control_base + ctrl->aon.offset); | ||
166 | val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; | ||
167 | iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val); | ||
149 | } | 168 | } |
150 | 169 | ||
151 | /* latch input value so core power can be shut down */ | 170 | if (pll->pwr_base) { |
152 | val = readl(pll->pwr_base + ctrl->aon.offset); | 171 | /* latch input value so core power can be shut down */ |
153 | val |= (1 << ctrl->aon.iso_shift); | 172 | val = readl(pll->pwr_base + ctrl->aon.offset); |
154 | writel(val, pll->pwr_base + ctrl->aon.offset); | 173 | val |= 1 << ctrl->aon.iso_shift; |
174 | iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val); | ||
155 | 175 | ||
156 | /* power down the core */ | 176 | /* power down the core */ |
157 | val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); | 177 | val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); |
158 | writel(val, pll->pwr_base + ctrl->aon.offset); | 178 | iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val); |
179 | } | ||
159 | } | 180 | } |
160 | 181 | ||
161 | static int __pll_enable(struct iproc_pll *pll) | 182 | static int __pll_enable(struct iproc_pll *pll) |
@@ -163,17 +184,25 @@ static int __pll_enable(struct iproc_pll *pll) | |||
163 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 184 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
164 | u32 val; | 185 | u32 val; |
165 | 186 | ||
166 | /* power up the PLL and make sure it's not latched */ | 187 | if (ctrl->flags & IPROC_CLK_EMBED_PWRCTRL) { |
167 | val = readl(pll->pwr_base + ctrl->aon.offset); | 188 | val = readl(pll->control_base + ctrl->aon.offset); |
168 | val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; | 189 | val &= ~(bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift); |
169 | val &= ~(1 << ctrl->aon.iso_shift); | 190 | iproc_pll_write(pll, pll->control_base, ctrl->aon.offset, val); |
170 | writel(val, pll->pwr_base + ctrl->aon.offset); | 191 | } |
192 | |||
193 | if (pll->pwr_base) { | ||
194 | /* power up the PLL and make sure it's not latched */ | ||
195 | val = readl(pll->pwr_base + ctrl->aon.offset); | ||
196 | val |= bit_mask(ctrl->aon.pwr_width) << ctrl->aon.pwr_shift; | ||
197 | val &= ~(1 << ctrl->aon.iso_shift); | ||
198 | iproc_pll_write(pll, pll->pwr_base, ctrl->aon.offset, val); | ||
199 | } | ||
171 | 200 | ||
172 | /* certain PLLs also need to be ungated from the ASIU top level */ | 201 | /* certain PLLs also need to be ungated from the ASIU top level */ |
173 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { | 202 | if (ctrl->flags & IPROC_CLK_PLL_ASIU) { |
174 | val = readl(pll->asiu_base + ctrl->asiu.offset); | 203 | val = readl(pll->asiu_base + ctrl->asiu.offset); |
175 | val |= (1 << ctrl->asiu.en_shift); | 204 | val |= (1 << ctrl->asiu.en_shift); |
176 | writel(val, pll->asiu_base + ctrl->asiu.offset); | 205 | iproc_pll_write(pll, pll->asiu_base, ctrl->asiu.offset, val); |
177 | } | 206 | } |
178 | 207 | ||
179 | return 0; | 208 | return 0; |
@@ -185,11 +214,9 @@ static void __pll_put_in_reset(struct iproc_pll *pll) | |||
185 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 214 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
186 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; | 215 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; |
187 | 216 | ||
188 | val = readl(pll->pll_base + reset->offset); | 217 | val = readl(pll->control_base + reset->offset); |
189 | val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); | 218 | val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); |
190 | writel(val, pll->pll_base + reset->offset); | 219 | iproc_pll_write(pll, pll->control_base, reset->offset, val); |
191 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
192 | readl(pll->pll_base + reset->offset); | ||
193 | } | 220 | } |
194 | 221 | ||
195 | static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, | 222 | static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, |
@@ -198,17 +225,19 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, | |||
198 | u32 val; | 225 | u32 val; |
199 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 226 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
200 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; | 227 | const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; |
228 | const struct iproc_pll_dig_filter_ctrl *dig_filter = &ctrl->dig_filter; | ||
229 | |||
230 | val = readl(pll->control_base + dig_filter->offset); | ||
231 | val &= ~(bit_mask(dig_filter->ki_width) << dig_filter->ki_shift | | ||
232 | bit_mask(dig_filter->kp_width) << dig_filter->kp_shift | | ||
233 | bit_mask(dig_filter->ka_width) << dig_filter->ka_shift); | ||
234 | val |= ki << dig_filter->ki_shift | kp << dig_filter->kp_shift | | ||
235 | ka << dig_filter->ka_shift; | ||
236 | iproc_pll_write(pll, pll->control_base, dig_filter->offset, val); | ||
201 | 237 | ||
202 | val = readl(pll->pll_base + reset->offset); | 238 | val = readl(pll->control_base + reset->offset); |
203 | val &= ~(bit_mask(reset->ki_width) << reset->ki_shift | | ||
204 | bit_mask(reset->kp_width) << reset->kp_shift | | ||
205 | bit_mask(reset->ka_width) << reset->ka_shift); | ||
206 | val |= ki << reset->ki_shift | kp << reset->kp_shift | | ||
207 | ka << reset->ka_shift; | ||
208 | val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; | 239 | val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; |
209 | writel(val, pll->pll_base + reset->offset); | 240 | iproc_pll_write(pll, pll->control_base, reset->offset, val); |
210 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
211 | readl(pll->pll_base + reset->offset); | ||
212 | } | 241 | } |
213 | 242 | ||
214 | static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, | 243 | static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, |
@@ -263,10 +292,9 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, | |||
263 | /* put PLL in reset */ | 292 | /* put PLL in reset */ |
264 | __pll_put_in_reset(pll); | 293 | __pll_put_in_reset(pll); |
265 | 294 | ||
266 | writel(0, pll->pll_base + ctrl->vco_ctrl.u_offset); | 295 | iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0); |
267 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | 296 | |
268 | readl(pll->pll_base + ctrl->vco_ctrl.u_offset); | 297 | val = readl(pll->control_base + ctrl->vco_ctrl.l_offset); |
269 | val = readl(pll->pll_base + ctrl->vco_ctrl.l_offset); | ||
270 | 298 | ||
271 | if (rate >= VCO_LOW && rate < VCO_MID) | 299 | if (rate >= VCO_LOW && rate < VCO_MID) |
272 | val |= (1 << PLL_VCO_LOW_SHIFT); | 300 | val |= (1 << PLL_VCO_LOW_SHIFT); |
@@ -276,36 +304,29 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, | |||
276 | else | 304 | else |
277 | val |= (1 << PLL_VCO_HIGH_SHIFT); | 305 | val |= (1 << PLL_VCO_HIGH_SHIFT); |
278 | 306 | ||
279 | writel(val, pll->pll_base + ctrl->vco_ctrl.l_offset); | 307 | iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.l_offset, val); |
280 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
281 | readl(pll->pll_base + ctrl->vco_ctrl.l_offset); | ||
282 | 308 | ||
283 | /* program integer part of NDIV */ | 309 | /* program integer part of NDIV */ |
284 | val = readl(pll->pll_base + ctrl->ndiv_int.offset); | 310 | val = readl(pll->control_base + ctrl->ndiv_int.offset); |
285 | val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift); | 311 | val &= ~(bit_mask(ctrl->ndiv_int.width) << ctrl->ndiv_int.shift); |
286 | val |= vco->ndiv_int << ctrl->ndiv_int.shift; | 312 | val |= vco->ndiv_int << ctrl->ndiv_int.shift; |
287 | writel(val, pll->pll_base + ctrl->ndiv_int.offset); | 313 | iproc_pll_write(pll, pll->control_base, ctrl->ndiv_int.offset, val); |
288 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
289 | readl(pll->pll_base + ctrl->ndiv_int.offset); | ||
290 | 314 | ||
291 | /* program fractional part of NDIV */ | 315 | /* program fractional part of NDIV */ |
292 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { | 316 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { |
293 | val = readl(pll->pll_base + ctrl->ndiv_frac.offset); | 317 | val = readl(pll->control_base + ctrl->ndiv_frac.offset); |
294 | val &= ~(bit_mask(ctrl->ndiv_frac.width) << | 318 | val &= ~(bit_mask(ctrl->ndiv_frac.width) << |
295 | ctrl->ndiv_frac.shift); | 319 | ctrl->ndiv_frac.shift); |
296 | val |= vco->ndiv_frac << ctrl->ndiv_frac.shift; | 320 | val |= vco->ndiv_frac << ctrl->ndiv_frac.shift; |
297 | writel(val, pll->pll_base + ctrl->ndiv_frac.offset); | 321 | iproc_pll_write(pll, pll->control_base, ctrl->ndiv_frac.offset, |
298 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | 322 | val); |
299 | readl(pll->pll_base + ctrl->ndiv_frac.offset); | ||
300 | } | 323 | } |
301 | 324 | ||
302 | /* program PDIV */ | 325 | /* program PDIV */ |
303 | val = readl(pll->pll_base + ctrl->pdiv.offset); | 326 | val = readl(pll->control_base + ctrl->pdiv.offset); |
304 | val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift); | 327 | val &= ~(bit_mask(ctrl->pdiv.width) << ctrl->pdiv.shift); |
305 | val |= vco->pdiv << ctrl->pdiv.shift; | 328 | val |= vco->pdiv << ctrl->pdiv.shift; |
306 | writel(val, pll->pll_base + ctrl->pdiv.offset); | 329 | iproc_pll_write(pll, pll->control_base, ctrl->pdiv.offset, val); |
307 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
308 | readl(pll->pll_base + ctrl->pdiv.offset); | ||
309 | 330 | ||
310 | __pll_bring_out_reset(pll, kp, ka, ki); | 331 | __pll_bring_out_reset(pll, kp, ka, ki); |
311 | 332 | ||
@@ -345,14 +366,14 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw, | |||
345 | struct iproc_pll *pll = clk->pll; | 366 | struct iproc_pll *pll = clk->pll; |
346 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; | 367 | const struct iproc_pll_ctrl *ctrl = pll->ctrl; |
347 | u32 val; | 368 | u32 val; |
348 | u64 ndiv; | 369 | u64 ndiv, ndiv_int, ndiv_frac; |
349 | unsigned int ndiv_int, ndiv_frac, pdiv; | 370 | unsigned int pdiv; |
350 | 371 | ||
351 | if (parent_rate == 0) | 372 | if (parent_rate == 0) |
352 | return 0; | 373 | return 0; |
353 | 374 | ||
354 | /* PLL needs to be locked */ | 375 | /* PLL needs to be locked */ |
355 | val = readl(pll->pll_base + ctrl->status.offset); | 376 | val = readl(pll->status_base + ctrl->status.offset); |
356 | if ((val & (1 << ctrl->status.shift)) == 0) { | 377 | if ((val & (1 << ctrl->status.shift)) == 0) { |
357 | clk->rate = 0; | 378 | clk->rate = 0; |
358 | return 0; | 379 | return 0; |
@@ -363,25 +384,22 @@ static unsigned long iproc_pll_recalc_rate(struct clk_hw *hw, | |||
363 | * | 384 | * |
364 | * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv) | 385 | * ((ndiv_int + ndiv_frac / 2^20) * (parent clock rate / pdiv) |
365 | */ | 386 | */ |
366 | val = readl(pll->pll_base + ctrl->ndiv_int.offset); | 387 | val = readl(pll->control_base + ctrl->ndiv_int.offset); |
367 | ndiv_int = (val >> ctrl->ndiv_int.shift) & | 388 | ndiv_int = (val >> ctrl->ndiv_int.shift) & |
368 | bit_mask(ctrl->ndiv_int.width); | 389 | bit_mask(ctrl->ndiv_int.width); |
369 | ndiv = (u64)ndiv_int << ctrl->ndiv_int.shift; | 390 | ndiv = ndiv_int << 20; |
370 | 391 | ||
371 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { | 392 | if (ctrl->flags & IPROC_CLK_PLL_HAS_NDIV_FRAC) { |
372 | val = readl(pll->pll_base + ctrl->ndiv_frac.offset); | 393 | val = readl(pll->control_base + ctrl->ndiv_frac.offset); |
373 | ndiv_frac = (val >> ctrl->ndiv_frac.shift) & | 394 | ndiv_frac = (val >> ctrl->ndiv_frac.shift) & |
374 | bit_mask(ctrl->ndiv_frac.width); | 395 | bit_mask(ctrl->ndiv_frac.width); |
375 | 396 | ndiv += ndiv_frac; | |
376 | if (ndiv_frac != 0) | ||
377 | ndiv = ((u64)ndiv_int << ctrl->ndiv_int.shift) | | ||
378 | ndiv_frac; | ||
379 | } | 397 | } |
380 | 398 | ||
381 | val = readl(pll->pll_base + ctrl->pdiv.offset); | 399 | val = readl(pll->control_base + ctrl->pdiv.offset); |
382 | pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width); | 400 | pdiv = (val >> ctrl->pdiv.shift) & bit_mask(ctrl->pdiv.width); |
383 | 401 | ||
384 | clk->rate = (ndiv * parent_rate) >> ctrl->ndiv_int.shift; | 402 | clk->rate = (ndiv * parent_rate) >> 20; |
385 | 403 | ||
386 | if (pdiv == 0) | 404 | if (pdiv == 0) |
387 | clk->rate *= 2; | 405 | clk->rate *= 2; |
@@ -443,16 +461,14 @@ static int iproc_clk_enable(struct clk_hw *hw) | |||
443 | u32 val; | 461 | u32 val; |
444 | 462 | ||
445 | /* channel enable is active low */ | 463 | /* channel enable is active low */ |
446 | val = readl(pll->pll_base + ctrl->enable.offset); | 464 | val = readl(pll->control_base + ctrl->enable.offset); |
447 | val &= ~(1 << ctrl->enable.enable_shift); | 465 | val &= ~(1 << ctrl->enable.enable_shift); |
448 | writel(val, pll->pll_base + ctrl->enable.offset); | 466 | iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val); |
449 | 467 | ||
450 | /* also make sure channel is not held */ | 468 | /* also make sure channel is not held */ |
451 | val = readl(pll->pll_base + ctrl->enable.offset); | 469 | val = readl(pll->control_base + ctrl->enable.offset); |
452 | val &= ~(1 << ctrl->enable.hold_shift); | 470 | val &= ~(1 << ctrl->enable.hold_shift); |
453 | writel(val, pll->pll_base + ctrl->enable.offset); | 471 | iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val); |
454 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
455 | readl(pll->pll_base + ctrl->enable.offset); | ||
456 | 472 | ||
457 | return 0; | 473 | return 0; |
458 | } | 474 | } |
@@ -467,11 +483,9 @@ static void iproc_clk_disable(struct clk_hw *hw) | |||
467 | if (ctrl->flags & IPROC_CLK_AON) | 483 | if (ctrl->flags & IPROC_CLK_AON) |
468 | return; | 484 | return; |
469 | 485 | ||
470 | val = readl(pll->pll_base + ctrl->enable.offset); | 486 | val = readl(pll->control_base + ctrl->enable.offset); |
471 | val |= 1 << ctrl->enable.enable_shift; | 487 | val |= 1 << ctrl->enable.enable_shift; |
472 | writel(val, pll->pll_base + ctrl->enable.offset); | 488 | iproc_pll_write(pll, pll->control_base, ctrl->enable.offset, val); |
473 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
474 | readl(pll->pll_base + ctrl->enable.offset); | ||
475 | } | 489 | } |
476 | 490 | ||
477 | static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, | 491 | static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, |
@@ -486,7 +500,7 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, | |||
486 | if (parent_rate == 0) | 500 | if (parent_rate == 0) |
487 | return 0; | 501 | return 0; |
488 | 502 | ||
489 | val = readl(pll->pll_base + ctrl->mdiv.offset); | 503 | val = readl(pll->control_base + ctrl->mdiv.offset); |
490 | mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width); | 504 | mdiv = (val >> ctrl->mdiv.shift) & bit_mask(ctrl->mdiv.width); |
491 | if (mdiv == 0) | 505 | if (mdiv == 0) |
492 | mdiv = 256; | 506 | mdiv = 256; |
@@ -533,16 +547,14 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
533 | if (div > 256) | 547 | if (div > 256) |
534 | return -EINVAL; | 548 | return -EINVAL; |
535 | 549 | ||
536 | val = readl(pll->pll_base + ctrl->mdiv.offset); | 550 | val = readl(pll->control_base + ctrl->mdiv.offset); |
537 | if (div == 256) { | 551 | if (div == 256) { |
538 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); | 552 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); |
539 | } else { | 553 | } else { |
540 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); | 554 | val &= ~(bit_mask(ctrl->mdiv.width) << ctrl->mdiv.shift); |
541 | val |= div << ctrl->mdiv.shift; | 555 | val |= div << ctrl->mdiv.shift; |
542 | } | 556 | } |
543 | writel(val, pll->pll_base + ctrl->mdiv.offset); | 557 | iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val); |
544 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | ||
545 | readl(pll->pll_base + ctrl->mdiv.offset); | ||
546 | clk->rate = parent_rate / div; | 558 | clk->rate = parent_rate / div; |
547 | 559 | ||
548 | return 0; | 560 | return 0; |
@@ -567,11 +579,10 @@ static void iproc_pll_sw_cfg(struct iproc_pll *pll) | |||
567 | if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) { | 579 | if (ctrl->flags & IPROC_CLK_PLL_NEEDS_SW_CFG) { |
568 | u32 val; | 580 | u32 val; |
569 | 581 | ||
570 | val = readl(pll->pll_base + ctrl->sw_ctrl.offset); | 582 | val = readl(pll->control_base + ctrl->sw_ctrl.offset); |
571 | val |= BIT(ctrl->sw_ctrl.shift); | 583 | val |= BIT(ctrl->sw_ctrl.shift); |
572 | writel(val, pll->pll_base + ctrl->sw_ctrl.offset); | 584 | iproc_pll_write(pll, pll->control_base, ctrl->sw_ctrl.offset, |
573 | if (unlikely(ctrl->flags & IPROC_CLK_NEEDS_READ_BACK)) | 585 | val); |
574 | readl(pll->pll_base + ctrl->sw_ctrl.offset); | ||
575 | } | 586 | } |
576 | } | 587 | } |
577 | 588 | ||
@@ -606,13 +617,12 @@ void __init iproc_pll_clk_setup(struct device_node *node, | |||
606 | if (WARN_ON(!pll->clks)) | 617 | if (WARN_ON(!pll->clks)) |
607 | goto err_clks; | 618 | goto err_clks; |
608 | 619 | ||
609 | pll->pll_base = of_iomap(node, 0); | 620 | pll->control_base = of_iomap(node, 0); |
610 | if (WARN_ON(!pll->pll_base)) | 621 | if (WARN_ON(!pll->control_base)) |
611 | goto err_pll_iomap; | 622 | goto err_pll_iomap; |
612 | 623 | ||
624 | /* Some SoCs do not require the pwr_base, thus failing is not fatal */ | ||
613 | pll->pwr_base = of_iomap(node, 1); | 625 | pll->pwr_base = of_iomap(node, 1); |
614 | if (WARN_ON(!pll->pwr_base)) | ||
615 | goto err_pwr_iomap; | ||
616 | 626 | ||
617 | /* some PLLs require gating control at the top ASIU level */ | 627 | /* some PLLs require gating control at the top ASIU level */ |
618 | if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) { | 628 | if (pll_ctrl->flags & IPROC_CLK_PLL_ASIU) { |
@@ -621,6 +631,16 @@ void __init iproc_pll_clk_setup(struct device_node *node, | |||
621 | goto err_asiu_iomap; | 631 | goto err_asiu_iomap; |
622 | } | 632 | } |
623 | 633 | ||
634 | if (pll_ctrl->flags & IPROC_CLK_PLL_SPLIT_STAT_CTRL) { | ||
635 | /* Some SoCs have a split status/control. If this does not | ||
636 | * exist, assume they are unified. | ||
637 | */ | ||
638 | pll->status_base = of_iomap(node, 2); | ||
639 | if (!pll->status_base) | ||
640 | goto err_status_iomap; | ||
641 | } else | ||
642 | pll->status_base = pll->control_base; | ||
643 | |||
624 | /* initialize and register the PLL itself */ | 644 | /* initialize and register the PLL itself */ |
625 | pll->ctrl = pll_ctrl; | 645 | pll->ctrl = pll_ctrl; |
626 | 646 | ||
@@ -691,14 +711,18 @@ err_clk_register: | |||
691 | clk_unregister(pll->clk_data.clks[i]); | 711 | clk_unregister(pll->clk_data.clks[i]); |
692 | 712 | ||
693 | err_pll_register: | 713 | err_pll_register: |
714 | if (pll->status_base != pll->control_base) | ||
715 | iounmap(pll->status_base); | ||
716 | |||
717 | err_status_iomap: | ||
694 | if (pll->asiu_base) | 718 | if (pll->asiu_base) |
695 | iounmap(pll->asiu_base); | 719 | iounmap(pll->asiu_base); |
696 | 720 | ||
697 | err_asiu_iomap: | 721 | err_asiu_iomap: |
698 | iounmap(pll->pwr_base); | 722 | if (pll->pwr_base) |
723 | iounmap(pll->pwr_base); | ||
699 | 724 | ||
700 | err_pwr_iomap: | 725 | iounmap(pll->control_base); |
701 | iounmap(pll->pll_base); | ||
702 | 726 | ||
703 | err_pll_iomap: | 727 | err_pll_iomap: |
704 | kfree(pll->clks); | 728 | kfree(pll->clks); |
diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index d834b7abd5c6..8988de70a98c 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h | |||
@@ -49,6 +49,18 @@ | |||
49 | #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) | 49 | #define IPROC_CLK_PLL_NEEDS_SW_CFG BIT(4) |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Some PLLs use a different way to control clock power, via the PWRDWN bit in | ||
53 | * the PLL control register | ||
54 | */ | ||
55 | #define IPROC_CLK_EMBED_PWRCTRL BIT(5) | ||
56 | |||
57 | /* | ||
58 | * Some PLLs have separate registers for Status and Control. Identify this to | ||
59 | * let the driver know if additional registers need to be used | ||
60 | */ | ||
61 | #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6) | ||
62 | |||
63 | /* | ||
52 | * Parameters for VCO frequency configuration | 64 | * Parameters for VCO frequency configuration |
53 | * | 65 | * |
54 | * VCO frequency = | 66 | * VCO frequency = |
@@ -88,12 +100,19 @@ struct iproc_pll_aon_pwr_ctrl { | |||
88 | }; | 100 | }; |
89 | 101 | ||
90 | /* | 102 | /* |
91 | * Control of the PLL reset, with Ki, Kp, and Ka parameters | 103 | * Control of the PLL reset |
92 | */ | 104 | */ |
93 | struct iproc_pll_reset_ctrl { | 105 | struct iproc_pll_reset_ctrl { |
94 | unsigned int offset; | 106 | unsigned int offset; |
95 | unsigned int reset_shift; | 107 | unsigned int reset_shift; |
96 | unsigned int p_reset_shift; | 108 | unsigned int p_reset_shift; |
109 | }; | ||
110 | |||
111 | /* | ||
112 | * Control of the Ki, Kp, and Ka parameters | ||
113 | */ | ||
114 | struct iproc_pll_dig_filter_ctrl { | ||
115 | unsigned int offset; | ||
97 | unsigned int ki_shift; | 116 | unsigned int ki_shift; |
98 | unsigned int ki_width; | 117 | unsigned int ki_width; |
99 | unsigned int kp_shift; | 118 | unsigned int kp_shift; |
@@ -123,6 +142,7 @@ struct iproc_pll_ctrl { | |||
123 | struct iproc_pll_aon_pwr_ctrl aon; | 142 | struct iproc_pll_aon_pwr_ctrl aon; |
124 | struct iproc_asiu_gate asiu; | 143 | struct iproc_asiu_gate asiu; |
125 | struct iproc_pll_reset_ctrl reset; | 144 | struct iproc_pll_reset_ctrl reset; |
145 | struct iproc_pll_dig_filter_ctrl dig_filter; | ||
126 | struct iproc_pll_sw_ctrl sw_ctrl; | 146 | struct iproc_pll_sw_ctrl sw_ctrl; |
127 | struct iproc_clk_reg_op ndiv_int; | 147 | struct iproc_clk_reg_op ndiv_int; |
128 | struct iproc_clk_reg_op ndiv_frac; | 148 | struct iproc_clk_reg_op ndiv_frac; |
diff --git a/drivers/clk/bcm/clk-ns2.c b/drivers/clk/bcm/clk-ns2.c new file mode 100644 index 000000000000..a564e9248814 --- /dev/null +++ b/drivers/clk/bcm/clk-ns2.c | |||
@@ -0,0 +1,288 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #include <dt-bindings/clock/bcm-ns2.h> | ||
22 | #include "clk-iproc.h" | ||
23 | |||
24 | #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } | ||
25 | |||
26 | #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ | ||
27 | .pwr_shift = ps, .iso_shift = is } | ||
28 | |||
29 | #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ | ||
30 | .p_reset_shift = prs } | ||
31 | |||
32 | #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\ | ||
33 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | ||
34 | .ka_width = kaw } | ||
35 | |||
36 | #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo } | ||
37 | |||
38 | #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ | ||
39 | .hold_shift = hs, .bypass_shift = bs } | ||
40 | |||
41 | static const struct iproc_pll_ctrl genpll_scr = { | ||
42 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
43 | .aon = AON_VAL(0x0, 1, 15, 12), | ||
44 | .reset = RESET_VAL(0x4, 2, 1), | ||
45 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3), | ||
46 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
47 | .pdiv = REG_VAL(0x8, 0, 4), | ||
48 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
49 | .status = REG_VAL(0x0, 27, 1), | ||
50 | }; | ||
51 | |||
52 | |||
53 | static const struct iproc_clk_ctrl genpll_scr_clk[] = { | ||
54 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
55 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
56 | * it to 0. | ||
57 | */ | ||
58 | [BCM_NS2_GENPLL_SCR_SCR_CLK] = { | ||
59 | .channel = BCM_NS2_GENPLL_SCR_SCR_CLK, | ||
60 | .flags = IPROC_CLK_AON, | ||
61 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
62 | .mdiv = REG_VAL(0x18, 0, 8), | ||
63 | }, | ||
64 | [BCM_NS2_GENPLL_SCR_FS_CLK] = { | ||
65 | .channel = BCM_NS2_GENPLL_SCR_FS_CLK, | ||
66 | .flags = IPROC_CLK_AON, | ||
67 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
68 | .mdiv = REG_VAL(0x18, 8, 8), | ||
69 | }, | ||
70 | [BCM_NS2_GENPLL_SCR_AUDIO_CLK] = { | ||
71 | .channel = BCM_NS2_GENPLL_SCR_AUDIO_CLK, | ||
72 | .flags = IPROC_CLK_AON, | ||
73 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
74 | .mdiv = REG_VAL(0x14, 0, 8), | ||
75 | }, | ||
76 | [BCM_NS2_GENPLL_SCR_CH3_UNUSED] = { | ||
77 | .channel = BCM_NS2_GENPLL_SCR_CH3_UNUSED, | ||
78 | .flags = IPROC_CLK_AON, | ||
79 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
80 | .mdiv = REG_VAL(0x14, 8, 8), | ||
81 | }, | ||
82 | [BCM_NS2_GENPLL_SCR_CH4_UNUSED] = { | ||
83 | .channel = BCM_NS2_GENPLL_SCR_CH4_UNUSED, | ||
84 | .flags = IPROC_CLK_AON, | ||
85 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
86 | .mdiv = REG_VAL(0x14, 16, 8), | ||
87 | }, | ||
88 | [BCM_NS2_GENPLL_SCR_CH5_UNUSED] = { | ||
89 | .channel = BCM_NS2_GENPLL_SCR_CH5_UNUSED, | ||
90 | .flags = IPROC_CLK_AON, | ||
91 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
92 | .mdiv = REG_VAL(0x14, 24, 8), | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static void __init ns2_genpll_scr_clk_init(struct device_node *node) | ||
97 | { | ||
98 | iproc_pll_clk_setup(node, &genpll_scr, NULL, 0, genpll_scr_clk, | ||
99 | ARRAY_SIZE(genpll_scr_clk)); | ||
100 | } | ||
101 | CLK_OF_DECLARE(ns2_genpll_src_clk, "brcm,ns2-genpll-scr", | ||
102 | ns2_genpll_scr_clk_init); | ||
103 | |||
104 | static const struct iproc_pll_ctrl genpll_sw = { | ||
105 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
106 | .aon = AON_VAL(0x0, 2, 9, 8), | ||
107 | .reset = RESET_VAL(0x4, 2, 1), | ||
108 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 2, 3), | ||
109 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
110 | .pdiv = REG_VAL(0x8, 0, 4), | ||
111 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
112 | .status = REG_VAL(0x0, 13, 1), | ||
113 | }; | ||
114 | |||
115 | static const struct iproc_clk_ctrl genpll_sw_clk[] = { | ||
116 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
117 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
118 | * it to 0. | ||
119 | */ | ||
120 | [BCM_NS2_GENPLL_SW_RPE_CLK] = { | ||
121 | .channel = BCM_NS2_GENPLL_SW_RPE_CLK, | ||
122 | .flags = IPROC_CLK_AON, | ||
123 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
124 | .mdiv = REG_VAL(0x18, 0, 8), | ||
125 | }, | ||
126 | [BCM_NS2_GENPLL_SW_250_CLK] = { | ||
127 | .channel = BCM_NS2_GENPLL_SW_250_CLK, | ||
128 | .flags = IPROC_CLK_AON, | ||
129 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
130 | .mdiv = REG_VAL(0x18, 8, 8), | ||
131 | }, | ||
132 | [BCM_NS2_GENPLL_SW_NIC_CLK] = { | ||
133 | .channel = BCM_NS2_GENPLL_SW_NIC_CLK, | ||
134 | .flags = IPROC_CLK_AON, | ||
135 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
136 | .mdiv = REG_VAL(0x14, 0, 8), | ||
137 | }, | ||
138 | [BCM_NS2_GENPLL_SW_CHIMP_CLK] = { | ||
139 | .channel = BCM_NS2_GENPLL_SW_CHIMP_CLK, | ||
140 | .flags = IPROC_CLK_AON, | ||
141 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
142 | .mdiv = REG_VAL(0x14, 8, 8), | ||
143 | }, | ||
144 | [BCM_NS2_GENPLL_SW_PORT_CLK] = { | ||
145 | .channel = BCM_NS2_GENPLL_SW_PORT_CLK, | ||
146 | .flags = IPROC_CLK_AON, | ||
147 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
148 | .mdiv = REG_VAL(0x14, 16, 8), | ||
149 | }, | ||
150 | [BCM_NS2_GENPLL_SW_SDIO_CLK] = { | ||
151 | .channel = BCM_NS2_GENPLL_SW_SDIO_CLK, | ||
152 | .flags = IPROC_CLK_AON, | ||
153 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
154 | .mdiv = REG_VAL(0x14, 24, 8), | ||
155 | }, | ||
156 | }; | ||
157 | |||
158 | static void __init ns2_genpll_sw_clk_init(struct device_node *node) | ||
159 | { | ||
160 | iproc_pll_clk_setup(node, &genpll_sw, NULL, 0, genpll_sw_clk, | ||
161 | ARRAY_SIZE(genpll_sw_clk)); | ||
162 | } | ||
163 | CLK_OF_DECLARE(ns2_genpll_sw_clk, "brcm,ns2-genpll-sw", | ||
164 | ns2_genpll_sw_clk_init); | ||
165 | |||
166 | static const struct iproc_pll_ctrl lcpll_ddr = { | ||
167 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
168 | .aon = AON_VAL(0x0, 2, 1, 0), | ||
169 | .reset = RESET_VAL(0x4, 2, 1), | ||
170 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4), | ||
171 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
172 | .pdiv = REG_VAL(0x8, 0, 4), | ||
173 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
174 | .status = REG_VAL(0x0, 0, 1), | ||
175 | }; | ||
176 | |||
177 | static const struct iproc_clk_ctrl lcpll_ddr_clk[] = { | ||
178 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
179 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
180 | * it to 0. | ||
181 | */ | ||
182 | [BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK] = { | ||
183 | .channel = BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK, | ||
184 | .flags = IPROC_CLK_AON, | ||
185 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
186 | .mdiv = REG_VAL(0x14, 0, 8), | ||
187 | }, | ||
188 | [BCM_NS2_LCPLL_DDR_DDR_CLK] = { | ||
189 | .channel = BCM_NS2_LCPLL_DDR_DDR_CLK, | ||
190 | .flags = IPROC_CLK_AON, | ||
191 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
192 | .mdiv = REG_VAL(0x14, 8, 8), | ||
193 | }, | ||
194 | [BCM_NS2_LCPLL_DDR_CH2_UNUSED] = { | ||
195 | .channel = BCM_NS2_LCPLL_DDR_CH2_UNUSED, | ||
196 | .flags = IPROC_CLK_AON, | ||
197 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
198 | .mdiv = REG_VAL(0x10, 0, 8), | ||
199 | }, | ||
200 | [BCM_NS2_LCPLL_DDR_CH3_UNUSED] = { | ||
201 | .channel = BCM_NS2_LCPLL_DDR_CH3_UNUSED, | ||
202 | .flags = IPROC_CLK_AON, | ||
203 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
204 | .mdiv = REG_VAL(0x10, 8, 8), | ||
205 | }, | ||
206 | [BCM_NS2_LCPLL_DDR_CH4_UNUSED] = { | ||
207 | .channel = BCM_NS2_LCPLL_DDR_CH4_UNUSED, | ||
208 | .flags = IPROC_CLK_AON, | ||
209 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
210 | .mdiv = REG_VAL(0x10, 16, 8), | ||
211 | }, | ||
212 | [BCM_NS2_LCPLL_DDR_CH5_UNUSED] = { | ||
213 | .channel = BCM_NS2_LCPLL_DDR_CH5_UNUSED, | ||
214 | .flags = IPROC_CLK_AON, | ||
215 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
216 | .mdiv = REG_VAL(0x10, 24, 8), | ||
217 | }, | ||
218 | }; | ||
219 | |||
220 | static void __init ns2_lcpll_ddr_clk_init(struct device_node *node) | ||
221 | { | ||
222 | iproc_pll_clk_setup(node, &lcpll_ddr, NULL, 0, lcpll_ddr_clk, | ||
223 | ARRAY_SIZE(lcpll_ddr_clk)); | ||
224 | } | ||
225 | CLK_OF_DECLARE(ns2_lcpll_ddr_clk, "brcm,ns2-lcpll-ddr", | ||
226 | ns2_lcpll_ddr_clk_init); | ||
227 | |||
228 | static const struct iproc_pll_ctrl lcpll_ports = { | ||
229 | .flags = IPROC_CLK_AON | IPROC_CLK_PLL_SPLIT_STAT_CTRL, | ||
230 | .aon = AON_VAL(0x0, 2, 5, 4), | ||
231 | .reset = RESET_VAL(0x4, 2, 1), | ||
232 | .dig_filter = DF_VAL(0x0, 9, 3, 5, 4, 1, 4), | ||
233 | .ndiv_int = REG_VAL(0x8, 4, 10), | ||
234 | .pdiv = REG_VAL(0x8, 0, 4), | ||
235 | .vco_ctrl = VCO_CTRL_VAL(0x10, 0xc), | ||
236 | .status = REG_VAL(0x0, 0, 1), | ||
237 | }; | ||
238 | |||
239 | static const struct iproc_clk_ctrl lcpll_ports_clk[] = { | ||
240 | /* bypass_shift, the last value passed into ENABLE_VAL(), is not defined | ||
241 | * in NS2. However, it doesn't appear to be used anywhere, so setting | ||
242 | * it to 0. | ||
243 | */ | ||
244 | [BCM_NS2_LCPLL_PORTS_WAN_CLK] = { | ||
245 | .channel = BCM_NS2_LCPLL_PORTS_WAN_CLK, | ||
246 | .flags = IPROC_CLK_AON, | ||
247 | .enable = ENABLE_VAL(0x0, 18, 12, 0), | ||
248 | .mdiv = REG_VAL(0x14, 0, 8), | ||
249 | }, | ||
250 | [BCM_NS2_LCPLL_PORTS_RGMII_CLK] = { | ||
251 | .channel = BCM_NS2_LCPLL_PORTS_RGMII_CLK, | ||
252 | .flags = IPROC_CLK_AON, | ||
253 | .enable = ENABLE_VAL(0x0, 19, 13, 0), | ||
254 | .mdiv = REG_VAL(0x14, 8, 8), | ||
255 | }, | ||
256 | [BCM_NS2_LCPLL_PORTS_CH2_UNUSED] = { | ||
257 | .channel = BCM_NS2_LCPLL_PORTS_CH2_UNUSED, | ||
258 | .flags = IPROC_CLK_AON, | ||
259 | .enable = ENABLE_VAL(0x0, 20, 14, 0), | ||
260 | .mdiv = REG_VAL(0x10, 0, 8), | ||
261 | }, | ||
262 | [BCM_NS2_LCPLL_PORTS_CH3_UNUSED] = { | ||
263 | .channel = BCM_NS2_LCPLL_PORTS_CH3_UNUSED, | ||
264 | .flags = IPROC_CLK_AON, | ||
265 | .enable = ENABLE_VAL(0x0, 21, 15, 0), | ||
266 | .mdiv = REG_VAL(0x10, 8, 8), | ||
267 | }, | ||
268 | [BCM_NS2_LCPLL_PORTS_CH4_UNUSED] = { | ||
269 | .channel = BCM_NS2_LCPLL_PORTS_CH4_UNUSED, | ||
270 | .flags = IPROC_CLK_AON, | ||
271 | .enable = ENABLE_VAL(0x0, 22, 16, 0), | ||
272 | .mdiv = REG_VAL(0x10, 16, 8), | ||
273 | }, | ||
274 | [BCM_NS2_LCPLL_PORTS_CH5_UNUSED] = { | ||
275 | .channel = BCM_NS2_LCPLL_PORTS_CH5_UNUSED, | ||
276 | .flags = IPROC_CLK_AON, | ||
277 | .enable = ENABLE_VAL(0x0, 23, 17, 0), | ||
278 | .mdiv = REG_VAL(0x10, 24, 8), | ||
279 | }, | ||
280 | }; | ||
281 | |||
282 | static void __init ns2_lcpll_ports_clk_init(struct device_node *node) | ||
283 | { | ||
284 | iproc_pll_clk_setup(node, &lcpll_ports, NULL, 0, lcpll_ports_clk, | ||
285 | ARRAY_SIZE(lcpll_ports_clk)); | ||
286 | } | ||
287 | CLK_OF_DECLARE(ns2_lcpll_ports_clk, "brcm,ns2-lcpll-ports", | ||
288 | ns2_lcpll_ports_clk_init); | ||
diff --git a/drivers/clk/bcm/clk-nsp.c b/drivers/clk/bcm/clk-nsp.c new file mode 100644 index 000000000000..cf66f640a47d --- /dev/null +++ b/drivers/clk/bcm/clk-nsp.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #include <dt-bindings/clock/bcm-nsp.h> | ||
22 | #include "clk-iproc.h" | ||
23 | |||
24 | #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } | ||
25 | |||
26 | #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ | ||
27 | .pwr_shift = ps, .iso_shift = is } | ||
28 | |||
29 | #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ | ||
30 | .p_reset_shift = prs } | ||
31 | |||
32 | #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, .ki_shift = kis,\ | ||
33 | .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, .ka_shift = kas, \ | ||
34 | .ka_width = kaw } | ||
35 | |||
36 | #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ | ||
37 | .hold_shift = hs, .bypass_shift = bs } | ||
38 | |||
39 | static void __init nsp_armpll_init(struct device_node *node) | ||
40 | { | ||
41 | iproc_armpll_setup(node); | ||
42 | } | ||
43 | CLK_OF_DECLARE(nsp_armpll, "brcm,nsp-armpll", nsp_armpll_init); | ||
44 | |||
45 | static const struct iproc_pll_ctrl genpll = { | ||
46 | .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL, | ||
47 | .aon = AON_VAL(0x0, 1, 12, 0), | ||
48 | .reset = RESET_VAL(0x0, 11, 10), | ||
49 | .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), | ||
50 | .ndiv_int = REG_VAL(0x14, 20, 10), | ||
51 | .ndiv_frac = REG_VAL(0x14, 0, 20), | ||
52 | .pdiv = REG_VAL(0x18, 24, 3), | ||
53 | .status = REG_VAL(0x20, 12, 1), | ||
54 | }; | ||
55 | |||
56 | static const struct iproc_clk_ctrl genpll_clk[] = { | ||
57 | [BCM_NSP_GENPLL_PHY_CLK] = { | ||
58 | .channel = BCM_NSP_GENPLL_PHY_CLK, | ||
59 | .flags = IPROC_CLK_AON, | ||
60 | .enable = ENABLE_VAL(0x4, 12, 6, 18), | ||
61 | .mdiv = REG_VAL(0x18, 16, 8), | ||
62 | }, | ||
63 | [BCM_NSP_GENPLL_ENET_SW_CLK] = { | ||
64 | .channel = BCM_NSP_GENPLL_ENET_SW_CLK, | ||
65 | .flags = IPROC_CLK_AON, | ||
66 | .enable = ENABLE_VAL(0x4, 13, 7, 19), | ||
67 | .mdiv = REG_VAL(0x18, 8, 8), | ||
68 | }, | ||
69 | [BCM_NSP_GENPLL_USB_PHY_REF_CLK] = { | ||
70 | .channel = BCM_NSP_GENPLL_USB_PHY_REF_CLK, | ||
71 | .flags = IPROC_CLK_AON, | ||
72 | .enable = ENABLE_VAL(0x4, 14, 8, 20), | ||
73 | .mdiv = REG_VAL(0x18, 0, 8), | ||
74 | }, | ||
75 | [BCM_NSP_GENPLL_IPROCFAST_CLK] = { | ||
76 | .channel = BCM_NSP_GENPLL_IPROCFAST_CLK, | ||
77 | .flags = IPROC_CLK_AON, | ||
78 | .enable = ENABLE_VAL(0x4, 15, 9, 21), | ||
79 | .mdiv = REG_VAL(0x1c, 16, 8), | ||
80 | }, | ||
81 | [BCM_NSP_GENPLL_SATA1_CLK] = { | ||
82 | .channel = BCM_NSP_GENPLL_SATA1_CLK, | ||
83 | .flags = IPROC_CLK_AON, | ||
84 | .enable = ENABLE_VAL(0x4, 16, 10, 22), | ||
85 | .mdiv = REG_VAL(0x1c, 8, 8), | ||
86 | }, | ||
87 | [BCM_NSP_GENPLL_SATA2_CLK] = { | ||
88 | .channel = BCM_NSP_GENPLL_SATA2_CLK, | ||
89 | .flags = IPROC_CLK_AON, | ||
90 | .enable = ENABLE_VAL(0x4, 17, 11, 23), | ||
91 | .mdiv = REG_VAL(0x1c, 0, 8), | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static void __init nsp_genpll_clk_init(struct device_node *node) | ||
96 | { | ||
97 | iproc_pll_clk_setup(node, &genpll, NULL, 0, genpll_clk, | ||
98 | ARRAY_SIZE(genpll_clk)); | ||
99 | } | ||
100 | CLK_OF_DECLARE(nsp_genpll_clk, "brcm,nsp-genpll", nsp_genpll_clk_init); | ||
101 | |||
102 | static const struct iproc_pll_ctrl lcpll0 = { | ||
103 | .flags = IPROC_CLK_PLL_HAS_NDIV_FRAC | IPROC_CLK_EMBED_PWRCTRL, | ||
104 | .aon = AON_VAL(0x0, 1, 24, 0), | ||
105 | .reset = RESET_VAL(0x0, 23, 22), | ||
106 | .dig_filter = DF_VAL(0x0, 16, 3, 12, 4, 19, 4), | ||
107 | .ndiv_int = REG_VAL(0x4, 20, 8), | ||
108 | .ndiv_frac = REG_VAL(0x4, 0, 20), | ||
109 | .pdiv = REG_VAL(0x4, 28, 3), | ||
110 | .status = REG_VAL(0x10, 12, 1), | ||
111 | }; | ||
112 | |||
113 | static const struct iproc_clk_ctrl lcpll0_clk[] = { | ||
114 | [BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK] = { | ||
115 | .channel = BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK, | ||
116 | .flags = IPROC_CLK_AON, | ||
117 | .enable = ENABLE_VAL(0x0, 6, 3, 9), | ||
118 | .mdiv = REG_VAL(0x8, 24, 8), | ||
119 | }, | ||
120 | [BCM_NSP_LCPLL0_SDIO_CLK] = { | ||
121 | .channel = BCM_NSP_LCPLL0_SDIO_CLK, | ||
122 | .flags = IPROC_CLK_AON, | ||
123 | .enable = ENABLE_VAL(0x0, 7, 4, 10), | ||
124 | .mdiv = REG_VAL(0x8, 16, 8), | ||
125 | }, | ||
126 | [BCM_NSP_LCPLL0_DDR_PHY_CLK] = { | ||
127 | .channel = BCM_NSP_LCPLL0_DDR_PHY_CLK, | ||
128 | .flags = IPROC_CLK_AON, | ||
129 | .enable = ENABLE_VAL(0x0, 8, 5, 11), | ||
130 | .mdiv = REG_VAL(0x8, 8, 8), | ||
131 | }, | ||
132 | }; | ||
133 | |||
134 | static void __init nsp_lcpll0_clk_init(struct device_node *node) | ||
135 | { | ||
136 | iproc_pll_clk_setup(node, &lcpll0, NULL, 0, lcpll0_clk, | ||
137 | ARRAY_SIZE(lcpll0_clk)); | ||
138 | } | ||
139 | CLK_OF_DECLARE(nsp_lcpll0_clk, "brcm,nsp-lcpll0", nsp_lcpll0_clk_init); | ||
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index 73153fc45ee9..23e0e3be6c37 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c | |||
@@ -490,8 +490,8 @@ static const struct berlin2_gate_data bg2_gates[] __initconst = { | |||
490 | { "usb0", "perif", 11 }, | 490 | { "usb0", "perif", 11 }, |
491 | { "usb1", "perif", 12 }, | 491 | { "usb1", "perif", 12 }, |
492 | { "pbridge", "perif", 13, CLK_IGNORE_UNUSED }, | 492 | { "pbridge", "perif", 13, CLK_IGNORE_UNUSED }, |
493 | { "sdio0", "perif", 14, CLK_IGNORE_UNUSED }, | 493 | { "sdio0", "perif", 14 }, |
494 | { "sdio1", "perif", 15, CLK_IGNORE_UNUSED }, | 494 | { "sdio1", "perif", 15 }, |
495 | { "nfc", "perif", 17 }, | 495 | { "nfc", "perif", 17 }, |
496 | { "smemc", "perif", 19 }, | 496 | { "smemc", "perif", 19 }, |
497 | { "audiohd", "audiohd_pll", 26 }, | 497 | { "audiohd", "audiohd_pll", 26 }, |
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 221f40c2b850..243f421abcb4 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c | |||
@@ -283,7 +283,7 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = { | |||
283 | { "usb2", "perif", 13 }, | 283 | { "usb2", "perif", 13 }, |
284 | { "usb3", "perif", 14 }, | 284 | { "usb3", "perif", 14 }, |
285 | { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, | 285 | { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, |
286 | { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, | 286 | { "sdio", "perif", 16 }, |
287 | { "nfc", "perif", 18 }, | 287 | { "nfc", "perif", 18 }, |
288 | { "pcie", "perif", 22 }, | 288 | { "pcie", "perif", 22 }, |
289 | }; | 289 | }; |
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c deleted file mode 100644 index dd295e498309..000000000000 --- a/drivers/clk/clk-bcm2835.c +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Broadcom | ||
3 | * Copyright (C) 2012 Stephen Warren | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | #include <linux/clk/bcm2835.h> | ||
23 | #include <linux/of.h> | ||
24 | |||
25 | /* | ||
26 | * These are fixed clocks. They're probably not all root clocks and it may | ||
27 | * be possible to turn them on and off but until this is mapped out better | ||
28 | * it's the only way they can be used. | ||
29 | */ | ||
30 | void __init bcm2835_init_clocks(void) | ||
31 | { | ||
32 | struct clk *clk; | ||
33 | int ret; | ||
34 | |||
35 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, | ||
36 | 126000000); | ||
37 | if (IS_ERR(clk)) | ||
38 | pr_err("apb_pclk not registered\n"); | ||
39 | |||
40 | clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, | ||
41 | 3000000); | ||
42 | if (IS_ERR(clk)) | ||
43 | pr_err("uart0_pclk not registered\n"); | ||
44 | ret = clk_register_clkdev(clk, NULL, "20201000.uart"); | ||
45 | if (ret) | ||
46 | pr_err("uart0_pclk alias not registered\n"); | ||
47 | |||
48 | clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, | ||
49 | 125000000); | ||
50 | if (IS_ERR(clk)) | ||
51 | pr_err("uart1_pclk not registered\n"); | ||
52 | ret = clk_register_clkdev(clk, NULL, "20215000.uart"); | ||
53 | if (ret) | ||
54 | pr_err("uart1_pclk alias not registered\n"); | ||
55 | } | ||
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index f24d0a19ae70..3ace102a2a0a 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * Traits of this clock: | 24 | * Traits of this clock: |
25 | * prepare - clk_prepare only ensures that parents are prepared | 25 | * prepare - clk_prepare only ensures that parents are prepared |
26 | * enable - clk_enable only ensures that parents are enabled | 26 | * enable - clk_enable only ensures that parents are enabled |
27 | * rate - rate is adjustable. clk->rate = DIV_ROUND_UP(parent->rate / divisor) | 27 | * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor) |
28 | * parent - fixed parent. No clk_set_parent support | 28 | * parent - fixed parent. No clk_set_parent support |
29 | */ | 29 | */ |
30 | 30 | ||
@@ -132,7 +132,7 @@ unsigned long divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, | |||
132 | return parent_rate; | 132 | return parent_rate; |
133 | } | 133 | } |
134 | 134 | ||
135 | return DIV_ROUND_UP(parent_rate, div); | 135 | return DIV_ROUND_UP_ULL((u64)parent_rate, div); |
136 | } | 136 | } |
137 | EXPORT_SYMBOL_GPL(divider_recalc_rate); | 137 | EXPORT_SYMBOL_GPL(divider_recalc_rate); |
138 | 138 | ||
@@ -210,7 +210,7 @@ static int _div_round_up(const struct clk_div_table *table, | |||
210 | unsigned long parent_rate, unsigned long rate, | 210 | unsigned long parent_rate, unsigned long rate, |
211 | unsigned long flags) | 211 | unsigned long flags) |
212 | { | 212 | { |
213 | int div = DIV_ROUND_UP(parent_rate, rate); | 213 | int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); |
214 | 214 | ||
215 | if (flags & CLK_DIVIDER_POWER_OF_TWO) | 215 | if (flags & CLK_DIVIDER_POWER_OF_TWO) |
216 | div = __roundup_pow_of_two(div); | 216 | div = __roundup_pow_of_two(div); |
@@ -227,7 +227,7 @@ static int _div_round_closest(const struct clk_div_table *table, | |||
227 | int up, down; | 227 | int up, down; |
228 | unsigned long up_rate, down_rate; | 228 | unsigned long up_rate, down_rate; |
229 | 229 | ||
230 | up = DIV_ROUND_UP(parent_rate, rate); | 230 | up = DIV_ROUND_UP_ULL((u64)parent_rate, rate); |
231 | down = parent_rate / rate; | 231 | down = parent_rate / rate; |
232 | 232 | ||
233 | if (flags & CLK_DIVIDER_POWER_OF_TWO) { | 233 | if (flags & CLK_DIVIDER_POWER_OF_TWO) { |
@@ -238,8 +238,8 @@ static int _div_round_closest(const struct clk_div_table *table, | |||
238 | down = _round_down_table(table, down); | 238 | down = _round_down_table(table, down); |
239 | } | 239 | } |
240 | 240 | ||
241 | up_rate = DIV_ROUND_UP(parent_rate, up); | 241 | up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up); |
242 | down_rate = DIV_ROUND_UP(parent_rate, down); | 242 | down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down); |
243 | 243 | ||
244 | return (rate - up_rate) <= (down_rate - rate) ? up : down; | 244 | return (rate - up_rate) <= (down_rate - rate) ? up : down; |
245 | } | 245 | } |
@@ -318,7 +318,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, | |||
318 | } | 318 | } |
319 | parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), | 319 | parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), |
320 | rate * i); | 320 | rate * i); |
321 | now = DIV_ROUND_UP(parent_rate, i); | 321 | now = DIV_ROUND_UP_ULL((u64)parent_rate, i); |
322 | if (_is_best_div(rate, now, best, flags)) { | 322 | if (_is_best_div(rate, now, best, flags)) { |
323 | bestdiv = i; | 323 | bestdiv = i; |
324 | best = now; | 324 | best = now; |
@@ -342,7 +342,7 @@ long divider_round_rate(struct clk_hw *hw, unsigned long rate, | |||
342 | 342 | ||
343 | div = clk_divider_bestdiv(hw, rate, prate, table, width, flags); | 343 | div = clk_divider_bestdiv(hw, rate, prate, table, width, flags); |
344 | 344 | ||
345 | return DIV_ROUND_UP(*prate, div); | 345 | return DIV_ROUND_UP_ULL((u64)*prate, div); |
346 | } | 346 | } |
347 | EXPORT_SYMBOL_GPL(divider_round_rate); | 347 | EXPORT_SYMBOL_GPL(divider_round_rate); |
348 | 348 | ||
@@ -358,7 +358,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, | |||
358 | bestdiv &= div_mask(divider->width); | 358 | bestdiv &= div_mask(divider->width); |
359 | bestdiv = _get_div(divider->table, bestdiv, divider->flags, | 359 | bestdiv = _get_div(divider->table, bestdiv, divider->flags, |
360 | divider->width); | 360 | divider->width); |
361 | return DIV_ROUND_UP(*prate, bestdiv); | 361 | return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); |
362 | } | 362 | } |
363 | 363 | ||
364 | return divider_round_rate(hw, rate, prate, divider->table, | 364 | return divider_round_rate(hw, rate, prate, divider->table, |
@@ -371,7 +371,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate, | |||
371 | { | 371 | { |
372 | unsigned int div, value; | 372 | unsigned int div, value; |
373 | 373 | ||
374 | div = DIV_ROUND_UP(parent_rate, rate); | 374 | div = DIV_ROUND_UP_ULL((u64)parent_rate, rate); |
375 | 375 | ||
376 | if (!_is_valid_div(table, div, flags)) | 376 | if (!_is_valid_div(table, div, flags)) |
377 | return -EINVAL; | 377 | return -EINVAL; |
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index e85f856b8592..5c4955e33f7a 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c | |||
@@ -7,13 +7,14 @@ | |||
7 | * | 7 | * |
8 | * Adjustable fractional divider clock implementation. | 8 | * Adjustable fractional divider clock implementation. |
9 | * Output rate = (m / n) * parent_rate. | 9 | * Output rate = (m / n) * parent_rate. |
10 | * Uses rational best approximation algorithm. | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/device.h> | 15 | #include <linux/device.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
16 | #include <linux/gcd.h> | 17 | #include <linux/rational.h> |
17 | 18 | ||
18 | #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) | 19 | #define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) |
19 | 20 | ||
@@ -22,7 +23,8 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, | |||
22 | { | 23 | { |
23 | struct clk_fractional_divider *fd = to_clk_fd(hw); | 24 | struct clk_fractional_divider *fd = to_clk_fd(hw); |
24 | unsigned long flags = 0; | 25 | unsigned long flags = 0; |
25 | u32 val, m, n; | 26 | unsigned long m, n; |
27 | u32 val; | ||
26 | u64 ret; | 28 | u64 ret; |
27 | 29 | ||
28 | if (fd->lock) | 30 | if (fd->lock) |
@@ -50,23 +52,33 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, | |||
50 | } | 52 | } |
51 | 53 | ||
52 | static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, | 54 | static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, |
53 | unsigned long *prate) | 55 | unsigned long *parent_rate) |
54 | { | 56 | { |
55 | struct clk_fractional_divider *fd = to_clk_fd(hw); | 57 | struct clk_fractional_divider *fd = to_clk_fd(hw); |
56 | unsigned maxn = (fd->nmask >> fd->nshift) + 1; | 58 | unsigned long scale; |
57 | unsigned div; | 59 | unsigned long m, n; |
60 | u64 ret; | ||
58 | 61 | ||
59 | if (!rate || rate >= *prate) | 62 | if (!rate || rate >= *parent_rate) |
60 | return *prate; | 63 | return *parent_rate; |
61 | 64 | ||
62 | div = gcd(*prate, rate); | 65 | /* |
66 | * Get rate closer to *parent_rate to guarantee there is no overflow | ||
67 | * for m and n. In the result it will be the nearest rate left shifted | ||
68 | * by (scale - fd->nwidth) bits. | ||
69 | */ | ||
70 | scale = fls_long(*parent_rate / rate - 1); | ||
71 | if (scale > fd->nwidth) | ||
72 | rate <<= scale - fd->nwidth; | ||
63 | 73 | ||
64 | while ((*prate / div) > maxn) { | 74 | rational_best_approximation(rate, *parent_rate, |
65 | div <<= 1; | 75 | GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), |
66 | rate <<= 1; | 76 | &m, &n); |
67 | } | ||
68 | 77 | ||
69 | return rate; | 78 | ret = (u64)*parent_rate * m; |
79 | do_div(ret, n); | ||
80 | |||
81 | return ret; | ||
70 | } | 82 | } |
71 | 83 | ||
72 | static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, | 84 | static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, |
@@ -74,13 +86,12 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, | |||
74 | { | 86 | { |
75 | struct clk_fractional_divider *fd = to_clk_fd(hw); | 87 | struct clk_fractional_divider *fd = to_clk_fd(hw); |
76 | unsigned long flags = 0; | 88 | unsigned long flags = 0; |
77 | unsigned long div; | 89 | unsigned long m, n; |
78 | unsigned n, m; | ||
79 | u32 val; | 90 | u32 val; |
80 | 91 | ||
81 | div = gcd(parent_rate, rate); | 92 | rational_best_approximation(rate, parent_rate, |
82 | m = rate / div; | 93 | GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), |
83 | n = parent_rate / div; | 94 | &m, &n); |
84 | 95 | ||
85 | if (fd->lock) | 96 | if (fd->lock) |
86 | spin_lock_irqsave(fd->lock, flags); | 97 | spin_lock_irqsave(fd->lock, flags); |
@@ -128,9 +139,11 @@ struct clk *clk_register_fractional_divider(struct device *dev, | |||
128 | 139 | ||
129 | fd->reg = reg; | 140 | fd->reg = reg; |
130 | fd->mshift = mshift; | 141 | fd->mshift = mshift; |
131 | fd->mmask = (BIT(mwidth) - 1) << mshift; | 142 | fd->mwidth = mwidth; |
143 | fd->mmask = GENMASK(mwidth - 1, 0) << mshift; | ||
132 | fd->nshift = nshift; | 144 | fd->nshift = nshift; |
133 | fd->nmask = (BIT(nwidth) - 1) << nshift; | 145 | fd->nwidth = nwidth; |
146 | fd->nmask = GENMASK(nwidth - 1, 0) << nshift; | ||
134 | fd->flags = clk_divider_flags; | 147 | fd->flags = clk_divider_flags; |
135 | fd->lock = lock; | 148 | fd->lock = lock; |
136 | fd->hw.init = &init; | 149 | fd->hw.init = &init; |
diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c index 74c49b93a6eb..4a89f7979ba0 100644 --- a/drivers/clk/clk-max77802.c +++ b/drivers/clk/clk-max77802.c | |||
@@ -94,5 +94,5 @@ static struct platform_driver max77802_clk_driver = { | |||
94 | module_platform_driver(max77802_clk_driver); | 94 | module_platform_driver(max77802_clk_driver); |
95 | 95 | ||
96 | MODULE_DESCRIPTION("MAXIM 77802 Clock Driver"); | 96 | MODULE_DESCRIPTION("MAXIM 77802 Clock Driver"); |
97 | MODULE_AUTHOR("Javier Martinez Canillas <javier.martinez@collabora.co.uk>"); | 97 | MODULE_AUTHOR("Javier Martinez Canillas <javier@osg.samsung.com"); |
98 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c new file mode 100644 index 000000000000..fe7806506bf3 --- /dev/null +++ b/drivers/clk/clk-multiplier.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Maxime Ripard <maxime.ripard@free-electrons.com> | ||
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 | |||
9 | #include <linux/bitops.h> | ||
10 | #include <linux/clk-provider.h> | ||
11 | #include <linux/err.h> | ||
12 | #include <linux/export.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/slab.h> | ||
16 | |||
17 | #define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) | ||
18 | |||
19 | static unsigned long __get_mult(struct clk_multiplier *mult, | ||
20 | unsigned long rate, | ||
21 | unsigned long parent_rate) | ||
22 | { | ||
23 | if (mult->flags & CLK_MULTIPLIER_ROUND_CLOSEST) | ||
24 | return DIV_ROUND_CLOSEST(rate, parent_rate); | ||
25 | |||
26 | return rate / parent_rate; | ||
27 | } | ||
28 | |||
29 | static unsigned long clk_multiplier_recalc_rate(struct clk_hw *hw, | ||
30 | unsigned long parent_rate) | ||
31 | { | ||
32 | struct clk_multiplier *mult = to_clk_multiplier(hw); | ||
33 | unsigned long val; | ||
34 | |||
35 | val = clk_readl(mult->reg) >> mult->shift; | ||
36 | val &= GENMASK(mult->width - 1, 0); | ||
37 | |||
38 | if (!val && mult->flags & CLK_MULTIPLIER_ZERO_BYPASS) | ||
39 | val = 1; | ||
40 | |||
41 | return parent_rate * val; | ||
42 | } | ||
43 | |||
44 | static bool __is_best_rate(unsigned long rate, unsigned long new, | ||
45 | unsigned long best, unsigned long flags) | ||
46 | { | ||
47 | if (flags & CLK_MULTIPLIER_ROUND_CLOSEST) | ||
48 | return abs(rate - new) < abs(rate - best); | ||
49 | |||
50 | return new >= rate && new < best; | ||
51 | } | ||
52 | |||
53 | static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate, | ||
54 | unsigned long *best_parent_rate, | ||
55 | u8 width, unsigned long flags) | ||
56 | { | ||
57 | unsigned long orig_parent_rate = *best_parent_rate; | ||
58 | unsigned long parent_rate, current_rate, best_rate = ~0; | ||
59 | unsigned int i, bestmult = 0; | ||
60 | |||
61 | if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) | ||
62 | return rate / *best_parent_rate; | ||
63 | |||
64 | for (i = 1; i < ((1 << width) - 1); i++) { | ||
65 | if (rate == orig_parent_rate * i) { | ||
66 | /* | ||
67 | * This is the best case for us if we have a | ||
68 | * perfect match without changing the parent | ||
69 | * rate. | ||
70 | */ | ||
71 | *best_parent_rate = orig_parent_rate; | ||
72 | return i; | ||
73 | } | ||
74 | |||
75 | parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), | ||
76 | rate / i); | ||
77 | current_rate = parent_rate * i; | ||
78 | |||
79 | if (__is_best_rate(rate, current_rate, best_rate, flags)) { | ||
80 | bestmult = i; | ||
81 | best_rate = current_rate; | ||
82 | *best_parent_rate = parent_rate; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | return bestmult; | ||
87 | } | ||
88 | |||
89 | static long clk_multiplier_round_rate(struct clk_hw *hw, unsigned long rate, | ||
90 | unsigned long *parent_rate) | ||
91 | { | ||
92 | struct clk_multiplier *mult = to_clk_multiplier(hw); | ||
93 | unsigned long factor = __bestmult(hw, rate, parent_rate, | ||
94 | mult->width, mult->flags); | ||
95 | |||
96 | return *parent_rate * factor; | ||
97 | } | ||
98 | |||
99 | static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate, | ||
100 | unsigned long parent_rate) | ||
101 | { | ||
102 | struct clk_multiplier *mult = to_clk_multiplier(hw); | ||
103 | unsigned long factor = __get_mult(mult, rate, parent_rate); | ||
104 | unsigned long flags = 0; | ||
105 | unsigned long val; | ||
106 | |||
107 | if (mult->lock) | ||
108 | spin_lock_irqsave(mult->lock, flags); | ||
109 | else | ||
110 | __acquire(mult->lock); | ||
111 | |||
112 | val = clk_readl(mult->reg); | ||
113 | val &= ~GENMASK(mult->width + mult->shift - 1, mult->shift); | ||
114 | val |= factor << mult->shift; | ||
115 | clk_writel(val, mult->reg); | ||
116 | |||
117 | if (mult->lock) | ||
118 | spin_unlock_irqrestore(mult->lock, flags); | ||
119 | else | ||
120 | __release(mult->lock); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | const struct clk_ops clk_multiplier_ops = { | ||
126 | .recalc_rate = clk_multiplier_recalc_rate, | ||
127 | .round_rate = clk_multiplier_round_rate, | ||
128 | .set_rate = clk_multiplier_set_rate, | ||
129 | }; | ||
130 | EXPORT_SYMBOL_GPL(clk_multiplier_ops); | ||
diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c new file mode 100644 index 000000000000..6af7dce54241 --- /dev/null +++ b/drivers/clk/clk-si514.c | |||
@@ -0,0 +1,379 @@ | |||
1 | /* | ||
2 | * Driver for Silicon Labs Si514 Programmable Oscillator | ||
3 | * | ||
4 | * Copyright (C) 2015 Topic Embedded Products | ||
5 | * | ||
6 | * Author: Mike Looijmans <mike.looijmans@topic.nl> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | /* I2C registers */ | ||
27 | #define SI514_REG_LP 0 | ||
28 | #define SI514_REG_M_FRAC1 5 | ||
29 | #define SI514_REG_M_FRAC2 6 | ||
30 | #define SI514_REG_M_FRAC3 7 | ||
31 | #define SI514_REG_M_INT_FRAC 8 | ||
32 | #define SI514_REG_M_INT 9 | ||
33 | #define SI514_REG_HS_DIV 10 | ||
34 | #define SI514_REG_LS_HS_DIV 11 | ||
35 | #define SI514_REG_OE_STATE 14 | ||
36 | #define SI514_REG_RESET 128 | ||
37 | #define SI514_REG_CONTROL 132 | ||
38 | |||
39 | /* Register values */ | ||
40 | #define SI514_RESET_RST BIT(7) | ||
41 | |||
42 | #define SI514_CONTROL_FCAL BIT(0) | ||
43 | #define SI514_CONTROL_OE BIT(2) | ||
44 | |||
45 | #define SI514_MIN_FREQ 100000U | ||
46 | #define SI514_MAX_FREQ 250000000U | ||
47 | |||
48 | #define FXO 31980000U | ||
49 | |||
50 | #define FVCO_MIN 2080000000U | ||
51 | #define FVCO_MAX 2500000000U | ||
52 | |||
53 | #define HS_DIV_MAX 1022 | ||
54 | |||
55 | struct clk_si514 { | ||
56 | struct clk_hw hw; | ||
57 | struct regmap *regmap; | ||
58 | struct i2c_client *i2c_client; | ||
59 | }; | ||
60 | #define to_clk_si514(_hw) container_of(_hw, struct clk_si514, hw) | ||
61 | |||
62 | /* Multiplier/divider settings */ | ||
63 | struct clk_si514_muldiv { | ||
64 | u32 m_frac; /* 29-bit Fractional part of multiplier M */ | ||
65 | u8 m_int; /* Integer part of multiplier M, 65..78 */ | ||
66 | u8 ls_div_bits; /* 2nd divider, as 2^x */ | ||
67 | u16 hs_div; /* 1st divider, must be even and 10<=x<=1022 */ | ||
68 | }; | ||
69 | |||
70 | /* Enables or disables the output driver */ | ||
71 | static int si514_enable_output(struct clk_si514 *data, bool enable) | ||
72 | { | ||
73 | return regmap_update_bits(data->regmap, SI514_REG_CONTROL, | ||
74 | SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0); | ||
75 | } | ||
76 | |||
77 | /* Retrieve clock multiplier and dividers from hardware */ | ||
78 | static int si514_get_muldiv(struct clk_si514 *data, | ||
79 | struct clk_si514_muldiv *settings) | ||
80 | { | ||
81 | int err; | ||
82 | u8 reg[7]; | ||
83 | |||
84 | err = regmap_bulk_read(data->regmap, SI514_REG_M_FRAC1, | ||
85 | reg, ARRAY_SIZE(reg)); | ||
86 | if (err) | ||
87 | return err; | ||
88 | |||
89 | settings->m_frac = reg[0] | reg[1] << 8 | reg[2] << 16 | | ||
90 | (reg[3] & 0x1F) << 24; | ||
91 | settings->m_int = (reg[4] & 0x3f) << 3 | reg[3] >> 5; | ||
92 | settings->ls_div_bits = (reg[6] >> 4) & 0x07; | ||
93 | settings->hs_div = (reg[6] & 0x03) << 8 | reg[5]; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int si514_set_muldiv(struct clk_si514 *data, | ||
98 | struct clk_si514_muldiv *settings) | ||
99 | { | ||
100 | u8 lp; | ||
101 | u8 reg[7]; | ||
102 | int err; | ||
103 | |||
104 | /* Calculate LP1/LP2 according to table 13 in the datasheet */ | ||
105 | /* 65.259980246 */ | ||
106 | if (settings->m_int < 65 || | ||
107 | (settings->m_int == 65 && settings->m_frac <= 139575831)) | ||
108 | lp = 0x22; | ||
109 | /* 67.859763463 */ | ||
110 | else if (settings->m_int < 67 || | ||
111 | (settings->m_int == 67 && settings->m_frac <= 461581994)) | ||
112 | lp = 0x23; | ||
113 | /* 72.937624981 */ | ||
114 | else if (settings->m_int < 72 || | ||
115 | (settings->m_int == 72 && settings->m_frac <= 503383578)) | ||
116 | lp = 0x33; | ||
117 | /* 75.843265046 */ | ||
118 | else if (settings->m_int < 75 || | ||
119 | (settings->m_int == 75 && settings->m_frac <= 452724474)) | ||
120 | lp = 0x34; | ||
121 | else | ||
122 | lp = 0x44; | ||
123 | |||
124 | err = regmap_write(data->regmap, SI514_REG_LP, lp); | ||
125 | if (err < 0) | ||
126 | return err; | ||
127 | |||
128 | reg[0] = settings->m_frac; | ||
129 | reg[1] = settings->m_frac >> 8; | ||
130 | reg[2] = settings->m_frac >> 16; | ||
131 | reg[3] = settings->m_frac >> 24 | settings->m_int << 5; | ||
132 | reg[4] = settings->m_int >> 3; | ||
133 | reg[5] = settings->hs_div; | ||
134 | reg[6] = (settings->hs_div >> 8) | (settings->ls_div_bits << 4); | ||
135 | |||
136 | err = regmap_bulk_write(data->regmap, SI514_REG_HS_DIV, reg + 5, 2); | ||
137 | if (err < 0) | ||
138 | return err; | ||
139 | /* | ||
140 | * Writing to SI514_REG_M_INT_FRAC triggers the clock change, so that | ||
141 | * must be written last | ||
142 | */ | ||
143 | return regmap_bulk_write(data->regmap, SI514_REG_M_FRAC1, reg, 5); | ||
144 | } | ||
145 | |||
146 | /* Calculate divider settings for a given frequency */ | ||
147 | static int si514_calc_muldiv(struct clk_si514_muldiv *settings, | ||
148 | unsigned long frequency) | ||
149 | { | ||
150 | u64 m; | ||
151 | u32 ls_freq; | ||
152 | u32 tmp; | ||
153 | u8 res; | ||
154 | |||
155 | if ((frequency < SI514_MIN_FREQ) || (frequency > SI514_MAX_FREQ)) | ||
156 | return -EINVAL; | ||
157 | |||
158 | /* Determine the minimum value of LS_DIV and resulting target freq. */ | ||
159 | ls_freq = frequency; | ||
160 | if (frequency >= (FVCO_MIN / HS_DIV_MAX)) | ||
161 | settings->ls_div_bits = 0; | ||
162 | else { | ||
163 | res = 1; | ||
164 | tmp = 2 * HS_DIV_MAX; | ||
165 | while (tmp <= (HS_DIV_MAX * 32)) { | ||
166 | if ((frequency * tmp) >= FVCO_MIN) | ||
167 | break; | ||
168 | ++res; | ||
169 | tmp <<= 1; | ||
170 | } | ||
171 | settings->ls_div_bits = res; | ||
172 | ls_freq = frequency << res; | ||
173 | } | ||
174 | |||
175 | /* Determine minimum HS_DIV, round up to even number */ | ||
176 | settings->hs_div = DIV_ROUND_UP(FVCO_MIN >> 1, ls_freq) << 1; | ||
177 | |||
178 | /* M = LS_DIV x HS_DIV x frequency / F_XO (in fixed-point) */ | ||
179 | m = ((u64)(ls_freq * settings->hs_div) << 29) + (FXO / 2); | ||
180 | do_div(m, FXO); | ||
181 | settings->m_frac = (u32)m & (BIT(29) - 1); | ||
182 | settings->m_int = (u32)(m >> 29); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | /* Calculate resulting frequency given the register settings */ | ||
188 | static unsigned long si514_calc_rate(struct clk_si514_muldiv *settings) | ||
189 | { | ||
190 | u64 m = settings->m_frac | ((u64)settings->m_int << 29); | ||
191 | u32 d = settings->hs_div * BIT(settings->ls_div_bits); | ||
192 | |||
193 | return ((u32)(((m * FXO) + (FXO / 2)) >> 29)) / d; | ||
194 | } | ||
195 | |||
196 | static unsigned long si514_recalc_rate(struct clk_hw *hw, | ||
197 | unsigned long parent_rate) | ||
198 | { | ||
199 | struct clk_si514 *data = to_clk_si514(hw); | ||
200 | struct clk_si514_muldiv settings; | ||
201 | int err; | ||
202 | |||
203 | err = si514_get_muldiv(data, &settings); | ||
204 | if (err) { | ||
205 | dev_err(&data->i2c_client->dev, "unable to retrieve settings\n"); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | return si514_calc_rate(&settings); | ||
210 | } | ||
211 | |||
212 | static long si514_round_rate(struct clk_hw *hw, unsigned long rate, | ||
213 | unsigned long *parent_rate) | ||
214 | { | ||
215 | struct clk_si514_muldiv settings; | ||
216 | int err; | ||
217 | |||
218 | if (!rate) | ||
219 | return 0; | ||
220 | |||
221 | err = si514_calc_muldiv(&settings, rate); | ||
222 | if (err) | ||
223 | return err; | ||
224 | |||
225 | return si514_calc_rate(&settings); | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * Update output frequency for big frequency changes (> 1000 ppm). | ||
230 | * The chip supports <1000ppm changes "on the fly", we haven't implemented | ||
231 | * that here. | ||
232 | */ | ||
233 | static int si514_set_rate(struct clk_hw *hw, unsigned long rate, | ||
234 | unsigned long parent_rate) | ||
235 | { | ||
236 | struct clk_si514 *data = to_clk_si514(hw); | ||
237 | struct clk_si514_muldiv settings; | ||
238 | int err; | ||
239 | |||
240 | err = si514_calc_muldiv(&settings, rate); | ||
241 | if (err) | ||
242 | return err; | ||
243 | |||
244 | si514_enable_output(data, false); | ||
245 | |||
246 | err = si514_set_muldiv(data, &settings); | ||
247 | if (err < 0) | ||
248 | return err; /* Undefined state now, best to leave disabled */ | ||
249 | |||
250 | /* Trigger calibration */ | ||
251 | err = regmap_write(data->regmap, SI514_REG_CONTROL, SI514_CONTROL_FCAL); | ||
252 | if (err < 0) | ||
253 | return err; | ||
254 | |||
255 | /* Applying a new frequency can take up to 10ms */ | ||
256 | usleep_range(10000, 12000); | ||
257 | |||
258 | si514_enable_output(data, true); | ||
259 | |||
260 | return err; | ||
261 | } | ||
262 | |||
263 | static const struct clk_ops si514_clk_ops = { | ||
264 | .recalc_rate = si514_recalc_rate, | ||
265 | .round_rate = si514_round_rate, | ||
266 | .set_rate = si514_set_rate, | ||
267 | }; | ||
268 | |||
269 | static bool si514_regmap_is_volatile(struct device *dev, unsigned int reg) | ||
270 | { | ||
271 | switch (reg) { | ||
272 | case SI514_REG_CONTROL: | ||
273 | case SI514_REG_RESET: | ||
274 | return true; | ||
275 | default: | ||
276 | return false; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | static bool si514_regmap_is_writeable(struct device *dev, unsigned int reg) | ||
281 | { | ||
282 | switch (reg) { | ||
283 | case SI514_REG_LP: | ||
284 | case SI514_REG_M_FRAC1 ... SI514_REG_LS_HS_DIV: | ||
285 | case SI514_REG_OE_STATE: | ||
286 | case SI514_REG_RESET: | ||
287 | case SI514_REG_CONTROL: | ||
288 | return true; | ||
289 | default: | ||
290 | return false; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | static const struct regmap_config si514_regmap_config = { | ||
295 | .reg_bits = 8, | ||
296 | .val_bits = 8, | ||
297 | .cache_type = REGCACHE_RBTREE, | ||
298 | .max_register = SI514_REG_CONTROL, | ||
299 | .writeable_reg = si514_regmap_is_writeable, | ||
300 | .volatile_reg = si514_regmap_is_volatile, | ||
301 | }; | ||
302 | |||
303 | static int si514_probe(struct i2c_client *client, | ||
304 | const struct i2c_device_id *id) | ||
305 | { | ||
306 | struct clk_si514 *data; | ||
307 | struct clk_init_data init; | ||
308 | struct clk *clk; | ||
309 | int err; | ||
310 | |||
311 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | ||
312 | if (!data) | ||
313 | return -ENOMEM; | ||
314 | |||
315 | init.ops = &si514_clk_ops; | ||
316 | init.flags = CLK_IS_ROOT; | ||
317 | init.num_parents = 0; | ||
318 | data->hw.init = &init; | ||
319 | data->i2c_client = client; | ||
320 | |||
321 | if (of_property_read_string(client->dev.of_node, "clock-output-names", | ||
322 | &init.name)) | ||
323 | init.name = client->dev.of_node->name; | ||
324 | |||
325 | data->regmap = devm_regmap_init_i2c(client, &si514_regmap_config); | ||
326 | if (IS_ERR(data->regmap)) { | ||
327 | dev_err(&client->dev, "failed to allocate register map\n"); | ||
328 | return PTR_ERR(data->regmap); | ||
329 | } | ||
330 | |||
331 | i2c_set_clientdata(client, data); | ||
332 | |||
333 | clk = devm_clk_register(&client->dev, &data->hw); | ||
334 | if (IS_ERR(clk)) { | ||
335 | dev_err(&client->dev, "clock registration failed\n"); | ||
336 | return PTR_ERR(clk); | ||
337 | } | ||
338 | err = of_clk_add_provider(client->dev.of_node, of_clk_src_simple_get, | ||
339 | clk); | ||
340 | if (err) { | ||
341 | dev_err(&client->dev, "unable to add clk provider\n"); | ||
342 | return err; | ||
343 | } | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static int si514_remove(struct i2c_client *client) | ||
349 | { | ||
350 | of_clk_del_provider(client->dev.of_node); | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static const struct i2c_device_id si514_id[] = { | ||
355 | { "si514", 0 }, | ||
356 | { } | ||
357 | }; | ||
358 | MODULE_DEVICE_TABLE(i2c, si514_id); | ||
359 | |||
360 | static const struct of_device_id clk_si514_of_match[] = { | ||
361 | { .compatible = "silabs,si514" }, | ||
362 | { }, | ||
363 | }; | ||
364 | MODULE_DEVICE_TABLE(of, clk_si514_of_match); | ||
365 | |||
366 | static struct i2c_driver si514_driver = { | ||
367 | .driver = { | ||
368 | .name = "si514", | ||
369 | .of_match_table = clk_si514_of_match, | ||
370 | }, | ||
371 | .probe = si514_probe, | ||
372 | .remove = si514_remove, | ||
373 | .id_table = si514_id, | ||
374 | }; | ||
375 | module_i2c_driver(si514_driver); | ||
376 | |||
377 | MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>"); | ||
378 | MODULE_DESCRIPTION("Si514 driver"); | ||
379 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 5596c0aac22f..e346b223199d 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c | |||
@@ -1183,13 +1183,13 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1183 | if (of_property_read_u32(child, "reg", &num)) { | 1183 | if (of_property_read_u32(child, "reg", &num)) { |
1184 | dev_err(&client->dev, "missing reg property of %s\n", | 1184 | dev_err(&client->dev, "missing reg property of %s\n", |
1185 | child->name); | 1185 | child->name); |
1186 | return -EINVAL; | 1186 | goto put_child; |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | if (num >= 8 || | 1189 | if (num >= 8 || |
1190 | (variant == SI5351_VARIANT_A3 && num >= 3)) { | 1190 | (variant == SI5351_VARIANT_A3 && num >= 3)) { |
1191 | dev_err(&client->dev, "invalid clkout %d\n", num); | 1191 | dev_err(&client->dev, "invalid clkout %d\n", num); |
1192 | return -EINVAL; | 1192 | goto put_child; |
1193 | } | 1193 | } |
1194 | 1194 | ||
1195 | if (!of_property_read_u32(child, "silabs,multisynth-source", | 1195 | if (!of_property_read_u32(child, "silabs,multisynth-source", |
@@ -1207,7 +1207,7 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1207 | dev_err(&client->dev, | 1207 | dev_err(&client->dev, |
1208 | "invalid parent %d for multisynth %d\n", | 1208 | "invalid parent %d for multisynth %d\n", |
1209 | val, num); | 1209 | val, num); |
1210 | return -EINVAL; | 1210 | goto put_child; |
1211 | } | 1211 | } |
1212 | } | 1212 | } |
1213 | 1213 | ||
@@ -1230,7 +1230,7 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1230 | dev_err(&client->dev, | 1230 | dev_err(&client->dev, |
1231 | "invalid parent %d for clkout %d\n", | 1231 | "invalid parent %d for clkout %d\n", |
1232 | val, num); | 1232 | val, num); |
1233 | return -EINVAL; | 1233 | goto put_child; |
1234 | } | 1234 | } |
1235 | pdata->clkout[num].clkout_src = | 1235 | pdata->clkout[num].clkout_src = |
1236 | SI5351_CLKOUT_SRC_CLKIN; | 1236 | SI5351_CLKOUT_SRC_CLKIN; |
@@ -1239,7 +1239,7 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1239 | dev_err(&client->dev, | 1239 | dev_err(&client->dev, |
1240 | "invalid parent %d for clkout %d\n", | 1240 | "invalid parent %d for clkout %d\n", |
1241 | val, num); | 1241 | val, num); |
1242 | return -EINVAL; | 1242 | goto put_child; |
1243 | } | 1243 | } |
1244 | } | 1244 | } |
1245 | 1245 | ||
@@ -1256,7 +1256,7 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1256 | dev_err(&client->dev, | 1256 | dev_err(&client->dev, |
1257 | "invalid drive strength %d for clkout %d\n", | 1257 | "invalid drive strength %d for clkout %d\n", |
1258 | val, num); | 1258 | val, num); |
1259 | return -EINVAL; | 1259 | goto put_child; |
1260 | } | 1260 | } |
1261 | } | 1261 | } |
1262 | 1262 | ||
@@ -1283,7 +1283,7 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1283 | dev_err(&client->dev, | 1283 | dev_err(&client->dev, |
1284 | "invalid disable state %d for clkout %d\n", | 1284 | "invalid disable state %d for clkout %d\n", |
1285 | val, num); | 1285 | val, num); |
1286 | return -EINVAL; | 1286 | goto put_child; |
1287 | } | 1287 | } |
1288 | } | 1288 | } |
1289 | 1289 | ||
@@ -1296,6 +1296,9 @@ static int si5351_dt_parse(struct i2c_client *client, | |||
1296 | client->dev.platform_data = pdata; | 1296 | client->dev.platform_data = pdata; |
1297 | 1297 | ||
1298 | return 0; | 1298 | return 0; |
1299 | put_child: | ||
1300 | of_node_put(child); | ||
1301 | return -EINVAL; | ||
1299 | } | 1302 | } |
1300 | #else | 1303 | #else |
1301 | static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant) | 1304 | static int si5351_dt_parse(struct i2c_client *client, enum si5351_variant variant) |
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 96a6190acac2..27c0da29eca3 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/clkdev.h> | 27 | #include <linux/clkdev.h> |
28 | #include <linux/clk-provider.h> | 28 | #include <linux/clk-provider.h> |
29 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
30 | #include <asm/setup.h> | ||
31 | 30 | ||
32 | /* Register SCU_PCPPLL bit fields */ | 31 | /* Register SCU_PCPPLL bit fields */ |
33 | #define N_DIV_RD(src) (((src) & 0x000001ff)) | 32 | #define N_DIV_RD(src) (((src) & 0x000001ff)) |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 0ebcf449778a..f13c3f4228d4 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -272,7 +272,7 @@ late_initcall_sync(clk_disable_unused); | |||
272 | 272 | ||
273 | /*** helper functions ***/ | 273 | /*** helper functions ***/ |
274 | 274 | ||
275 | const char *__clk_get_name(struct clk *clk) | 275 | const char *__clk_get_name(const struct clk *clk) |
276 | { | 276 | { |
277 | return !clk ? NULL : clk->core->name; | 277 | return !clk ? NULL : clk->core->name; |
278 | } | 278 | } |
@@ -427,6 +427,11 @@ bool clk_hw_is_prepared(const struct clk_hw *hw) | |||
427 | return clk_core_is_prepared(hw->core); | 427 | return clk_core_is_prepared(hw->core); |
428 | } | 428 | } |
429 | 429 | ||
430 | bool clk_hw_is_enabled(const struct clk_hw *hw) | ||
431 | { | ||
432 | return clk_core_is_enabled(hw->core); | ||
433 | } | ||
434 | |||
430 | bool __clk_is_enabled(struct clk *clk) | 435 | bool __clk_is_enabled(struct clk *clk) |
431 | { | 436 | { |
432 | if (!clk) | 437 | if (!clk) |
@@ -1685,7 +1690,7 @@ static struct clk_core *__clk_init_parent(struct clk_core *core) | |||
1685 | "%s: multi-parent clocks must implement .get_parent\n", | 1690 | "%s: multi-parent clocks must implement .get_parent\n", |
1686 | __func__); | 1691 | __func__); |
1687 | goto out; | 1692 | goto out; |
1688 | }; | 1693 | } |
1689 | 1694 | ||
1690 | /* | 1695 | /* |
1691 | * Do our best to cache parent clocks in core->parents. This prevents | 1696 | * Do our best to cache parent clocks in core->parents. This prevents |
@@ -2932,7 +2937,7 @@ struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) | |||
2932 | unsigned int idx = clkspec->args[0]; | 2937 | unsigned int idx = clkspec->args[0]; |
2933 | 2938 | ||
2934 | if (idx >= clk_data->clk_num) { | 2939 | if (idx >= clk_data->clk_num) { |
2935 | pr_err("%s: invalid clock index %d\n", __func__, idx); | 2940 | pr_err("%s: invalid clock index %u\n", __func__, idx); |
2936 | return ERR_PTR(-EINVAL); | 2941 | return ERR_PTR(-EINVAL); |
2937 | } | 2942 | } |
2938 | 2943 | ||
@@ -3055,6 +3060,7 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) | |||
3055 | u32 pv; | 3060 | u32 pv; |
3056 | int rc; | 3061 | int rc; |
3057 | int count; | 3062 | int count; |
3063 | struct clk *clk; | ||
3058 | 3064 | ||
3059 | if (index < 0) | 3065 | if (index < 0) |
3060 | return NULL; | 3066 | return NULL; |
@@ -3080,8 +3086,25 @@ const char *of_clk_get_parent_name(struct device_node *np, int index) | |||
3080 | 3086 | ||
3081 | if (of_property_read_string_index(clkspec.np, "clock-output-names", | 3087 | if (of_property_read_string_index(clkspec.np, "clock-output-names", |
3082 | index, | 3088 | index, |
3083 | &clk_name) < 0) | 3089 | &clk_name) < 0) { |
3084 | clk_name = clkspec.np->name; | 3090 | /* |
3091 | * Best effort to get the name if the clock has been | ||
3092 | * registered with the framework. If the clock isn't | ||
3093 | * registered, we return the node name as the name of | ||
3094 | * the clock as long as #clock-cells = 0. | ||
3095 | */ | ||
3096 | clk = of_clk_get_from_provider(&clkspec); | ||
3097 | if (IS_ERR(clk)) { | ||
3098 | if (clkspec.args_count == 0) | ||
3099 | clk_name = clkspec.np->name; | ||
3100 | else | ||
3101 | clk_name = NULL; | ||
3102 | } else { | ||
3103 | clk_name = __clk_get_name(clk); | ||
3104 | clk_put(clk); | ||
3105 | } | ||
3106 | } | ||
3107 | |||
3085 | 3108 | ||
3086 | of_node_put(clkspec.np); | 3109 | of_node_put(clkspec.np); |
3087 | return clk_name; | 3110 | return clk_name; |
@@ -3179,13 +3202,15 @@ void __init of_clk_init(const struct of_device_id *matches) | |||
3179 | list_for_each_entry_safe(clk_provider, next, | 3202 | list_for_each_entry_safe(clk_provider, next, |
3180 | &clk_provider_list, node) { | 3203 | &clk_provider_list, node) { |
3181 | list_del(&clk_provider->node); | 3204 | list_del(&clk_provider->node); |
3205 | of_node_put(clk_provider->np); | ||
3182 | kfree(clk_provider); | 3206 | kfree(clk_provider); |
3183 | } | 3207 | } |
3208 | of_node_put(np); | ||
3184 | return; | 3209 | return; |
3185 | } | 3210 | } |
3186 | 3211 | ||
3187 | parent->clk_init_cb = match->data; | 3212 | parent->clk_init_cb = match->data; |
3188 | parent->np = np; | 3213 | parent->np = of_node_get(np); |
3189 | list_add_tail(&parent->node, &clk_provider_list); | 3214 | list_add_tail(&parent->node, &clk_provider_list); |
3190 | } | 3215 | } |
3191 | 3216 | ||
@@ -3199,6 +3224,7 @@ void __init of_clk_init(const struct of_device_id *matches) | |||
3199 | of_clk_set_defaults(clk_provider->np, true); | 3224 | of_clk_set_defaults(clk_provider->np, true); |
3200 | 3225 | ||
3201 | list_del(&clk_provider->node); | 3226 | list_del(&clk_provider->node); |
3227 | of_node_put(clk_provider->np); | ||
3202 | kfree(clk_provider); | 3228 | kfree(clk_provider); |
3203 | is_init_done = true; | 3229 | is_init_done = true; |
3204 | } | 3230 | } |
diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c index 2c4add11c1ca..8afb40ef40ce 100644 --- a/drivers/clk/hisilicon/clk-hi6220-stub.c +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c | |||
@@ -230,7 +230,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev) | |||
230 | if (IS_ERR(stub_clk->mbox)) { | 230 | if (IS_ERR(stub_clk->mbox)) { |
231 | dev_err(dev, "failed get mailbox channel\n"); | 231 | dev_err(dev, "failed get mailbox channel\n"); |
232 | return PTR_ERR(stub_clk->mbox); | 232 | return PTR_ERR(stub_clk->mbox); |
233 | }; | 233 | } |
234 | 234 | ||
235 | init.name = "acpu0"; | 235 | init.name = "acpu0"; |
236 | init.ops = &hi6220_stub_clk_ops; | 236 | init.ops = &hi6220_stub_clk_ops; |
diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c index ec1a4c1dacf1..c4c141cab444 100644 --- a/drivers/clk/imx/clk-imx25.c +++ b/drivers/clk/imx/clk-imx25.c | |||
@@ -86,6 +86,16 @@ enum mx25_clks { | |||
86 | 86 | ||
87 | static struct clk *clk[clk_max]; | 87 | static struct clk *clk[clk_max]; |
88 | 88 | ||
89 | static struct clk ** const uart_clks[] __initconst = { | ||
90 | &clk[uart_ipg_per], | ||
91 | &clk[uart1_ipg], | ||
92 | &clk[uart2_ipg], | ||
93 | &clk[uart3_ipg], | ||
94 | &clk[uart4_ipg], | ||
95 | &clk[uart5_ipg], | ||
96 | NULL | ||
97 | }; | ||
98 | |||
89 | static int __init __mx25_clocks_init(unsigned long osc_rate, | 99 | static int __init __mx25_clocks_init(unsigned long osc_rate, |
90 | void __iomem *ccm_base) | 100 | void __iomem *ccm_base) |
91 | { | 101 | { |
@@ -233,6 +243,8 @@ static int __init __mx25_clocks_init(unsigned long osc_rate, | |||
233 | */ | 243 | */ |
234 | clk_set_parent(clk[cko_sel], clk[ipg]); | 244 | clk_set_parent(clk[cko_sel], clk[ipg]); |
235 | 245 | ||
246 | imx_register_uart_clocks(uart_clks); | ||
247 | |||
236 | return 0; | 248 | return 0; |
237 | } | 249 | } |
238 | 250 | ||
diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c index d9d50d54ef2a..cf5cf75a4848 100644 --- a/drivers/clk/imx/clk-imx27.c +++ b/drivers/clk/imx/clk-imx27.c | |||
@@ -47,6 +47,17 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", }; | |||
47 | static struct clk *clk[IMX27_CLK_MAX]; | 47 | static struct clk *clk[IMX27_CLK_MAX]; |
48 | static struct clk_onecell_data clk_data; | 48 | static struct clk_onecell_data clk_data; |
49 | 49 | ||
50 | static struct clk ** const uart_clks[] __initconst = { | ||
51 | &clk[IMX27_CLK_PER1_GATE], | ||
52 | &clk[IMX27_CLK_UART1_IPG_GATE], | ||
53 | &clk[IMX27_CLK_UART2_IPG_GATE], | ||
54 | &clk[IMX27_CLK_UART3_IPG_GATE], | ||
55 | &clk[IMX27_CLK_UART4_IPG_GATE], | ||
56 | &clk[IMX27_CLK_UART5_IPG_GATE], | ||
57 | &clk[IMX27_CLK_UART6_IPG_GATE], | ||
58 | NULL | ||
59 | }; | ||
60 | |||
50 | static void __init _mx27_clocks_init(unsigned long fref) | 61 | static void __init _mx27_clocks_init(unsigned long fref) |
51 | { | 62 | { |
52 | BUG_ON(!ccm); | 63 | BUG_ON(!ccm); |
@@ -163,6 +174,8 @@ static void __init _mx27_clocks_init(unsigned long fref) | |||
163 | 174 | ||
164 | clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]); | 175 | clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]); |
165 | 176 | ||
177 | imx_register_uart_clocks(uart_clks); | ||
178 | |||
166 | imx_print_silicon_rev("i.MX27", mx27_revision()); | 179 | imx_print_silicon_rev("i.MX27", mx27_revision()); |
167 | } | 180 | } |
168 | 181 | ||
@@ -248,8 +261,10 @@ static void __init mx27_clocks_init_dt(struct device_node *np) | |||
248 | if (!of_device_is_compatible(refnp, "fsl,imx-osc26m")) | 261 | if (!of_device_is_compatible(refnp, "fsl,imx-osc26m")) |
249 | continue; | 262 | continue; |
250 | 263 | ||
251 | if (!of_property_read_u32(refnp, "clock-frequency", &fref)) | 264 | if (!of_property_read_u32(refnp, "clock-frequency", &fref)) { |
265 | of_node_put(refnp); | ||
252 | break; | 266 | break; |
267 | } | ||
253 | } | 268 | } |
254 | 269 | ||
255 | ccm = of_iomap(np, 0); | 270 | ccm = of_iomap(np, 0); |
diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c index 1f8383475bb3..6a964144a5b5 100644 --- a/drivers/clk/imx/clk-imx31.c +++ b/drivers/clk/imx/clk-imx31.c | |||
@@ -62,7 +62,17 @@ enum mx31_clks { | |||
62 | static struct clk *clk[clk_max]; | 62 | static struct clk *clk[clk_max]; |
63 | static struct clk_onecell_data clk_data; | 63 | static struct clk_onecell_data clk_data; |
64 | 64 | ||
65 | int __init mx31_clocks_init(unsigned long fref) | 65 | static struct clk ** const uart_clks[] __initconst = { |
66 | &clk[ipg], | ||
67 | &clk[uart1_gate], | ||
68 | &clk[uart2_gate], | ||
69 | &clk[uart3_gate], | ||
70 | &clk[uart4_gate], | ||
71 | &clk[uart5_gate], | ||
72 | NULL | ||
73 | }; | ||
74 | |||
75 | static void __init _mx31_clocks_init(unsigned long fref) | ||
66 | { | 76 | { |
67 | void __iomem *base; | 77 | void __iomem *base; |
68 | struct device_node *np; | 78 | struct device_node *np; |
@@ -132,6 +142,12 @@ int __init mx31_clocks_init(unsigned long fref) | |||
132 | 142 | ||
133 | imx_check_clocks(clk, ARRAY_SIZE(clk)); | 143 | imx_check_clocks(clk, ARRAY_SIZE(clk)); |
134 | 144 | ||
145 | clk_set_parent(clk[csi], clk[upll]); | ||
146 | clk_prepare_enable(clk[emi_gate]); | ||
147 | clk_prepare_enable(clk[iim_gate]); | ||
148 | mx31_revision(); | ||
149 | clk_disable_unprepare(clk[iim_gate]); | ||
150 | |||
135 | np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); | 151 | np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); |
136 | 152 | ||
137 | if (np) { | 153 | if (np) { |
@@ -139,6 +155,13 @@ int __init mx31_clocks_init(unsigned long fref) | |||
139 | clk_data.clk_num = ARRAY_SIZE(clk); | 155 | clk_data.clk_num = ARRAY_SIZE(clk); |
140 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 156 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); |
141 | } | 157 | } |
158 | } | ||
159 | |||
160 | int __init mx31_clocks_init(void) | ||
161 | { | ||
162 | u32 fref = 26000000; /* default */ | ||
163 | |||
164 | _mx31_clocks_init(fref); | ||
142 | 165 | ||
143 | clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); | 166 | clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); |
144 | clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); | 167 | clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); |
@@ -194,12 +217,8 @@ int __init mx31_clocks_init(unsigned long fref) | |||
194 | clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma"); | 217 | clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma"); |
195 | clk_register_clkdev(clk[iim_gate], "iim", NULL); | 218 | clk_register_clkdev(clk[iim_gate], "iim", NULL); |
196 | 219 | ||
197 | clk_set_parent(clk[csi], clk[upll]); | ||
198 | clk_prepare_enable(clk[emi_gate]); | ||
199 | clk_prepare_enable(clk[iim_gate]); | ||
200 | mx31_revision(); | ||
201 | clk_disable_unprepare(clk[iim_gate]); | ||
202 | 220 | ||
221 | imx_register_uart_clocks(uart_clks); | ||
203 | mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); | 222 | mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31); |
204 | 223 | ||
205 | return 0; | 224 | return 0; |
@@ -214,9 +233,13 @@ int __init mx31_clocks_init_dt(void) | |||
214 | if (!of_device_is_compatible(np, "fsl,imx-osc26m")) | 233 | if (!of_device_is_compatible(np, "fsl,imx-osc26m")) |
215 | continue; | 234 | continue; |
216 | 235 | ||
217 | if (!of_property_read_u32(np, "clock-frequency", &fref)) | 236 | if (!of_property_read_u32(np, "clock-frequency", &fref)) { |
237 | of_node_put(np); | ||
218 | break; | 238 | break; |
239 | } | ||
219 | } | 240 | } |
220 | 241 | ||
221 | return mx31_clocks_init(fref); | 242 | _mx31_clocks_init(fref); |
243 | |||
244 | return 0; | ||
222 | } | 245 | } |
diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c index 8623cd4e49fd..a71d24cb4c06 100644 --- a/drivers/clk/imx/clk-imx35.c +++ b/drivers/clk/imx/clk-imx35.c | |||
@@ -84,7 +84,15 @@ enum mx35_clks { | |||
84 | 84 | ||
85 | static struct clk *clk[clk_max]; | 85 | static struct clk *clk[clk_max]; |
86 | 86 | ||
87 | int __init mx35_clocks_init(void) | 87 | static struct clk ** const uart_clks[] __initconst = { |
88 | &clk[ipg], | ||
89 | &clk[uart1_gate], | ||
90 | &clk[uart2_gate], | ||
91 | &clk[uart3_gate], | ||
92 | NULL | ||
93 | }; | ||
94 | |||
95 | static void __init _mx35_clocks_init(void) | ||
88 | { | 96 | { |
89 | void __iomem *base; | 97 | void __iomem *base; |
90 | u32 pdr0, consumer_sel, hsp_sel; | 98 | u32 pdr0, consumer_sel, hsp_sel; |
@@ -220,6 +228,32 @@ int __init mx35_clocks_init(void) | |||
220 | 228 | ||
221 | imx_check_clocks(clk, ARRAY_SIZE(clk)); | 229 | imx_check_clocks(clk, ARRAY_SIZE(clk)); |
222 | 230 | ||
231 | clk_prepare_enable(clk[spba_gate]); | ||
232 | clk_prepare_enable(clk[gpio1_gate]); | ||
233 | clk_prepare_enable(clk[gpio2_gate]); | ||
234 | clk_prepare_enable(clk[gpio3_gate]); | ||
235 | clk_prepare_enable(clk[iim_gate]); | ||
236 | clk_prepare_enable(clk[emi_gate]); | ||
237 | clk_prepare_enable(clk[max_gate]); | ||
238 | clk_prepare_enable(clk[iomuxc_gate]); | ||
239 | |||
240 | /* | ||
241 | * SCC is needed to boot via mmc after a watchdog reset. The clock code | ||
242 | * before conversion to common clk also enabled UART1 (which isn't | ||
243 | * handled here and not needed for mmc) and IIM (which is enabled | ||
244 | * unconditionally above). | ||
245 | */ | ||
246 | clk_prepare_enable(clk[scc_gate]); | ||
247 | |||
248 | imx_register_uart_clocks(uart_clks); | ||
249 | |||
250 | imx_print_silicon_rev("i.MX35", mx35_revision()); | ||
251 | } | ||
252 | |||
253 | int __init mx35_clocks_init(void) | ||
254 | { | ||
255 | _mx35_clocks_init(); | ||
256 | |||
223 | clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); | 257 | clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); |
224 | clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); | 258 | clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); |
225 | clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); | 259 | clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); |
@@ -279,25 +313,6 @@ int __init mx35_clocks_init(void) | |||
279 | clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); | 313 | clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); |
280 | clk_register_clkdev(clk[admux_gate], "audmux", NULL); | 314 | clk_register_clkdev(clk[admux_gate], "audmux", NULL); |
281 | 315 | ||
282 | clk_prepare_enable(clk[spba_gate]); | ||
283 | clk_prepare_enable(clk[gpio1_gate]); | ||
284 | clk_prepare_enable(clk[gpio2_gate]); | ||
285 | clk_prepare_enable(clk[gpio3_gate]); | ||
286 | clk_prepare_enable(clk[iim_gate]); | ||
287 | clk_prepare_enable(clk[emi_gate]); | ||
288 | clk_prepare_enable(clk[max_gate]); | ||
289 | clk_prepare_enable(clk[iomuxc_gate]); | ||
290 | |||
291 | /* | ||
292 | * SCC is needed to boot via mmc after a watchdog reset. The clock code | ||
293 | * before conversion to common clk also enabled UART1 (which isn't | ||
294 | * handled here and not needed for mmc) and IIM (which is enabled | ||
295 | * unconditionally above). | ||
296 | */ | ||
297 | clk_prepare_enable(clk[scc_gate]); | ||
298 | |||
299 | imx_print_silicon_rev("i.MX35", mx35_revision()); | ||
300 | |||
301 | mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31); | 316 | mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31); |
302 | 317 | ||
303 | return 0; | 318 | return 0; |
@@ -305,10 +320,10 @@ int __init mx35_clocks_init(void) | |||
305 | 320 | ||
306 | static void __init mx35_clocks_init_dt(struct device_node *ccm_node) | 321 | static void __init mx35_clocks_init_dt(struct device_node *ccm_node) |
307 | { | 322 | { |
323 | _mx35_clocks_init(); | ||
324 | |||
308 | clk_data.clks = clk; | 325 | clk_data.clks = clk; |
309 | clk_data.clk_num = ARRAY_SIZE(clk); | 326 | clk_data.clk_num = ARRAY_SIZE(clk); |
310 | of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); | 327 | of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); |
311 | |||
312 | mx35_clocks_init(); | ||
313 | } | 328 | } |
314 | CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); | 329 | CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); |
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index a7e4f394be0d..c6770348d2ab 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c | |||
@@ -130,6 +130,20 @@ static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" }; | |||
130 | static struct clk *clk[IMX5_CLK_END]; | 130 | static struct clk *clk[IMX5_CLK_END]; |
131 | static struct clk_onecell_data clk_data; | 131 | static struct clk_onecell_data clk_data; |
132 | 132 | ||
133 | static struct clk ** const uart_clks[] __initconst = { | ||
134 | &clk[IMX5_CLK_UART1_IPG_GATE], | ||
135 | &clk[IMX5_CLK_UART1_PER_GATE], | ||
136 | &clk[IMX5_CLK_UART2_IPG_GATE], | ||
137 | &clk[IMX5_CLK_UART2_PER_GATE], | ||
138 | &clk[IMX5_CLK_UART3_IPG_GATE], | ||
139 | &clk[IMX5_CLK_UART3_PER_GATE], | ||
140 | &clk[IMX5_CLK_UART4_IPG_GATE], | ||
141 | &clk[IMX5_CLK_UART4_PER_GATE], | ||
142 | &clk[IMX5_CLK_UART5_IPG_GATE], | ||
143 | &clk[IMX5_CLK_UART5_PER_GATE], | ||
144 | NULL | ||
145 | }; | ||
146 | |||
133 | static void __init mx5_clocks_common_init(void __iomem *ccm_base) | 147 | static void __init mx5_clocks_common_init(void __iomem *ccm_base) |
134 | { | 148 | { |
135 | clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); | 149 | clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); |
@@ -310,6 +324,8 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base) | |||
310 | clk_prepare_enable(clk[IMX5_CLK_TMAX1]); | 324 | clk_prepare_enable(clk[IMX5_CLK_TMAX1]); |
311 | clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ | 325 | clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ |
312 | clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ | 326 | clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ |
327 | |||
328 | imx_register_uart_clocks(uart_clks); | ||
313 | } | 329 | } |
314 | 330 | ||
315 | static void __init mx50_clocks_init(struct device_node *np) | 331 | static void __init mx50_clocks_init(struct device_node *np) |
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index b2c1c047dc94..c1935081d34a 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c | |||
@@ -119,6 +119,7 @@ static unsigned int share_count_ssi1; | |||
119 | static unsigned int share_count_ssi2; | 119 | static unsigned int share_count_ssi2; |
120 | static unsigned int share_count_ssi3; | 120 | static unsigned int share_count_ssi3; |
121 | static unsigned int share_count_mipi_core_cfg; | 121 | static unsigned int share_count_mipi_core_cfg; |
122 | static unsigned int share_count_spdif; | ||
122 | 123 | ||
123 | static inline int clk_on_imx6q(void) | 124 | static inline int clk_on_imx6q(void) |
124 | { | 125 | { |
@@ -130,6 +131,12 @@ static inline int clk_on_imx6dl(void) | |||
130 | return of_machine_is_compatible("fsl,imx6dl"); | 131 | return of_machine_is_compatible("fsl,imx6dl"); |
131 | } | 132 | } |
132 | 133 | ||
134 | static struct clk ** const uart_clks[] __initconst = { | ||
135 | &clk[IMX6QDL_CLK_UART_IPG], | ||
136 | &clk[IMX6QDL_CLK_UART_SERIAL], | ||
137 | NULL | ||
138 | }; | ||
139 | |||
133 | static void __init imx6q_clocks_init(struct device_node *ccm_node) | 140 | static void __init imx6q_clocks_init(struct device_node *ccm_node) |
134 | { | 141 | { |
135 | struct device_node *np; | 142 | struct device_node *np; |
@@ -456,7 +463,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
456 | clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); | 463 | clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); |
457 | clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); | 464 | clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); |
458 | clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 465 | clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); |
459 | clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); | 466 | clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_spdif); |
467 | clk[IMX6QDL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); | ||
460 | clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 468 | clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
461 | clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 469 | clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
462 | clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 470 | clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
@@ -541,5 +549,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) | |||
541 | /* All existing boards with PCIe use LVDS1 */ | 549 | /* All existing boards with PCIe use LVDS1 */ |
542 | if (IS_ENABLED(CONFIG_PCI_IMX6)) | 550 | if (IS_ENABLED(CONFIG_PCI_IMX6)) |
543 | clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); | 551 | clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); |
552 | |||
553 | imx_register_uart_clocks(uart_clks); | ||
544 | } | 554 | } |
545 | CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); | 555 | CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); |
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index a0d4cf26cfa9..1be6230a07af 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c | |||
@@ -97,6 +97,7 @@ static struct clk_div_table video_div_table[] = { | |||
97 | static unsigned int share_count_ssi1; | 97 | static unsigned int share_count_ssi1; |
98 | static unsigned int share_count_ssi2; | 98 | static unsigned int share_count_ssi2; |
99 | static unsigned int share_count_ssi3; | 99 | static unsigned int share_count_ssi3; |
100 | static unsigned int share_count_spdif; | ||
100 | 101 | ||
101 | static struct clk *clks[IMX6SL_CLK_END]; | 102 | static struct clk *clks[IMX6SL_CLK_END]; |
102 | static struct clk_onecell_data clk_data; | 103 | static struct clk_onecell_data clk_data; |
@@ -184,6 +185,12 @@ void imx6sl_set_wait_clk(bool enter) | |||
184 | imx6sl_enable_pll_arm(false); | 185 | imx6sl_enable_pll_arm(false); |
185 | } | 186 | } |
186 | 187 | ||
188 | static struct clk ** const uart_clks[] __initconst = { | ||
189 | &clks[IMX6SL_CLK_UART], | ||
190 | &clks[IMX6SL_CLK_UART_SERIAL], | ||
191 | NULL | ||
192 | }; | ||
193 | |||
187 | static void __init imx6sl_clocks_init(struct device_node *ccm_node) | 194 | static void __init imx6sl_clocks_init(struct device_node *ccm_node) |
188 | { | 195 | { |
189 | struct device_node *np; | 196 | struct device_node *np; |
@@ -391,7 +398,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
391 | clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); | 398 | clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); |
392 | clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); | 399 | clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); |
393 | clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 400 | clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); |
394 | clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14); | 401 | clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif0_podf", base + 0x7c, 14, &share_count_spdif); |
402 | clks[IMX6SL_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_spdif); | ||
395 | clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 403 | clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
396 | clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 404 | clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
397 | clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 405 | clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
@@ -439,5 +447,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) | |||
439 | 447 | ||
440 | clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], | 448 | clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], |
441 | clks[IMX6SL_CLK_PLL2_PFD2]); | 449 | clks[IMX6SL_CLK_PLL2_PFD2]); |
450 | |||
451 | imx_register_uart_clocks(uart_clks); | ||
442 | } | 452 | } |
443 | CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); | 453 | CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); |
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index 5b95c2c2bf52..fea125eb4330 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c | |||
@@ -135,6 +135,12 @@ static u32 share_count_ssi1; | |||
135 | static u32 share_count_ssi2; | 135 | static u32 share_count_ssi2; |
136 | static u32 share_count_ssi3; | 136 | static u32 share_count_ssi3; |
137 | 137 | ||
138 | static struct clk ** const uart_clks[] __initconst = { | ||
139 | &clks[IMX6SX_CLK_UART_IPG], | ||
140 | &clks[IMX6SX_CLK_UART_SERIAL], | ||
141 | NULL | ||
142 | }; | ||
143 | |||
138 | static void __init imx6sx_clocks_init(struct device_node *ccm_node) | 144 | static void __init imx6sx_clocks_init(struct device_node *ccm_node) |
139 | { | 145 | { |
140 | struct device_node *np; | 146 | struct device_node *np; |
@@ -454,6 +460,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
454 | clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); | 460 | clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); |
455 | clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); | 461 | clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); |
456 | clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); | 462 | clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); |
463 | clks[IMX6SX_CLK_SPDIF_GCLK] = imx_clk_gate2_shared("spdif_gclk", "ipg", base + 0x7c, 14, &share_count_audio); | ||
457 | clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); | 464 | clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); |
458 | clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); | 465 | clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); |
459 | clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); | 466 | clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); |
@@ -557,5 +564,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) | |||
557 | 564 | ||
558 | clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); | 565 | clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); |
559 | clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); | 566 | clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); |
567 | |||
568 | imx_register_uart_clocks(uart_clks); | ||
560 | } | 569 | } |
561 | CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); | 570 | CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); |
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index aaa36650695f..01718d05e952 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c | |||
@@ -407,6 +407,24 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) | |||
407 | clk_data.clk_num = ARRAY_SIZE(clks); | 407 | clk_data.clk_num = ARRAY_SIZE(clks); |
408 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | 408 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); |
409 | 409 | ||
410 | /* | ||
411 | * Lower the AHB clock rate before changing the parent clock source, | ||
412 | * as AHB clock rate can NOT be higher than 133MHz, but its parent | ||
413 | * will be switched from 396MHz PFD to 528MHz PLL in order to increase | ||
414 | * AXI clock rate, so we need to lower AHB rate first to make sure at | ||
415 | * any time, AHB rate is <= 133MHz. | ||
416 | */ | ||
417 | clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000); | ||
418 | |||
419 | /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */ | ||
420 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]); | ||
421 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]); | ||
422 | clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]); | ||
423 | clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]); | ||
424 | |||
425 | /* Make sure AHB rate is 132MHz */ | ||
426 | clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000); | ||
427 | |||
410 | /* set perclk to from OSC */ | 428 | /* set perclk to from OSC */ |
411 | clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]); | 429 | clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]); |
412 | 430 | ||
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 71f3a94b472c..448ef321948b 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c | |||
@@ -363,6 +363,17 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_ | |||
363 | 363 | ||
364 | static struct clk_onecell_data clk_data; | 364 | static struct clk_onecell_data clk_data; |
365 | 365 | ||
366 | static struct clk ** const uart_clks[] __initconst = { | ||
367 | &clks[IMX7D_UART1_ROOT_CLK], | ||
368 | &clks[IMX7D_UART2_ROOT_CLK], | ||
369 | &clks[IMX7D_UART3_ROOT_CLK], | ||
370 | &clks[IMX7D_UART4_ROOT_CLK], | ||
371 | &clks[IMX7D_UART5_ROOT_CLK], | ||
372 | &clks[IMX7D_UART6_ROOT_CLK], | ||
373 | &clks[IMX7D_UART7_ROOT_CLK], | ||
374 | NULL | ||
375 | }; | ||
376 | |||
366 | static void __init imx7d_clocks_init(struct device_node *ccm_node) | 377 | static void __init imx7d_clocks_init(struct device_node *ccm_node) |
367 | { | 378 | { |
368 | struct device_node *np; | 379 | struct device_node *np; |
@@ -818,6 +829,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) | |||
818 | clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); | 829 | clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); |
819 | clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); | 830 | clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); |
820 | clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); | 831 | clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); |
832 | clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate2("adc_root_clk", "ipg_root_clk", base + 0x4200, 0); | ||
821 | 833 | ||
822 | clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); | 834 | clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); |
823 | 835 | ||
@@ -856,5 +868,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) | |||
856 | /* set uart module clock's parent clock source that must be great then 80MHz */ | 868 | /* set uart module clock's parent clock source that must be great then 80MHz */ |
857 | clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); | 869 | clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]); |
858 | 870 | ||
871 | imx_register_uart_clocks(uart_clks); | ||
872 | |||
859 | } | 873 | } |
860 | CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init); | 874 | CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init); |
diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c index 20889d59b44d..b18f875eac6a 100644 --- a/drivers/clk/imx/clk-pllv2.c +++ b/drivers/clk/imx/clk-pllv2.c | |||
@@ -77,7 +77,7 @@ struct clk_pllv2 { | |||
77 | static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, | 77 | static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, |
78 | u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) | 78 | u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) |
79 | { | 79 | { |
80 | long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; | 80 | long mfi, mfn, mfd, pdf, ref_clk; |
81 | unsigned long dbl; | 81 | unsigned long dbl; |
82 | s64 temp; | 82 | s64 temp; |
83 | 83 | ||
@@ -87,19 +87,15 @@ static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, | |||
87 | mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; | 87 | mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; |
88 | mfi = (mfi <= 5) ? 5 : mfi; | 88 | mfi = (mfi <= 5) ? 5 : mfi; |
89 | mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; | 89 | mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; |
90 | mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; | 90 | mfn = dp_mfn & MXC_PLL_DP_MFN_MASK; |
91 | /* Sign extend to 32-bits */ | 91 | mfn = sign_extend32(mfn, 26); |
92 | if (mfn >= 0x04000000) { | ||
93 | mfn |= 0xFC000000; | ||
94 | mfn_abs = -mfn; | ||
95 | } | ||
96 | 92 | ||
97 | ref_clk = 2 * parent_rate; | 93 | ref_clk = 2 * parent_rate; |
98 | if (dbl != 0) | 94 | if (dbl != 0) |
99 | ref_clk *= 2; | 95 | ref_clk *= 2; |
100 | 96 | ||
101 | ref_clk /= (pdf + 1); | 97 | ref_clk /= (pdf + 1); |
102 | temp = (u64) ref_clk * mfn_abs; | 98 | temp = (u64) ref_clk * abs(mfn); |
103 | do_div(temp, mfd + 1); | 99 | do_div(temp, mfd + 1); |
104 | if (mfn < 0) | 100 | if (mfn < 0) |
105 | temp = -temp; | 101 | temp = -temp; |
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index bff45ead7389..d1b1c95177bb 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c | |||
@@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) | |||
387 | 387 | ||
388 | clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); | 388 | clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); |
389 | clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24); | 389 | clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24); |
390 | clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5)); | ||
390 | 391 | ||
391 | imx_check_clocks(clk, ARRAY_SIZE(clk)); | 392 | imx_check_clocks(clk, ARRAY_SIZE(clk)); |
392 | 393 | ||
diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index df12b5307175..a634b1185be3 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c | |||
@@ -73,3 +73,41 @@ void imx_cscmr1_fixup(u32 *val) | |||
73 | *val ^= CSCMR1_FIXUP; | 73 | *val ^= CSCMR1_FIXUP; |
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | |||
77 | static int imx_keep_uart_clocks __initdata; | ||
78 | static struct clk ** const *imx_uart_clocks __initdata; | ||
79 | |||
80 | static int __init imx_keep_uart_clocks_param(char *str) | ||
81 | { | ||
82 | imx_keep_uart_clocks = 1; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | __setup_param("earlycon", imx_keep_uart_earlycon, | ||
87 | imx_keep_uart_clocks_param, 0); | ||
88 | __setup_param("earlyprintk", imx_keep_uart_earlyprintk, | ||
89 | imx_keep_uart_clocks_param, 0); | ||
90 | |||
91 | void __init imx_register_uart_clocks(struct clk ** const clks[]) | ||
92 | { | ||
93 | if (imx_keep_uart_clocks) { | ||
94 | int i; | ||
95 | |||
96 | imx_uart_clocks = clks; | ||
97 | for (i = 0; imx_uart_clocks[i]; i++) | ||
98 | clk_prepare_enable(*imx_uart_clocks[i]); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static int __init imx_clk_disable_uart(void) | ||
103 | { | ||
104 | if (imx_keep_uart_clocks && imx_uart_clocks) { | ||
105 | int i; | ||
106 | |||
107 | for (i = 0; imx_uart_clocks[i]; i++) | ||
108 | clk_disable_unprepare(*imx_uart_clocks[i]); | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | late_initcall_sync(imx_clk_disable_uart); | ||
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 1049b0c7d818..c94ac5c26226 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h | |||
@@ -7,6 +7,7 @@ | |||
7 | extern spinlock_t imx_ccm_lock; | 7 | extern spinlock_t imx_ccm_lock; |
8 | 8 | ||
9 | void imx_check_clocks(struct clk *clks[], unsigned int count); | 9 | void imx_check_clocks(struct clk *clks[], unsigned int count); |
10 | void imx_register_uart_clocks(struct clk ** const clks[]); | ||
10 | 11 | ||
11 | extern void imx_cscmr1_fixup(u32 *val); | 12 | extern void imx_cscmr1_fixup(u32 *val); |
12 | 13 | ||
diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c index 3f553d0ae0b5..a26ba2184454 100644 --- a/drivers/clk/keystone/pll.c +++ b/drivers/clk/keystone/pll.c | |||
@@ -157,7 +157,7 @@ out: | |||
157 | * _of_clk_init - PLL initialisation via DT | 157 | * _of_clk_init - PLL initialisation via DT |
158 | * @node: device tree node for this clock | 158 | * @node: device tree node for this clock |
159 | * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of | 159 | * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of |
160 | * pll controller, else it is in the control regsiter0(bit 11-6) | 160 | * pll controller, else it is in the control register0(bit 11-6) |
161 | */ | 161 | */ |
162 | static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) | 162 | static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) |
163 | { | 163 | { |
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 8e4b2a4635b9..95fdfacb2ebf 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y += clk-mtk.o clk-pll.o clk-gate.o | 1 | obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o |
2 | obj-$(CONFIG_RESET_CONTROLLER) += reset.o | 2 | obj-$(CONFIG_RESET_CONTROLLER) += reset.o |
3 | obj-y += clk-mt8135.o | 3 | obj-y += clk-mt8135.o |
4 | obj-y += clk-mt8173.o | 4 | obj-y += clk-mt8173.o |
diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c new file mode 100644 index 000000000000..5303c5980867 --- /dev/null +++ b/drivers/clk/mediatek/clk-apmixed.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 MediaTek Inc. | ||
3 | * Author: James Liao <jamesjj.liao@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/delay.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #include "clk-mtk.h" | ||
20 | |||
21 | #define REF2USB_TX_EN BIT(0) | ||
22 | #define REF2USB_TX_LPF_EN BIT(1) | ||
23 | #define REF2USB_TX_OUT_EN BIT(2) | ||
24 | #define REF2USB_EN_MASK (REF2USB_TX_EN | REF2USB_TX_LPF_EN | \ | ||
25 | REF2USB_TX_OUT_EN) | ||
26 | |||
27 | struct mtk_ref2usb_tx { | ||
28 | struct clk_hw hw; | ||
29 | void __iomem *base_addr; | ||
30 | }; | ||
31 | |||
32 | static inline struct mtk_ref2usb_tx *to_mtk_ref2usb_tx(struct clk_hw *hw) | ||
33 | { | ||
34 | return container_of(hw, struct mtk_ref2usb_tx, hw); | ||
35 | } | ||
36 | |||
37 | static int mtk_ref2usb_tx_is_prepared(struct clk_hw *hw) | ||
38 | { | ||
39 | struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw); | ||
40 | |||
41 | return (readl(tx->base_addr) & REF2USB_EN_MASK) == REF2USB_EN_MASK; | ||
42 | } | ||
43 | |||
44 | static int mtk_ref2usb_tx_prepare(struct clk_hw *hw) | ||
45 | { | ||
46 | struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw); | ||
47 | u32 val; | ||
48 | |||
49 | val = readl(tx->base_addr); | ||
50 | |||
51 | val |= REF2USB_TX_EN; | ||
52 | writel(val, tx->base_addr); | ||
53 | udelay(100); | ||
54 | |||
55 | val |= REF2USB_TX_LPF_EN; | ||
56 | writel(val, tx->base_addr); | ||
57 | |||
58 | val |= REF2USB_TX_OUT_EN; | ||
59 | writel(val, tx->base_addr); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static void mtk_ref2usb_tx_unprepare(struct clk_hw *hw) | ||
65 | { | ||
66 | struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw); | ||
67 | u32 val; | ||
68 | |||
69 | val = readl(tx->base_addr); | ||
70 | val &= ~REF2USB_EN_MASK; | ||
71 | writel(val, tx->base_addr); | ||
72 | } | ||
73 | |||
74 | static const struct clk_ops mtk_ref2usb_tx_ops = { | ||
75 | .is_prepared = mtk_ref2usb_tx_is_prepared, | ||
76 | .prepare = mtk_ref2usb_tx_prepare, | ||
77 | .unprepare = mtk_ref2usb_tx_unprepare, | ||
78 | }; | ||
79 | |||
80 | struct clk * __init mtk_clk_register_ref2usb_tx(const char *name, | ||
81 | const char *parent_name, void __iomem *reg) | ||
82 | { | ||
83 | struct mtk_ref2usb_tx *tx; | ||
84 | struct clk_init_data init = {}; | ||
85 | struct clk *clk; | ||
86 | |||
87 | tx = kzalloc(sizeof(*tx), GFP_KERNEL); | ||
88 | if (!tx) | ||
89 | return ERR_PTR(-ENOMEM); | ||
90 | |||
91 | tx->base_addr = reg; | ||
92 | tx->hw.init = &init; | ||
93 | |||
94 | init.name = name; | ||
95 | init.ops = &mtk_ref2usb_tx_ops; | ||
96 | init.parent_names = &parent_name; | ||
97 | init.num_parents = 1; | ||
98 | |||
99 | clk = clk_register(NULL, &tx->hw); | ||
100 | |||
101 | if (IS_ERR(clk)) { | ||
102 | pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk)); | ||
103 | kfree(tx); | ||
104 | } | ||
105 | |||
106 | return clk; | ||
107 | } | ||
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 57020368a693..576bdb7c98b8 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c | |||
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = { | |||
97 | .disable = mtk_cg_disable_inv, | 97 | .disable = mtk_cg_disable_inv, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | struct clk *mtk_clk_register_gate( | 100 | struct clk * __init mtk_clk_register_gate( |
101 | const char *name, | 101 | const char *name, |
102 | const char *parent_name, | 102 | const char *parent_name, |
103 | struct regmap *regmap, | 103 | struct regmap *regmap, |
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c index 90eff85f4285..227e356403d9 100644 --- a/drivers/clk/mediatek/clk-mt8173.c +++ b/drivers/clk/mediatek/clk-mt8173.c | |||
@@ -15,21 +15,28 @@ | |||
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/mfd/syscon.h> | ||
20 | 18 | ||
21 | #include "clk-mtk.h" | 19 | #include "clk-mtk.h" |
22 | #include "clk-gate.h" | 20 | #include "clk-gate.h" |
23 | 21 | ||
24 | #include <dt-bindings/clock/mt8173-clk.h> | 22 | #include <dt-bindings/clock/mt8173-clk.h> |
25 | 23 | ||
24 | /* | ||
25 | * For some clocks, we don't care what their actual rates are. And these | ||
26 | * clocks may change their rate on different products or different scenarios. | ||
27 | * So we model these clocks' rate as 0, to denote it's not an actual rate. | ||
28 | */ | ||
29 | #define DUMMY_RATE 0 | ||
30 | |||
26 | static DEFINE_SPINLOCK(mt8173_clk_lock); | 31 | static DEFINE_SPINLOCK(mt8173_clk_lock); |
27 | 32 | ||
28 | static const struct mtk_fixed_factor root_clk_alias[] __initconst = { | 33 | static const struct mtk_fixed_clk fixed_clks[] __initconst = { |
29 | FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1), | 34 | FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE), |
30 | FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1), | 35 | FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ), |
31 | FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1), | 36 | FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", DUMMY_RATE), |
32 | FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1), | 37 | FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", DUMMY_RATE), |
38 | FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", DUMMY_RATE), | ||
39 | FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", DUMMY_RATE), | ||
33 | }; | 40 | }; |
34 | 41 | ||
35 | static const struct mtk_fixed_factor top_divs[] __initconst = { | 42 | static const struct mtk_fixed_factor top_divs[] __initconst = { |
@@ -54,6 +61,7 @@ static const struct mtk_fixed_factor top_divs[] __initconst = { | |||
54 | FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793), | 61 | FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793), |
55 | FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1), | 62 | FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1), |
56 | 63 | ||
64 | FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "tvdpll_445p5m", 1, 3), | ||
57 | FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2), | 65 | FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2), |
58 | FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3), | 66 | FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3), |
59 | 67 | ||
@@ -590,7 +598,7 @@ static const struct mtk_composite top_muxes[] __initconst = { | |||
590 | MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1), | 598 | MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1), |
591 | }; | 599 | }; |
592 | 600 | ||
593 | static const struct mtk_gate_regs infra_cg_regs = { | 601 | static const struct mtk_gate_regs infra_cg_regs __initconst = { |
594 | .set_ofs = 0x0040, | 602 | .set_ofs = 0x0040, |
595 | .clr_ofs = 0x0044, | 603 | .clr_ofs = 0x0044, |
596 | .sta_ofs = 0x0048, | 604 | .sta_ofs = 0x0048, |
@@ -612,20 +620,24 @@ static const struct mtk_gate infra_clks[] __initconst = { | |||
612 | GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6), | 620 | GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6), |
613 | GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7), | 621 | GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7), |
614 | GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8), | 622 | GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8), |
615 | GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15), | 623 | GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15), |
616 | GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16), | 624 | GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16), |
617 | GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18), | 625 | GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18), |
618 | GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22), | 626 | GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22), |
619 | GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23), | 627 | GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23), |
620 | }; | 628 | }; |
621 | 629 | ||
622 | static const struct mtk_gate_regs peri0_cg_regs = { | 630 | static const struct mtk_fixed_factor infra_divs[] __initconst = { |
631 | FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2), | ||
632 | }; | ||
633 | |||
634 | static const struct mtk_gate_regs peri0_cg_regs __initconst = { | ||
623 | .set_ofs = 0x0008, | 635 | .set_ofs = 0x0008, |
624 | .clr_ofs = 0x0010, | 636 | .clr_ofs = 0x0010, |
625 | .sta_ofs = 0x0018, | 637 | .sta_ofs = 0x0018, |
626 | }; | 638 | }; |
627 | 639 | ||
628 | static const struct mtk_gate_regs peri1_cg_regs = { | 640 | static const struct mtk_gate_regs peri1_cg_regs __initconst = { |
629 | .set_ofs = 0x000c, | 641 | .set_ofs = 0x000c, |
630 | .clr_ofs = 0x0014, | 642 | .clr_ofs = 0x0014, |
631 | .sta_ofs = 0x001c, | 643 | .sta_ofs = 0x001c, |
@@ -701,6 +713,183 @@ static const struct mtk_composite peri_clks[] __initconst = { | |||
701 | MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), | 713 | MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), |
702 | }; | 714 | }; |
703 | 715 | ||
716 | static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = { | ||
717 | .set_ofs = 0x0004, | ||
718 | .clr_ofs = 0x0008, | ||
719 | .sta_ofs = 0x0000, | ||
720 | }; | ||
721 | |||
722 | #define GATE_IMG(_id, _name, _parent, _shift) { \ | ||
723 | .id = _id, \ | ||
724 | .name = _name, \ | ||
725 | .parent_name = _parent, \ | ||
726 | .regs = &cg_regs_4_8_0, \ | ||
727 | .shift = _shift, \ | ||
728 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
729 | } | ||
730 | |||
731 | static const struct mtk_gate img_clks[] __initconst = { | ||
732 | GATE_IMG(CLK_IMG_LARB2_SMI, "img_larb2_smi", "mm_sel", 0), | ||
733 | GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "mm_sel", 5), | ||
734 | GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "mm_sel", 6), | ||
735 | GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "camtg_sel", 7), | ||
736 | GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "mm_sel", 8), | ||
737 | GATE_IMG(CLK_IMG_CAM_SV, "img_cam_sv", "mm_sel", 9), | ||
738 | GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11), | ||
739 | }; | ||
740 | |||
741 | static const struct mtk_gate_regs mm0_cg_regs __initconst = { | ||
742 | .set_ofs = 0x0104, | ||
743 | .clr_ofs = 0x0108, | ||
744 | .sta_ofs = 0x0100, | ||
745 | }; | ||
746 | |||
747 | static const struct mtk_gate_regs mm1_cg_regs __initconst = { | ||
748 | .set_ofs = 0x0114, | ||
749 | .clr_ofs = 0x0118, | ||
750 | .sta_ofs = 0x0110, | ||
751 | }; | ||
752 | |||
753 | #define GATE_MM0(_id, _name, _parent, _shift) { \ | ||
754 | .id = _id, \ | ||
755 | .name = _name, \ | ||
756 | .parent_name = _parent, \ | ||
757 | .regs = &mm0_cg_regs, \ | ||
758 | .shift = _shift, \ | ||
759 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
760 | } | ||
761 | |||
762 | #define GATE_MM1(_id, _name, _parent, _shift) { \ | ||
763 | .id = _id, \ | ||
764 | .name = _name, \ | ||
765 | .parent_name = _parent, \ | ||
766 | .regs = &mm1_cg_regs, \ | ||
767 | .shift = _shift, \ | ||
768 | .ops = &mtk_clk_gate_ops_setclr, \ | ||
769 | } | ||
770 | |||
771 | static const struct mtk_gate mm_clks[] __initconst = { | ||
772 | /* MM0 */ | ||
773 | GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0), | ||
774 | GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1), | ||
775 | GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2), | ||
776 | GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3), | ||
777 | GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4), | ||
778 | GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5), | ||
779 | GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6), | ||
780 | GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7), | ||
781 | GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8), | ||
782 | GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9), | ||
783 | GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11), | ||
784 | GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12), | ||
785 | GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13), | ||
786 | GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14), | ||
787 | GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15), | ||
788 | GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16), | ||
789 | GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17), | ||
790 | GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18), | ||
791 | GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19), | ||
792 | GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20), | ||
793 | GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21), | ||
794 | GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22), | ||
795 | GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23), | ||
796 | GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24), | ||
797 | GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25), | ||
798 | GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26), | ||
799 | GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27), | ||
800 | GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28), | ||
801 | GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29), | ||
802 | GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30), | ||
803 | GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31), | ||
804 | /* MM1 */ | ||
805 | GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0), | ||
806 | GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1), | ||
807 | GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2), | ||
808 | GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3), | ||
809 | GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4), | ||
810 | GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5), | ||
811 | GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6), | ||
812 | GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7), | ||
813 | GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8), | ||
814 | GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9), | ||
815 | GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10), | ||
816 | GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11), | ||
817 | GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12), | ||
818 | GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13), | ||
819 | GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14), | ||
820 | GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15), | ||
821 | GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16), | ||
822 | GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17), | ||
823 | GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18), | ||
824 | GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19), | ||
825 | GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20), | ||
826 | }; | ||
827 | |||
828 | static const struct mtk_gate_regs vdec0_cg_regs __initconst = { | ||
829 | .set_ofs = 0x0000, | ||
830 | .clr_ofs = 0x0004, | ||
831 | .sta_ofs = 0x0000, | ||
832 | }; | ||
833 | |||
834 | static const struct mtk_gate_regs vdec1_cg_regs __initconst = { | ||
835 | .set_ofs = 0x0008, | ||
836 | .clr_ofs = 0x000c, | ||
837 | .sta_ofs = 0x0008, | ||
838 | }; | ||
839 | |||
840 | #define GATE_VDEC0(_id, _name, _parent, _shift) { \ | ||
841 | .id = _id, \ | ||
842 | .name = _name, \ | ||
843 | .parent_name = _parent, \ | ||
844 | .regs = &vdec0_cg_regs, \ | ||
845 | .shift = _shift, \ | ||
846 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
847 | } | ||
848 | |||
849 | #define GATE_VDEC1(_id, _name, _parent, _shift) { \ | ||
850 | .id = _id, \ | ||
851 | .name = _name, \ | ||
852 | .parent_name = _parent, \ | ||
853 | .regs = &vdec1_cg_regs, \ | ||
854 | .shift = _shift, \ | ||
855 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
856 | } | ||
857 | |||
858 | static const struct mtk_gate vdec_clks[] __initconst = { | ||
859 | GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0), | ||
860 | GATE_VDEC1(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", 0), | ||
861 | }; | ||
862 | |||
863 | #define GATE_VENC(_id, _name, _parent, _shift) { \ | ||
864 | .id = _id, \ | ||
865 | .name = _name, \ | ||
866 | .parent_name = _parent, \ | ||
867 | .regs = &cg_regs_4_8_0, \ | ||
868 | .shift = _shift, \ | ||
869 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
870 | } | ||
871 | |||
872 | static const struct mtk_gate venc_clks[] __initconst = { | ||
873 | GATE_VENC(CLK_VENC_CKE0, "venc_cke0", "mm_sel", 0), | ||
874 | GATE_VENC(CLK_VENC_CKE1, "venc_cke1", "venc_sel", 4), | ||
875 | GATE_VENC(CLK_VENC_CKE2, "venc_cke2", "venc_sel", 8), | ||
876 | GATE_VENC(CLK_VENC_CKE3, "venc_cke3", "venc_sel", 12), | ||
877 | }; | ||
878 | |||
879 | #define GATE_VENCLT(_id, _name, _parent, _shift) { \ | ||
880 | .id = _id, \ | ||
881 | .name = _name, \ | ||
882 | .parent_name = _parent, \ | ||
883 | .regs = &cg_regs_4_8_0, \ | ||
884 | .shift = _shift, \ | ||
885 | .ops = &mtk_clk_gate_ops_setclr_inv, \ | ||
886 | } | ||
887 | |||
888 | static const struct mtk_gate venclt_clks[] __initconst = { | ||
889 | GATE_VENCLT(CLK_VENCLT_CKE0, "venclt_cke0", "mm_sel", 0), | ||
890 | GATE_VENCLT(CLK_VENCLT_CKE1, "venclt_cke1", "venclt_sel", 4), | ||
891 | }; | ||
892 | |||
704 | static struct clk_onecell_data *mt8173_top_clk_data __initdata; | 893 | static struct clk_onecell_data *mt8173_top_clk_data __initdata; |
705 | static struct clk_onecell_data *mt8173_pll_clk_data __initdata; | 894 | static struct clk_onecell_data *mt8173_pll_clk_data __initdata; |
706 | 895 | ||
@@ -731,7 +920,7 @@ static void __init mtk_topckgen_init(struct device_node *node) | |||
731 | 920 | ||
732 | mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); | 921 | mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); |
733 | 922 | ||
734 | mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); | 923 | mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data); |
735 | mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); | 924 | mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); |
736 | mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, | 925 | mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, |
737 | &mt8173_clk_lock, clk_data); | 926 | &mt8173_clk_lock, clk_data); |
@@ -754,6 +943,7 @@ static void __init mtk_infrasys_init(struct device_node *node) | |||
754 | 943 | ||
755 | mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), | 944 | mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), |
756 | clk_data); | 945 | clk_data); |
946 | mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data); | ||
757 | 947 | ||
758 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | 948 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); |
759 | if (r) | 949 | if (r) |
@@ -792,6 +982,24 @@ static void __init mtk_pericfg_init(struct device_node *node) | |||
792 | } | 982 | } |
793 | CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init); | 983 | CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init); |
794 | 984 | ||
985 | struct mtk_clk_usb { | ||
986 | int id; | ||
987 | const char *name; | ||
988 | const char *parent; | ||
989 | u32 reg_ofs; | ||
990 | }; | ||
991 | |||
992 | #define APMIXED_USB(_id, _name, _parent, _reg_ofs) { \ | ||
993 | .id = _id, \ | ||
994 | .name = _name, \ | ||
995 | .parent = _parent, \ | ||
996 | .reg_ofs = _reg_ofs, \ | ||
997 | } | ||
998 | |||
999 | static const struct mtk_clk_usb apmixed_usb[] __initconst = { | ||
1000 | APMIXED_USB(CLK_APMIXED_REF2USB_TX, "ref2usb_tx", "clk26m", 0x8), | ||
1001 | }; | ||
1002 | |||
795 | #define MT8173_PLL_FMAX (3000UL * MHZ) | 1003 | #define MT8173_PLL_FMAX (3000UL * MHZ) |
796 | 1004 | ||
797 | #define CON0_MT8173_RST_BAR BIT(24) | 1005 | #define CON0_MT8173_RST_BAR BIT(24) |
@@ -852,6 +1060,15 @@ static const struct mtk_pll_data plls[] = { | |||
852 | static void __init mtk_apmixedsys_init(struct device_node *node) | 1060 | static void __init mtk_apmixedsys_init(struct device_node *node) |
853 | { | 1061 | { |
854 | struct clk_onecell_data *clk_data; | 1062 | struct clk_onecell_data *clk_data; |
1063 | void __iomem *base; | ||
1064 | struct clk *clk; | ||
1065 | int r, i; | ||
1066 | |||
1067 | base = of_iomap(node, 0); | ||
1068 | if (!base) { | ||
1069 | pr_err("%s(): ioremap failed\n", __func__); | ||
1070 | return; | ||
1071 | } | ||
855 | 1072 | ||
856 | mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); | 1073 | mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); |
857 | if (!clk_data) | 1074 | if (!clk_data) |
@@ -859,7 +1076,113 @@ static void __init mtk_apmixedsys_init(struct device_node *node) | |||
859 | 1076 | ||
860 | mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); | 1077 | mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); |
861 | 1078 | ||
1079 | for (i = 0; i < ARRAY_SIZE(apmixed_usb); i++) { | ||
1080 | const struct mtk_clk_usb *cku = &apmixed_usb[i]; | ||
1081 | |||
1082 | clk = mtk_clk_register_ref2usb_tx(cku->name, cku->parent, | ||
1083 | base + cku->reg_ofs); | ||
1084 | |||
1085 | if (IS_ERR(clk)) { | ||
1086 | pr_err("Failed to register clk %s: %ld\n", cku->name, | ||
1087 | PTR_ERR(clk)); | ||
1088 | continue; | ||
1089 | } | ||
1090 | |||
1091 | clk_data->clks[cku->id] = clk; | ||
1092 | } | ||
1093 | |||
1094 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1095 | if (r) | ||
1096 | pr_err("%s(): could not register clock provider: %d\n", | ||
1097 | __func__, r); | ||
1098 | |||
862 | mtk_clk_enable_critical(); | 1099 | mtk_clk_enable_critical(); |
863 | } | 1100 | } |
864 | CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys", | 1101 | CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys", |
865 | mtk_apmixedsys_init); | 1102 | mtk_apmixedsys_init); |
1103 | |||
1104 | static void __init mtk_imgsys_init(struct device_node *node) | ||
1105 | { | ||
1106 | struct clk_onecell_data *clk_data; | ||
1107 | int r; | ||
1108 | |||
1109 | clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK); | ||
1110 | |||
1111 | mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), | ||
1112 | clk_data); | ||
1113 | |||
1114 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1115 | |||
1116 | if (r) | ||
1117 | pr_err("%s(): could not register clock provider: %d\n", | ||
1118 | __func__, r); | ||
1119 | } | ||
1120 | CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init); | ||
1121 | |||
1122 | static void __init mtk_mmsys_init(struct device_node *node) | ||
1123 | { | ||
1124 | struct clk_onecell_data *clk_data; | ||
1125 | int r; | ||
1126 | |||
1127 | clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK); | ||
1128 | |||
1129 | mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), | ||
1130 | clk_data); | ||
1131 | |||
1132 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1133 | if (r) | ||
1134 | pr_err("%s(): could not register clock provider: %d\n", | ||
1135 | __func__, r); | ||
1136 | } | ||
1137 | CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init); | ||
1138 | |||
1139 | static void __init mtk_vdecsys_init(struct device_node *node) | ||
1140 | { | ||
1141 | struct clk_onecell_data *clk_data; | ||
1142 | int r; | ||
1143 | |||
1144 | clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK); | ||
1145 | |||
1146 | mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), | ||
1147 | clk_data); | ||
1148 | |||
1149 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1150 | if (r) | ||
1151 | pr_err("%s(): could not register clock provider: %d\n", | ||
1152 | __func__, r); | ||
1153 | } | ||
1154 | CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init); | ||
1155 | |||
1156 | static void __init mtk_vencsys_init(struct device_node *node) | ||
1157 | { | ||
1158 | struct clk_onecell_data *clk_data; | ||
1159 | int r; | ||
1160 | |||
1161 | clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK); | ||
1162 | |||
1163 | mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks), | ||
1164 | clk_data); | ||
1165 | |||
1166 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1167 | if (r) | ||
1168 | pr_err("%s(): could not register clock provider: %d\n", | ||
1169 | __func__, r); | ||
1170 | } | ||
1171 | CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init); | ||
1172 | |||
1173 | static void __init mtk_vencltsys_init(struct device_node *node) | ||
1174 | { | ||
1175 | struct clk_onecell_data *clk_data; | ||
1176 | int r; | ||
1177 | |||
1178 | clk_data = mtk_alloc_clk_data(CLK_VENCLT_NR_CLK); | ||
1179 | |||
1180 | mtk_clk_register_gates(node, venclt_clks, ARRAY_SIZE(venclt_clks), | ||
1181 | clk_data); | ||
1182 | |||
1183 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
1184 | if (r) | ||
1185 | pr_err("%s(): could not register clock provider: %d\n", | ||
1186 | __func__, r); | ||
1187 | } | ||
1188 | CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init); | ||
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 18444aea63c9..cf08db6c130c 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "clk-mtk.h" | 24 | #include "clk-mtk.h" |
25 | #include "clk-gate.h" | 25 | #include "clk-gate.h" |
26 | 26 | ||
27 | struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num) | 27 | struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num) |
28 | { | 28 | { |
29 | int i; | 29 | int i; |
30 | struct clk_onecell_data *clk_data; | 30 | struct clk_onecell_data *clk_data; |
@@ -49,8 +49,31 @@ err_out: | |||
49 | return NULL; | 49 | return NULL; |
50 | } | 50 | } |
51 | 51 | ||
52 | void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num, | 52 | void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, |
53 | struct clk_onecell_data *clk_data) | 53 | int num, struct clk_onecell_data *clk_data) |
54 | { | ||
55 | int i; | ||
56 | struct clk *clk; | ||
57 | |||
58 | for (i = 0; i < num; i++) { | ||
59 | const struct mtk_fixed_clk *rc = &clks[i]; | ||
60 | |||
61 | clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, | ||
62 | rc->parent ? 0 : CLK_IS_ROOT, rc->rate); | ||
63 | |||
64 | if (IS_ERR(clk)) { | ||
65 | pr_err("Failed to register clk %s: %ld\n", | ||
66 | rc->name, PTR_ERR(clk)); | ||
67 | continue; | ||
68 | } | ||
69 | |||
70 | if (clk_data) | ||
71 | clk_data->clks[rc->id] = clk; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks, | ||
76 | int num, struct clk_onecell_data *clk_data) | ||
54 | { | 77 | { |
55 | int i; | 78 | int i; |
56 | struct clk *clk; | 79 | struct clk *clk; |
@@ -72,7 +95,8 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num, | |||
72 | } | 95 | } |
73 | } | 96 | } |
74 | 97 | ||
75 | int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, | 98 | int __init mtk_clk_register_gates(struct device_node *node, |
99 | const struct mtk_gate *clks, | ||
76 | int num, struct clk_onecell_data *clk_data) | 100 | int num, struct clk_onecell_data *clk_data) |
77 | { | 101 | { |
78 | int i; | 102 | int i; |
@@ -111,7 +135,7 @@ int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks | |||
111 | return 0; | 135 | return 0; |
112 | } | 136 | } |
113 | 137 | ||
114 | struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, | 138 | struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc, |
115 | void __iomem *base, spinlock_t *lock) | 139 | void __iomem *base, spinlock_t *lock) |
116 | { | 140 | { |
117 | struct clk *clk; | 141 | struct clk *clk; |
@@ -196,7 +220,7 @@ err_out: | |||
196 | return ERR_PTR(ret); | 220 | return ERR_PTR(ret); |
197 | } | 221 | } |
198 | 222 | ||
199 | void mtk_clk_register_composites(const struct mtk_composite *mcs, | 223 | void __init mtk_clk_register_composites(const struct mtk_composite *mcs, |
200 | int num, void __iomem *base, spinlock_t *lock, | 224 | int num, void __iomem *base, spinlock_t *lock, |
201 | struct clk_onecell_data *clk_data) | 225 | struct clk_onecell_data *clk_data) |
202 | { | 226 | { |
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index c5cbecb3d218..32d2e455eb3f 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h | |||
@@ -26,6 +26,23 @@ struct clk; | |||
26 | 26 | ||
27 | #define MHZ (1000 * 1000) | 27 | #define MHZ (1000 * 1000) |
28 | 28 | ||
29 | struct mtk_fixed_clk { | ||
30 | int id; | ||
31 | const char *name; | ||
32 | const char *parent; | ||
33 | unsigned long rate; | ||
34 | }; | ||
35 | |||
36 | #define FIXED_CLK(_id, _name, _parent, _rate) { \ | ||
37 | .id = _id, \ | ||
38 | .name = _name, \ | ||
39 | .parent = _parent, \ | ||
40 | .rate = _rate, \ | ||
41 | } | ||
42 | |||
43 | void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, | ||
44 | int num, struct clk_onecell_data *clk_data); | ||
45 | |||
29 | struct mtk_fixed_factor { | 46 | struct mtk_fixed_factor { |
30 | int id; | 47 | int id; |
31 | const char *name; | 48 | const char *name; |
@@ -42,7 +59,7 @@ struct mtk_fixed_factor { | |||
42 | .div = _div, \ | 59 | .div = _div, \ |
43 | } | 60 | } |
44 | 61 | ||
45 | extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, | 62 | void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, |
46 | int num, struct clk_onecell_data *clk_data); | 63 | int num, struct clk_onecell_data *clk_data); |
47 | 64 | ||
48 | struct mtk_composite { | 65 | struct mtk_composite { |
@@ -159,10 +176,13 @@ struct mtk_pll_data { | |||
159 | const struct mtk_pll_div_table *div_table; | 176 | const struct mtk_pll_div_table *div_table; |
160 | }; | 177 | }; |
161 | 178 | ||
162 | void __init mtk_clk_register_plls(struct device_node *node, | 179 | void mtk_clk_register_plls(struct device_node *node, |
163 | const struct mtk_pll_data *plls, int num_plls, | 180 | const struct mtk_pll_data *plls, int num_plls, |
164 | struct clk_onecell_data *clk_data); | 181 | struct clk_onecell_data *clk_data); |
165 | 182 | ||
183 | struct clk *mtk_clk_register_ref2usb_tx(const char *name, | ||
184 | const char *parent_name, void __iomem *reg); | ||
185 | |||
166 | #ifdef CONFIG_RESET_CONTROLLER | 186 | #ifdef CONFIG_RESET_CONTROLLER |
167 | void mtk_register_reset_controller(struct device_node *np, | 187 | void mtk_register_reset_controller(struct device_node *np, |
168 | unsigned int num_regs, int regofs); | 188 | unsigned int num_regs, int regofs); |
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index 622e7b6c62b4..966cab1348da 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c | |||
@@ -317,7 +317,7 @@ void __init mtk_clk_register_plls(struct device_node *node, | |||
317 | const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data) | 317 | const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data) |
318 | { | 318 | { |
319 | void __iomem *base; | 319 | void __iomem *base; |
320 | int r, i; | 320 | int i; |
321 | struct clk *clk; | 321 | struct clk *clk; |
322 | 322 | ||
323 | base = of_iomap(node, 0); | 323 | base = of_iomap(node, 0); |
@@ -339,9 +339,4 @@ void __init mtk_clk_register_plls(struct device_node *node, | |||
339 | 339 | ||
340 | clk_data->clks[pll->id] = clk; | 340 | clk_data->clks[pll->id] = clk; |
341 | } | 341 | } |
342 | |||
343 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
344 | if (r) | ||
345 | pr_err("%s(): could not register clock provider: %d\n", | ||
346 | __func__, r); | ||
347 | } | 342 | } |
diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 85da8b983256..5837eb8a212f 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c | |||
@@ -197,7 +197,6 @@ static void __init of_cpu_clk_setup(struct device_node *node) | |||
197 | for_each_node_by_type(dn, "cpu") { | 197 | for_each_node_by_type(dn, "cpu") { |
198 | struct clk_init_data init; | 198 | struct clk_init_data init; |
199 | struct clk *clk; | 199 | struct clk *clk; |
200 | struct clk *parent_clk; | ||
201 | char *clk_name = kzalloc(5, GFP_KERNEL); | 200 | char *clk_name = kzalloc(5, GFP_KERNEL); |
202 | int cpu, err; | 201 | int cpu, err; |
203 | 202 | ||
@@ -209,9 +208,8 @@ static void __init of_cpu_clk_setup(struct device_node *node) | |||
209 | goto bail_out; | 208 | goto bail_out; |
210 | 209 | ||
211 | sprintf(clk_name, "cpu%d", cpu); | 210 | sprintf(clk_name, "cpu%d", cpu); |
212 | parent_clk = of_clk_get(node, 0); | ||
213 | 211 | ||
214 | cpuclk[cpu].parent_name = __clk_get_name(parent_clk); | 212 | cpuclk[cpu].parent_name = of_clk_get_parent_name(node, 0); |
215 | cpuclk[cpu].clk_name = clk_name; | 213 | cpuclk[cpu].clk_name = clk_name; |
216 | cpuclk[cpu].cpu = cpu; | 214 | cpuclk[cpu].cpu = cpu; |
217 | cpuclk[cpu].reg_base = clock_complex_base; | 215 | cpuclk[cpu].reg_base = clock_complex_base; |
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 4a22429cd7a2..28aac67e7b92 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c | |||
@@ -165,7 +165,7 @@ void __init mvebu_coreclk_setup(struct device_node *np, | |||
165 | clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name, | 165 | clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name, |
166 | cpuclk_name, 0, mult, div); | 166 | cpuclk_name, 0, mult, div); |
167 | WARN_ON(IS_ERR(clk_data.clks[2+n])); | 167 | WARN_ON(IS_ERR(clk_data.clks[2+n])); |
168 | }; | 168 | } |
169 | 169 | ||
170 | /* Register optional refclk */ | 170 | /* Register optional refclk */ |
171 | if (desc->get_refclk_freq) { | 171 | if (desc->get_refclk_freq) { |
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c index 73f0240569ac..f8dd10f6df3d 100644 --- a/drivers/clk/mxs/clk-frac.c +++ b/drivers/clk/mxs/clk-frac.c | |||
@@ -41,11 +41,13 @@ static unsigned long clk_frac_recalc_rate(struct clk_hw *hw, | |||
41 | { | 41 | { |
42 | struct clk_frac *frac = to_clk_frac(hw); | 42 | struct clk_frac *frac = to_clk_frac(hw); |
43 | u32 div; | 43 | u32 div; |
44 | u64 tmp_rate; | ||
44 | 45 | ||
45 | div = readl_relaxed(frac->reg) >> frac->shift; | 46 | div = readl_relaxed(frac->reg) >> frac->shift; |
46 | div &= (1 << frac->width) - 1; | 47 | div &= (1 << frac->width) - 1; |
47 | 48 | ||
48 | return (parent_rate >> frac->width) * div; | 49 | tmp_rate = (u64)parent_rate * div; |
50 | return tmp_rate >> frac->width; | ||
49 | } | 51 | } |
50 | 52 | ||
51 | static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, | 53 | static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, |
@@ -54,7 +56,7 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, | |||
54 | struct clk_frac *frac = to_clk_frac(hw); | 56 | struct clk_frac *frac = to_clk_frac(hw); |
55 | unsigned long parent_rate = *prate; | 57 | unsigned long parent_rate = *prate; |
56 | u32 div; | 58 | u32 div; |
57 | u64 tmp; | 59 | u64 tmp, tmp_rate, result; |
58 | 60 | ||
59 | if (rate > parent_rate) | 61 | if (rate > parent_rate) |
60 | return -EINVAL; | 62 | return -EINVAL; |
@@ -67,7 +69,11 @@ static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate, | |||
67 | if (!div) | 69 | if (!div) |
68 | return -EINVAL; | 70 | return -EINVAL; |
69 | 71 | ||
70 | return (parent_rate >> frac->width) * div; | 72 | tmp_rate = (u64)parent_rate * div; |
73 | result = tmp_rate >> frac->width; | ||
74 | if ((result << frac->width) < tmp_rate) | ||
75 | result += 1; | ||
76 | return result; | ||
71 | } | 77 | } |
72 | 78 | ||
73 | static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, | 79 | static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate, |
diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index eeaee97da110..13aabbb3acbe 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c | |||
@@ -179,9 +179,22 @@ static void lpc18xx_ccu_gate_disable(struct clk_hw *hw) | |||
179 | 179 | ||
180 | static int lpc18xx_ccu_gate_is_enabled(struct clk_hw *hw) | 180 | static int lpc18xx_ccu_gate_is_enabled(struct clk_hw *hw) |
181 | { | 181 | { |
182 | struct clk_gate *gate = to_clk_gate(hw); | 182 | const struct clk_hw *parent; |
183 | |||
184 | /* | ||
185 | * The branch clock registers are only accessible | ||
186 | * if the base (parent) clock is enabled. Register | ||
187 | * access with a disabled base clock will hang the | ||
188 | * system. | ||
189 | */ | ||
190 | parent = clk_hw_get_parent(hw); | ||
191 | if (!parent) | ||
192 | return 0; | ||
193 | |||
194 | if (!clk_hw_is_enabled(parent)) | ||
195 | return 0; | ||
183 | 196 | ||
184 | return clk_readl(gate->reg) & LPC18XX_CCU_RUN; | 197 | return clk_gate_ops.is_enabled(hw); |
185 | } | 198 | } |
186 | 199 | ||
187 | static const struct clk_ops lpc18xx_ccu_gate_ops = { | 200 | static const struct clk_ops lpc18xx_ccu_gate_ops = { |
diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index e0a3cb8970ab..c924572fc9bc 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c | |||
@@ -480,6 +480,42 @@ static const struct clk_ops lpc18xx_pll1_ops = { | |||
480 | .recalc_rate = lpc18xx_pll1_recalc_rate, | 480 | .recalc_rate = lpc18xx_pll1_recalc_rate, |
481 | }; | 481 | }; |
482 | 482 | ||
483 | static int lpc18xx_cgu_gate_enable(struct clk_hw *hw) | ||
484 | { | ||
485 | return clk_gate_ops.enable(hw); | ||
486 | } | ||
487 | |||
488 | static void lpc18xx_cgu_gate_disable(struct clk_hw *hw) | ||
489 | { | ||
490 | clk_gate_ops.disable(hw); | ||
491 | } | ||
492 | |||
493 | static int lpc18xx_cgu_gate_is_enabled(struct clk_hw *hw) | ||
494 | { | ||
495 | const struct clk_hw *parent; | ||
496 | |||
497 | /* | ||
498 | * The consumer of base clocks needs know if the | ||
499 | * base clock is really enabled before it can be | ||
500 | * accessed. It is therefore necessary to verify | ||
501 | * this all the way up. | ||
502 | */ | ||
503 | parent = clk_hw_get_parent(hw); | ||
504 | if (!parent) | ||
505 | return 0; | ||
506 | |||
507 | if (!clk_hw_is_enabled(parent)) | ||
508 | return 0; | ||
509 | |||
510 | return clk_gate_ops.is_enabled(hw); | ||
511 | } | ||
512 | |||
513 | static const struct clk_ops lpc18xx_gate_ops = { | ||
514 | .enable = lpc18xx_cgu_gate_enable, | ||
515 | .disable = lpc18xx_cgu_gate_disable, | ||
516 | .is_enabled = lpc18xx_cgu_gate_is_enabled, | ||
517 | }; | ||
518 | |||
483 | static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = { | 519 | static struct lpc18xx_cgu_pll_clk lpc18xx_cgu_src_clk_plls[] = { |
484 | LPC1XX_CGU_CLK_PLL(PLL0USB, pll0_src_ids, pll0_ops), | 520 | LPC1XX_CGU_CLK_PLL(PLL0USB, pll0_src_ids, pll0_ops), |
485 | LPC1XX_CGU_CLK_PLL(PLL0AUDIO, pll0_src_ids, pll0_ops), | 521 | LPC1XX_CGU_CLK_PLL(PLL0AUDIO, pll0_src_ids, pll0_ops), |
@@ -510,7 +546,7 @@ static struct clk *lpc18xx_cgu_register_div(struct lpc18xx_cgu_src_clk_div *clk, | |||
510 | return clk_register_composite(NULL, name, parents, clk->n_parents, | 546 | return clk_register_composite(NULL, name, parents, clk->n_parents, |
511 | &clk->mux.hw, &clk_mux_ops, | 547 | &clk->mux.hw, &clk_mux_ops, |
512 | &clk->div.hw, &clk_divider_ops, | 548 | &clk->div.hw, &clk_divider_ops, |
513 | &clk->gate.hw, &clk_gate_ops, 0); | 549 | &clk->gate.hw, &lpc18xx_gate_ops, 0); |
514 | } | 550 | } |
515 | 551 | ||
516 | 552 | ||
@@ -538,7 +574,7 @@ static struct clk *lpc18xx_register_base_clk(struct lpc18xx_cgu_base_clk *clk, | |||
538 | return clk_register_composite(NULL, name, parents, clk->n_parents, | 574 | return clk_register_composite(NULL, name, parents, clk->n_parents, |
539 | &clk->mux.hw, &clk_mux_ops, | 575 | &clk->mux.hw, &clk_mux_ops, |
540 | NULL, NULL, | 576 | NULL, NULL, |
541 | &clk->gate.hw, &clk_gate_ops, 0); | 577 | &clk->gate.hw, &lpc18xx_gate_ops, 0); |
542 | } | 578 | } |
543 | 579 | ||
544 | 580 | ||
@@ -557,7 +593,7 @@ static struct clk *lpc18xx_cgu_register_pll(struct lpc18xx_cgu_pll_clk *clk, | |||
557 | return clk_register_composite(NULL, name, parents, clk->n_parents, | 593 | return clk_register_composite(NULL, name, parents, clk->n_parents, |
558 | &clk->mux.hw, &clk_mux_ops, | 594 | &clk->mux.hw, &clk_mux_ops, |
559 | &clk->pll.hw, clk->pll_ops, | 595 | &clk->pll.hw, clk->pll_ops, |
560 | &clk->gate.hw, &clk_gate_ops, 0); | 596 | &clk->gate.hw, &lpc18xx_gate_ops, 0); |
561 | } | 597 | } |
562 | 598 | ||
563 | static void __init lpc18xx_cgu_register_source_clks(struct device_node *np, | 599 | static void __init lpc18xx_cgu_register_source_clks(struct device_node *np, |
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 59d16668bdf5..ee4c83aab4f4 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig | |||
@@ -1,3 +1,7 @@ | |||
1 | config QCOM_GDSC | ||
2 | bool | ||
3 | select PM_GENERIC_DOMAINS if PM | ||
4 | |||
1 | config COMMON_CLK_QCOM | 5 | config COMMON_CLK_QCOM |
2 | tristate "Support for Qualcomm's clock controllers" | 6 | tristate "Support for Qualcomm's clock controllers" |
3 | depends on OF | 7 | depends on OF |
@@ -7,6 +11,7 @@ config COMMON_CLK_QCOM | |||
7 | 11 | ||
8 | config APQ_GCC_8084 | 12 | config APQ_GCC_8084 |
9 | tristate "APQ8084 Global Clock Controller" | 13 | tristate "APQ8084 Global Clock Controller" |
14 | select QCOM_GDSC | ||
10 | depends on COMMON_CLK_QCOM | 15 | depends on COMMON_CLK_QCOM |
11 | help | 16 | help |
12 | Support for the global clock controller on apq8084 devices. | 17 | Support for the global clock controller on apq8084 devices. |
@@ -16,6 +21,7 @@ config APQ_GCC_8084 | |||
16 | config APQ_MMCC_8084 | 21 | config APQ_MMCC_8084 |
17 | tristate "APQ8084 Multimedia Clock Controller" | 22 | tristate "APQ8084 Multimedia Clock Controller" |
18 | select APQ_GCC_8084 | 23 | select APQ_GCC_8084 |
24 | select QCOM_GDSC | ||
19 | depends on COMMON_CLK_QCOM | 25 | depends on COMMON_CLK_QCOM |
20 | help | 26 | help |
21 | Support for the multimedia clock controller on apq8084 devices. | 27 | Support for the multimedia clock controller on apq8084 devices. |
@@ -49,6 +55,7 @@ config MSM_GCC_8660 | |||
49 | 55 | ||
50 | config MSM_GCC_8916 | 56 | config MSM_GCC_8916 |
51 | tristate "MSM8916 Global Clock Controller" | 57 | tristate "MSM8916 Global Clock Controller" |
58 | select QCOM_GDSC | ||
52 | depends on COMMON_CLK_QCOM | 59 | depends on COMMON_CLK_QCOM |
53 | help | 60 | help |
54 | Support for the global clock controller on msm8916 devices. | 61 | Support for the global clock controller on msm8916 devices. |
@@ -83,6 +90,7 @@ config MSM_MMCC_8960 | |||
83 | 90 | ||
84 | config MSM_GCC_8974 | 91 | config MSM_GCC_8974 |
85 | tristate "MSM8974 Global Clock Controller" | 92 | tristate "MSM8974 Global Clock Controller" |
93 | select QCOM_GDSC | ||
86 | depends on COMMON_CLK_QCOM | 94 | depends on COMMON_CLK_QCOM |
87 | help | 95 | help |
88 | Support for the global clock controller on msm8974 devices. | 96 | Support for the global clock controller on msm8974 devices. |
@@ -92,6 +100,7 @@ config MSM_GCC_8974 | |||
92 | config MSM_MMCC_8974 | 100 | config MSM_MMCC_8974 |
93 | tristate "MSM8974 Multimedia Clock Controller" | 101 | tristate "MSM8974 Multimedia Clock Controller" |
94 | select MSM_GCC_8974 | 102 | select MSM_GCC_8974 |
103 | select QCOM_GDSC | ||
95 | depends on COMMON_CLK_QCOM | 104 | depends on COMMON_CLK_QCOM |
96 | help | 105 | help |
97 | Support for the multimedia clock controller on msm8974 devices. | 106 | Support for the multimedia clock controller on msm8974 devices. |
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 50b337a24a87..fe6252349e55 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile | |||
@@ -9,6 +9,7 @@ clk-qcom-y += clk-branch.o | |||
9 | clk-qcom-y += clk-regmap-divider.o | 9 | clk-qcom-y += clk-regmap-divider.o |
10 | clk-qcom-y += clk-regmap-mux.o | 10 | clk-qcom-y += clk-regmap-mux.o |
11 | clk-qcom-y += reset.o | 11 | clk-qcom-y += reset.o |
12 | clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o | 14 | obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o |
14 | obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o | 15 | obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o |
diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index bccedc4b5756..bfbb28f450c2 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c | |||
@@ -542,6 +542,200 @@ static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate, | |||
542 | return __clk_rcg_set_rate(rcg, rcg->freq_tbl); | 542 | return __clk_rcg_set_rate(rcg, rcg->freq_tbl); |
543 | } | 543 | } |
544 | 544 | ||
545 | static int clk_rcg_bypass2_determine_rate(struct clk_hw *hw, | ||
546 | struct clk_rate_request *req) | ||
547 | { | ||
548 | struct clk_hw *p; | ||
549 | |||
550 | p = req->best_parent_hw; | ||
551 | req->best_parent_rate = clk_hw_round_rate(p, req->rate); | ||
552 | req->rate = req->best_parent_rate; | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static int clk_rcg_bypass2_set_rate(struct clk_hw *hw, unsigned long rate, | ||
558 | unsigned long parent_rate) | ||
559 | { | ||
560 | struct clk_rcg *rcg = to_clk_rcg(hw); | ||
561 | struct freq_tbl f = { 0 }; | ||
562 | u32 ns, src; | ||
563 | int i, ret, num_parents = clk_hw_get_num_parents(hw); | ||
564 | |||
565 | ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); | ||
566 | if (ret) | ||
567 | return ret; | ||
568 | |||
569 | src = ns_to_src(&rcg->s, ns); | ||
570 | f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1; | ||
571 | |||
572 | for (i = 0; i < num_parents; i++) { | ||
573 | if (src == rcg->s.parent_map[i].cfg) { | ||
574 | f.src = rcg->s.parent_map[i].src; | ||
575 | return __clk_rcg_set_rate(rcg, &f); | ||
576 | } | ||
577 | } | ||
578 | |||
579 | return -EINVAL; | ||
580 | } | ||
581 | |||
582 | static int clk_rcg_bypass2_set_rate_and_parent(struct clk_hw *hw, | ||
583 | unsigned long rate, unsigned long parent_rate, u8 index) | ||
584 | { | ||
585 | /* Read the hardware to determine parent during set_rate */ | ||
586 | return clk_rcg_bypass2_set_rate(hw, rate, parent_rate); | ||
587 | } | ||
588 | |||
589 | struct frac_entry { | ||
590 | int num; | ||
591 | int den; | ||
592 | }; | ||
593 | |||
594 | static const struct frac_entry pixel_table[] = { | ||
595 | { 1, 2 }, | ||
596 | { 1, 3 }, | ||
597 | { 3, 16 }, | ||
598 | { } | ||
599 | }; | ||
600 | |||
601 | static int clk_rcg_pixel_determine_rate(struct clk_hw *hw, | ||
602 | struct clk_rate_request *req) | ||
603 | { | ||
604 | int delta = 100000; | ||
605 | const struct frac_entry *frac = pixel_table; | ||
606 | unsigned long request, src_rate; | ||
607 | |||
608 | for (; frac->num; frac++) { | ||
609 | request = (req->rate * frac->den) / frac->num; | ||
610 | |||
611 | src_rate = clk_hw_round_rate(req->best_parent_hw, request); | ||
612 | |||
613 | if ((src_rate < (request - delta)) || | ||
614 | (src_rate > (request + delta))) | ||
615 | continue; | ||
616 | |||
617 | req->best_parent_rate = src_rate; | ||
618 | req->rate = (src_rate * frac->num) / frac->den; | ||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | return -EINVAL; | ||
623 | } | ||
624 | |||
625 | static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, | ||
626 | unsigned long parent_rate) | ||
627 | { | ||
628 | struct clk_rcg *rcg = to_clk_rcg(hw); | ||
629 | int delta = 100000; | ||
630 | const struct frac_entry *frac = pixel_table; | ||
631 | unsigned long request; | ||
632 | struct freq_tbl f = { 0 }; | ||
633 | u32 ns, src; | ||
634 | int i, ret, num_parents = clk_hw_get_num_parents(hw); | ||
635 | |||
636 | ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); | ||
637 | if (ret) | ||
638 | return ret; | ||
639 | |||
640 | src = ns_to_src(&rcg->s, ns); | ||
641 | f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1; | ||
642 | |||
643 | for (i = 0; i < num_parents; i++) { | ||
644 | if (src == rcg->s.parent_map[i].cfg) { | ||
645 | f.src = rcg->s.parent_map[i].src; | ||
646 | break; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | /* let us find appropriate m/n values for this */ | ||
651 | for (; frac->num; frac++) { | ||
652 | request = (rate * frac->den) / frac->num; | ||
653 | |||
654 | if ((parent_rate < (request - delta)) || | ||
655 | (parent_rate > (request + delta))) | ||
656 | continue; | ||
657 | |||
658 | f.m = frac->num; | ||
659 | f.n = frac->den; | ||
660 | |||
661 | return __clk_rcg_set_rate(rcg, &f); | ||
662 | } | ||
663 | |||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
667 | static int clk_rcg_pixel_set_rate_and_parent(struct clk_hw *hw, | ||
668 | unsigned long rate, unsigned long parent_rate, u8 index) | ||
669 | { | ||
670 | return clk_rcg_pixel_set_rate(hw, rate, parent_rate); | ||
671 | } | ||
672 | |||
673 | static int clk_rcg_esc_determine_rate(struct clk_hw *hw, | ||
674 | struct clk_rate_request *req) | ||
675 | { | ||
676 | struct clk_rcg *rcg = to_clk_rcg(hw); | ||
677 | int pre_div_max = BIT(rcg->p.pre_div_width); | ||
678 | int div; | ||
679 | unsigned long src_rate; | ||
680 | |||
681 | if (req->rate == 0) | ||
682 | return -EINVAL; | ||
683 | |||
684 | src_rate = clk_hw_get_rate(req->best_parent_hw); | ||
685 | |||
686 | div = src_rate / req->rate; | ||
687 | |||
688 | if (div >= 1 && div <= pre_div_max) { | ||
689 | req->best_parent_rate = src_rate; | ||
690 | req->rate = src_rate / div; | ||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | return -EINVAL; | ||
695 | } | ||
696 | |||
697 | static int clk_rcg_esc_set_rate(struct clk_hw *hw, unsigned long rate, | ||
698 | unsigned long parent_rate) | ||
699 | { | ||
700 | struct clk_rcg *rcg = to_clk_rcg(hw); | ||
701 | struct freq_tbl f = { 0 }; | ||
702 | int pre_div_max = BIT(rcg->p.pre_div_width); | ||
703 | int div; | ||
704 | u32 ns; | ||
705 | int i, ret, num_parents = clk_hw_get_num_parents(hw); | ||
706 | |||
707 | if (rate == 0) | ||
708 | return -EINVAL; | ||
709 | |||
710 | ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns); | ||
711 | if (ret) | ||
712 | return ret; | ||
713 | |||
714 | ns = ns_to_src(&rcg->s, ns); | ||
715 | |||
716 | for (i = 0; i < num_parents; i++) { | ||
717 | if (ns == rcg->s.parent_map[i].cfg) { | ||
718 | f.src = rcg->s.parent_map[i].src; | ||
719 | break; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | div = parent_rate / rate; | ||
724 | |||
725 | if (div >= 1 && div <= pre_div_max) { | ||
726 | f.pre_div = div; | ||
727 | return __clk_rcg_set_rate(rcg, &f); | ||
728 | } | ||
729 | |||
730 | return -EINVAL; | ||
731 | } | ||
732 | |||
733 | static int clk_rcg_esc_set_rate_and_parent(struct clk_hw *hw, | ||
734 | unsigned long rate, unsigned long parent_rate, u8 index) | ||
735 | { | ||
736 | return clk_rcg_esc_set_rate(hw, rate, parent_rate); | ||
737 | } | ||
738 | |||
545 | /* | 739 | /* |
546 | * This type of clock has a glitch-free mux that switches between the output of | 740 | * This type of clock has a glitch-free mux that switches between the output of |
547 | * the M/N counter and an always on clock source (XO). When clk_set_rate() is | 741 | * the M/N counter and an always on clock source (XO). When clk_set_rate() is |
@@ -639,6 +833,42 @@ const struct clk_ops clk_rcg_bypass_ops = { | |||
639 | }; | 833 | }; |
640 | EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops); | 834 | EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops); |
641 | 835 | ||
836 | const struct clk_ops clk_rcg_bypass2_ops = { | ||
837 | .enable = clk_enable_regmap, | ||
838 | .disable = clk_disable_regmap, | ||
839 | .get_parent = clk_rcg_get_parent, | ||
840 | .set_parent = clk_rcg_set_parent, | ||
841 | .recalc_rate = clk_rcg_recalc_rate, | ||
842 | .determine_rate = clk_rcg_bypass2_determine_rate, | ||
843 | .set_rate = clk_rcg_bypass2_set_rate, | ||
844 | .set_rate_and_parent = clk_rcg_bypass2_set_rate_and_parent, | ||
845 | }; | ||
846 | EXPORT_SYMBOL_GPL(clk_rcg_bypass2_ops); | ||
847 | |||
848 | const struct clk_ops clk_rcg_pixel_ops = { | ||
849 | .enable = clk_enable_regmap, | ||
850 | .disable = clk_disable_regmap, | ||
851 | .get_parent = clk_rcg_get_parent, | ||
852 | .set_parent = clk_rcg_set_parent, | ||
853 | .recalc_rate = clk_rcg_recalc_rate, | ||
854 | .determine_rate = clk_rcg_pixel_determine_rate, | ||
855 | .set_rate = clk_rcg_pixel_set_rate, | ||
856 | .set_rate_and_parent = clk_rcg_pixel_set_rate_and_parent, | ||
857 | }; | ||
858 | EXPORT_SYMBOL_GPL(clk_rcg_pixel_ops); | ||
859 | |||
860 | const struct clk_ops clk_rcg_esc_ops = { | ||
861 | .enable = clk_enable_regmap, | ||
862 | .disable = clk_disable_regmap, | ||
863 | .get_parent = clk_rcg_get_parent, | ||
864 | .set_parent = clk_rcg_set_parent, | ||
865 | .recalc_rate = clk_rcg_recalc_rate, | ||
866 | .determine_rate = clk_rcg_esc_determine_rate, | ||
867 | .set_rate = clk_rcg_esc_set_rate, | ||
868 | .set_rate_and_parent = clk_rcg_esc_set_rate_and_parent, | ||
869 | }; | ||
870 | EXPORT_SYMBOL_GPL(clk_rcg_esc_ops); | ||
871 | |||
642 | const struct clk_ops clk_rcg_lcc_ops = { | 872 | const struct clk_ops clk_rcg_lcc_ops = { |
643 | .enable = clk_rcg_lcc_enable, | 873 | .enable = clk_rcg_lcc_enable, |
644 | .disable = clk_rcg_lcc_disable, | 874 | .disable = clk_rcg_lcc_disable, |
diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 56028bb31d87..4b1e94bdf29e 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h | |||
@@ -106,6 +106,9 @@ struct clk_rcg { | |||
106 | 106 | ||
107 | extern const struct clk_ops clk_rcg_ops; | 107 | extern const struct clk_ops clk_rcg_ops; |
108 | extern const struct clk_ops clk_rcg_bypass_ops; | 108 | extern const struct clk_ops clk_rcg_bypass_ops; |
109 | extern const struct clk_ops clk_rcg_bypass2_ops; | ||
110 | extern const struct clk_ops clk_rcg_pixel_ops; | ||
111 | extern const struct clk_ops clk_rcg_esc_ops; | ||
109 | extern const struct clk_ops clk_rcg_lcc_ops; | 112 | extern const struct clk_ops clk_rcg_lcc_ops; |
110 | 113 | ||
111 | #define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr) | 114 | #define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr) |
@@ -153,8 +156,8 @@ extern const struct clk_ops clk_dyn_rcg_ops; | |||
153 | * @hid_width: number of bits in half integer divider | 156 | * @hid_width: number of bits in half integer divider |
154 | * @parent_map: map from software's parent index to hardware's src_sel field | 157 | * @parent_map: map from software's parent index to hardware's src_sel field |
155 | * @freq_tbl: frequency table | 158 | * @freq_tbl: frequency table |
159 | * @current_freq: last cached frequency when using branches with shared RCGs | ||
156 | * @clkr: regmap clock handle | 160 | * @clkr: regmap clock handle |
157 | * @lock: register lock | ||
158 | * | 161 | * |
159 | */ | 162 | */ |
160 | struct clk_rcg2 { | 163 | struct clk_rcg2 { |
@@ -163,14 +166,17 @@ struct clk_rcg2 { | |||
163 | u8 hid_width; | 166 | u8 hid_width; |
164 | const struct parent_map *parent_map; | 167 | const struct parent_map *parent_map; |
165 | const struct freq_tbl *freq_tbl; | 168 | const struct freq_tbl *freq_tbl; |
169 | unsigned long current_freq; | ||
166 | struct clk_regmap clkr; | 170 | struct clk_regmap clkr; |
167 | }; | 171 | }; |
168 | 172 | ||
169 | #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) | 173 | #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) |
170 | 174 | ||
171 | extern const struct clk_ops clk_rcg2_ops; | 175 | extern const struct clk_ops clk_rcg2_ops; |
176 | extern const struct clk_ops clk_rcg2_shared_ops; | ||
172 | extern const struct clk_ops clk_edp_pixel_ops; | 177 | extern const struct clk_ops clk_edp_pixel_ops; |
173 | extern const struct clk_ops clk_byte_ops; | 178 | extern const struct clk_ops clk_byte_ops; |
179 | extern const struct clk_ops clk_byte2_ops; | ||
174 | extern const struct clk_ops clk_pixel_ops; | 180 | extern const struct clk_ops clk_pixel_ops; |
175 | 181 | ||
176 | #endif | 182 | #endif |
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 9aec1761fd29..b544bb302f79 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c | |||
@@ -300,6 +300,85 @@ const struct clk_ops clk_rcg2_ops = { | |||
300 | }; | 300 | }; |
301 | EXPORT_SYMBOL_GPL(clk_rcg2_ops); | 301 | EXPORT_SYMBOL_GPL(clk_rcg2_ops); |
302 | 302 | ||
303 | static int clk_rcg2_shared_force_enable(struct clk_hw *hw, unsigned long rate) | ||
304 | { | ||
305 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
306 | const char *name = clk_hw_get_name(hw); | ||
307 | int ret, count; | ||
308 | |||
309 | /* force enable RCG */ | ||
310 | ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, | ||
311 | CMD_ROOT_EN, CMD_ROOT_EN); | ||
312 | if (ret) | ||
313 | return ret; | ||
314 | |||
315 | /* wait for RCG to turn ON */ | ||
316 | for (count = 500; count > 0; count--) { | ||
317 | ret = clk_rcg2_is_enabled(hw); | ||
318 | if (ret) | ||
319 | break; | ||
320 | udelay(1); | ||
321 | } | ||
322 | if (!count) | ||
323 | pr_err("%s: RCG did not turn on\n", name); | ||
324 | |||
325 | /* set clock rate */ | ||
326 | ret = __clk_rcg2_set_rate(hw, rate); | ||
327 | if (ret) | ||
328 | return ret; | ||
329 | |||
330 | /* clear force enable RCG */ | ||
331 | return regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CMD_REG, | ||
332 | CMD_ROOT_EN, 0); | ||
333 | } | ||
334 | |||
335 | static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, | ||
336 | unsigned long parent_rate) | ||
337 | { | ||
338 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
339 | |||
340 | /* cache the rate */ | ||
341 | rcg->current_freq = rate; | ||
342 | |||
343 | if (!__clk_is_enabled(hw->clk)) | ||
344 | return 0; | ||
345 | |||
346 | return clk_rcg2_shared_force_enable(hw, rcg->current_freq); | ||
347 | } | ||
348 | |||
349 | static unsigned long | ||
350 | clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | ||
351 | { | ||
352 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
353 | |||
354 | return rcg->current_freq = clk_rcg2_recalc_rate(hw, parent_rate); | ||
355 | } | ||
356 | |||
357 | static int clk_rcg2_shared_enable(struct clk_hw *hw) | ||
358 | { | ||
359 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
360 | |||
361 | return clk_rcg2_shared_force_enable(hw, rcg->current_freq); | ||
362 | } | ||
363 | |||
364 | static void clk_rcg2_shared_disable(struct clk_hw *hw) | ||
365 | { | ||
366 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
367 | |||
368 | /* switch to XO, which is the lowest entry in the freq table */ | ||
369 | clk_rcg2_shared_set_rate(hw, rcg->freq_tbl[0].freq, 0); | ||
370 | } | ||
371 | |||
372 | const struct clk_ops clk_rcg2_shared_ops = { | ||
373 | .enable = clk_rcg2_shared_enable, | ||
374 | .disable = clk_rcg2_shared_disable, | ||
375 | .get_parent = clk_rcg2_get_parent, | ||
376 | .recalc_rate = clk_rcg2_shared_recalc_rate, | ||
377 | .determine_rate = clk_rcg2_determine_rate, | ||
378 | .set_rate = clk_rcg2_shared_set_rate, | ||
379 | }; | ||
380 | EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); | ||
381 | |||
303 | struct frac_entry { | 382 | struct frac_entry { |
304 | int num; | 383 | int num; |
305 | int den; | 384 | int den; |
@@ -485,6 +564,76 @@ const struct clk_ops clk_byte_ops = { | |||
485 | }; | 564 | }; |
486 | EXPORT_SYMBOL_GPL(clk_byte_ops); | 565 | EXPORT_SYMBOL_GPL(clk_byte_ops); |
487 | 566 | ||
567 | static int clk_byte2_determine_rate(struct clk_hw *hw, | ||
568 | struct clk_rate_request *req) | ||
569 | { | ||
570 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
571 | unsigned long parent_rate, div; | ||
572 | u32 mask = BIT(rcg->hid_width) - 1; | ||
573 | struct clk_hw *p; | ||
574 | unsigned long rate = req->rate; | ||
575 | |||
576 | if (rate == 0) | ||
577 | return -EINVAL; | ||
578 | |||
579 | p = req->best_parent_hw; | ||
580 | req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate); | ||
581 | |||
582 | div = DIV_ROUND_UP((2 * parent_rate), rate) - 1; | ||
583 | div = min_t(u32, div, mask); | ||
584 | |||
585 | req->rate = calc_rate(parent_rate, 0, 0, 0, div); | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int clk_byte2_set_rate(struct clk_hw *hw, unsigned long rate, | ||
591 | unsigned long parent_rate) | ||
592 | { | ||
593 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
594 | struct freq_tbl f = { 0 }; | ||
595 | unsigned long div; | ||
596 | int i, num_parents = clk_hw_get_num_parents(hw); | ||
597 | u32 mask = BIT(rcg->hid_width) - 1; | ||
598 | u32 cfg; | ||
599 | |||
600 | div = DIV_ROUND_UP((2 * parent_rate), rate) - 1; | ||
601 | div = min_t(u32, div, mask); | ||
602 | |||
603 | f.pre_div = div; | ||
604 | |||
605 | regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); | ||
606 | cfg &= CFG_SRC_SEL_MASK; | ||
607 | cfg >>= CFG_SRC_SEL_SHIFT; | ||
608 | |||
609 | for (i = 0; i < num_parents; i++) { | ||
610 | if (cfg == rcg->parent_map[i].cfg) { | ||
611 | f.src = rcg->parent_map[i].src; | ||
612 | return clk_rcg2_configure(rcg, &f); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | return -EINVAL; | ||
617 | } | ||
618 | |||
619 | static int clk_byte2_set_rate_and_parent(struct clk_hw *hw, | ||
620 | unsigned long rate, unsigned long parent_rate, u8 index) | ||
621 | { | ||
622 | /* Read the hardware to determine parent during set_rate */ | ||
623 | return clk_byte2_set_rate(hw, rate, parent_rate); | ||
624 | } | ||
625 | |||
626 | const struct clk_ops clk_byte2_ops = { | ||
627 | .is_enabled = clk_rcg2_is_enabled, | ||
628 | .get_parent = clk_rcg2_get_parent, | ||
629 | .set_parent = clk_rcg2_set_parent, | ||
630 | .recalc_rate = clk_rcg2_recalc_rate, | ||
631 | .set_rate = clk_byte2_set_rate, | ||
632 | .set_rate_and_parent = clk_byte2_set_rate_and_parent, | ||
633 | .determine_rate = clk_byte2_determine_rate, | ||
634 | }; | ||
635 | EXPORT_SYMBOL_GPL(clk_byte2_ops); | ||
636 | |||
488 | static const struct frac_entry frac_table_pixel[] = { | 637 | static const struct frac_entry frac_table_pixel[] = { |
489 | { 3, 8 }, | 638 | { 3, 8 }, |
490 | { 2, 9 }, | 639 | { 2, 9 }, |
@@ -496,14 +645,9 @@ static const struct frac_entry frac_table_pixel[] = { | |||
496 | static int clk_pixel_determine_rate(struct clk_hw *hw, | 645 | static int clk_pixel_determine_rate(struct clk_hw *hw, |
497 | struct clk_rate_request *req) | 646 | struct clk_rate_request *req) |
498 | { | 647 | { |
499 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | ||
500 | unsigned long request, src_rate; | 648 | unsigned long request, src_rate; |
501 | int delta = 100000; | 649 | int delta = 100000; |
502 | const struct freq_tbl *f = rcg->freq_tbl; | ||
503 | const struct frac_entry *frac = frac_table_pixel; | 650 | const struct frac_entry *frac = frac_table_pixel; |
504 | int index = qcom_find_src_index(hw, rcg->parent_map, f->src); | ||
505 | |||
506 | req->best_parent_hw = clk_hw_get_parent_by_index(hw, index); | ||
507 | 651 | ||
508 | for (; frac->num; frac++) { | 652 | for (; frac->num; frac++) { |
509 | request = (req->rate * frac->den) / frac->num; | 653 | request = (req->rate * frac->den) / frac->num; |
@@ -525,12 +669,23 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate, | |||
525 | unsigned long parent_rate) | 669 | unsigned long parent_rate) |
526 | { | 670 | { |
527 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); | 671 | struct clk_rcg2 *rcg = to_clk_rcg2(hw); |
528 | struct freq_tbl f = *rcg->freq_tbl; | 672 | struct freq_tbl f = { 0 }; |
529 | const struct frac_entry *frac = frac_table_pixel; | 673 | const struct frac_entry *frac = frac_table_pixel; |
530 | unsigned long request; | 674 | unsigned long request; |
531 | int delta = 100000; | 675 | int delta = 100000; |
532 | u32 mask = BIT(rcg->hid_width) - 1; | 676 | u32 mask = BIT(rcg->hid_width) - 1; |
533 | u32 hid_div; | 677 | u32 hid_div, cfg; |
678 | int i, num_parents = clk_hw_get_num_parents(hw); | ||
679 | |||
680 | regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); | ||
681 | cfg &= CFG_SRC_SEL_MASK; | ||
682 | cfg >>= CFG_SRC_SEL_SHIFT; | ||
683 | |||
684 | for (i = 0; i < num_parents; i++) | ||
685 | if (cfg == rcg->parent_map[i].cfg) { | ||
686 | f.src = rcg->parent_map[i].src; | ||
687 | break; | ||
688 | } | ||
534 | 689 | ||
535 | for (; frac->num; frac++) { | 690 | for (; frac->num; frac++) { |
536 | request = (rate * frac->den) / frac->num; | 691 | request = (rate * frac->den) / frac->num; |
@@ -555,7 +710,6 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate, | |||
555 | static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, | 710 | static int clk_pixel_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, |
556 | unsigned long parent_rate, u8 index) | 711 | unsigned long parent_rate, u8 index) |
557 | { | 712 | { |
558 | /* Parent index is set statically in frequency table */ | ||
559 | return clk_pixel_set_rate(hw, rate, parent_rate); | 713 | return clk_pixel_set_rate(hw, rate, parent_rate); |
560 | } | 714 | } |
561 | 715 | ||
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index 2dedceefd21d..8fa477293ae0 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "clk-rcg.h" | 22 | #include "clk-rcg.h" |
23 | #include "clk-regmap.h" | 23 | #include "clk-regmap.h" |
24 | #include "reset.h" | 24 | #include "reset.h" |
25 | #include "gdsc.h" | ||
25 | 26 | ||
26 | struct qcom_cc { | 27 | struct qcom_cc { |
27 | struct qcom_reset_controller reset; | 28 | struct qcom_reset_controller reset; |
@@ -72,6 +73,21 @@ qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc) | |||
72 | } | 73 | } |
73 | EXPORT_SYMBOL_GPL(qcom_cc_map); | 74 | EXPORT_SYMBOL_GPL(qcom_cc_map); |
74 | 75 | ||
76 | static void qcom_cc_del_clk_provider(void *data) | ||
77 | { | ||
78 | of_clk_del_provider(data); | ||
79 | } | ||
80 | |||
81 | static void qcom_cc_reset_unregister(void *data) | ||
82 | { | ||
83 | reset_controller_unregister(data); | ||
84 | } | ||
85 | |||
86 | static void qcom_cc_gdsc_unregister(void *data) | ||
87 | { | ||
88 | gdsc_unregister(data); | ||
89 | } | ||
90 | |||
75 | int qcom_cc_really_probe(struct platform_device *pdev, | 91 | int qcom_cc_really_probe(struct platform_device *pdev, |
76 | const struct qcom_cc_desc *desc, struct regmap *regmap) | 92 | const struct qcom_cc_desc *desc, struct regmap *regmap) |
77 | { | 93 | { |
@@ -110,6 +126,8 @@ int qcom_cc_really_probe(struct platform_device *pdev, | |||
110 | if (ret) | 126 | if (ret) |
111 | return ret; | 127 | return ret; |
112 | 128 | ||
129 | devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node); | ||
130 | |||
113 | reset = &cc->reset; | 131 | reset = &cc->reset; |
114 | reset->rcdev.of_node = dev->of_node; | 132 | reset->rcdev.of_node = dev->of_node; |
115 | reset->rcdev.ops = &qcom_reset_ops; | 133 | reset->rcdev.ops = &qcom_reset_ops; |
@@ -117,13 +135,24 @@ int qcom_cc_really_probe(struct platform_device *pdev, | |||
117 | reset->rcdev.nr_resets = desc->num_resets; | 135 | reset->rcdev.nr_resets = desc->num_resets; |
118 | reset->regmap = regmap; | 136 | reset->regmap = regmap; |
119 | reset->reset_map = desc->resets; | 137 | reset->reset_map = desc->resets; |
120 | platform_set_drvdata(pdev, &reset->rcdev); | ||
121 | 138 | ||
122 | ret = reset_controller_register(&reset->rcdev); | 139 | ret = reset_controller_register(&reset->rcdev); |
123 | if (ret) | 140 | if (ret) |
124 | of_clk_del_provider(dev->of_node); | 141 | return ret; |
142 | |||
143 | devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev); | ||
144 | |||
145 | if (desc->gdscs && desc->num_gdscs) { | ||
146 | ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, | ||
147 | &reset->rcdev, regmap); | ||
148 | if (ret) | ||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | devm_add_action(dev, qcom_cc_gdsc_unregister, dev); | ||
125 | 153 | ||
126 | return ret; | 154 | |
155 | return 0; | ||
127 | } | 156 | } |
128 | EXPORT_SYMBOL_GPL(qcom_cc_really_probe); | 157 | EXPORT_SYMBOL_GPL(qcom_cc_really_probe); |
129 | 158 | ||
@@ -139,11 +168,4 @@ int qcom_cc_probe(struct platform_device *pdev, const struct qcom_cc_desc *desc) | |||
139 | } | 168 | } |
140 | EXPORT_SYMBOL_GPL(qcom_cc_probe); | 169 | EXPORT_SYMBOL_GPL(qcom_cc_probe); |
141 | 170 | ||
142 | void qcom_cc_remove(struct platform_device *pdev) | ||
143 | { | ||
144 | of_clk_del_provider(pdev->dev.of_node); | ||
145 | reset_controller_unregister(platform_get_drvdata(pdev)); | ||
146 | } | ||
147 | EXPORT_SYMBOL_GPL(qcom_cc_remove); | ||
148 | |||
149 | MODULE_LICENSE("GPL v2"); | 171 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 7a0e73713063..7c1fba3ebc03 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h | |||
@@ -28,6 +28,8 @@ struct qcom_cc_desc { | |||
28 | size_t num_clks; | 28 | size_t num_clks; |
29 | const struct qcom_reset_map *resets; | 29 | const struct qcom_reset_map *resets; |
30 | size_t num_resets; | 30 | size_t num_resets; |
31 | struct gdsc **gdscs; | ||
32 | size_t num_gdscs; | ||
31 | }; | 33 | }; |
32 | 34 | ||
33 | extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, | 35 | extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, |
@@ -43,6 +45,4 @@ extern int qcom_cc_really_probe(struct platform_device *pdev, | |||
43 | extern int qcom_cc_probe(struct platform_device *pdev, | 45 | extern int qcom_cc_probe(struct platform_device *pdev, |
44 | const struct qcom_cc_desc *desc); | 46 | const struct qcom_cc_desc *desc); |
45 | 47 | ||
46 | extern void qcom_cc_remove(struct platform_device *pdev); | ||
47 | |||
48 | #endif | 48 | #endif |
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c index 3563019b8e3c..1567c3a79534 100644 --- a/drivers/clk/qcom/gcc-apq8084.c +++ b/drivers/clk/qcom/gcc-apq8084.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
32 | #include "clk-branch.h" | 32 | #include "clk-branch.h" |
33 | #include "reset.h" | 33 | #include "reset.h" |
34 | #include "gdsc.h" | ||
34 | 35 | ||
35 | enum { | 36 | enum { |
36 | P_XO, | 37 | P_XO, |
@@ -3254,6 +3255,38 @@ static struct clk_branch gcc_usb_hsic_system_clk = { | |||
3254 | }, | 3255 | }, |
3255 | }; | 3256 | }; |
3256 | 3257 | ||
3258 | static struct gdsc usb_hs_hsic_gdsc = { | ||
3259 | .gdscr = 0x404, | ||
3260 | .pd = { | ||
3261 | .name = "usb_hs_hsic", | ||
3262 | }, | ||
3263 | .pwrsts = PWRSTS_OFF_ON, | ||
3264 | }; | ||
3265 | |||
3266 | static struct gdsc pcie0_gdsc = { | ||
3267 | .gdscr = 0x1ac4, | ||
3268 | .pd = { | ||
3269 | .name = "pcie0", | ||
3270 | }, | ||
3271 | .pwrsts = PWRSTS_OFF_ON, | ||
3272 | }; | ||
3273 | |||
3274 | static struct gdsc pcie1_gdsc = { | ||
3275 | .gdscr = 0x1b44, | ||
3276 | .pd = { | ||
3277 | .name = "pcie1", | ||
3278 | }, | ||
3279 | .pwrsts = PWRSTS_OFF_ON, | ||
3280 | }; | ||
3281 | |||
3282 | static struct gdsc usb30_gdsc = { | ||
3283 | .gdscr = 0x1e84, | ||
3284 | .pd = { | ||
3285 | .name = "usb30", | ||
3286 | }, | ||
3287 | .pwrsts = PWRSTS_OFF_ON, | ||
3288 | }; | ||
3289 | |||
3257 | static struct clk_regmap *gcc_apq8084_clocks[] = { | 3290 | static struct clk_regmap *gcc_apq8084_clocks[] = { |
3258 | [GPLL0] = &gpll0.clkr, | 3291 | [GPLL0] = &gpll0.clkr, |
3259 | [GPLL0_VOTE] = &gpll0_vote, | 3292 | [GPLL0_VOTE] = &gpll0_vote, |
@@ -3447,6 +3480,13 @@ static struct clk_regmap *gcc_apq8084_clocks[] = { | |||
3447 | [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr, | 3480 | [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr, |
3448 | }; | 3481 | }; |
3449 | 3482 | ||
3483 | static struct gdsc *gcc_apq8084_gdscs[] = { | ||
3484 | [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc, | ||
3485 | [PCIE0_GDSC] = &pcie0_gdsc, | ||
3486 | [PCIE1_GDSC] = &pcie1_gdsc, | ||
3487 | [USB30_GDSC] = &usb30_gdsc, | ||
3488 | }; | ||
3489 | |||
3450 | static const struct qcom_reset_map gcc_apq8084_resets[] = { | 3490 | static const struct qcom_reset_map gcc_apq8084_resets[] = { |
3451 | [GCC_SYSTEM_NOC_BCR] = { 0x0100 }, | 3491 | [GCC_SYSTEM_NOC_BCR] = { 0x0100 }, |
3452 | [GCC_CONFIG_NOC_BCR] = { 0x0140 }, | 3492 | [GCC_CONFIG_NOC_BCR] = { 0x0140 }, |
@@ -3555,6 +3595,8 @@ static const struct qcom_cc_desc gcc_apq8084_desc = { | |||
3555 | .num_clks = ARRAY_SIZE(gcc_apq8084_clocks), | 3595 | .num_clks = ARRAY_SIZE(gcc_apq8084_clocks), |
3556 | .resets = gcc_apq8084_resets, | 3596 | .resets = gcc_apq8084_resets, |
3557 | .num_resets = ARRAY_SIZE(gcc_apq8084_resets), | 3597 | .num_resets = ARRAY_SIZE(gcc_apq8084_resets), |
3598 | .gdscs = gcc_apq8084_gdscs, | ||
3599 | .num_gdscs = ARRAY_SIZE(gcc_apq8084_gdscs), | ||
3558 | }; | 3600 | }; |
3559 | 3601 | ||
3560 | static const struct of_device_id gcc_apq8084_match_table[] = { | 3602 | static const struct of_device_id gcc_apq8084_match_table[] = { |
@@ -3581,15 +3623,8 @@ static int gcc_apq8084_probe(struct platform_device *pdev) | |||
3581 | return qcom_cc_probe(pdev, &gcc_apq8084_desc); | 3623 | return qcom_cc_probe(pdev, &gcc_apq8084_desc); |
3582 | } | 3624 | } |
3583 | 3625 | ||
3584 | static int gcc_apq8084_remove(struct platform_device *pdev) | ||
3585 | { | ||
3586 | qcom_cc_remove(pdev); | ||
3587 | return 0; | ||
3588 | } | ||
3589 | |||
3590 | static struct platform_driver gcc_apq8084_driver = { | 3626 | static struct platform_driver gcc_apq8084_driver = { |
3591 | .probe = gcc_apq8084_probe, | 3627 | .probe = gcc_apq8084_probe, |
3592 | .remove = gcc_apq8084_remove, | ||
3593 | .driver = { | 3628 | .driver = { |
3594 | .name = "gcc-apq8084", | 3629 | .name = "gcc-apq8084", |
3595 | .of_match_table = gcc_apq8084_match_table, | 3630 | .of_match_table = gcc_apq8084_match_table, |
diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index 40e480220cd3..16fc64c082a5 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c | |||
@@ -3058,15 +3058,8 @@ static int gcc_ipq806x_probe(struct platform_device *pdev) | |||
3058 | return 0; | 3058 | return 0; |
3059 | } | 3059 | } |
3060 | 3060 | ||
3061 | static int gcc_ipq806x_remove(struct platform_device *pdev) | ||
3062 | { | ||
3063 | qcom_cc_remove(pdev); | ||
3064 | return 0; | ||
3065 | } | ||
3066 | |||
3067 | static struct platform_driver gcc_ipq806x_driver = { | 3061 | static struct platform_driver gcc_ipq806x_driver = { |
3068 | .probe = gcc_ipq806x_probe, | 3062 | .probe = gcc_ipq806x_probe, |
3069 | .remove = gcc_ipq806x_remove, | ||
3070 | .driver = { | 3063 | .driver = { |
3071 | .name = "gcc-ipq806x", | 3064 | .name = "gcc-ipq806x", |
3072 | .of_match_table = gcc_ipq806x_match_table, | 3065 | .of_match_table = gcc_ipq806x_match_table, |
diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index b02826ed770a..f110bb5a1df3 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c | |||
@@ -2735,15 +2735,8 @@ static int gcc_msm8660_probe(struct platform_device *pdev) | |||
2735 | return qcom_cc_probe(pdev, &gcc_msm8660_desc); | 2735 | return qcom_cc_probe(pdev, &gcc_msm8660_desc); |
2736 | } | 2736 | } |
2737 | 2737 | ||
2738 | static int gcc_msm8660_remove(struct platform_device *pdev) | ||
2739 | { | ||
2740 | qcom_cc_remove(pdev); | ||
2741 | return 0; | ||
2742 | } | ||
2743 | |||
2744 | static struct platform_driver gcc_msm8660_driver = { | 2738 | static struct platform_driver gcc_msm8660_driver = { |
2745 | .probe = gcc_msm8660_probe, | 2739 | .probe = gcc_msm8660_probe, |
2746 | .remove = gcc_msm8660_remove, | ||
2747 | .driver = { | 2740 | .driver = { |
2748 | .name = "gcc-msm8660", | 2741 | .name = "gcc-msm8660", |
2749 | .of_match_table = gcc_msm8660_match_table, | 2742 | .of_match_table = gcc_msm8660_match_table, |
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index 22a4e1e732c0..d0a0313d6bef 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
32 | #include "clk-branch.h" | 32 | #include "clk-branch.h" |
33 | #include "reset.h" | 33 | #include "reset.h" |
34 | #include "gdsc.h" | ||
34 | 35 | ||
35 | enum { | 36 | enum { |
36 | P_XO, | 37 | P_XO, |
@@ -44,6 +45,9 @@ enum { | |||
44 | P_SLEEP_CLK, | 45 | P_SLEEP_CLK, |
45 | P_DSI0_PHYPLL_BYTE, | 46 | P_DSI0_PHYPLL_BYTE, |
46 | P_DSI0_PHYPLL_DSI, | 47 | P_DSI0_PHYPLL_DSI, |
48 | P_EXT_PRI_I2S, | ||
49 | P_EXT_SEC_I2S, | ||
50 | P_EXT_MCLK, | ||
47 | }; | 51 | }; |
48 | 52 | ||
49 | static const struct parent_map gcc_xo_gpll0_map[] = { | 53 | static const struct parent_map gcc_xo_gpll0_map[] = { |
@@ -190,6 +194,76 @@ static const char * const gcc_xo_gpll0a_gpll1_gpll2[] = { | |||
190 | "gpll2_vote", | 194 | "gpll2_vote", |
191 | }; | 195 | }; |
192 | 196 | ||
197 | static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = { | ||
198 | { P_XO, 0 }, | ||
199 | { P_GPLL0, 1 }, | ||
200 | { P_GPLL1, 2 }, | ||
201 | { P_SLEEP_CLK, 6 } | ||
202 | }; | ||
203 | |||
204 | static const char * const gcc_xo_gpll0_gpll1_sleep[] = { | ||
205 | "xo", | ||
206 | "gpll0_vote", | ||
207 | "gpll1_vote", | ||
208 | "sleep_clk", | ||
209 | }; | ||
210 | |||
211 | static const struct parent_map gcc_xo_gpll1_epi2s_emclk_sleep_map[] = { | ||
212 | { P_XO, 0 }, | ||
213 | { P_GPLL1, 1 }, | ||
214 | { P_EXT_PRI_I2S, 2 }, | ||
215 | { P_EXT_MCLK, 3 }, | ||
216 | { P_SLEEP_CLK, 6 } | ||
217 | }; | ||
218 | |||
219 | static const char * const gcc_xo_gpll1_epi2s_emclk_sleep[] = { | ||
220 | "xo", | ||
221 | "gpll1_vote", | ||
222 | "ext_pri_i2s", | ||
223 | "ext_mclk", | ||
224 | "sleep_clk", | ||
225 | }; | ||
226 | |||
227 | static const struct parent_map gcc_xo_gpll1_esi2s_emclk_sleep_map[] = { | ||
228 | { P_XO, 0 }, | ||
229 | { P_GPLL1, 1 }, | ||
230 | { P_EXT_SEC_I2S, 2 }, | ||
231 | { P_EXT_MCLK, 3 }, | ||
232 | { P_SLEEP_CLK, 6 } | ||
233 | }; | ||
234 | |||
235 | static const char * const gcc_xo_gpll1_esi2s_emclk_sleep[] = { | ||
236 | "xo", | ||
237 | "gpll1_vote", | ||
238 | "ext_sec_i2s", | ||
239 | "ext_mclk", | ||
240 | "sleep_clk", | ||
241 | }; | ||
242 | |||
243 | static const struct parent_map gcc_xo_sleep_map[] = { | ||
244 | { P_XO, 0 }, | ||
245 | { P_SLEEP_CLK, 6 } | ||
246 | }; | ||
247 | |||
248 | static const char * const gcc_xo_sleep[] = { | ||
249 | "xo", | ||
250 | "sleep_clk", | ||
251 | }; | ||
252 | |||
253 | static const struct parent_map gcc_xo_gpll1_emclk_sleep_map[] = { | ||
254 | { P_XO, 0 }, | ||
255 | { P_GPLL1, 1 }, | ||
256 | { P_EXT_MCLK, 2 }, | ||
257 | { P_SLEEP_CLK, 6 } | ||
258 | }; | ||
259 | |||
260 | static const char * const gcc_xo_gpll1_emclk_sleep[] = { | ||
261 | "xo", | ||
262 | "gpll1_vote", | ||
263 | "ext_mclk", | ||
264 | "sleep_clk", | ||
265 | }; | ||
266 | |||
193 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } | 267 | #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } |
194 | 268 | ||
195 | static struct clk_pll gpll0 = { | 269 | static struct clk_pll gpll0 = { |
@@ -906,21 +980,15 @@ static struct clk_rcg2 gp3_clk_src = { | |||
906 | }, | 980 | }, |
907 | }; | 981 | }; |
908 | 982 | ||
909 | static struct freq_tbl ftbl_gcc_mdss_byte0_clk[] = { | ||
910 | { .src = P_DSI0_PHYPLL_BYTE }, | ||
911 | { } | ||
912 | }; | ||
913 | |||
914 | static struct clk_rcg2 byte0_clk_src = { | 983 | static struct clk_rcg2 byte0_clk_src = { |
915 | .cmd_rcgr = 0x4d044, | 984 | .cmd_rcgr = 0x4d044, |
916 | .hid_width = 5, | 985 | .hid_width = 5, |
917 | .parent_map = gcc_xo_gpll0a_dsibyte_map, | 986 | .parent_map = gcc_xo_gpll0a_dsibyte_map, |
918 | .freq_tbl = ftbl_gcc_mdss_byte0_clk, | ||
919 | .clkr.hw.init = &(struct clk_init_data){ | 987 | .clkr.hw.init = &(struct clk_init_data){ |
920 | .name = "byte0_clk_src", | 988 | .name = "byte0_clk_src", |
921 | .parent_names = gcc_xo_gpll0a_dsibyte, | 989 | .parent_names = gcc_xo_gpll0a_dsibyte, |
922 | .num_parents = 3, | 990 | .num_parents = 3, |
923 | .ops = &clk_byte_ops, | 991 | .ops = &clk_byte2_ops, |
924 | .flags = CLK_SET_RATE_PARENT, | 992 | .flags = CLK_SET_RATE_PARENT, |
925 | }, | 993 | }, |
926 | }; | 994 | }; |
@@ -968,17 +1036,11 @@ static struct clk_rcg2 mdp_clk_src = { | |||
968 | }, | 1036 | }, |
969 | }; | 1037 | }; |
970 | 1038 | ||
971 | static struct freq_tbl ftbl_gcc_mdss_pclk[] = { | ||
972 | { .src = P_DSI0_PHYPLL_DSI }, | ||
973 | { } | ||
974 | }; | ||
975 | |||
976 | static struct clk_rcg2 pclk0_clk_src = { | 1039 | static struct clk_rcg2 pclk0_clk_src = { |
977 | .cmd_rcgr = 0x4d000, | 1040 | .cmd_rcgr = 0x4d000, |
978 | .mnd_width = 8, | 1041 | .mnd_width = 8, |
979 | .hid_width = 5, | 1042 | .hid_width = 5, |
980 | .parent_map = gcc_xo_gpll0a_dsiphy_map, | 1043 | .parent_map = gcc_xo_gpll0a_dsiphy_map, |
981 | .freq_tbl = ftbl_gcc_mdss_pclk, | ||
982 | .clkr.hw.init = &(struct clk_init_data){ | 1044 | .clkr.hw.init = &(struct clk_init_data){ |
983 | .name = "pclk0_clk_src", | 1045 | .name = "pclk0_clk_src", |
984 | .parent_names = gcc_xo_gpll0a_dsiphy, | 1046 | .parent_names = gcc_xo_gpll0a_dsiphy, |
@@ -1094,6 +1156,30 @@ static struct clk_rcg2 apss_tcu_clk_src = { | |||
1094 | }, | 1156 | }, |
1095 | }; | 1157 | }; |
1096 | 1158 | ||
1159 | static const struct freq_tbl ftbl_gcc_bimc_gpu_clk[] = { | ||
1160 | F(19200000, P_XO, 1, 0, 0), | ||
1161 | F(100000000, P_GPLL0, 8, 0, 0), | ||
1162 | F(200000000, P_GPLL0, 4, 0, 0), | ||
1163 | F(266500000, P_BIMC, 4, 0, 0), | ||
1164 | F(400000000, P_GPLL0, 2, 0, 0), | ||
1165 | F(533000000, P_BIMC, 2, 0, 0), | ||
1166 | { } | ||
1167 | }; | ||
1168 | |||
1169 | static struct clk_rcg2 bimc_gpu_clk_src = { | ||
1170 | .cmd_rcgr = 0x31028, | ||
1171 | .hid_width = 5, | ||
1172 | .parent_map = gcc_xo_gpll0_bimc_map, | ||
1173 | .freq_tbl = ftbl_gcc_bimc_gpu_clk, | ||
1174 | .clkr.hw.init = &(struct clk_init_data){ | ||
1175 | .name = "bimc_gpu_clk_src", | ||
1176 | .parent_names = gcc_xo_gpll0_bimc, | ||
1177 | .num_parents = 3, | ||
1178 | .flags = CLK_GET_RATE_NOCACHE, | ||
1179 | .ops = &clk_rcg2_shared_ops, | ||
1180 | }, | ||
1181 | }; | ||
1182 | |||
1097 | static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { | 1183 | static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { |
1098 | F(80000000, P_GPLL0, 10, 0, 0), | 1184 | F(80000000, P_GPLL0, 10, 0, 0), |
1099 | { } | 1185 | { } |
@@ -1112,6 +1198,305 @@ static struct clk_rcg2 usb_hs_system_clk_src = { | |||
1112 | }, | 1198 | }, |
1113 | }; | 1199 | }; |
1114 | 1200 | ||
1201 | static const struct freq_tbl ftbl_gcc_ultaudio_ahb_clk[] = { | ||
1202 | F(3200000, P_XO, 6, 0, 0), | ||
1203 | F(6400000, P_XO, 3, 0, 0), | ||
1204 | F(9600000, P_XO, 2, 0, 0), | ||
1205 | F(19200000, P_XO, 1, 0, 0), | ||
1206 | F(40000000, P_GPLL0, 10, 1, 2), | ||
1207 | F(66670000, P_GPLL0, 12, 0, 0), | ||
1208 | F(80000000, P_GPLL0, 10, 0, 0), | ||
1209 | F(100000000, P_GPLL0, 8, 0, 0), | ||
1210 | { } | ||
1211 | }; | ||
1212 | |||
1213 | static struct clk_rcg2 ultaudio_ahbfabric_clk_src = { | ||
1214 | .cmd_rcgr = 0x1c010, | ||
1215 | .hid_width = 5, | ||
1216 | .mnd_width = 8, | ||
1217 | .parent_map = gcc_xo_gpll0_gpll1_sleep_map, | ||
1218 | .freq_tbl = ftbl_gcc_ultaudio_ahb_clk, | ||
1219 | .clkr.hw.init = &(struct clk_init_data){ | ||
1220 | .name = "ultaudio_ahbfabric_clk_src", | ||
1221 | .parent_names = gcc_xo_gpll0_gpll1_sleep, | ||
1222 | .num_parents = 4, | ||
1223 | .ops = &clk_rcg2_ops, | ||
1224 | }, | ||
1225 | }; | ||
1226 | |||
1227 | static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_clk = { | ||
1228 | .halt_reg = 0x1c028, | ||
1229 | .clkr = { | ||
1230 | .enable_reg = 0x1c028, | ||
1231 | .enable_mask = BIT(0), | ||
1232 | .hw.init = &(struct clk_init_data){ | ||
1233 | .name = "gcc_ultaudio_ahbfabric_ixfabric_clk", | ||
1234 | .parent_names = (const char *[]){ | ||
1235 | "ultaudio_ahbfabric_clk_src", | ||
1236 | }, | ||
1237 | .num_parents = 1, | ||
1238 | .flags = CLK_SET_RATE_PARENT, | ||
1239 | .ops = &clk_branch2_ops, | ||
1240 | }, | ||
1241 | }, | ||
1242 | }; | ||
1243 | |||
1244 | static struct clk_branch gcc_ultaudio_ahbfabric_ixfabric_lpm_clk = { | ||
1245 | .halt_reg = 0x1c024, | ||
1246 | .clkr = { | ||
1247 | .enable_reg = 0x1c024, | ||
1248 | .enable_mask = BIT(0), | ||
1249 | .hw.init = &(struct clk_init_data){ | ||
1250 | .name = "gcc_ultaudio_ahbfabric_ixfabric_lpm_clk", | ||
1251 | .parent_names = (const char *[]){ | ||
1252 | "ultaudio_ahbfabric_clk_src", | ||
1253 | }, | ||
1254 | .num_parents = 1, | ||
1255 | .flags = CLK_SET_RATE_PARENT, | ||
1256 | .ops = &clk_branch2_ops, | ||
1257 | }, | ||
1258 | }, | ||
1259 | }; | ||
1260 | |||
1261 | static const struct freq_tbl ftbl_gcc_ultaudio_lpaif_i2s_clk[] = { | ||
1262 | F(256000, P_XO, 5, 1, 15), | ||
1263 | F(512000, P_XO, 5, 2, 15), | ||
1264 | F(705600, P_GPLL1, 16, 1, 80), | ||
1265 | F(768000, P_XO, 5, 1, 5), | ||
1266 | F(800000, P_XO, 5, 5, 24), | ||
1267 | F(1024000, P_GPLL1, 14, 1, 63), | ||
1268 | F(1152000, P_XO, 1, 3, 50), | ||
1269 | F(1411200, P_GPLL1, 16, 1, 40), | ||
1270 | F(1536000, P_XO, 1, 2, 25), | ||
1271 | F(1600000, P_XO, 12, 0, 0), | ||
1272 | F(2048000, P_GPLL1, 9, 1, 49), | ||
1273 | F(2400000, P_XO, 8, 0, 0), | ||
1274 | F(2822400, P_GPLL1, 16, 1, 20), | ||
1275 | F(3072000, P_GPLL1, 14, 1, 21), | ||
1276 | F(4096000, P_GPLL1, 9, 2, 49), | ||
1277 | F(4800000, P_XO, 4, 0, 0), | ||
1278 | F(5644800, P_GPLL1, 16, 1, 10), | ||
1279 | F(6144000, P_GPLL1, 7, 1, 21), | ||
1280 | F(8192000, P_GPLL1, 9, 4, 49), | ||
1281 | F(9600000, P_XO, 2, 0, 0), | ||
1282 | F(11289600, P_GPLL1, 16, 1, 5), | ||
1283 | F(12288000, P_GPLL1, 7, 2, 21), | ||
1284 | { } | ||
1285 | }; | ||
1286 | |||
1287 | static struct clk_rcg2 ultaudio_lpaif_pri_i2s_clk_src = { | ||
1288 | .cmd_rcgr = 0x1c054, | ||
1289 | .hid_width = 5, | ||
1290 | .mnd_width = 8, | ||
1291 | .parent_map = gcc_xo_gpll1_epi2s_emclk_sleep_map, | ||
1292 | .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk, | ||
1293 | .clkr.hw.init = &(struct clk_init_data){ | ||
1294 | .name = "ultaudio_lpaif_pri_i2s_clk_src", | ||
1295 | .parent_names = gcc_xo_gpll1_epi2s_emclk_sleep, | ||
1296 | .num_parents = 5, | ||
1297 | .ops = &clk_rcg2_ops, | ||
1298 | }, | ||
1299 | }; | ||
1300 | |||
1301 | static struct clk_branch gcc_ultaudio_lpaif_pri_i2s_clk = { | ||
1302 | .halt_reg = 0x1c068, | ||
1303 | .clkr = { | ||
1304 | .enable_reg = 0x1c068, | ||
1305 | .enable_mask = BIT(0), | ||
1306 | .hw.init = &(struct clk_init_data){ | ||
1307 | .name = "gcc_ultaudio_lpaif_pri_i2s_clk", | ||
1308 | .parent_names = (const char *[]){ | ||
1309 | "ultaudio_lpaif_pri_i2s_clk_src", | ||
1310 | }, | ||
1311 | .num_parents = 1, | ||
1312 | .flags = CLK_SET_RATE_PARENT, | ||
1313 | .ops = &clk_branch2_ops, | ||
1314 | }, | ||
1315 | }, | ||
1316 | }; | ||
1317 | |||
1318 | static struct clk_rcg2 ultaudio_lpaif_sec_i2s_clk_src = { | ||
1319 | .cmd_rcgr = 0x1c06c, | ||
1320 | .hid_width = 5, | ||
1321 | .mnd_width = 8, | ||
1322 | .parent_map = gcc_xo_gpll1_esi2s_emclk_sleep_map, | ||
1323 | .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk, | ||
1324 | .clkr.hw.init = &(struct clk_init_data){ | ||
1325 | .name = "ultaudio_lpaif_sec_i2s_clk_src", | ||
1326 | .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep, | ||
1327 | .num_parents = 5, | ||
1328 | .ops = &clk_rcg2_ops, | ||
1329 | }, | ||
1330 | }; | ||
1331 | |||
1332 | static struct clk_branch gcc_ultaudio_lpaif_sec_i2s_clk = { | ||
1333 | .halt_reg = 0x1c080, | ||
1334 | .clkr = { | ||
1335 | .enable_reg = 0x1c080, | ||
1336 | .enable_mask = BIT(0), | ||
1337 | .hw.init = &(struct clk_init_data){ | ||
1338 | .name = "gcc_ultaudio_lpaif_sec_i2s_clk", | ||
1339 | .parent_names = (const char *[]){ | ||
1340 | "ultaudio_lpaif_sec_i2s_clk_src", | ||
1341 | }, | ||
1342 | .num_parents = 1, | ||
1343 | .flags = CLK_SET_RATE_PARENT, | ||
1344 | .ops = &clk_branch2_ops, | ||
1345 | }, | ||
1346 | }, | ||
1347 | }; | ||
1348 | |||
1349 | static struct clk_rcg2 ultaudio_lpaif_aux_i2s_clk_src = { | ||
1350 | .cmd_rcgr = 0x1c084, | ||
1351 | .hid_width = 5, | ||
1352 | .mnd_width = 8, | ||
1353 | .parent_map = gcc_xo_gpll1_emclk_sleep_map, | ||
1354 | .freq_tbl = ftbl_gcc_ultaudio_lpaif_i2s_clk, | ||
1355 | .clkr.hw.init = &(struct clk_init_data){ | ||
1356 | .name = "ultaudio_lpaif_aux_i2s_clk_src", | ||
1357 | .parent_names = gcc_xo_gpll1_esi2s_emclk_sleep, | ||
1358 | .num_parents = 5, | ||
1359 | .ops = &clk_rcg2_ops, | ||
1360 | }, | ||
1361 | }; | ||
1362 | |||
1363 | static struct clk_branch gcc_ultaudio_lpaif_aux_i2s_clk = { | ||
1364 | .halt_reg = 0x1c098, | ||
1365 | .clkr = { | ||
1366 | .enable_reg = 0x1c098, | ||
1367 | .enable_mask = BIT(0), | ||
1368 | .hw.init = &(struct clk_init_data){ | ||
1369 | .name = "gcc_ultaudio_lpaif_aux_i2s_clk", | ||
1370 | .parent_names = (const char *[]){ | ||
1371 | "ultaudio_lpaif_aux_i2s_clk_src", | ||
1372 | }, | ||
1373 | .num_parents = 1, | ||
1374 | .flags = CLK_SET_RATE_PARENT, | ||
1375 | .ops = &clk_branch2_ops, | ||
1376 | }, | ||
1377 | }, | ||
1378 | }; | ||
1379 | |||
1380 | static const struct freq_tbl ftbl_gcc_ultaudio_xo_clk[] = { | ||
1381 | F(19200000, P_XO, 1, 0, 0), | ||
1382 | { } | ||
1383 | }; | ||
1384 | |||
1385 | static struct clk_rcg2 ultaudio_xo_clk_src = { | ||
1386 | .cmd_rcgr = 0x1c034, | ||
1387 | .hid_width = 5, | ||
1388 | .parent_map = gcc_xo_sleep_map, | ||
1389 | .freq_tbl = ftbl_gcc_ultaudio_xo_clk, | ||
1390 | .clkr.hw.init = &(struct clk_init_data){ | ||
1391 | .name = "ultaudio_xo_clk_src", | ||
1392 | .parent_names = gcc_xo_sleep, | ||
1393 | .num_parents = 2, | ||
1394 | .ops = &clk_rcg2_ops, | ||
1395 | }, | ||
1396 | }; | ||
1397 | |||
1398 | static struct clk_branch gcc_ultaudio_avsync_xo_clk = { | ||
1399 | .halt_reg = 0x1c04c, | ||
1400 | .clkr = { | ||
1401 | .enable_reg = 0x1c04c, | ||
1402 | .enable_mask = BIT(0), | ||
1403 | .hw.init = &(struct clk_init_data){ | ||
1404 | .name = "gcc_ultaudio_avsync_xo_clk", | ||
1405 | .parent_names = (const char *[]){ | ||
1406 | "ultaudio_xo_clk_src", | ||
1407 | }, | ||
1408 | .num_parents = 1, | ||
1409 | .flags = CLK_SET_RATE_PARENT, | ||
1410 | .ops = &clk_branch2_ops, | ||
1411 | }, | ||
1412 | }, | ||
1413 | }; | ||
1414 | |||
1415 | static struct clk_branch gcc_ultaudio_stc_xo_clk = { | ||
1416 | .halt_reg = 0x1c050, | ||
1417 | .clkr = { | ||
1418 | .enable_reg = 0x1c050, | ||
1419 | .enable_mask = BIT(0), | ||
1420 | .hw.init = &(struct clk_init_data){ | ||
1421 | .name = "gcc_ultaudio_stc_xo_clk", | ||
1422 | .parent_names = (const char *[]){ | ||
1423 | "ultaudio_xo_clk_src", | ||
1424 | }, | ||
1425 | .num_parents = 1, | ||
1426 | .flags = CLK_SET_RATE_PARENT, | ||
1427 | .ops = &clk_branch2_ops, | ||
1428 | }, | ||
1429 | }, | ||
1430 | }; | ||
1431 | |||
1432 | static const struct freq_tbl ftbl_codec_clk[] = { | ||
1433 | F(19200000, P_XO, 1, 0, 0), | ||
1434 | F(11289600, P_EXT_MCLK, 1, 0, 0), | ||
1435 | { } | ||
1436 | }; | ||
1437 | |||
1438 | static struct clk_rcg2 codec_digcodec_clk_src = { | ||
1439 | .cmd_rcgr = 0x1c09c, | ||
1440 | .hid_width = 5, | ||
1441 | .parent_map = gcc_xo_gpll1_emclk_sleep_map, | ||
1442 | .freq_tbl = ftbl_codec_clk, | ||
1443 | .clkr.hw.init = &(struct clk_init_data){ | ||
1444 | .name = "codec_digcodec_clk_src", | ||
1445 | .parent_names = gcc_xo_gpll1_emclk_sleep, | ||
1446 | .num_parents = 4, | ||
1447 | .ops = &clk_rcg2_ops, | ||
1448 | }, | ||
1449 | }; | ||
1450 | |||
1451 | static struct clk_branch gcc_codec_digcodec_clk = { | ||
1452 | .halt_reg = 0x1c0b0, | ||
1453 | .clkr = { | ||
1454 | .enable_reg = 0x1c0b0, | ||
1455 | .enable_mask = BIT(0), | ||
1456 | .hw.init = &(struct clk_init_data){ | ||
1457 | .name = "gcc_ultaudio_codec_digcodec_clk", | ||
1458 | .parent_names = (const char *[]){ | ||
1459 | "codec_digcodec_clk_src", | ||
1460 | }, | ||
1461 | .num_parents = 1, | ||
1462 | .flags = CLK_SET_RATE_PARENT, | ||
1463 | .ops = &clk_branch2_ops, | ||
1464 | }, | ||
1465 | }, | ||
1466 | }; | ||
1467 | |||
1468 | static struct clk_branch gcc_ultaudio_pcnoc_mport_clk = { | ||
1469 | .halt_reg = 0x1c000, | ||
1470 | .clkr = { | ||
1471 | .enable_reg = 0x1c000, | ||
1472 | .enable_mask = BIT(0), | ||
1473 | .hw.init = &(struct clk_init_data){ | ||
1474 | .name = "gcc_ultaudio_pcnoc_mport_clk", | ||
1475 | .parent_names = (const char *[]){ | ||
1476 | "pcnoc_bfdcd_clk_src", | ||
1477 | }, | ||
1478 | .num_parents = 1, | ||
1479 | .ops = &clk_branch2_ops, | ||
1480 | }, | ||
1481 | }, | ||
1482 | }; | ||
1483 | |||
1484 | static struct clk_branch gcc_ultaudio_pcnoc_sway_clk = { | ||
1485 | .halt_reg = 0x1c004, | ||
1486 | .clkr = { | ||
1487 | .enable_reg = 0x1c004, | ||
1488 | .enable_mask = BIT(0), | ||
1489 | .hw.init = &(struct clk_init_data){ | ||
1490 | .name = "gcc_ultaudio_pcnoc_sway_clk", | ||
1491 | .parent_names = (const char *[]){ | ||
1492 | "pcnoc_bfdcd_clk_src", | ||
1493 | }, | ||
1494 | .num_parents = 1, | ||
1495 | .ops = &clk_branch2_ops, | ||
1496 | }, | ||
1497 | }, | ||
1498 | }; | ||
1499 | |||
1115 | static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = { | 1500 | static const struct freq_tbl ftbl_gcc_venus0_vcodec0_clk[] = { |
1116 | F(100000000, P_GPLL0, 8, 0, 0), | 1501 | F(100000000, P_GPLL0, 8, 0, 0), |
1117 | F(160000000, P_GPLL0, 5, 0, 0), | 1502 | F(160000000, P_GPLL0, 5, 0, 0), |
@@ -2358,6 +2743,51 @@ static struct clk_branch gcc_sdcc2_apps_clk = { | |||
2358 | }, | 2743 | }, |
2359 | }; | 2744 | }; |
2360 | 2745 | ||
2746 | static struct clk_rcg2 bimc_ddr_clk_src = { | ||
2747 | .cmd_rcgr = 0x32004, | ||
2748 | .hid_width = 5, | ||
2749 | .parent_map = gcc_xo_gpll0_bimc_map, | ||
2750 | .clkr.hw.init = &(struct clk_init_data){ | ||
2751 | .name = "bimc_ddr_clk_src", | ||
2752 | .parent_names = gcc_xo_gpll0_bimc, | ||
2753 | .num_parents = 3, | ||
2754 | .ops = &clk_rcg2_ops, | ||
2755 | .flags = CLK_GET_RATE_NOCACHE, | ||
2756 | }, | ||
2757 | }; | ||
2758 | |||
2759 | static struct clk_branch gcc_apss_tcu_clk = { | ||
2760 | .halt_reg = 0x12018, | ||
2761 | .clkr = { | ||
2762 | .enable_reg = 0x4500c, | ||
2763 | .enable_mask = BIT(1), | ||
2764 | .hw.init = &(struct clk_init_data){ | ||
2765 | .name = "gcc_apss_tcu_clk", | ||
2766 | .parent_names = (const char *[]){ | ||
2767 | "bimc_ddr_clk_src", | ||
2768 | }, | ||
2769 | .num_parents = 1, | ||
2770 | .ops = &clk_branch2_ops, | ||
2771 | }, | ||
2772 | }, | ||
2773 | }; | ||
2774 | |||
2775 | static struct clk_branch gcc_gfx_tcu_clk = { | ||
2776 | .halt_reg = 0x12020, | ||
2777 | .clkr = { | ||
2778 | .enable_reg = 0x4500c, | ||
2779 | .enable_mask = BIT(2), | ||
2780 | .hw.init = &(struct clk_init_data){ | ||
2781 | .name = "gcc_gfx_tcu_clk", | ||
2782 | .parent_names = (const char *[]){ | ||
2783 | "bimc_ddr_clk_src", | ||
2784 | }, | ||
2785 | .num_parents = 1, | ||
2786 | .ops = &clk_branch2_ops, | ||
2787 | }, | ||
2788 | }, | ||
2789 | }; | ||
2790 | |||
2361 | static struct clk_branch gcc_gtcu_ahb_clk = { | 2791 | static struct clk_branch gcc_gtcu_ahb_clk = { |
2362 | .halt_reg = 0x12044, | 2792 | .halt_reg = 0x12044, |
2363 | .clkr = { | 2793 | .clkr = { |
@@ -2375,6 +2805,40 @@ static struct clk_branch gcc_gtcu_ahb_clk = { | |||
2375 | }, | 2805 | }, |
2376 | }; | 2806 | }; |
2377 | 2807 | ||
2808 | static struct clk_branch gcc_bimc_gfx_clk = { | ||
2809 | .halt_reg = 0x31024, | ||
2810 | .clkr = { | ||
2811 | .enable_reg = 0x31024, | ||
2812 | .enable_mask = BIT(0), | ||
2813 | .hw.init = &(struct clk_init_data){ | ||
2814 | .name = "gcc_bimc_gfx_clk", | ||
2815 | .parent_names = (const char *[]){ | ||
2816 | "bimc_gpu_clk_src", | ||
2817 | }, | ||
2818 | .num_parents = 1, | ||
2819 | .flags = CLK_SET_RATE_PARENT, | ||
2820 | .ops = &clk_branch2_ops, | ||
2821 | }, | ||
2822 | }, | ||
2823 | }; | ||
2824 | |||
2825 | static struct clk_branch gcc_bimc_gpu_clk = { | ||
2826 | .halt_reg = 0x31040, | ||
2827 | .clkr = { | ||
2828 | .enable_reg = 0x31040, | ||
2829 | .enable_mask = BIT(0), | ||
2830 | .hw.init = &(struct clk_init_data){ | ||
2831 | .name = "gcc_bimc_gpu_clk", | ||
2832 | .parent_names = (const char *[]){ | ||
2833 | "bimc_gpu_clk_src", | ||
2834 | }, | ||
2835 | .num_parents = 1, | ||
2836 | .flags = CLK_SET_RATE_PARENT, | ||
2837 | .ops = &clk_branch2_ops, | ||
2838 | }, | ||
2839 | }, | ||
2840 | }; | ||
2841 | |||
2378 | static struct clk_branch gcc_jpeg_tbu_clk = { | 2842 | static struct clk_branch gcc_jpeg_tbu_clk = { |
2379 | .halt_reg = 0x12034, | 2843 | .halt_reg = 0x12034, |
2380 | .clkr = { | 2844 | .clkr = { |
@@ -2562,6 +3026,46 @@ static struct clk_branch gcc_venus0_vcodec0_clk = { | |||
2562 | }, | 3026 | }, |
2563 | }; | 3027 | }; |
2564 | 3028 | ||
3029 | static struct gdsc venus_gdsc = { | ||
3030 | .gdscr = 0x4c018, | ||
3031 | .pd = { | ||
3032 | .name = "venus", | ||
3033 | }, | ||
3034 | .pwrsts = PWRSTS_OFF_ON, | ||
3035 | }; | ||
3036 | |||
3037 | static struct gdsc mdss_gdsc = { | ||
3038 | .gdscr = 0x4d078, | ||
3039 | .pd = { | ||
3040 | .name = "mdss", | ||
3041 | }, | ||
3042 | .pwrsts = PWRSTS_OFF_ON, | ||
3043 | }; | ||
3044 | |||
3045 | static struct gdsc jpeg_gdsc = { | ||
3046 | .gdscr = 0x5701c, | ||
3047 | .pd = { | ||
3048 | .name = "jpeg", | ||
3049 | }, | ||
3050 | .pwrsts = PWRSTS_OFF_ON, | ||
3051 | }; | ||
3052 | |||
3053 | static struct gdsc vfe_gdsc = { | ||
3054 | .gdscr = 0x58034, | ||
3055 | .pd = { | ||
3056 | .name = "vfe", | ||
3057 | }, | ||
3058 | .pwrsts = PWRSTS_OFF_ON, | ||
3059 | }; | ||
3060 | |||
3061 | static struct gdsc oxili_gdsc = { | ||
3062 | .gdscr = 0x5901c, | ||
3063 | .pd = { | ||
3064 | .name = "oxili", | ||
3065 | }, | ||
3066 | .pwrsts = PWRSTS_OFF_ON, | ||
3067 | }; | ||
3068 | |||
2565 | static struct clk_regmap *gcc_msm8916_clocks[] = { | 3069 | static struct clk_regmap *gcc_msm8916_clocks[] = { |
2566 | [GPLL0] = &gpll0.clkr, | 3070 | [GPLL0] = &gpll0.clkr, |
2567 | [GPLL0_VOTE] = &gpll0_vote, | 3071 | [GPLL0_VOTE] = &gpll0_vote, |
@@ -2701,6 +3205,36 @@ static struct clk_regmap *gcc_msm8916_clocks[] = { | |||
2701 | [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr, | 3205 | [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr, |
2702 | [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr, | 3206 | [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr, |
2703 | [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, | 3207 | [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, |
3208 | [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr, | ||
3209 | [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, | ||
3210 | [GCC_GFX_TCU_CLK] = &gcc_gfx_tcu_clk.clkr, | ||
3211 | [BIMC_GPU_CLK_SRC] = &bimc_gpu_clk_src.clkr, | ||
3212 | [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, | ||
3213 | [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, | ||
3214 | [ULTAUDIO_AHBFABRIC_CLK_SRC] = &ultaudio_ahbfabric_clk_src.clkr, | ||
3215 | [ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC] = &ultaudio_lpaif_pri_i2s_clk_src.clkr, | ||
3216 | [ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC] = &ultaudio_lpaif_sec_i2s_clk_src.clkr, | ||
3217 | [ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC] = &ultaudio_lpaif_aux_i2s_clk_src.clkr, | ||
3218 | [ULTAUDIO_XO_CLK_SRC] = &ultaudio_xo_clk_src.clkr, | ||
3219 | [CODEC_DIGCODEC_CLK_SRC] = &codec_digcodec_clk_src.clkr, | ||
3220 | [GCC_ULTAUDIO_PCNOC_MPORT_CLK] = &gcc_ultaudio_pcnoc_mport_clk.clkr, | ||
3221 | [GCC_ULTAUDIO_PCNOC_SWAY_CLK] = &gcc_ultaudio_pcnoc_sway_clk.clkr, | ||
3222 | [GCC_ULTAUDIO_AVSYNC_XO_CLK] = &gcc_ultaudio_avsync_xo_clk.clkr, | ||
3223 | [GCC_ULTAUDIO_STC_XO_CLK] = &gcc_ultaudio_stc_xo_clk.clkr, | ||
3224 | [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_clk.clkr, | ||
3225 | [GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK] = &gcc_ultaudio_ahbfabric_ixfabric_lpm_clk.clkr, | ||
3226 | [GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK] = &gcc_ultaudio_lpaif_pri_i2s_clk.clkr, | ||
3227 | [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr, | ||
3228 | [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr, | ||
3229 | [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr, | ||
3230 | }; | ||
3231 | |||
3232 | static struct gdsc *gcc_msm8916_gdscs[] = { | ||
3233 | [VENUS_GDSC] = &venus_gdsc, | ||
3234 | [MDSS_GDSC] = &mdss_gdsc, | ||
3235 | [JPEG_GDSC] = &jpeg_gdsc, | ||
3236 | [VFE_GDSC] = &vfe_gdsc, | ||
3237 | [OXILI_GDSC] = &oxili_gdsc, | ||
2704 | }; | 3238 | }; |
2705 | 3239 | ||
2706 | static const struct qcom_reset_map gcc_msm8916_resets[] = { | 3240 | static const struct qcom_reset_map gcc_msm8916_resets[] = { |
@@ -2810,6 +3344,8 @@ static const struct qcom_cc_desc gcc_msm8916_desc = { | |||
2810 | .num_clks = ARRAY_SIZE(gcc_msm8916_clocks), | 3344 | .num_clks = ARRAY_SIZE(gcc_msm8916_clocks), |
2811 | .resets = gcc_msm8916_resets, | 3345 | .resets = gcc_msm8916_resets, |
2812 | .num_resets = ARRAY_SIZE(gcc_msm8916_resets), | 3346 | .num_resets = ARRAY_SIZE(gcc_msm8916_resets), |
3347 | .gdscs = gcc_msm8916_gdscs, | ||
3348 | .num_gdscs = ARRAY_SIZE(gcc_msm8916_gdscs), | ||
2813 | }; | 3349 | }; |
2814 | 3350 | ||
2815 | static const struct of_device_id gcc_msm8916_match_table[] = { | 3351 | static const struct of_device_id gcc_msm8916_match_table[] = { |
@@ -2836,15 +3372,8 @@ static int gcc_msm8916_probe(struct platform_device *pdev) | |||
2836 | return qcom_cc_probe(pdev, &gcc_msm8916_desc); | 3372 | return qcom_cc_probe(pdev, &gcc_msm8916_desc); |
2837 | } | 3373 | } |
2838 | 3374 | ||
2839 | static int gcc_msm8916_remove(struct platform_device *pdev) | ||
2840 | { | ||
2841 | qcom_cc_remove(pdev); | ||
2842 | return 0; | ||
2843 | } | ||
2844 | |||
2845 | static struct platform_driver gcc_msm8916_driver = { | 3375 | static struct platform_driver gcc_msm8916_driver = { |
2846 | .probe = gcc_msm8916_probe, | 3376 | .probe = gcc_msm8916_probe, |
2847 | .remove = gcc_msm8916_remove, | ||
2848 | .driver = { | 3377 | .driver = { |
2849 | .name = "gcc-msm8916", | 3378 | .name = "gcc-msm8916", |
2850 | .of_match_table = gcc_msm8916_match_table, | 3379 | .of_match_table = gcc_msm8916_match_table, |
diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index aa294b1bad34..66c18bc97857 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c | |||
@@ -3506,6 +3506,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev) | |||
3506 | struct clk *clk; | 3506 | struct clk *clk; |
3507 | struct device *dev = &pdev->dev; | 3507 | struct device *dev = &pdev->dev; |
3508 | const struct of_device_id *match; | 3508 | const struct of_device_id *match; |
3509 | struct platform_device *tsens; | ||
3510 | int ret; | ||
3509 | 3511 | ||
3510 | match = of_match_device(gcc_msm8960_match_table, &pdev->dev); | 3512 | match = of_match_device(gcc_msm8960_match_table, &pdev->dev); |
3511 | if (!match) | 3513 | if (!match) |
@@ -3520,12 +3522,26 @@ static int gcc_msm8960_probe(struct platform_device *pdev) | |||
3520 | if (IS_ERR(clk)) | 3522 | if (IS_ERR(clk)) |
3521 | return PTR_ERR(clk); | 3523 | return PTR_ERR(clk); |
3522 | 3524 | ||
3523 | return qcom_cc_probe(pdev, match->data); | 3525 | ret = qcom_cc_probe(pdev, match->data); |
3526 | if (ret) | ||
3527 | return ret; | ||
3528 | |||
3529 | tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1, | ||
3530 | NULL, 0); | ||
3531 | if (IS_ERR(tsens)) | ||
3532 | return PTR_ERR(tsens); | ||
3533 | |||
3534 | platform_set_drvdata(pdev, tsens); | ||
3535 | |||
3536 | return 0; | ||
3524 | } | 3537 | } |
3525 | 3538 | ||
3526 | static int gcc_msm8960_remove(struct platform_device *pdev) | 3539 | static int gcc_msm8960_remove(struct platform_device *pdev) |
3527 | { | 3540 | { |
3528 | qcom_cc_remove(pdev); | 3541 | struct platform_device *tsens = platform_get_drvdata(pdev); |
3542 | |||
3543 | platform_device_unregister(tsens); | ||
3544 | |||
3529 | return 0; | 3545 | return 0; |
3530 | } | 3546 | } |
3531 | 3547 | ||
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 2bcf87538f9d..28abb8f8f293 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
32 | #include "clk-branch.h" | 32 | #include "clk-branch.h" |
33 | #include "reset.h" | 33 | #include "reset.h" |
34 | #include "gdsc.h" | ||
34 | 35 | ||
35 | enum { | 36 | enum { |
36 | P_XO, | 37 | P_XO, |
@@ -2432,6 +2433,14 @@ static struct clk_branch gcc_usb_hsic_system_clk = { | |||
2432 | }, | 2433 | }, |
2433 | }; | 2434 | }; |
2434 | 2435 | ||
2436 | static struct gdsc usb_hs_hsic_gdsc = { | ||
2437 | .gdscr = 0x404, | ||
2438 | .pd = { | ||
2439 | .name = "usb_hs_hsic", | ||
2440 | }, | ||
2441 | .pwrsts = PWRSTS_OFF_ON, | ||
2442 | }; | ||
2443 | |||
2435 | static struct clk_regmap *gcc_msm8974_clocks[] = { | 2444 | static struct clk_regmap *gcc_msm8974_clocks[] = { |
2436 | [GPLL0] = &gpll0.clkr, | 2445 | [GPLL0] = &gpll0.clkr, |
2437 | [GPLL0_VOTE] = &gpll0_vote, | 2446 | [GPLL0_VOTE] = &gpll0_vote, |
@@ -2661,6 +2670,10 @@ static const struct qcom_reset_map gcc_msm8974_resets[] = { | |||
2661 | [GCC_VENUS_RESTART] = { 0x1740 }, | 2670 | [GCC_VENUS_RESTART] = { 0x1740 }, |
2662 | }; | 2671 | }; |
2663 | 2672 | ||
2673 | static struct gdsc *gcc_msm8974_gdscs[] = { | ||
2674 | [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc, | ||
2675 | }; | ||
2676 | |||
2664 | static const struct regmap_config gcc_msm8974_regmap_config = { | 2677 | static const struct regmap_config gcc_msm8974_regmap_config = { |
2665 | .reg_bits = 32, | 2678 | .reg_bits = 32, |
2666 | .reg_stride = 4, | 2679 | .reg_stride = 4, |
@@ -2675,6 +2688,8 @@ static const struct qcom_cc_desc gcc_msm8974_desc = { | |||
2675 | .num_clks = ARRAY_SIZE(gcc_msm8974_clocks), | 2688 | .num_clks = ARRAY_SIZE(gcc_msm8974_clocks), |
2676 | .resets = gcc_msm8974_resets, | 2689 | .resets = gcc_msm8974_resets, |
2677 | .num_resets = ARRAY_SIZE(gcc_msm8974_resets), | 2690 | .num_resets = ARRAY_SIZE(gcc_msm8974_resets), |
2691 | .gdscs = gcc_msm8974_gdscs, | ||
2692 | .num_gdscs = ARRAY_SIZE(gcc_msm8974_gdscs), | ||
2678 | }; | 2693 | }; |
2679 | 2694 | ||
2680 | static const struct of_device_id gcc_msm8974_match_table[] = { | 2695 | static const struct of_device_id gcc_msm8974_match_table[] = { |
@@ -2729,15 +2744,8 @@ static int gcc_msm8974_probe(struct platform_device *pdev) | |||
2729 | return qcom_cc_probe(pdev, &gcc_msm8974_desc); | 2744 | return qcom_cc_probe(pdev, &gcc_msm8974_desc); |
2730 | } | 2745 | } |
2731 | 2746 | ||
2732 | static int gcc_msm8974_remove(struct platform_device *pdev) | ||
2733 | { | ||
2734 | qcom_cc_remove(pdev); | ||
2735 | return 0; | ||
2736 | } | ||
2737 | |||
2738 | static struct platform_driver gcc_msm8974_driver = { | 2747 | static struct platform_driver gcc_msm8974_driver = { |
2739 | .probe = gcc_msm8974_probe, | 2748 | .probe = gcc_msm8974_probe, |
2740 | .remove = gcc_msm8974_remove, | ||
2741 | .driver = { | 2749 | .driver = { |
2742 | .name = "gcc-msm8974", | 2750 | .name = "gcc-msm8974", |
2743 | .of_match_table = gcc_msm8974_match_table, | 2751 | .of_match_table = gcc_msm8974_match_table, |
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c new file mode 100644 index 000000000000..da9fad8b642b --- /dev/null +++ b/drivers/clk/qcom/gdsc.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015, The Linux Foundation. All rights reserved. | ||
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 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/bitops.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/jiffies.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/pm_domain.h> | ||
20 | #include <linux/regmap.h> | ||
21 | #include <linux/reset-controller.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include "gdsc.h" | ||
24 | |||
25 | #define PWR_ON_MASK BIT(31) | ||
26 | #define EN_REST_WAIT_MASK GENMASK_ULL(23, 20) | ||
27 | #define EN_FEW_WAIT_MASK GENMASK_ULL(19, 16) | ||
28 | #define CLK_DIS_WAIT_MASK GENMASK_ULL(15, 12) | ||
29 | #define SW_OVERRIDE_MASK BIT(2) | ||
30 | #define HW_CONTROL_MASK BIT(1) | ||
31 | #define SW_COLLAPSE_MASK BIT(0) | ||
32 | |||
33 | /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ | ||
34 | #define EN_REST_WAIT_VAL (0x2 << 20) | ||
35 | #define EN_FEW_WAIT_VAL (0x8 << 16) | ||
36 | #define CLK_DIS_WAIT_VAL (0x2 << 12) | ||
37 | |||
38 | #define RETAIN_MEM BIT(14) | ||
39 | #define RETAIN_PERIPH BIT(13) | ||
40 | |||
41 | #define TIMEOUT_US 100 | ||
42 | |||
43 | #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd) | ||
44 | |||
45 | static int gdsc_is_enabled(struct gdsc *sc) | ||
46 | { | ||
47 | u32 val; | ||
48 | int ret; | ||
49 | |||
50 | ret = regmap_read(sc->regmap, sc->gdscr, &val); | ||
51 | if (ret) | ||
52 | return ret; | ||
53 | |||
54 | return !!(val & PWR_ON_MASK); | ||
55 | } | ||
56 | |||
57 | static int gdsc_toggle_logic(struct gdsc *sc, bool en) | ||
58 | { | ||
59 | int ret; | ||
60 | u32 val = en ? 0 : SW_COLLAPSE_MASK; | ||
61 | u32 check = en ? PWR_ON_MASK : 0; | ||
62 | unsigned long timeout; | ||
63 | |||
64 | ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); | ||
65 | if (ret) | ||
66 | return ret; | ||
67 | |||
68 | timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); | ||
69 | do { | ||
70 | ret = regmap_read(sc->regmap, sc->gdscr, &val); | ||
71 | if (ret) | ||
72 | return ret; | ||
73 | |||
74 | if ((val & PWR_ON_MASK) == check) | ||
75 | return 0; | ||
76 | } while (time_before(jiffies, timeout)); | ||
77 | |||
78 | ret = regmap_read(sc->regmap, sc->gdscr, &val); | ||
79 | if (ret) | ||
80 | return ret; | ||
81 | |||
82 | if ((val & PWR_ON_MASK) == check) | ||
83 | return 0; | ||
84 | |||
85 | return -ETIMEDOUT; | ||
86 | } | ||
87 | |||
88 | static inline int gdsc_deassert_reset(struct gdsc *sc) | ||
89 | { | ||
90 | int i; | ||
91 | |||
92 | for (i = 0; i < sc->reset_count; i++) | ||
93 | sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static inline int gdsc_assert_reset(struct gdsc *sc) | ||
98 | { | ||
99 | int i; | ||
100 | |||
101 | for (i = 0; i < sc->reset_count; i++) | ||
102 | sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]); | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static inline void gdsc_force_mem_on(struct gdsc *sc) | ||
107 | { | ||
108 | int i; | ||
109 | u32 mask = RETAIN_MEM | RETAIN_PERIPH; | ||
110 | |||
111 | for (i = 0; i < sc->cxc_count; i++) | ||
112 | regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask); | ||
113 | } | ||
114 | |||
115 | static inline void gdsc_clear_mem_on(struct gdsc *sc) | ||
116 | { | ||
117 | int i; | ||
118 | u32 mask = RETAIN_MEM | RETAIN_PERIPH; | ||
119 | |||
120 | for (i = 0; i < sc->cxc_count; i++) | ||
121 | regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0); | ||
122 | } | ||
123 | |||
124 | static int gdsc_enable(struct generic_pm_domain *domain) | ||
125 | { | ||
126 | struct gdsc *sc = domain_to_gdsc(domain); | ||
127 | int ret; | ||
128 | |||
129 | if (sc->pwrsts == PWRSTS_ON) | ||
130 | return gdsc_deassert_reset(sc); | ||
131 | |||
132 | ret = gdsc_toggle_logic(sc, true); | ||
133 | if (ret) | ||
134 | return ret; | ||
135 | |||
136 | if (sc->pwrsts & PWRSTS_OFF) | ||
137 | gdsc_force_mem_on(sc); | ||
138 | |||
139 | /* | ||
140 | * If clocks to this power domain were already on, they will take an | ||
141 | * additional 4 clock cycles to re-enable after the power domain is | ||
142 | * enabled. Delay to account for this. A delay is also needed to ensure | ||
143 | * clocks are not enabled within 400ns of enabling power to the | ||
144 | * memories. | ||
145 | */ | ||
146 | udelay(1); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int gdsc_disable(struct generic_pm_domain *domain) | ||
152 | { | ||
153 | struct gdsc *sc = domain_to_gdsc(domain); | ||
154 | |||
155 | if (sc->pwrsts == PWRSTS_ON) | ||
156 | return gdsc_assert_reset(sc); | ||
157 | |||
158 | if (sc->pwrsts & PWRSTS_OFF) | ||
159 | gdsc_clear_mem_on(sc); | ||
160 | |||
161 | return gdsc_toggle_logic(sc, false); | ||
162 | } | ||
163 | |||
164 | static int gdsc_init(struct gdsc *sc) | ||
165 | { | ||
166 | u32 mask, val; | ||
167 | int on, ret; | ||
168 | |||
169 | /* | ||
170 | * Disable HW trigger: collapse/restore occur based on registers writes. | ||
171 | * Disable SW override: Use hardware state-machine for sequencing. | ||
172 | * Configure wait time between states. | ||
173 | */ | ||
174 | mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK | | ||
175 | EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK; | ||
176 | val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; | ||
177 | ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val); | ||
178 | if (ret) | ||
179 | return ret; | ||
180 | |||
181 | /* Force gdsc ON if only ON state is supported */ | ||
182 | if (sc->pwrsts == PWRSTS_ON) { | ||
183 | ret = gdsc_toggle_logic(sc, true); | ||
184 | if (ret) | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | on = gdsc_is_enabled(sc); | ||
189 | if (on < 0) | ||
190 | return on; | ||
191 | |||
192 | if (on || (sc->pwrsts & PWRSTS_RET)) | ||
193 | gdsc_force_mem_on(sc); | ||
194 | else | ||
195 | gdsc_clear_mem_on(sc); | ||
196 | |||
197 | sc->pd.power_off = gdsc_disable; | ||
198 | sc->pd.power_on = gdsc_enable; | ||
199 | pm_genpd_init(&sc->pd, NULL, !on); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, | ||
205 | struct reset_controller_dev *rcdev, struct regmap *regmap) | ||
206 | { | ||
207 | int i, ret; | ||
208 | struct genpd_onecell_data *data; | ||
209 | |||
210 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | ||
211 | if (!data) | ||
212 | return -ENOMEM; | ||
213 | |||
214 | data->domains = devm_kcalloc(dev, num, sizeof(*data->domains), | ||
215 | GFP_KERNEL); | ||
216 | if (!data->domains) | ||
217 | return -ENOMEM; | ||
218 | |||
219 | data->num_domains = num; | ||
220 | for (i = 0; i < num; i++) { | ||
221 | if (!scs[i]) | ||
222 | continue; | ||
223 | scs[i]->regmap = regmap; | ||
224 | scs[i]->rcdev = rcdev; | ||
225 | ret = gdsc_init(scs[i]); | ||
226 | if (ret) | ||
227 | return ret; | ||
228 | data->domains[i] = &scs[i]->pd; | ||
229 | } | ||
230 | |||
231 | return of_genpd_add_provider_onecell(dev->of_node, data); | ||
232 | } | ||
233 | |||
234 | void gdsc_unregister(struct device *dev) | ||
235 | { | ||
236 | of_genpd_del_provider(dev->of_node); | ||
237 | } | ||
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h new file mode 100644 index 000000000000..5ded26884f08 --- /dev/null +++ b/drivers/clk/qcom/gdsc.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015, The Linux Foundation. All rights reserved. | ||
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 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef __QCOM_GDSC_H__ | ||
15 | #define __QCOM_GDSC_H__ | ||
16 | |||
17 | #include <linux/err.h> | ||
18 | #include <linux/pm_domain.h> | ||
19 | |||
20 | struct regmap; | ||
21 | struct reset_controller_dev; | ||
22 | |||
23 | /* Powerdomain allowable state bitfields */ | ||
24 | #define PWRSTS_OFF BIT(0) | ||
25 | #define PWRSTS_RET BIT(1) | ||
26 | #define PWRSTS_ON BIT(2) | ||
27 | #define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) | ||
28 | #define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) | ||
29 | |||
30 | /** | ||
31 | * struct gdsc - Globally Distributed Switch Controller | ||
32 | * @pd: generic power domain | ||
33 | * @regmap: regmap for MMIO accesses | ||
34 | * @gdscr: gsdc control register | ||
35 | * @cxcs: offsets of branch registers to toggle mem/periph bits in | ||
36 | * @cxc_count: number of @cxcs | ||
37 | * @pwrsts: Possible powerdomain power states | ||
38 | * @resets: ids of resets associated with this gdsc | ||
39 | * @reset_count: number of @resets | ||
40 | * @rcdev: reset controller | ||
41 | */ | ||
42 | struct gdsc { | ||
43 | struct generic_pm_domain pd; | ||
44 | struct regmap *regmap; | ||
45 | unsigned int gdscr; | ||
46 | unsigned int *cxcs; | ||
47 | unsigned int cxc_count; | ||
48 | const u8 pwrsts; | ||
49 | struct reset_controller_dev *rcdev; | ||
50 | unsigned int *resets; | ||
51 | unsigned int reset_count; | ||
52 | }; | ||
53 | |||
54 | #ifdef CONFIG_QCOM_GDSC | ||
55 | int gdsc_register(struct device *, struct gdsc **, size_t n, | ||
56 | struct reset_controller_dev *, struct regmap *); | ||
57 | void gdsc_unregister(struct device *); | ||
58 | #else | ||
59 | static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n, | ||
60 | struct reset_controller_dev *rcdev, | ||
61 | struct regmap *r) | ||
62 | { | ||
63 | return -ENOSYS; | ||
64 | } | ||
65 | |||
66 | static inline void gdsc_unregister(struct device *d) {}; | ||
67 | #endif /* CONFIG_QCOM_GDSC */ | ||
68 | #endif /* __QCOM_GDSC_H__ */ | ||
diff --git a/drivers/clk/qcom/lcc-ipq806x.c b/drivers/clk/qcom/lcc-ipq806x.c index 93ad42b14366..db3998e5e2d8 100644 --- a/drivers/clk/qcom/lcc-ipq806x.c +++ b/drivers/clk/qcom/lcc-ipq806x.c | |||
@@ -452,15 +452,8 @@ static int lcc_ipq806x_probe(struct platform_device *pdev) | |||
452 | return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap); | 452 | return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap); |
453 | } | 453 | } |
454 | 454 | ||
455 | static int lcc_ipq806x_remove(struct platform_device *pdev) | ||
456 | { | ||
457 | qcom_cc_remove(pdev); | ||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | static struct platform_driver lcc_ipq806x_driver = { | 455 | static struct platform_driver lcc_ipq806x_driver = { |
462 | .probe = lcc_ipq806x_probe, | 456 | .probe = lcc_ipq806x_probe, |
463 | .remove = lcc_ipq806x_remove, | ||
464 | .driver = { | 457 | .driver = { |
465 | .name = "lcc-ipq806x", | 458 | .name = "lcc-ipq806x", |
466 | .of_match_table = lcc_ipq806x_match_table, | 459 | .of_match_table = lcc_ipq806x_match_table, |
diff --git a/drivers/clk/qcom/lcc-msm8960.c b/drivers/clk/qcom/lcc-msm8960.c index ecb96c284675..4fcf9d1d233c 100644 --- a/drivers/clk/qcom/lcc-msm8960.c +++ b/drivers/clk/qcom/lcc-msm8960.c | |||
@@ -565,15 +565,8 @@ static int lcc_msm8960_probe(struct platform_device *pdev) | |||
565 | return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap); | 565 | return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap); |
566 | } | 566 | } |
567 | 567 | ||
568 | static int lcc_msm8960_remove(struct platform_device *pdev) | ||
569 | { | ||
570 | qcom_cc_remove(pdev); | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static struct platform_driver lcc_msm8960_driver = { | 568 | static struct platform_driver lcc_msm8960_driver = { |
575 | .probe = lcc_msm8960_probe, | 569 | .probe = lcc_msm8960_probe, |
576 | .remove = lcc_msm8960_remove, | ||
577 | .driver = { | 570 | .driver = { |
578 | .name = "lcc-msm8960", | 571 | .name = "lcc-msm8960", |
579 | .of_match_table = lcc_msm8960_match_table, | 572 | .of_match_table = lcc_msm8960_match_table, |
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c index f0ee6bde11af..30777f9f1a43 100644 --- a/drivers/clk/qcom/mmcc-apq8084.c +++ b/drivers/clk/qcom/mmcc-apq8084.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. | 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. |
3 | * | 3 | * |
4 | * This software is licensed under the terms of the GNU General Public | 4 | * This software is licensed under the terms of the GNU General Public |
5 | * License version 2, as published by the Free Software Foundation, and | 5 | * License version 2, as published by the Free Software Foundation, and |
@@ -26,6 +26,7 @@ | |||
26 | #include "clk-rcg.h" | 26 | #include "clk-rcg.h" |
27 | #include "clk-branch.h" | 27 | #include "clk-branch.h" |
28 | #include "reset.h" | 28 | #include "reset.h" |
29 | #include "gdsc.h" | ||
29 | 30 | ||
30 | enum { | 31 | enum { |
31 | P_XO, | 32 | P_XO, |
@@ -571,17 +572,11 @@ static struct clk_rcg2 jpeg2_clk_src = { | |||
571 | }, | 572 | }, |
572 | }; | 573 | }; |
573 | 574 | ||
574 | static struct freq_tbl pixel_freq_tbl[] = { | ||
575 | { .src = P_DSI0PLL }, | ||
576 | { } | ||
577 | }; | ||
578 | |||
579 | static struct clk_rcg2 pclk0_clk_src = { | 575 | static struct clk_rcg2 pclk0_clk_src = { |
580 | .cmd_rcgr = 0x2000, | 576 | .cmd_rcgr = 0x2000, |
581 | .mnd_width = 8, | 577 | .mnd_width = 8, |
582 | .hid_width = 5, | 578 | .hid_width = 5, |
583 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, | 579 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, |
584 | .freq_tbl = pixel_freq_tbl, | ||
585 | .clkr.hw.init = &(struct clk_init_data){ | 580 | .clkr.hw.init = &(struct clk_init_data){ |
586 | .name = "pclk0_clk_src", | 581 | .name = "pclk0_clk_src", |
587 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, | 582 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, |
@@ -596,7 +591,6 @@ static struct clk_rcg2 pclk1_clk_src = { | |||
596 | .mnd_width = 8, | 591 | .mnd_width = 8, |
597 | .hid_width = 5, | 592 | .hid_width = 5, |
598 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, | 593 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, |
599 | .freq_tbl = pixel_freq_tbl, | ||
600 | .clkr.hw.init = &(struct clk_init_data){ | 594 | .clkr.hw.init = &(struct clk_init_data){ |
601 | .name = "pclk1_clk_src", | 595 | .name = "pclk1_clk_src", |
602 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, | 596 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, |
@@ -844,21 +838,15 @@ static struct clk_rcg2 cpp_clk_src = { | |||
844 | }, | 838 | }, |
845 | }; | 839 | }; |
846 | 840 | ||
847 | static struct freq_tbl byte_freq_tbl[] = { | ||
848 | { .src = P_DSI0PLL_BYTE }, | ||
849 | { } | ||
850 | }; | ||
851 | |||
852 | static struct clk_rcg2 byte0_clk_src = { | 841 | static struct clk_rcg2 byte0_clk_src = { |
853 | .cmd_rcgr = 0x2120, | 842 | .cmd_rcgr = 0x2120, |
854 | .hid_width = 5, | 843 | .hid_width = 5, |
855 | .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, | 844 | .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, |
856 | .freq_tbl = byte_freq_tbl, | ||
857 | .clkr.hw.init = &(struct clk_init_data){ | 845 | .clkr.hw.init = &(struct clk_init_data){ |
858 | .name = "byte0_clk_src", | 846 | .name = "byte0_clk_src", |
859 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, | 847 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, |
860 | .num_parents = 6, | 848 | .num_parents = 6, |
861 | .ops = &clk_byte_ops, | 849 | .ops = &clk_byte2_ops, |
862 | .flags = CLK_SET_RATE_PARENT, | 850 | .flags = CLK_SET_RATE_PARENT, |
863 | }, | 851 | }, |
864 | }; | 852 | }; |
@@ -867,12 +855,11 @@ static struct clk_rcg2 byte1_clk_src = { | |||
867 | .cmd_rcgr = 0x2140, | 855 | .cmd_rcgr = 0x2140, |
868 | .hid_width = 5, | 856 | .hid_width = 5, |
869 | .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, | 857 | .parent_map = mmcc_xo_dsibyte_hdmi_edp_gpll0_map, |
870 | .freq_tbl = byte_freq_tbl, | ||
871 | .clkr.hw.init = &(struct clk_init_data){ | 858 | .clkr.hw.init = &(struct clk_init_data){ |
872 | .name = "byte1_clk_src", | 859 | .name = "byte1_clk_src", |
873 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, | 860 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, |
874 | .num_parents = 6, | 861 | .num_parents = 6, |
875 | .ops = &clk_byte_ops, | 862 | .ops = &clk_byte2_ops, |
876 | .flags = CLK_SET_RATE_PARENT, | 863 | .flags = CLK_SET_RATE_PARENT, |
877 | }, | 864 | }, |
878 | }; | 865 | }; |
@@ -3077,6 +3064,76 @@ static const struct pll_config mmpll3_config = { | |||
3077 | .aux_output_mask = BIT(1), | 3064 | .aux_output_mask = BIT(1), |
3078 | }; | 3065 | }; |
3079 | 3066 | ||
3067 | static struct gdsc venus0_gdsc = { | ||
3068 | .gdscr = 0x1024, | ||
3069 | .pd = { | ||
3070 | .name = "venus0", | ||
3071 | }, | ||
3072 | .pwrsts = PWRSTS_OFF_ON, | ||
3073 | }; | ||
3074 | |||
3075 | static struct gdsc venus0_core0_gdsc = { | ||
3076 | .gdscr = 0x1040, | ||
3077 | .pd = { | ||
3078 | .name = "venus0_core0", | ||
3079 | }, | ||
3080 | .pwrsts = PWRSTS_OFF_ON, | ||
3081 | }; | ||
3082 | |||
3083 | static struct gdsc venus0_core1_gdsc = { | ||
3084 | .gdscr = 0x1044, | ||
3085 | .pd = { | ||
3086 | .name = "venus0_core1", | ||
3087 | }, | ||
3088 | .pwrsts = PWRSTS_OFF_ON, | ||
3089 | }; | ||
3090 | |||
3091 | static struct gdsc mdss_gdsc = { | ||
3092 | .gdscr = 0x2304, | ||
3093 | .cxcs = (unsigned int []){ 0x231c, 0x2320 }, | ||
3094 | .cxc_count = 2, | ||
3095 | .pd = { | ||
3096 | .name = "mdss", | ||
3097 | }, | ||
3098 | .pwrsts = PWRSTS_OFF_ON, | ||
3099 | }; | ||
3100 | |||
3101 | static struct gdsc camss_jpeg_gdsc = { | ||
3102 | .gdscr = 0x35a4, | ||
3103 | .pd = { | ||
3104 | .name = "camss_jpeg", | ||
3105 | }, | ||
3106 | .pwrsts = PWRSTS_OFF_ON, | ||
3107 | }; | ||
3108 | |||
3109 | static struct gdsc camss_vfe_gdsc = { | ||
3110 | .gdscr = 0x36a4, | ||
3111 | .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x36b0 }, | ||
3112 | .cxc_count = 3, | ||
3113 | .pd = { | ||
3114 | .name = "camss_vfe", | ||
3115 | }, | ||
3116 | .pwrsts = PWRSTS_OFF_ON, | ||
3117 | }; | ||
3118 | |||
3119 | static struct gdsc oxili_gdsc = { | ||
3120 | .gdscr = 0x4024, | ||
3121 | .cxcs = (unsigned int []){ 0x4028 }, | ||
3122 | .cxc_count = 1, | ||
3123 | .pd = { | ||
3124 | .name = "oxili", | ||
3125 | }, | ||
3126 | .pwrsts = PWRSTS_OFF_ON, | ||
3127 | }; | ||
3128 | |||
3129 | static struct gdsc oxilicx_gdsc = { | ||
3130 | .gdscr = 0x4034, | ||
3131 | .pd = { | ||
3132 | .name = "oxilicx", | ||
3133 | }, | ||
3134 | .pwrsts = PWRSTS_OFF_ON, | ||
3135 | }; | ||
3136 | |||
3080 | static struct clk_regmap *mmcc_apq8084_clocks[] = { | 3137 | static struct clk_regmap *mmcc_apq8084_clocks[] = { |
3081 | [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, | 3138 | [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, |
3082 | [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, | 3139 | [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, |
@@ -3294,6 +3351,17 @@ static const struct qcom_reset_map mmcc_apq8084_resets[] = { | |||
3294 | [MMSSNOCAXI_RESET] = { 0x5060 }, | 3351 | [MMSSNOCAXI_RESET] = { 0x5060 }, |
3295 | }; | 3352 | }; |
3296 | 3353 | ||
3354 | static struct gdsc *mmcc_apq8084_gdscs[] = { | ||
3355 | [VENUS0_GDSC] = &venus0_gdsc, | ||
3356 | [VENUS0_CORE0_GDSC] = &venus0_core0_gdsc, | ||
3357 | [VENUS0_CORE1_GDSC] = &venus0_core1_gdsc, | ||
3358 | [MDSS_GDSC] = &mdss_gdsc, | ||
3359 | [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc, | ||
3360 | [CAMSS_VFE_GDSC] = &camss_vfe_gdsc, | ||
3361 | [OXILI_GDSC] = &oxili_gdsc, | ||
3362 | [OXILICX_GDSC] = &oxilicx_gdsc, | ||
3363 | }; | ||
3364 | |||
3297 | static const struct regmap_config mmcc_apq8084_regmap_config = { | 3365 | static const struct regmap_config mmcc_apq8084_regmap_config = { |
3298 | .reg_bits = 32, | 3366 | .reg_bits = 32, |
3299 | .reg_stride = 4, | 3367 | .reg_stride = 4, |
@@ -3308,6 +3376,8 @@ static const struct qcom_cc_desc mmcc_apq8084_desc = { | |||
3308 | .num_clks = ARRAY_SIZE(mmcc_apq8084_clocks), | 3376 | .num_clks = ARRAY_SIZE(mmcc_apq8084_clocks), |
3309 | .resets = mmcc_apq8084_resets, | 3377 | .resets = mmcc_apq8084_resets, |
3310 | .num_resets = ARRAY_SIZE(mmcc_apq8084_resets), | 3378 | .num_resets = ARRAY_SIZE(mmcc_apq8084_resets), |
3379 | .gdscs = mmcc_apq8084_gdscs, | ||
3380 | .num_gdscs = ARRAY_SIZE(mmcc_apq8084_gdscs), | ||
3311 | }; | 3381 | }; |
3312 | 3382 | ||
3313 | static const struct of_device_id mmcc_apq8084_match_table[] = { | 3383 | static const struct of_device_id mmcc_apq8084_match_table[] = { |
@@ -3332,15 +3402,8 @@ static int mmcc_apq8084_probe(struct platform_device *pdev) | |||
3332 | return 0; | 3402 | return 0; |
3333 | } | 3403 | } |
3334 | 3404 | ||
3335 | static int mmcc_apq8084_remove(struct platform_device *pdev) | ||
3336 | { | ||
3337 | qcom_cc_remove(pdev); | ||
3338 | return 0; | ||
3339 | } | ||
3340 | |||
3341 | static struct platform_driver mmcc_apq8084_driver = { | 3405 | static struct platform_driver mmcc_apq8084_driver = { |
3342 | .probe = mmcc_apq8084_probe, | 3406 | .probe = mmcc_apq8084_probe, |
3343 | .remove = mmcc_apq8084_remove, | ||
3344 | .driver = { | 3407 | .driver = { |
3345 | .name = "mmcc-apq8084", | 3408 | .name = "mmcc-apq8084", |
3346 | .of_match_table = mmcc_apq8084_match_table, | 3409 | .of_match_table = mmcc_apq8084_match_table, |
diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index bad02aebf959..00e36192a1de 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c | |||
@@ -41,6 +41,10 @@ enum { | |||
41 | P_PLL3, | 41 | P_PLL3, |
42 | P_PLL15, | 42 | P_PLL15, |
43 | P_HDMI_PLL, | 43 | P_HDMI_PLL, |
44 | P_DSI1_PLL_DSICLK, | ||
45 | P_DSI2_PLL_DSICLK, | ||
46 | P_DSI1_PLL_BYTECLK, | ||
47 | P_DSI2_PLL_BYTECLK, | ||
44 | }; | 48 | }; |
45 | 49 | ||
46 | #define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n } | 50 | #define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n } |
@@ -85,6 +89,30 @@ static const char * const mmcc_pxo_pll8_pll2_pll3[] = { | |||
85 | "pll3", | 89 | "pll3", |
86 | }; | 90 | }; |
87 | 91 | ||
92 | static const struct parent_map mmcc_pxo_dsi2_dsi1_map[] = { | ||
93 | { P_PXO, 0 }, | ||
94 | { P_DSI2_PLL_DSICLK, 1 }, | ||
95 | { P_DSI1_PLL_DSICLK, 3 }, | ||
96 | }; | ||
97 | |||
98 | static const char * const mmcc_pxo_dsi2_dsi1[] = { | ||
99 | "pxo", | ||
100 | "dsi2pll", | ||
101 | "dsi1pll", | ||
102 | }; | ||
103 | |||
104 | static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = { | ||
105 | { P_PXO, 0 }, | ||
106 | { P_DSI1_PLL_BYTECLK, 1 }, | ||
107 | { P_DSI2_PLL_BYTECLK, 2 }, | ||
108 | }; | ||
109 | |||
110 | static const char * const mmcc_pxo_dsi1_dsi2_byte[] = { | ||
111 | "pxo", | ||
112 | "dsi1pllbyte", | ||
113 | "dsi2pllbyte", | ||
114 | }; | ||
115 | |||
88 | static struct clk_pll pll2 = { | 116 | static struct clk_pll pll2 = { |
89 | .l_reg = 0x320, | 117 | .l_reg = 0x320, |
90 | .m_reg = 0x324, | 118 | .m_reg = 0x324, |
@@ -2042,6 +2070,350 @@ static struct clk_branch dsi2_s_ahb_clk = { | |||
2042 | }, | 2070 | }, |
2043 | }; | 2071 | }; |
2044 | 2072 | ||
2073 | static struct clk_rcg dsi1_src = { | ||
2074 | .ns_reg = 0x0054, | ||
2075 | .md_reg = 0x0050, | ||
2076 | .mn = { | ||
2077 | .mnctr_en_bit = 5, | ||
2078 | .mnctr_reset_bit = 7, | ||
2079 | .mnctr_mode_shift = 6, | ||
2080 | .n_val_shift = 24, | ||
2081 | .m_val_shift = 8, | ||
2082 | .width = 8, | ||
2083 | }, | ||
2084 | .p = { | ||
2085 | .pre_div_shift = 14, | ||
2086 | .pre_div_width = 2, | ||
2087 | }, | ||
2088 | .s = { | ||
2089 | .src_sel_shift = 0, | ||
2090 | .parent_map = mmcc_pxo_dsi2_dsi1_map, | ||
2091 | }, | ||
2092 | .clkr = { | ||
2093 | .enable_reg = 0x004c, | ||
2094 | .enable_mask = BIT(2), | ||
2095 | .hw.init = &(struct clk_init_data){ | ||
2096 | .name = "dsi1_src", | ||
2097 | .parent_names = mmcc_pxo_dsi2_dsi1, | ||
2098 | .num_parents = 3, | ||
2099 | .ops = &clk_rcg_bypass2_ops, | ||
2100 | .flags = CLK_SET_RATE_PARENT, | ||
2101 | }, | ||
2102 | }, | ||
2103 | }; | ||
2104 | |||
2105 | static struct clk_branch dsi1_clk = { | ||
2106 | .halt_reg = 0x01d0, | ||
2107 | .halt_bit = 2, | ||
2108 | .clkr = { | ||
2109 | .enable_reg = 0x004c, | ||
2110 | .enable_mask = BIT(0), | ||
2111 | .hw.init = &(struct clk_init_data){ | ||
2112 | .name = "dsi1_clk", | ||
2113 | .parent_names = (const char *[]){ "dsi1_src" }, | ||
2114 | .num_parents = 1, | ||
2115 | .ops = &clk_branch_ops, | ||
2116 | .flags = CLK_SET_RATE_PARENT, | ||
2117 | }, | ||
2118 | }, | ||
2119 | }; | ||
2120 | |||
2121 | static struct clk_rcg dsi2_src = { | ||
2122 | .ns_reg = 0x012c, | ||
2123 | .md_reg = 0x00a8, | ||
2124 | .mn = { | ||
2125 | .mnctr_en_bit = 5, | ||
2126 | .mnctr_reset_bit = 7, | ||
2127 | .mnctr_mode_shift = 6, | ||
2128 | .n_val_shift = 24, | ||
2129 | .m_val_shift = 8, | ||
2130 | .width = 8, | ||
2131 | }, | ||
2132 | .p = { | ||
2133 | .pre_div_shift = 14, | ||
2134 | .pre_div_width = 2, | ||
2135 | }, | ||
2136 | .s = { | ||
2137 | .src_sel_shift = 0, | ||
2138 | .parent_map = mmcc_pxo_dsi2_dsi1_map, | ||
2139 | }, | ||
2140 | .clkr = { | ||
2141 | .enable_reg = 0x003c, | ||
2142 | .enable_mask = BIT(2), | ||
2143 | .hw.init = &(struct clk_init_data){ | ||
2144 | .name = "dsi2_src", | ||
2145 | .parent_names = mmcc_pxo_dsi2_dsi1, | ||
2146 | .num_parents = 3, | ||
2147 | .ops = &clk_rcg_bypass2_ops, | ||
2148 | .flags = CLK_SET_RATE_PARENT, | ||
2149 | }, | ||
2150 | }, | ||
2151 | }; | ||
2152 | |||
2153 | static struct clk_branch dsi2_clk = { | ||
2154 | .halt_reg = 0x01d0, | ||
2155 | .halt_bit = 20, | ||
2156 | .clkr = { | ||
2157 | .enable_reg = 0x003c, | ||
2158 | .enable_mask = BIT(0), | ||
2159 | .hw.init = &(struct clk_init_data){ | ||
2160 | .name = "dsi2_clk", | ||
2161 | .parent_names = (const char *[]){ "dsi2_src" }, | ||
2162 | .num_parents = 1, | ||
2163 | .ops = &clk_branch_ops, | ||
2164 | .flags = CLK_SET_RATE_PARENT, | ||
2165 | }, | ||
2166 | }, | ||
2167 | }; | ||
2168 | |||
2169 | static struct clk_rcg dsi1_byte_src = { | ||
2170 | .ns_reg = 0x00b0, | ||
2171 | .p = { | ||
2172 | .pre_div_shift = 12, | ||
2173 | .pre_div_width = 4, | ||
2174 | }, | ||
2175 | .s = { | ||
2176 | .src_sel_shift = 0, | ||
2177 | .parent_map = mmcc_pxo_dsi1_dsi2_byte_map, | ||
2178 | }, | ||
2179 | .clkr = { | ||
2180 | .enable_reg = 0x0090, | ||
2181 | .enable_mask = BIT(2), | ||
2182 | .hw.init = &(struct clk_init_data){ | ||
2183 | .name = "dsi1_byte_src", | ||
2184 | .parent_names = mmcc_pxo_dsi1_dsi2_byte, | ||
2185 | .num_parents = 3, | ||
2186 | .ops = &clk_rcg_bypass2_ops, | ||
2187 | .flags = CLK_SET_RATE_PARENT, | ||
2188 | }, | ||
2189 | }, | ||
2190 | }; | ||
2191 | |||
2192 | static struct clk_branch dsi1_byte_clk = { | ||
2193 | .halt_reg = 0x01cc, | ||
2194 | .halt_bit = 21, | ||
2195 | .clkr = { | ||
2196 | .enable_reg = 0x0090, | ||
2197 | .enable_mask = BIT(0), | ||
2198 | .hw.init = &(struct clk_init_data){ | ||
2199 | .name = "dsi1_byte_clk", | ||
2200 | .parent_names = (const char *[]){ "dsi1_byte_src" }, | ||
2201 | .num_parents = 1, | ||
2202 | .ops = &clk_branch_ops, | ||
2203 | .flags = CLK_SET_RATE_PARENT, | ||
2204 | }, | ||
2205 | }, | ||
2206 | }; | ||
2207 | |||
2208 | static struct clk_rcg dsi2_byte_src = { | ||
2209 | .ns_reg = 0x012c, | ||
2210 | .p = { | ||
2211 | .pre_div_shift = 12, | ||
2212 | .pre_div_width = 4, | ||
2213 | }, | ||
2214 | .s = { | ||
2215 | .src_sel_shift = 0, | ||
2216 | .parent_map = mmcc_pxo_dsi1_dsi2_byte_map, | ||
2217 | }, | ||
2218 | .clkr = { | ||
2219 | .enable_reg = 0x0130, | ||
2220 | .enable_mask = BIT(2), | ||
2221 | .hw.init = &(struct clk_init_data){ | ||
2222 | .name = "dsi2_byte_src", | ||
2223 | .parent_names = mmcc_pxo_dsi1_dsi2_byte, | ||
2224 | .num_parents = 3, | ||
2225 | .ops = &clk_rcg_bypass2_ops, | ||
2226 | .flags = CLK_SET_RATE_PARENT, | ||
2227 | }, | ||
2228 | }, | ||
2229 | }; | ||
2230 | |||
2231 | static struct clk_branch dsi2_byte_clk = { | ||
2232 | .halt_reg = 0x01cc, | ||
2233 | .halt_bit = 20, | ||
2234 | .clkr = { | ||
2235 | .enable_reg = 0x00b4, | ||
2236 | .enable_mask = BIT(0), | ||
2237 | .hw.init = &(struct clk_init_data){ | ||
2238 | .name = "dsi2_byte_clk", | ||
2239 | .parent_names = (const char *[]){ "dsi2_byte_src" }, | ||
2240 | .num_parents = 1, | ||
2241 | .ops = &clk_branch_ops, | ||
2242 | .flags = CLK_SET_RATE_PARENT, | ||
2243 | }, | ||
2244 | }, | ||
2245 | }; | ||
2246 | |||
2247 | static struct clk_rcg dsi1_esc_src = { | ||
2248 | .ns_reg = 0x0011c, | ||
2249 | .p = { | ||
2250 | .pre_div_shift = 12, | ||
2251 | .pre_div_width = 4, | ||
2252 | }, | ||
2253 | .s = { | ||
2254 | .src_sel_shift = 0, | ||
2255 | .parent_map = mmcc_pxo_dsi1_dsi2_byte_map, | ||
2256 | }, | ||
2257 | .clkr = { | ||
2258 | .enable_reg = 0x00cc, | ||
2259 | .enable_mask = BIT(2), | ||
2260 | .hw.init = &(struct clk_init_data){ | ||
2261 | .name = "dsi1_esc_src", | ||
2262 | .parent_names = mmcc_pxo_dsi1_dsi2_byte, | ||
2263 | .num_parents = 3, | ||
2264 | .ops = &clk_rcg_esc_ops, | ||
2265 | }, | ||
2266 | }, | ||
2267 | }; | ||
2268 | |||
2269 | static struct clk_branch dsi1_esc_clk = { | ||
2270 | .halt_reg = 0x01e8, | ||
2271 | .halt_bit = 1, | ||
2272 | .clkr = { | ||
2273 | .enable_reg = 0x00cc, | ||
2274 | .enable_mask = BIT(0), | ||
2275 | .hw.init = &(struct clk_init_data){ | ||
2276 | .name = "dsi1_esc_clk", | ||
2277 | .parent_names = (const char *[]){ "dsi1_esc_src" }, | ||
2278 | .num_parents = 1, | ||
2279 | .ops = &clk_branch_ops, | ||
2280 | .flags = CLK_SET_RATE_PARENT, | ||
2281 | }, | ||
2282 | }, | ||
2283 | }; | ||
2284 | |||
2285 | static struct clk_rcg dsi2_esc_src = { | ||
2286 | .ns_reg = 0x0150, | ||
2287 | .p = { | ||
2288 | .pre_div_shift = 12, | ||
2289 | .pre_div_width = 4, | ||
2290 | }, | ||
2291 | .s = { | ||
2292 | .src_sel_shift = 0, | ||
2293 | .parent_map = mmcc_pxo_dsi1_dsi2_byte_map, | ||
2294 | }, | ||
2295 | .clkr = { | ||
2296 | .enable_reg = 0x013c, | ||
2297 | .enable_mask = BIT(2), | ||
2298 | .hw.init = &(struct clk_init_data){ | ||
2299 | .name = "dsi2_esc_src", | ||
2300 | .parent_names = mmcc_pxo_dsi1_dsi2_byte, | ||
2301 | .num_parents = 3, | ||
2302 | .ops = &clk_rcg_esc_ops, | ||
2303 | }, | ||
2304 | }, | ||
2305 | }; | ||
2306 | |||
2307 | static struct clk_branch dsi2_esc_clk = { | ||
2308 | .halt_reg = 0x01e8, | ||
2309 | .halt_bit = 3, | ||
2310 | .clkr = { | ||
2311 | .enable_reg = 0x013c, | ||
2312 | .enable_mask = BIT(0), | ||
2313 | .hw.init = &(struct clk_init_data){ | ||
2314 | .name = "dsi2_esc_clk", | ||
2315 | .parent_names = (const char *[]){ "dsi2_esc_src" }, | ||
2316 | .num_parents = 1, | ||
2317 | .ops = &clk_branch_ops, | ||
2318 | .flags = CLK_SET_RATE_PARENT, | ||
2319 | }, | ||
2320 | }, | ||
2321 | }; | ||
2322 | |||
2323 | static struct clk_rcg dsi1_pixel_src = { | ||
2324 | .ns_reg = 0x0138, | ||
2325 | .md_reg = 0x0134, | ||
2326 | .mn = { | ||
2327 | .mnctr_en_bit = 5, | ||
2328 | .mnctr_reset_bit = 7, | ||
2329 | .mnctr_mode_shift = 6, | ||
2330 | .n_val_shift = 16, | ||
2331 | .m_val_shift = 8, | ||
2332 | .width = 8, | ||
2333 | }, | ||
2334 | .p = { | ||
2335 | .pre_div_shift = 12, | ||
2336 | .pre_div_width = 4, | ||
2337 | }, | ||
2338 | .s = { | ||
2339 | .src_sel_shift = 0, | ||
2340 | .parent_map = mmcc_pxo_dsi2_dsi1_map, | ||
2341 | }, | ||
2342 | .clkr = { | ||
2343 | .enable_reg = 0x0130, | ||
2344 | .enable_mask = BIT(2), | ||
2345 | .hw.init = &(struct clk_init_data){ | ||
2346 | .name = "dsi1_pixel_src", | ||
2347 | .parent_names = mmcc_pxo_dsi2_dsi1, | ||
2348 | .num_parents = 3, | ||
2349 | .ops = &clk_rcg_pixel_ops, | ||
2350 | }, | ||
2351 | }, | ||
2352 | }; | ||
2353 | |||
2354 | static struct clk_branch dsi1_pixel_clk = { | ||
2355 | .halt_reg = 0x01d0, | ||
2356 | .halt_bit = 6, | ||
2357 | .clkr = { | ||
2358 | .enable_reg = 0x0130, | ||
2359 | .enable_mask = BIT(0), | ||
2360 | .hw.init = &(struct clk_init_data){ | ||
2361 | .name = "mdp_pclk1_clk", | ||
2362 | .parent_names = (const char *[]){ "dsi1_pixel_src" }, | ||
2363 | .num_parents = 1, | ||
2364 | .ops = &clk_branch_ops, | ||
2365 | .flags = CLK_SET_RATE_PARENT, | ||
2366 | }, | ||
2367 | }, | ||
2368 | }; | ||
2369 | |||
2370 | static struct clk_rcg dsi2_pixel_src = { | ||
2371 | .ns_reg = 0x00e4, | ||
2372 | .md_reg = 0x00b8, | ||
2373 | .mn = { | ||
2374 | .mnctr_en_bit = 5, | ||
2375 | .mnctr_reset_bit = 7, | ||
2376 | .mnctr_mode_shift = 6, | ||
2377 | .n_val_shift = 16, | ||
2378 | .m_val_shift = 8, | ||
2379 | .width = 8, | ||
2380 | }, | ||
2381 | .p = { | ||
2382 | .pre_div_shift = 12, | ||
2383 | .pre_div_width = 4, | ||
2384 | }, | ||
2385 | .s = { | ||
2386 | .src_sel_shift = 0, | ||
2387 | .parent_map = mmcc_pxo_dsi2_dsi1_map, | ||
2388 | }, | ||
2389 | .clkr = { | ||
2390 | .enable_reg = 0x0094, | ||
2391 | .enable_mask = BIT(2), | ||
2392 | .hw.init = &(struct clk_init_data){ | ||
2393 | .name = "dsi2_pixel_src", | ||
2394 | .parent_names = mmcc_pxo_dsi2_dsi1, | ||
2395 | .num_parents = 3, | ||
2396 | .ops = &clk_rcg_pixel_ops, | ||
2397 | }, | ||
2398 | }, | ||
2399 | }; | ||
2400 | |||
2401 | static struct clk_branch dsi2_pixel_clk = { | ||
2402 | .halt_reg = 0x01d0, | ||
2403 | .halt_bit = 19, | ||
2404 | .clkr = { | ||
2405 | .enable_reg = 0x0094, | ||
2406 | .enable_mask = BIT(0), | ||
2407 | .hw.init = &(struct clk_init_data){ | ||
2408 | .name = "mdp_pclk2_clk", | ||
2409 | .parent_names = (const char *[]){ "dsi2_pixel_src" }, | ||
2410 | .num_parents = 1, | ||
2411 | .ops = &clk_branch_ops, | ||
2412 | .flags = CLK_SET_RATE_PARENT, | ||
2413 | }, | ||
2414 | }, | ||
2415 | }; | ||
2416 | |||
2045 | static struct clk_branch gfx2d0_ahb_clk = { | 2417 | static struct clk_branch gfx2d0_ahb_clk = { |
2046 | .hwcg_reg = 0x0038, | 2418 | .hwcg_reg = 0x0038, |
2047 | .hwcg_bit = 28, | 2419 | .hwcg_bit = 28, |
@@ -2325,6 +2697,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = { | |||
2325 | [CSI2_SRC] = &csi2_src.clkr, | 2697 | [CSI2_SRC] = &csi2_src.clkr, |
2326 | [CSI2_CLK] = &csi2_clk.clkr, | 2698 | [CSI2_CLK] = &csi2_clk.clkr, |
2327 | [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, | 2699 | [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, |
2700 | [DSI_SRC] = &dsi1_src.clkr, | ||
2701 | [DSI_CLK] = &dsi1_clk.clkr, | ||
2328 | [CSI_PIX_CLK] = &csi_pix_clk.clkr, | 2702 | [CSI_PIX_CLK] = &csi_pix_clk.clkr, |
2329 | [CSI_RDI_CLK] = &csi_rdi_clk.clkr, | 2703 | [CSI_RDI_CLK] = &csi_rdi_clk.clkr, |
2330 | [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, | 2704 | [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, |
@@ -2345,6 +2719,18 @@ static struct clk_regmap *mmcc_msm8960_clks[] = { | |||
2345 | [MDP_SRC] = &mdp_src.clkr, | 2719 | [MDP_SRC] = &mdp_src.clkr, |
2346 | [MDP_CLK] = &mdp_clk.clkr, | 2720 | [MDP_CLK] = &mdp_clk.clkr, |
2347 | [MDP_LUT_CLK] = &mdp_lut_clk.clkr, | 2721 | [MDP_LUT_CLK] = &mdp_lut_clk.clkr, |
2722 | [DSI2_PIXEL_SRC] = &dsi2_pixel_src.clkr, | ||
2723 | [DSI2_PIXEL_CLK] = &dsi2_pixel_clk.clkr, | ||
2724 | [DSI2_SRC] = &dsi2_src.clkr, | ||
2725 | [DSI2_CLK] = &dsi2_clk.clkr, | ||
2726 | [DSI1_BYTE_SRC] = &dsi1_byte_src.clkr, | ||
2727 | [DSI1_BYTE_CLK] = &dsi1_byte_clk.clkr, | ||
2728 | [DSI2_BYTE_SRC] = &dsi2_byte_src.clkr, | ||
2729 | [DSI2_BYTE_CLK] = &dsi2_byte_clk.clkr, | ||
2730 | [DSI1_ESC_SRC] = &dsi1_esc_src.clkr, | ||
2731 | [DSI1_ESC_CLK] = &dsi1_esc_clk.clkr, | ||
2732 | [DSI2_ESC_SRC] = &dsi2_esc_src.clkr, | ||
2733 | [DSI2_ESC_CLK] = &dsi2_esc_clk.clkr, | ||
2348 | [ROT_SRC] = &rot_src.clkr, | 2734 | [ROT_SRC] = &rot_src.clkr, |
2349 | [ROT_CLK] = &rot_clk.clkr, | 2735 | [ROT_CLK] = &rot_clk.clkr, |
2350 | [TV_ENC_CLK] = &tv_enc_clk.clkr, | 2736 | [TV_ENC_CLK] = &tv_enc_clk.clkr, |
@@ -2359,6 +2745,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = { | |||
2359 | [VFE_CSI_CLK] = &vfe_csi_clk.clkr, | 2745 | [VFE_CSI_CLK] = &vfe_csi_clk.clkr, |
2360 | [VPE_SRC] = &vpe_src.clkr, | 2746 | [VPE_SRC] = &vpe_src.clkr, |
2361 | [VPE_CLK] = &vpe_clk.clkr, | 2747 | [VPE_CLK] = &vpe_clk.clkr, |
2748 | [DSI_PIXEL_SRC] = &dsi1_pixel_src.clkr, | ||
2749 | [DSI_PIXEL_CLK] = &dsi1_pixel_clk.clkr, | ||
2362 | [CAMCLK0_SRC] = &camclk0_src.clkr, | 2750 | [CAMCLK0_SRC] = &camclk0_src.clkr, |
2363 | [CAMCLK0_CLK] = &camclk0_clk.clkr, | 2751 | [CAMCLK0_CLK] = &camclk0_clk.clkr, |
2364 | [CAMCLK1_SRC] = &camclk1_src.clkr, | 2752 | [CAMCLK1_SRC] = &camclk1_src.clkr, |
@@ -2490,6 +2878,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = { | |||
2490 | [CSI2_SRC] = &csi2_src.clkr, | 2878 | [CSI2_SRC] = &csi2_src.clkr, |
2491 | [CSI2_CLK] = &csi2_clk.clkr, | 2879 | [CSI2_CLK] = &csi2_clk.clkr, |
2492 | [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, | 2880 | [CSI2_PHY_CLK] = &csi2_phy_clk.clkr, |
2881 | [DSI_SRC] = &dsi1_src.clkr, | ||
2882 | [DSI_CLK] = &dsi1_clk.clkr, | ||
2493 | [CSI_PIX_CLK] = &csi_pix_clk.clkr, | 2883 | [CSI_PIX_CLK] = &csi_pix_clk.clkr, |
2494 | [CSI_RDI_CLK] = &csi_rdi_clk.clkr, | 2884 | [CSI_RDI_CLK] = &csi_rdi_clk.clkr, |
2495 | [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, | 2885 | [MDP_VSYNC_CLK] = &mdp_vsync_clk.clkr, |
@@ -2506,6 +2896,18 @@ static struct clk_regmap *mmcc_apq8064_clks[] = { | |||
2506 | [MDP_SRC] = &mdp_src.clkr, | 2896 | [MDP_SRC] = &mdp_src.clkr, |
2507 | [MDP_CLK] = &mdp_clk.clkr, | 2897 | [MDP_CLK] = &mdp_clk.clkr, |
2508 | [MDP_LUT_CLK] = &mdp_lut_clk.clkr, | 2898 | [MDP_LUT_CLK] = &mdp_lut_clk.clkr, |
2899 | [DSI2_PIXEL_SRC] = &dsi2_pixel_src.clkr, | ||
2900 | [DSI2_PIXEL_CLK] = &dsi2_pixel_clk.clkr, | ||
2901 | [DSI2_SRC] = &dsi2_src.clkr, | ||
2902 | [DSI2_CLK] = &dsi2_clk.clkr, | ||
2903 | [DSI1_BYTE_SRC] = &dsi1_byte_src.clkr, | ||
2904 | [DSI1_BYTE_CLK] = &dsi1_byte_clk.clkr, | ||
2905 | [DSI2_BYTE_SRC] = &dsi2_byte_src.clkr, | ||
2906 | [DSI2_BYTE_CLK] = &dsi2_byte_clk.clkr, | ||
2907 | [DSI1_ESC_SRC] = &dsi1_esc_src.clkr, | ||
2908 | [DSI1_ESC_CLK] = &dsi1_esc_clk.clkr, | ||
2909 | [DSI2_ESC_SRC] = &dsi2_esc_src.clkr, | ||
2910 | [DSI2_ESC_CLK] = &dsi2_esc_clk.clkr, | ||
2509 | [ROT_SRC] = &rot_src.clkr, | 2911 | [ROT_SRC] = &rot_src.clkr, |
2510 | [ROT_CLK] = &rot_clk.clkr, | 2912 | [ROT_CLK] = &rot_clk.clkr, |
2511 | [TV_DAC_CLK] = &tv_dac_clk.clkr, | 2913 | [TV_DAC_CLK] = &tv_dac_clk.clkr, |
@@ -2519,6 +2921,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = { | |||
2519 | [VFE_CSI_CLK] = &vfe_csi_clk.clkr, | 2921 | [VFE_CSI_CLK] = &vfe_csi_clk.clkr, |
2520 | [VPE_SRC] = &vpe_src.clkr, | 2922 | [VPE_SRC] = &vpe_src.clkr, |
2521 | [VPE_CLK] = &vpe_clk.clkr, | 2923 | [VPE_CLK] = &vpe_clk.clkr, |
2924 | [DSI_PIXEL_SRC] = &dsi1_pixel_src.clkr, | ||
2925 | [DSI_PIXEL_CLK] = &dsi1_pixel_clk.clkr, | ||
2522 | [CAMCLK0_SRC] = &camclk0_src.clkr, | 2926 | [CAMCLK0_SRC] = &camclk0_src.clkr, |
2523 | [CAMCLK0_CLK] = &camclk0_clk.clkr, | 2927 | [CAMCLK0_CLK] = &camclk0_clk.clkr, |
2524 | [CAMCLK1_SRC] = &camclk1_src.clkr, | 2928 | [CAMCLK1_SRC] = &camclk1_src.clkr, |
@@ -2686,15 +3090,8 @@ static int mmcc_msm8960_probe(struct platform_device *pdev) | |||
2686 | return qcom_cc_really_probe(pdev, match->data, regmap); | 3090 | return qcom_cc_really_probe(pdev, match->data, regmap); |
2687 | } | 3091 | } |
2688 | 3092 | ||
2689 | static int mmcc_msm8960_remove(struct platform_device *pdev) | ||
2690 | { | ||
2691 | qcom_cc_remove(pdev); | ||
2692 | return 0; | ||
2693 | } | ||
2694 | |||
2695 | static struct platform_driver mmcc_msm8960_driver = { | 3093 | static struct platform_driver mmcc_msm8960_driver = { |
2696 | .probe = mmcc_msm8960_probe, | 3094 | .probe = mmcc_msm8960_probe, |
2697 | .remove = mmcc_msm8960_remove, | ||
2698 | .driver = { | 3095 | .driver = { |
2699 | .name = "mmcc-msm8960", | 3096 | .name = "mmcc-msm8960", |
2700 | .of_match_table = mmcc_msm8960_match_table, | 3097 | .of_match_table = mmcc_msm8960_match_table, |
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index 0987bf443e1f..9d790bcadf25 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "clk-rcg.h" | 31 | #include "clk-rcg.h" |
32 | #include "clk-branch.h" | 32 | #include "clk-branch.h" |
33 | #include "reset.h" | 33 | #include "reset.h" |
34 | #include "gdsc.h" | ||
34 | 35 | ||
35 | enum { | 36 | enum { |
36 | P_XO, | 37 | P_XO, |
@@ -522,17 +523,11 @@ static struct clk_rcg2 jpeg2_clk_src = { | |||
522 | }, | 523 | }, |
523 | }; | 524 | }; |
524 | 525 | ||
525 | static struct freq_tbl pixel_freq_tbl[] = { | ||
526 | { .src = P_DSI0PLL }, | ||
527 | { } | ||
528 | }; | ||
529 | |||
530 | static struct clk_rcg2 pclk0_clk_src = { | 526 | static struct clk_rcg2 pclk0_clk_src = { |
531 | .cmd_rcgr = 0x2000, | 527 | .cmd_rcgr = 0x2000, |
532 | .mnd_width = 8, | 528 | .mnd_width = 8, |
533 | .hid_width = 5, | 529 | .hid_width = 5, |
534 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, | 530 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, |
535 | .freq_tbl = pixel_freq_tbl, | ||
536 | .clkr.hw.init = &(struct clk_init_data){ | 531 | .clkr.hw.init = &(struct clk_init_data){ |
537 | .name = "pclk0_clk_src", | 532 | .name = "pclk0_clk_src", |
538 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, | 533 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, |
@@ -547,7 +542,6 @@ static struct clk_rcg2 pclk1_clk_src = { | |||
547 | .mnd_width = 8, | 542 | .mnd_width = 8, |
548 | .hid_width = 5, | 543 | .hid_width = 5, |
549 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, | 544 | .parent_map = mmcc_xo_dsi_hdmi_edp_gpll0_map, |
550 | .freq_tbl = pixel_freq_tbl, | ||
551 | .clkr.hw.init = &(struct clk_init_data){ | 545 | .clkr.hw.init = &(struct clk_init_data){ |
552 | .name = "pclk1_clk_src", | 546 | .name = "pclk1_clk_src", |
553 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, | 547 | .parent_names = mmcc_xo_dsi_hdmi_edp_gpll0, |
@@ -785,7 +779,7 @@ static struct clk_rcg2 byte0_clk_src = { | |||
785 | .name = "byte0_clk_src", | 779 | .name = "byte0_clk_src", |
786 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, | 780 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, |
787 | .num_parents = 6, | 781 | .num_parents = 6, |
788 | .ops = &clk_byte_ops, | 782 | .ops = &clk_byte2_ops, |
789 | .flags = CLK_SET_RATE_PARENT, | 783 | .flags = CLK_SET_RATE_PARENT, |
790 | }, | 784 | }, |
791 | }; | 785 | }; |
@@ -799,7 +793,7 @@ static struct clk_rcg2 byte1_clk_src = { | |||
799 | .name = "byte1_clk_src", | 793 | .name = "byte1_clk_src", |
800 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, | 794 | .parent_names = mmcc_xo_dsibyte_hdmi_edp_gpll0, |
801 | .num_parents = 6, | 795 | .num_parents = 6, |
802 | .ops = &clk_byte_ops, | 796 | .ops = &clk_byte2_ops, |
803 | .flags = CLK_SET_RATE_PARENT, | 797 | .flags = CLK_SET_RATE_PARENT, |
804 | }, | 798 | }, |
805 | }; | 799 | }; |
@@ -2349,6 +2343,66 @@ static struct pll_config mmpll3_config = { | |||
2349 | .aux_output_mask = BIT(1), | 2343 | .aux_output_mask = BIT(1), |
2350 | }; | 2344 | }; |
2351 | 2345 | ||
2346 | static struct gdsc venus0_gdsc = { | ||
2347 | .gdscr = 0x1024, | ||
2348 | .cxcs = (unsigned int []){ 0x1028 }, | ||
2349 | .cxc_count = 1, | ||
2350 | .resets = (unsigned int []){ VENUS0_RESET }, | ||
2351 | .reset_count = 1, | ||
2352 | .pd = { | ||
2353 | .name = "venus0", | ||
2354 | }, | ||
2355 | .pwrsts = PWRSTS_ON, | ||
2356 | }; | ||
2357 | |||
2358 | static struct gdsc mdss_gdsc = { | ||
2359 | .gdscr = 0x2304, | ||
2360 | .cxcs = (unsigned int []){ 0x231c, 0x2320 }, | ||
2361 | .cxc_count = 2, | ||
2362 | .pd = { | ||
2363 | .name = "mdss", | ||
2364 | }, | ||
2365 | .pwrsts = PWRSTS_RET_ON, | ||
2366 | }; | ||
2367 | |||
2368 | static struct gdsc camss_jpeg_gdsc = { | ||
2369 | .gdscr = 0x35a4, | ||
2370 | .cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 }, | ||
2371 | .cxc_count = 3, | ||
2372 | .pd = { | ||
2373 | .name = "camss_jpeg", | ||
2374 | }, | ||
2375 | .pwrsts = PWRSTS_OFF_ON, | ||
2376 | }; | ||
2377 | |||
2378 | static struct gdsc camss_vfe_gdsc = { | ||
2379 | .gdscr = 0x36a4, | ||
2380 | .cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 }, | ||
2381 | .cxc_count = 5, | ||
2382 | .pd = { | ||
2383 | .name = "camss_vfe", | ||
2384 | }, | ||
2385 | .pwrsts = PWRSTS_OFF_ON, | ||
2386 | }; | ||
2387 | |||
2388 | static struct gdsc oxili_gdsc = { | ||
2389 | .gdscr = 0x4024, | ||
2390 | .cxcs = (unsigned int []){ 0x4028 }, | ||
2391 | .cxc_count = 1, | ||
2392 | .pd = { | ||
2393 | .name = "oxili", | ||
2394 | }, | ||
2395 | .pwrsts = PWRSTS_OFF_ON, | ||
2396 | }; | ||
2397 | |||
2398 | static struct gdsc oxilicx_gdsc = { | ||
2399 | .gdscr = 0x4034, | ||
2400 | .pd = { | ||
2401 | .name = "oxilicx", | ||
2402 | }, | ||
2403 | .pwrsts = PWRSTS_OFF_ON, | ||
2404 | }; | ||
2405 | |||
2352 | static struct clk_regmap *mmcc_msm8974_clocks[] = { | 2406 | static struct clk_regmap *mmcc_msm8974_clocks[] = { |
2353 | [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, | 2407 | [MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr, |
2354 | [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, | 2408 | [MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr, |
@@ -2525,6 +2579,15 @@ static const struct qcom_reset_map mmcc_msm8974_resets[] = { | |||
2525 | [OCMEMNOC_RESET] = { 0x50b0 }, | 2579 | [OCMEMNOC_RESET] = { 0x50b0 }, |
2526 | }; | 2580 | }; |
2527 | 2581 | ||
2582 | static struct gdsc *mmcc_msm8974_gdscs[] = { | ||
2583 | [VENUS0_GDSC] = &venus0_gdsc, | ||
2584 | [MDSS_GDSC] = &mdss_gdsc, | ||
2585 | [CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc, | ||
2586 | [CAMSS_VFE_GDSC] = &camss_vfe_gdsc, | ||
2587 | [OXILI_GDSC] = &oxili_gdsc, | ||
2588 | [OXILICX_GDSC] = &oxilicx_gdsc, | ||
2589 | }; | ||
2590 | |||
2528 | static const struct regmap_config mmcc_msm8974_regmap_config = { | 2591 | static const struct regmap_config mmcc_msm8974_regmap_config = { |
2529 | .reg_bits = 32, | 2592 | .reg_bits = 32, |
2530 | .reg_stride = 4, | 2593 | .reg_stride = 4, |
@@ -2539,6 +2602,8 @@ static const struct qcom_cc_desc mmcc_msm8974_desc = { | |||
2539 | .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks), | 2602 | .num_clks = ARRAY_SIZE(mmcc_msm8974_clocks), |
2540 | .resets = mmcc_msm8974_resets, | 2603 | .resets = mmcc_msm8974_resets, |
2541 | .num_resets = ARRAY_SIZE(mmcc_msm8974_resets), | 2604 | .num_resets = ARRAY_SIZE(mmcc_msm8974_resets), |
2605 | .gdscs = mmcc_msm8974_gdscs, | ||
2606 | .num_gdscs = ARRAY_SIZE(mmcc_msm8974_gdscs), | ||
2542 | }; | 2607 | }; |
2543 | 2608 | ||
2544 | static const struct of_device_id mmcc_msm8974_match_table[] = { | 2609 | static const struct of_device_id mmcc_msm8974_match_table[] = { |
@@ -2550,6 +2615,7 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); | |||
2550 | static int mmcc_msm8974_probe(struct platform_device *pdev) | 2615 | static int mmcc_msm8974_probe(struct platform_device *pdev) |
2551 | { | 2616 | { |
2552 | struct regmap *regmap; | 2617 | struct regmap *regmap; |
2618 | int ret; | ||
2553 | 2619 | ||
2554 | regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc); | 2620 | regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc); |
2555 | if (IS_ERR(regmap)) | 2621 | if (IS_ERR(regmap)) |
@@ -2558,12 +2624,16 @@ static int mmcc_msm8974_probe(struct platform_device *pdev) | |||
2558 | clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); | 2624 | clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); |
2559 | clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); | 2625 | clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); |
2560 | 2626 | ||
2561 | return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); | 2627 | ret = qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); |
2628 | if (ret) | ||
2629 | return ret; | ||
2630 | |||
2631 | return pm_genpd_add_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd); | ||
2562 | } | 2632 | } |
2563 | 2633 | ||
2564 | static int mmcc_msm8974_remove(struct platform_device *pdev) | 2634 | static int mmcc_msm8974_remove(struct platform_device *pdev) |
2565 | { | 2635 | { |
2566 | qcom_cc_remove(pdev); | 2636 | pm_genpd_remove_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd); |
2567 | return 0; | 2637 | return 0; |
2568 | } | 2638 | } |
2569 | 2639 | ||
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index bc24e5a002e7..2685644826a0 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c | |||
@@ -41,6 +41,8 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw, | |||
41 | #define ROCKCHIP_MMC_DEGREE_MASK 0x3 | 41 | #define ROCKCHIP_MMC_DEGREE_MASK 0x3 |
42 | #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 | 42 | #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 |
43 | #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) | 43 | #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) |
44 | #define ROCKCHIP_MMC_INIT_STATE_RESET 0x1 | ||
45 | #define ROCKCHIP_MMC_INIT_STATE_SHIFT 1 | ||
44 | 46 | ||
45 | #define PSECS_PER_SEC 1000000000000LL | 47 | #define PSECS_PER_SEC 1000000000000LL |
46 | 48 | ||
@@ -159,6 +161,15 @@ struct clk *rockchip_clk_register_mmc(const char *name, | |||
159 | mmc_clock->reg = reg; | 161 | mmc_clock->reg = reg; |
160 | mmc_clock->shift = shift; | 162 | mmc_clock->shift = shift; |
161 | 163 | ||
164 | /* | ||
165 | * Assert init_state to soft reset the CLKGEN | ||
166 | * for mmc tuning phase and degree | ||
167 | */ | ||
168 | if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT) | ||
169 | writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET, | ||
170 | ROCKCHIP_MMC_INIT_STATE_RESET, | ||
171 | mmc_clock->shift), mmc_clock->reg); | ||
172 | |||
162 | clk = clk_register(NULL, &mmc_clock->hw); | 173 | clk = clk_register(NULL, &mmc_clock->hw); |
163 | if (IS_ERR(clk)) | 174 | if (IS_ERR(clk)) |
164 | goto err_free; | 175 | goto err_free; |
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 7737a1df1e4b..4881eb8a1576 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c | |||
@@ -126,11 +126,32 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) | |||
126 | #define RK3066_PLLCON3_PWRDOWN (1 << 1) | 126 | #define RK3066_PLLCON3_PWRDOWN (1 << 1) |
127 | #define RK3066_PLLCON3_BYPASS (1 << 0) | 127 | #define RK3066_PLLCON3_BYPASS (1 << 0) |
128 | 128 | ||
129 | static void rockchip_rk3066_pll_get_params(struct rockchip_clk_pll *pll, | ||
130 | struct rockchip_pll_rate_table *rate) | ||
131 | { | ||
132 | u32 pllcon; | ||
133 | |||
134 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); | ||
135 | rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) | ||
136 | & RK3066_PLLCON0_NR_MASK) + 1; | ||
137 | rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) | ||
138 | & RK3066_PLLCON0_OD_MASK) + 1; | ||
139 | |||
140 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); | ||
141 | rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) | ||
142 | & RK3066_PLLCON1_NF_MASK) + 1; | ||
143 | |||
144 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2)); | ||
145 | rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) | ||
146 | & RK3066_PLLCON2_NB_MASK) + 1; | ||
147 | } | ||
148 | |||
129 | static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, | 149 | static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, |
130 | unsigned long prate) | 150 | unsigned long prate) |
131 | { | 151 | { |
132 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); | 152 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); |
133 | u64 nf, nr, no, rate64 = prate; | 153 | struct rockchip_pll_rate_table cur; |
154 | u64 rate64 = prate; | ||
134 | u32 pllcon; | 155 | u32 pllcon; |
135 | 156 | ||
136 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3)); | 157 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(3)); |
@@ -140,53 +161,31 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw, | |||
140 | return prate; | 161 | return prate; |
141 | } | 162 | } |
142 | 163 | ||
143 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); | 164 | rockchip_rk3066_pll_get_params(pll, &cur); |
144 | nf = (pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK; | ||
145 | |||
146 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); | ||
147 | nr = (pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK; | ||
148 | no = (pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK; | ||
149 | 165 | ||
150 | rate64 *= (nf + 1); | 166 | rate64 *= cur.nf; |
151 | do_div(rate64, nr + 1); | 167 | do_div(rate64, cur.nr); |
152 | do_div(rate64, no + 1); | 168 | do_div(rate64, cur.no); |
153 | 169 | ||
154 | return (unsigned long)rate64; | 170 | return (unsigned long)rate64; |
155 | } | 171 | } |
156 | 172 | ||
157 | static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, | 173 | static int rockchip_rk3066_pll_set_params(struct rockchip_clk_pll *pll, |
158 | unsigned long prate) | 174 | const struct rockchip_pll_rate_table *rate) |
159 | { | 175 | { |
160 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); | ||
161 | const struct rockchip_pll_rate_table *rate; | ||
162 | unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); | ||
163 | struct regmap *grf = rockchip_clk_get_grf(); | ||
164 | struct clk_mux *pll_mux = &pll->pll_mux; | ||
165 | const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; | 176 | const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; |
177 | struct clk_mux *pll_mux = &pll->pll_mux; | ||
178 | struct rockchip_pll_rate_table cur; | ||
166 | int rate_change_remuxed = 0; | 179 | int rate_change_remuxed = 0; |
167 | int cur_parent; | 180 | int cur_parent; |
168 | int ret; | 181 | int ret; |
169 | 182 | ||
170 | if (IS_ERR(grf)) { | ||
171 | pr_debug("%s: grf regmap not available, aborting rate change\n", | ||
172 | __func__); | ||
173 | return PTR_ERR(grf); | ||
174 | } | ||
175 | |||
176 | pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", | ||
177 | __func__, clk_hw_get_name(hw), old_rate, drate, prate); | ||
178 | |||
179 | /* Get required rate settings from table */ | ||
180 | rate = rockchip_get_pll_settings(pll, drate); | ||
181 | if (!rate) { | ||
182 | pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, | ||
183 | drate, clk_hw_get_name(hw)); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
187 | pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", | 183 | pr_debug("%s: rate settings for %lu (nr, no, nf): (%d, %d, %d)\n", |
188 | __func__, rate->rate, rate->nr, rate->no, rate->nf); | 184 | __func__, rate->rate, rate->nr, rate->no, rate->nf); |
189 | 185 | ||
186 | rockchip_rk3066_pll_get_params(pll, &cur); | ||
187 | cur.rate = 0; | ||
188 | |||
190 | cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); | 189 | cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); |
191 | if (cur_parent == PLL_MODE_NORM) { | 190 | if (cur_parent == PLL_MODE_NORM) { |
192 | pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); | 191 | pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); |
@@ -219,9 +218,9 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, | |||
219 | /* wait for the pll to lock */ | 218 | /* wait for the pll to lock */ |
220 | ret = rockchip_pll_wait_lock(pll); | 219 | ret = rockchip_pll_wait_lock(pll); |
221 | if (ret) { | 220 | if (ret) { |
222 | pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", | 221 | pr_warn("%s: pll update unsucessful, trying to restore old params\n", |
223 | __func__, old_rate); | 222 | __func__); |
224 | rockchip_rk3066_pll_set_rate(hw, old_rate, prate); | 223 | rockchip_rk3066_pll_set_params(pll, &cur); |
225 | } | 224 | } |
226 | 225 | ||
227 | if (rate_change_remuxed) | 226 | if (rate_change_remuxed) |
@@ -230,6 +229,34 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, | |||
230 | return ret; | 229 | return ret; |
231 | } | 230 | } |
232 | 231 | ||
232 | static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate, | ||
233 | unsigned long prate) | ||
234 | { | ||
235 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); | ||
236 | const struct rockchip_pll_rate_table *rate; | ||
237 | unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); | ||
238 | struct regmap *grf = rockchip_clk_get_grf(); | ||
239 | |||
240 | if (IS_ERR(grf)) { | ||
241 | pr_debug("%s: grf regmap not available, aborting rate change\n", | ||
242 | __func__); | ||
243 | return PTR_ERR(grf); | ||
244 | } | ||
245 | |||
246 | pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", | ||
247 | __func__, clk_hw_get_name(hw), old_rate, drate, prate); | ||
248 | |||
249 | /* Get required rate settings from table */ | ||
250 | rate = rockchip_get_pll_settings(pll, drate); | ||
251 | if (!rate) { | ||
252 | pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, | ||
253 | drate, clk_hw_get_name(hw)); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | |||
257 | return rockchip_rk3066_pll_set_params(pll, rate); | ||
258 | } | ||
259 | |||
233 | static int rockchip_rk3066_pll_enable(struct clk_hw *hw) | 260 | static int rockchip_rk3066_pll_enable(struct clk_hw *hw) |
234 | { | 261 | { |
235 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); | 262 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); |
@@ -261,9 +288,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw) | |||
261 | { | 288 | { |
262 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); | 289 | struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); |
263 | const struct rockchip_pll_rate_table *rate; | 290 | const struct rockchip_pll_rate_table *rate; |
264 | unsigned int nf, nr, no, nb; | 291 | struct rockchip_pll_rate_table cur; |
265 | unsigned long drate; | 292 | unsigned long drate; |
266 | u32 pllcon; | ||
267 | 293 | ||
268 | if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) | 294 | if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) |
269 | return; | 295 | return; |
@@ -275,34 +301,21 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw) | |||
275 | if (!rate) | 301 | if (!rate) |
276 | return; | 302 | return; |
277 | 303 | ||
278 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(0)); | 304 | rockchip_rk3066_pll_get_params(pll, &cur); |
279 | nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1; | ||
280 | no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1; | ||
281 | |||
282 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(1)); | ||
283 | nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1; | ||
284 | |||
285 | pllcon = readl_relaxed(pll->reg_base + RK3066_PLLCON(2)); | ||
286 | nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1; | ||
287 | 305 | ||
288 | pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n", | 306 | pr_debug("%s: pll %s@%lu: nr (%d:%d); no (%d:%d); nf(%d:%d), nb(%d:%d)\n", |
289 | __func__, clk_hw_get_name(hw), drate, rate->nr, nr, | 307 | __func__, clk_hw_get_name(hw), drate, rate->nr, cur.nr, |
290 | rate->no, no, rate->nf, nf, rate->nb, nb); | 308 | rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb); |
291 | if (rate->nr != nr || rate->no != no || rate->nf != nf | 309 | if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf |
292 | || rate->nb != nb) { | 310 | || rate->nb != cur.nb) { |
293 | struct clk_hw *parent = clk_hw_get_parent(hw); | 311 | struct regmap *grf = rockchip_clk_get_grf(); |
294 | unsigned long prate; | 312 | |
295 | 313 | if (IS_ERR(grf)) | |
296 | if (!parent) { | ||
297 | pr_warn("%s: parent of %s not available\n", | ||
298 | __func__, clk_hw_get_name(hw)); | ||
299 | return; | 314 | return; |
300 | } | ||
301 | 315 | ||
302 | pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", | 316 | pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", |
303 | __func__, clk_hw_get_name(hw)); | 317 | __func__, clk_hw_get_name(hw)); |
304 | prate = clk_hw_get_rate(parent); | 318 | rockchip_rk3066_pll_set_params(pll, rate); |
305 | rockchip_rk3066_pll_set_rate(hw, drate, prate); | ||
306 | } | 319 | } |
307 | } | 320 | } |
308 | 321 | ||
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 24938815655f..be6c7fd8315d 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c | |||
@@ -135,9 +135,11 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, | |||
135 | div->flags = div_flags; | 135 | div->flags = div_flags; |
136 | div->reg = base + muxdiv_offset; | 136 | div->reg = base + muxdiv_offset; |
137 | div->mshift = 16; | 137 | div->mshift = 16; |
138 | div->mmask = 0xffff0000; | 138 | div->mwidth = 16; |
139 | div->mmask = GENMASK(div->mwidth - 1, 0) << div->mshift; | ||
139 | div->nshift = 0; | 140 | div->nshift = 0; |
140 | div->nmask = 0xffff; | 141 | div->nwidth = 16; |
142 | div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; | ||
141 | div->lock = lock; | 143 | div->lock = lock; |
142 | div_ops = &clk_fractional_divider_ops; | 144 | div_ops = &clk_fractional_divider_ops; |
143 | 145 | ||
diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index 8524e667097e..55f8e2e24ab8 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c | |||
@@ -32,39 +32,41 @@ | |||
32 | #define DIV_TOPC0 0x0600 | 32 | #define DIV_TOPC0 0x0600 |
33 | #define DIV_TOPC1 0x0604 | 33 | #define DIV_TOPC1 0x0604 |
34 | #define DIV_TOPC3 0x060C | 34 | #define DIV_TOPC3 0x060C |
35 | #define ENABLE_ACLK_TOPC0 0x0800 | ||
35 | #define ENABLE_ACLK_TOPC1 0x0804 | 36 | #define ENABLE_ACLK_TOPC1 0x0804 |
37 | #define ENABLE_SCLK_TOPC1 0x0A04 | ||
36 | 38 | ||
37 | static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = { | 39 | static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = { |
38 | FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0), | 40 | FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_topc_bus0_pll", 1, 2, 0), |
39 | FFACTOR(0, "ffac_topc_bus0_pll_div4", | 41 | FFACTOR(0, "ffac_topc_bus0_pll_div4", |
40 | "ffac_topc_bus0_pll_div2", 1, 2, 0), | 42 | "ffac_topc_bus0_pll_div2", 1, 2, 0), |
41 | FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0), | 43 | FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_topc_bus1_pll", 1, 2, 0), |
42 | FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0), | 44 | FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_topc_cc_pll", 1, 2, 0), |
43 | FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0), | 45 | FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_topc_mfc_pll", 1, 2, 0), |
44 | }; | 46 | }; |
45 | 47 | ||
46 | /* List of parent clocks for Muxes in CMU_TOPC */ | 48 | /* List of parent clocks for Muxes in CMU_TOPC */ |
47 | PNAME(mout_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" }; | 49 | PNAME(mout_topc_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" }; |
48 | PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" }; | 50 | PNAME(mout_topc_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" }; |
49 | PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" }; | 51 | PNAME(mout_topc_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" }; |
50 | PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" }; | 52 | PNAME(mout_topc_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" }; |
51 | PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" }; | 53 | PNAME(mout_topc_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" }; |
52 | 54 | ||
53 | PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc", | 55 | PNAME(mout_topc_group2) = { "mout_topc_bus0_pll_half", |
54 | "mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc", | 56 | "mout_topc_bus1_pll_half", "mout_topc_cc_pll_half", |
55 | "mout_sclk_mfc_pll_cmuc" }; | 57 | "mout_topc_mfc_pll_half" }; |
56 | 58 | ||
57 | PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl", | 59 | PNAME(mout_topc_bus0_pll_half_p) = { "mout_topc_bus0_pll", |
58 | "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"}; | 60 | "ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"}; |
59 | PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl", | 61 | PNAME(mout_topc_bus1_pll_half_p) = { "mout_topc_bus1_pll", |
60 | "ffac_topc_bus1_pll_div2"}; | 62 | "ffac_topc_bus1_pll_div2"}; |
61 | PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl", | 63 | PNAME(mout_topc_cc_pll_half_p) = { "mout_topc_cc_pll", |
62 | "ffac_topc_cc_pll_div2"}; | 64 | "ffac_topc_cc_pll_div2"}; |
63 | PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl", | 65 | PNAME(mout_topc_mfc_pll_half_p) = { "mout_topc_mfc_pll", |
64 | "ffac_topc_mfc_pll_div2"}; | 66 | "ffac_topc_mfc_pll_div2"}; |
65 | 67 | ||
66 | 68 | ||
67 | PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl", | 69 | PNAME(mout_topc_bus0_pll_out_p) = {"mout_topc_bus0_pll", |
68 | "ffac_topc_bus0_pll_div2"}; | 70 | "ffac_topc_bus0_pll_div2"}; |
69 | 71 | ||
70 | static unsigned long topc_clk_regs[] __initdata = { | 72 | static unsigned long topc_clk_regs[] __initdata = { |
@@ -88,23 +90,27 @@ static unsigned long topc_clk_regs[] __initdata = { | |||
88 | }; | 90 | }; |
89 | 91 | ||
90 | static struct samsung_mux_clock topc_mux_clks[] __initdata = { | 92 | static struct samsung_mux_clock topc_mux_clks[] __initdata = { |
91 | MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1), | 93 | MUX(0, "mout_topc_bus0_pll", mout_topc_bus0_pll_ctrl_p, |
92 | MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1), | 94 | MUX_SEL_TOPC0, 0, 1), |
93 | MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1), | 95 | MUX(0, "mout_topc_bus1_pll", mout_topc_bus1_pll_ctrl_p, |
94 | MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1), | 96 | MUX_SEL_TOPC0, 4, 1), |
95 | 97 | MUX(0, "mout_topc_cc_pll", mout_topc_cc_pll_ctrl_p, | |
96 | MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p, | 98 | MUX_SEL_TOPC0, 8, 1), |
99 | MUX(0, "mout_topc_mfc_pll", mout_topc_mfc_pll_ctrl_p, | ||
100 | MUX_SEL_TOPC0, 12, 1), | ||
101 | MUX(0, "mout_topc_bus0_pll_half", mout_topc_bus0_pll_half_p, | ||
97 | MUX_SEL_TOPC0, 16, 2), | 102 | MUX_SEL_TOPC0, 16, 2), |
98 | MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p, | 103 | MUX(0, "mout_topc_bus1_pll_half", mout_topc_bus1_pll_half_p, |
99 | MUX_SEL_TOPC0, 20, 1), | 104 | MUX_SEL_TOPC0, 20, 1), |
100 | MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p, | 105 | MUX(0, "mout_topc_cc_pll_half", mout_topc_cc_pll_half_p, |
101 | MUX_SEL_TOPC0, 24, 1), | 106 | MUX_SEL_TOPC0, 24, 1), |
102 | MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p, | 107 | MUX(0, "mout_topc_mfc_pll_half", mout_topc_mfc_pll_half_p, |
103 | MUX_SEL_TOPC0, 28, 1), | 108 | MUX_SEL_TOPC0, 28, 1), |
104 | 109 | ||
105 | MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_bus0_pll_out_p, | 110 | MUX(0, "mout_topc_aud_pll", mout_topc_aud_pll_ctrl_p, |
111 | MUX_SEL_TOPC1, 0, 1), | ||
112 | MUX(0, "mout_topc_bus0_pll_out", mout_topc_bus0_pll_out_p, | ||
106 | MUX_SEL_TOPC1, 16, 1), | 113 | MUX_SEL_TOPC1, 16, 1), |
107 | MUX(0, "mout_aud_pll_ctrl", mout_aud_pll_ctrl_p, MUX_SEL_TOPC1, 0, 1), | ||
108 | 114 | ||
109 | MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2), | 115 | MUX(0, "mout_aclk_ccore_133", mout_topc_group2, MUX_SEL_TOPC2, 4, 2), |
110 | 116 | ||
@@ -121,16 +127,16 @@ static struct samsung_div_clock topc_div_clks[] __initdata = { | |||
121 | DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66", | 127 | DIV(DOUT_ACLK_PERIS, "dout_aclk_peris_66", "mout_aclk_peris_66", |
122 | DIV_TOPC1, 24, 4), | 128 | DIV_TOPC1, 24, 4), |
123 | 129 | ||
124 | DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_sclk_bus0_pll_out", | 130 | DIV(DOUT_SCLK_BUS0_PLL, "dout_sclk_bus0_pll", "mout_topc_bus0_pll_out", |
125 | DIV_TOPC3, 0, 3), | 131 | DIV_TOPC3, 0, 4), |
126 | DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_bus1_pll_ctrl", | 132 | DIV(DOUT_SCLK_BUS1_PLL, "dout_sclk_bus1_pll", "mout_topc_bus1_pll", |
127 | DIV_TOPC3, 8, 3), | 133 | DIV_TOPC3, 8, 4), |
128 | DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_cc_pll_ctrl", | 134 | DIV(DOUT_SCLK_CC_PLL, "dout_sclk_cc_pll", "mout_topc_cc_pll", |
129 | DIV_TOPC3, 12, 3), | 135 | DIV_TOPC3, 12, 4), |
130 | DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_mfc_pll_ctrl", | 136 | DIV(DOUT_SCLK_MFC_PLL, "dout_sclk_mfc_pll", "mout_topc_mfc_pll", |
131 | DIV_TOPC3, 16, 3), | 137 | DIV_TOPC3, 16, 4), |
132 | DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_aud_pll_ctrl", | 138 | DIV(DOUT_SCLK_AUD_PLL, "dout_sclk_aud_pll", "mout_topc_aud_pll", |
133 | DIV_TOPC3, 28, 3), | 139 | DIV_TOPC3, 28, 4), |
134 | }; | 140 | }; |
135 | 141 | ||
136 | static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = { | 142 | static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = { |
@@ -139,8 +145,33 @@ static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = { | |||
139 | }; | 145 | }; |
140 | 146 | ||
141 | static struct samsung_gate_clock topc_gate_clks[] __initdata = { | 147 | static struct samsung_gate_clock topc_gate_clks[] __initdata = { |
148 | GATE(ACLK_CCORE_133, "aclk_ccore_133", "dout_aclk_ccore_133", | ||
149 | ENABLE_ACLK_TOPC0, 4, 0, 0), | ||
150 | |||
142 | GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532", | 151 | GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532", |
143 | ENABLE_ACLK_TOPC1, 20, 0, 0), | 152 | ENABLE_ACLK_TOPC1, 20, 0, 0), |
153 | |||
154 | GATE(ACLK_PERIS_66, "aclk_peris_66", "dout_aclk_peris_66", | ||
155 | ENABLE_ACLK_TOPC1, 24, 0, 0), | ||
156 | |||
157 | GATE(SCLK_AUD_PLL, "sclk_aud_pll", "dout_sclk_aud_pll", | ||
158 | ENABLE_SCLK_TOPC1, 20, 0, 0), | ||
159 | GATE(SCLK_MFC_PLL_B, "sclk_mfc_pll_b", "dout_sclk_mfc_pll", | ||
160 | ENABLE_SCLK_TOPC1, 17, 0, 0), | ||
161 | GATE(SCLK_MFC_PLL_A, "sclk_mfc_pll_a", "dout_sclk_mfc_pll", | ||
162 | ENABLE_SCLK_TOPC1, 16, 0, 0), | ||
163 | GATE(SCLK_BUS1_PLL_B, "sclk_bus1_pll_b", "dout_sclk_bus1_pll", | ||
164 | ENABLE_SCLK_TOPC1, 13, 0, 0), | ||
165 | GATE(SCLK_BUS1_PLL_A, "sclk_bus1_pll_a", "dout_sclk_bus1_pll", | ||
166 | ENABLE_SCLK_TOPC1, 12, 0, 0), | ||
167 | GATE(SCLK_BUS0_PLL_B, "sclk_bus0_pll_b", "dout_sclk_bus0_pll", | ||
168 | ENABLE_SCLK_TOPC1, 5, 0, 0), | ||
169 | GATE(SCLK_BUS0_PLL_A, "sclk_bus0_pll_a", "dout_sclk_bus0_pll", | ||
170 | ENABLE_SCLK_TOPC1, 4, 0, 0), | ||
171 | GATE(SCLK_CC_PLL_B, "sclk_cc_pll_b", "dout_sclk_cc_pll", | ||
172 | ENABLE_SCLK_TOPC1, 1, 0, 0), | ||
173 | GATE(SCLK_CC_PLL_A, "sclk_cc_pll_a", "dout_sclk_cc_pll", | ||
174 | ENABLE_SCLK_TOPC1, 0, 0, 0), | ||
144 | }; | 175 | }; |
145 | 176 | ||
146 | static struct samsung_pll_clock topc_pll_clks[] __initdata = { | 177 | static struct samsung_pll_clock topc_pll_clks[] __initdata = { |
@@ -193,36 +224,37 @@ CLK_OF_DECLARE(exynos7_clk_topc, "samsung,exynos7-clock-topc", | |||
193 | #define DIV_TOP0_PERIC1 0x0634 | 224 | #define DIV_TOP0_PERIC1 0x0634 |
194 | #define DIV_TOP0_PERIC2 0x0638 | 225 | #define DIV_TOP0_PERIC2 0x0638 |
195 | #define DIV_TOP0_PERIC3 0x063C | 226 | #define DIV_TOP0_PERIC3 0x063C |
227 | #define ENABLE_ACLK_TOP03 0x080C | ||
196 | #define ENABLE_SCLK_TOP0_PERIC0 0x0A30 | 228 | #define ENABLE_SCLK_TOP0_PERIC0 0x0A30 |
197 | #define ENABLE_SCLK_TOP0_PERIC1 0x0A34 | 229 | #define ENABLE_SCLK_TOP0_PERIC1 0x0A34 |
198 | #define ENABLE_SCLK_TOP0_PERIC2 0x0A38 | 230 | #define ENABLE_SCLK_TOP0_PERIC2 0x0A38 |
199 | #define ENABLE_SCLK_TOP0_PERIC3 0x0A3C | 231 | #define ENABLE_SCLK_TOP0_PERIC3 0x0A3C |
200 | 232 | ||
201 | /* List of parent clocks for Muxes in CMU_TOP0 */ | 233 | /* List of parent clocks for Muxes in CMU_TOP0 */ |
202 | PNAME(mout_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; | 234 | PNAME(mout_top0_bus0_pll_user_p) = { "fin_pll", "sclk_bus0_pll_a" }; |
203 | PNAME(mout_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll" }; | 235 | PNAME(mout_top0_bus1_pll_user_p) = { "fin_pll", "sclk_bus1_pll_a" }; |
204 | PNAME(mout_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll" }; | 236 | PNAME(mout_top0_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_a" }; |
205 | PNAME(mout_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll" }; | 237 | PNAME(mout_top0_mfc_pll_user_p) = { "fin_pll", "sclk_mfc_pll_a" }; |
206 | PNAME(mout_aud_pll_p) = { "fin_pll", "dout_sclk_aud_pll" }; | 238 | PNAME(mout_top0_aud_pll_user_p) = { "fin_pll", "sclk_aud_pll" }; |
207 | 239 | ||
208 | PNAME(mout_top0_half_bus0_pll_p) = {"mout_top0_bus0_pll", | 240 | PNAME(mout_top0_bus0_pll_half_p) = {"mout_top0_bus0_pll_user", |
209 | "ffac_top0_bus0_pll_div2"}; | 241 | "ffac_top0_bus0_pll_div2"}; |
210 | PNAME(mout_top0_half_bus1_pll_p) = {"mout_top0_bus1_pll", | 242 | PNAME(mout_top0_bus1_pll_half_p) = {"mout_top0_bus1_pll_user", |
211 | "ffac_top0_bus1_pll_div2"}; | 243 | "ffac_top0_bus1_pll_div2"}; |
212 | PNAME(mout_top0_half_cc_pll_p) = {"mout_top0_cc_pll", | 244 | PNAME(mout_top0_cc_pll_half_p) = {"mout_top0_cc_pll_user", |
213 | "ffac_top0_cc_pll_div2"}; | 245 | "ffac_top0_cc_pll_div2"}; |
214 | PNAME(mout_top0_half_mfc_pll_p) = {"mout_top0_mfc_pll", | 246 | PNAME(mout_top0_mfc_pll_half_p) = {"mout_top0_mfc_pll_user", |
215 | "ffac_top0_mfc_pll_div2"}; | 247 | "ffac_top0_mfc_pll_div2"}; |
216 | 248 | ||
217 | PNAME(mout_top0_group1) = {"mout_top0_half_bus0_pll", | 249 | PNAME(mout_top0_group1) = {"mout_top0_bus0_pll_half", |
218 | "mout_top0_half_bus1_pll", "mout_top0_half_cc_pll", | 250 | "mout_top0_bus1_pll_half", "mout_top0_cc_pll_half", |
219 | "mout_top0_half_mfc_pll"}; | 251 | "mout_top0_mfc_pll_half"}; |
220 | PNAME(mout_top0_group3) = {"ioclk_audiocdclk0", | 252 | PNAME(mout_top0_group3) = {"ioclk_audiocdclk0", |
221 | "ioclk_audiocdclk1", "ioclk_spdif_extclk", | 253 | "ioclk_audiocdclk1", "ioclk_spdif_extclk", |
222 | "mout_top0_aud_pll", "mout_top0_half_bus0_pll", | 254 | "mout_top0_aud_pll_user", "mout_top0_bus0_pll_half", |
223 | "mout_top0_half_bus1_pll"}; | 255 | "mout_top0_bus1_pll_half"}; |
224 | PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll", | 256 | PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll_user", |
225 | "mout_top0_half_bus0_pll", "mout_top0_half_bus1_pll"}; | 257 | "mout_top0_bus0_pll_half", "mout_top0_bus1_pll_half"}; |
226 | 258 | ||
227 | static unsigned long top0_clk_regs[] __initdata = { | 259 | static unsigned long top0_clk_regs[] __initdata = { |
228 | MUX_SEL_TOP00, | 260 | MUX_SEL_TOP00, |
@@ -244,19 +276,24 @@ static unsigned long top0_clk_regs[] __initdata = { | |||
244 | }; | 276 | }; |
245 | 277 | ||
246 | static struct samsung_mux_clock top0_mux_clks[] __initdata = { | 278 | static struct samsung_mux_clock top0_mux_clks[] __initdata = { |
247 | MUX(0, "mout_top0_aud_pll", mout_aud_pll_p, MUX_SEL_TOP00, 0, 1), | 279 | MUX(0, "mout_top0_aud_pll_user", mout_top0_aud_pll_user_p, |
248 | MUX(0, "mout_top0_mfc_pll", mout_mfc_pll_p, MUX_SEL_TOP00, 4, 1), | 280 | MUX_SEL_TOP00, 0, 1), |
249 | MUX(0, "mout_top0_cc_pll", mout_cc_pll_p, MUX_SEL_TOP00, 8, 1), | 281 | MUX(0, "mout_top0_mfc_pll_user", mout_top0_mfc_pll_user_p, |
250 | MUX(0, "mout_top0_bus1_pll", mout_bus1_pll_p, MUX_SEL_TOP00, 12, 1), | 282 | MUX_SEL_TOP00, 4, 1), |
251 | MUX(0, "mout_top0_bus0_pll", mout_bus0_pll_p, MUX_SEL_TOP00, 16, 1), | 283 | MUX(0, "mout_top0_cc_pll_user", mout_top0_cc_pll_user_p, |
252 | 284 | MUX_SEL_TOP00, 8, 1), | |
253 | MUX(0, "mout_top0_half_mfc_pll", mout_top0_half_mfc_pll_p, | 285 | MUX(0, "mout_top0_bus1_pll_user", mout_top0_bus1_pll_user_p, |
286 | MUX_SEL_TOP00, 12, 1), | ||
287 | MUX(0, "mout_top0_bus0_pll_user", mout_top0_bus0_pll_user_p, | ||
288 | MUX_SEL_TOP00, 16, 1), | ||
289 | |||
290 | MUX(0, "mout_top0_mfc_pll_half", mout_top0_mfc_pll_half_p, | ||
254 | MUX_SEL_TOP01, 4, 1), | 291 | MUX_SEL_TOP01, 4, 1), |
255 | MUX(0, "mout_top0_half_cc_pll", mout_top0_half_cc_pll_p, | 292 | MUX(0, "mout_top0_cc_pll_half", mout_top0_cc_pll_half_p, |
256 | MUX_SEL_TOP01, 8, 1), | 293 | MUX_SEL_TOP01, 8, 1), |
257 | MUX(0, "mout_top0_half_bus1_pll", mout_top0_half_bus1_pll_p, | 294 | MUX(0, "mout_top0_bus1_pll_half", mout_top0_bus1_pll_half_p, |
258 | MUX_SEL_TOP01, 12, 1), | 295 | MUX_SEL_TOP01, 12, 1), |
259 | MUX(0, "mout_top0_half_bus0_pll", mout_top0_half_bus0_pll_p, | 296 | MUX(0, "mout_top0_bus0_pll_half", mout_top0_bus0_pll_half_p, |
260 | MUX_SEL_TOP01, 16, 1), | 297 | MUX_SEL_TOP01, 16, 1), |
261 | 298 | ||
262 | MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2), | 299 | MUX(0, "mout_aclk_peric1_66", mout_top0_group1, MUX_SEL_TOP03, 12, 2), |
@@ -302,6 +339,11 @@ static struct samsung_div_clock top0_div_clks[] __initdata = { | |||
302 | }; | 339 | }; |
303 | 340 | ||
304 | static struct samsung_gate_clock top0_gate_clks[] __initdata = { | 341 | static struct samsung_gate_clock top0_gate_clks[] __initdata = { |
342 | GATE(CLK_ACLK_PERIC0_66, "aclk_peric0_66", "dout_aclk_peric0_66", | ||
343 | ENABLE_ACLK_TOP03, 20, CLK_SET_RATE_PARENT, 0), | ||
344 | GATE(CLK_ACLK_PERIC1_66, "aclk_peric1_66", "dout_aclk_peric1_66", | ||
345 | ENABLE_ACLK_TOP03, 12, CLK_SET_RATE_PARENT, 0), | ||
346 | |||
305 | GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif", | 347 | GATE(CLK_SCLK_SPDIF, "sclk_spdif", "dout_sclk_spdif", |
306 | ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0), | 348 | ENABLE_SCLK_TOP0_PERIC0, 4, CLK_SET_RATE_PARENT, 0), |
307 | GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1", | 349 | GATE(CLK_SCLK_PCM1, "sclk_pcm1", "dout_sclk_pcm1", |
@@ -331,10 +373,12 @@ static struct samsung_gate_clock top0_gate_clks[] __initdata = { | |||
331 | }; | 373 | }; |
332 | 374 | ||
333 | static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = { | 375 | static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = { |
334 | FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll", 1, 2, 0), | 376 | FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll_user", |
335 | FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll", 1, 2, 0), | 377 | 1, 2, 0), |
336 | FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll", 1, 2, 0), | 378 | FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll_user", |
337 | FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll", 1, 2, 0), | 379 | 1, 2, 0), |
380 | FFACTOR(0, "ffac_top0_cc_pll_div2", "mout_top0_cc_pll_user", 1, 2, 0), | ||
381 | FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll_user", 1, 2, 0), | ||
338 | }; | 382 | }; |
339 | 383 | ||
340 | static struct samsung_cmu_info top0_cmu_info __initdata = { | 384 | static struct samsung_cmu_info top0_cmu_info __initdata = { |
@@ -365,31 +409,34 @@ CLK_OF_DECLARE(exynos7_clk_top0, "samsung,exynos7-clock-top0", | |||
365 | #define MUX_SEL_TOP13 0x020C | 409 | #define MUX_SEL_TOP13 0x020C |
366 | #define MUX_SEL_TOP1_FSYS0 0x0224 | 410 | #define MUX_SEL_TOP1_FSYS0 0x0224 |
367 | #define MUX_SEL_TOP1_FSYS1 0x0228 | 411 | #define MUX_SEL_TOP1_FSYS1 0x0228 |
412 | #define MUX_SEL_TOP1_FSYS11 0x022C | ||
368 | #define DIV_TOP13 0x060C | 413 | #define DIV_TOP13 0x060C |
369 | #define DIV_TOP1_FSYS0 0x0624 | 414 | #define DIV_TOP1_FSYS0 0x0624 |
370 | #define DIV_TOP1_FSYS1 0x0628 | 415 | #define DIV_TOP1_FSYS1 0x0628 |
416 | #define DIV_TOP1_FSYS11 0x062C | ||
371 | #define ENABLE_ACLK_TOP13 0x080C | 417 | #define ENABLE_ACLK_TOP13 0x080C |
372 | #define ENABLE_SCLK_TOP1_FSYS0 0x0A24 | 418 | #define ENABLE_SCLK_TOP1_FSYS0 0x0A24 |
373 | #define ENABLE_SCLK_TOP1_FSYS1 0x0A28 | 419 | #define ENABLE_SCLK_TOP1_FSYS1 0x0A28 |
420 | #define ENABLE_SCLK_TOP1_FSYS11 0x0A2C | ||
374 | 421 | ||
375 | /* List of parent clocks for Muxes in CMU_TOP1 */ | 422 | /* List of parent clocks for Muxes in CMU_TOP1 */ |
376 | PNAME(mout_top1_bus0_pll_p) = { "fin_pll", "dout_sclk_bus0_pll" }; | 423 | PNAME(mout_top1_bus0_pll_user_p) = { "fin_pll", "sclk_bus0_pll_b" }; |
377 | PNAME(mout_top1_bus1_pll_p) = { "fin_pll", "dout_sclk_bus1_pll_b" }; | 424 | PNAME(mout_top1_bus1_pll_user_p) = { "fin_pll", "sclk_bus1_pll_b" }; |
378 | PNAME(mout_top1_cc_pll_p) = { "fin_pll", "dout_sclk_cc_pll_b" }; | 425 | PNAME(mout_top1_cc_pll_user_p) = { "fin_pll", "sclk_cc_pll_b" }; |
379 | PNAME(mout_top1_mfc_pll_p) = { "fin_pll", "dout_sclk_mfc_pll_b" }; | 426 | PNAME(mout_top1_mfc_pll_user_p) = { "fin_pll", "sclk_mfc_pll_b" }; |
380 | 427 | ||
381 | PNAME(mout_top1_half_bus0_pll_p) = {"mout_top1_bus0_pll", | 428 | PNAME(mout_top1_bus0_pll_half_p) = {"mout_top1_bus0_pll_user", |
382 | "ffac_top1_bus0_pll_div2"}; | 429 | "ffac_top1_bus0_pll_div2"}; |
383 | PNAME(mout_top1_half_bus1_pll_p) = {"mout_top1_bus1_pll", | 430 | PNAME(mout_top1_bus1_pll_half_p) = {"mout_top1_bus1_pll_user", |
384 | "ffac_top1_bus1_pll_div2"}; | 431 | "ffac_top1_bus1_pll_div2"}; |
385 | PNAME(mout_top1_half_cc_pll_p) = {"mout_top1_cc_pll", | 432 | PNAME(mout_top1_cc_pll_half_p) = {"mout_top1_cc_pll_user", |
386 | "ffac_top1_cc_pll_div2"}; | 433 | "ffac_top1_cc_pll_div2"}; |
387 | PNAME(mout_top1_half_mfc_pll_p) = {"mout_top1_mfc_pll", | 434 | PNAME(mout_top1_mfc_pll_half_p) = {"mout_top1_mfc_pll_user", |
388 | "ffac_top1_mfc_pll_div2"}; | 435 | "ffac_top1_mfc_pll_div2"}; |
389 | 436 | ||
390 | PNAME(mout_top1_group1) = {"mout_top1_half_bus0_pll", | 437 | PNAME(mout_top1_group1) = {"mout_top1_bus0_pll_half", |
391 | "mout_top1_half_bus1_pll", "mout_top1_half_cc_pll", | 438 | "mout_top1_bus1_pll_half", "mout_top1_cc_pll_half", |
392 | "mout_top1_half_mfc_pll"}; | 439 | "mout_top1_mfc_pll_half"}; |
393 | 440 | ||
394 | static unsigned long top1_clk_regs[] __initdata = { | 441 | static unsigned long top1_clk_regs[] __initdata = { |
395 | MUX_SEL_TOP10, | 442 | MUX_SEL_TOP10, |
@@ -397,40 +444,54 @@ static unsigned long top1_clk_regs[] __initdata = { | |||
397 | MUX_SEL_TOP13, | 444 | MUX_SEL_TOP13, |
398 | MUX_SEL_TOP1_FSYS0, | 445 | MUX_SEL_TOP1_FSYS0, |
399 | MUX_SEL_TOP1_FSYS1, | 446 | MUX_SEL_TOP1_FSYS1, |
447 | MUX_SEL_TOP1_FSYS11, | ||
400 | DIV_TOP13, | 448 | DIV_TOP13, |
401 | DIV_TOP1_FSYS0, | 449 | DIV_TOP1_FSYS0, |
402 | DIV_TOP1_FSYS1, | 450 | DIV_TOP1_FSYS1, |
451 | DIV_TOP1_FSYS11, | ||
403 | ENABLE_ACLK_TOP13, | 452 | ENABLE_ACLK_TOP13, |
404 | ENABLE_SCLK_TOP1_FSYS0, | 453 | ENABLE_SCLK_TOP1_FSYS0, |
405 | ENABLE_SCLK_TOP1_FSYS1, | 454 | ENABLE_SCLK_TOP1_FSYS1, |
455 | ENABLE_SCLK_TOP1_FSYS11, | ||
406 | }; | 456 | }; |
407 | 457 | ||
408 | static struct samsung_mux_clock top1_mux_clks[] __initdata = { | 458 | static struct samsung_mux_clock top1_mux_clks[] __initdata = { |
409 | MUX(0, "mout_top1_mfc_pll", mout_top1_mfc_pll_p, MUX_SEL_TOP10, 4, 1), | 459 | MUX(0, "mout_top1_mfc_pll_user", mout_top1_mfc_pll_user_p, |
410 | MUX(0, "mout_top1_cc_pll", mout_top1_cc_pll_p, MUX_SEL_TOP10, 8, 1), | 460 | MUX_SEL_TOP10, 4, 1), |
411 | MUX(0, "mout_top1_bus1_pll", mout_top1_bus1_pll_p, | 461 | MUX(0, "mout_top1_cc_pll_user", mout_top1_cc_pll_user_p, |
462 | MUX_SEL_TOP10, 8, 1), | ||
463 | MUX(0, "mout_top1_bus1_pll_user", mout_top1_bus1_pll_user_p, | ||
412 | MUX_SEL_TOP10, 12, 1), | 464 | MUX_SEL_TOP10, 12, 1), |
413 | MUX(0, "mout_top1_bus0_pll", mout_top1_bus0_pll_p, | 465 | MUX(0, "mout_top1_bus0_pll_user", mout_top1_bus0_pll_user_p, |
414 | MUX_SEL_TOP10, 16, 1), | 466 | MUX_SEL_TOP10, 16, 1), |
415 | 467 | ||
416 | MUX(0, "mout_top1_half_mfc_pll", mout_top1_half_mfc_pll_p, | 468 | MUX(0, "mout_top1_mfc_pll_half", mout_top1_mfc_pll_half_p, |
417 | MUX_SEL_TOP11, 4, 1), | 469 | MUX_SEL_TOP11, 4, 1), |
418 | MUX(0, "mout_top1_half_cc_pll", mout_top1_half_cc_pll_p, | 470 | MUX(0, "mout_top1_cc_pll_half", mout_top1_cc_pll_half_p, |
419 | MUX_SEL_TOP11, 8, 1), | 471 | MUX_SEL_TOP11, 8, 1), |
420 | MUX(0, "mout_top1_half_bus1_pll", mout_top1_half_bus1_pll_p, | 472 | MUX(0, "mout_top1_bus1_pll_half", mout_top1_bus1_pll_half_p, |
421 | MUX_SEL_TOP11, 12, 1), | 473 | MUX_SEL_TOP11, 12, 1), |
422 | MUX(0, "mout_top1_half_bus0_pll", mout_top1_half_bus0_pll_p, | 474 | MUX(0, "mout_top1_bus0_pll_half", mout_top1_bus0_pll_half_p, |
423 | MUX_SEL_TOP11, 16, 1), | 475 | MUX_SEL_TOP11, 16, 1), |
424 | 476 | ||
425 | MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2), | 477 | MUX(0, "mout_aclk_fsys1_200", mout_top1_group1, MUX_SEL_TOP13, 24, 2), |
426 | MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2), | 478 | MUX(0, "mout_aclk_fsys0_200", mout_top1_group1, MUX_SEL_TOP13, 28, 2), |
427 | 479 | ||
428 | MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 24, 2), | 480 | MUX(0, "mout_sclk_phy_fsys0_26m", mout_top1_group1, |
481 | MUX_SEL_TOP1_FSYS0, 0, 2), | ||
482 | MUX(0, "mout_sclk_mmc2", mout_top1_group1, MUX_SEL_TOP1_FSYS0, 16, 2), | ||
429 | MUX(0, "mout_sclk_usbdrd300", mout_top1_group1, | 483 | MUX(0, "mout_sclk_usbdrd300", mout_top1_group1, |
430 | MUX_SEL_TOP1_FSYS0, 28, 2), | 484 | MUX_SEL_TOP1_FSYS0, 28, 2), |
431 | 485 | ||
432 | MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 24, 2), | 486 | MUX(0, "mout_sclk_phy_fsys1", mout_top1_group1, |
433 | MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS1, 28, 2), | 487 | MUX_SEL_TOP1_FSYS1, 0, 2), |
488 | MUX(0, "mout_sclk_ufsunipro20", mout_top1_group1, | ||
489 | MUX_SEL_TOP1_FSYS1, 16, 2), | ||
490 | |||
491 | MUX(0, "mout_sclk_mmc1", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 0, 2), | ||
492 | MUX(0, "mout_sclk_mmc0", mout_top1_group1, MUX_SEL_TOP1_FSYS11, 12, 2), | ||
493 | MUX(0, "mout_sclk_phy_fsys1_26m", mout_top1_group1, | ||
494 | MUX_SEL_TOP1_FSYS11, 24, 2), | ||
434 | }; | 495 | }; |
435 | 496 | ||
436 | static struct samsung_div_clock top1_div_clks[] __initdata = { | 497 | static struct samsung_div_clock top1_div_clks[] __initdata = { |
@@ -439,34 +500,61 @@ static struct samsung_div_clock top1_div_clks[] __initdata = { | |||
439 | DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200", | 500 | DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200", |
440 | DIV_TOP13, 28, 4), | 501 | DIV_TOP13, 28, 4), |
441 | 502 | ||
503 | DIV(DOUT_SCLK_PHY_FSYS1, "dout_sclk_phy_fsys1", | ||
504 | "mout_sclk_phy_fsys1", DIV_TOP1_FSYS1, 0, 6), | ||
505 | |||
506 | DIV(DOUT_SCLK_UFSUNIPRO20, "dout_sclk_ufsunipro20", | ||
507 | "mout_sclk_ufsunipro20", | ||
508 | DIV_TOP1_FSYS1, 16, 6), | ||
509 | |||
442 | DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2", | 510 | DIV(DOUT_SCLK_MMC2, "dout_sclk_mmc2", "mout_sclk_mmc2", |
443 | DIV_TOP1_FSYS0, 24, 4), | 511 | DIV_TOP1_FSYS0, 16, 10), |
444 | DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300", | 512 | DIV(0, "dout_sclk_usbdrd300", "mout_sclk_usbdrd300", |
445 | DIV_TOP1_FSYS0, 28, 4), | 513 | DIV_TOP1_FSYS0, 28, 4), |
446 | 514 | ||
447 | DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1", | 515 | DIV(DOUT_SCLK_MMC1, "dout_sclk_mmc1", "mout_sclk_mmc1", |
448 | DIV_TOP1_FSYS1, 24, 4), | 516 | DIV_TOP1_FSYS11, 0, 10), |
449 | DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0", | 517 | DIV(DOUT_SCLK_MMC0, "dout_sclk_mmc0", "mout_sclk_mmc0", |
450 | DIV_TOP1_FSYS1, 28, 4), | 518 | DIV_TOP1_FSYS11, 12, 10), |
519 | |||
520 | DIV(DOUT_SCLK_PHY_FSYS1_26M, "dout_sclk_phy_fsys1_26m", | ||
521 | "mout_sclk_phy_fsys1_26m", DIV_TOP1_FSYS11, 24, 6), | ||
451 | }; | 522 | }; |
452 | 523 | ||
453 | static struct samsung_gate_clock top1_gate_clks[] __initdata = { | 524 | static struct samsung_gate_clock top1_gate_clks[] __initdata = { |
454 | GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2", | 525 | GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2", |
455 | ENABLE_SCLK_TOP1_FSYS0, 24, CLK_SET_RATE_PARENT, 0), | 526 | ENABLE_SCLK_TOP1_FSYS0, 16, CLK_SET_RATE_PARENT, 0), |
456 | GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300", | 527 | GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300", |
457 | ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0), | 528 | ENABLE_SCLK_TOP1_FSYS0, 28, 0, 0), |
458 | 529 | ||
530 | GATE(CLK_SCLK_PHY_FSYS1, "sclk_phy_fsys1", "dout_sclk_phy_fsys1", | ||
531 | ENABLE_SCLK_TOP1_FSYS1, 0, CLK_SET_RATE_PARENT, 0), | ||
532 | |||
533 | GATE(CLK_SCLK_UFSUNIPRO20, "sclk_ufsunipro20", "dout_sclk_ufsunipro20", | ||
534 | ENABLE_SCLK_TOP1_FSYS1, 16, CLK_SET_RATE_PARENT, 0), | ||
535 | |||
459 | GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1", | 536 | GATE(CLK_SCLK_MMC1, "sclk_mmc1", "dout_sclk_mmc1", |
460 | ENABLE_SCLK_TOP1_FSYS1, 24, CLK_SET_RATE_PARENT, 0), | 537 | ENABLE_SCLK_TOP1_FSYS11, 0, CLK_SET_RATE_PARENT, 0), |
461 | GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0", | 538 | GATE(CLK_SCLK_MMC0, "sclk_mmc0", "dout_sclk_mmc0", |
462 | ENABLE_SCLK_TOP1_FSYS1, 28, CLK_SET_RATE_PARENT, 0), | 539 | ENABLE_SCLK_TOP1_FSYS11, 12, CLK_SET_RATE_PARENT, 0), |
540 | |||
541 | GATE(CLK_ACLK_FSYS0_200, "aclk_fsys0_200", "dout_aclk_fsys0_200", | ||
542 | ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT, 0), | ||
543 | GATE(CLK_ACLK_FSYS1_200, "aclk_fsys1_200", "dout_aclk_fsys1_200", | ||
544 | ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT, 0), | ||
545 | |||
546 | GATE(CLK_SCLK_PHY_FSYS1_26M, "sclk_phy_fsys1_26m", | ||
547 | "dout_sclk_phy_fsys1_26m", ENABLE_SCLK_TOP1_FSYS11, | ||
548 | 24, CLK_SET_RATE_PARENT, 0), | ||
463 | }; | 549 | }; |
464 | 550 | ||
465 | static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = { | 551 | static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = { |
466 | FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll", 1, 2, 0), | 552 | FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll_user", |
467 | FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll", 1, 2, 0), | 553 | 1, 2, 0), |
468 | FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll", 1, 2, 0), | 554 | FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll_user", |
469 | FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll", 1, 2, 0), | 555 | 1, 2, 0), |
556 | FFACTOR(0, "ffac_top1_cc_pll_div2", "mout_top1_cc_pll_user", 1, 2, 0), | ||
557 | FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll_user", 1, 2, 0), | ||
470 | }; | 558 | }; |
471 | 559 | ||
472 | static struct samsung_cmu_info top1_cmu_info __initdata = { | 560 | static struct samsung_cmu_info top1_cmu_info __initdata = { |
@@ -501,7 +589,7 @@ CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1", | |||
501 | /* | 589 | /* |
502 | * List of parent clocks for Muxes in CMU_CCORE | 590 | * List of parent clocks for Muxes in CMU_CCORE |
503 | */ | 591 | */ |
504 | PNAME(mout_aclk_ccore_133_p) = { "fin_pll", "dout_aclk_ccore_133" }; | 592 | PNAME(mout_aclk_ccore_133_user_p) = { "fin_pll", "aclk_ccore_133" }; |
505 | 593 | ||
506 | static unsigned long ccore_clk_regs[] __initdata = { | 594 | static unsigned long ccore_clk_regs[] __initdata = { |
507 | MUX_SEL_CCORE, | 595 | MUX_SEL_CCORE, |
@@ -509,7 +597,7 @@ static unsigned long ccore_clk_regs[] __initdata = { | |||
509 | }; | 597 | }; |
510 | 598 | ||
511 | static struct samsung_mux_clock ccore_mux_clks[] __initdata = { | 599 | static struct samsung_mux_clock ccore_mux_clks[] __initdata = { |
512 | MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_p, | 600 | MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_user_p, |
513 | MUX_SEL_CCORE, 1, 1), | 601 | MUX_SEL_CCORE, 1, 1), |
514 | }; | 602 | }; |
515 | 603 | ||
@@ -542,8 +630,8 @@ CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore", | |||
542 | #define ENABLE_SCLK_PERIC0 0x0A00 | 630 | #define ENABLE_SCLK_PERIC0 0x0A00 |
543 | 631 | ||
544 | /* List of parent clocks for Muxes in CMU_PERIC0 */ | 632 | /* List of parent clocks for Muxes in CMU_PERIC0 */ |
545 | PNAME(mout_aclk_peric0_66_p) = { "fin_pll", "dout_aclk_peric0_66" }; | 633 | PNAME(mout_aclk_peric0_66_user_p) = { "fin_pll", "aclk_peric0_66" }; |
546 | PNAME(mout_sclk_uart0_p) = { "fin_pll", "sclk_uart0" }; | 634 | PNAME(mout_sclk_uart0_user_p) = { "fin_pll", "sclk_uart0" }; |
547 | 635 | ||
548 | static unsigned long peric0_clk_regs[] __initdata = { | 636 | static unsigned long peric0_clk_regs[] __initdata = { |
549 | MUX_SEL_PERIC0, | 637 | MUX_SEL_PERIC0, |
@@ -552,9 +640,9 @@ static unsigned long peric0_clk_regs[] __initdata = { | |||
552 | }; | 640 | }; |
553 | 641 | ||
554 | static struct samsung_mux_clock peric0_mux_clks[] __initdata = { | 642 | static struct samsung_mux_clock peric0_mux_clks[] __initdata = { |
555 | MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_p, | 643 | MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_user_p, |
556 | MUX_SEL_PERIC0, 0, 1), | 644 | MUX_SEL_PERIC0, 0, 1), |
557 | MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_p, | 645 | MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_user_p, |
558 | MUX_SEL_PERIC0, 16, 1), | 646 | MUX_SEL_PERIC0, 16, 1), |
559 | }; | 647 | }; |
560 | 648 | ||
@@ -611,15 +699,15 @@ CLK_OF_DECLARE(exynos7_clk_peric0, "samsung,exynos7-clock-peric0", | |||
611 | exynos7_clk_peric0_init); | 699 | exynos7_clk_peric0_init); |
612 | 700 | ||
613 | /* List of parent clocks for Muxes in CMU_PERIC1 */ | 701 | /* List of parent clocks for Muxes in CMU_PERIC1 */ |
614 | PNAME(mout_aclk_peric1_66_p) = { "fin_pll", "dout_aclk_peric1_66" }; | 702 | PNAME(mout_aclk_peric1_66_user_p) = { "fin_pll", "aclk_peric1_66" }; |
615 | PNAME(mout_sclk_uart1_p) = { "fin_pll", "sclk_uart1" }; | 703 | PNAME(mout_sclk_uart1_user_p) = { "fin_pll", "sclk_uart1" }; |
616 | PNAME(mout_sclk_uart2_p) = { "fin_pll", "sclk_uart2" }; | 704 | PNAME(mout_sclk_uart2_user_p) = { "fin_pll", "sclk_uart2" }; |
617 | PNAME(mout_sclk_uart3_p) = { "fin_pll", "sclk_uart3" }; | 705 | PNAME(mout_sclk_uart3_user_p) = { "fin_pll", "sclk_uart3" }; |
618 | PNAME(mout_sclk_spi0_p) = { "fin_pll", "sclk_spi0" }; | 706 | PNAME(mout_sclk_spi0_user_p) = { "fin_pll", "sclk_spi0" }; |
619 | PNAME(mout_sclk_spi1_p) = { "fin_pll", "sclk_spi1" }; | 707 | PNAME(mout_sclk_spi1_user_p) = { "fin_pll", "sclk_spi1" }; |
620 | PNAME(mout_sclk_spi2_p) = { "fin_pll", "sclk_spi2" }; | 708 | PNAME(mout_sclk_spi2_user_p) = { "fin_pll", "sclk_spi2" }; |
621 | PNAME(mout_sclk_spi3_p) = { "fin_pll", "sclk_spi3" }; | 709 | PNAME(mout_sclk_spi3_user_p) = { "fin_pll", "sclk_spi3" }; |
622 | PNAME(mout_sclk_spi4_p) = { "fin_pll", "sclk_spi4" }; | 710 | PNAME(mout_sclk_spi4_user_p) = { "fin_pll", "sclk_spi4" }; |
623 | 711 | ||
624 | static unsigned long peric1_clk_regs[] __initdata = { | 712 | static unsigned long peric1_clk_regs[] __initdata = { |
625 | MUX_SEL_PERIC10, | 713 | MUX_SEL_PERIC10, |
@@ -630,24 +718,24 @@ static unsigned long peric1_clk_regs[] __initdata = { | |||
630 | }; | 718 | }; |
631 | 719 | ||
632 | static struct samsung_mux_clock peric1_mux_clks[] __initdata = { | 720 | static struct samsung_mux_clock peric1_mux_clks[] __initdata = { |
633 | MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_p, | 721 | MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_user_p, |
634 | MUX_SEL_PERIC10, 0, 1), | 722 | MUX_SEL_PERIC10, 0, 1), |
635 | 723 | ||
636 | MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_p, | 724 | MUX_F(0, "mout_sclk_spi0_user", mout_sclk_spi0_user_p, |
637 | MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0), | 725 | MUX_SEL_PERIC11, 0, 1, CLK_SET_RATE_PARENT, 0), |
638 | MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_p, | 726 | MUX_F(0, "mout_sclk_spi1_user", mout_sclk_spi1_user_p, |
639 | MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0), | 727 | MUX_SEL_PERIC11, 4, 1, CLK_SET_RATE_PARENT, 0), |
640 | MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_p, | 728 | MUX_F(0, "mout_sclk_spi2_user", mout_sclk_spi2_user_p, |
641 | MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0), | 729 | MUX_SEL_PERIC11, 8, 1, CLK_SET_RATE_PARENT, 0), |
642 | MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_p, | 730 | MUX_F(0, "mout_sclk_spi3_user", mout_sclk_spi3_user_p, |
643 | MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0), | 731 | MUX_SEL_PERIC11, 12, 1, CLK_SET_RATE_PARENT, 0), |
644 | MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_p, | 732 | MUX_F(0, "mout_sclk_spi4_user", mout_sclk_spi4_user_p, |
645 | MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0), | 733 | MUX_SEL_PERIC11, 16, 1, CLK_SET_RATE_PARENT, 0), |
646 | MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_p, | 734 | MUX(0, "mout_sclk_uart1_user", mout_sclk_uart1_user_p, |
647 | MUX_SEL_PERIC11, 20, 1), | 735 | MUX_SEL_PERIC11, 20, 1), |
648 | MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_p, | 736 | MUX(0, "mout_sclk_uart2_user", mout_sclk_uart2_user_p, |
649 | MUX_SEL_PERIC11, 24, 1), | 737 | MUX_SEL_PERIC11, 24, 1), |
650 | MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_p, | 738 | MUX(0, "mout_sclk_uart3_user", mout_sclk_uart3_user_p, |
651 | MUX_SEL_PERIC11, 28, 1), | 739 | MUX_SEL_PERIC11, 28, 1), |
652 | }; | 740 | }; |
653 | 741 | ||
@@ -735,7 +823,7 @@ CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1", | |||
735 | #define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10 | 823 | #define ENABLE_SCLK_PERIS_SECURE_CHIPID 0x0A10 |
736 | 824 | ||
737 | /* List of parent clocks for Muxes in CMU_PERIS */ | 825 | /* List of parent clocks for Muxes in CMU_PERIS */ |
738 | PNAME(mout_aclk_peris_66_p) = { "fin_pll", "dout_aclk_peris_66" }; | 826 | PNAME(mout_aclk_peris_66_user_p) = { "fin_pll", "aclk_peris_66" }; |
739 | 827 | ||
740 | static unsigned long peris_clk_regs[] __initdata = { | 828 | static unsigned long peris_clk_regs[] __initdata = { |
741 | MUX_SEL_PERIS, | 829 | MUX_SEL_PERIS, |
@@ -747,7 +835,7 @@ static unsigned long peris_clk_regs[] __initdata = { | |||
747 | 835 | ||
748 | static struct samsung_mux_clock peris_mux_clks[] __initdata = { | 836 | static struct samsung_mux_clock peris_mux_clks[] __initdata = { |
749 | MUX(0, "mout_aclk_peris_66_user", | 837 | MUX(0, "mout_aclk_peris_66_user", |
750 | mout_aclk_peris_66_p, MUX_SEL_PERIS, 0, 1), | 838 | mout_aclk_peris_66_user_p, MUX_SEL_PERIS, 0, 1), |
751 | }; | 839 | }; |
752 | 840 | ||
753 | static struct samsung_gate_clock peris_gate_clks[] __initdata = { | 841 | static struct samsung_gate_clock peris_gate_clks[] __initdata = { |
@@ -795,17 +883,17 @@ CLK_OF_DECLARE(exynos7_clk_peris, "samsung,exynos7-clock-peris", | |||
795 | /* | 883 | /* |
796 | * List of parent clocks for Muxes in CMU_FSYS0 | 884 | * List of parent clocks for Muxes in CMU_FSYS0 |
797 | */ | 885 | */ |
798 | PNAME(mout_aclk_fsys0_200_p) = { "fin_pll", "dout_aclk_fsys0_200" }; | 886 | PNAME(mout_aclk_fsys0_200_user_p) = { "fin_pll", "aclk_fsys0_200" }; |
799 | PNAME(mout_sclk_mmc2_p) = { "fin_pll", "sclk_mmc2" }; | 887 | PNAME(mout_sclk_mmc2_user_p) = { "fin_pll", "sclk_mmc2" }; |
800 | 888 | ||
801 | PNAME(mout_sclk_usbdrd300_p) = { "fin_pll", "sclk_usbdrd300" }; | 889 | PNAME(mout_sclk_usbdrd300_user_p) = { "fin_pll", "sclk_usbdrd300" }; |
802 | PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_p) = { "fin_pll", | 890 | PNAME(mout_phyclk_usbdrd300_udrd30_phyclk_user_p) = { "fin_pll", |
803 | "phyclk_usbdrd300_udrd30_phyclock" }; | 891 | "phyclk_usbdrd300_udrd30_phyclock" }; |
804 | PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_p) = { "fin_pll", | 892 | PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p) = { "fin_pll", |
805 | "phyclk_usbdrd300_udrd30_pipe_pclk" }; | 893 | "phyclk_usbdrd300_udrd30_pipe_pclk" }; |
806 | 894 | ||
807 | /* fixed rate clocks used in the FSYS0 block */ | 895 | /* fixed rate clocks used in the FSYS0 block */ |
808 | struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = { | 896 | static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = { |
809 | FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, | 897 | FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, |
810 | CLK_IS_ROOT, 60000000), | 898 | CLK_IS_ROOT, 60000000), |
811 | FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, | 899 | FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, |
@@ -824,29 +912,30 @@ static unsigned long fsys0_clk_regs[] __initdata = { | |||
824 | }; | 912 | }; |
825 | 913 | ||
826 | static struct samsung_mux_clock fsys0_mux_clks[] __initdata = { | 914 | static struct samsung_mux_clock fsys0_mux_clks[] __initdata = { |
827 | MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_p, | 915 | MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_user_p, |
828 | MUX_SEL_FSYS00, 24, 1), | 916 | MUX_SEL_FSYS00, 24, 1), |
829 | 917 | ||
830 | MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_p, MUX_SEL_FSYS01, 24, 1), | 918 | MUX(0, "mout_sclk_mmc2_user", mout_sclk_mmc2_user_p, |
831 | MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_p, | 919 | MUX_SEL_FSYS01, 24, 1), |
920 | MUX(0, "mout_sclk_usbdrd300_user", mout_sclk_usbdrd300_user_p, | ||
832 | MUX_SEL_FSYS01, 28, 1), | 921 | MUX_SEL_FSYS01, 28, 1), |
833 | 922 | ||
834 | MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user", | 923 | MUX(0, "mout_phyclk_usbdrd300_udrd30_pipe_pclk_user", |
835 | mout_phyclk_usbdrd300_udrd30_pipe_pclk_p, | 924 | mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p, |
836 | MUX_SEL_FSYS02, 24, 1), | 925 | MUX_SEL_FSYS02, 24, 1), |
837 | MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user", | 926 | MUX(0, "mout_phyclk_usbdrd300_udrd30_phyclk_user", |
838 | mout_phyclk_usbdrd300_udrd30_phyclk_p, | 927 | mout_phyclk_usbdrd300_udrd30_phyclk_user_p, |
839 | MUX_SEL_FSYS02, 28, 1), | 928 | MUX_SEL_FSYS02, 28, 1), |
840 | }; | 929 | }; |
841 | 930 | ||
842 | static struct samsung_gate_clock fsys0_gate_clks[] __initdata = { | 931 | static struct samsung_gate_clock fsys0_gate_clks[] __initdata = { |
843 | GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x", | ||
844 | "mout_aclk_fsys0_200_user", | ||
845 | ENABLE_ACLK_FSYS00, 19, 0, 0), | ||
846 | GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user", | 932 | GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user", |
847 | ENABLE_ACLK_FSYS00, 3, 0, 0), | 933 | ENABLE_ACLK_FSYS00, 3, 0, 0), |
848 | GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user", | 934 | GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user", |
849 | ENABLE_ACLK_FSYS00, 4, 0, 0), | 935 | ENABLE_ACLK_FSYS00, 4, 0, 0), |
936 | GATE(ACLK_AXIUS_USBDRD30X_FSYS0X, "aclk_axius_usbdrd30x_fsys0x", | ||
937 | "mout_aclk_fsys0_200_user", | ||
938 | ENABLE_ACLK_FSYS00, 19, 0, 0), | ||
850 | 939 | ||
851 | GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user", | 940 | GATE(ACLK_USBDRD300, "aclk_usbdrd300", "mout_aclk_fsys0_200_user", |
852 | ENABLE_ACLK_FSYS01, 29, 0, 0), | 941 | ENABLE_ACLK_FSYS01, 29, 0, 0), |
@@ -874,11 +963,13 @@ static struct samsung_gate_clock fsys0_gate_clks[] __initdata = { | |||
874 | }; | 963 | }; |
875 | 964 | ||
876 | static struct samsung_cmu_info fsys0_cmu_info __initdata = { | 965 | static struct samsung_cmu_info fsys0_cmu_info __initdata = { |
966 | .fixed_clks = fixed_rate_clks_fsys0, | ||
967 | .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys0), | ||
877 | .mux_clks = fsys0_mux_clks, | 968 | .mux_clks = fsys0_mux_clks, |
878 | .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks), | 969 | .nr_mux_clks = ARRAY_SIZE(fsys0_mux_clks), |
879 | .gate_clks = fsys0_gate_clks, | 970 | .gate_clks = fsys0_gate_clks, |
880 | .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks), | 971 | .nr_gate_clks = ARRAY_SIZE(fsys0_gate_clks), |
881 | .nr_clk_ids = TOP1_NR_CLK, | 972 | .nr_clk_ids = FSYS0_NR_CLK, |
882 | .clk_regs = fsys0_clk_regs, | 973 | .clk_regs = fsys0_clk_regs, |
883 | .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs), | 974 | .nr_clk_regs = ARRAY_SIZE(fsys0_clk_regs), |
884 | }; | 975 | }; |
@@ -894,42 +985,122 @@ CLK_OF_DECLARE(exynos7_clk_fsys0, "samsung,exynos7-clock-fsys0", | |||
894 | /* Register Offset definitions for CMU_FSYS1 (0x156E0000) */ | 985 | /* Register Offset definitions for CMU_FSYS1 (0x156E0000) */ |
895 | #define MUX_SEL_FSYS10 0x0200 | 986 | #define MUX_SEL_FSYS10 0x0200 |
896 | #define MUX_SEL_FSYS11 0x0204 | 987 | #define MUX_SEL_FSYS11 0x0204 |
988 | #define MUX_SEL_FSYS12 0x0208 | ||
989 | #define DIV_FSYS1 0x0600 | ||
897 | #define ENABLE_ACLK_FSYS1 0x0800 | 990 | #define ENABLE_ACLK_FSYS1 0x0800 |
991 | #define ENABLE_PCLK_FSYS1 0x0900 | ||
992 | #define ENABLE_SCLK_FSYS11 0x0A04 | ||
993 | #define ENABLE_SCLK_FSYS12 0x0A08 | ||
994 | #define ENABLE_SCLK_FSYS13 0x0A0C | ||
898 | 995 | ||
899 | /* | 996 | /* |
900 | * List of parent clocks for Muxes in CMU_FSYS1 | 997 | * List of parent clocks for Muxes in CMU_FSYS1 |
901 | */ | 998 | */ |
902 | PNAME(mout_aclk_fsys1_200_p) = { "fin_pll", "dout_aclk_fsys1_200" }; | 999 | PNAME(mout_aclk_fsys1_200_user_p) = { "fin_pll", "aclk_fsys1_200" }; |
903 | PNAME(mout_sclk_mmc0_p) = { "fin_pll", "sclk_mmc0" }; | 1000 | PNAME(mout_fsys1_group_p) = { "fin_pll", "fin_pll_26m", |
904 | PNAME(mout_sclk_mmc1_p) = { "fin_pll", "sclk_mmc1" }; | 1001 | "sclk_phy_fsys1_26m" }; |
1002 | PNAME(mout_sclk_mmc0_user_p) = { "fin_pll", "sclk_mmc0" }; | ||
1003 | PNAME(mout_sclk_mmc1_user_p) = { "fin_pll", "sclk_mmc1" }; | ||
1004 | PNAME(mout_sclk_ufsunipro20_user_p) = { "fin_pll", "sclk_ufsunipro20" }; | ||
1005 | PNAME(mout_phyclk_ufs20_tx0_user_p) = { "fin_pll", "phyclk_ufs20_tx0_symbol" }; | ||
1006 | PNAME(mout_phyclk_ufs20_rx0_user_p) = { "fin_pll", "phyclk_ufs20_rx0_symbol" }; | ||
1007 | PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" }; | ||
1008 | |||
1009 | /* fixed rate clocks used in the FSYS1 block */ | ||
1010 | static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = { | ||
1011 | FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL, | ||
1012 | CLK_IS_ROOT, 300000000), | ||
1013 | FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL, | ||
1014 | CLK_IS_ROOT, 300000000), | ||
1015 | FRATE(PHYCLK_UFS20_RX1_SYMBOL, "phyclk_ufs20_rx1_symbol", NULL, | ||
1016 | CLK_IS_ROOT, 300000000), | ||
1017 | }; | ||
905 | 1018 | ||
906 | static unsigned long fsys1_clk_regs[] __initdata = { | 1019 | static unsigned long fsys1_clk_regs[] __initdata = { |
907 | MUX_SEL_FSYS10, | 1020 | MUX_SEL_FSYS10, |
908 | MUX_SEL_FSYS11, | 1021 | MUX_SEL_FSYS11, |
1022 | MUX_SEL_FSYS12, | ||
1023 | DIV_FSYS1, | ||
909 | ENABLE_ACLK_FSYS1, | 1024 | ENABLE_ACLK_FSYS1, |
1025 | ENABLE_PCLK_FSYS1, | ||
1026 | ENABLE_SCLK_FSYS11, | ||
1027 | ENABLE_SCLK_FSYS12, | ||
1028 | ENABLE_SCLK_FSYS13, | ||
910 | }; | 1029 | }; |
911 | 1030 | ||
912 | static struct samsung_mux_clock fsys1_mux_clks[] __initdata = { | 1031 | static struct samsung_mux_clock fsys1_mux_clks[] __initdata = { |
913 | MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_p, | 1032 | MUX(MOUT_FSYS1_PHYCLK_SEL1, "mout_fsys1_phyclk_sel1", |
1033 | mout_fsys1_group_p, MUX_SEL_FSYS10, 16, 2), | ||
1034 | MUX(0, "mout_fsys1_phyclk_sel0", mout_fsys1_group_p, | ||
1035 | MUX_SEL_FSYS10, 20, 2), | ||
1036 | MUX(0, "mout_aclk_fsys1_200_user", mout_aclk_fsys1_200_user_p, | ||
914 | MUX_SEL_FSYS10, 28, 1), | 1037 | MUX_SEL_FSYS10, 28, 1), |
915 | 1038 | ||
916 | MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_p, MUX_SEL_FSYS11, 24, 1), | 1039 | MUX(0, "mout_sclk_mmc1_user", mout_sclk_mmc1_user_p, |
917 | MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_p, MUX_SEL_FSYS11, 28, 1), | 1040 | MUX_SEL_FSYS11, 24, 1), |
1041 | MUX(0, "mout_sclk_mmc0_user", mout_sclk_mmc0_user_p, | ||
1042 | MUX_SEL_FSYS11, 28, 1), | ||
1043 | MUX(0, "mout_sclk_ufsunipro20_user", mout_sclk_ufsunipro20_user_p, | ||
1044 | MUX_SEL_FSYS11, 20, 1), | ||
1045 | |||
1046 | MUX(0, "mout_phyclk_ufs20_rx1_symbol_user", | ||
1047 | mout_phyclk_ufs20_rx1_user_p, MUX_SEL_FSYS12, 16, 1), | ||
1048 | MUX(0, "mout_phyclk_ufs20_rx0_symbol_user", | ||
1049 | mout_phyclk_ufs20_rx0_user_p, MUX_SEL_FSYS12, 24, 1), | ||
1050 | MUX(0, "mout_phyclk_ufs20_tx0_symbol_user", | ||
1051 | mout_phyclk_ufs20_tx0_user_p, MUX_SEL_FSYS12, 28, 1), | ||
1052 | }; | ||
1053 | |||
1054 | static struct samsung_div_clock fsys1_div_clks[] __initdata = { | ||
1055 | DIV(DOUT_PCLK_FSYS1, "dout_pclk_fsys1", "mout_aclk_fsys1_200_user", | ||
1056 | DIV_FSYS1, 0, 2), | ||
918 | }; | 1057 | }; |
919 | 1058 | ||
920 | static struct samsung_gate_clock fsys1_gate_clks[] __initdata = { | 1059 | static struct samsung_gate_clock fsys1_gate_clks[] __initdata = { |
1060 | GATE(SCLK_UFSUNIPRO20_USER, "sclk_ufsunipro20_user", | ||
1061 | "mout_sclk_ufsunipro20_user", | ||
1062 | ENABLE_SCLK_FSYS11, 20, 0, 0), | ||
1063 | |||
921 | GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user", | 1064 | GATE(ACLK_MMC1, "aclk_mmc1", "mout_aclk_fsys1_200_user", |
922 | ENABLE_ACLK_FSYS1, 29, 0, 0), | 1065 | ENABLE_ACLK_FSYS1, 29, 0, 0), |
923 | GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user", | 1066 | GATE(ACLK_MMC0, "aclk_mmc0", "mout_aclk_fsys1_200_user", |
924 | ENABLE_ACLK_FSYS1, 30, 0, 0), | 1067 | ENABLE_ACLK_FSYS1, 30, 0, 0), |
1068 | |||
1069 | GATE(ACLK_UFS20_LINK, "aclk_ufs20_link", "dout_pclk_fsys1", | ||
1070 | ENABLE_ACLK_FSYS1, 31, 0, 0), | ||
1071 | GATE(PCLK_GPIO_FSYS1, "pclk_gpio_fsys1", "mout_aclk_fsys1_200_user", | ||
1072 | ENABLE_PCLK_FSYS1, 30, 0, 0), | ||
1073 | |||
1074 | GATE(PHYCLK_UFS20_RX1_SYMBOL_USER, "phyclk_ufs20_rx1_symbol_user", | ||
1075 | "mout_phyclk_ufs20_rx1_symbol_user", | ||
1076 | ENABLE_SCLK_FSYS12, 16, 0, 0), | ||
1077 | GATE(PHYCLK_UFS20_RX0_SYMBOL_USER, "phyclk_ufs20_rx0_symbol_user", | ||
1078 | "mout_phyclk_ufs20_rx0_symbol_user", | ||
1079 | ENABLE_SCLK_FSYS12, 24, 0, 0), | ||
1080 | GATE(PHYCLK_UFS20_TX0_SYMBOL_USER, "phyclk_ufs20_tx0_symbol_user", | ||
1081 | "mout_phyclk_ufs20_tx0_symbol_user", | ||
1082 | ENABLE_SCLK_FSYS12, 28, 0, 0), | ||
1083 | |||
1084 | GATE(OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY, | ||
1085 | "oscclk_phy_clkout_embedded_combo_phy", | ||
1086 | "fin_pll", | ||
1087 | ENABLE_SCLK_FSYS12, 4, CLK_IGNORE_UNUSED, 0), | ||
1088 | |||
1089 | GATE(SCLK_COMBO_PHY_EMBEDDED_26M, "sclk_combo_phy_embedded_26m", | ||
1090 | "mout_fsys1_phyclk_sel1", | ||
1091 | ENABLE_SCLK_FSYS13, 24, CLK_IGNORE_UNUSED, 0), | ||
925 | }; | 1092 | }; |
926 | 1093 | ||
927 | static struct samsung_cmu_info fsys1_cmu_info __initdata = { | 1094 | static struct samsung_cmu_info fsys1_cmu_info __initdata = { |
1095 | .fixed_clks = fixed_rate_clks_fsys1, | ||
1096 | .nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys1), | ||
928 | .mux_clks = fsys1_mux_clks, | 1097 | .mux_clks = fsys1_mux_clks, |
929 | .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks), | 1098 | .nr_mux_clks = ARRAY_SIZE(fsys1_mux_clks), |
1099 | .div_clks = fsys1_div_clks, | ||
1100 | .nr_div_clks = ARRAY_SIZE(fsys1_div_clks), | ||
930 | .gate_clks = fsys1_gate_clks, | 1101 | .gate_clks = fsys1_gate_clks, |
931 | .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks), | 1102 | .nr_gate_clks = ARRAY_SIZE(fsys1_gate_clks), |
932 | .nr_clk_ids = TOP1_NR_CLK, | 1103 | .nr_clk_ids = FSYS1_NR_CLK, |
933 | .clk_regs = fsys1_clk_regs, | 1104 | .clk_regs = fsys1_clk_regs, |
934 | .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs), | 1105 | .nr_clk_regs = ARRAY_SIZE(fsys1_clk_regs), |
935 | }; | 1106 | }; |
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c index b1df7b2f1e97..4abf21172625 100644 --- a/drivers/clk/shmobile/clk-mstp.c +++ b/drivers/clk/shmobile/clk-mstp.c | |||
@@ -214,7 +214,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) | |||
214 | break; | 214 | break; |
215 | 215 | ||
216 | if (clkidx >= MSTP_MAX_CLOCKS) { | 216 | if (clkidx >= MSTP_MAX_CLOCKS) { |
217 | pr_err("%s: invalid clock %s %s index %u)\n", | 217 | pr_err("%s: invalid clock %s %s index %u\n", |
218 | __func__, np->name, name, clkidx); | 218 | __func__, np->name, name, clkidx); |
219 | continue; | 219 | continue; |
220 | } | 220 | } |
diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/shmobile/clk-r8a7778.c index 87c1d2f2fb57..b1741551fff2 100644 --- a/drivers/clk/shmobile/clk-r8a7778.c +++ b/drivers/clk/shmobile/clk-r8a7778.c | |||
@@ -20,10 +20,10 @@ struct r8a7778_cpg { | |||
20 | }; | 20 | }; |
21 | 21 | ||
22 | /* PLL multipliers per bits 11, 12, and 18 of MODEMR */ | 22 | /* PLL multipliers per bits 11, 12, and 18 of MODEMR */ |
23 | struct { | 23 | static const struct { |
24 | unsigned long plla_mult; | 24 | unsigned long plla_mult; |
25 | unsigned long pllb_mult; | 25 | unsigned long pllb_mult; |
26 | } r8a7778_rates[] __initdata = { | 26 | } r8a7778_rates[] __initconst = { |
27 | [0] = { 21, 21 }, | 27 | [0] = { 21, 21 }, |
28 | [1] = { 24, 24 }, | 28 | [1] = { 24, 24 }, |
29 | [2] = { 28, 28 }, | 29 | [2] = { 28, 28 }, |
@@ -34,10 +34,10 @@ struct { | |||
34 | }; | 34 | }; |
35 | 35 | ||
36 | /* Clock dividers per bits 1 and 2 of MODEMR */ | 36 | /* Clock dividers per bits 1 and 2 of MODEMR */ |
37 | struct { | 37 | static const struct { |
38 | const char *name; | 38 | const char *name; |
39 | unsigned int div[4]; | 39 | unsigned int div[4]; |
40 | } r8a7778_divs[6] __initdata = { | 40 | } r8a7778_divs[6] __initconst = { |
41 | { "b", { 12, 12, 16, 18 } }, | 41 | { "b", { 12, 12, 16, 18 } }, |
42 | { "out", { 12, 12, 16, 18 } }, | 42 | { "out", { 12, 12, 16, 18 } }, |
43 | { "p", { 16, 12, 16, 12 } }, | 43 | { "p", { 16, 12, 16, 12 } }, |
diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c index a98e21fe773a..957aae63e7cc 100644 --- a/drivers/clk/sirf/clk-atlas7.c +++ b/drivers/clk/sirf/clk-atlas7.c | |||
@@ -205,18 +205,11 @@ | |||
205 | #define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530 | 205 | #define SIRFSOC_CLKC_LEAF_CLK_EN7_SET 0x0530 |
206 | #define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548 | 206 | #define SIRFSOC_CLKC_LEAF_CLK_EN8_SET 0x0548 |
207 | 207 | ||
208 | 208 | #define SIRFSOC_NOC_CLK_IDLEREQ_SET 0x02D0 | |
209 | static void __iomem *sirfsoc_clk_vbase; | 209 | #define SIRFSOC_NOC_CLK_IDLEREQ_CLR 0x02D4 |
210 | static struct clk_onecell_data clk_data; | 210 | #define SIRFSOC_NOC_CLK_SLVRDY_SET 0x02E8 |
211 | 211 | #define SIRFSOC_NOC_CLK_SLVRDY_CLR 0x02EC | |
212 | static const struct clk_div_table pll_div_table[] = { | 212 | #define SIRFSOC_NOC_CLK_IDLE_STATUS 0x02F4 |
213 | { .val = 0, .div = 1 }, | ||
214 | { .val = 1, .div = 2 }, | ||
215 | { .val = 2, .div = 4 }, | ||
216 | { .val = 3, .div = 8 }, | ||
217 | { .val = 4, .div = 16 }, | ||
218 | { .val = 5, .div = 32 }, | ||
219 | }; | ||
220 | 213 | ||
221 | struct clk_pll { | 214 | struct clk_pll { |
222 | struct clk_hw hw; | 215 | struct clk_hw hw; |
@@ -231,10 +224,18 @@ struct clk_dto { | |||
231 | }; | 224 | }; |
232 | #define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw) | 225 | #define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw) |
233 | 226 | ||
227 | enum clk_unit_type { | ||
228 | CLK_UNIT_NOC_OTHER, | ||
229 | CLK_UNIT_NOC_CLOCK, | ||
230 | CLK_UNIT_NOC_SOCKET, | ||
231 | }; | ||
232 | |||
234 | struct clk_unit { | 233 | struct clk_unit { |
235 | struct clk_hw hw; | 234 | struct clk_hw hw; |
236 | u16 regofs; | 235 | u16 regofs; |
237 | u16 bit; | 236 | u16 bit; |
237 | u32 type; | ||
238 | u8 idle_bit; | ||
238 | spinlock_t *lock; | 239 | spinlock_t *lock; |
239 | }; | 240 | }; |
240 | #define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw) | 241 | #define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw) |
@@ -272,6 +273,8 @@ struct atlas7_unit_init_data { | |||
272 | unsigned long flags; | 273 | unsigned long flags; |
273 | u32 regofs; | 274 | u32 regofs; |
274 | u8 bit; | 275 | u8 bit; |
276 | u32 type; | ||
277 | u8 idle_bit; | ||
275 | spinlock_t *lock; | 278 | spinlock_t *lock; |
276 | }; | 279 | }; |
277 | 280 | ||
@@ -284,6 +287,18 @@ struct atlas7_reset_desc { | |||
284 | spinlock_t *lock; | 287 | spinlock_t *lock; |
285 | }; | 288 | }; |
286 | 289 | ||
290 | static void __iomem *sirfsoc_clk_vbase; | ||
291 | static struct clk_onecell_data clk_data; | ||
292 | |||
293 | static const struct clk_div_table pll_div_table[] = { | ||
294 | { .val = 0, .div = 1 }, | ||
295 | { .val = 1, .div = 2 }, | ||
296 | { .val = 2, .div = 4 }, | ||
297 | { .val = 3, .div = 8 }, | ||
298 | { .val = 4, .div = 16 }, | ||
299 | { .val = 5, .div = 32 }, | ||
300 | }; | ||
301 | |||
287 | static DEFINE_SPINLOCK(cpupll_ctrl1_lock); | 302 | static DEFINE_SPINLOCK(cpupll_ctrl1_lock); |
288 | static DEFINE_SPINLOCK(mempll_ctrl1_lock); | 303 | static DEFINE_SPINLOCK(mempll_ctrl1_lock); |
289 | static DEFINE_SPINLOCK(sys0pll_ctrl1_lock); | 304 | static DEFINE_SPINLOCK(sys0pll_ctrl1_lock); |
@@ -1040,148 +1055,148 @@ static struct atlas7_mux_init_data mux_list[] __initdata = { | |||
1040 | /* new unit should add start from the tail of list */ | 1055 | /* new unit should add start from the tail of list */ |
1041 | static struct atlas7_unit_init_data unit_list[] __initdata = { | 1056 | static struct atlas7_unit_init_data unit_list[] __initdata = { |
1042 | /* unit_name, parent_name, flags, regofs, bit, lock */ | 1057 | /* unit_name, parent_name, flags, regofs, bit, lock */ |
1043 | { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock }, | 1058 | { 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, 0, 0, &root0_gate_lock }, |
1044 | { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock }, | 1059 | { 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, 0, 0, &root0_gate_lock }, |
1045 | { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock }, | 1060 | { 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, 0, 0, &root0_gate_lock }, |
1046 | { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock }, | 1061 | { 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, 0, 0, &root0_gate_lock }, |
1047 | { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock }, | 1062 | { 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, 0, 0, &root0_gate_lock }, |
1048 | { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock }, | 1063 | { 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, 0, 0, &root0_gate_lock }, |
1049 | { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock }, | 1064 | { 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, 0, 0, &root0_gate_lock }, |
1050 | { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock }, | 1065 | { 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, 0, 0, &root0_gate_lock }, |
1051 | { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock }, | 1066 | { 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, 0, 0, &root0_gate_lock }, |
1052 | { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock }, | 1067 | { 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, 0, 0, &root0_gate_lock }, |
1053 | { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock }, | 1068 | { 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, 0, 0, &root0_gate_lock }, |
1054 | { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock }, | 1069 | { 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, 0, 0, &root0_gate_lock }, |
1055 | { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock }, | 1070 | { 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, 0, 0, &root0_gate_lock }, |
1056 | { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock }, | 1071 | { 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, 0, 0, &root0_gate_lock }, |
1057 | { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock }, | 1072 | { 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, 0, 0, &root0_gate_lock }, |
1058 | { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock }, | 1073 | { 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, 0, 0, &root0_gate_lock }, |
1059 | { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock }, | 1074 | { 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, 0, 0, &root0_gate_lock }, |
1060 | { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock }, | 1075 | { 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, 0, 0, &root0_gate_lock }, |
1061 | { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock }, | 1076 | { 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, 0, 0, &root0_gate_lock }, |
1062 | { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock }, | 1077 | { 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, 0, 0, &root0_gate_lock }, |
1063 | { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock }, | 1078 | { 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, 0, 0, &root0_gate_lock }, |
1064 | { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock }, | 1079 | { 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, 0, 0, &root0_gate_lock }, |
1065 | { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock }, | 1080 | { 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, 0, 0, &root0_gate_lock }, |
1066 | { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock }, | 1081 | { 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, 0, 0, &root1_gate_lock }, |
1067 | { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock }, | 1082 | { 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, 0, 0, &root1_gate_lock }, |
1068 | { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock }, | 1083 | { 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, 0, 0, &root1_gate_lock }, |
1069 | { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock }, | 1084 | { 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, 0, 0, &root1_gate_lock }, |
1070 | { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock }, | 1085 | { 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, 0, 0, &root1_gate_lock }, |
1071 | { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock }, | 1086 | { 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, 0, 0, &root1_gate_lock }, |
1072 | { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock }, | 1087 | { 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, 0, 0, &root1_gate_lock }, |
1073 | { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock }, | 1088 | { 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, 0, 0, &root1_gate_lock }, |
1074 | { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock }, | 1089 | { 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, 0, 0, &root1_gate_lock }, |
1075 | { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock }, | 1090 | { 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, 0, 0, &root1_gate_lock }, |
1076 | { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock }, | 1091 | { 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, 0, 0, &root1_gate_lock }, |
1077 | { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock }, | 1092 | { 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, 0, 0, &root1_gate_lock }, |
1078 | { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock }, | 1093 | { 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, 0, 0, &root1_gate_lock }, |
1079 | { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock }, | 1094 | { 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, 0, 0, &root1_gate_lock }, |
1080 | { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock }, | 1095 | { 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, 0, 0, &root1_gate_lock }, |
1081 | { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock }, | 1096 | { 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, 0, 0, &root1_gate_lock }, |
1082 | { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock }, | 1097 | { 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, 0, 0, &root1_gate_lock }, |
1083 | { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock }, | 1098 | { 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, 0, 0, &root1_gate_lock }, |
1084 | { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock }, | 1099 | { 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, 0, 0, &root1_gate_lock }, |
1085 | { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock }, | 1100 | { 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, 0, 0, &root1_gate_lock }, |
1086 | { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock }, | 1101 | { 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, 0, 0, &root1_gate_lock }, |
1087 | { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock }, | 1102 | { 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, 0, 0, &root1_gate_lock }, |
1088 | { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock }, | 1103 | { 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, 0, 0, &root1_gate_lock }, |
1089 | { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock }, | 1104 | { 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, CLK_UNIT_NOC_CLOCK, 4, &leaf1_gate_lock }, |
1090 | { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock }, | 1105 | { 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, 0, 0, &leaf1_gate_lock }, |
1091 | { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock }, | 1106 | { 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, 0, 0, &leaf1_gate_lock }, |
1092 | { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock }, | 1107 | { 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, 0, 0, &leaf1_gate_lock }, |
1093 | { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock }, | 1108 | { 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, 0, 0, &leaf1_gate_lock }, |
1094 | { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock }, | 1109 | { 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, 0, 0, &leaf1_gate_lock }, |
1095 | { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock }, | 1110 | { 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, 0, 0, &leaf1_gate_lock }, |
1096 | { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock }, | 1111 | { 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, CLK_UNIT_NOC_SOCKET, 7, &leaf1_gate_lock }, |
1097 | { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock }, | 1112 | { 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, CLK_UNIT_NOC_SOCKET, 8, &leaf1_gate_lock }, |
1098 | { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock }, | 1113 | { 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock }, |
1099 | { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock }, | 1114 | { 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, 0, 0, &leaf1_gate_lock }, |
1100 | { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock }, | 1115 | { 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, CLK_UNIT_NOC_SOCKET, 4, &leaf1_gate_lock }, |
1101 | { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock }, | 1116 | { 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, CLK_UNIT_NOC_SOCKET, 5, &leaf1_gate_lock }, |
1102 | { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock }, | 1117 | { 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, CLK_UNIT_NOC_SOCKET, 6, &leaf1_gate_lock }, |
1103 | { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock }, | 1118 | { 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, CLK_UNIT_NOC_SOCKET, 1, &leaf1_gate_lock }, |
1104 | { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock }, | 1119 | { 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, CLK_UNIT_NOC_SOCKET, 2, &leaf1_gate_lock }, |
1105 | { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock }, | 1120 | { 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, CLK_UNIT_NOC_SOCKET, 0, &leaf1_gate_lock }, |
1106 | { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock }, | 1121 | { 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock }, |
1107 | { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock }, | 1122 | { 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, 0, 0, &leaf1_gate_lock }, |
1108 | { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock }, | 1123 | { 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, 0, 0, &leaf1_gate_lock }, |
1109 | { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock }, | 1124 | { 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, CLK_UNIT_NOC_CLOCK, 20, &leaf2_gate_lock }, |
1110 | { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock }, | 1125 | { 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, 0, 0, &leaf2_gate_lock }, |
1111 | { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock }, | 1126 | { 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, 0, 0, &leaf2_gate_lock }, |
1112 | { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock }, | 1127 | { 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, 0, 0, &leaf2_gate_lock }, |
1113 | { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock }, | 1128 | { 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, 0, 0, &leaf2_gate_lock }, |
1114 | { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock }, | 1129 | { 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, 0, 0, &leaf2_gate_lock }, |
1115 | { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock }, | 1130 | { 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, 0, 0, &leaf2_gate_lock }, |
1116 | { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock }, | 1131 | { 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, 0, 0, &leaf2_gate_lock }, |
1117 | { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock }, | 1132 | { 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, CLK_UNIT_NOC_CLOCK, 21, &leaf2_gate_lock }, |
1118 | { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock }, | 1133 | { 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, 0, 0, &leaf2_gate_lock }, |
1119 | { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock }, | 1134 | { 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, 0, 0, &leaf2_gate_lock }, |
1120 | { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock }, | 1135 | { 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, 0, 0, &leaf2_gate_lock }, |
1121 | { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock }, | 1136 | { 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, CLK_UNIT_NOC_CLOCK, 22, &leaf2_gate_lock }, |
1122 | { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock }, | 1137 | { 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, CLK_UNIT_NOC_CLOCK, 18, &leaf2_gate_lock }, |
1123 | { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock }, | 1138 | { 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, CLK_UNIT_NOC_CLOCK, 23, &leaf2_gate_lock }, |
1124 | { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock }, | 1139 | { 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, CLK_UNIT_NOC_CLOCK, 19, &leaf2_gate_lock }, |
1125 | { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock }, | 1140 | { 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, CLK_UNIT_NOC_CLOCK, 17, &leaf2_gate_lock }, |
1126 | { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock }, | 1141 | { 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, 0, 0, &leaf2_gate_lock }, |
1127 | { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock }, | 1142 | { 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, 0, 0, &leaf2_gate_lock }, |
1128 | { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock }, | 1143 | { 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, 0, 0, &leaf2_gate_lock }, |
1129 | { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock }, | 1144 | { 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, 0, 0, &leaf3_gate_lock }, |
1130 | { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock }, | 1145 | { 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, CLK_UNIT_NOC_CLOCK, 10, &leaf3_gate_lock }, |
1131 | { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock }, | 1146 | { 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, CLK_UNIT_NOC_SOCKET, 14, &leaf3_gate_lock }, |
1132 | { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock }, | 1147 | { 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, CLK_UNIT_NOC_SOCKET, 11, &leaf3_gate_lock }, |
1133 | { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock }, | 1148 | { 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, CLK_UNIT_NOC_SOCKET, 13, &leaf3_gate_lock }, |
1134 | { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock }, | 1149 | { 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, CLK_UNIT_NOC_SOCKET, 15, &leaf3_gate_lock }, |
1135 | { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock }, | 1150 | { 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, CLK_UNIT_NOC_SOCKET, 16, &leaf3_gate_lock }, |
1136 | { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock }, | 1151 | { 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, CLK_UNIT_NOC_SOCKET, 17, &leaf3_gate_lock }, |
1137 | { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock }, | 1152 | { 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, CLK_UNIT_NOC_SOCKET, 18, &leaf3_gate_lock }, |
1138 | { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock }, | 1153 | { 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, CLK_UNIT_NOC_SOCKET, 12, &leaf3_gate_lock }, |
1139 | { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock }, | 1154 | { 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, 0, 0, &leaf3_gate_lock }, |
1140 | { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock }, | 1155 | { 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, CLK_UNIT_NOC_CLOCK, 7, &leaf3_gate_lock }, |
1141 | { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock }, | 1156 | { 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, CLK_UNIT_NOC_CLOCK, 9, &leaf3_gate_lock }, |
1142 | { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock }, | 1157 | { 99, "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, CLK_UNIT_NOC_CLOCK, 8, &leaf3_gate_lock }, |
1143 | { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock }, | 1158 | { 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, 0, 0, &leaf3_gate_lock }, |
1144 | { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock }, | 1159 | { 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, 0, 0, &leaf3_gate_lock }, |
1145 | { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock }, | 1160 | { 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, CLK_UNIT_NOC_CLOCK, 3, &leaf4_gate_lock }, |
1146 | { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock }, | 1161 | { 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, CLK_UNIT_NOC_CLOCK, 1, &leaf4_gate_lock }, |
1147 | { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock }, | 1162 | { 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, CLK_UNIT_NOC_CLOCK, 12, &leaf4_gate_lock }, |
1148 | { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock }, | 1163 | { 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, CLK_UNIT_NOC_SOCKET, 21, &leaf4_gate_lock }, |
1149 | { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock }, | 1164 | { 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, CLK_UNIT_NOC_SOCKET, 20, &leaf4_gate_lock }, |
1150 | { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock }, | 1165 | { 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, CLK_UNIT_NOC_SOCKET, 19, &leaf4_gate_lock }, |
1151 | { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock }, | 1166 | { 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, 0, 0, &leaf4_gate_lock }, |
1152 | { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock }, | 1167 | { 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, 0, 0, &leaf4_gate_lock }, |
1153 | { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock }, | 1168 | { 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, CLK_UNIT_NOC_CLOCK, 13, &leaf4_gate_lock }, |
1154 | { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock }, | 1169 | { 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, 0, 0, &leaf4_gate_lock }, |
1155 | { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock }, | 1170 | { 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, CLK_UNIT_NOC_CLOCK, 14, &leaf4_gate_lock }, |
1156 | { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock }, | 1171 | { 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, CLK_UNIT_NOC_CLOCK, 15, &leaf4_gate_lock }, |
1157 | { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock }, | 1172 | { 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, CLK_UNIT_NOC_CLOCK, 16, &leaf4_gate_lock }, |
1158 | { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock }, | 1173 | { 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, 0, 0, &leaf4_gate_lock }, |
1159 | { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock }, | 1174 | { 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, 0, 0, &leaf4_gate_lock }, |
1160 | { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock }, | 1175 | { 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, 0, 0, &leaf4_gate_lock }, |
1161 | { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock }, | 1176 | { 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, 0, 0, &leaf5_gate_lock }, |
1162 | { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock }, | 1177 | { 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, 0, 0, &leaf5_gate_lock }, |
1163 | { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock }, | 1178 | { 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, 0, 0, &leaf5_gate_lock }, |
1164 | { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock }, | 1179 | { 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, 0, 0, &leaf5_gate_lock }, |
1165 | { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock }, | 1180 | { 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, CLK_UNIT_NOC_SOCKET, 9, &leaf6_gate_lock }, |
1166 | { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock }, | 1181 | { 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, CLK_UNIT_NOC_SOCKET, 10, &leaf6_gate_lock }, |
1167 | { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock }, | 1182 | { 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, 0, 0, &leaf6_gate_lock }, |
1168 | { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock }, | 1183 | { 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, 0, 0, &leaf6_gate_lock }, |
1169 | { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock }, | 1184 | { 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, CLK_UNIT_NOC_CLOCK, 0, &leaf7_gate_lock }, |
1170 | { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock }, | 1185 | { 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, CLK_UNIT_NOC_CLOCK, 11, &leaf7_gate_lock }, |
1171 | { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock }, | 1186 | { 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, 0, 0, &leaf7_gate_lock }, |
1172 | { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock }, | 1187 | { 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, 0, 0, &leaf8_gate_lock }, |
1173 | { 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock }, | 1188 | { 130, "dmac4_io", "a7ca_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, 0, 0, &leaf8_gate_lock }, |
1174 | { 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock }, | 1189 | { 131, "uart6_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, 0, 0, &leaf8_gate_lock }, |
1175 | { 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock }, | 1190 | { 132, "usp3_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, 0, 0, &leaf8_gate_lock }, |
1176 | { 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock }, | 1191 | { 133, "a7ca_io", "noc_btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, 0, 0, &leaf8_gate_lock }, |
1177 | { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock }, | 1192 | { 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, 0, 0, &leaf8_gate_lock }, |
1178 | { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock }, | 1193 | { 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, 0, 0, &leaf8_gate_lock }, |
1179 | { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock }, | 1194 | { 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, 0, 0, &root1_gate_lock }, |
1180 | { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock }, | 1195 | { 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, 0, 0, &leaf8_gate_lock }, |
1181 | { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock }, | 1196 | { 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, 0, 0, &leaf0_gate_lock }, |
1182 | { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock }, | 1197 | { 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, 0, 0, &leaf0_gate_lock }, |
1183 | { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock }, | 1198 | { 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, 0, 0, &leaf0_gate_lock }, |
1184 | { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock }, | 1199 | { 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, 0, 0, &leaf0_gate_lock }, |
1185 | }; | 1200 | }; |
1186 | 1201 | ||
1187 | static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)]; | 1202 | static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)]; |
@@ -1206,20 +1221,44 @@ static int unit_clk_enable(struct clk_hw *hw) | |||
1206 | 1221 | ||
1207 | spin_lock_irqsave(clk->lock, flags); | 1222 | spin_lock_irqsave(clk->lock, flags); |
1208 | clkc_writel(BIT(clk->bit), reg); | 1223 | clkc_writel(BIT(clk->bit), reg); |
1224 | if (clk->type == CLK_UNIT_NOC_CLOCK) | ||
1225 | clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR); | ||
1226 | else if (clk->type == CLK_UNIT_NOC_SOCKET) | ||
1227 | clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_SET); | ||
1228 | |||
1209 | spin_unlock_irqrestore(clk->lock, flags); | 1229 | spin_unlock_irqrestore(clk->lock, flags); |
1210 | return 0; | 1230 | return 0; |
1211 | } | 1231 | } |
1212 | 1232 | ||
1213 | static void unit_clk_disable(struct clk_hw *hw) | 1233 | static void unit_clk_disable(struct clk_hw *hw) |
1214 | { | 1234 | { |
1215 | u32 reg; | 1235 | u32 reg; |
1236 | u32 i = 0; | ||
1216 | struct clk_unit *clk = to_unitclk(hw); | 1237 | struct clk_unit *clk = to_unitclk(hw); |
1217 | unsigned long flags; | 1238 | unsigned long flags; |
1218 | 1239 | ||
1219 | reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET; | 1240 | reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET; |
1220 | |||
1221 | spin_lock_irqsave(clk->lock, flags); | 1241 | spin_lock_irqsave(clk->lock, flags); |
1242 | if (clk->type == CLK_UNIT_NOC_CLOCK) { | ||
1243 | clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_SET); | ||
1244 | while (!(clkc_readl(SIRFSOC_NOC_CLK_IDLE_STATUS) & | ||
1245 | BIT(clk->idle_bit)) && (i++ < 100)) { | ||
1246 | cpu_relax(); | ||
1247 | udelay(10); | ||
1248 | } | ||
1249 | |||
1250 | if (i == 100) { | ||
1251 | pr_err("unit NoC Clock disconnect Error:timeout\n"); | ||
1252 | /*once timeout, undo idlereq by CLR*/ | ||
1253 | clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR); | ||
1254 | goto err; | ||
1255 | } | ||
1256 | |||
1257 | } else if (clk->type == CLK_UNIT_NOC_SOCKET) | ||
1258 | clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_CLR); | ||
1259 | |||
1222 | clkc_writel(BIT(clk->bit), reg); | 1260 | clkc_writel(BIT(clk->bit), reg); |
1261 | err: | ||
1223 | spin_unlock_irqrestore(clk->lock, flags); | 1262 | spin_unlock_irqrestore(clk->lock, flags); |
1224 | } | 1263 | } |
1225 | 1264 | ||
@@ -1232,7 +1271,7 @@ static const struct clk_ops unit_clk_ops = { | |||
1232 | static struct clk * __init | 1271 | static struct clk * __init |
1233 | atlas7_unit_clk_register(struct device *dev, const char *name, | 1272 | atlas7_unit_clk_register(struct device *dev, const char *name, |
1234 | const char * const parent_name, unsigned long flags, | 1273 | const char * const parent_name, unsigned long flags, |
1235 | u32 regofs, u8 bit, spinlock_t *lock) | 1274 | u32 regofs, u8 bit, u32 type, u8 idle_bit, spinlock_t *lock) |
1236 | { | 1275 | { |
1237 | struct clk *clk; | 1276 | struct clk *clk; |
1238 | struct clk_unit *unit; | 1277 | struct clk_unit *unit; |
@@ -1251,6 +1290,9 @@ atlas7_unit_clk_register(struct device *dev, const char *name, | |||
1251 | unit->hw.init = &init; | 1290 | unit->hw.init = &init; |
1252 | unit->regofs = regofs; | 1291 | unit->regofs = regofs; |
1253 | unit->bit = bit; | 1292 | unit->bit = bit; |
1293 | |||
1294 | unit->type = type; | ||
1295 | unit->idle_bit = idle_bit; | ||
1254 | unit->lock = lock; | 1296 | unit->lock = lock; |
1255 | 1297 | ||
1256 | clk = clk_register(dev, &unit->hw); | 1298 | clk = clk_register(dev, &unit->hw); |
@@ -1624,7 +1666,7 @@ static void __init atlas7_clk_init(struct device_node *np) | |||
1624 | for (i = 0; i < ARRAY_SIZE(unit_list); i++) { | 1666 | for (i = 0; i < ARRAY_SIZE(unit_list); i++) { |
1625 | unit = &unit_list[i]; | 1667 | unit = &unit_list[i]; |
1626 | atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name, | 1668 | atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name, |
1627 | unit->flags, unit->regofs, unit->bit, unit->lock); | 1669 | unit->flags, unit->regofs, unit->bit, unit->type, unit->idle_bit, unit->lock); |
1628 | BUG_ON(!atlas7_clks[i]); | 1670 | BUG_ON(!atlas7_clks[i]); |
1629 | } | 1671 | } |
1630 | 1672 | ||
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index bd355ee33766..24d99594c0b3 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c | |||
@@ -268,6 +268,7 @@ static void __init st_of_flexgen_setup(struct device_node *np) | |||
268 | int num_parents, i; | 268 | int num_parents, i; |
269 | spinlock_t *rlock = NULL; | 269 | spinlock_t *rlock = NULL; |
270 | unsigned long flex_flags = 0; | 270 | unsigned long flex_flags = 0; |
271 | int ret; | ||
271 | 272 | ||
272 | pnode = of_get_parent(np); | 273 | pnode = of_get_parent(np); |
273 | if (!pnode) | 274 | if (!pnode) |
@@ -285,13 +286,13 @@ static void __init st_of_flexgen_setup(struct device_node *np) | |||
285 | if (!clk_data) | 286 | if (!clk_data) |
286 | goto err; | 287 | goto err; |
287 | 288 | ||
288 | clk_data->clk_num = of_property_count_strings(np , | 289 | ret = of_property_count_strings(np, "clock-output-names"); |
289 | "clock-output-names"); | 290 | if (ret <= 0) { |
290 | if (clk_data->clk_num <= 0) { | ||
291 | pr_err("%s: Failed to get number of output clocks (%d)", | 291 | pr_err("%s: Failed to get number of output clocks (%d)", |
292 | __func__, clk_data->clk_num); | 292 | __func__, clk_data->clk_num); |
293 | goto err; | 293 | goto err; |
294 | } | 294 | } |
295 | clk_data->clk_num = ret; | ||
295 | 296 | ||
296 | clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), | 297 | clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), |
297 | GFP_KERNEL); | 298 | GFP_KERNEL); |
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index 4f7f6c00b219..5dc5ce217960 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/of_address.h> | 17 | #include <linux/of_address.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/clk-provider.h> | 19 | #include <linux/clk-provider.h> |
20 | #include "clkgen.h" | ||
20 | 21 | ||
21 | static DEFINE_SPINLOCK(clkgena_divmux_lock); | 22 | static DEFINE_SPINLOCK(clkgena_divmux_lock); |
22 | static DEFINE_SPINLOCK(clkgenf_lock); | 23 | static DEFINE_SPINLOCK(clkgenf_lock); |
@@ -576,6 +577,7 @@ static struct clkgen_mux_data stih415_a9_mux_data = { | |||
576 | .offset = 0, | 577 | .offset = 0, |
577 | .shift = 1, | 578 | .shift = 1, |
578 | .width = 2, | 579 | .width = 2, |
580 | .lock = &clkgen_a9_lock, | ||
579 | }; | 581 | }; |
580 | static struct clkgen_mux_data stih416_a9_mux_data = { | 582 | static struct clkgen_mux_data stih416_a9_mux_data = { |
581 | .offset = 0, | 583 | .offset = 0, |
@@ -586,6 +588,7 @@ static struct clkgen_mux_data stih407_a9_mux_data = { | |||
586 | .offset = 0x1a4, | 588 | .offset = 0x1a4, |
587 | .shift = 0, | 589 | .shift = 0, |
588 | .width = 2, | 590 | .width = 2, |
591 | .lock = &clkgen_a9_lock, | ||
589 | }; | 592 | }; |
590 | 593 | ||
591 | static const struct of_device_id mux_of_match[] = { | 594 | static const struct of_device_id mux_of_match[] = { |
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index b2a332cf8985..38f6f3a9098e 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c | |||
@@ -18,10 +18,12 @@ | |||
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
21 | #include <linux/iopoll.h> | ||
21 | 22 | ||
22 | #include "clkgen.h" | 23 | #include "clkgen.h" |
23 | 24 | ||
24 | static DEFINE_SPINLOCK(clkgena_c32_odf_lock); | 25 | static DEFINE_SPINLOCK(clkgena_c32_odf_lock); |
26 | DEFINE_SPINLOCK(clkgen_a9_lock); | ||
25 | 27 | ||
26 | /* | 28 | /* |
27 | * Common PLL configuration register bits for PLL800 and PLL1600 C65 | 29 | * Common PLL configuration register bits for PLL800 and PLL1600 C65 |
@@ -38,30 +40,46 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock); | |||
38 | #define C32_IDF_MASK (0x7) | 40 | #define C32_IDF_MASK (0x7) |
39 | #define C32_ODF_MASK (0x3f) | 41 | #define C32_ODF_MASK (0x3f) |
40 | #define C32_LDF_MASK (0x7f) | 42 | #define C32_LDF_MASK (0x7f) |
43 | #define C32_CP_MASK (0x1f) | ||
41 | 44 | ||
42 | #define C32_MAX_ODFS (4) | 45 | #define C32_MAX_ODFS (4) |
43 | 46 | ||
47 | /* | ||
48 | * PLL configuration register bits for PLL4600 C28 | ||
49 | */ | ||
50 | #define C28_NDIV_MASK (0xff) | ||
51 | #define C28_IDF_MASK (0x7) | ||
52 | #define C28_ODF_MASK (0x3f) | ||
53 | |||
44 | struct clkgen_pll_data { | 54 | struct clkgen_pll_data { |
45 | struct clkgen_field pdn_status; | 55 | struct clkgen_field pdn_status; |
56 | struct clkgen_field pdn_ctrl; | ||
46 | struct clkgen_field locked_status; | 57 | struct clkgen_field locked_status; |
47 | struct clkgen_field mdiv; | 58 | struct clkgen_field mdiv; |
48 | struct clkgen_field ndiv; | 59 | struct clkgen_field ndiv; |
49 | struct clkgen_field pdiv; | 60 | struct clkgen_field pdiv; |
50 | struct clkgen_field idf; | 61 | struct clkgen_field idf; |
51 | struct clkgen_field ldf; | 62 | struct clkgen_field ldf; |
63 | struct clkgen_field cp; | ||
52 | unsigned int num_odfs; | 64 | unsigned int num_odfs; |
53 | struct clkgen_field odf[C32_MAX_ODFS]; | 65 | struct clkgen_field odf[C32_MAX_ODFS]; |
54 | struct clkgen_field odf_gate[C32_MAX_ODFS]; | 66 | struct clkgen_field odf_gate[C32_MAX_ODFS]; |
67 | bool switch2pll_en; | ||
68 | struct clkgen_field switch2pll; | ||
69 | spinlock_t *lock; | ||
55 | const struct clk_ops *ops; | 70 | const struct clk_ops *ops; |
56 | }; | 71 | }; |
57 | 72 | ||
58 | static const struct clk_ops st_pll1600c65_ops; | 73 | static const struct clk_ops st_pll1600c65_ops; |
59 | static const struct clk_ops st_pll800c65_ops; | 74 | static const struct clk_ops st_pll800c65_ops; |
60 | static const struct clk_ops stm_pll3200c32_ops; | 75 | static const struct clk_ops stm_pll3200c32_ops; |
76 | static const struct clk_ops stm_pll3200c32_a9_ops; | ||
61 | static const struct clk_ops st_pll1200c32_ops; | 77 | static const struct clk_ops st_pll1200c32_ops; |
78 | static const struct clk_ops stm_pll4600c28_ops; | ||
62 | 79 | ||
63 | static const struct clkgen_pll_data st_pll1600c65_ax = { | 80 | static const struct clkgen_pll_data st_pll1600c65_ax = { |
64 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), | 81 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), |
82 | .pdn_ctrl = CLKGEN_FIELD(0x10, 0x1, 0), | ||
65 | .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), | 83 | .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), |
66 | .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0), | 84 | .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0), |
67 | .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), | 85 | .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), |
@@ -70,6 +88,7 @@ static const struct clkgen_pll_data st_pll1600c65_ax = { | |||
70 | 88 | ||
71 | static const struct clkgen_pll_data st_pll800c65_ax = { | 89 | static const struct clkgen_pll_data st_pll800c65_ax = { |
72 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), | 90 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), |
91 | .pdn_ctrl = CLKGEN_FIELD(0xC, 0x1, 1), | ||
73 | .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), | 92 | .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), |
74 | .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0), | 93 | .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0), |
75 | .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), | 94 | .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), |
@@ -79,6 +98,7 @@ static const struct clkgen_pll_data st_pll800c65_ax = { | |||
79 | 98 | ||
80 | static const struct clkgen_pll_data st_pll3200c32_a1x_0 = { | 99 | static const struct clkgen_pll_data st_pll3200c32_a1x_0 = { |
81 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31), | 100 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31), |
101 | .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 0), | ||
82 | .locked_status = CLKGEN_FIELD(0x4, 0x1, 31), | 102 | .locked_status = CLKGEN_FIELD(0x4, 0x1, 31), |
83 | .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0), | 103 | .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0), |
84 | .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0), | 104 | .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0), |
@@ -96,6 +116,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_0 = { | |||
96 | 116 | ||
97 | static const struct clkgen_pll_data st_pll3200c32_a1x_1 = { | 117 | static const struct clkgen_pll_data st_pll3200c32_a1x_1 = { |
98 | .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31), | 118 | .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31), |
119 | .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 1), | ||
99 | .locked_status = CLKGEN_FIELD(0x10, 0x1, 31), | 120 | .locked_status = CLKGEN_FIELD(0x10, 0x1, 31), |
100 | .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0), | 121 | .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0), |
101 | .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0), | 122 | .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0), |
@@ -114,6 +135,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_1 = { | |||
114 | /* 415 specific */ | 135 | /* 415 specific */ |
115 | static const struct clkgen_pll_data st_pll3200c32_a9_415 = { | 136 | static const struct clkgen_pll_data st_pll3200c32_a9_415 = { |
116 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), | 137 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), |
138 | .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), | ||
117 | .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), | 139 | .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), |
118 | .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9), | 140 | .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9), |
119 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22), | 141 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22), |
@@ -125,6 +147,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_415 = { | |||
125 | 147 | ||
126 | static const struct clkgen_pll_data st_pll3200c32_ddr_415 = { | 148 | static const struct clkgen_pll_data st_pll3200c32_ddr_415 = { |
127 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), | 149 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), |
150 | .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), | ||
128 | .locked_status = CLKGEN_FIELD(0x100, 0x1, 0), | 151 | .locked_status = CLKGEN_FIELD(0x100, 0x1, 0), |
129 | .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), | 152 | .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), |
130 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), | 153 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), |
@@ -137,7 +160,8 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_415 = { | |||
137 | }; | 160 | }; |
138 | 161 | ||
139 | static const struct clkgen_pll_data st_pll1200c32_gpu_415 = { | 162 | static const struct clkgen_pll_data st_pll1200c32_gpu_415 = { |
140 | .pdn_status = CLKGEN_FIELD(0x144, 0x1, 3), | 163 | .pdn_status = CLKGEN_FIELD(0x4, 0x1, 0), |
164 | .pdn_ctrl = CLKGEN_FIELD(0x4, 0x1, 0), | ||
141 | .locked_status = CLKGEN_FIELD(0x168, 0x1, 0), | 165 | .locked_status = CLKGEN_FIELD(0x168, 0x1, 0), |
142 | .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), | 166 | .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), |
143 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), | 167 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), |
@@ -149,6 +173,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_415 = { | |||
149 | /* 416 specific */ | 173 | /* 416 specific */ |
150 | static const struct clkgen_pll_data st_pll3200c32_a9_416 = { | 174 | static const struct clkgen_pll_data st_pll3200c32_a9_416 = { |
151 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), | 175 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), |
176 | .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), | ||
152 | .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), | 177 | .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), |
153 | .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), | 178 | .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), |
154 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), | 179 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), |
@@ -160,6 +185,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_416 = { | |||
160 | 185 | ||
161 | static const struct clkgen_pll_data st_pll3200c32_ddr_416 = { | 186 | static const struct clkgen_pll_data st_pll3200c32_ddr_416 = { |
162 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), | 187 | .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), |
188 | .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), | ||
163 | .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0), | 189 | .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0), |
164 | .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), | 190 | .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), |
165 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), | 191 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), |
@@ -173,6 +199,7 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_416 = { | |||
173 | 199 | ||
174 | static const struct clkgen_pll_data st_pll1200c32_gpu_416 = { | 200 | static const struct clkgen_pll_data st_pll1200c32_gpu_416 = { |
175 | .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3), | 201 | .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3), |
202 | .pdn_ctrl = CLKGEN_FIELD(0x8E4, 0x1, 3), | ||
176 | .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0), | 203 | .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0), |
177 | .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), | 204 | .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), |
178 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), | 205 | .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), |
@@ -184,6 +211,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_416 = { | |||
184 | static const struct clkgen_pll_data st_pll3200c32_407_a0 = { | 211 | static const struct clkgen_pll_data st_pll3200c32_407_a0 = { |
185 | /* 407 A0 */ | 212 | /* 407 A0 */ |
186 | .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), | 213 | .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), |
214 | .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8), | ||
187 | .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), | 215 | .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), |
188 | .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), | 216 | .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), |
189 | .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), | 217 | .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), |
@@ -196,6 +224,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_a0 = { | |||
196 | static const struct clkgen_pll_data st_pll3200c32_cx_0 = { | 224 | static const struct clkgen_pll_data st_pll3200c32_cx_0 = { |
197 | /* 407 C0 PLL0 */ | 225 | /* 407 C0 PLL0 */ |
198 | .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), | 226 | .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), |
227 | .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8), | ||
199 | .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), | 228 | .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), |
200 | .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), | 229 | .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), |
201 | .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), | 230 | .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), |
@@ -208,6 +237,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_0 = { | |||
208 | static const struct clkgen_pll_data st_pll3200c32_cx_1 = { | 237 | static const struct clkgen_pll_data st_pll3200c32_cx_1 = { |
209 | /* 407 C0 PLL1 */ | 238 | /* 407 C0 PLL1 */ |
210 | .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8), | 239 | .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8), |
240 | .pdn_ctrl = CLKGEN_FIELD(0x2c8, 0x1, 8), | ||
211 | .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24), | 241 | .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24), |
212 | .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16), | 242 | .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16), |
213 | .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0), | 243 | .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0), |
@@ -220,13 +250,34 @@ static const struct clkgen_pll_data st_pll3200c32_cx_1 = { | |||
220 | static const struct clkgen_pll_data st_pll3200c32_407_a9 = { | 250 | static const struct clkgen_pll_data st_pll3200c32_407_a9 = { |
221 | /* 407 A9 */ | 251 | /* 407 A9 */ |
222 | .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), | 252 | .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), |
253 | .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0), | ||
223 | .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0), | 254 | .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0), |
224 | .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0), | 255 | .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0), |
225 | .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25), | 256 | .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25), |
226 | .num_odfs = 1, | 257 | .num_odfs = 1, |
227 | .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) }, | 258 | .odf = { CLKGEN_FIELD(0x1b0, C32_ODF_MASK, 8) }, |
228 | .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) }, | 259 | .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) }, |
229 | .ops = &stm_pll3200c32_ops, | 260 | .switch2pll_en = true, |
261 | .cp = CLKGEN_FIELD(0x1a8, C32_CP_MASK, 1), | ||
262 | .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1), | ||
263 | .lock = &clkgen_a9_lock, | ||
264 | .ops = &stm_pll3200c32_a9_ops, | ||
265 | }; | ||
266 | |||
267 | static struct clkgen_pll_data st_pll4600c28_418_a9 = { | ||
268 | /* 418 A9 */ | ||
269 | .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), | ||
270 | .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0), | ||
271 | .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0), | ||
272 | .ndiv = CLKGEN_FIELD(0x1b0, C28_NDIV_MASK, 0), | ||
273 | .idf = CLKGEN_FIELD(0x1a8, C28_IDF_MASK, 25), | ||
274 | .num_odfs = 1, | ||
275 | .odf = { CLKGEN_FIELD(0x1b0, C28_ODF_MASK, 8) }, | ||
276 | .odf_gate = { CLKGEN_FIELD(0x1ac, 0x1, 28) }, | ||
277 | .switch2pll_en = true, | ||
278 | .switch2pll = CLKGEN_FIELD(0x1a4, 0x1, 1), | ||
279 | .lock = &clkgen_a9_lock, | ||
280 | .ops = &stm_pll4600c28_ops, | ||
230 | }; | 281 | }; |
231 | 282 | ||
232 | /** | 283 | /** |
@@ -252,10 +303,26 @@ struct clkgen_pll { | |||
252 | struct clk_hw hw; | 303 | struct clk_hw hw; |
253 | struct clkgen_pll_data *data; | 304 | struct clkgen_pll_data *data; |
254 | void __iomem *regs_base; | 305 | void __iomem *regs_base; |
306 | spinlock_t *lock; | ||
307 | |||
308 | u32 ndiv; | ||
309 | u32 idf; | ||
310 | u32 odf; | ||
311 | u32 cp; | ||
255 | }; | 312 | }; |
256 | 313 | ||
257 | #define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw) | 314 | #define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw) |
258 | 315 | ||
316 | struct stm_pll { | ||
317 | unsigned long mdiv; | ||
318 | unsigned long ndiv; | ||
319 | unsigned long pdiv; | ||
320 | unsigned long odf; | ||
321 | unsigned long idf; | ||
322 | unsigned long ldf; | ||
323 | unsigned long cp; | ||
324 | }; | ||
325 | |||
259 | static int clkgen_pll_is_locked(struct clk_hw *hw) | 326 | static int clkgen_pll_is_locked(struct clk_hw *hw) |
260 | { | 327 | { |
261 | struct clkgen_pll *pll = to_clkgen_pll(hw); | 328 | struct clkgen_pll *pll = to_clkgen_pll(hw); |
@@ -271,6 +338,78 @@ static int clkgen_pll_is_enabled(struct clk_hw *hw) | |||
271 | return !poweroff; | 338 | return !poweroff; |
272 | } | 339 | } |
273 | 340 | ||
341 | static int __clkgen_pll_enable(struct clk_hw *hw) | ||
342 | { | ||
343 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
344 | void __iomem *base = pll->regs_base; | ||
345 | struct clkgen_field *field = &pll->data->locked_status; | ||
346 | int ret = 0; | ||
347 | u32 reg; | ||
348 | |||
349 | if (clkgen_pll_is_enabled(hw)) | ||
350 | return 0; | ||
351 | |||
352 | CLKGEN_WRITE(pll, pdn_ctrl, 0); | ||
353 | |||
354 | ret = readl_relaxed_poll_timeout(base + field->offset, reg, | ||
355 | !!((reg >> field->shift) & field->mask), 0, 10000); | ||
356 | |||
357 | if (!ret) { | ||
358 | if (pll->data->switch2pll_en) | ||
359 | CLKGEN_WRITE(pll, switch2pll, 0); | ||
360 | |||
361 | pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__); | ||
362 | } | ||
363 | |||
364 | return ret; | ||
365 | } | ||
366 | |||
367 | static int clkgen_pll_enable(struct clk_hw *hw) | ||
368 | { | ||
369 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
370 | unsigned long flags = 0; | ||
371 | int ret = 0; | ||
372 | |||
373 | if (pll->lock) | ||
374 | spin_lock_irqsave(pll->lock, flags); | ||
375 | |||
376 | ret = __clkgen_pll_enable(hw); | ||
377 | |||
378 | if (pll->lock) | ||
379 | spin_unlock_irqrestore(pll->lock, flags); | ||
380 | |||
381 | return ret; | ||
382 | } | ||
383 | |||
384 | static void __clkgen_pll_disable(struct clk_hw *hw) | ||
385 | { | ||
386 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
387 | |||
388 | if (!clkgen_pll_is_enabled(hw)) | ||
389 | return; | ||
390 | |||
391 | if (pll->data->switch2pll_en) | ||
392 | CLKGEN_WRITE(pll, switch2pll, 1); | ||
393 | |||
394 | CLKGEN_WRITE(pll, pdn_ctrl, 1); | ||
395 | |||
396 | pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__); | ||
397 | } | ||
398 | |||
399 | static void clkgen_pll_disable(struct clk_hw *hw) | ||
400 | { | ||
401 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
402 | unsigned long flags = 0; | ||
403 | |||
404 | if (pll->lock) | ||
405 | spin_lock_irqsave(pll->lock, flags); | ||
406 | |||
407 | __clkgen_pll_disable(hw); | ||
408 | |||
409 | if (pll->lock) | ||
410 | spin_unlock_irqrestore(pll->lock, flags); | ||
411 | } | ||
412 | |||
274 | static unsigned long recalc_stm_pll800c65(struct clk_hw *hw, | 413 | static unsigned long recalc_stm_pll800c65(struct clk_hw *hw, |
275 | unsigned long parent_rate) | 414 | unsigned long parent_rate) |
276 | { | 415 | { |
@@ -322,6 +461,67 @@ static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw, | |||
322 | return rate; | 461 | return rate; |
323 | } | 462 | } |
324 | 463 | ||
464 | static int clk_pll3200c32_get_params(unsigned long input, unsigned long output, | ||
465 | struct stm_pll *pll) | ||
466 | { | ||
467 | unsigned long i, n; | ||
468 | unsigned long deviation = ~0; | ||
469 | unsigned long new_freq; | ||
470 | long new_deviation; | ||
471 | /* Charge pump table: highest ndiv value for cp=6 to 25 */ | ||
472 | static const unsigned char cp_table[] = { | ||
473 | 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, | ||
474 | 128, 136, 144, 152, 160, 168, 176, 184, 192 | ||
475 | }; | ||
476 | |||
477 | /* Output clock range: 800Mhz to 1600Mhz */ | ||
478 | if (output < 800000000 || output > 1600000000) | ||
479 | return -EINVAL; | ||
480 | |||
481 | input /= 1000; | ||
482 | output /= 1000; | ||
483 | |||
484 | for (i = 1; i <= 7 && deviation; i++) { | ||
485 | n = i * output / (2 * input); | ||
486 | |||
487 | /* Checks */ | ||
488 | if (n < 8) | ||
489 | continue; | ||
490 | if (n > 200) | ||
491 | break; | ||
492 | |||
493 | new_freq = (input * 2 * n) / i; | ||
494 | |||
495 | new_deviation = abs(new_freq - output); | ||
496 | |||
497 | if (!new_deviation || new_deviation < deviation) { | ||
498 | pll->idf = i; | ||
499 | pll->ndiv = n; | ||
500 | deviation = new_deviation; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | if (deviation == ~0) /* No solution found */ | ||
505 | return -EINVAL; | ||
506 | |||
507 | /* Computing recommended charge pump value */ | ||
508 | for (pll->cp = 6; pll->ndiv > cp_table[pll->cp-6]; (pll->cp)++) | ||
509 | ; | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | static int clk_pll3200c32_get_rate(unsigned long input, struct stm_pll *pll, | ||
515 | unsigned long *rate) | ||
516 | { | ||
517 | if (!pll->idf) | ||
518 | pll->idf = 1; | ||
519 | |||
520 | *rate = ((2 * (input / 1000) * pll->ndiv) / pll->idf) * 1000; | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
325 | static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, | 525 | static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, |
326 | unsigned long parent_rate) | 526 | unsigned long parent_rate) |
327 | { | 527 | { |
@@ -344,6 +544,70 @@ static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw, | |||
344 | return rate; | 544 | return rate; |
345 | } | 545 | } |
346 | 546 | ||
547 | static long round_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate, | ||
548 | unsigned long *prate) | ||
549 | { | ||
550 | struct stm_pll params; | ||
551 | |||
552 | if (!clk_pll3200c32_get_params(*prate, rate, ¶ms)) | ||
553 | clk_pll3200c32_get_rate(*prate, ¶ms, &rate); | ||
554 | else { | ||
555 | pr_debug("%s: %s rate %ld Invalid\n", __func__, | ||
556 | __clk_get_name(hw->clk), rate); | ||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n", | ||
561 | __func__, __clk_get_name(hw->clk), | ||
562 | rate, (unsigned int)params.ndiv, | ||
563 | (unsigned int)params.idf); | ||
564 | |||
565 | return rate; | ||
566 | } | ||
567 | |||
568 | static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate, | ||
569 | unsigned long parent_rate) | ||
570 | { | ||
571 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
572 | struct stm_pll params; | ||
573 | long hwrate = 0; | ||
574 | unsigned long flags = 0; | ||
575 | |||
576 | if (!rate || !parent_rate) | ||
577 | return -EINVAL; | ||
578 | |||
579 | if (!clk_pll3200c32_get_params(parent_rate, rate, ¶ms)) | ||
580 | clk_pll3200c32_get_rate(parent_rate, ¶ms, &hwrate); | ||
581 | |||
582 | pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n", | ||
583 | __func__, __clk_get_name(hw->clk), | ||
584 | hwrate, (unsigned int)params.ndiv, | ||
585 | (unsigned int)params.idf); | ||
586 | |||
587 | if (!hwrate) | ||
588 | return -EINVAL; | ||
589 | |||
590 | pll->ndiv = params.ndiv; | ||
591 | pll->idf = params.idf; | ||
592 | pll->cp = params.cp; | ||
593 | |||
594 | __clkgen_pll_disable(hw); | ||
595 | |||
596 | if (pll->lock) | ||
597 | spin_lock_irqsave(pll->lock, flags); | ||
598 | |||
599 | CLKGEN_WRITE(pll, ndiv, pll->ndiv); | ||
600 | CLKGEN_WRITE(pll, idf, pll->idf); | ||
601 | CLKGEN_WRITE(pll, cp, pll->cp); | ||
602 | |||
603 | if (pll->lock) | ||
604 | spin_unlock_irqrestore(pll->lock, flags); | ||
605 | |||
606 | __clkgen_pll_enable(hw); | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
347 | static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, | 611 | static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, |
348 | unsigned long parent_rate) | 612 | unsigned long parent_rate) |
349 | { | 613 | { |
@@ -371,30 +635,213 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, | |||
371 | return rate; | 635 | return rate; |
372 | } | 636 | } |
373 | 637 | ||
638 | /* PLL output structure | ||
639 | * FVCO >> /2 >> FVCOBY2 (no output) | ||
640 | * |> Divider (ODF) >> PHI | ||
641 | * | ||
642 | * FVCOby2 output = (input * 2 * NDIV) / IDF (assuming FRAC_CONTROL==L) | ||
643 | * | ||
644 | * Rules: | ||
645 | * 4Mhz <= INFF input <= 350Mhz | ||
646 | * 4Mhz <= INFIN (INFF / IDF) <= 50Mhz | ||
647 | * 19.05Mhz <= FVCOby2 output (PHI w ODF=1) <= 3000Mhz | ||
648 | * 1 <= i (register/dec value for IDF) <= 7 | ||
649 | * 8 <= n (register/dec value for NDIV) <= 246 | ||
650 | */ | ||
651 | |||
652 | static int clk_pll4600c28_get_params(unsigned long input, unsigned long output, | ||
653 | struct stm_pll *pll) | ||
654 | { | ||
655 | |||
656 | unsigned long i, infin, n; | ||
657 | unsigned long deviation = ~0; | ||
658 | unsigned long new_freq, new_deviation; | ||
659 | |||
660 | /* Output clock range: 19Mhz to 3000Mhz */ | ||
661 | if (output < 19000000 || output > 3000000000u) | ||
662 | return -EINVAL; | ||
663 | |||
664 | /* For better jitter, IDF should be smallest and NDIV must be maximum */ | ||
665 | for (i = 1; i <= 7 && deviation; i++) { | ||
666 | /* INFIN checks */ | ||
667 | infin = input / i; | ||
668 | if (infin < 4000000 || infin > 50000000) | ||
669 | continue; /* Invalid case */ | ||
670 | |||
671 | n = output / (infin * 2); | ||
672 | if (n < 8 || n > 246) | ||
673 | continue; /* Invalid case */ | ||
674 | if (n < 246) | ||
675 | n++; /* To work around 'y' when n=x.y */ | ||
676 | |||
677 | for (; n >= 8 && deviation; n--) { | ||
678 | new_freq = infin * 2 * n; | ||
679 | if (new_freq < output) | ||
680 | break; /* Optimization: shorting loop */ | ||
681 | |||
682 | new_deviation = new_freq - output; | ||
683 | if (!new_deviation || new_deviation < deviation) { | ||
684 | pll->idf = i; | ||
685 | pll->ndiv = n; | ||
686 | deviation = new_deviation; | ||
687 | } | ||
688 | } | ||
689 | } | ||
690 | |||
691 | if (deviation == ~0) /* No solution found */ | ||
692 | return -EINVAL; | ||
693 | |||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int clk_pll4600c28_get_rate(unsigned long input, struct stm_pll *pll, | ||
698 | unsigned long *rate) | ||
699 | { | ||
700 | if (!pll->idf) | ||
701 | pll->idf = 1; | ||
702 | |||
703 | *rate = (input / pll->idf) * 2 * pll->ndiv; | ||
704 | |||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw, | ||
709 | unsigned long parent_rate) | ||
710 | { | ||
711 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
712 | struct stm_pll params; | ||
713 | unsigned long rate; | ||
714 | |||
715 | if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw)) | ||
716 | return 0; | ||
717 | |||
718 | params.ndiv = CLKGEN_READ(pll, ndiv); | ||
719 | params.idf = CLKGEN_READ(pll, idf); | ||
720 | |||
721 | clk_pll4600c28_get_rate(parent_rate, ¶ms, &rate); | ||
722 | |||
723 | pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate); | ||
724 | |||
725 | return rate; | ||
726 | } | ||
727 | |||
728 | static long round_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate, | ||
729 | unsigned long *prate) | ||
730 | { | ||
731 | struct stm_pll params; | ||
732 | |||
733 | if (!clk_pll4600c28_get_params(*prate, rate, ¶ms)) { | ||
734 | clk_pll4600c28_get_rate(*prate, ¶ms, &rate); | ||
735 | } else { | ||
736 | pr_debug("%s: %s rate %ld Invalid\n", __func__, | ||
737 | __clk_get_name(hw->clk), rate); | ||
738 | return 0; | ||
739 | } | ||
740 | |||
741 | pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n", | ||
742 | __func__, __clk_get_name(hw->clk), | ||
743 | rate, (unsigned int)params.ndiv, | ||
744 | (unsigned int)params.idf); | ||
745 | |||
746 | return rate; | ||
747 | } | ||
748 | |||
749 | static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate, | ||
750 | unsigned long parent_rate) | ||
751 | { | ||
752 | struct clkgen_pll *pll = to_clkgen_pll(hw); | ||
753 | struct stm_pll params; | ||
754 | long hwrate; | ||
755 | unsigned long flags = 0; | ||
756 | |||
757 | if (!rate || !parent_rate) | ||
758 | return -EINVAL; | ||
759 | |||
760 | if (!clk_pll4600c28_get_params(parent_rate, rate, ¶ms)) { | ||
761 | clk_pll4600c28_get_rate(parent_rate, ¶ms, &hwrate); | ||
762 | } else { | ||
763 | pr_debug("%s: %s rate %ld Invalid\n", __func__, | ||
764 | __clk_get_name(hw->clk), rate); | ||
765 | return -EINVAL; | ||
766 | } | ||
767 | |||
768 | pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n", | ||
769 | __func__, __clk_get_name(hw->clk), | ||
770 | hwrate, (unsigned int)params.ndiv, | ||
771 | (unsigned int)params.idf); | ||
772 | |||
773 | if (!hwrate) | ||
774 | return -EINVAL; | ||
775 | |||
776 | pll->ndiv = params.ndiv; | ||
777 | pll->idf = params.idf; | ||
778 | |||
779 | __clkgen_pll_disable(hw); | ||
780 | |||
781 | if (pll->lock) | ||
782 | spin_lock_irqsave(pll->lock, flags); | ||
783 | |||
784 | CLKGEN_WRITE(pll, ndiv, pll->ndiv); | ||
785 | CLKGEN_WRITE(pll, idf, pll->idf); | ||
786 | |||
787 | if (pll->lock) | ||
788 | spin_unlock_irqrestore(pll->lock, flags); | ||
789 | |||
790 | __clkgen_pll_enable(hw); | ||
791 | |||
792 | return 0; | ||
793 | } | ||
794 | |||
374 | static const struct clk_ops st_pll1600c65_ops = { | 795 | static const struct clk_ops st_pll1600c65_ops = { |
796 | .enable = clkgen_pll_enable, | ||
797 | .disable = clkgen_pll_disable, | ||
375 | .is_enabled = clkgen_pll_is_enabled, | 798 | .is_enabled = clkgen_pll_is_enabled, |
376 | .recalc_rate = recalc_stm_pll1600c65, | 799 | .recalc_rate = recalc_stm_pll1600c65, |
377 | }; | 800 | }; |
378 | 801 | ||
379 | static const struct clk_ops st_pll800c65_ops = { | 802 | static const struct clk_ops st_pll800c65_ops = { |
803 | .enable = clkgen_pll_enable, | ||
804 | .disable = clkgen_pll_disable, | ||
380 | .is_enabled = clkgen_pll_is_enabled, | 805 | .is_enabled = clkgen_pll_is_enabled, |
381 | .recalc_rate = recalc_stm_pll800c65, | 806 | .recalc_rate = recalc_stm_pll800c65, |
382 | }; | 807 | }; |
383 | 808 | ||
384 | static const struct clk_ops stm_pll3200c32_ops = { | 809 | static const struct clk_ops stm_pll3200c32_ops = { |
810 | .enable = clkgen_pll_enable, | ||
811 | .disable = clkgen_pll_disable, | ||
385 | .is_enabled = clkgen_pll_is_enabled, | 812 | .is_enabled = clkgen_pll_is_enabled, |
386 | .recalc_rate = recalc_stm_pll3200c32, | 813 | .recalc_rate = recalc_stm_pll3200c32, |
387 | }; | 814 | }; |
388 | 815 | ||
816 | static const struct clk_ops stm_pll3200c32_a9_ops = { | ||
817 | .enable = clkgen_pll_enable, | ||
818 | .disable = clkgen_pll_disable, | ||
819 | .is_enabled = clkgen_pll_is_enabled, | ||
820 | .recalc_rate = recalc_stm_pll3200c32, | ||
821 | .round_rate = round_rate_stm_pll3200c32, | ||
822 | .set_rate = set_rate_stm_pll3200c32, | ||
823 | }; | ||
824 | |||
389 | static const struct clk_ops st_pll1200c32_ops = { | 825 | static const struct clk_ops st_pll1200c32_ops = { |
826 | .enable = clkgen_pll_enable, | ||
827 | .disable = clkgen_pll_disable, | ||
390 | .is_enabled = clkgen_pll_is_enabled, | 828 | .is_enabled = clkgen_pll_is_enabled, |
391 | .recalc_rate = recalc_stm_pll1200c32, | 829 | .recalc_rate = recalc_stm_pll1200c32, |
392 | }; | 830 | }; |
393 | 831 | ||
832 | static const struct clk_ops stm_pll4600c28_ops = { | ||
833 | .enable = clkgen_pll_enable, | ||
834 | .disable = clkgen_pll_disable, | ||
835 | .is_enabled = clkgen_pll_is_enabled, | ||
836 | .recalc_rate = recalc_stm_pll4600c28, | ||
837 | .round_rate = round_rate_stm_pll4600c28, | ||
838 | .set_rate = set_rate_stm_pll4600c28, | ||
839 | }; | ||
840 | |||
394 | static struct clk * __init clkgen_pll_register(const char *parent_name, | 841 | static struct clk * __init clkgen_pll_register(const char *parent_name, |
395 | struct clkgen_pll_data *pll_data, | 842 | struct clkgen_pll_data *pll_data, |
396 | void __iomem *reg, | 843 | void __iomem *reg, |
397 | const char *clk_name) | 844 | const char *clk_name, spinlock_t *lock) |
398 | { | 845 | { |
399 | struct clkgen_pll *pll; | 846 | struct clkgen_pll *pll; |
400 | struct clk *clk; | 847 | struct clk *clk; |
@@ -414,6 +861,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name, | |||
414 | pll->data = pll_data; | 861 | pll->data = pll_data; |
415 | pll->regs_base = reg; | 862 | pll->regs_base = reg; |
416 | pll->hw.init = &init; | 863 | pll->hw.init = &init; |
864 | pll->lock = lock; | ||
417 | 865 | ||
418 | clk = clk_register(NULL, &pll->hw); | 866 | clk = clk_register(NULL, &pll->hw); |
419 | if (IS_ERR(clk)) { | 867 | if (IS_ERR(clk)) { |
@@ -500,7 +948,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np) | |||
500 | */ | 948 | */ |
501 | clk_data->clks[0] = clkgen_pll_register(parent_name, | 949 | clk_data->clks[0] = clkgen_pll_register(parent_name, |
502 | (struct clkgen_pll_data *) &st_pll1600c65_ax, | 950 | (struct clkgen_pll_data *) &st_pll1600c65_ax, |
503 | reg + CLKGENAx_PLL0_OFFSET, clk_name); | 951 | reg + CLKGENAx_PLL0_OFFSET, clk_name, NULL); |
504 | 952 | ||
505 | if (IS_ERR(clk_data->clks[0])) | 953 | if (IS_ERR(clk_data->clks[0])) |
506 | goto err; | 954 | goto err; |
@@ -529,7 +977,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np) | |||
529 | */ | 977 | */ |
530 | clk_data->clks[2] = clkgen_pll_register(parent_name, | 978 | clk_data->clks[2] = clkgen_pll_register(parent_name, |
531 | (struct clkgen_pll_data *) &st_pll800c65_ax, | 979 | (struct clkgen_pll_data *) &st_pll800c65_ax, |
532 | reg + CLKGENAx_PLL1_OFFSET, clk_name); | 980 | reg + CLKGENAx_PLL1_OFFSET, clk_name, NULL); |
533 | 981 | ||
534 | if (IS_ERR(clk_data->clks[2])) | 982 | if (IS_ERR(clk_data->clks[2])) |
535 | goto err; | 983 | goto err; |
@@ -556,7 +1004,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name, | |||
556 | struct clk_gate *gate; | 1004 | struct clk_gate *gate; |
557 | struct clk_divider *div; | 1005 | struct clk_divider *div; |
558 | 1006 | ||
559 | flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE; | 1007 | flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT; |
560 | 1008 | ||
561 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | 1009 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); |
562 | if (!gate) | 1010 | if (!gate) |
@@ -635,6 +1083,10 @@ static const struct of_device_id c32_pll_of_match[] = { | |||
635 | .compatible = "st,stih407-plls-c32-a9", | 1083 | .compatible = "st,stih407-plls-c32-a9", |
636 | .data = &st_pll3200c32_407_a9, | 1084 | .data = &st_pll3200c32_407_a9, |
637 | }, | 1085 | }, |
1086 | { | ||
1087 | .compatible = "st,stih418-plls-c28-a9", | ||
1088 | .data = &st_pll4600c28_418_a9, | ||
1089 | }, | ||
638 | {} | 1090 | {} |
639 | }; | 1091 | }; |
640 | 1092 | ||
@@ -664,7 +1116,8 @@ static void __init clkgen_c32_pll_setup(struct device_node *np) | |||
664 | if (!pll_base) | 1116 | if (!pll_base) |
665 | return; | 1117 | return; |
666 | 1118 | ||
667 | clk = clkgen_pll_register(parent_name, data, pll_base, np->name); | 1119 | clk = clkgen_pll_register(parent_name, data, pll_base, np->name, |
1120 | data->lock); | ||
668 | if (IS_ERR(clk)) | 1121 | if (IS_ERR(clk)) |
669 | return; | 1122 | return; |
670 | 1123 | ||
@@ -753,7 +1206,7 @@ static void __init clkgengpu_c32_pll_setup(struct device_node *np) | |||
753 | /* | 1206 | /* |
754 | * PLL 1200MHz output | 1207 | * PLL 1200MHz output |
755 | */ | 1208 | */ |
756 | clk = clkgen_pll_register(parent_name, data, reg, clk_name); | 1209 | clk = clkgen_pll_register(parent_name, data, reg, clk_name, data->lock); |
757 | 1210 | ||
758 | if (!IS_ERR(clk)) | 1211 | if (!IS_ERR(clk)) |
759 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 1212 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
diff --git a/drivers/clk/st/clkgen.h b/drivers/clk/st/clkgen.h index 35c863295268..f7ec2d9139d6 100644 --- a/drivers/clk/st/clkgen.h +++ b/drivers/clk/st/clkgen.h | |||
@@ -9,6 +9,8 @@ Copyright (C) 2014 STMicroelectronics | |||
9 | #ifndef __CLKGEN_INFO_H | 9 | #ifndef __CLKGEN_INFO_H |
10 | #define __CLKGEN_INFO_H | 10 | #define __CLKGEN_INFO_H |
11 | 11 | ||
12 | extern spinlock_t clkgen_a9_lock; | ||
13 | |||
12 | struct clkgen_field { | 14 | struct clkgen_field { |
13 | unsigned int offset; | 15 | unsigned int offset; |
14 | unsigned int mask; | 16 | unsigned int mask; |
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile index f5a35b82cc1a..cb4c299214ce 100644 --- a/drivers/clk/sunxi/Makefile +++ b/drivers/clk/sunxi/Makefile | |||
@@ -3,7 +3,10 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += clk-sunxi.o clk-factors.o | 5 | obj-y += clk-sunxi.o clk-factors.o |
6 | obj-y += clk-a10-codec.o | ||
6 | obj-y += clk-a10-hosc.o | 7 | obj-y += clk-a10-hosc.o |
8 | obj-y += clk-a10-mod1.o | ||
9 | obj-y += clk-a10-pll2.o | ||
7 | obj-y += clk-a20-gmac.o | 10 | obj-y += clk-a20-gmac.o |
8 | obj-y += clk-mod0.o | 11 | obj-y += clk-mod0.o |
9 | obj-y += clk-simple-gates.o | 12 | obj-y += clk-simple-gates.o |
diff --git a/drivers/clk/sunxi/clk-a10-codec.c b/drivers/clk/sunxi/clk-a10-codec.c new file mode 100644 index 000000000000..ac321d6a0df5 --- /dev/null +++ b/drivers/clk/sunxi/clk-a10-codec.c | |||
@@ -0,0 +1,44 @@ | |||
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/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | |||
21 | #define SUN4I_CODEC_GATE 31 | ||
22 | |||
23 | static void __init sun4i_codec_clk_setup(struct device_node *node) | ||
24 | { | ||
25 | struct clk *clk; | ||
26 | const char *clk_name = node->name, *parent_name; | ||
27 | void __iomem *reg; | ||
28 | |||
29 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
30 | if (IS_ERR(reg)) | ||
31 | return; | ||
32 | |||
33 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
34 | parent_name = of_clk_get_parent_name(node, 0); | ||
35 | |||
36 | clk = clk_register_gate(NULL, clk_name, parent_name, | ||
37 | CLK_SET_RATE_PARENT, reg, | ||
38 | SUN4I_CODEC_GATE, 0, NULL); | ||
39 | |||
40 | if (!IS_ERR(clk)) | ||
41 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
42 | } | ||
43 | CLK_OF_DECLARE(sun4i_codec, "allwinner,sun4i-a10-codec-clk", | ||
44 | sun4i_codec_clk_setup); | ||
diff --git a/drivers/clk/sunxi/clk-a10-mod1.c b/drivers/clk/sunxi/clk-a10-mod1.c new file mode 100644 index 000000000000..e9d870de165c --- /dev/null +++ b/drivers/clk/sunxi/clk-a10-mod1.c | |||
@@ -0,0 +1,81 @@ | |||
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/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | static DEFINE_SPINLOCK(mod1_lock); | ||
23 | |||
24 | #define SUN4I_MOD1_ENABLE 31 | ||
25 | #define SUN4I_MOD1_MUX 16 | ||
26 | #define SUN4I_MOD1_MUX_WIDTH 2 | ||
27 | #define SUN4I_MOD1_MAX_PARENTS 4 | ||
28 | |||
29 | static void __init sun4i_mod1_clk_setup(struct device_node *node) | ||
30 | { | ||
31 | struct clk *clk; | ||
32 | struct clk_mux *mux; | ||
33 | struct clk_gate *gate; | ||
34 | const char *parents[4]; | ||
35 | const char *clk_name = node->name; | ||
36 | void __iomem *reg; | ||
37 | int i; | ||
38 | |||
39 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
40 | if (IS_ERR(reg)) | ||
41 | return; | ||
42 | |||
43 | mux = kzalloc(sizeof(*mux), GFP_KERNEL); | ||
44 | if (!mux) | ||
45 | goto err_unmap; | ||
46 | |||
47 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
48 | if (!gate) | ||
49 | goto err_free_mux; | ||
50 | |||
51 | of_property_read_string(node, "clock-output-names", &clk_name); | ||
52 | i = of_clk_parent_fill(node, parents, SUN4I_MOD1_MAX_PARENTS); | ||
53 | |||
54 | gate->reg = reg; | ||
55 | gate->bit_idx = SUN4I_MOD1_ENABLE; | ||
56 | gate->lock = &mod1_lock; | ||
57 | mux->reg = reg; | ||
58 | mux->shift = SUN4I_MOD1_MUX; | ||
59 | mux->mask = BIT(SUN4I_MOD1_MUX_WIDTH) - 1; | ||
60 | mux->lock = &mod1_lock; | ||
61 | |||
62 | clk = clk_register_composite(NULL, clk_name, parents, i, | ||
63 | &mux->hw, &clk_mux_ops, | ||
64 | NULL, NULL, | ||
65 | &gate->hw, &clk_gate_ops, 0); | ||
66 | if (IS_ERR(clk)) | ||
67 | goto err_free_gate; | ||
68 | |||
69 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | ||
70 | |||
71 | return; | ||
72 | |||
73 | err_free_gate: | ||
74 | kfree(gate); | ||
75 | err_free_mux: | ||
76 | kfree(mux); | ||
77 | err_unmap: | ||
78 | iounmap(reg); | ||
79 | } | ||
80 | CLK_OF_DECLARE(sun4i_mod1, "allwinner,sun4i-a10-mod1-clk", | ||
81 | sun4i_mod1_clk_setup); | ||
diff --git a/drivers/clk/sunxi/clk-a10-pll2.c b/drivers/clk/sunxi/clk-a10-pll2.c new file mode 100644 index 000000000000..5484c31ec568 --- /dev/null +++ b/drivers/clk/sunxi/clk-a10-pll2.c | |||
@@ -0,0 +1,216 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Emilio López | ||
3 | * Emilio López <emilio@elopez.com.ar> | ||
4 | * | ||
5 | * Copyright 2015 Maxime Ripard | ||
6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | */ | ||
18 | |||
19 | #include <linux/clk-provider.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_address.h> | ||
22 | #include <linux/slab.h> | ||
23 | |||
24 | #include <dt-bindings/clock/sun4i-a10-pll2.h> | ||
25 | |||
26 | #define SUN4I_PLL2_ENABLE 31 | ||
27 | |||
28 | #define SUN4I_PLL2_PRE_DIV_SHIFT 0 | ||
29 | #define SUN4I_PLL2_PRE_DIV_WIDTH 5 | ||
30 | #define SUN4I_PLL2_PRE_DIV_MASK GENMASK(SUN4I_PLL2_PRE_DIV_WIDTH - 1, 0) | ||
31 | |||
32 | #define SUN4I_PLL2_N_SHIFT 8 | ||
33 | #define SUN4I_PLL2_N_WIDTH 7 | ||
34 | #define SUN4I_PLL2_N_MASK GENMASK(SUN4I_PLL2_N_WIDTH - 1, 0) | ||
35 | |||
36 | #define SUN4I_PLL2_POST_DIV_SHIFT 26 | ||
37 | #define SUN4I_PLL2_POST_DIV_WIDTH 4 | ||
38 | #define SUN4I_PLL2_POST_DIV_MASK GENMASK(SUN4I_PLL2_POST_DIV_WIDTH - 1, 0) | ||
39 | |||
40 | #define SUN4I_PLL2_POST_DIV_VALUE 4 | ||
41 | |||
42 | #define SUN4I_PLL2_OUTPUTS 4 | ||
43 | |||
44 | struct sun4i_pll2_data { | ||
45 | u32 post_div_offset; | ||
46 | u32 pre_div_flags; | ||
47 | }; | ||
48 | |||
49 | static DEFINE_SPINLOCK(sun4i_a10_pll2_lock); | ||
50 | |||
51 | static void __init sun4i_pll2_setup(struct device_node *node, | ||
52 | struct sun4i_pll2_data *data) | ||
53 | { | ||
54 | const char *clk_name = node->name, *parent; | ||
55 | struct clk **clks, *base_clk, *prediv_clk; | ||
56 | struct clk_onecell_data *clk_data; | ||
57 | struct clk_multiplier *mult; | ||
58 | struct clk_gate *gate; | ||
59 | void __iomem *reg; | ||
60 | u32 val; | ||
61 | |||
62 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
63 | if (IS_ERR(reg)) | ||
64 | return; | ||
65 | |||
66 | clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); | ||
67 | if (!clk_data) | ||
68 | goto err_unmap; | ||
69 | |||
70 | clks = kcalloc(SUN4I_PLL2_OUTPUTS, sizeof(struct clk *), GFP_KERNEL); | ||
71 | if (!clks) | ||
72 | goto err_free_data; | ||
73 | |||
74 | parent = of_clk_get_parent_name(node, 0); | ||
75 | prediv_clk = clk_register_divider(NULL, "pll2-prediv", | ||
76 | parent, 0, reg, | ||
77 | SUN4I_PLL2_PRE_DIV_SHIFT, | ||
78 | SUN4I_PLL2_PRE_DIV_WIDTH, | ||
79 | data->pre_div_flags, | ||
80 | &sun4i_a10_pll2_lock); | ||
81 | if (!prediv_clk) { | ||
82 | pr_err("Couldn't register the prediv clock\n"); | ||
83 | goto err_free_array; | ||
84 | } | ||
85 | |||
86 | /* Setup the gate part of the PLL2 */ | ||
87 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | ||
88 | if (!gate) | ||
89 | goto err_unregister_prediv; | ||
90 | |||
91 | gate->reg = reg; | ||
92 | gate->bit_idx = SUN4I_PLL2_ENABLE; | ||
93 | gate->lock = &sun4i_a10_pll2_lock; | ||
94 | |||
95 | /* Setup the multiplier part of the PLL2 */ | ||
96 | mult = kzalloc(sizeof(struct clk_multiplier), GFP_KERNEL); | ||
97 | if (!mult) | ||
98 | goto err_free_gate; | ||
99 | |||
100 | mult->reg = reg; | ||
101 | mult->shift = SUN4I_PLL2_N_SHIFT; | ||
102 | mult->width = 7; | ||
103 | mult->flags = CLK_MULTIPLIER_ZERO_BYPASS | | ||
104 | CLK_MULTIPLIER_ROUND_CLOSEST; | ||
105 | mult->lock = &sun4i_a10_pll2_lock; | ||
106 | |||
107 | parent = __clk_get_name(prediv_clk); | ||
108 | base_clk = clk_register_composite(NULL, "pll2-base", | ||
109 | &parent, 1, | ||
110 | NULL, NULL, | ||
111 | &mult->hw, &clk_multiplier_ops, | ||
112 | &gate->hw, &clk_gate_ops, | ||
113 | CLK_SET_RATE_PARENT); | ||
114 | if (!base_clk) { | ||
115 | pr_err("Couldn't register the base multiplier clock\n"); | ||
116 | goto err_free_multiplier; | ||
117 | } | ||
118 | |||
119 | parent = __clk_get_name(base_clk); | ||
120 | |||
121 | /* | ||
122 | * PLL2-1x | ||
123 | * | ||
124 | * This is supposed to have a post divider, but we won't need | ||
125 | * to use it, we just need to initialise it to 4, and use a | ||
126 | * fixed divider. | ||
127 | */ | ||
128 | val = readl(reg); | ||
129 | val &= ~(SUN4I_PLL2_POST_DIV_MASK << SUN4I_PLL2_POST_DIV_SHIFT); | ||
130 | val |= (SUN4I_PLL2_POST_DIV_VALUE - data->post_div_offset) << SUN4I_PLL2_POST_DIV_SHIFT; | ||
131 | writel(val, reg); | ||
132 | |||
133 | of_property_read_string_index(node, "clock-output-names", | ||
134 | SUN4I_A10_PLL2_1X, &clk_name); | ||
135 | clks[SUN4I_A10_PLL2_1X] = clk_register_fixed_factor(NULL, clk_name, | ||
136 | parent, | ||
137 | CLK_SET_RATE_PARENT, | ||
138 | 1, | ||
139 | SUN4I_PLL2_POST_DIV_VALUE); | ||
140 | WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_1X])); | ||
141 | |||
142 | /* | ||
143 | * PLL2-2x | ||
144 | * | ||
145 | * This clock doesn't use the post divider, and really is just | ||
146 | * a fixed divider from the PLL2 base clock. | ||
147 | */ | ||
148 | of_property_read_string_index(node, "clock-output-names", | ||
149 | SUN4I_A10_PLL2_2X, &clk_name); | ||
150 | clks[SUN4I_A10_PLL2_2X] = clk_register_fixed_factor(NULL, clk_name, | ||
151 | parent, | ||
152 | CLK_SET_RATE_PARENT, | ||
153 | 1, 2); | ||
154 | WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_2X])); | ||
155 | |||
156 | /* PLL2-4x */ | ||
157 | of_property_read_string_index(node, "clock-output-names", | ||
158 | SUN4I_A10_PLL2_4X, &clk_name); | ||
159 | clks[SUN4I_A10_PLL2_4X] = clk_register_fixed_factor(NULL, clk_name, | ||
160 | parent, | ||
161 | CLK_SET_RATE_PARENT, | ||
162 | 1, 1); | ||
163 | WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_4X])); | ||
164 | |||
165 | /* PLL2-8x */ | ||
166 | of_property_read_string_index(node, "clock-output-names", | ||
167 | SUN4I_A10_PLL2_8X, &clk_name); | ||
168 | clks[SUN4I_A10_PLL2_8X] = clk_register_fixed_factor(NULL, clk_name, | ||
169 | parent, | ||
170 | CLK_SET_RATE_PARENT, | ||
171 | 2, 1); | ||
172 | WARN_ON(IS_ERR(clks[SUN4I_A10_PLL2_8X])); | ||
173 | |||
174 | clk_data->clks = clks; | ||
175 | clk_data->clk_num = SUN4I_PLL2_OUTPUTS; | ||
176 | of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | ||
177 | |||
178 | return; | ||
179 | |||
180 | err_free_multiplier: | ||
181 | kfree(mult); | ||
182 | err_free_gate: | ||
183 | kfree(gate); | ||
184 | err_unregister_prediv: | ||
185 | clk_unregister_divider(prediv_clk); | ||
186 | err_free_array: | ||
187 | kfree(clks); | ||
188 | err_free_data: | ||
189 | kfree(clk_data); | ||
190 | err_unmap: | ||
191 | iounmap(reg); | ||
192 | } | ||
193 | |||
194 | static struct sun4i_pll2_data sun4i_a10_pll2_data = { | ||
195 | .pre_div_flags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, | ||
196 | }; | ||
197 | |||
198 | static void __init sun4i_a10_pll2_setup(struct device_node *node) | ||
199 | { | ||
200 | sun4i_pll2_setup(node, &sun4i_a10_pll2_data); | ||
201 | } | ||
202 | |||
203 | CLK_OF_DECLARE(sun4i_a10_pll2, "allwinner,sun4i-a10-pll2-clk", | ||
204 | sun4i_a10_pll2_setup); | ||
205 | |||
206 | static struct sun4i_pll2_data sun5i_a13_pll2_data = { | ||
207 | .post_div_offset = 1, | ||
208 | }; | ||
209 | |||
210 | static void __init sun5i_a13_pll2_setup(struct device_node *node) | ||
211 | { | ||
212 | sun4i_pll2_setup(node, &sun5i_a13_pll2_data); | ||
213 | } | ||
214 | |||
215 | CLK_OF_DECLARE(sun5i_a13_pll2, "allwinner,sun5i-a13-pll2-clk", | ||
216 | sun5i_a13_pll2_setup); | ||
diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index 6ce91180da1b..0214c6548afd 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c | |||
@@ -128,6 +128,8 @@ CLK_OF_DECLARE(sun8i_a23_apb1, "allwinner,sun8i-a23-apb1-gates-clk", | |||
128 | sunxi_simple_gates_init); | 128 | sunxi_simple_gates_init); |
129 | CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", | 129 | CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", |
130 | sunxi_simple_gates_init); | 130 | sunxi_simple_gates_init); |
131 | CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk", | ||
132 | sunxi_simple_gates_init); | ||
131 | CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", | 133 | CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", |
132 | sunxi_simple_gates_init); | 134 | sunxi_simple_gates_init); |
133 | CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", | 135 | CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", |
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index 64f3e46d383c..23d042aabb4f 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c | |||
@@ -34,6 +34,7 @@ static const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = { | |||
34 | { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates }, | 34 | { .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates }, |
35 | { /* sentinel */ } | 35 | { /* sentinel */ } |
36 | }; | 36 | }; |
37 | MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_gates_clk_dt_ids); | ||
37 | 38 | ||
38 | static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) | 39 | static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) |
39 | { | 40 | { |
diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c index 70763600aeae..e703e1895b76 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0.c | |||
@@ -61,6 +61,7 @@ static const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = { | |||
61 | { .compatible = "allwinner,sun6i-a31-apb0-clk" }, | 61 | { .compatible = "allwinner,sun6i-a31-apb0-clk" }, |
62 | { /* sentinel */ } | 62 | { /* sentinel */ } |
63 | }; | 63 | }; |
64 | MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_clk_dt_ids); | ||
64 | 65 | ||
65 | static struct platform_driver sun6i_a31_apb0_clk_driver = { | 66 | static struct platform_driver sun6i_a31_apb0_clk_driver = { |
66 | .driver = { | 67 | .driver = { |
diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 806fd019c05d..20887686bdbe 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c | |||
@@ -219,6 +219,7 @@ static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { | |||
219 | { .compatible = "allwinner,sun6i-a31-ar100-clk" }, | 219 | { .compatible = "allwinner,sun6i-a31-ar100-clk" }, |
220 | { /* sentinel */ } | 220 | { /* sentinel */ } |
221 | }; | 221 | }; |
222 | MODULE_DEVICE_TABLE(of, sun6i_a31_ar100_clk_dt_ids); | ||
222 | 223 | ||
223 | static struct platform_driver sun6i_a31_ar100_clk_driver = { | 224 | static struct platform_driver sun6i_a31_ar100_clk_driver = { |
224 | .driver = { | 225 | .driver = { |
diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c index 155d0022194f..7ae5d2c2cde1 100644 --- a/drivers/clk/sunxi/clk-sun8i-apb0.c +++ b/drivers/clk/sunxi/clk-sun8i-apb0.c | |||
@@ -52,6 +52,7 @@ static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = { | |||
52 | { .compatible = "allwinner,sun8i-a23-apb0-clk" }, | 52 | { .compatible = "allwinner,sun8i-a23-apb0-clk" }, |
53 | { /* sentinel */ } | 53 | { /* sentinel */ } |
54 | }; | 54 | }; |
55 | MODULE_DEVICE_TABLE(of, sun8i_a23_apb0_clk_dt_ids); | ||
55 | 56 | ||
56 | static struct platform_driver sun8i_a23_apb0_clk_driver = { | 57 | static struct platform_driver sun8i_a23_apb0_clk_driver = { |
57 | .driver = { | 58 | .driver = { |
diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c index 3436a948b796..a9b176139aca 100644 --- a/drivers/clk/sunxi/clk-sun9i-mmc.c +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c | |||
@@ -204,6 +204,7 @@ static const struct of_device_id sun9i_a80_mmc_config_clk_dt_ids[] = { | |||
204 | { .compatible = "allwinner,sun9i-a80-mmc-config-clk" }, | 204 | { .compatible = "allwinner,sun9i-a80-mmc-config-clk" }, |
205 | { /* sentinel */ } | 205 | { /* sentinel */ } |
206 | }; | 206 | }; |
207 | MODULE_DEVICE_TABLE(of, sun9i_a80_mmc_config_clk_dt_ids); | ||
207 | 208 | ||
208 | static struct platform_driver sun9i_a80_mmc_config_clk_driver = { | 209 | static struct platform_driver sun9i_a80_mmc_config_clk_driver = { |
209 | .driver = { | 210 | .driver = { |
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index c4e3a52e225b..86a307b17eb0 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c | |||
@@ -469,56 +469,6 @@ static unsigned long dfll_scale_dvco_rate(int scale_bits, | |||
469 | } | 469 | } |
470 | 470 | ||
471 | /* | 471 | /* |
472 | * Monitor control | ||
473 | */ | ||
474 | |||
475 | /** | ||
476 | * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq | ||
477 | * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield | ||
478 | * @ref_rate: DFLL reference clock rate | ||
479 | * | ||
480 | * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles | ||
481 | * per second. Returns the converted value. | ||
482 | */ | ||
483 | static u64 dfll_calc_monitored_rate(u32 monitor_data, | ||
484 | unsigned long ref_rate) | ||
485 | { | ||
486 | return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE); | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor | ||
491 | * @td: DFLL instance | ||
492 | * | ||
493 | * If the DFLL is enabled, return the last rate reported by the DFLL's | ||
494 | * internal monitoring hardware. This works in both open-loop and | ||
495 | * closed-loop mode, and takes the output scaler setting into account. | ||
496 | * Assumes that the monitor was programmed to monitor frequency before | ||
497 | * the sample period started. If the driver believes that the DFLL is | ||
498 | * currently uninitialized or disabled, it will return 0, since | ||
499 | * otherwise the DFLL monitor data register will return the last | ||
500 | * measured rate from when the DFLL was active. | ||
501 | */ | ||
502 | static u64 dfll_read_monitor_rate(struct tegra_dfll *td) | ||
503 | { | ||
504 | u32 v, s; | ||
505 | u64 pre_scaler_rate, post_scaler_rate; | ||
506 | |||
507 | if (!dfll_is_running(td)) | ||
508 | return 0; | ||
509 | |||
510 | v = dfll_readl(td, DFLL_MONITOR_DATA); | ||
511 | v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT; | ||
512 | pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate); | ||
513 | |||
514 | s = dfll_readl(td, DFLL_FREQ_REQ); | ||
515 | s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT; | ||
516 | post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate); | ||
517 | |||
518 | return post_scaler_rate; | ||
519 | } | ||
520 | |||
521 | /* | ||
522 | * DFLL mode switching | 472 | * DFLL mode switching |
523 | */ | 473 | */ |
524 | 474 | ||
@@ -1006,24 +956,25 @@ static unsigned long dfll_clk_recalc_rate(struct clk_hw *hw, | |||
1006 | return td->last_unrounded_rate; | 956 | return td->last_unrounded_rate; |
1007 | } | 957 | } |
1008 | 958 | ||
1009 | static long dfll_clk_round_rate(struct clk_hw *hw, | 959 | /* Must use determine_rate since it allows for rates exceeding 2^31-1 */ |
1010 | unsigned long rate, | 960 | static int dfll_clk_determine_rate(struct clk_hw *hw, |
1011 | unsigned long *parent_rate) | 961 | struct clk_rate_request *clk_req) |
1012 | { | 962 | { |
1013 | struct tegra_dfll *td = clk_hw_to_dfll(hw); | 963 | struct tegra_dfll *td = clk_hw_to_dfll(hw); |
1014 | struct dfll_rate_req req; | 964 | struct dfll_rate_req req; |
1015 | int ret; | 965 | int ret; |
1016 | 966 | ||
1017 | ret = dfll_calculate_rate_request(td, &req, rate); | 967 | ret = dfll_calculate_rate_request(td, &req, clk_req->rate); |
1018 | if (ret) | 968 | if (ret) |
1019 | return ret; | 969 | return ret; |
1020 | 970 | ||
1021 | /* | 971 | /* |
1022 | * Don't return the rounded rate, since it doesn't really matter as | 972 | * Don't set the rounded rate, since it doesn't really matter as |
1023 | * the output rate will be voltage controlled anyway, and cpufreq | 973 | * the output rate will be voltage controlled anyway, and cpufreq |
1024 | * freaks out if any rounding happens. | 974 | * freaks out if any rounding happens. |
1025 | */ | 975 | */ |
1026 | return rate; | 976 | |
977 | return 0; | ||
1027 | } | 978 | } |
1028 | 979 | ||
1029 | static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate, | 980 | static int dfll_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
@@ -1039,7 +990,7 @@ static const struct clk_ops dfll_clk_ops = { | |||
1039 | .enable = dfll_clk_enable, | 990 | .enable = dfll_clk_enable, |
1040 | .disable = dfll_clk_disable, | 991 | .disable = dfll_clk_disable, |
1041 | .recalc_rate = dfll_clk_recalc_rate, | 992 | .recalc_rate = dfll_clk_recalc_rate, |
1042 | .round_rate = dfll_clk_round_rate, | 993 | .determine_rate = dfll_clk_determine_rate, |
1043 | .set_rate = dfll_clk_set_rate, | 994 | .set_rate = dfll_clk_set_rate, |
1044 | }; | 995 | }; |
1045 | 996 | ||
@@ -1101,6 +1052,55 @@ static void dfll_unregister_clk(struct tegra_dfll *td) | |||
1101 | */ | 1052 | */ |
1102 | 1053 | ||
1103 | #ifdef CONFIG_DEBUG_FS | 1054 | #ifdef CONFIG_DEBUG_FS |
1055 | /* | ||
1056 | * Monitor control | ||
1057 | */ | ||
1058 | |||
1059 | /** | ||
1060 | * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq | ||
1061 | * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield | ||
1062 | * @ref_rate: DFLL reference clock rate | ||
1063 | * | ||
1064 | * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles | ||
1065 | * per second. Returns the converted value. | ||
1066 | */ | ||
1067 | static u64 dfll_calc_monitored_rate(u32 monitor_data, | ||
1068 | unsigned long ref_rate) | ||
1069 | { | ||
1070 | return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE); | ||
1071 | } | ||
1072 | |||
1073 | /** | ||
1074 | * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor | ||
1075 | * @td: DFLL instance | ||
1076 | * | ||
1077 | * If the DFLL is enabled, return the last rate reported by the DFLL's | ||
1078 | * internal monitoring hardware. This works in both open-loop and | ||
1079 | * closed-loop mode, and takes the output scaler setting into account. | ||
1080 | * Assumes that the monitor was programmed to monitor frequency before | ||
1081 | * the sample period started. If the driver believes that the DFLL is | ||
1082 | * currently uninitialized or disabled, it will return 0, since | ||
1083 | * otherwise the DFLL monitor data register will return the last | ||
1084 | * measured rate from when the DFLL was active. | ||
1085 | */ | ||
1086 | static u64 dfll_read_monitor_rate(struct tegra_dfll *td) | ||
1087 | { | ||
1088 | u32 v, s; | ||
1089 | u64 pre_scaler_rate, post_scaler_rate; | ||
1090 | |||
1091 | if (!dfll_is_running(td)) | ||
1092 | return 0; | ||
1093 | |||
1094 | v = dfll_readl(td, DFLL_MONITOR_DATA); | ||
1095 | v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT; | ||
1096 | pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate); | ||
1097 | |||
1098 | s = dfll_readl(td, DFLL_FREQ_REQ); | ||
1099 | s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT; | ||
1100 | post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate); | ||
1101 | |||
1102 | return post_scaler_rate; | ||
1103 | } | ||
1104 | 1104 | ||
1105 | static int attr_enable_get(void *data, u64 *val) | 1105 | static int attr_enable_get(void *data, u64 *val) |
1106 | { | 1106 | { |
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index 138a94b99b5b..e1fe8f35d45c 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c | |||
@@ -491,10 +491,8 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np, | |||
491 | for_each_child_of_node(np, node) { | 491 | for_each_child_of_node(np, node) { |
492 | err = of_property_read_u32(node, "nvidia,ram-code", | 492 | err = of_property_read_u32(node, "nvidia,ram-code", |
493 | &node_ram_code); | 493 | &node_ram_code); |
494 | if (err) { | 494 | if (err) |
495 | of_node_put(node); | ||
496 | continue; | 495 | continue; |
497 | } | ||
498 | 496 | ||
499 | /* | 497 | /* |
500 | * Store timings for all ram codes as we cannot read the | 498 | * Store timings for all ram codes as we cannot read the |
diff --git a/drivers/clk/tegra/clk-tegra-audio.c b/drivers/clk/tegra/clk-tegra-audio.c index 11e3ad7ad7a3..e2bfa9b368f6 100644 --- a/drivers/clk/tegra/clk-tegra-audio.c +++ b/drivers/clk/tegra/clk-tegra-audio.c | |||
@@ -125,18 +125,29 @@ static struct tegra_audio2x_clk_initdata audio2x_clks[] = { | |||
125 | 125 | ||
126 | void __init tegra_audio_clk_init(void __iomem *clk_base, | 126 | void __init tegra_audio_clk_init(void __iomem *clk_base, |
127 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, | 127 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, |
128 | struct tegra_clk_pll_params *pll_a_params) | 128 | struct tegra_audio_clk_info *audio_info, |
129 | unsigned int num_plls) | ||
129 | { | 130 | { |
130 | struct clk *clk; | 131 | struct clk *clk; |
131 | struct clk **dt_clk; | 132 | struct clk **dt_clk; |
132 | int i; | 133 | int i; |
133 | 134 | ||
134 | /* PLLA */ | 135 | if (!audio_info || num_plls < 1) { |
135 | dt_clk = tegra_lookup_dt_id(tegra_clk_pll_a, tegra_clks); | 136 | pr_err("No audio data passed to tegra_audio_clk_init\n"); |
136 | if (dt_clk) { | 137 | WARN_ON(1); |
137 | clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, | 138 | return; |
138 | pmc_base, 0, pll_a_params, NULL); | 139 | } |
139 | *dt_clk = clk; | 140 | |
141 | for (i = 0; i < num_plls; i++) { | ||
142 | struct tegra_audio_clk_info *info = &audio_info[i]; | ||
143 | |||
144 | dt_clk = tegra_lookup_dt_id(info->clk_id, tegra_clks); | ||
145 | if (dt_clk) { | ||
146 | clk = tegra_clk_register_pll(info->name, info->parent, | ||
147 | clk_base, pmc_base, 0, info->pll_params, | ||
148 | NULL); | ||
149 | *dt_clk = clk; | ||
150 | } | ||
140 | } | 151 | } |
141 | 152 | ||
142 | /* PLLA_OUT0 */ | 153 | /* PLLA_OUT0 */ |
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index db5871519bf5..b7d03e9add97 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c | |||
@@ -933,6 +933,10 @@ static u32 mux_pllm_pllc2_c_c3_pllp_plla_idx[] = { | |||
933 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, | 933 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, |
934 | }; | 934 | }; |
935 | 935 | ||
936 | static struct tegra_audio_clk_info tegra114_audio_plls[] = { | ||
937 | { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, | ||
938 | }; | ||
939 | |||
936 | static struct clk **clks; | 940 | static struct clk **clks; |
937 | 941 | ||
938 | static unsigned long osc_freq; | 942 | static unsigned long osc_freq; |
@@ -1481,7 +1485,9 @@ static void __init tegra114_clock_init(struct device_node *np) | |||
1481 | tegra114_fixed_clk_init(clk_base); | 1485 | tegra114_fixed_clk_init(clk_base); |
1482 | tegra114_pll_init(clk_base, pmc_base); | 1486 | tegra114_pll_init(clk_base, pmc_base); |
1483 | tegra114_periph_clk_init(clk_base, pmc_base); | 1487 | tegra114_periph_clk_init(clk_base, pmc_base); |
1484 | tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, &pll_a_params); | 1488 | tegra_audio_clk_init(clk_base, pmc_base, tegra114_clks, |
1489 | tegra114_audio_plls, | ||
1490 | ARRAY_SIZE(tegra114_audio_plls)); | ||
1485 | tegra_pmc_clk_init(pmc_base, tegra114_clks); | 1491 | tegra_pmc_clk_init(pmc_base, tegra114_clks); |
1486 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, | 1492 | tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks, |
1487 | &pll_x_params); | 1493 | &pll_x_params); |
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 824d75883d2b..87975f7adddc 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c | |||
@@ -1417,6 +1417,10 @@ static struct tegra_clk_init_table tegra132_init_table[] __initdata = { | |||
1417 | {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, | 1417 | {TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0}, |
1418 | }; | 1418 | }; |
1419 | 1419 | ||
1420 | static struct tegra_audio_clk_info tegra124_audio_plls[] = { | ||
1421 | { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, | ||
1422 | }; | ||
1423 | |||
1420 | /** | 1424 | /** |
1421 | * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs | 1425 | * tegra124_clock_apply_init_table - initialize clocks on Tegra124 SoCs |
1422 | * | 1426 | * |
@@ -1555,7 +1559,9 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np) | |||
1555 | tegra_fixed_clk_init(tegra124_clks); | 1559 | tegra_fixed_clk_init(tegra124_clks); |
1556 | tegra124_pll_init(clk_base, pmc_base); | 1560 | tegra124_pll_init(clk_base, pmc_base); |
1557 | tegra124_periph_clk_init(clk_base, pmc_base); | 1561 | tegra124_periph_clk_init(clk_base, pmc_base); |
1558 | tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, &pll_a_params); | 1562 | tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, |
1563 | tegra124_audio_plls, | ||
1564 | ARRAY_SIZE(tegra124_audio_plls)); | ||
1559 | tegra_pmc_clk_init(pmc_base, tegra124_clks); | 1565 | tegra_pmc_clk_init(pmc_base, tegra124_clks); |
1560 | 1566 | ||
1561 | /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */ | 1567 | /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */ |
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index fad561a5896b..b90db615c29e 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c | |||
@@ -1405,6 +1405,10 @@ static const struct of_device_id pmc_match[] __initconst = { | |||
1405 | {}, | 1405 | {}, |
1406 | }; | 1406 | }; |
1407 | 1407 | ||
1408 | static struct tegra_audio_clk_info tegra30_audio_plls[] = { | ||
1409 | { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" }, | ||
1410 | }; | ||
1411 | |||
1408 | static void __init tegra30_clock_init(struct device_node *np) | 1412 | static void __init tegra30_clock_init(struct device_node *np) |
1409 | { | 1413 | { |
1410 | struct device_node *node; | 1414 | struct device_node *node; |
@@ -1442,7 +1446,9 @@ static void __init tegra30_clock_init(struct device_node *np) | |||
1442 | tegra30_pll_init(); | 1446 | tegra30_pll_init(); |
1443 | tegra30_super_clk_init(); | 1447 | tegra30_super_clk_init(); |
1444 | tegra30_periph_clk_init(); | 1448 | tegra30_periph_clk_init(); |
1445 | tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, &pll_a_params); | 1449 | tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks, |
1450 | tegra30_audio_plls, | ||
1451 | ARRAY_SIZE(tegra30_audio_plls)); | ||
1446 | tegra_pmc_clk_init(pmc_base, tegra30_clks); | 1452 | tegra_pmc_clk_init(pmc_base, tegra30_clks); |
1447 | 1453 | ||
1448 | tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); | 1454 | tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX); |
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 0621887e06f7..5d2678914160 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
@@ -157,7 +157,7 @@ struct div_nmp { | |||
157 | }; | 157 | }; |
158 | 158 | ||
159 | /** | 159 | /** |
160 | * struct clk_pll_params - PLL parameters | 160 | * struct tegra_clk_pll_params - PLL parameters |
161 | * | 161 | * |
162 | * @input_min: Minimum input frequency | 162 | * @input_min: Minimum input frequency |
163 | * @input_max: Maximum input frequency | 163 | * @input_max: Maximum input frequency |
@@ -168,9 +168,45 @@ struct div_nmp { | |||
168 | * @base_reg: PLL base reg offset | 168 | * @base_reg: PLL base reg offset |
169 | * @misc_reg: PLL misc reg offset | 169 | * @misc_reg: PLL misc reg offset |
170 | * @lock_reg: PLL lock reg offset | 170 | * @lock_reg: PLL lock reg offset |
171 | * @lock_bit_idx: Bit index for PLL lock status | 171 | * @lock_mask: Bitmask for PLL lock status |
172 | * @lock_enable_bit_idx: Bit index to enable PLL lock | 172 | * @lock_enable_bit_idx: Bit index to enable PLL lock |
173 | * @iddq_reg: PLL IDDQ register offset | ||
174 | * @iddq_bit_idx: Bit index to enable PLL IDDQ | ||
175 | * @aux_reg: AUX register offset | ||
176 | * @dyn_ramp_reg: Dynamic ramp control register offset | ||
177 | * @ext_misc_reg: Miscellaneous control register offsets | ||
178 | * @pmc_divnm_reg: n, m divider PMC override register offset (PLLM) | ||
179 | * @pmc_divp_reg: p divider PMC override register offset (PLLM) | ||
180 | * @flags: PLL flags | ||
181 | * @stepa_shift: Dynamic ramp step A field shift | ||
182 | * @stepb_shift: Dynamic ramp step B field shift | ||
173 | * @lock_delay: Delay in us if PLL lock is not used | 183 | * @lock_delay: Delay in us if PLL lock is not used |
184 | * @max_p: maximum value for the p divider | ||
185 | * @pdiv_tohw: mapping of p divider to register values | ||
186 | * @div_nmp: offsets and widths on n, m and p fields | ||
187 | * @freq_table: array of frequencies supported by PLL | ||
188 | * @fixed_rate: PLL rate if it is fixed | ||
189 | * | ||
190 | * Flags: | ||
191 | * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for | ||
192 | * PLL locking. If not set it will use lock_delay value to wait. | ||
193 | * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs | ||
194 | * to be programmed to change output frequency of the PLL. | ||
195 | * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs | ||
196 | * to be programmed to change output frequency of the PLL. | ||
197 | * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs | ||
198 | * to be programmed to change output frequency of the PLL. | ||
199 | * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated | ||
200 | * that it is PLLU and invert post divider value. | ||
201 | * TEGRA_PLLM - PLLM has additional override settings in PMC. This | ||
202 | * flag indicates that it is PLLM and use override settings. | ||
203 | * TEGRA_PLL_FIXED - We are not supposed to change output frequency | ||
204 | * of some plls. | ||
205 | * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling. | ||
206 | * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the | ||
207 | * base register. | ||
208 | * TEGRA_PLL_BYPASS - PLL has bypass bit | ||
209 | * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring | ||
174 | */ | 210 | */ |
175 | struct tegra_clk_pll_params { | 211 | struct tegra_clk_pll_params { |
176 | unsigned long input_min; | 212 | unsigned long input_min; |
@@ -203,38 +239,26 @@ struct tegra_clk_pll_params { | |||
203 | unsigned long fixed_rate; | 239 | unsigned long fixed_rate; |
204 | }; | 240 | }; |
205 | 241 | ||
242 | #define TEGRA_PLL_USE_LOCK BIT(0) | ||
243 | #define TEGRA_PLL_HAS_CPCON BIT(1) | ||
244 | #define TEGRA_PLL_SET_LFCON BIT(2) | ||
245 | #define TEGRA_PLL_SET_DCCON BIT(3) | ||
246 | #define TEGRA_PLLU BIT(4) | ||
247 | #define TEGRA_PLLM BIT(5) | ||
248 | #define TEGRA_PLL_FIXED BIT(6) | ||
249 | #define TEGRA_PLLE_CONFIGURE BIT(7) | ||
250 | #define TEGRA_PLL_LOCK_MISC BIT(8) | ||
251 | #define TEGRA_PLL_BYPASS BIT(9) | ||
252 | #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) | ||
253 | |||
206 | /** | 254 | /** |
207 | * struct tegra_clk_pll - Tegra PLL clock | 255 | * struct tegra_clk_pll - Tegra PLL clock |
208 | * | 256 | * |
209 | * @hw: handle between common and hardware-specifix interfaces | 257 | * @hw: handle between common and hardware-specifix interfaces |
210 | * @clk_base: address of CAR controller | 258 | * @clk_base: address of CAR controller |
211 | * @pmc: address of PMC, required to read override bits | 259 | * @pmc: address of PMC, required to read override bits |
212 | * @freq_table: array of frequencies supported by PLL | ||
213 | * @params: PLL parameters | ||
214 | * @flags: PLL flags | ||
215 | * @fixed_rate: PLL rate if it is fixed | ||
216 | * @lock: register lock | 260 | * @lock: register lock |
217 | * | 261 | * @params: PLL parameters |
218 | * Flags: | ||
219 | * TEGRA_PLL_USE_LOCK - This flag indicated to use lock bits for | ||
220 | * PLL locking. If not set it will use lock_delay value to wait. | ||
221 | * TEGRA_PLL_HAS_CPCON - This flag indicates that CPCON value needs | ||
222 | * to be programmed to change output frequency of the PLL. | ||
223 | * TEGRA_PLL_SET_LFCON - This flag indicates that LFCON value needs | ||
224 | * to be programmed to change output frequency of the PLL. | ||
225 | * TEGRA_PLL_SET_DCCON - This flag indicates that DCCON value needs | ||
226 | * to be programmed to change output frequency of the PLL. | ||
227 | * TEGRA_PLLU - PLLU has inverted post divider. This flags indicated | ||
228 | * that it is PLLU and invert post divider value. | ||
229 | * TEGRA_PLLM - PLLM has additional override settings in PMC. This | ||
230 | * flag indicates that it is PLLM and use override settings. | ||
231 | * TEGRA_PLL_FIXED - We are not supposed to change output frequency | ||
232 | * of some plls. | ||
233 | * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling. | ||
234 | * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the | ||
235 | * base register. | ||
236 | * TEGRA_PLL_BYPASS - PLL has bypass bit | ||
237 | * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring | ||
238 | */ | 262 | */ |
239 | struct tegra_clk_pll { | 263 | struct tegra_clk_pll { |
240 | struct clk_hw hw; | 264 | struct clk_hw hw; |
@@ -246,17 +270,20 @@ struct tegra_clk_pll { | |||
246 | 270 | ||
247 | #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw) | 271 | #define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw) |
248 | 272 | ||
249 | #define TEGRA_PLL_USE_LOCK BIT(0) | 273 | /** |
250 | #define TEGRA_PLL_HAS_CPCON BIT(1) | 274 | * struct tegra_audio_clk_info - Tegra Audio Clk Information |
251 | #define TEGRA_PLL_SET_LFCON BIT(2) | 275 | * |
252 | #define TEGRA_PLL_SET_DCCON BIT(3) | 276 | * @name: name for the audio pll |
253 | #define TEGRA_PLLU BIT(4) | 277 | * @pll_params: pll_params for audio pll |
254 | #define TEGRA_PLLM BIT(5) | 278 | * @clk_id: clk_ids for the audio pll |
255 | #define TEGRA_PLL_FIXED BIT(6) | 279 | * @parent: name of the parent of the audio pll |
256 | #define TEGRA_PLLE_CONFIGURE BIT(7) | 280 | */ |
257 | #define TEGRA_PLL_LOCK_MISC BIT(8) | 281 | struct tegra_audio_clk_info { |
258 | #define TEGRA_PLL_BYPASS BIT(9) | 282 | char *name; |
259 | #define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10) | 283 | struct tegra_clk_pll_params *pll_params; |
284 | int clk_id; | ||
285 | char *parent; | ||
286 | }; | ||
260 | 287 | ||
261 | extern const struct clk_ops tegra_clk_pll_ops; | 288 | extern const struct clk_ops tegra_clk_pll_ops; |
262 | extern const struct clk_ops tegra_clk_plle_ops; | 289 | extern const struct clk_ops tegra_clk_plle_ops; |
@@ -610,7 +637,8 @@ void tegra_register_devclks(struct tegra_devclk *dev_clks, int num); | |||
610 | 637 | ||
611 | void tegra_audio_clk_init(void __iomem *clk_base, | 638 | void tegra_audio_clk_init(void __iomem *clk_base, |
612 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, | 639 | void __iomem *pmc_base, struct tegra_clk *tegra_clks, |
613 | struct tegra_clk_pll_params *pll_params); | 640 | struct tegra_audio_clk_info *audio_info, |
641 | unsigned int num_plls); | ||
614 | 642 | ||
615 | void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, | 643 | void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base, |
616 | struct tegra_clk *tegra_clks, | 644 | struct tegra_clk *tegra_clks, |
diff --git a/drivers/clk/tegra/cvb.c b/drivers/clk/tegra/cvb.c index 0204e0861134..69c74eec3a4b 100644 --- a/drivers/clk/tegra/cvb.c +++ b/drivers/clk/tegra/cvb.c | |||
@@ -78,13 +78,6 @@ static int build_opp_table(const struct cvb_table *d, | |||
78 | if (!table->freq || (table->freq > max_freq)) | 78 | if (!table->freq || (table->freq > max_freq)) |
79 | break; | 79 | break; |
80 | 80 | ||
81 | /* | ||
82 | * FIXME after clk_round_rate/clk_determine_rate prototypes | ||
83 | * have been updated | ||
84 | */ | ||
85 | if (table->freq & (1<<31)) | ||
86 | continue; | ||
87 | |||
88 | dfll_mv = get_cvb_voltage( | 81 | dfll_mv = get_cvb_voltage( |
89 | speedo_value, d->speedo_scale, &table->coefficients); | 82 | speedo_value, d->speedo_scale, &table->coefficients); |
90 | dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align); | 83 | dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align); |
diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig index 1530c9352a76..fc50b6264bed 100644 --- a/drivers/clk/versatile/Kconfig +++ b/drivers/clk/versatile/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config COMMON_CLK_VERSATILE | 1 | config COMMON_CLK_VERSATILE |
2 | bool "Clock driver for ARM Reference designs" | 2 | bool "Clock driver for ARM Reference designs" |
3 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 | 3 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 || COMPILE_TEST |
4 | ---help--- | 4 | ---help--- |
5 | Supports clocking on ARM Reference designs: | 5 | Supports clocking on ARM Reference designs: |
6 | - Integrator/AP and Integrator/CP | 6 | - Integrator/AP and Integrator/CP |
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index a3893ea2199d..08c5ee976879 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c | |||
@@ -157,8 +157,10 @@ struct clk *icst_clk_register(struct device *dev, | |||
157 | icst->lockreg = base + desc->lock_offset; | 157 | icst->lockreg = base + desc->lock_offset; |
158 | 158 | ||
159 | clk = clk_register(dev, &icst->hw); | 159 | clk = clk_register(dev, &icst->hw); |
160 | if (IS_ERR(clk)) | 160 | if (IS_ERR(clk)) { |
161 | kfree(pclone); | ||
161 | kfree(icst); | 162 | kfree(icst); |
163 | } | ||
162 | 164 | ||
163 | return clk; | 165 | return clk; |
164 | } | 166 | } |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a0cdbf35dcb1..a5d319e4aae6 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -227,10 +227,6 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, | |||
227 | if (IS_ERR(d->clk) || !old) | 227 | if (IS_ERR(d->clk) || !old) |
228 | goto out; | 228 | goto out; |
229 | 229 | ||
230 | /* Not requesting clock rates below 1.8432Mhz */ | ||
231 | if (baud < 115200) | ||
232 | baud = 115200; | ||
233 | |||
234 | clk_disable_unprepare(d->clk); | 230 | clk_disable_unprepare(d->clk); |
235 | rate = clk_round_rate(d->clk, baud * 16); | 231 | rate = clk_round_rate(d->clk, baud * 16); |
236 | ret = clk_set_rate(d->clk, rate); | 232 | ret = clk_set_rate(d->clk, rate); |
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h index 0b4cb999a3f7..ab3ee241d10c 100644 --- a/include/dt-bindings/clock/at91.h +++ b/include/dt-bindings/clock/at91.h | |||
@@ -18,5 +18,6 @@ | |||
18 | #define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */ | 18 | #define AT91_PMC_MOSCSELS 16 /* Main Oscillator Selection */ |
19 | #define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */ | 19 | #define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */ |
20 | #define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */ | 20 | #define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */ |
21 | #define AT91_PMC_GCKRDY 24 /* Generated Clocks */ | ||
21 | 22 | ||
22 | #endif | 23 | #endif |
diff --git a/include/dt-bindings/clock/bcm-ns2.h b/include/dt-bindings/clock/bcm-ns2.h new file mode 100644 index 000000000000..d99c7a2e70cb --- /dev/null +++ b/include/dt-bindings/clock/bcm-ns2.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * BSD LICENSE | ||
3 | * | ||
4 | * Copyright(c) 2015 Broadcom Corporation. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * * Neither the name of Broadcom Corporation nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #ifndef _CLOCK_BCM_NS2_H | ||
34 | #define _CLOCK_BCM_NS2_H | ||
35 | |||
36 | /* GENPLL SCR clock channel ID */ | ||
37 | #define BCM_NS2_GENPLL_SCR 0 | ||
38 | #define BCM_NS2_GENPLL_SCR_SCR_CLK 1 | ||
39 | #define BCM_NS2_GENPLL_SCR_FS_CLK 2 | ||
40 | #define BCM_NS2_GENPLL_SCR_AUDIO_CLK 3 | ||
41 | #define BCM_NS2_GENPLL_SCR_CH3_UNUSED 4 | ||
42 | #define BCM_NS2_GENPLL_SCR_CH4_UNUSED 5 | ||
43 | #define BCM_NS2_GENPLL_SCR_CH5_UNUSED 6 | ||
44 | |||
45 | /* GENPLL SW clock channel ID */ | ||
46 | #define BCM_NS2_GENPLL_SW 0 | ||
47 | #define BCM_NS2_GENPLL_SW_RPE_CLK 1 | ||
48 | #define BCM_NS2_GENPLL_SW_250_CLK 2 | ||
49 | #define BCM_NS2_GENPLL_SW_NIC_CLK 3 | ||
50 | #define BCM_NS2_GENPLL_SW_CHIMP_CLK 4 | ||
51 | #define BCM_NS2_GENPLL_SW_PORT_CLK 5 | ||
52 | #define BCM_NS2_GENPLL_SW_SDIO_CLK 6 | ||
53 | |||
54 | /* LCPLL DDR clock channel ID */ | ||
55 | #define BCM_NS2_LCPLL_DDR 0 | ||
56 | #define BCM_NS2_LCPLL_DDR_PCIE_SATA_USB_CLK 1 | ||
57 | #define BCM_NS2_LCPLL_DDR_DDR_CLK 2 | ||
58 | #define BCM_NS2_LCPLL_DDR_CH2_UNUSED 3 | ||
59 | #define BCM_NS2_LCPLL_DDR_CH3_UNUSED 4 | ||
60 | #define BCM_NS2_LCPLL_DDR_CH4_UNUSED 5 | ||
61 | #define BCM_NS2_LCPLL_DDR_CH5_UNUSED 6 | ||
62 | |||
63 | /* LCPLL PORTS clock channel ID */ | ||
64 | #define BCM_NS2_LCPLL_PORTS 0 | ||
65 | #define BCM_NS2_LCPLL_PORTS_WAN_CLK 1 | ||
66 | #define BCM_NS2_LCPLL_PORTS_RGMII_CLK 2 | ||
67 | #define BCM_NS2_LCPLL_PORTS_CH2_UNUSED 3 | ||
68 | #define BCM_NS2_LCPLL_PORTS_CH3_UNUSED 4 | ||
69 | #define BCM_NS2_LCPLL_PORTS_CH4_UNUSED 5 | ||
70 | #define BCM_NS2_LCPLL_PORTS_CH5_UNUSED 6 | ||
71 | |||
72 | #endif /* _CLOCK_BCM_NS2_H */ | ||
diff --git a/include/dt-bindings/clock/bcm-nsp.h b/include/dt-bindings/clock/bcm-nsp.h new file mode 100644 index 000000000000..ad5827cde782 --- /dev/null +++ b/include/dt-bindings/clock/bcm-nsp.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * BSD LICENSE | ||
3 | * | ||
4 | * Copyright(c) 2015 Broadcom Corporation. All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * | ||
10 | * * Redistributions of source code must retain the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer. | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in | ||
14 | * the documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * * Neither the name of Broadcom Corporation nor the names of its | ||
17 | * contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | */ | ||
32 | |||
33 | #ifndef _CLOCK_BCM_NSP_H | ||
34 | #define _CLOCK_BCM_NSP_H | ||
35 | |||
36 | /* GENPLL clock channel ID */ | ||
37 | #define BCM_NSP_GENPLL 0 | ||
38 | #define BCM_NSP_GENPLL_PHY_CLK 1 | ||
39 | #define BCM_NSP_GENPLL_ENET_SW_CLK 2 | ||
40 | #define BCM_NSP_GENPLL_USB_PHY_REF_CLK 3 | ||
41 | #define BCM_NSP_GENPLL_IPROCFAST_CLK 4 | ||
42 | #define BCM_NSP_GENPLL_SATA1_CLK 5 | ||
43 | #define BCM_NSP_GENPLL_SATA2_CLK 6 | ||
44 | |||
45 | /* LCPLL0 clock channel ID */ | ||
46 | #define BCM_NSP_LCPLL0 0 | ||
47 | #define BCM_NSP_LCPLL0_PCIE_PHY_REF_CLK 1 | ||
48 | #define BCM_NSP_LCPLL0_SDIO_CLK 2 | ||
49 | #define BCM_NSP_LCPLL0_DDR_PHY_CLK 3 | ||
50 | |||
51 | #endif /* _CLOCK_BCM_NSP_H */ | ||
diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h new file mode 100644 index 000000000000..d323efac7edf --- /dev/null +++ b/include/dt-bindings/clock/bcm2835.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #define BCM2835_PLLA 0 | ||
15 | #define BCM2835_PLLB 1 | ||
16 | #define BCM2835_PLLC 2 | ||
17 | #define BCM2835_PLLD 3 | ||
18 | #define BCM2835_PLLH 4 | ||
19 | |||
20 | #define BCM2835_PLLA_CORE 5 | ||
21 | #define BCM2835_PLLA_PER 6 | ||
22 | #define BCM2835_PLLB_ARM 7 | ||
23 | #define BCM2835_PLLC_CORE0 8 | ||
24 | #define BCM2835_PLLC_CORE1 9 | ||
25 | #define BCM2835_PLLC_CORE2 10 | ||
26 | #define BCM2835_PLLC_PER 11 | ||
27 | #define BCM2835_PLLD_CORE 12 | ||
28 | #define BCM2835_PLLD_PER 13 | ||
29 | #define BCM2835_PLLH_RCAL 14 | ||
30 | #define BCM2835_PLLH_AUX 15 | ||
31 | #define BCM2835_PLLH_PIX 16 | ||
32 | |||
33 | #define BCM2835_CLOCK_TIMER 17 | ||
34 | #define BCM2835_CLOCK_OTP 18 | ||
35 | #define BCM2835_CLOCK_UART 19 | ||
36 | #define BCM2835_CLOCK_VPU 20 | ||
37 | #define BCM2835_CLOCK_V3D 21 | ||
38 | #define BCM2835_CLOCK_ISP 22 | ||
39 | #define BCM2835_CLOCK_H264 23 | ||
40 | #define BCM2835_CLOCK_VEC 24 | ||
41 | #define BCM2835_CLOCK_HSM 25 | ||
42 | #define BCM2835_CLOCK_SDRAM 26 | ||
43 | #define BCM2835_CLOCK_TSENS 27 | ||
44 | #define BCM2835_CLOCK_EMMC 28 | ||
45 | #define BCM2835_CLOCK_PERI_IMAGE 29 | ||
46 | |||
47 | #define BCM2835_CLOCK_COUNT 30 | ||
diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index e33c75a3c09d..10c558611085 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h | |||
@@ -21,7 +21,18 @@ | |||
21 | #define ACLK_MSCL_532 8 | 21 | #define ACLK_MSCL_532 8 |
22 | #define DOUT_SCLK_AUD_PLL 9 | 22 | #define DOUT_SCLK_AUD_PLL 9 |
23 | #define FOUT_AUD_PLL 10 | 23 | #define FOUT_AUD_PLL 10 |
24 | #define TOPC_NR_CLK 11 | 24 | #define SCLK_AUD_PLL 11 |
25 | #define SCLK_MFC_PLL_B 12 | ||
26 | #define SCLK_MFC_PLL_A 13 | ||
27 | #define SCLK_BUS1_PLL_B 14 | ||
28 | #define SCLK_BUS1_PLL_A 15 | ||
29 | #define SCLK_BUS0_PLL_B 16 | ||
30 | #define SCLK_BUS0_PLL_A 17 | ||
31 | #define SCLK_CC_PLL_B 18 | ||
32 | #define SCLK_CC_PLL_A 19 | ||
33 | #define ACLK_CCORE_133 20 | ||
34 | #define ACLK_PERIS_66 21 | ||
35 | #define TOPC_NR_CLK 22 | ||
25 | 36 | ||
26 | /* TOP0 */ | 37 | /* TOP0 */ |
27 | #define DOUT_ACLK_PERIC1 1 | 38 | #define DOUT_ACLK_PERIC1 1 |
@@ -38,7 +49,9 @@ | |||
38 | #define CLK_SCLK_SPDIF 12 | 49 | #define CLK_SCLK_SPDIF 12 |
39 | #define CLK_SCLK_PCM1 13 | 50 | #define CLK_SCLK_PCM1 13 |
40 | #define CLK_SCLK_I2S1 14 | 51 | #define CLK_SCLK_I2S1 14 |
41 | #define TOP0_NR_CLK 15 | 52 | #define CLK_ACLK_PERIC0_66 15 |
53 | #define CLK_ACLK_PERIC1_66 16 | ||
54 | #define TOP0_NR_CLK 17 | ||
42 | 55 | ||
43 | /* TOP1 */ | 56 | /* TOP1 */ |
44 | #define DOUT_ACLK_FSYS1_200 1 | 57 | #define DOUT_ACLK_FSYS1_200 1 |
@@ -49,7 +62,16 @@ | |||
49 | #define CLK_SCLK_MMC2 6 | 62 | #define CLK_SCLK_MMC2 6 |
50 | #define CLK_SCLK_MMC1 7 | 63 | #define CLK_SCLK_MMC1 7 |
51 | #define CLK_SCLK_MMC0 8 | 64 | #define CLK_SCLK_MMC0 8 |
52 | #define TOP1_NR_CLK 9 | 65 | #define CLK_ACLK_FSYS0_200 9 |
66 | #define CLK_ACLK_FSYS1_200 10 | ||
67 | #define CLK_SCLK_PHY_FSYS1 11 | ||
68 | #define CLK_SCLK_PHY_FSYS1_26M 12 | ||
69 | #define MOUT_SCLK_UFSUNIPRO20 13 | ||
70 | #define DOUT_SCLK_UFSUNIPRO20 14 | ||
71 | #define CLK_SCLK_UFSUNIPRO20 15 | ||
72 | #define DOUT_SCLK_PHY_FSYS1 16 | ||
73 | #define DOUT_SCLK_PHY_FSYS1_26M 17 | ||
74 | #define TOP1_NR_CLK 18 | ||
53 | 75 | ||
54 | /* CCORE */ | 76 | /* CCORE */ |
55 | #define PCLK_RTC 1 | 77 | #define PCLK_RTC 1 |
@@ -124,7 +146,20 @@ | |||
124 | /* FSYS1 */ | 146 | /* FSYS1 */ |
125 | #define ACLK_MMC1 1 | 147 | #define ACLK_MMC1 1 |
126 | #define ACLK_MMC0 2 | 148 | #define ACLK_MMC0 2 |
127 | #define FSYS1_NR_CLK 3 | 149 | #define PHYCLK_UFS20_TX0_SYMBOL 3 |
150 | #define PHYCLK_UFS20_RX0_SYMBOL 4 | ||
151 | #define PHYCLK_UFS20_RX1_SYMBOL 5 | ||
152 | #define ACLK_UFS20_LINK 6 | ||
153 | #define SCLK_UFSUNIPRO20_USER 7 | ||
154 | #define PHYCLK_UFS20_RX1_SYMBOL_USER 8 | ||
155 | #define PHYCLK_UFS20_RX0_SYMBOL_USER 9 | ||
156 | #define PHYCLK_UFS20_TX0_SYMBOL_USER 10 | ||
157 | #define OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY 11 | ||
158 | #define SCLK_COMBO_PHY_EMBEDDED_26M 12 | ||
159 | #define DOUT_PCLK_FSYS1 13 | ||
160 | #define PCLK_GPIO_FSYS1 14 | ||
161 | #define MOUT_FSYS1_PHYCLK_SEL1 15 | ||
162 | #define FSYS1_NR_CLK 16 | ||
128 | 163 | ||
129 | /* MSCL */ | 164 | /* MSCL */ |
130 | #define USERMUX_ACLK_MSCL_532 1 | 165 | #define USERMUX_ACLK_MSCL_532 1 |
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h index 8de173ff19f3..77985cc43316 100644 --- a/include/dt-bindings/clock/imx6qdl-clock.h +++ b/include/dt-bindings/clock/imx6qdl-clock.h | |||
@@ -254,6 +254,7 @@ | |||
254 | #define IMX6QDL_CLK_CAAM_MEM 241 | 254 | #define IMX6QDL_CLK_CAAM_MEM 241 |
255 | #define IMX6QDL_CLK_CAAM_ACLK 242 | 255 | #define IMX6QDL_CLK_CAAM_ACLK 242 |
256 | #define IMX6QDL_CLK_CAAM_IPG 243 | 256 | #define IMX6QDL_CLK_CAAM_IPG 243 |
257 | #define IMX6QDL_CLK_END 244 | 257 | #define IMX6QDL_CLK_SPDIF_GCLK 244 |
258 | #define IMX6QDL_CLK_END 245 | ||
258 | 259 | ||
259 | #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ | 260 | #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ |
diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h index 9ce4e421096f..e14573e293c5 100644 --- a/include/dt-bindings/clock/imx6sl-clock.h +++ b/include/dt-bindings/clock/imx6sl-clock.h | |||
@@ -174,6 +174,7 @@ | |||
174 | #define IMX6SL_CLK_SSI1_IPG 161 | 174 | #define IMX6SL_CLK_SSI1_IPG 161 |
175 | #define IMX6SL_CLK_SSI2_IPG 162 | 175 | #define IMX6SL_CLK_SSI2_IPG 162 |
176 | #define IMX6SL_CLK_SSI3_IPG 163 | 176 | #define IMX6SL_CLK_SSI3_IPG 163 |
177 | #define IMX6SL_CLK_END 164 | 177 | #define IMX6SL_CLK_SPDIF_GCLK 164 |
178 | #define IMX6SL_CLK_END 165 | ||
178 | 179 | ||
179 | #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ | 180 | #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ |
diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h index 995709119ec5..36f0324902a5 100644 --- a/include/dt-bindings/clock/imx6sx-clock.h +++ b/include/dt-bindings/clock/imx6sx-clock.h | |||
@@ -274,6 +274,7 @@ | |||
274 | #define IMX6SX_PLL5_BYPASS 261 | 274 | #define IMX6SX_PLL5_BYPASS 261 |
275 | #define IMX6SX_PLL6_BYPASS 262 | 275 | #define IMX6SX_PLL6_BYPASS 262 |
276 | #define IMX6SX_PLL7_BYPASS 263 | 276 | #define IMX6SX_PLL7_BYPASS 263 |
277 | #define IMX6SX_CLK_CLK_END 264 | 277 | #define IMX6SX_CLK_SPDIF_GCLK 264 |
278 | #define IMX6SX_CLK_CLK_END 265 | ||
278 | 279 | ||
279 | #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ | 280 | #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ |
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h index 728df28b00d5..a4a7a9ce3457 100644 --- a/include/dt-bindings/clock/imx7d-clock.h +++ b/include/dt-bindings/clock/imx7d-clock.h | |||
@@ -446,5 +446,6 @@ | |||
446 | #define IMX7D_MU_ROOT_CLK 433 | 446 | #define IMX7D_MU_ROOT_CLK 433 |
447 | #define IMX7D_SEMA4_HS_ROOT_CLK 434 | 447 | #define IMX7D_SEMA4_HS_ROOT_CLK 434 |
448 | #define IMX7D_PLL_DRAM_TEST_DIV 435 | 448 | #define IMX7D_PLL_DRAM_TEST_DIV 435 |
449 | #define IMX7D_CLK_END 436 | 449 | #define IMX7D_ADC_ROOT_CLK 436 |
450 | #define IMX7D_CLK_END 437 | ||
450 | #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ | 451 | #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */ |
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h index 4ad76ed882ad..7956ba1bc974 100644 --- a/include/dt-bindings/clock/mt8173-clk.h +++ b/include/dt-bindings/clock/mt8173-clk.h | |||
@@ -18,7 +18,6 @@ | |||
18 | /* TOPCKGEN */ | 18 | /* TOPCKGEN */ |
19 | 19 | ||
20 | #define CLK_TOP_CLKPH_MCK_O 1 | 20 | #define CLK_TOP_CLKPH_MCK_O 1 |
21 | #define CLK_TOP_DPI 2 | ||
22 | #define CLK_TOP_USB_SYSPLL_125M 3 | 21 | #define CLK_TOP_USB_SYSPLL_125M 3 |
23 | #define CLK_TOP_HDMITX_DIG_CTS 4 | 22 | #define CLK_TOP_HDMITX_DIG_CTS 4 |
24 | #define CLK_TOP_ARMCA7PLL_754M 5 | 23 | #define CLK_TOP_ARMCA7PLL_754M 5 |
@@ -154,12 +153,16 @@ | |||
154 | #define CLK_TOP_I2S2_M_SEL 135 | 153 | #define CLK_TOP_I2S2_M_SEL 135 |
155 | #define CLK_TOP_I2S3_M_SEL 136 | 154 | #define CLK_TOP_I2S3_M_SEL 136 |
156 | #define CLK_TOP_I2S3_B_SEL 137 | 155 | #define CLK_TOP_I2S3_B_SEL 137 |
157 | #define CLK_TOP_NR_CLK 138 | 156 | #define CLK_TOP_DSI0_DIG 138 |
157 | #define CLK_TOP_DSI1_DIG 139 | ||
158 | #define CLK_TOP_LVDS_PXL 140 | ||
159 | #define CLK_TOP_LVDS_CTS 141 | ||
160 | #define CLK_TOP_NR_CLK 142 | ||
158 | 161 | ||
159 | /* APMIXED_SYS */ | 162 | /* APMIXED_SYS */ |
160 | 163 | ||
161 | #define CLK_APMIXED_ARMCA15PLL 1 | 164 | #define CLK_APMIXED_ARMCA15PLL 1 |
162 | #define CLK_APMIXED_ARMCA7PLL 2 | 165 | #define CLK_APMIXED_ARMCA7PLL 2 |
163 | #define CLK_APMIXED_MAINPLL 3 | 166 | #define CLK_APMIXED_MAINPLL 3 |
164 | #define CLK_APMIXED_UNIVPLL 4 | 167 | #define CLK_APMIXED_UNIVPLL 4 |
165 | #define CLK_APMIXED_MMPLL 5 | 168 | #define CLK_APMIXED_MMPLL 5 |
@@ -172,7 +175,8 @@ | |||
172 | #define CLK_APMIXED_APLL2 12 | 175 | #define CLK_APMIXED_APLL2 12 |
173 | #define CLK_APMIXED_LVDSPLL 13 | 176 | #define CLK_APMIXED_LVDSPLL 13 |
174 | #define CLK_APMIXED_MSDCPLL2 14 | 177 | #define CLK_APMIXED_MSDCPLL2 14 |
175 | #define CLK_APMIXED_NR_CLK 15 | 178 | #define CLK_APMIXED_REF2USB_TX 15 |
179 | #define CLK_APMIXED_NR_CLK 16 | ||
176 | 180 | ||
177 | /* INFRA_SYS */ | 181 | /* INFRA_SYS */ |
178 | 182 | ||
@@ -187,7 +191,8 @@ | |||
187 | #define CLK_INFRA_CEC 9 | 191 | #define CLK_INFRA_CEC 9 |
188 | #define CLK_INFRA_PMICSPI 10 | 192 | #define CLK_INFRA_PMICSPI 10 |
189 | #define CLK_INFRA_PMICWRAP 11 | 193 | #define CLK_INFRA_PMICWRAP 11 |
190 | #define CLK_INFRA_NR_CLK 12 | 194 | #define CLK_INFRA_CLK_13M 12 |
195 | #define CLK_INFRA_NR_CLK 13 | ||
191 | 196 | ||
192 | /* PERI_SYS */ | 197 | /* PERI_SYS */ |
193 | 198 | ||
@@ -232,4 +237,91 @@ | |||
232 | #define CLK_PERI_UART3_SEL 39 | 237 | #define CLK_PERI_UART3_SEL 39 |
233 | #define CLK_PERI_NR_CLK 40 | 238 | #define CLK_PERI_NR_CLK 40 |
234 | 239 | ||
240 | /* IMG_SYS */ | ||
241 | |||
242 | #define CLK_IMG_LARB2_SMI 1 | ||
243 | #define CLK_IMG_CAM_SMI 2 | ||
244 | #define CLK_IMG_CAM_CAM 3 | ||
245 | #define CLK_IMG_SEN_TG 4 | ||
246 | #define CLK_IMG_SEN_CAM 5 | ||
247 | #define CLK_IMG_CAM_SV 6 | ||
248 | #define CLK_IMG_FD 7 | ||
249 | #define CLK_IMG_NR_CLK 8 | ||
250 | |||
251 | /* MM_SYS */ | ||
252 | |||
253 | #define CLK_MM_SMI_COMMON 1 | ||
254 | #define CLK_MM_SMI_LARB0 2 | ||
255 | #define CLK_MM_CAM_MDP 3 | ||
256 | #define CLK_MM_MDP_RDMA0 4 | ||
257 | #define CLK_MM_MDP_RDMA1 5 | ||
258 | #define CLK_MM_MDP_RSZ0 6 | ||
259 | #define CLK_MM_MDP_RSZ1 7 | ||
260 | #define CLK_MM_MDP_RSZ2 8 | ||
261 | #define CLK_MM_MDP_TDSHP0 9 | ||
262 | #define CLK_MM_MDP_TDSHP1 10 | ||
263 | #define CLK_MM_MDP_WDMA 11 | ||
264 | #define CLK_MM_MDP_WROT0 12 | ||
265 | #define CLK_MM_MDP_WROT1 13 | ||
266 | #define CLK_MM_FAKE_ENG 14 | ||
267 | #define CLK_MM_MUTEX_32K 15 | ||
268 | #define CLK_MM_DISP_OVL0 16 | ||
269 | #define CLK_MM_DISP_OVL1 17 | ||
270 | #define CLK_MM_DISP_RDMA0 18 | ||
271 | #define CLK_MM_DISP_RDMA1 19 | ||
272 | #define CLK_MM_DISP_RDMA2 20 | ||
273 | #define CLK_MM_DISP_WDMA0 21 | ||
274 | #define CLK_MM_DISP_WDMA1 22 | ||
275 | #define CLK_MM_DISP_COLOR0 23 | ||
276 | #define CLK_MM_DISP_COLOR1 24 | ||
277 | #define CLK_MM_DISP_AAL 25 | ||
278 | #define CLK_MM_DISP_GAMMA 26 | ||
279 | #define CLK_MM_DISP_UFOE 27 | ||
280 | #define CLK_MM_DISP_SPLIT0 28 | ||
281 | #define CLK_MM_DISP_SPLIT1 29 | ||
282 | #define CLK_MM_DISP_MERGE 30 | ||
283 | #define CLK_MM_DISP_OD 31 | ||
284 | #define CLK_MM_DISP_PWM0MM 32 | ||
285 | #define CLK_MM_DISP_PWM026M 33 | ||
286 | #define CLK_MM_DISP_PWM1MM 34 | ||
287 | #define CLK_MM_DISP_PWM126M 35 | ||
288 | #define CLK_MM_DSI0_ENGINE 36 | ||
289 | #define CLK_MM_DSI0_DIGITAL 37 | ||
290 | #define CLK_MM_DSI1_ENGINE 38 | ||
291 | #define CLK_MM_DSI1_DIGITAL 39 | ||
292 | #define CLK_MM_DPI_PIXEL 40 | ||
293 | #define CLK_MM_DPI_ENGINE 41 | ||
294 | #define CLK_MM_DPI1_PIXEL 42 | ||
295 | #define CLK_MM_DPI1_ENGINE 43 | ||
296 | #define CLK_MM_HDMI_PIXEL 44 | ||
297 | #define CLK_MM_HDMI_PLLCK 45 | ||
298 | #define CLK_MM_HDMI_AUDIO 46 | ||
299 | #define CLK_MM_HDMI_SPDIF 47 | ||
300 | #define CLK_MM_LVDS_PIXEL 48 | ||
301 | #define CLK_MM_LVDS_CTS 49 | ||
302 | #define CLK_MM_SMI_LARB4 50 | ||
303 | #define CLK_MM_HDMI_HDCP 51 | ||
304 | #define CLK_MM_HDMI_HDCP24M 52 | ||
305 | #define CLK_MM_NR_CLK 53 | ||
306 | |||
307 | /* VDEC_SYS */ | ||
308 | |||
309 | #define CLK_VDEC_CKEN 1 | ||
310 | #define CLK_VDEC_LARB_CKEN 2 | ||
311 | #define CLK_VDEC_NR_CLK 3 | ||
312 | |||
313 | /* VENC_SYS */ | ||
314 | |||
315 | #define CLK_VENC_CKE0 1 | ||
316 | #define CLK_VENC_CKE1 2 | ||
317 | #define CLK_VENC_CKE2 3 | ||
318 | #define CLK_VENC_CKE3 4 | ||
319 | #define CLK_VENC_NR_CLK 5 | ||
320 | |||
321 | /* VENCLT_SYS */ | ||
322 | |||
323 | #define CLK_VENCLT_CKE0 1 | ||
324 | #define CLK_VENCLT_CKE1 2 | ||
325 | #define CLK_VENCLT_NR_CLK 3 | ||
326 | |||
235 | #endif /* _DT_BINDINGS_CLK_MT8173_H */ | 327 | #endif /* _DT_BINDINGS_CLK_MT8173_H */ |
diff --git a/include/dt-bindings/clock/qcom,gcc-apq8084.h b/include/dt-bindings/clock/qcom,gcc-apq8084.h index 2c0da566c46a..5aa7ebeae411 100644 --- a/include/dt-bindings/clock/qcom,gcc-apq8084.h +++ b/include/dt-bindings/clock/qcom,gcc-apq8084.h | |||
@@ -348,4 +348,10 @@ | |||
348 | #define GCC_PCIE_1_PIPE_CLK 331 | 348 | #define GCC_PCIE_1_PIPE_CLK 331 |
349 | #define GCC_PCIE_1_SLV_AXI_CLK 332 | 349 | #define GCC_PCIE_1_SLV_AXI_CLK 332 |
350 | 350 | ||
351 | /* gdscs */ | ||
352 | #define USB_HS_HSIC_GDSC 0 | ||
353 | #define PCIE0_GDSC 1 | ||
354 | #define PCIE1_GDSC 2 | ||
355 | #define USB30_GDSC 3 | ||
356 | |||
351 | #endif | 357 | #endif |
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8916.h b/include/dt-bindings/clock/qcom,gcc-msm8916.h index e430f644dd6c..257e2fbedd94 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8916.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8916.h | |||
@@ -152,5 +152,35 @@ | |||
152 | #define GCC_VENUS0_AHB_CLK 135 | 152 | #define GCC_VENUS0_AHB_CLK 135 |
153 | #define GCC_VENUS0_AXI_CLK 136 | 153 | #define GCC_VENUS0_AXI_CLK 136 |
154 | #define GCC_VENUS0_VCODEC0_CLK 137 | 154 | #define GCC_VENUS0_VCODEC0_CLK 137 |
155 | #define BIMC_DDR_CLK_SRC 138 | ||
156 | #define GCC_APSS_TCU_CLK 139 | ||
157 | #define GCC_GFX_TCU_CLK 140 | ||
158 | #define BIMC_GPU_CLK_SRC 141 | ||
159 | #define GCC_BIMC_GFX_CLK 142 | ||
160 | #define GCC_BIMC_GPU_CLK 143 | ||
161 | #define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC 144 | ||
162 | #define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC 145 | ||
163 | #define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC 146 | ||
164 | #define ULTAUDIO_XO_CLK_SRC 147 | ||
165 | #define ULTAUDIO_AHBFABRIC_CLK_SRC 148 | ||
166 | #define CODEC_DIGCODEC_CLK_SRC 149 | ||
167 | #define GCC_ULTAUDIO_PCNOC_MPORT_CLK 150 | ||
168 | #define GCC_ULTAUDIO_PCNOC_SWAY_CLK 151 | ||
169 | #define GCC_ULTAUDIO_AVSYNC_XO_CLK 152 | ||
170 | #define GCC_ULTAUDIO_STC_XO_CLK 153 | ||
171 | #define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK 154 | ||
172 | #define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK 155 | ||
173 | #define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK 156 | ||
174 | #define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157 | ||
175 | #define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158 | ||
176 | #define GCC_CODEC_DIGCODEC_CLK 159 | ||
177 | |||
178 | /* Indexes for GDSCs */ | ||
179 | #define BIMC_GDSC 0 | ||
180 | #define VENUS_GDSC 1 | ||
181 | #define MDSS_GDSC 2 | ||
182 | #define JPEG_GDSC 3 | ||
183 | #define VFE_GDSC 4 | ||
184 | #define OXILI_GDSC 5 | ||
155 | 185 | ||
156 | #endif | 186 | #endif |
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8974.h b/include/dt-bindings/clock/qcom,gcc-msm8974.h index 51e51c860fe6..81d32f639190 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8974.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h | |||
@@ -321,4 +321,7 @@ | |||
321 | #define GCC_SDCC1_CDCCAL_SLEEP_CLK 304 | 321 | #define GCC_SDCC1_CDCCAL_SLEEP_CLK 304 |
322 | #define GCC_SDCC1_CDCCAL_FF_CLK 305 | 322 | #define GCC_SDCC1_CDCCAL_FF_CLK 305 |
323 | 323 | ||
324 | /* gdscs */ | ||
325 | #define USB_HS_HSIC_GDSC 0 | ||
326 | |||
324 | #endif | 327 | #endif |
diff --git a/include/dt-bindings/clock/qcom,mmcc-apq8084.h b/include/dt-bindings/clock/qcom,mmcc-apq8084.h index d72b5b35f15e..03861e3f498e 100644 --- a/include/dt-bindings/clock/qcom,mmcc-apq8084.h +++ b/include/dt-bindings/clock/qcom,mmcc-apq8084.h | |||
@@ -180,4 +180,14 @@ | |||
180 | #define VPU_SLEEP_CLK 163 | 180 | #define VPU_SLEEP_CLK 163 |
181 | #define VPU_VDP_CLK 164 | 181 | #define VPU_VDP_CLK 164 |
182 | 182 | ||
183 | /* GDSCs */ | ||
184 | #define VENUS0_GDSC 0 | ||
185 | #define VENUS0_CORE0_GDSC 1 | ||
186 | #define VENUS0_CORE1_GDSC 2 | ||
187 | #define MDSS_GDSC 3 | ||
188 | #define CAMSS_JPEG_GDSC 4 | ||
189 | #define CAMSS_VFE_GDSC 5 | ||
190 | #define OXILI_GDSC 6 | ||
191 | #define OXILICX_GDSC 7 | ||
192 | |||
183 | #endif | 193 | #endif |
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8974.h b/include/dt-bindings/clock/qcom,mmcc-msm8974.h index 032ed87ef0f3..28651e54c9ae 100644 --- a/include/dt-bindings/clock/qcom,mmcc-msm8974.h +++ b/include/dt-bindings/clock/qcom,mmcc-msm8974.h | |||
@@ -158,4 +158,12 @@ | |||
158 | #define SPDM_RM_AXI 141 | 158 | #define SPDM_RM_AXI 141 |
159 | #define SPDM_RM_OCMEMNOC 142 | 159 | #define SPDM_RM_OCMEMNOC 142 |
160 | 160 | ||
161 | /* gdscs */ | ||
162 | #define VENUS0_GDSC 0 | ||
163 | #define MDSS_GDSC 1 | ||
164 | #define CAMSS_JPEG_GDSC 2 | ||
165 | #define CAMSS_VFE_GDSC 3 | ||
166 | #define OXILI_GDSC 4 | ||
167 | #define OXILICX_GDSC 5 | ||
168 | |||
161 | #endif | 169 | #endif |
diff --git a/include/dt-bindings/clock/r8a7795-cpg-mssr.h b/include/dt-bindings/clock/r8a7795-cpg-mssr.h new file mode 100644 index 000000000000..e864aae0a256 --- /dev/null +++ b/include/dt-bindings/clock/r8a7795-cpg-mssr.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Renesas Electronics Corp. | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | #ifndef __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ | ||
10 | #define __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ | ||
11 | |||
12 | #include <dt-bindings/clock/renesas-cpg-mssr.h> | ||
13 | |||
14 | /* r8a7795 CPG Core Clocks */ | ||
15 | #define R8A7795_CLK_Z 0 | ||
16 | #define R8A7795_CLK_Z2 1 | ||
17 | #define R8A7795_CLK_ZR 2 | ||
18 | #define R8A7795_CLK_ZG 3 | ||
19 | #define R8A7795_CLK_ZTR 4 | ||
20 | #define R8A7795_CLK_ZTRD2 5 | ||
21 | #define R8A7795_CLK_ZT 6 | ||
22 | #define R8A7795_CLK_ZX 7 | ||
23 | #define R8A7795_CLK_S0D1 8 | ||
24 | #define R8A7795_CLK_S0D4 9 | ||
25 | #define R8A7795_CLK_S1D1 10 | ||
26 | #define R8A7795_CLK_S1D2 11 | ||
27 | #define R8A7795_CLK_S1D4 12 | ||
28 | #define R8A7795_CLK_S2D1 13 | ||
29 | #define R8A7795_CLK_S2D2 14 | ||
30 | #define R8A7795_CLK_S2D4 15 | ||
31 | #define R8A7795_CLK_S3D1 16 | ||
32 | #define R8A7795_CLK_S3D2 17 | ||
33 | #define R8A7795_CLK_S3D4 18 | ||
34 | #define R8A7795_CLK_LB 19 | ||
35 | #define R8A7795_CLK_CL 20 | ||
36 | #define R8A7795_CLK_ZB3 21 | ||
37 | #define R8A7795_CLK_ZB3D2 22 | ||
38 | #define R8A7795_CLK_CR 23 | ||
39 | #define R8A7795_CLK_CRD2 24 | ||
40 | #define R8A7795_CLK_SD0H 25 | ||
41 | #define R8A7795_CLK_SD0 26 | ||
42 | #define R8A7795_CLK_SD1H 27 | ||
43 | #define R8A7795_CLK_SD1 28 | ||
44 | #define R8A7795_CLK_SD2H 29 | ||
45 | #define R8A7795_CLK_SD2 30 | ||
46 | #define R8A7795_CLK_SD3H 31 | ||
47 | #define R8A7795_CLK_SD3 32 | ||
48 | #define R8A7795_CLK_SSP2 33 | ||
49 | #define R8A7795_CLK_SSP1 34 | ||
50 | #define R8A7795_CLK_SSPRS 35 | ||
51 | #define R8A7795_CLK_RPC 36 | ||
52 | #define R8A7795_CLK_RPCD2 37 | ||
53 | #define R8A7795_CLK_MSO 38 | ||
54 | #define R8A7795_CLK_CANFD 39 | ||
55 | #define R8A7795_CLK_HDMI 40 | ||
56 | #define R8A7795_CLK_CSI0 41 | ||
57 | #define R8A7795_CLK_CSIREF 42 | ||
58 | #define R8A7795_CLK_CP 43 | ||
59 | #define R8A7795_CLK_CPEX 44 | ||
60 | #define R8A7795_CLK_R 45 | ||
61 | #define R8A7795_CLK_OSC 46 | ||
62 | |||
63 | #endif /* __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ */ | ||
diff --git a/include/dt-bindings/clock/renesas-cpg-mssr.h b/include/dt-bindings/clock/renesas-cpg-mssr.h new file mode 100644 index 000000000000..569a3cc33ffb --- /dev/null +++ b/include/dt-bindings/clock/renesas-cpg-mssr.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 Renesas Electronics Corp. | ||
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 as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | #ifndef __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ | ||
10 | #define __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ | ||
11 | |||
12 | #define CPG_CORE 0 /* Core Clock */ | ||
13 | #define CPG_MOD 1 /* Module Clock */ | ||
14 | |||
15 | #endif /* __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ */ | ||
diff --git a/include/dt-bindings/clock/sun4i-a10-pll2.h b/include/dt-bindings/clock/sun4i-a10-pll2.h new file mode 100644 index 000000000000..071c8112d531 --- /dev/null +++ b/include/dt-bindings/clock/sun4i-a10-pll2.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Maxime Ripard | ||
3 | * | ||
4 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
5 | * | ||
6 | * This file is dual-licensed: you can use it either under the terms | ||
7 | * of the GPL or the X11 license, at your option. Note that this dual | ||
8 | * licensing only applies to this file, and not this project as a | ||
9 | * whole. | ||
10 | * | ||
11 | * a) This file is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License as | ||
13 | * published by the Free Software Foundation; either version 2 of the | ||
14 | * License, or (at your option) any later version. | ||
15 | * | ||
16 | * This file is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * Or, alternatively, | ||
22 | * | ||
23 | * b) Permission is hereby granted, free of charge, to any person | ||
24 | * obtaining a copy of this software and associated documentation | ||
25 | * files (the "Software"), to deal in the Software without | ||
26 | * restriction, including without limitation the rights to use, | ||
27 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
28 | * sell copies of the Software, and to permit persons to whom the | ||
29 | * Software is furnished to do so, subject to the following | ||
30 | * conditions: | ||
31 | * | ||
32 | * The above copyright notice and this permission notice shall be | ||
33 | * included in all copies or substantial portions of the Software. | ||
34 | * | ||
35 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
36 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
37 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
38 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
39 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
40 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
41 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
42 | * OTHER DEALINGS IN THE SOFTWARE. | ||
43 | */ | ||
44 | |||
45 | #ifndef __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_ | ||
46 | #define __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_ | ||
47 | |||
48 | #define SUN4I_A10_PLL2_1X 0 | ||
49 | #define SUN4I_A10_PLL2_2X 1 | ||
50 | #define SUN4I_A10_PLL2_4X 2 | ||
51 | #define SUN4I_A10_PLL2_8X 3 | ||
52 | |||
53 | #endif /* __DT_BINDINGS_CLOCK_SUN4I_A10_PLL2_H_ */ | ||
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index d19763439472..56c16aaea112 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h | |||
@@ -194,6 +194,7 @@ | |||
194 | #define VF610_PLL7_BYPASS 181 | 194 | #define VF610_PLL7_BYPASS 181 |
195 | #define VF610_CLK_SNVS 182 | 195 | #define VF610_CLK_SNVS 182 |
196 | #define VF610_CLK_DAP 183 | 196 | #define VF610_CLK_DAP 183 |
197 | #define VF610_CLK_END 184 | 197 | #define VF610_CLK_OCOTP 184 |
198 | #define VF610_CLK_END 185 | ||
198 | 199 | ||
199 | #endif /* __DT_BINDINGS_CLOCK_VF610_H */ | 200 | #endif /* __DT_BINDINGS_CLOCK_VF610_H */ |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 3ecc07d0da77..c56988ac63f7 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -500,13 +500,14 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, | |||
500 | * | 500 | * |
501 | * Clock with adjustable fractional divider affecting its output frequency. | 501 | * Clock with adjustable fractional divider affecting its output frequency. |
502 | */ | 502 | */ |
503 | |||
504 | struct clk_fractional_divider { | 503 | struct clk_fractional_divider { |
505 | struct clk_hw hw; | 504 | struct clk_hw hw; |
506 | void __iomem *reg; | 505 | void __iomem *reg; |
507 | u8 mshift; | 506 | u8 mshift; |
507 | u8 mwidth; | ||
508 | u32 mmask; | 508 | u32 mmask; |
509 | u8 nshift; | 509 | u8 nshift; |
510 | u8 nwidth; | ||
510 | u32 nmask; | 511 | u32 nmask; |
511 | u8 flags; | 512 | u8 flags; |
512 | spinlock_t *lock; | 513 | spinlock_t *lock; |
@@ -518,6 +519,41 @@ struct clk *clk_register_fractional_divider(struct device *dev, | |||
518 | void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, | 519 | void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, |
519 | u8 clk_divider_flags, spinlock_t *lock); | 520 | u8 clk_divider_flags, spinlock_t *lock); |
520 | 521 | ||
522 | /** | ||
523 | * struct clk_multiplier - adjustable multiplier clock | ||
524 | * | ||
525 | * @hw: handle between common and hardware-specific interfaces | ||
526 | * @reg: register containing the multiplier | ||
527 | * @shift: shift to the multiplier bit field | ||
528 | * @width: width of the multiplier bit field | ||
529 | * @lock: register lock | ||
530 | * | ||
531 | * Clock with an adjustable multiplier affecting its output frequency. | ||
532 | * Implements .recalc_rate, .set_rate and .round_rate | ||
533 | * | ||
534 | * Flags: | ||
535 | * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read | ||
536 | * from the register, with 0 being a valid value effectively | ||
537 | * zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is | ||
538 | * set, then a null multiplier will be considered as a bypass, | ||
539 | * leaving the parent rate unmodified. | ||
540 | * CLK_MULTIPLIER_ROUND_CLOSEST - Makes the best calculated divider to be | ||
541 | * rounded to the closest integer instead of the down one. | ||
542 | */ | ||
543 | struct clk_multiplier { | ||
544 | struct clk_hw hw; | ||
545 | void __iomem *reg; | ||
546 | u8 shift; | ||
547 | u8 width; | ||
548 | u8 flags; | ||
549 | spinlock_t *lock; | ||
550 | }; | ||
551 | |||
552 | #define CLK_MULTIPLIER_ZERO_BYPASS BIT(0) | ||
553 | #define CLK_MULTIPLIER_ROUND_CLOSEST BIT(1) | ||
554 | |||
555 | extern const struct clk_ops clk_multiplier_ops; | ||
556 | |||
521 | /*** | 557 | /*** |
522 | * struct clk_composite - aggregate clock of mux, divider and gate clocks | 558 | * struct clk_composite - aggregate clock of mux, divider and gate clocks |
523 | * | 559 | * |
@@ -606,7 +642,7 @@ void clk_unregister(struct clk *clk); | |||
606 | void devm_clk_unregister(struct device *dev, struct clk *clk); | 642 | void devm_clk_unregister(struct device *dev, struct clk *clk); |
607 | 643 | ||
608 | /* helper functions */ | 644 | /* helper functions */ |
609 | const char *__clk_get_name(struct clk *clk); | 645 | const char *__clk_get_name(const struct clk *clk); |
610 | const char *clk_hw_get_name(const struct clk_hw *hw); | 646 | const char *clk_hw_get_name(const struct clk_hw *hw); |
611 | struct clk_hw *__clk_get_hw(struct clk *clk); | 647 | struct clk_hw *__clk_get_hw(struct clk *clk); |
612 | unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); | 648 | unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); |
@@ -618,6 +654,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw); | |||
618 | unsigned long __clk_get_flags(struct clk *clk); | 654 | unsigned long __clk_get_flags(struct clk *clk); |
619 | unsigned long clk_hw_get_flags(const struct clk_hw *hw); | 655 | unsigned long clk_hw_get_flags(const struct clk_hw *hw); |
620 | bool clk_hw_is_prepared(const struct clk_hw *hw); | 656 | bool clk_hw_is_prepared(const struct clk_hw *hw); |
657 | bool clk_hw_is_enabled(const struct clk_hw *hw); | ||
621 | bool __clk_is_enabled(struct clk *clk); | 658 | bool __clk_is_enabled(struct clk *clk); |
622 | struct clk *__clk_lookup(const char *name); | 659 | struct clk *__clk_lookup(const char *name); |
623 | int __clk_mux_determine_rate(struct clk_hw *hw, | 660 | int __clk_mux_determine_rate(struct clk_hw *hw, |
@@ -690,6 +727,15 @@ static inline struct clk *of_clk_src_onecell_get( | |||
690 | { | 727 | { |
691 | return ERR_PTR(-ENOENT); | 728 | return ERR_PTR(-ENOENT); |
692 | } | 729 | } |
730 | static inline int of_clk_get_parent_count(struct device_node *np) | ||
731 | { | ||
732 | return 0; | ||
733 | } | ||
734 | static inline int of_clk_parent_fill(struct device_node *np, | ||
735 | const char **parents, unsigned int size) | ||
736 | { | ||
737 | return 0; | ||
738 | } | ||
693 | static inline const char *of_clk_get_parent_name(struct device_node *np, | 739 | static inline const char *of_clk_get_parent_name(struct device_node *np, |
694 | int index) | 740 | int index) |
695 | { | 741 | { |
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 7669f7618f39..1e6932222e11 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h | |||
@@ -164,6 +164,7 @@ extern void __iomem *at91_pmc_base; | |||
164 | #define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */ | 164 | #define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */ |
165 | #define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ | 165 | #define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ |
166 | #define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ | 166 | #define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ |
167 | #define AT91_PMC_GCKRDY (1 << 24) /* Generated Clocks */ | ||
167 | #define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ | 168 | #define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ |
168 | 169 | ||
169 | #define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */ | 170 | #define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */ |
@@ -182,13 +183,18 @@ extern void __iomem *at91_pmc_base; | |||
182 | #define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */ | 183 | #define AT91_PMC_PCSR1 0x108 /* Peripheral Clock Enable Register 1 */ |
183 | 184 | ||
184 | #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ | 185 | #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ |
185 | #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ | 186 | #define AT91_PMC_PCR_PID_MASK 0x3f |
186 | #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ | 187 | #define AT91_PMC_PCR_GCKCSS_OFFSET 8 |
187 | #define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor Value */ | 188 | #define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET) |
188 | #define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */ | 189 | #define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */ |
189 | #define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */ | 190 | #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ |
190 | #define AT91_PMC_PCR_DIV4 0x2 /* Peripheral clock is MCK/4 */ | 191 | #define AT91_PMC_PCR_DIV_OFFSET 16 |
191 | #define AT91_PMC_PCR_DIV8 0x3 /* Peripheral clock is MCK/8 */ | 192 | #define AT91_PMC_PCR_DIV_MASK (0x3 << AT91_PMC_PCR_DIV_OFFSET) |
192 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ | 193 | #define AT91_PMC_PCR_DIV(n) ((n) << AT91_PMC_PCR_DIV_OFFSET) /* Divisor Value */ |
194 | #define AT91_PMC_PCR_GCKDIV_OFFSET 20 | ||
195 | #define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET) | ||
196 | #define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */ | ||
197 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ | ||
198 | #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ | ||
193 | 199 | ||
194 | #endif | 200 | #endif |