diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-13 14:04:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-13 14:04:14 -0400 |
commit | f60a2abfdbf298a4722dfef331c38447fa18c4e3 (patch) | |
tree | 1ac56db32fb1909aedefc21b1c62d0bbe5a13e68 | |
parent | 561a8eb3e1d219f415597c76dae44b530b7f961a (diff) | |
parent | 73c950da6ec523136090d6d4d6907a6ea8e8b67b (diff) |
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd:
"The diff is dominated by the Allwinner A10/A20 SoCs getting converted
to the sunxi-ng framework. Otherwise, the heavy hitters are various
drivers for SoCs like AT91, Amlogic, Renesas, and Rockchip. There are
some other new clk drivers in here too but overall this is just a
bunch of clk drivers for various different pieces of hardware and a
collection of non-critical fixes for clk drivers.
New Drivers:
- Allwinner R40 SoCs
- Renesas R-Car Gen3 USB 2.0 clock selector PHY
- Atmel AT91 audio PLL
- Uniphier PXs3 SoCs
- ARC HSDK Board PLLs
- AXS10X Board PLLs
- STMicroelectronics STM32H743 SoCs
Removed Drivers:
- Non-compiling mb86s7x support
Updates:
- Allwinner A10/A20 SoCs converted to sunxi-ng framework
- Allwinner H3 CPU clk fixes
- Renesas R-Car D3 SoC
- Renesas V2H and M3-W modules
- Samsung Exynos5420/5422/5800 audio fixes
- Rockchip fractional clk approximation fixes
- Rockchip rk3126 SoC support within the rk3128 driver
- Amlogic gxbb CEC32 and sd_emmc clks
- Amlogic meson8b reset controller support
- IDT VersaClock 5P49V5925/5P49V6901 support
- Qualcomm MSM8996 SMMU clks
- Various 'const' applications for struct clk_ops
- si5351 PLL reset bugfix
- Uniphier audio on LD11/LD20 and ethernet support on LD11/LD20/Pro4/PXs2
- Assorted Tegra clk driver fixes"
* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (120 commits)
clk: si5351: fix PLL reset
ASoC: atmel-classd: remove aclk clock
ASoC: atmel-classd: remove aclk clock from DT binding
clk: at91: clk-generated: make gclk determine audio_pll rate
clk: at91: clk-generated: create function to find best_diff
clk: at91: add audio pll clock drivers
dt-bindings: clk: at91: add audio plls to the compatible list
clk: at91: clk-generated: remove useless divisor loop
clk: mb86s7x: Drop non-building driver
clk: ti: check for null return in strrchr to avoid null dereferencing
clk: Don't write error code into divider register
clk: uniphier: add video input subsystem clock
clk: uniphier: add audio system clock
clk: stm32h7: Add stm32h743 clock driver
clk: gate: expose clk_gate_ops::is_enabled
clk: nxp: clk-lpc32xx: rename clk_gate_is_enabled()
clk: uniphier: add PXs3 clock data
clk: hi6220: change watchdog clock source
clk: Kconfig: Name RK805 in Kconfig for COMMON_CLK_RK808
clk: cs2000: Add cs2000_set_saved_rate
...
142 files changed, 9354 insertions, 1101 deletions
diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt index faa6d8ac5834..786dc39ca904 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt | |||
@@ -5,9 +5,11 @@ controllers within the Always-On part of the SoC. | |||
5 | 5 | ||
6 | Required Properties: | 6 | Required Properties: |
7 | 7 | ||
8 | - compatible: should be "amlogic,gxbb-aoclkc" | 8 | - compatible: value should be different for each SoC family as : |
9 | - reg: physical base address of the clock controller and length of memory | 9 | - GXBB (S905) : "amlogic,meson-gxbb-aoclkc" |
10 | mapped region. | 10 | - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" |
11 | - GXM (S912) : "amlogic,meson-gxm-aoclkc" | ||
12 | followed by the common "amlogic,meson-gx-aoclkc" | ||
11 | 13 | ||
12 | - #clock-cells: should be 1. | 14 | - #clock-cells: should be 1. |
13 | 15 | ||
@@ -23,14 +25,22 @@ to specify the reset which they consume. All available resets are defined as | |||
23 | preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be | 25 | preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be |
24 | used in device tree sources. | 26 | used in device tree sources. |
25 | 27 | ||
28 | Parent node should have the following properties : | ||
29 | - compatible: "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd" | ||
30 | - reg: base address and size of the AO system control register space. | ||
31 | |||
26 | Example: AO Clock controller node: | 32 | Example: AO Clock controller node: |
27 | 33 | ||
28 | clkc_AO: clock-controller@040 { | 34 | ao_sysctrl: sys-ctrl@0 { |
29 | compatible = "amlogic,gxbb-aoclkc"; | 35 | compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; |
30 | reg = <0x0 0x040 0x0 0x4>; | 36 | reg = <0x0 0x0 0x0 0x100>; |
37 | |||
38 | clkc_AO: clock-controller { | ||
39 | compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc"; | ||
31 | #clock-cells = <1>; | 40 | #clock-cells = <1>; |
32 | #reset-cells = <1>; | 41 | #reset-cells = <1>; |
33 | }; | 42 | }; |
43 | }; | ||
34 | 44 | ||
35 | Example: UART controller node that consumes the clock and reset generated | 45 | Example: UART controller node that consumes the clock and reset generated |
36 | by the clock controller: | 46 | by the clock controller: |
diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index 5f3ad65daf69..51c259a92d02 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt | |||
@@ -81,6 +81,16 @@ Required properties: | |||
81 | "atmel,sama5d2-clk-generated": | 81 | "atmel,sama5d2-clk-generated": |
82 | at91 generated clock | 82 | at91 generated clock |
83 | 83 | ||
84 | "atmel,sama5d2-clk-audio-pll-frac": | ||
85 | at91 audio fractional pll | ||
86 | |||
87 | "atmel,sama5d2-clk-audio-pll-pad": | ||
88 | at91 audio pll CLK_AUDIO output pin | ||
89 | |||
90 | "atmel,sama5d2-clk-audio-pll-pmc" | ||
91 | at91 audio pll output on AUDIOPLLCLK that feeds the PMC | ||
92 | and can be used by peripheral clock or generic clock | ||
93 | |||
84 | Required properties for SCKC node: | 94 | Required properties for SCKC node: |
85 | - reg : defines the IO memory reserved for the SCKC. | 95 | - reg : defines the IO memory reserved for the SCKC. |
86 | - #size-cells : shall be 0 (reg is used to encode clk id). | 96 | - #size-cells : shall be 0 (reg is used to encode clk id). |
diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt index 53d7e50ed875..05a245c9df08 100644 --- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt +++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt | |||
@@ -1,24 +1,32 @@ | |||
1 | Binding for IDT VersaClock5 programmable i2c clock generator. | 1 | Binding for IDT VersaClock 5,6 programmable i2c clock generators. |
2 | 2 | ||
3 | The IDT VersaClock5 are programmable i2c clock generators providing | 3 | The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock |
4 | from 3 to 12 output clocks. | 4 | generators providing from 3 to 12 output clocks. |
5 | 5 | ||
6 | ==I2C device node== | 6 | ==I2C device node== |
7 | 7 | ||
8 | Required properties: | 8 | Required properties: |
9 | - compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933" , | 9 | - compatible: shall be one of |
10 | "idt,5p49v5935". | 10 | "idt,5p49v5923" |
11 | "idt,5p49v5925" | ||
12 | "idt,5p49v5933" | ||
13 | "idt,5p49v5935" | ||
14 | "idt,5p49v6901" | ||
11 | - reg: i2c device address, shall be 0x68 or 0x6a. | 15 | - reg: i2c device address, shall be 0x68 or 0x6a. |
12 | - #clock-cells: from common clock binding; shall be set to 1. | 16 | - #clock-cells: from common clock binding; shall be set to 1. |
13 | - clocks: from common clock binding; list of parent clock handles, | 17 | - clocks: from common clock binding; list of parent clock handles, |
14 | - 5p49v5923: (required) either or both of XTAL or CLKIN | 18 | - 5p49v5923 and |
19 | 5p49v5925 and | ||
20 | 5p49v6901: (required) either or both of XTAL or CLKIN | ||
15 | reference clock. | 21 | reference clock. |
16 | - 5p49v5933 and | 22 | - 5p49v5933 and |
17 | - 5p49v5935: (optional) property not present (internal | 23 | - 5p49v5935: (optional) property not present (internal |
18 | Xtal used) or CLKIN reference | 24 | Xtal used) or CLKIN reference |
19 | clock. | 25 | clock. |
20 | - clock-names: from common clock binding; clock input names, can be | 26 | - clock-names: from common clock binding; clock input names, can be |
21 | - 5p49v5923: (required) either or both of "xin", "clkin". | 27 | - 5p49v5923 and |
28 | 5p49v5925 and | ||
29 | 5p49v6901: (required) either or both of "xin", "clkin". | ||
22 | - 5p49v5933 and | 30 | - 5p49v5933 and |
23 | - 5p49v5935: (optional) property not present or "clkin". | 31 | - 5p49v5935: (optional) property not present or "clkin". |
24 | 32 | ||
@@ -37,6 +45,7 @@ clock specifier, the following mapping applies: | |||
37 | 1 -- OUT1 | 45 | 1 -- OUT1 |
38 | 2 -- OUT4 | 46 | 2 -- OUT4 |
39 | 47 | ||
48 | 5P49V5925 and | ||
40 | 5P49V5935: | 49 | 5P49V5935: |
41 | 0 -- OUT0_SEL_I2CB | 50 | 0 -- OUT0_SEL_I2CB |
42 | 1 -- OUT1 | 51 | 1 -- OUT1 |
@@ -44,6 +53,13 @@ clock specifier, the following mapping applies: | |||
44 | 3 -- OUT3 | 53 | 3 -- OUT3 |
45 | 4 -- OUT4 | 54 | 4 -- OUT4 |
46 | 55 | ||
56 | 5P49V6901: | ||
57 | 0 -- OUT0_SEL_I2CB | ||
58 | 1 -- OUT1 | ||
59 | 2 -- OUT2 | ||
60 | 3 -- OUT3 | ||
61 | 4 -- OUT4 | ||
62 | |||
47 | ==Example== | 63 | ==Example== |
48 | 64 | ||
49 | /* 25MHz reference crystal */ | 65 | /* 25MHz reference crystal */ |
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 707a686d8d3e..316e13686568 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt | |||
@@ -22,6 +22,7 @@ Required Properties: | |||
22 | - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) | 22 | - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) |
23 | - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) | 23 | - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) |
24 | - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) | 24 | - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) |
25 | - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) | ||
25 | 26 | ||
26 | - reg: Base address and length of the memory resource used by the CPG/MSSR | 27 | - reg: Base address and length of the memory resource used by the CPG/MSSR |
27 | block | 28 | block |
@@ -30,7 +31,7 @@ Required Properties: | |||
30 | clock-names | 31 | clock-names |
31 | - clock-names: List of external parent clock names. Valid names are: | 32 | - clock-names: List of external parent clock names. Valid names are: |
32 | - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, | 33 | - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, |
33 | r8a7795, r8a7796) | 34 | r8a7795, r8a7796, r8a77995) |
34 | - "extalr" (r8a7795, r8a7796) | 35 | - "extalr" (r8a7795, r8a7796) |
35 | - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) | 36 | - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) |
36 | 37 | ||
diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt new file mode 100644 index 000000000000..e96e085271c1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt | |||
@@ -0,0 +1,55 @@ | |||
1 | * Renesas R-Car USB 2.0 clock selector | ||
2 | |||
3 | This file provides information on what the device node for the R-Car USB 2.0 | ||
4 | clock selector. | ||
5 | |||
6 | If you connect an external clock to the USB_EXTAL pin only, you should set | ||
7 | the clock rate to "usb_extal" node only. | ||
8 | If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module | ||
9 | is not needed because this is default setting. (Of course, you can set the | ||
10 | clock rates to both "usb_extal" and "usb_xtal" nodes. | ||
11 | |||
12 | Case 1: An external clock connects to R-Car SoC | ||
13 | +----------+ +--- R-Car ---------------------+ | ||
14 | |External |---|USB_EXTAL ---> all usb channels| | ||
15 | |clock | |USB_XTAL | | ||
16 | +----------+ +-------------------------------+ | ||
17 | In this case, we need this driver with "usb_extal" clock. | ||
18 | |||
19 | Case 2: An oscillator connects to R-Car SoC | ||
20 | +----------+ +--- R-Car ---------------------+ | ||
21 | |Oscillator|---|USB_EXTAL -+-> all usb channels| | ||
22 | | |---|USB_XTAL --+ | | ||
23 | +----------+ +-------------------------------+ | ||
24 | In this case, we don't need this selector. | ||
25 | |||
26 | Required properties: | ||
27 | - compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of | ||
28 | an R8A7795 SoC. | ||
29 | "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of | ||
30 | an R8A7796 SoC. | ||
31 | "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3 | ||
32 | compatible device. | ||
33 | |||
34 | When compatible with the generic version, nodes must list the | ||
35 | SoC-specific version corresponding to the platform first | ||
36 | followed by the generic version. | ||
37 | |||
38 | - reg: offset and length of the USB 2.0 clock selector register block. | ||
39 | - clocks: A list of phandles and specifier pairs. | ||
40 | - clock-names: Name of the clocks. | ||
41 | - The functional clock must be "ehci_ohci" | ||
42 | - The USB_EXTAL clock pin must be "usb_extal" | ||
43 | - The USB_XTAL clock pin must be "usb_xtal" | ||
44 | - #clock-cells: Must be 0 | ||
45 | |||
46 | Example (R-Car H3): | ||
47 | |||
48 | usb2_clksel: clock-controller@e6590630 { | ||
49 | compatible = "renesas,r8a77950-rcar-usb2-clock-sel", | ||
50 | "renesas,rcar-gen3-usb2-clock-sel"; | ||
51 | reg = <0 0xe6590630 0 0x02>; | ||
52 | clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; | ||
53 | clock-names = "ehci_ohci", "usb_extal", "usb_xtal"; | ||
54 | #clock-cells = <0>; | ||
55 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt index 455a9a00a623..6f8744fd301b 100644 --- a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt | |||
@@ -1,12 +1,14 @@ | |||
1 | * Rockchip RK3128 Clock and Reset Unit | 1 | * Rockchip RK3126/RK3128 Clock and Reset Unit |
2 | 2 | ||
3 | The RK3128 clock controller generates and supplies clock to various | 3 | The RK3126/RK3128 clock controller generates and supplies clock to various |
4 | controllers within the SoC and also implements a reset controller for SoC | 4 | controllers within the SoC and also implements a reset controller for SoC |
5 | peripherals. | 5 | peripherals. |
6 | 6 | ||
7 | Required Properties: | 7 | Required Properties: |
8 | 8 | ||
9 | - compatible: should be "rockchip,rk3128-cru" | 9 | - compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru" |
10 | "rockchip,rk3126-cru" - controller compatible with RK3126 SoC. | ||
11 | "rockchip,rk3128-cru" - controller compatible with RK3128 SoC. | ||
10 | - reg: physical base address of the controller and length of memory mapped | 12 | - reg: physical base address of the controller and length of memory mapped |
11 | region. | 13 | region. |
12 | - #clock-cells: should be 1. | 14 | - #clock-cells: should be 1. |
diff --git a/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt new file mode 100644 index 000000000000..c56c7553c730 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | Binding for the HSDK Generic PLL clock | ||
2 | |||
3 | This binding uses the common clock binding[1]. | ||
4 | |||
5 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: should be "snps,hsdk-<name>-pll-clock" | ||
9 | "snps,hsdk-core-pll-clock" | ||
10 | "snps,hsdk-gp-pll-clock" | ||
11 | "snps,hsdk-hdmi-pll-clock" | ||
12 | - reg : should contain base register location and length. | ||
13 | - clocks: shall be the input parent clock phandle for the PLL. | ||
14 | - #clock-cells: from common clock binding; Should always be set to 0. | ||
15 | |||
16 | Example: | ||
17 | input_clk: input-clk { | ||
18 | clock-frequency = <33333333>; | ||
19 | compatible = "fixed-clock"; | ||
20 | #clock-cells = <0>; | ||
21 | }; | ||
22 | |||
23 | cpu_clk: cpu-clk@0 { | ||
24 | compatible = "snps,hsdk-core-pll-clock"; | ||
25 | reg = <0x00 0x10>; | ||
26 | #clock-cells = <0>; | ||
27 | clocks = <&input_clk>; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt new file mode 100644 index 000000000000..11fe4876612c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | Binding for the AXS10X Generic PLL clock | ||
2 | |||
3 | This binding uses the common clock binding[1]. | ||
4 | |||
5 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: should be "snps,axs10x-<name>-pll-clock" | ||
9 | "snps,axs10x-arc-pll-clock" | ||
10 | "snps,axs10x-pgu-pll-clock" | ||
11 | - reg: should always contain 2 pairs address - length: first for PLL config | ||
12 | registers and second for corresponding LOCK CGU register. | ||
13 | - clocks: shall be the input parent clock phandle for the PLL. | ||
14 | - #clock-cells: from common clock binding; Should always be set to 0. | ||
15 | |||
16 | Example: | ||
17 | input-clk: input-clk { | ||
18 | clock-frequency = <33333333>; | ||
19 | compatible = "fixed-clock"; | ||
20 | #clock-cells = <0>; | ||
21 | }; | ||
22 | |||
23 | core-clk: core-clk@80 { | ||
24 | compatible = "snps,axs10x-arc-pll-clock"; | ||
25 | reg = <0x80 0x10>, <0x100 0x10>; | ||
26 | #clock-cells = <0>; | ||
27 | clocks = <&input-clk>; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt new file mode 100644 index 000000000000..a135504c7d57 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt | |||
@@ -0,0 +1,71 @@ | |||
1 | STMicroelectronics STM32H7 Reset and Clock Controller | ||
2 | ===================================================== | ||
3 | |||
4 | The RCC IP is both a reset and a clock controller. | ||
5 | |||
6 | Please refer to clock-bindings.txt for common clock controller binding usage. | ||
7 | Please also refer to reset.txt for common reset controller binding usage. | ||
8 | |||
9 | Required properties: | ||
10 | - compatible: Should be: | ||
11 | "st,stm32h743-rcc" | ||
12 | |||
13 | - reg: should be register base and length as documented in the | ||
14 | datasheet | ||
15 | |||
16 | - #reset-cells: 1, see below | ||
17 | |||
18 | - #clock-cells : from common clock binding; shall be set to 1 | ||
19 | |||
20 | - clocks: External oscillator clock phandle | ||
21 | - high speed external clock signal (HSE) | ||
22 | - low speed external clock signal (LSE) | ||
23 | - external I2S clock (I2S_CKIN) | ||
24 | |||
25 | Optional properties: | ||
26 | - st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain | ||
27 | write protection (RTC clock). | ||
28 | |||
29 | Example: | ||
30 | |||
31 | rcc: reset-clock-controller@58024400 { | ||
32 | compatible = "st,stm32h743-rcc", "st,stm32-rcc"; | ||
33 | reg = <0x58024400 0x400>; | ||
34 | #reset-cells = <1>; | ||
35 | #clock-cells = <2>; | ||
36 | clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>; | ||
37 | |||
38 | st,syscfg = <&pwrcfg>; | ||
39 | }; | ||
40 | |||
41 | The peripheral clock consumer should specify the desired clock by | ||
42 | having the clock ID in its "clocks" phandle cell. | ||
43 | |||
44 | Example: | ||
45 | |||
46 | timer5: timer@40000c00 { | ||
47 | compatible = "st,stm32-timer"; | ||
48 | reg = <0x40000c00 0x400>; | ||
49 | interrupts = <50>; | ||
50 | clocks = <&rcc TIM5_CK>; | ||
51 | }; | ||
52 | |||
53 | Specifying softreset control of devices | ||
54 | ======================================= | ||
55 | |||
56 | Device nodes should specify the reset channel required in their "resets" | ||
57 | property, containing a phandle to the reset device node and an index specifying | ||
58 | which channel to use. | ||
59 | The index is the bit number within the RCC registers bank, starting from RCC | ||
60 | base address. | ||
61 | It is calculated as: index = register_offset / 4 * 32 + bit_offset. | ||
62 | Where bit_offset is the bit offset within the register. | ||
63 | |||
64 | For example, for CRC reset: | ||
65 | crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107 | ||
66 | |||
67 | Example: | ||
68 | |||
69 | timer2 { | ||
70 | resets = <&rcc STM32H7_APB1L_RESET(TIM2)>; | ||
71 | }; | ||
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index df9fad58facd..7eda08eb8a1e 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt | |||
@@ -3,18 +3,24 @@ Allwinner Clock Control Unit Binding | |||
3 | 3 | ||
4 | Required properties : | 4 | Required properties : |
5 | - compatible: must contain one of the following compatibles: | 5 | - compatible: must contain one of the following compatibles: |
6 | - "allwinner,sun4i-a10-ccu" | ||
7 | - "allwinner,sun5i-a10s-ccu" | ||
8 | - "allwinner,sun5i-a13-ccu" | ||
6 | - "allwinner,sun6i-a31-ccu" | 9 | - "allwinner,sun6i-a31-ccu" |
10 | - "allwinner,sun7i-a20-ccu" | ||
7 | - "allwinner,sun8i-a23-ccu" | 11 | - "allwinner,sun8i-a23-ccu" |
8 | - "allwinner,sun8i-a33-ccu" | 12 | - "allwinner,sun8i-a33-ccu" |
9 | - "allwinner,sun8i-a83t-ccu" | 13 | - "allwinner,sun8i-a83t-ccu" |
10 | - "allwinner,sun8i-a83t-r-ccu" | 14 | - "allwinner,sun8i-a83t-r-ccu" |
11 | - "allwinner,sun8i-h3-ccu" | 15 | - "allwinner,sun8i-h3-ccu" |
12 | - "allwinner,sun8i-h3-r-ccu" | 16 | - "allwinner,sun8i-h3-r-ccu" |
17 | + - "allwinner,sun8i-r40-ccu" | ||
13 | - "allwinner,sun8i-v3s-ccu" | 18 | - "allwinner,sun8i-v3s-ccu" |
14 | - "allwinner,sun9i-a80-ccu" | 19 | - "allwinner,sun9i-a80-ccu" |
15 | - "allwinner,sun50i-a64-ccu" | 20 | - "allwinner,sun50i-a64-ccu" |
16 | - "allwinner,sun50i-a64-r-ccu" | 21 | - "allwinner,sun50i-a64-r-ccu" |
17 | - "allwinner,sun50i-h5-ccu" | 22 | - "allwinner,sun50i-h5-ccu" |
23 | - "nextthing,gr8-ccu" | ||
18 | 24 | ||
19 | - reg: Must contain the registers base address and length | 25 | - reg: Must contain the registers base address and length |
20 | - clocks: phandle to the oscillators feeding the CCU. Two are needed: | 26 | - clocks: phandle to the oscillators feeding the CCU. Two are needed: |
diff --git a/Documentation/devicetree/bindings/clock/uniphier-clock.txt b/Documentation/devicetree/bindings/clock/uniphier-clock.txt index 812163060fa3..7b5f602765fe 100644 --- a/Documentation/devicetree/bindings/clock/uniphier-clock.txt +++ b/Documentation/devicetree/bindings/clock/uniphier-clock.txt | |||
@@ -6,7 +6,6 @@ System clock | |||
6 | 6 | ||
7 | Required properties: | 7 | Required properties: |
8 | - compatible: should be one of the following: | 8 | - compatible: should be one of the following: |
9 | "socionext,uniphier-sld3-clock" - for sLD3 SoC. | ||
10 | "socionext,uniphier-ld4-clock" - for LD4 SoC. | 9 | "socionext,uniphier-ld4-clock" - for LD4 SoC. |
11 | "socionext,uniphier-pro4-clock" - for Pro4 SoC. | 10 | "socionext,uniphier-pro4-clock" - for Pro4 SoC. |
12 | "socionext,uniphier-sld8-clock" - for sLD8 SoC. | 11 | "socionext,uniphier-sld8-clock" - for sLD8 SoC. |
@@ -14,6 +13,7 @@ Required properties: | |||
14 | "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC. | 13 | "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC. |
15 | "socionext,uniphier-ld11-clock" - for LD11 SoC. | 14 | "socionext,uniphier-ld11-clock" - for LD11 SoC. |
16 | "socionext,uniphier-ld20-clock" - for LD20 SoC. | 15 | "socionext,uniphier-ld20-clock" - for LD20 SoC. |
16 | "socionext,uniphier-pxs3-clock" - for PXs3 SoC | ||
17 | - #clock-cells: should be 1. | 17 | - #clock-cells: should be 1. |
18 | 18 | ||
19 | Example: | 19 | Example: |
@@ -48,7 +48,6 @@ Media I/O (MIO) clock, SD clock | |||
48 | 48 | ||
49 | Required properties: | 49 | Required properties: |
50 | - compatible: should be one of the following: | 50 | - compatible: should be one of the following: |
51 | "socionext,uniphier-sld3-mio-clock" - for sLD3 SoC. | ||
52 | "socionext,uniphier-ld4-mio-clock" - for LD4 SoC. | 51 | "socionext,uniphier-ld4-mio-clock" - for LD4 SoC. |
53 | "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC. | 52 | "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC. |
54 | "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC. | 53 | "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC. |
@@ -56,6 +55,7 @@ Required properties: | |||
56 | "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC. | 55 | "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC. |
57 | "socionext,uniphier-ld11-mio-clock" - for LD11 SoC. | 56 | "socionext,uniphier-ld11-mio-clock" - for LD11 SoC. |
58 | "socionext,uniphier-ld20-sd-clock" - for LD20 SoC. | 57 | "socionext,uniphier-ld20-sd-clock" - for LD20 SoC. |
58 | "socionext,uniphier-pxs3-sd-clock" - for PXs3 SoC | ||
59 | - #clock-cells: should be 1. | 59 | - #clock-cells: should be 1. |
60 | 60 | ||
61 | Example: | 61 | Example: |
@@ -82,11 +82,9 @@ Provided clocks: | |||
82 | 8: USB2 ch0 host | 82 | 8: USB2 ch0 host |
83 | 9: USB2 ch1 host | 83 | 9: USB2 ch1 host |
84 | 10: USB2 ch2 host | 84 | 10: USB2 ch2 host |
85 | 11: USB2 ch3 host | ||
86 | 12: USB2 ch0 PHY | 85 | 12: USB2 ch0 PHY |
87 | 13: USB2 ch1 PHY | 86 | 13: USB2 ch1 PHY |
88 | 14: USB2 ch2 PHY | 87 | 14: USB2 ch2 PHY |
89 | 15: USB2 ch3 PHY | ||
90 | 88 | ||
91 | 89 | ||
92 | Peripheral clock | 90 | Peripheral clock |
@@ -94,7 +92,6 @@ Peripheral clock | |||
94 | 92 | ||
95 | Required properties: | 93 | Required properties: |
96 | - compatible: should be one of the following: | 94 | - compatible: should be one of the following: |
97 | "socionext,uniphier-sld3-peri-clock" - for sLD3 SoC. | ||
98 | "socionext,uniphier-ld4-peri-clock" - for LD4 SoC. | 95 | "socionext,uniphier-ld4-peri-clock" - for LD4 SoC. |
99 | "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC. | 96 | "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC. |
100 | "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC. | 97 | "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC. |
@@ -102,6 +99,7 @@ Required properties: | |||
102 | "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC. | 99 | "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC. |
103 | "socionext,uniphier-ld11-peri-clock" - for LD11 SoC. | 100 | "socionext,uniphier-ld11-peri-clock" - for LD11 SoC. |
104 | "socionext,uniphier-ld20-peri-clock" - for LD20 SoC. | 101 | "socionext,uniphier-ld20-peri-clock" - for LD20 SoC. |
102 | "socionext,uniphier-pxs3-peri-clock" - for PXs3 SoC | ||
105 | - #clock-cells: should be 1. | 103 | - #clock-cells: should be 1. |
106 | 104 | ||
107 | Example: | 105 | Example: |
diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt index 549e701cb7a1..898551076382 100644 --- a/Documentation/devicetree/bindings/sound/atmel-classd.txt +++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt | |||
@@ -13,13 +13,11 @@ Required properties: | |||
13 | Must be "tx". | 13 | Must be "tx". |
14 | - clock-names | 14 | - clock-names |
15 | Tuple listing input clock names. | 15 | Tuple listing input clock names. |
16 | Required elements: "pclk", "gclk" and "aclk". | 16 | Required elements: "pclk" and "gclk". |
17 | - clocks | 17 | - clocks |
18 | Please refer to clock-bindings.txt. | 18 | Please refer to clock-bindings.txt. |
19 | - assigned-clocks | 19 | - assigned-clocks |
20 | Should be <&classd_gclk>. | 20 | Should be <&classd_gclk>. |
21 | - assigned-clock-parents | ||
22 | Should be <&audio_pll_pmc>. | ||
23 | 21 | ||
24 | Optional properties: | 22 | Optional properties: |
25 | - pinctrl-names, pinctrl-0 | 23 | - pinctrl-names, pinctrl-0 |
@@ -45,10 +43,9 @@ classd: classd@fc048000 { | |||
45 | (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | 43 | (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
46 | | AT91_XDMAC_DT_PERID(47))>; | 44 | | AT91_XDMAC_DT_PERID(47))>; |
47 | dma-names = "tx"; | 45 | dma-names = "tx"; |
48 | clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; | 46 | clocks = <&classd_clk>, <&classd_gclk>; |
49 | clock-names = "pclk", "gclk", "aclk"; | 47 | clock-names = "pclk", "gclk"; |
50 | assigned-clocks = <&classd_gclk>; | 48 | assigned-clocks = <&classd_gclk>; |
51 | assigned-clock-parents = <&audio_pll_pmc>; | ||
52 | 49 | ||
53 | pinctrl-names = "default"; | 50 | pinctrl-names = "default"; |
54 | pinctrl-0 = <&pinctrl_classd_default>; | 51 | pinctrl-0 = <&pinctrl_classd_default>; |
diff --git a/MAINTAINERS b/MAINTAINERS index 048586a2a9be..7be4129ec951 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -12842,6 +12842,18 @@ F: drivers/clocksource/arc_timer.c | |||
12842 | F: drivers/tty/serial/arc_uart.c | 12842 | F: drivers/tty/serial/arc_uart.c |
12843 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git | 12843 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git |
12844 | 12844 | ||
12845 | SYNOPSYS ARC HSDK SDP pll clock driver | ||
12846 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> | ||
12847 | S: Supported | ||
12848 | F: drivers/clk/clk-hsdk-pll.c | ||
12849 | F: Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt | ||
12850 | |||
12851 | SYNOPSYS ARC SDP clock driver | ||
12852 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> | ||
12853 | S: Supported | ||
12854 | F: drivers/clk/axs10x/* | ||
12855 | F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt | ||
12856 | |||
12845 | SYNOPSYS ARC SDP platform support | 12857 | SYNOPSYS ARC SDP platform support |
12846 | M: Alexey Brodkin <abrodkin@synopsys.com> | 12858 | M: Alexey Brodkin <abrodkin@synopsys.com> |
12847 | S: Supported | 12859 | S: Supported |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 195da38cb9a2..6d870421a7a6 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -26,6 +26,7 @@ config SOC_SAMA5D2 | |||
26 | select HAVE_AT91_USB_CLK | 26 | select HAVE_AT91_USB_CLK |
27 | select HAVE_AT91_H32MX | 27 | select HAVE_AT91_H32MX |
28 | select HAVE_AT91_GENERATED_CLK | 28 | select HAVE_AT91_GENERATED_CLK |
29 | select HAVE_AT91_AUDIO_PLL | ||
29 | select PINCTRL_AT91PIO4 | 30 | select PINCTRL_AT91PIO4 |
30 | help | 31 | help |
31 | Select this if ou are using one of Atmel's SAMA5D2 family SoC. | 32 | Select this if ou are using one of Atmel's SAMA5D2 family SoC. |
@@ -125,6 +126,9 @@ config HAVE_AT91_H32MX | |||
125 | config HAVE_AT91_GENERATED_CLK | 126 | config HAVE_AT91_GENERATED_CLK |
126 | bool | 127 | bool |
127 | 128 | ||
129 | config HAVE_AT91_AUDIO_PLL | ||
130 | bool | ||
131 | |||
128 | config SOC_SAM_V4_V5 | 132 | config SOC_SAM_V4_V5 |
129 | bool | 133 | bool |
130 | 134 | ||
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 68ca2d9fcd73..1c4e1aa6767e 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -31,6 +31,13 @@ config COMMON_CLK_WM831X | |||
31 | 31 | ||
32 | source "drivers/clk/versatile/Kconfig" | 32 | source "drivers/clk/versatile/Kconfig" |
33 | 33 | ||
34 | config CLK_HSDK | ||
35 | bool "PLL Driver for HSDK platform" | ||
36 | depends on OF || COMPILE_TEST | ||
37 | ---help--- | ||
38 | This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs | ||
39 | control. | ||
40 | |||
34 | config COMMON_CLK_MAX77686 | 41 | config COMMON_CLK_MAX77686 |
35 | tristate "Clock driver for Maxim 77620/77686/77802 MFD" | 42 | tristate "Clock driver for Maxim 77620/77686/77802 MFD" |
36 | depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST | 43 | depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST |
@@ -39,10 +46,10 @@ config COMMON_CLK_MAX77686 | |||
39 | clock. | 46 | clock. |
40 | 47 | ||
41 | config COMMON_CLK_RK808 | 48 | config COMMON_CLK_RK808 |
42 | tristate "Clock driver for RK808/RK818" | 49 | tristate "Clock driver for RK805/RK808/RK818" |
43 | depends on MFD_RK808 | 50 | depends on MFD_RK808 |
44 | ---help--- | 51 | ---help--- |
45 | This driver supports RK808 and RK818 crystal oscillator clock. These | 52 | This driver supports RK805, RK808 and RK818 crystal oscillator clock. These |
46 | multi-function devices have two fixed-rate oscillators, | 53 | multi-function devices have two fixed-rate oscillators, |
47 | clocked at 32KHz each. Clkout1 is always on, Clkout2 can off | 54 | clocked at 32KHz each. Clkout1 is always on, Clkout2 can off |
48 | by control register. | 55 | by control register. |
@@ -210,14 +217,14 @@ config COMMON_CLK_OXNAS | |||
210 | Support for the OXNAS SoC Family clocks. | 217 | Support for the OXNAS SoC Family clocks. |
211 | 218 | ||
212 | config COMMON_CLK_VC5 | 219 | config COMMON_CLK_VC5 |
213 | tristate "Clock driver for IDT VersaClock5 devices" | 220 | tristate "Clock driver for IDT VersaClock 5,6 devices" |
214 | depends on I2C | 221 | depends on I2C |
215 | depends on OF | 222 | depends on OF |
216 | select REGMAP_I2C | 223 | select REGMAP_I2C |
217 | help | 224 | help |
218 | ---help--- | 225 | ---help--- |
219 | This driver supports the IDT VersaClock5 programmable clock | 226 | This driver supports the IDT VersaClock 5 and VersaClock 6 |
220 | generator. | 227 | programmable clock generators. |
221 | 228 | ||
222 | source "drivers/clk/bcm/Kconfig" | 229 | source "drivers/clk/bcm/Kconfig" |
223 | source "drivers/clk/hisilicon/Kconfig" | 230 | source "drivers/clk/hisilicon/Kconfig" |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cd376b3fb47a..c99f363826f0 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -27,8 +27,8 @@ obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o | |||
27 | obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o | 27 | obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o |
28 | obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o | 28 | obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o |
29 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o | 29 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o |
30 | obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o | ||
30 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o | 31 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o |
31 | obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o | ||
32 | obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o | 32 | obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o |
33 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o | 33 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o |
34 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o | 34 | obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o |
@@ -44,6 +44,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o | |||
44 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o | 44 | obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o |
45 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o | 45 | obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o |
46 | obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o | 46 | obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o |
47 | obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o | ||
47 | obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o | 48 | obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o |
48 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o | 49 | obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o |
49 | obj-$(CONFIG_ARCH_U300) += clk-u300.o | 50 | obj-$(CONFIG_ARCH_U300) += clk-u300.o |
diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 13e67bd35cff..c68947b65a4c 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile | |||
@@ -6,6 +6,7 @@ obj-y += pmc.o sckc.o | |||
6 | obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o | 6 | obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o |
7 | obj-y += clk-system.o clk-peripheral.o clk-programmable.o | 7 | obj-y += clk-system.o clk-peripheral.o clk-programmable.o |
8 | 8 | ||
9 | obj-$(CONFIG_HAVE_AT91_AUDIO_PLL) += clk-audio-pll.o | ||
9 | obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o | 10 | obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o |
10 | obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o | 11 | obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o |
11 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o | 12 | obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o |
diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c new file mode 100644 index 000000000000..da7bafcfbe70 --- /dev/null +++ b/drivers/clk/at91/clk-audio-pll.c | |||
@@ -0,0 +1,536 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 Atmel Corporation, | ||
3 | * Songjun Wu <songjun.wu@atmel.com>, | ||
4 | * Nicolas Ferre <nicolas.ferre@atmel.com> | ||
5 | * Copyright (C) 2017 Free Electrons, | ||
6 | * Quentin Schulz <quentin.schulz@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 | * The Sama5d2 SoC has two audio PLLs (PMC and PAD) that shares the same parent | ||
14 | * (FRAC). FRAC can output between 620 and 700MHz and only multiply the rate of | ||
15 | * its own parent. PMC and PAD can then divide the FRAC rate to best match the | ||
16 | * asked rate. | ||
17 | * | ||
18 | * Traits of FRAC clock: | ||
19 | * enable - clk_enable writes nd, fracr parameters and enables PLL | ||
20 | * rate - rate is adjustable. | ||
21 | * clk->rate = parent->rate * ((nd + 1) + (fracr / 2^22)) | ||
22 | * parent - fixed parent. No clk_set_parent support | ||
23 | * | ||
24 | * Traits of PMC clock: | ||
25 | * enable - clk_enable writes qdpmc, and enables PMC output | ||
26 | * rate - rate is adjustable. | ||
27 | * clk->rate = parent->rate / (qdpmc + 1) | ||
28 | * parent - fixed parent. No clk_set_parent support | ||
29 | * | ||
30 | * Traits of PAD clock: | ||
31 | * enable - clk_enable writes divisors and enables PAD output | ||
32 | * rate - rate is adjustable. | ||
33 | * clk->rate = parent->rate / (qdaudio * div)) | ||
34 | * parent - fixed parent. No clk_set_parent support | ||
35 | * | ||
36 | */ | ||
37 | |||
38 | #include <linux/clk.h> | ||
39 | #include <linux/clk-provider.h> | ||
40 | #include <linux/clk/at91_pmc.h> | ||
41 | #include <linux/of.h> | ||
42 | #include <linux/mfd/syscon.h> | ||
43 | #include <linux/regmap.h> | ||
44 | #include <linux/slab.h> | ||
45 | |||
46 | #define AUDIO_PLL_DIV_FRAC BIT(22) | ||
47 | #define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \ | ||
48 | AT91_PMC_AUDIO_PLL_ND_OFFSET) | ||
49 | |||
50 | #define AUDIO_PLL_QDPAD(qd, div) ((AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(qd) & \ | ||
51 | AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK) | \ | ||
52 | (AT91_PMC_AUDIO_PLL_QDPAD_DIV(div) & \ | ||
53 | AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK)) | ||
54 | |||
55 | #define AUDIO_PLL_QDPMC_MAX (AT91_PMC_AUDIO_PLL_QDPMC_MASK >> \ | ||
56 | AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) | ||
57 | |||
58 | #define AUDIO_PLL_FOUT_MIN 620000000UL | ||
59 | #define AUDIO_PLL_FOUT_MAX 700000000UL | ||
60 | |||
61 | struct clk_audio_frac { | ||
62 | struct clk_hw hw; | ||
63 | struct regmap *regmap; | ||
64 | u32 fracr; | ||
65 | u8 nd; | ||
66 | }; | ||
67 | |||
68 | struct clk_audio_pad { | ||
69 | struct clk_hw hw; | ||
70 | struct regmap *regmap; | ||
71 | u8 qdaudio; | ||
72 | u8 div; | ||
73 | }; | ||
74 | |||
75 | struct clk_audio_pmc { | ||
76 | struct clk_hw hw; | ||
77 | struct regmap *regmap; | ||
78 | u8 qdpmc; | ||
79 | }; | ||
80 | |||
81 | #define to_clk_audio_frac(hw) container_of(hw, struct clk_audio_frac, hw) | ||
82 | #define to_clk_audio_pad(hw) container_of(hw, struct clk_audio_pad, hw) | ||
83 | #define to_clk_audio_pmc(hw) container_of(hw, struct clk_audio_pmc, hw) | ||
84 | |||
85 | static int clk_audio_pll_frac_enable(struct clk_hw *hw) | ||
86 | { | ||
87 | struct clk_audio_frac *frac = to_clk_audio_frac(hw); | ||
88 | |||
89 | regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, | ||
90 | AT91_PMC_AUDIO_PLL_RESETN, 0); | ||
91 | regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, | ||
92 | AT91_PMC_AUDIO_PLL_RESETN, | ||
93 | AT91_PMC_AUDIO_PLL_RESETN); | ||
94 | regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL1, | ||
95 | AT91_PMC_AUDIO_PLL_FRACR_MASK, frac->fracr); | ||
96 | |||
97 | /* | ||
98 | * reset and enable have to be done in 2 separated writes | ||
99 | * for AT91_PMC_AUDIO_PLL0 | ||
100 | */ | ||
101 | regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, | ||
102 | AT91_PMC_AUDIO_PLL_PLLEN | | ||
103 | AT91_PMC_AUDIO_PLL_ND_MASK, | ||
104 | AT91_PMC_AUDIO_PLL_PLLEN | | ||
105 | AT91_PMC_AUDIO_PLL_ND(frac->nd)); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int clk_audio_pll_pad_enable(struct clk_hw *hw) | ||
111 | { | ||
112 | struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); | ||
113 | |||
114 | regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL1, | ||
115 | AT91_PMC_AUDIO_PLL_QDPAD_MASK, | ||
116 | AUDIO_PLL_QDPAD(apad_ck->qdaudio, apad_ck->div)); | ||
117 | regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0, | ||
118 | AT91_PMC_AUDIO_PLL_PADEN, AT91_PMC_AUDIO_PLL_PADEN); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int clk_audio_pll_pmc_enable(struct clk_hw *hw) | ||
124 | { | ||
125 | struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); | ||
126 | |||
127 | regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0, | ||
128 | AT91_PMC_AUDIO_PLL_PMCEN | | ||
129 | AT91_PMC_AUDIO_PLL_QDPMC_MASK, | ||
130 | AT91_PMC_AUDIO_PLL_PMCEN | | ||
131 | AT91_PMC_AUDIO_PLL_QDPMC(apmc_ck->qdpmc)); | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static void clk_audio_pll_frac_disable(struct clk_hw *hw) | ||
136 | { | ||
137 | struct clk_audio_frac *frac = to_clk_audio_frac(hw); | ||
138 | |||
139 | regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, | ||
140 | AT91_PMC_AUDIO_PLL_PLLEN, 0); | ||
141 | /* do it in 2 separated writes */ | ||
142 | regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, | ||
143 | AT91_PMC_AUDIO_PLL_RESETN, 0); | ||
144 | } | ||
145 | |||
146 | static void clk_audio_pll_pad_disable(struct clk_hw *hw) | ||
147 | { | ||
148 | struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); | ||
149 | |||
150 | regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0, | ||
151 | AT91_PMC_AUDIO_PLL_PADEN, 0); | ||
152 | } | ||
153 | |||
154 | static void clk_audio_pll_pmc_disable(struct clk_hw *hw) | ||
155 | { | ||
156 | struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); | ||
157 | |||
158 | regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0, | ||
159 | AT91_PMC_AUDIO_PLL_PMCEN, 0); | ||
160 | } | ||
161 | |||
162 | static unsigned long clk_audio_pll_fout(unsigned long parent_rate, | ||
163 | unsigned long nd, unsigned long fracr) | ||
164 | { | ||
165 | unsigned long long fr = (unsigned long long)parent_rate * fracr; | ||
166 | |||
167 | pr_debug("A PLL: %s, fr = %llu\n", __func__, fr); | ||
168 | |||
169 | fr = DIV_ROUND_CLOSEST_ULL(fr, AUDIO_PLL_DIV_FRAC); | ||
170 | |||
171 | pr_debug("A PLL: %s, fr = %llu\n", __func__, fr); | ||
172 | |||
173 | return parent_rate * (nd + 1) + fr; | ||
174 | } | ||
175 | |||
176 | static unsigned long clk_audio_pll_frac_recalc_rate(struct clk_hw *hw, | ||
177 | unsigned long parent_rate) | ||
178 | { | ||
179 | struct clk_audio_frac *frac = to_clk_audio_frac(hw); | ||
180 | unsigned long fout; | ||
181 | |||
182 | fout = clk_audio_pll_fout(parent_rate, frac->nd, frac->fracr); | ||
183 | |||
184 | pr_debug("A PLL: %s, fout = %lu (nd = %u, fracr = %lu)\n", __func__, | ||
185 | fout, frac->nd, (unsigned long)frac->fracr); | ||
186 | |||
187 | return fout; | ||
188 | } | ||
189 | |||
190 | static unsigned long clk_audio_pll_pad_recalc_rate(struct clk_hw *hw, | ||
191 | unsigned long parent_rate) | ||
192 | { | ||
193 | struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); | ||
194 | unsigned long apad_rate = 0; | ||
195 | |||
196 | if (apad_ck->qdaudio && apad_ck->div) | ||
197 | apad_rate = parent_rate / (apad_ck->qdaudio * apad_ck->div); | ||
198 | |||
199 | pr_debug("A PLL/PAD: %s, apad_rate = %lu (div = %u, qdaudio = %u)\n", | ||
200 | __func__, apad_rate, apad_ck->div, apad_ck->qdaudio); | ||
201 | |||
202 | return apad_rate; | ||
203 | } | ||
204 | |||
205 | static unsigned long clk_audio_pll_pmc_recalc_rate(struct clk_hw *hw, | ||
206 | unsigned long parent_rate) | ||
207 | { | ||
208 | struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); | ||
209 | unsigned long apmc_rate = 0; | ||
210 | |||
211 | apmc_rate = parent_rate / (apmc_ck->qdpmc + 1); | ||
212 | |||
213 | pr_debug("A PLL/PMC: %s, apmc_rate = %lu (qdpmc = %u)\n", __func__, | ||
214 | apmc_rate, apmc_ck->qdpmc); | ||
215 | |||
216 | return apmc_rate; | ||
217 | } | ||
218 | |||
219 | static int clk_audio_pll_frac_compute_frac(unsigned long rate, | ||
220 | unsigned long parent_rate, | ||
221 | unsigned long *nd, | ||
222 | unsigned long *fracr) | ||
223 | { | ||
224 | unsigned long long tmp, rem; | ||
225 | |||
226 | if (!rate) | ||
227 | return -EINVAL; | ||
228 | |||
229 | tmp = rate; | ||
230 | rem = do_div(tmp, parent_rate); | ||
231 | if (!tmp || tmp >= AUDIO_PLL_ND_MAX) | ||
232 | return -EINVAL; | ||
233 | |||
234 | *nd = tmp - 1; | ||
235 | |||
236 | tmp = rem * AUDIO_PLL_DIV_FRAC; | ||
237 | tmp = DIV_ROUND_CLOSEST_ULL(tmp, parent_rate); | ||
238 | if (tmp > AT91_PMC_AUDIO_PLL_FRACR_MASK) | ||
239 | return -EINVAL; | ||
240 | |||
241 | /* we can cast here as we verified the bounds just above */ | ||
242 | *fracr = (unsigned long)tmp; | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int clk_audio_pll_frac_determine_rate(struct clk_hw *hw, | ||
248 | struct clk_rate_request *req) | ||
249 | { | ||
250 | unsigned long fracr, nd; | ||
251 | int ret; | ||
252 | |||
253 | pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__, | ||
254 | req->rate, req->best_parent_rate); | ||
255 | |||
256 | req->rate = clamp(req->rate, AUDIO_PLL_FOUT_MIN, AUDIO_PLL_FOUT_MAX); | ||
257 | |||
258 | req->min_rate = max(req->min_rate, AUDIO_PLL_FOUT_MIN); | ||
259 | req->max_rate = min(req->max_rate, AUDIO_PLL_FOUT_MAX); | ||
260 | |||
261 | ret = clk_audio_pll_frac_compute_frac(req->rate, req->best_parent_rate, | ||
262 | &nd, &fracr); | ||
263 | if (ret) | ||
264 | return ret; | ||
265 | |||
266 | req->rate = clk_audio_pll_fout(req->best_parent_rate, nd, fracr); | ||
267 | |||
268 | req->best_parent_hw = clk_hw_get_parent(hw); | ||
269 | |||
270 | pr_debug("A PLL: %s, best_rate = %lu (nd = %lu, fracr = %lu)\n", | ||
271 | __func__, req->rate, nd, fracr); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate, | ||
277 | unsigned long *parent_rate) | ||
278 | { | ||
279 | struct clk_hw *pclk = clk_hw_get_parent(hw); | ||
280 | long best_rate = -EINVAL; | ||
281 | unsigned long best_parent_rate; | ||
282 | unsigned long tmp_qd; | ||
283 | u32 div; | ||
284 | long tmp_rate; | ||
285 | int tmp_diff; | ||
286 | int best_diff = -1; | ||
287 | |||
288 | pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__, | ||
289 | rate, *parent_rate); | ||
290 | |||
291 | /* | ||
292 | * Rate divisor is actually made of two different divisors, multiplied | ||
293 | * between themselves before dividing the rate. | ||
294 | * tmp_qd goes from 1 to 31 and div is either 2 or 3. | ||
295 | * In order to avoid testing twice the rate divisor (e.g. divisor 12 can | ||
296 | * be found with (tmp_qd, div) = (2, 6) or (3, 4)), we remove any loop | ||
297 | * for a rate divisor when div is 2 and tmp_qd is a multiple of 3. | ||
298 | * We cannot inverse it (condition div is 3 and tmp_qd is even) or we | ||
299 | * would miss some rate divisor that aren't reachable with div being 2 | ||
300 | * (e.g. rate divisor 90 is made with div = 3 and tmp_qd = 30, thus | ||
301 | * tmp_qd is even so we skip it because we think div 2 could make this | ||
302 | * rate divisor which isn't possible since tmp_qd has to be <= 31). | ||
303 | */ | ||
304 | for (tmp_qd = 1; tmp_qd < AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX; tmp_qd++) | ||
305 | for (div = 2; div <= 3; div++) { | ||
306 | if (div == 2 && tmp_qd % 3 == 0) | ||
307 | continue; | ||
308 | |||
309 | best_parent_rate = clk_hw_round_rate(pclk, | ||
310 | rate * tmp_qd * div); | ||
311 | tmp_rate = best_parent_rate / (div * tmp_qd); | ||
312 | tmp_diff = abs(rate - tmp_rate); | ||
313 | |||
314 | if (best_diff < 0 || best_diff > tmp_diff) { | ||
315 | *parent_rate = best_parent_rate; | ||
316 | best_rate = tmp_rate; | ||
317 | best_diff = tmp_diff; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n", | ||
322 | __func__, best_rate, best_parent_rate); | ||
323 | |||
324 | return best_rate; | ||
325 | } | ||
326 | |||
327 | static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate, | ||
328 | unsigned long *parent_rate) | ||
329 | { | ||
330 | struct clk_hw *pclk = clk_hw_get_parent(hw); | ||
331 | long best_rate = -EINVAL; | ||
332 | unsigned long best_parent_rate = 0; | ||
333 | u32 tmp_qd = 0, div; | ||
334 | long tmp_rate; | ||
335 | int tmp_diff; | ||
336 | int best_diff = -1; | ||
337 | |||
338 | pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__, | ||
339 | rate, *parent_rate); | ||
340 | |||
341 | for (div = 1; div <= AUDIO_PLL_QDPMC_MAX; div++) { | ||
342 | best_parent_rate = clk_round_rate(pclk->clk, rate * div); | ||
343 | tmp_rate = best_parent_rate / div; | ||
344 | tmp_diff = abs(rate - tmp_rate); | ||
345 | |||
346 | if (best_diff < 0 || best_diff > tmp_diff) { | ||
347 | *parent_rate = best_parent_rate; | ||
348 | best_rate = tmp_rate; | ||
349 | best_diff = tmp_diff; | ||
350 | tmp_qd = div; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %d)\n", | ||
355 | __func__, best_rate, *parent_rate, tmp_qd - 1); | ||
356 | |||
357 | return best_rate; | ||
358 | } | ||
359 | |||
360 | static int clk_audio_pll_frac_set_rate(struct clk_hw *hw, unsigned long rate, | ||
361 | unsigned long parent_rate) | ||
362 | { | ||
363 | struct clk_audio_frac *frac = to_clk_audio_frac(hw); | ||
364 | unsigned long fracr, nd; | ||
365 | int ret; | ||
366 | |||
367 | pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__, rate, | ||
368 | parent_rate); | ||
369 | |||
370 | if (rate < AUDIO_PLL_FOUT_MIN || rate > AUDIO_PLL_FOUT_MAX) | ||
371 | return -EINVAL; | ||
372 | |||
373 | ret = clk_audio_pll_frac_compute_frac(rate, parent_rate, &nd, &fracr); | ||
374 | if (ret) | ||
375 | return ret; | ||
376 | |||
377 | frac->nd = nd; | ||
378 | frac->fracr = fracr; | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int clk_audio_pll_pad_set_rate(struct clk_hw *hw, unsigned long rate, | ||
384 | unsigned long parent_rate) | ||
385 | { | ||
386 | struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); | ||
387 | u8 tmp_div; | ||
388 | |||
389 | pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__, | ||
390 | rate, parent_rate); | ||
391 | |||
392 | if (!rate) | ||
393 | return -EINVAL; | ||
394 | |||
395 | tmp_div = parent_rate / rate; | ||
396 | if (tmp_div % 3 == 0) { | ||
397 | apad_ck->qdaudio = tmp_div / 3; | ||
398 | apad_ck->div = 3; | ||
399 | } else { | ||
400 | apad_ck->qdaudio = tmp_div / 2; | ||
401 | apad_ck->div = 2; | ||
402 | } | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int clk_audio_pll_pmc_set_rate(struct clk_hw *hw, unsigned long rate, | ||
408 | unsigned long parent_rate) | ||
409 | { | ||
410 | struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); | ||
411 | |||
412 | if (!rate) | ||
413 | return -EINVAL; | ||
414 | |||
415 | pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__, | ||
416 | rate, parent_rate); | ||
417 | |||
418 | apmc_ck->qdpmc = parent_rate / rate - 1; | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static const struct clk_ops audio_pll_frac_ops = { | ||
424 | .enable = clk_audio_pll_frac_enable, | ||
425 | .disable = clk_audio_pll_frac_disable, | ||
426 | .recalc_rate = clk_audio_pll_frac_recalc_rate, | ||
427 | .determine_rate = clk_audio_pll_frac_determine_rate, | ||
428 | .set_rate = clk_audio_pll_frac_set_rate, | ||
429 | }; | ||
430 | |||
431 | static const struct clk_ops audio_pll_pad_ops = { | ||
432 | .enable = clk_audio_pll_pad_enable, | ||
433 | .disable = clk_audio_pll_pad_disable, | ||
434 | .recalc_rate = clk_audio_pll_pad_recalc_rate, | ||
435 | .round_rate = clk_audio_pll_pad_round_rate, | ||
436 | .set_rate = clk_audio_pll_pad_set_rate, | ||
437 | }; | ||
438 | |||
439 | static const struct clk_ops audio_pll_pmc_ops = { | ||
440 | .enable = clk_audio_pll_pmc_enable, | ||
441 | .disable = clk_audio_pll_pmc_disable, | ||
442 | .recalc_rate = clk_audio_pll_pmc_recalc_rate, | ||
443 | .round_rate = clk_audio_pll_pmc_round_rate, | ||
444 | .set_rate = clk_audio_pll_pmc_set_rate, | ||
445 | }; | ||
446 | |||
447 | static int of_sama5d2_clk_audio_pll_setup(struct device_node *np, | ||
448 | struct clk_init_data *init, | ||
449 | struct clk_hw *hw, | ||
450 | struct regmap **clk_audio_regmap) | ||
451 | { | ||
452 | struct regmap *regmap; | ||
453 | const char *parent_names[1]; | ||
454 | int ret; | ||
455 | |||
456 | regmap = syscon_node_to_regmap(of_get_parent(np)); | ||
457 | if (IS_ERR(regmap)) | ||
458 | return PTR_ERR(regmap); | ||
459 | |||
460 | init->name = np->name; | ||
461 | of_clk_parent_fill(np, parent_names, 1); | ||
462 | init->parent_names = parent_names; | ||
463 | init->num_parents = 1; | ||
464 | |||
465 | hw->init = init; | ||
466 | *clk_audio_regmap = regmap; | ||
467 | |||
468 | ret = clk_hw_register(NULL, hw); | ||
469 | if (ret) | ||
470 | return ret; | ||
471 | |||
472 | return of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); | ||
473 | } | ||
474 | |||
475 | static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) | ||
476 | { | ||
477 | struct clk_audio_frac *frac_ck; | ||
478 | struct clk_init_data init = {}; | ||
479 | |||
480 | frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL); | ||
481 | if (!frac_ck) | ||
482 | return; | ||
483 | |||
484 | init.ops = &audio_pll_frac_ops; | ||
485 | init.flags = CLK_SET_RATE_GATE; | ||
486 | |||
487 | if (of_sama5d2_clk_audio_pll_setup(np, &init, &frac_ck->hw, | ||
488 | &frac_ck->regmap)) | ||
489 | kfree(frac_ck); | ||
490 | } | ||
491 | |||
492 | static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np) | ||
493 | { | ||
494 | struct clk_audio_pad *apad_ck; | ||
495 | struct clk_init_data init = {}; | ||
496 | |||
497 | apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL); | ||
498 | if (!apad_ck) | ||
499 | return; | ||
500 | |||
501 | init.ops = &audio_pll_pad_ops; | ||
502 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | | ||
503 | CLK_SET_RATE_PARENT; | ||
504 | |||
505 | if (of_sama5d2_clk_audio_pll_setup(np, &init, &apad_ck->hw, | ||
506 | &apad_ck->regmap)) | ||
507 | kfree(apad_ck); | ||
508 | } | ||
509 | |||
510 | static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np) | ||
511 | { | ||
512 | struct clk_audio_pad *apmc_ck; | ||
513 | struct clk_init_data init = {}; | ||
514 | |||
515 | apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL); | ||
516 | if (!apmc_ck) | ||
517 | return; | ||
518 | |||
519 | init.ops = &audio_pll_pmc_ops; | ||
520 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | | ||
521 | CLK_SET_RATE_PARENT; | ||
522 | |||
523 | if (of_sama5d2_clk_audio_pll_setup(np, &init, &apmc_ck->hw, | ||
524 | &apmc_ck->regmap)) | ||
525 | kfree(apmc_ck); | ||
526 | } | ||
527 | |||
528 | CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup, | ||
529 | "atmel,sama5d2-clk-audio-pll-frac", | ||
530 | of_sama5d2_clk_audio_pll_frac_setup); | ||
531 | CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup, | ||
532 | "atmel,sama5d2-clk-audio-pll-pad", | ||
533 | of_sama5d2_clk_audio_pll_pad_setup); | ||
534 | CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup, | ||
535 | "atmel,sama5d2-clk-audio-pll-pmc", | ||
536 | of_sama5d2_clk_audio_pll_pmc_setup); | ||
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index f0b7ae904ce2..33481368740e 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c | |||
@@ -26,6 +26,13 @@ | |||
26 | #define GENERATED_SOURCE_MAX 6 | 26 | #define GENERATED_SOURCE_MAX 6 |
27 | #define GENERATED_MAX_DIV 255 | 27 | #define GENERATED_MAX_DIV 255 |
28 | 28 | ||
29 | #define GCK_ID_SSC0 43 | ||
30 | #define GCK_ID_SSC1 44 | ||
31 | #define GCK_ID_I2S0 54 | ||
32 | #define GCK_ID_I2S1 55 | ||
33 | #define GCK_ID_CLASSD 59 | ||
34 | #define GCK_INDEX_DT_AUDIO_PLL 5 | ||
35 | |||
29 | struct clk_generated { | 36 | struct clk_generated { |
30 | struct clk_hw hw; | 37 | struct clk_hw hw; |
31 | struct regmap *regmap; | 38 | struct regmap *regmap; |
@@ -34,6 +41,7 @@ struct clk_generated { | |||
34 | u32 id; | 41 | u32 id; |
35 | u32 gckdiv; | 42 | u32 gckdiv; |
36 | u8 parent_id; | 43 | u8 parent_id; |
44 | bool audio_pll_allowed; | ||
37 | }; | 45 | }; |
38 | 46 | ||
39 | #define to_clk_generated(hw) \ | 47 | #define to_clk_generated(hw) \ |
@@ -99,21 +107,41 @@ clk_generated_recalc_rate(struct clk_hw *hw, | |||
99 | return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); | 107 | return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); |
100 | } | 108 | } |
101 | 109 | ||
110 | static void clk_generated_best_diff(struct clk_rate_request *req, | ||
111 | struct clk_hw *parent, | ||
112 | unsigned long parent_rate, u32 div, | ||
113 | int *best_diff, long *best_rate) | ||
114 | { | ||
115 | unsigned long tmp_rate; | ||
116 | int tmp_diff; | ||
117 | |||
118 | if (!div) | ||
119 | tmp_rate = parent_rate; | ||
120 | else | ||
121 | tmp_rate = parent_rate / div; | ||
122 | tmp_diff = abs(req->rate - tmp_rate); | ||
123 | |||
124 | if (*best_diff < 0 || *best_diff > tmp_diff) { | ||
125 | *best_rate = tmp_rate; | ||
126 | *best_diff = tmp_diff; | ||
127 | req->best_parent_rate = parent_rate; | ||
128 | req->best_parent_hw = parent; | ||
129 | } | ||
130 | } | ||
131 | |||
102 | static int clk_generated_determine_rate(struct clk_hw *hw, | 132 | static int clk_generated_determine_rate(struct clk_hw *hw, |
103 | struct clk_rate_request *req) | 133 | struct clk_rate_request *req) |
104 | { | 134 | { |
105 | struct clk_generated *gck = to_clk_generated(hw); | 135 | struct clk_generated *gck = to_clk_generated(hw); |
106 | struct clk_hw *parent = NULL; | 136 | struct clk_hw *parent = NULL; |
137 | struct clk_rate_request req_parent = *req; | ||
107 | long best_rate = -EINVAL; | 138 | long best_rate = -EINVAL; |
108 | unsigned long tmp_rate, min_rate; | 139 | unsigned long min_rate, parent_rate; |
109 | int best_diff = -1; | 140 | int best_diff = -1; |
110 | int tmp_diff; | ||
111 | int i; | 141 | int i; |
142 | u32 div; | ||
112 | 143 | ||
113 | for (i = 0; i < clk_hw_get_num_parents(hw); i++) { | 144 | for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) { |
114 | u32 div; | ||
115 | unsigned long parent_rate; | ||
116 | |||
117 | parent = clk_hw_get_parent_by_index(hw, i); | 145 | parent = clk_hw_get_parent_by_index(hw, i); |
118 | if (!parent) | 146 | if (!parent) |
119 | continue; | 147 | continue; |
@@ -124,25 +152,43 @@ static int clk_generated_determine_rate(struct clk_hw *hw, | |||
124 | (gck->range.max && min_rate > gck->range.max)) | 152 | (gck->range.max && min_rate > gck->range.max)) |
125 | continue; | 153 | continue; |
126 | 154 | ||
127 | for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { | 155 | div = DIV_ROUND_CLOSEST(parent_rate, req->rate); |
128 | tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div); | ||
129 | tmp_diff = abs(req->rate - tmp_rate); | ||
130 | 156 | ||
131 | if (best_diff < 0 || best_diff > tmp_diff) { | 157 | clk_generated_best_diff(req, parent, parent_rate, div, |
132 | best_rate = tmp_rate; | 158 | &best_diff, &best_rate); |
133 | best_diff = tmp_diff; | ||
134 | req->best_parent_rate = parent_rate; | ||
135 | req->best_parent_hw = parent; | ||
136 | } | ||
137 | 159 | ||
138 | if (!best_diff || tmp_rate < req->rate) | 160 | if (!best_diff) |
139 | break; | 161 | break; |
140 | } | 162 | } |
163 | |||
164 | /* | ||
165 | * The audio_pll rate can be modified, unlike the five others clocks | ||
166 | * that should never be altered. | ||
167 | * The audio_pll can technically be used by multiple consumers. However, | ||
168 | * with the rate locking, the first consumer to enable to clock will be | ||
169 | * the one definitely setting the rate of the clock. | ||
170 | * Since audio IPs are most likely to request the same rate, we enforce | ||
171 | * that the only clks able to modify gck rate are those of audio IPs. | ||
172 | */ | ||
173 | |||
174 | if (!gck->audio_pll_allowed) | ||
175 | goto end; | ||
176 | |||
177 | parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL); | ||
178 | if (!parent) | ||
179 | goto end; | ||
180 | |||
181 | for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { | ||
182 | req_parent.rate = req->rate * div; | ||
183 | __clk_determine_rate(parent, &req_parent); | ||
184 | clk_generated_best_diff(req, parent, req_parent.rate, div, | ||
185 | &best_diff, &best_rate); | ||
141 | 186 | ||
142 | if (!best_diff) | 187 | if (!best_diff) |
143 | break; | 188 | break; |
144 | } | 189 | } |
145 | 190 | ||
191 | end: | ||
146 | pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", | 192 | pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", |
147 | __func__, best_rate, | 193 | __func__, best_rate, |
148 | __clk_get_name((req->best_parent_hw)->clk), | 194 | __clk_get_name((req->best_parent_hw)->clk), |
@@ -252,7 +298,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, | |||
252 | init.ops = &generated_ops; | 298 | init.ops = &generated_ops; |
253 | init.parent_names = parent_names; | 299 | init.parent_names = parent_names; |
254 | init.num_parents = num_parents; | 300 | init.num_parents = num_parents; |
255 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; | 301 | init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | |
302 | CLK_SET_RATE_PARENT; | ||
256 | 303 | ||
257 | gck->id = id; | 304 | gck->id = id; |
258 | gck->hw.init = &init; | 305 | gck->hw.init = &init; |
@@ -284,6 +331,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) | |||
284 | struct device_node *gcknp; | 331 | struct device_node *gcknp; |
285 | struct clk_range range = CLK_RANGE(0, 0); | 332 | struct clk_range range = CLK_RANGE(0, 0); |
286 | struct regmap *regmap; | 333 | struct regmap *regmap; |
334 | struct clk_generated *gck; | ||
287 | 335 | ||
288 | num_parents = of_clk_get_parent_count(np); | 336 | num_parents = of_clk_get_parent_count(np); |
289 | if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) | 337 | if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) |
@@ -315,6 +363,21 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) | |||
315 | hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, | 363 | hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, |
316 | parent_names, num_parents, | 364 | parent_names, num_parents, |
317 | id, &range); | 365 | id, &range); |
366 | |||
367 | gck = to_clk_generated(hw); | ||
368 | |||
369 | if (of_device_is_compatible(np, | ||
370 | "atmel,sama5d2-clk-generated")) { | ||
371 | if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 || | ||
372 | gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 || | ||
373 | gck->id == GCK_ID_CLASSD) | ||
374 | gck->audio_pll_allowed = true; | ||
375 | else | ||
376 | gck->audio_pll_allowed = false; | ||
377 | } else { | ||
378 | gck->audio_pll_allowed = false; | ||
379 | } | ||
380 | |||
318 | if (IS_ERR(hw)) | 381 | if (IS_ERR(hw)) |
319 | continue; | 382 | continue; |
320 | 383 | ||
diff --git a/drivers/clk/axs10x/Makefile b/drivers/clk/axs10x/Makefile index 01996b871b06..d747deafbf1e 100644 --- a/drivers/clk/axs10x/Makefile +++ b/drivers/clk/axs10x/Makefile | |||
@@ -1 +1,2 @@ | |||
1 | obj-y += i2s_pll_clock.o | 1 | obj-y += i2s_pll_clock.o |
2 | obj-y += pll_clock.o | ||
diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c new file mode 100644 index 000000000000..25d8c240ddfb --- /dev/null +++ b/drivers/clk/axs10x/pll_clock.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * Synopsys AXS10X SDP Generic PLL clock driver | ||
3 | * | ||
4 | * Copyright (C) 2017 Synopsys | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/clk-provider.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/of_address.h> | ||
18 | #include <linux/of_device.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/of.h> | ||
21 | |||
22 | /* PLL registers addresses */ | ||
23 | #define PLL_REG_IDIV 0x0 | ||
24 | #define PLL_REG_FBDIV 0x4 | ||
25 | #define PLL_REG_ODIV 0x8 | ||
26 | |||
27 | /* | ||
28 | * Bit fields of the PLL IDIV/FBDIV/ODIV registers: | ||
29 | * ________________________________________________________________________ | ||
30 | * |31 15| 14 | 13 | 12 |11 6|5 0| | ||
31 | * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| | ||
32 | * |____________________|__________|________|______|____________|___________| | ||
33 | * | ||
34 | * Following macros determine the way of access to these registers | ||
35 | * They should be set up only using the macros. | ||
36 | * reg should be an u32 variable. | ||
37 | */ | ||
38 | |||
39 | #define PLL_REG_GET_LOW(reg) \ | ||
40 | (((reg) & (0x3F << 0)) >> 0) | ||
41 | #define PLL_REG_GET_HIGH(reg) \ | ||
42 | (((reg) & (0x3F << 6)) >> 6) | ||
43 | #define PLL_REG_GET_EDGE(reg) \ | ||
44 | (((reg) & (BIT(12))) ? 1 : 0) | ||
45 | #define PLL_REG_GET_BYPASS(reg) \ | ||
46 | (((reg) & (BIT(13))) ? 1 : 0) | ||
47 | #define PLL_REG_GET_NOUPD(reg) \ | ||
48 | (((reg) & (BIT(14))) ? 1 : 0) | ||
49 | #define PLL_REG_GET_PAD(reg) \ | ||
50 | (((reg) & (0x1FFFF << 15)) >> 15) | ||
51 | |||
52 | #define PLL_REG_SET_LOW(reg, value) \ | ||
53 | { reg |= (((value) & 0x3F) << 0); } | ||
54 | #define PLL_REG_SET_HIGH(reg, value) \ | ||
55 | { reg |= (((value) & 0x3F) << 6); } | ||
56 | #define PLL_REG_SET_EDGE(reg, value) \ | ||
57 | { reg |= (((value) & 0x01) << 12); } | ||
58 | #define PLL_REG_SET_BYPASS(reg, value) \ | ||
59 | { reg |= (((value) & 0x01) << 13); } | ||
60 | #define PLL_REG_SET_NOUPD(reg, value) \ | ||
61 | { reg |= (((value) & 0x01) << 14); } | ||
62 | #define PLL_REG_SET_PAD(reg, value) \ | ||
63 | { reg |= (((value) & 0x1FFFF) << 15); } | ||
64 | |||
65 | #define PLL_LOCK BIT(0) | ||
66 | #define PLL_ERROR BIT(1) | ||
67 | #define PLL_MAX_LOCK_TIME 100 /* 100 us */ | ||
68 | |||
69 | struct axs10x_pll_cfg { | ||
70 | u32 rate; | ||
71 | u32 idiv; | ||
72 | u32 fbdiv; | ||
73 | u32 odiv; | ||
74 | }; | ||
75 | |||
76 | static const struct axs10x_pll_cfg arc_pll_cfg[] = { | ||
77 | { 33333333, 1, 1, 1 }, | ||
78 | { 50000000, 1, 30, 20 }, | ||
79 | { 75000000, 2, 45, 10 }, | ||
80 | { 90000000, 2, 54, 10 }, | ||
81 | { 100000000, 1, 30, 10 }, | ||
82 | { 125000000, 2, 45, 6 }, | ||
83 | {} | ||
84 | }; | ||
85 | |||
86 | static const struct axs10x_pll_cfg pgu_pll_cfg[] = { | ||
87 | { 25200000, 1, 84, 90 }, | ||
88 | { 50000000, 1, 100, 54 }, | ||
89 | { 74250000, 1, 44, 16 }, | ||
90 | {} | ||
91 | }; | ||
92 | |||
93 | struct axs10x_pll_clk { | ||
94 | struct clk_hw hw; | ||
95 | void __iomem *base; | ||
96 | void __iomem *lock; | ||
97 | const struct axs10x_pll_cfg *pll_cfg; | ||
98 | struct device *dev; | ||
99 | }; | ||
100 | |||
101 | static inline void axs10x_pll_write(struct axs10x_pll_clk *clk, u32 reg, | ||
102 | u32 val) | ||
103 | { | ||
104 | iowrite32(val, clk->base + reg); | ||
105 | } | ||
106 | |||
107 | static inline u32 axs10x_pll_read(struct axs10x_pll_clk *clk, u32 reg) | ||
108 | { | ||
109 | return ioread32(clk->base + reg); | ||
110 | } | ||
111 | |||
112 | static inline struct axs10x_pll_clk *to_axs10x_pll_clk(struct clk_hw *hw) | ||
113 | { | ||
114 | return container_of(hw, struct axs10x_pll_clk, hw); | ||
115 | } | ||
116 | |||
117 | static inline u32 axs10x_div_get_value(u32 reg) | ||
118 | { | ||
119 | if (PLL_REG_GET_BYPASS(reg)) | ||
120 | return 1; | ||
121 | |||
122 | return PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg); | ||
123 | } | ||
124 | |||
125 | static inline u32 axs10x_encode_div(unsigned int id, int upd) | ||
126 | { | ||
127 | u32 div = 0; | ||
128 | |||
129 | PLL_REG_SET_LOW(div, (id % 2 == 0) ? id >> 1 : (id >> 1) + 1); | ||
130 | PLL_REG_SET_HIGH(div, id >> 1); | ||
131 | PLL_REG_SET_EDGE(div, id % 2); | ||
132 | PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); | ||
133 | PLL_REG_SET_NOUPD(div, upd == 0 ? 1 : 0); | ||
134 | |||
135 | return div; | ||
136 | } | ||
137 | |||
138 | static unsigned long axs10x_pll_recalc_rate(struct clk_hw *hw, | ||
139 | unsigned long parent_rate) | ||
140 | { | ||
141 | u64 rate; | ||
142 | u32 idiv, fbdiv, odiv; | ||
143 | struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); | ||
144 | |||
145 | idiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_IDIV)); | ||
146 | fbdiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_FBDIV)); | ||
147 | odiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_ODIV)); | ||
148 | |||
149 | rate = (u64)parent_rate * fbdiv; | ||
150 | do_div(rate, idiv * odiv); | ||
151 | |||
152 | return rate; | ||
153 | } | ||
154 | |||
155 | static long axs10x_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
156 | unsigned long *prate) | ||
157 | { | ||
158 | int i; | ||
159 | long best_rate; | ||
160 | struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); | ||
161 | const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg; | ||
162 | |||
163 | if (pll_cfg[0].rate == 0) | ||
164 | return -EINVAL; | ||
165 | |||
166 | best_rate = pll_cfg[0].rate; | ||
167 | |||
168 | for (i = 1; pll_cfg[i].rate != 0; i++) { | ||
169 | if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) | ||
170 | best_rate = pll_cfg[i].rate; | ||
171 | } | ||
172 | |||
173 | return best_rate; | ||
174 | } | ||
175 | |||
176 | static int axs10x_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
177 | unsigned long parent_rate) | ||
178 | { | ||
179 | int i; | ||
180 | struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); | ||
181 | const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg; | ||
182 | |||
183 | for (i = 0; pll_cfg[i].rate != 0; i++) { | ||
184 | if (pll_cfg[i].rate == rate) { | ||
185 | axs10x_pll_write(clk, PLL_REG_IDIV, | ||
186 | axs10x_encode_div(pll_cfg[i].idiv, 0)); | ||
187 | axs10x_pll_write(clk, PLL_REG_FBDIV, | ||
188 | axs10x_encode_div(pll_cfg[i].fbdiv, 0)); | ||
189 | axs10x_pll_write(clk, PLL_REG_ODIV, | ||
190 | axs10x_encode_div(pll_cfg[i].odiv, 1)); | ||
191 | |||
192 | /* | ||
193 | * Wait until CGU relocks and check error status. | ||
194 | * If after timeout CGU is unlocked yet return error | ||
195 | */ | ||
196 | udelay(PLL_MAX_LOCK_TIME); | ||
197 | if (!(ioread32(clk->lock) & PLL_LOCK)) | ||
198 | return -ETIMEDOUT; | ||
199 | |||
200 | if (ioread32(clk->lock) & PLL_ERROR) | ||
201 | return -EINVAL; | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, | ||
208 | parent_rate); | ||
209 | return -EINVAL; | ||
210 | } | ||
211 | |||
212 | static const struct clk_ops axs10x_pll_ops = { | ||
213 | .recalc_rate = axs10x_pll_recalc_rate, | ||
214 | .round_rate = axs10x_pll_round_rate, | ||
215 | .set_rate = axs10x_pll_set_rate, | ||
216 | }; | ||
217 | |||
218 | static int axs10x_pll_clk_probe(struct platform_device *pdev) | ||
219 | { | ||
220 | struct device *dev = &pdev->dev; | ||
221 | const char *parent_name; | ||
222 | struct axs10x_pll_clk *pll_clk; | ||
223 | struct resource *mem; | ||
224 | struct clk_init_data init = { }; | ||
225 | int ret; | ||
226 | |||
227 | pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); | ||
228 | if (!pll_clk) | ||
229 | return -ENOMEM; | ||
230 | |||
231 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
232 | pll_clk->base = devm_ioremap_resource(dev, mem); | ||
233 | if (IS_ERR(pll_clk->base)) | ||
234 | return PTR_ERR(pll_clk->base); | ||
235 | |||
236 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
237 | pll_clk->lock = devm_ioremap_resource(dev, mem); | ||
238 | if (IS_ERR(pll_clk->lock)) | ||
239 | return PTR_ERR(pll_clk->lock); | ||
240 | |||
241 | init.name = dev->of_node->name; | ||
242 | init.ops = &axs10x_pll_ops; | ||
243 | parent_name = of_clk_get_parent_name(dev->of_node, 0); | ||
244 | init.parent_names = &parent_name; | ||
245 | init.num_parents = 1; | ||
246 | pll_clk->hw.init = &init; | ||
247 | pll_clk->dev = dev; | ||
248 | pll_clk->pll_cfg = of_device_get_match_data(dev); | ||
249 | |||
250 | if (!pll_clk->pll_cfg) { | ||
251 | dev_err(dev, "No OF match data provided\n"); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
255 | ret = devm_clk_hw_register(dev, &pll_clk->hw); | ||
256 | if (ret) { | ||
257 | dev_err(dev, "failed to register %s clock\n", init.name); | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, | ||
262 | &pll_clk->hw); | ||
263 | } | ||
264 | |||
265 | static int axs10x_pll_clk_remove(struct platform_device *pdev) | ||
266 | { | ||
267 | of_clk_del_provider(pdev->dev.of_node); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static void __init of_axs10x_pll_clk_setup(struct device_node *node) | ||
272 | { | ||
273 | const char *parent_name; | ||
274 | struct axs10x_pll_clk *pll_clk; | ||
275 | struct clk_init_data init = { }; | ||
276 | int ret; | ||
277 | |||
278 | pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); | ||
279 | if (!pll_clk) | ||
280 | return; | ||
281 | |||
282 | pll_clk->base = of_iomap(node, 0); | ||
283 | if (!pll_clk->base) { | ||
284 | pr_err("failed to map pll div registers\n"); | ||
285 | goto err_free_pll_clk; | ||
286 | } | ||
287 | |||
288 | pll_clk->lock = of_iomap(node, 1); | ||
289 | if (!pll_clk->lock) { | ||
290 | pr_err("failed to map pll lock register\n"); | ||
291 | goto err_unmap_base; | ||
292 | } | ||
293 | |||
294 | init.name = node->name; | ||
295 | init.ops = &axs10x_pll_ops; | ||
296 | parent_name = of_clk_get_parent_name(node, 0); | ||
297 | init.parent_names = &parent_name; | ||
298 | init.num_parents = parent_name ? 1 : 0; | ||
299 | pll_clk->hw.init = &init; | ||
300 | pll_clk->pll_cfg = arc_pll_cfg; | ||
301 | |||
302 | ret = clk_hw_register(NULL, &pll_clk->hw); | ||
303 | if (ret) { | ||
304 | pr_err("failed to register %s clock\n", node->name); | ||
305 | goto err_unmap_lock; | ||
306 | } | ||
307 | |||
308 | ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); | ||
309 | if (ret) { | ||
310 | pr_err("failed to add hw provider for %s clock\n", node->name); | ||
311 | goto err_unregister_clk; | ||
312 | } | ||
313 | |||
314 | return; | ||
315 | |||
316 | err_unregister_clk: | ||
317 | clk_hw_unregister(&pll_clk->hw); | ||
318 | err_unmap_lock: | ||
319 | iounmap(pll_clk->lock); | ||
320 | err_unmap_base: | ||
321 | iounmap(pll_clk->base); | ||
322 | err_free_pll_clk: | ||
323 | kfree(pll_clk); | ||
324 | } | ||
325 | CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", | ||
326 | of_axs10x_pll_clk_setup); | ||
327 | |||
328 | static const struct of_device_id axs10x_pll_clk_id[] = { | ||
329 | { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_cfg}, | ||
330 | { } | ||
331 | }; | ||
332 | MODULE_DEVICE_TABLE(of, axs10x_pll_clk_id); | ||
333 | |||
334 | static struct platform_driver axs10x_pll_clk_driver = { | ||
335 | .driver = { | ||
336 | .name = "axs10x-pll-clock", | ||
337 | .of_match_table = axs10x_pll_clk_id, | ||
338 | }, | ||
339 | .probe = axs10x_pll_clk_probe, | ||
340 | .remove = axs10x_pll_clk_remove, | ||
341 | }; | ||
342 | builtin_platform_driver(axs10x_pll_clk_driver); | ||
343 | |||
344 | MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>"); | ||
345 | MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver"); | ||
346 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index 1d99292e2039..e7331ace0337 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c | |||
@@ -679,8 +679,7 @@ static void __init berlin2_clock_setup(struct device_node *np) | |||
679 | if (!IS_ERR(hws[n])) | 679 | if (!IS_ERR(hws[n])) |
680 | continue; | 680 | continue; |
681 | 681 | ||
682 | pr_err("%s: Unable to register leaf clock %d\n", | 682 | pr_err("%pOF: Unable to register leaf clock %d\n", np, n); |
683 | np->full_name, n); | ||
684 | goto bg2_fail; | 683 | goto bg2_fail; |
685 | } | 684 | } |
686 | 685 | ||
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 3b784b593afd..67c270b143f7 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c | |||
@@ -304,14 +304,14 @@ static void __init berlin2q_clock_setup(struct device_node *np) | |||
304 | 304 | ||
305 | gbase = of_iomap(parent_np, 0); | 305 | gbase = of_iomap(parent_np, 0); |
306 | if (!gbase) { | 306 | if (!gbase) { |
307 | pr_err("%s: Unable to map global base\n", np->full_name); | 307 | pr_err("%pOF: Unable to map global base\n", np); |
308 | return; | 308 | return; |
309 | } | 309 | } |
310 | 310 | ||
311 | /* BG2Q CPU PLL is not part of global registers */ | 311 | /* BG2Q CPU PLL is not part of global registers */ |
312 | cpupll_base = of_iomap(parent_np, 1); | 312 | cpupll_base = of_iomap(parent_np, 1); |
313 | if (!cpupll_base) { | 313 | if (!cpupll_base) { |
314 | pr_err("%s: Unable to map cpupll base\n", np->full_name); | 314 | pr_err("%pOF: Unable to map cpupll base\n", np); |
315 | iounmap(gbase); | 315 | iounmap(gbase); |
316 | return; | 316 | return; |
317 | } | 317 | } |
@@ -376,8 +376,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) | |||
376 | if (!IS_ERR(hws[n])) | 376 | if (!IS_ERR(hws[n])) |
377 | continue; | 377 | continue; |
378 | 378 | ||
379 | pr_err("%s: Unable to register leaf clock %d\n", | 379 | pr_err("%pOF: Unable to register leaf clock %d\n", np, n); |
380 | np->full_name, n); | ||
381 | goto bg2q_fail; | 380 | goto bg2q_fail; |
382 | } | 381 | } |
383 | 382 | ||
diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index ea8568536193..bf0582cbbf38 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c | |||
@@ -338,8 +338,8 @@ static void __init asm9260_acc_init(struct device_node *np) | |||
338 | if (!IS_ERR(hws[n])) | 338 | if (!IS_ERR(hws[n])) |
339 | continue; | 339 | continue; |
340 | 340 | ||
341 | pr_err("%s: Unable to register leaf clock %d\n", | 341 | pr_err("%pOF: Unable to register leaf clock %d\n", |
342 | np->full_name, n); | 342 | np, n); |
343 | goto fail; | 343 | goto fail; |
344 | } | 344 | } |
345 | 345 | ||
diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c index 7ec36722f8ab..49819b546134 100644 --- a/drivers/clk/clk-conf.c +++ b/drivers/clk/clk-conf.c | |||
@@ -23,8 +23,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) | |||
23 | num_parents = of_count_phandle_with_args(node, "assigned-clock-parents", | 23 | num_parents = of_count_phandle_with_args(node, "assigned-clock-parents", |
24 | "#clock-cells"); | 24 | "#clock-cells"); |
25 | if (num_parents == -EINVAL) | 25 | if (num_parents == -EINVAL) |
26 | pr_err("clk: invalid value of clock-parents property at %s\n", | 26 | pr_err("clk: invalid value of clock-parents property at %pOF\n", |
27 | node->full_name); | 27 | node); |
28 | 28 | ||
29 | for (index = 0; index < num_parents; index++) { | 29 | for (index = 0; index < num_parents; index++) { |
30 | rc = of_parse_phandle_with_args(node, "assigned-clock-parents", | 30 | rc = of_parse_phandle_with_args(node, "assigned-clock-parents", |
@@ -41,8 +41,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) | |||
41 | pclk = of_clk_get_from_provider(&clkspec); | 41 | pclk = of_clk_get_from_provider(&clkspec); |
42 | if (IS_ERR(pclk)) { | 42 | if (IS_ERR(pclk)) { |
43 | if (PTR_ERR(pclk) != -EPROBE_DEFER) | 43 | if (PTR_ERR(pclk) != -EPROBE_DEFER) |
44 | pr_warn("clk: couldn't get parent clock %d for %s\n", | 44 | pr_warn("clk: couldn't get parent clock %d for %pOF\n", |
45 | index, node->full_name); | 45 | index, node); |
46 | return PTR_ERR(pclk); | 46 | return PTR_ERR(pclk); |
47 | } | 47 | } |
48 | 48 | ||
@@ -57,8 +57,8 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier) | |||
57 | clk = of_clk_get_from_provider(&clkspec); | 57 | clk = of_clk_get_from_provider(&clkspec); |
58 | if (IS_ERR(clk)) { | 58 | if (IS_ERR(clk)) { |
59 | if (PTR_ERR(clk) != -EPROBE_DEFER) | 59 | if (PTR_ERR(clk) != -EPROBE_DEFER) |
60 | pr_warn("clk: couldn't get assigned clock %d for %s\n", | 60 | pr_warn("clk: couldn't get assigned clock %d for %pOF\n", |
61 | index, node->full_name); | 61 | index, node); |
62 | rc = PTR_ERR(clk); | 62 | rc = PTR_ERR(clk); |
63 | goto err; | 63 | goto err; |
64 | } | 64 | } |
@@ -102,8 +102,8 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier) | |||
102 | clk = of_clk_get_from_provider(&clkspec); | 102 | clk = of_clk_get_from_provider(&clkspec); |
103 | if (IS_ERR(clk)) { | 103 | if (IS_ERR(clk)) { |
104 | if (PTR_ERR(clk) != -EPROBE_DEFER) | 104 | if (PTR_ERR(clk) != -EPROBE_DEFER) |
105 | pr_warn("clk: couldn't get clock %d for %s\n", | 105 | pr_warn("clk: couldn't get clock %d for %pOF\n", |
106 | index, node->full_name); | 106 | index, node); |
107 | return PTR_ERR(clk); | 107 | return PTR_ERR(clk); |
108 | } | 108 | } |
109 | 109 | ||
diff --git a/drivers/clk/clk-cs2000-cp.c b/drivers/clk/clk-cs2000-cp.c index c54baede4d68..e8ea81c30f0c 100644 --- a/drivers/clk/clk-cs2000-cp.c +++ b/drivers/clk/clk-cs2000-cp.c | |||
@@ -343,6 +343,15 @@ static int cs2000_set_rate(struct clk_hw *hw, | |||
343 | return __cs2000_set_rate(priv, ch, rate, parent_rate); | 343 | return __cs2000_set_rate(priv, ch, rate, parent_rate); |
344 | } | 344 | } |
345 | 345 | ||
346 | static int cs2000_set_saved_rate(struct cs2000_priv *priv) | ||
347 | { | ||
348 | int ch = 0; /* it uses ch0 only at this point */ | ||
349 | |||
350 | return __cs2000_set_rate(priv, ch, | ||
351 | priv->saved_rate, | ||
352 | priv->saved_parent_rate); | ||
353 | } | ||
354 | |||
346 | static int cs2000_enable(struct clk_hw *hw) | 355 | static int cs2000_enable(struct clk_hw *hw) |
347 | { | 356 | { |
348 | struct cs2000_priv *priv = hw_to_priv(hw); | 357 | struct cs2000_priv *priv = hw_to_priv(hw); |
@@ -535,11 +544,8 @@ probe_err: | |||
535 | static int cs2000_resume(struct device *dev) | 544 | static int cs2000_resume(struct device *dev) |
536 | { | 545 | { |
537 | struct cs2000_priv *priv = dev_get_drvdata(dev); | 546 | struct cs2000_priv *priv = dev_get_drvdata(dev); |
538 | int ch = 0; /* it uses ch0 only at this point */ | ||
539 | 547 | ||
540 | return __cs2000_set_rate(priv, ch, | 548 | return cs2000_set_saved_rate(priv); |
541 | priv->saved_rate, | ||
542 | priv->saved_parent_rate); | ||
543 | } | 549 | } |
544 | 550 | ||
545 | static const struct dev_pm_ops cs2000_pm_ops = { | 551 | static const struct dev_pm_ops cs2000_pm_ops = { |
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 9bb472cccca6..4ed516cb7276 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -385,12 +385,14 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, | |||
385 | unsigned long parent_rate) | 385 | unsigned long parent_rate) |
386 | { | 386 | { |
387 | struct clk_divider *divider = to_clk_divider(hw); | 387 | struct clk_divider *divider = to_clk_divider(hw); |
388 | unsigned int value; | 388 | int value; |
389 | unsigned long flags = 0; | 389 | unsigned long flags = 0; |
390 | u32 val; | 390 | u32 val; |
391 | 391 | ||
392 | value = divider_get_val(rate, parent_rate, divider->table, | 392 | value = divider_get_val(rate, parent_rate, divider->table, |
393 | divider->width, divider->flags); | 393 | divider->width, divider->flags); |
394 | if (value < 0) | ||
395 | return value; | ||
394 | 396 | ||
395 | if (divider->lock) | 397 | if (divider->lock) |
396 | spin_lock_irqsave(divider->lock, flags); | 398 | spin_lock_irqsave(divider->lock, flags); |
@@ -403,7 +405,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, | |||
403 | val = clk_readl(divider->reg); | 405 | val = clk_readl(divider->reg); |
404 | val &= ~(div_mask(divider->width) << divider->shift); | 406 | val &= ~(div_mask(divider->width) << divider->shift); |
405 | } | 407 | } |
406 | val |= value << divider->shift; | 408 | val |= (u32)value << divider->shift; |
407 | clk_writel(val, divider->reg); | 409 | clk_writel(val, divider->reg); |
408 | 410 | ||
409 | if (divider->lock) | 411 | if (divider->lock) |
diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index aab904618eb6..fdf625fb10fa 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c | |||
@@ -49,16 +49,12 @@ static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, | |||
49 | return ret; | 49 | return ret; |
50 | } | 50 | } |
51 | 51 | ||
52 | static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, | 52 | static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate, |
53 | unsigned long *parent_rate) | 53 | unsigned long *parent_rate, |
54 | unsigned long *m, unsigned long *n) | ||
54 | { | 55 | { |
55 | struct clk_fractional_divider *fd = to_clk_fd(hw); | 56 | struct clk_fractional_divider *fd = to_clk_fd(hw); |
56 | unsigned long scale; | 57 | unsigned long scale; |
57 | unsigned long m, n; | ||
58 | u64 ret; | ||
59 | |||
60 | if (!rate || rate >= *parent_rate) | ||
61 | return *parent_rate; | ||
62 | 58 | ||
63 | /* | 59 | /* |
64 | * Get rate closer to *parent_rate to guarantee there is no overflow | 60 | * Get rate closer to *parent_rate to guarantee there is no overflow |
@@ -71,7 +67,23 @@ static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, | |||
71 | 67 | ||
72 | rational_best_approximation(rate, *parent_rate, | 68 | rational_best_approximation(rate, *parent_rate, |
73 | GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), | 69 | GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), |
74 | &m, &n); | 70 | m, n); |
71 | } | ||
72 | |||
73 | static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, | ||
74 | unsigned long *parent_rate) | ||
75 | { | ||
76 | struct clk_fractional_divider *fd = to_clk_fd(hw); | ||
77 | unsigned long m, n; | ||
78 | u64 ret; | ||
79 | |||
80 | if (!rate || rate >= *parent_rate) | ||
81 | return *parent_rate; | ||
82 | |||
83 | if (fd->approximation) | ||
84 | fd->approximation(hw, rate, parent_rate, &m, &n); | ||
85 | else | ||
86 | clk_fd_general_approximation(hw, rate, parent_rate, &m, &n); | ||
75 | 87 | ||
76 | ret = (u64)*parent_rate * m; | 88 | ret = (u64)*parent_rate * m; |
77 | do_div(ret, n); | 89 | do_div(ret, n); |
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 4e0c054a787c..dd82485e09a1 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c | |||
@@ -86,7 +86,7 @@ static void clk_gate_disable(struct clk_hw *hw) | |||
86 | clk_gate_endisable(hw, 0); | 86 | clk_gate_endisable(hw, 0); |
87 | } | 87 | } |
88 | 88 | ||
89 | static int clk_gate_is_enabled(struct clk_hw *hw) | 89 | int clk_gate_is_enabled(struct clk_hw *hw) |
90 | { | 90 | { |
91 | u32 reg; | 91 | u32 reg; |
92 | struct clk_gate *gate = to_clk_gate(hw); | 92 | struct clk_gate *gate = to_clk_gate(hw); |
@@ -101,6 +101,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw) | |||
101 | 101 | ||
102 | return reg ? 1 : 0; | 102 | return reg ? 1 : 0; |
103 | } | 103 | } |
104 | EXPORT_SYMBOL_GPL(clk_gate_is_enabled); | ||
104 | 105 | ||
105 | const struct clk_ops clk_gate_ops = { | 106 | const struct clk_ops clk_gate_ops = { |
106 | .enable = clk_gate_enable, | 107 | .enable = clk_gate_enable, |
diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index b4cf2f699a21..f940e5af845b 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c | |||
@@ -37,7 +37,6 @@ static DEFINE_SPINLOCK(gemini_clk_lock); | |||
37 | 37 | ||
38 | #define GEMINI_GLOBAL_MISC_CONTROL 0x30 | 38 | #define GEMINI_GLOBAL_MISC_CONTROL 0x30 |
39 | #define PCI_CLK_66MHZ BIT(18) | 39 | #define PCI_CLK_66MHZ BIT(18) |
40 | #define PCI_CLK_OE BIT(17) | ||
41 | 40 | ||
42 | #define GEMINI_GLOBAL_CLOCK_CONTROL 0x34 | 41 | #define GEMINI_GLOBAL_CLOCK_CONTROL 0x34 |
43 | #define PCI_CLKRUN_EN BIT(16) | 42 | #define PCI_CLKRUN_EN BIT(16) |
@@ -159,9 +158,6 @@ static int gemini_pci_enable(struct clk_hw *hw) | |||
159 | 158 | ||
160 | regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, | 159 | regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, |
161 | 0, PCI_CLKRUN_EN); | 160 | 0, PCI_CLKRUN_EN); |
162 | regmap_update_bits(pciclk->map, | ||
163 | GEMINI_GLOBAL_MISC_CONTROL, | ||
164 | 0, PCI_CLK_OE); | ||
165 | return 0; | 161 | return 0; |
166 | } | 162 | } |
167 | 163 | ||
@@ -169,9 +165,6 @@ static void gemini_pci_disable(struct clk_hw *hw) | |||
169 | { | 165 | { |
170 | struct clk_gemini_pci *pciclk = to_pciclk(hw); | 166 | struct clk_gemini_pci *pciclk = to_pciclk(hw); |
171 | 167 | ||
172 | regmap_update_bits(pciclk->map, | ||
173 | GEMINI_GLOBAL_MISC_CONTROL, | ||
174 | PCI_CLK_OE, 0); | ||
175 | regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, | 168 | regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, |
176 | PCI_CLKRUN_EN, 0); | 169 | PCI_CLKRUN_EN, 0); |
177 | } | 170 | } |
diff --git a/drivers/clk/clk-hsdk-pll.c b/drivers/clk/clk-hsdk-pll.c new file mode 100644 index 000000000000..bbf237173b37 --- /dev/null +++ b/drivers/clk/clk-hsdk-pll.c | |||
@@ -0,0 +1,431 @@ | |||
1 | /* | ||
2 | * Synopsys HSDK SDP Generic PLL clock driver | ||
3 | * | ||
4 | * Copyright (C) 2017 Synopsys | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | |||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/slab.h> | ||
20 | |||
21 | #define CGU_PLL_CTRL 0x000 /* ARC PLL control register */ | ||
22 | #define CGU_PLL_STATUS 0x004 /* ARC PLL status register */ | ||
23 | #define CGU_PLL_FMEAS 0x008 /* ARC PLL frequency measurement register */ | ||
24 | #define CGU_PLL_MON 0x00C /* ARC PLL monitor register */ | ||
25 | |||
26 | #define CGU_PLL_CTRL_ODIV_SHIFT 2 | ||
27 | #define CGU_PLL_CTRL_IDIV_SHIFT 4 | ||
28 | #define CGU_PLL_CTRL_FBDIV_SHIFT 9 | ||
29 | #define CGU_PLL_CTRL_BAND_SHIFT 20 | ||
30 | |||
31 | #define CGU_PLL_CTRL_ODIV_MASK GENMASK(3, CGU_PLL_CTRL_ODIV_SHIFT) | ||
32 | #define CGU_PLL_CTRL_IDIV_MASK GENMASK(8, CGU_PLL_CTRL_IDIV_SHIFT) | ||
33 | #define CGU_PLL_CTRL_FBDIV_MASK GENMASK(15, CGU_PLL_CTRL_FBDIV_SHIFT) | ||
34 | |||
35 | #define CGU_PLL_CTRL_PD BIT(0) | ||
36 | #define CGU_PLL_CTRL_BYPASS BIT(1) | ||
37 | |||
38 | #define CGU_PLL_STATUS_LOCK BIT(0) | ||
39 | #define CGU_PLL_STATUS_ERR BIT(1) | ||
40 | |||
41 | #define HSDK_PLL_MAX_LOCK_TIME 100 /* 100 us */ | ||
42 | |||
43 | #define CGU_PLL_SOURCE_MAX 1 | ||
44 | |||
45 | #define CORE_IF_CLK_THRESHOLD_HZ 500000000 | ||
46 | #define CREG_CORE_IF_CLK_DIV_1 0x0 | ||
47 | #define CREG_CORE_IF_CLK_DIV_2 0x1 | ||
48 | |||
49 | struct hsdk_pll_cfg { | ||
50 | u32 rate; | ||
51 | u32 idiv; | ||
52 | u32 fbdiv; | ||
53 | u32 odiv; | ||
54 | u32 band; | ||
55 | }; | ||
56 | |||
57 | static const struct hsdk_pll_cfg asdt_pll_cfg[] = { | ||
58 | { 100000000, 0, 11, 3, 0 }, | ||
59 | { 133000000, 0, 15, 3, 0 }, | ||
60 | { 200000000, 1, 47, 3, 0 }, | ||
61 | { 233000000, 1, 27, 2, 0 }, | ||
62 | { 300000000, 1, 35, 2, 0 }, | ||
63 | { 333000000, 1, 39, 2, 0 }, | ||
64 | { 400000000, 1, 47, 2, 0 }, | ||
65 | { 500000000, 0, 14, 1, 0 }, | ||
66 | { 600000000, 0, 17, 1, 0 }, | ||
67 | { 700000000, 0, 20, 1, 0 }, | ||
68 | { 800000000, 0, 23, 1, 0 }, | ||
69 | { 900000000, 1, 26, 0, 0 }, | ||
70 | { 1000000000, 1, 29, 0, 0 }, | ||
71 | { 1100000000, 1, 32, 0, 0 }, | ||
72 | { 1200000000, 1, 35, 0, 0 }, | ||
73 | { 1300000000, 1, 38, 0, 0 }, | ||
74 | { 1400000000, 1, 41, 0, 0 }, | ||
75 | { 1500000000, 1, 44, 0, 0 }, | ||
76 | { 1600000000, 1, 47, 0, 0 }, | ||
77 | {} | ||
78 | }; | ||
79 | |||
80 | static const struct hsdk_pll_cfg hdmi_pll_cfg[] = { | ||
81 | { 297000000, 0, 21, 2, 0 }, | ||
82 | { 540000000, 0, 19, 1, 0 }, | ||
83 | { 594000000, 0, 21, 1, 0 }, | ||
84 | {} | ||
85 | }; | ||
86 | |||
87 | struct hsdk_pll_clk { | ||
88 | struct clk_hw hw; | ||
89 | void __iomem *regs; | ||
90 | void __iomem *spec_regs; | ||
91 | const struct hsdk_pll_devdata *pll_devdata; | ||
92 | struct device *dev; | ||
93 | }; | ||
94 | |||
95 | struct hsdk_pll_devdata { | ||
96 | const struct hsdk_pll_cfg *pll_cfg; | ||
97 | int (*update_rate)(struct hsdk_pll_clk *clk, unsigned long rate, | ||
98 | const struct hsdk_pll_cfg *cfg); | ||
99 | }; | ||
100 | |||
101 | static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *, unsigned long, | ||
102 | const struct hsdk_pll_cfg *); | ||
103 | static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *, unsigned long, | ||
104 | const struct hsdk_pll_cfg *); | ||
105 | |||
106 | static const struct hsdk_pll_devdata core_pll_devdata = { | ||
107 | .pll_cfg = asdt_pll_cfg, | ||
108 | .update_rate = hsdk_pll_core_update_rate, | ||
109 | }; | ||
110 | |||
111 | static const struct hsdk_pll_devdata sdt_pll_devdata = { | ||
112 | .pll_cfg = asdt_pll_cfg, | ||
113 | .update_rate = hsdk_pll_comm_update_rate, | ||
114 | }; | ||
115 | |||
116 | static const struct hsdk_pll_devdata hdmi_pll_devdata = { | ||
117 | .pll_cfg = hdmi_pll_cfg, | ||
118 | .update_rate = hsdk_pll_comm_update_rate, | ||
119 | }; | ||
120 | |||
121 | static inline void hsdk_pll_write(struct hsdk_pll_clk *clk, u32 reg, u32 val) | ||
122 | { | ||
123 | iowrite32(val, clk->regs + reg); | ||
124 | } | ||
125 | |||
126 | static inline u32 hsdk_pll_read(struct hsdk_pll_clk *clk, u32 reg) | ||
127 | { | ||
128 | return ioread32(clk->regs + reg); | ||
129 | } | ||
130 | |||
131 | static inline void hsdk_pll_set_cfg(struct hsdk_pll_clk *clk, | ||
132 | const struct hsdk_pll_cfg *cfg) | ||
133 | { | ||
134 | u32 val = 0; | ||
135 | |||
136 | /* Powerdown and Bypass bits should be cleared */ | ||
137 | val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT; | ||
138 | val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT; | ||
139 | val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT; | ||
140 | val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT; | ||
141 | |||
142 | dev_dbg(clk->dev, "write configurarion: %#x\n", val); | ||
143 | |||
144 | hsdk_pll_write(clk, CGU_PLL_CTRL, val); | ||
145 | } | ||
146 | |||
147 | static inline bool hsdk_pll_is_locked(struct hsdk_pll_clk *clk) | ||
148 | { | ||
149 | return !!(hsdk_pll_read(clk, CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK); | ||
150 | } | ||
151 | |||
152 | static inline bool hsdk_pll_is_err(struct hsdk_pll_clk *clk) | ||
153 | { | ||
154 | return !!(hsdk_pll_read(clk, CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR); | ||
155 | } | ||
156 | |||
157 | static inline struct hsdk_pll_clk *to_hsdk_pll_clk(struct clk_hw *hw) | ||
158 | { | ||
159 | return container_of(hw, struct hsdk_pll_clk, hw); | ||
160 | } | ||
161 | |||
162 | static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw, | ||
163 | unsigned long parent_rate) | ||
164 | { | ||
165 | u32 val; | ||
166 | u64 rate; | ||
167 | u32 idiv, fbdiv, odiv; | ||
168 | struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw); | ||
169 | |||
170 | val = hsdk_pll_read(clk, CGU_PLL_CTRL); | ||
171 | |||
172 | dev_dbg(clk->dev, "current configurarion: %#x\n", val); | ||
173 | |||
174 | /* Check if PLL is disabled */ | ||
175 | if (val & CGU_PLL_CTRL_PD) | ||
176 | return 0; | ||
177 | |||
178 | /* Check if PLL is bypassed */ | ||
179 | if (val & CGU_PLL_CTRL_BYPASS) | ||
180 | return parent_rate; | ||
181 | |||
182 | /* input divider = reg.idiv + 1 */ | ||
183 | idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT); | ||
184 | /* fb divider = 2*(reg.fbdiv + 1) */ | ||
185 | fbdiv = 2 * (1 + ((val & CGU_PLL_CTRL_FBDIV_MASK) >> CGU_PLL_CTRL_FBDIV_SHIFT)); | ||
186 | /* output divider = 2^(reg.odiv) */ | ||
187 | odiv = 1 << ((val & CGU_PLL_CTRL_ODIV_MASK) >> CGU_PLL_CTRL_ODIV_SHIFT); | ||
188 | |||
189 | rate = (u64)parent_rate * fbdiv; | ||
190 | do_div(rate, idiv * odiv); | ||
191 | |||
192 | return rate; | ||
193 | } | ||
194 | |||
195 | static long hsdk_pll_round_rate(struct clk_hw *hw, unsigned long rate, | ||
196 | unsigned long *prate) | ||
197 | { | ||
198 | int i; | ||
199 | unsigned long best_rate; | ||
200 | struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw); | ||
201 | const struct hsdk_pll_cfg *pll_cfg = clk->pll_devdata->pll_cfg; | ||
202 | |||
203 | if (pll_cfg[0].rate == 0) | ||
204 | return -EINVAL; | ||
205 | |||
206 | best_rate = pll_cfg[0].rate; | ||
207 | |||
208 | for (i = 1; pll_cfg[i].rate != 0; i++) { | ||
209 | if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) | ||
210 | best_rate = pll_cfg[i].rate; | ||
211 | } | ||
212 | |||
213 | dev_dbg(clk->dev, "chosen best rate: %lu\n", best_rate); | ||
214 | |||
215 | return best_rate; | ||
216 | } | ||
217 | |||
218 | static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *clk, | ||
219 | unsigned long rate, | ||
220 | const struct hsdk_pll_cfg *cfg) | ||
221 | { | ||
222 | hsdk_pll_set_cfg(clk, cfg); | ||
223 | |||
224 | /* | ||
225 | * Wait until CGU relocks and check error status. | ||
226 | * If after timeout CGU is unlocked yet return error. | ||
227 | */ | ||
228 | udelay(HSDK_PLL_MAX_LOCK_TIME); | ||
229 | if (!hsdk_pll_is_locked(clk)) | ||
230 | return -ETIMEDOUT; | ||
231 | |||
232 | if (hsdk_pll_is_err(clk)) | ||
233 | return -EINVAL; | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *clk, | ||
239 | unsigned long rate, | ||
240 | const struct hsdk_pll_cfg *cfg) | ||
241 | { | ||
242 | /* | ||
243 | * When core clock exceeds 500MHz, the divider for the interface | ||
244 | * clock must be programmed to div-by-2. | ||
245 | */ | ||
246 | if (rate > CORE_IF_CLK_THRESHOLD_HZ) | ||
247 | iowrite32(CREG_CORE_IF_CLK_DIV_2, clk->spec_regs); | ||
248 | |||
249 | hsdk_pll_set_cfg(clk, cfg); | ||
250 | |||
251 | /* | ||
252 | * Wait until CGU relocks and check error status. | ||
253 | * If after timeout CGU is unlocked yet return error. | ||
254 | */ | ||
255 | udelay(HSDK_PLL_MAX_LOCK_TIME); | ||
256 | if (!hsdk_pll_is_locked(clk)) | ||
257 | return -ETIMEDOUT; | ||
258 | |||
259 | if (hsdk_pll_is_err(clk)) | ||
260 | return -EINVAL; | ||
261 | |||
262 | /* | ||
263 | * Program divider to div-by-1 if we succesfuly set core clock below | ||
264 | * 500MHz threshold. | ||
265 | */ | ||
266 | if (rate <= CORE_IF_CLK_THRESHOLD_HZ) | ||
267 | iowrite32(CREG_CORE_IF_CLK_DIV_1, clk->spec_regs); | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int hsdk_pll_set_rate(struct clk_hw *hw, unsigned long rate, | ||
273 | unsigned long parent_rate) | ||
274 | { | ||
275 | int i; | ||
276 | struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw); | ||
277 | const struct hsdk_pll_cfg *pll_cfg = clk->pll_devdata->pll_cfg; | ||
278 | |||
279 | for (i = 0; pll_cfg[i].rate != 0; i++) { | ||
280 | if (pll_cfg[i].rate == rate) { | ||
281 | return clk->pll_devdata->update_rate(clk, rate, | ||
282 | &pll_cfg[i]); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, | ||
287 | parent_rate); | ||
288 | |||
289 | return -EINVAL; | ||
290 | } | ||
291 | |||
292 | static const struct clk_ops hsdk_pll_ops = { | ||
293 | .recalc_rate = hsdk_pll_recalc_rate, | ||
294 | .round_rate = hsdk_pll_round_rate, | ||
295 | .set_rate = hsdk_pll_set_rate, | ||
296 | }; | ||
297 | |||
298 | static int hsdk_pll_clk_probe(struct platform_device *pdev) | ||
299 | { | ||
300 | int ret; | ||
301 | struct resource *mem; | ||
302 | const char *parent_name; | ||
303 | unsigned int num_parents; | ||
304 | struct hsdk_pll_clk *pll_clk; | ||
305 | struct clk_init_data init = { }; | ||
306 | struct device *dev = &pdev->dev; | ||
307 | |||
308 | pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); | ||
309 | if (!pll_clk) | ||
310 | return -ENOMEM; | ||
311 | |||
312 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
313 | pll_clk->regs = devm_ioremap_resource(dev, mem); | ||
314 | if (IS_ERR(pll_clk->regs)) | ||
315 | return PTR_ERR(pll_clk->regs); | ||
316 | |||
317 | init.name = dev->of_node->name; | ||
318 | init.ops = &hsdk_pll_ops; | ||
319 | parent_name = of_clk_get_parent_name(dev->of_node, 0); | ||
320 | init.parent_names = &parent_name; | ||
321 | num_parents = of_clk_get_parent_count(dev->of_node); | ||
322 | if (num_parents == 0 || num_parents > CGU_PLL_SOURCE_MAX) { | ||
323 | dev_err(dev, "wrong clock parents number: %u\n", num_parents); | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | init.num_parents = num_parents; | ||
327 | |||
328 | pll_clk->hw.init = &init; | ||
329 | pll_clk->dev = dev; | ||
330 | pll_clk->pll_devdata = of_device_get_match_data(dev); | ||
331 | |||
332 | if (!pll_clk->pll_devdata) { | ||
333 | dev_err(dev, "No OF match data provided\n"); | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | |||
337 | ret = devm_clk_hw_register(dev, &pll_clk->hw); | ||
338 | if (ret) { | ||
339 | dev_err(dev, "failed to register %s clock\n", init.name); | ||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, | ||
344 | &pll_clk->hw); | ||
345 | } | ||
346 | |||
347 | static int hsdk_pll_clk_remove(struct platform_device *pdev) | ||
348 | { | ||
349 | of_clk_del_provider(pdev->dev.of_node); | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static void __init of_hsdk_pll_clk_setup(struct device_node *node) | ||
354 | { | ||
355 | int ret; | ||
356 | const char *parent_name; | ||
357 | unsigned int num_parents; | ||
358 | struct hsdk_pll_clk *pll_clk; | ||
359 | struct clk_init_data init = { }; | ||
360 | |||
361 | pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); | ||
362 | if (!pll_clk) | ||
363 | return; | ||
364 | |||
365 | pll_clk->regs = of_iomap(node, 0); | ||
366 | if (!pll_clk->regs) { | ||
367 | pr_err("failed to map pll registers\n"); | ||
368 | goto err_free_pll_clk; | ||
369 | } | ||
370 | |||
371 | pll_clk->spec_regs = of_iomap(node, 1); | ||
372 | if (!pll_clk->spec_regs) { | ||
373 | pr_err("failed to map pll registers\n"); | ||
374 | goto err_unmap_comm_regs; | ||
375 | } | ||
376 | |||
377 | init.name = node->name; | ||
378 | init.ops = &hsdk_pll_ops; | ||
379 | parent_name = of_clk_get_parent_name(node, 0); | ||
380 | init.parent_names = &parent_name; | ||
381 | num_parents = of_clk_get_parent_count(node); | ||
382 | if (num_parents > CGU_PLL_SOURCE_MAX) { | ||
383 | pr_err("too much clock parents: %u\n", num_parents); | ||
384 | goto err_unmap_spec_regs; | ||
385 | } | ||
386 | init.num_parents = num_parents; | ||
387 | |||
388 | pll_clk->hw.init = &init; | ||
389 | pll_clk->pll_devdata = &core_pll_devdata; | ||
390 | |||
391 | ret = clk_hw_register(NULL, &pll_clk->hw); | ||
392 | if (ret) { | ||
393 | pr_err("failed to register %s clock\n", node->name); | ||
394 | goto err_unmap_spec_regs; | ||
395 | } | ||
396 | |||
397 | ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); | ||
398 | if (ret) { | ||
399 | pr_err("failed to add hw provider for %s clock\n", node->name); | ||
400 | goto err_unmap_spec_regs; | ||
401 | } | ||
402 | |||
403 | return; | ||
404 | |||
405 | err_unmap_spec_regs: | ||
406 | iounmap(pll_clk->spec_regs); | ||
407 | err_unmap_comm_regs: | ||
408 | iounmap(pll_clk->regs); | ||
409 | err_free_pll_clk: | ||
410 | kfree(pll_clk); | ||
411 | } | ||
412 | |||
413 | /* Core PLL needed early for ARC cpus timers */ | ||
414 | CLK_OF_DECLARE(hsdk_pll_clock, "snps,hsdk-core-pll-clock", | ||
415 | of_hsdk_pll_clk_setup); | ||
416 | |||
417 | static const struct of_device_id hsdk_pll_clk_id[] = { | ||
418 | { .compatible = "snps,hsdk-gp-pll-clock", .data = &sdt_pll_devdata}, | ||
419 | { .compatible = "snps,hsdk-hdmi-pll-clock", .data = &hdmi_pll_devdata}, | ||
420 | { } | ||
421 | }; | ||
422 | |||
423 | static struct platform_driver hsdk_pll_clk_driver = { | ||
424 | .driver = { | ||
425 | .name = "hsdk-gp-pll-clock", | ||
426 | .of_match_table = hsdk_pll_clk_id, | ||
427 | }, | ||
428 | .probe = hsdk_pll_clk_probe, | ||
429 | .remove = hsdk_pll_clk_remove, | ||
430 | }; | ||
431 | builtin_platform_driver(hsdk_pll_clk_driver); | ||
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c deleted file mode 100644 index 2a83a3ff1d09..000000000000 --- a/drivers/clk/clk-mb86s7x.c +++ /dev/null | |||
@@ -1,390 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED | ||
3 | * Copyright (C) 2015 Linaro Ltd. | ||
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, version 2 of the License. | ||
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/clkdev.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/cpu.h> | ||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/topology.h> | ||
24 | #include <linux/mailbox_client.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | |||
27 | #include <soc/mb86s7x/scb_mhu.h> | ||
28 | |||
29 | #define to_crg_clk(p) container_of(p, struct crg_clk, hw) | ||
30 | #define to_clc_clk(p) container_of(p, struct cl_clk, hw) | ||
31 | |||
32 | struct mb86s7x_peri_clk { | ||
33 | u32 payload_size; | ||
34 | u32 cntrlr; | ||
35 | u32 domain; | ||
36 | u32 port; | ||
37 | u32 en; | ||
38 | u64 frequency; | ||
39 | } __packed __aligned(4); | ||
40 | |||
41 | struct hack_rate { | ||
42 | unsigned clk_id; | ||
43 | unsigned long rate; | ||
44 | int gated; | ||
45 | }; | ||
46 | |||
47 | struct crg_clk { | ||
48 | struct clk_hw hw; | ||
49 | u8 cntrlr, domain, port; | ||
50 | }; | ||
51 | |||
52 | static int crg_gate_control(struct clk_hw *hw, int en) | ||
53 | { | ||
54 | struct crg_clk *crgclk = to_crg_clk(hw); | ||
55 | struct mb86s7x_peri_clk cmd; | ||
56 | int ret; | ||
57 | |||
58 | cmd.payload_size = sizeof(cmd); | ||
59 | cmd.cntrlr = crgclk->cntrlr; | ||
60 | cmd.domain = crgclk->domain; | ||
61 | cmd.port = crgclk->port; | ||
62 | cmd.en = en; | ||
63 | |||
64 | /* Port is UngatedCLK */ | ||
65 | if (cmd.port == 8) | ||
66 | return en ? 0 : -EINVAL; | ||
67 | |||
68 | pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n", | ||
69 | __func__, __LINE__, cmd.cntrlr, | ||
70 | cmd.domain, cmd.port, cmd.en); | ||
71 | |||
72 | ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ, | ||
73 | &cmd, sizeof(cmd)); | ||
74 | if (ret < 0) { | ||
75 | pr_err("%s:%d failed!\n", __func__, __LINE__); | ||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n", | ||
80 | __func__, __LINE__, cmd.cntrlr, | ||
81 | cmd.domain, cmd.port, cmd.en); | ||
82 | |||
83 | /* If the request was rejected */ | ||
84 | if (cmd.en != en) | ||
85 | ret = -EINVAL; | ||
86 | else | ||
87 | ret = 0; | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int crg_port_prepare(struct clk_hw *hw) | ||
93 | { | ||
94 | return crg_gate_control(hw, 1); | ||
95 | } | ||
96 | |||
97 | static void crg_port_unprepare(struct clk_hw *hw) | ||
98 | { | ||
99 | crg_gate_control(hw, 0); | ||
100 | } | ||
101 | |||
102 | static int | ||
103 | crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate) | ||
104 | { | ||
105 | struct crg_clk *crgclk = to_crg_clk(hw); | ||
106 | struct mb86s7x_peri_clk cmd; | ||
107 | int code, ret; | ||
108 | |||
109 | cmd.payload_size = sizeof(cmd); | ||
110 | cmd.cntrlr = crgclk->cntrlr; | ||
111 | cmd.domain = crgclk->domain; | ||
112 | cmd.port = crgclk->port; | ||
113 | cmd.frequency = *rate; | ||
114 | |||
115 | if (set) { | ||
116 | code = CMD_PERI_CLOCK_RATE_SET_REQ; | ||
117 | pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n", | ||
118 | __func__, __LINE__, cmd.cntrlr, | ||
119 | cmd.domain, cmd.port, cmd.frequency); | ||
120 | } else { | ||
121 | code = CMD_PERI_CLOCK_RATE_GET_REQ; | ||
122 | pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n", | ||
123 | __func__, __LINE__, cmd.cntrlr, | ||
124 | cmd.domain, cmd.port); | ||
125 | } | ||
126 | |||
127 | ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd)); | ||
128 | if (ret < 0) { | ||
129 | pr_err("%s:%d failed!\n", __func__, __LINE__); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | if (set) | ||
134 | pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n", | ||
135 | __func__, __LINE__, cmd.cntrlr, | ||
136 | cmd.domain, cmd.port, cmd.frequency); | ||
137 | else | ||
138 | pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n", | ||
139 | __func__, __LINE__, cmd.cntrlr, | ||
140 | cmd.domain, cmd.port, cmd.frequency); | ||
141 | |||
142 | *rate = cmd.frequency; | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static unsigned long | ||
147 | crg_port_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | ||
148 | { | ||
149 | unsigned long rate; | ||
150 | |||
151 | crg_rate_control(hw, 0, &rate); | ||
152 | |||
153 | return rate; | ||
154 | } | ||
155 | |||
156 | static long | ||
157 | crg_port_round_rate(struct clk_hw *hw, | ||
158 | unsigned long rate, unsigned long *pr) | ||
159 | { | ||
160 | return rate; | ||
161 | } | ||
162 | |||
163 | static int | ||
164 | crg_port_set_rate(struct clk_hw *hw, | ||
165 | unsigned long rate, unsigned long parent_rate) | ||
166 | { | ||
167 | return crg_rate_control(hw, 1, &rate); | ||
168 | } | ||
169 | |||
170 | const struct clk_ops crg_port_ops = { | ||
171 | .prepare = crg_port_prepare, | ||
172 | .unprepare = crg_port_unprepare, | ||
173 | .recalc_rate = crg_port_recalc_rate, | ||
174 | .round_rate = crg_port_round_rate, | ||
175 | .set_rate = crg_port_set_rate, | ||
176 | }; | ||
177 | |||
178 | struct mb86s70_crg11 { | ||
179 | struct mutex lock; /* protects CLK populating and searching */ | ||
180 | }; | ||
181 | |||
182 | static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data) | ||
183 | { | ||
184 | struct mb86s70_crg11 *crg11 = data; | ||
185 | struct clk_init_data init; | ||
186 | u32 cntrlr, domain, port; | ||
187 | struct crg_clk *crgclk; | ||
188 | struct clk *clk; | ||
189 | char clkp[20]; | ||
190 | |||
191 | if (clkspec->args_count != 3) | ||
192 | return ERR_PTR(-EINVAL); | ||
193 | |||
194 | cntrlr = clkspec->args[0]; | ||
195 | domain = clkspec->args[1]; | ||
196 | port = clkspec->args[2]; | ||
197 | |||
198 | if (port > 7) | ||
199 | snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain); | ||
200 | else | ||
201 | snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port); | ||
202 | |||
203 | mutex_lock(&crg11->lock); | ||
204 | |||
205 | clk = __clk_lookup(clkp); | ||
206 | if (clk) { | ||
207 | mutex_unlock(&crg11->lock); | ||
208 | return clk; | ||
209 | } | ||
210 | |||
211 | crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL); | ||
212 | if (!crgclk) { | ||
213 | mutex_unlock(&crg11->lock); | ||
214 | return ERR_PTR(-ENOMEM); | ||
215 | } | ||
216 | |||
217 | init.name = clkp; | ||
218 | init.num_parents = 0; | ||
219 | init.ops = &crg_port_ops; | ||
220 | init.flags = 0; | ||
221 | crgclk->hw.init = &init; | ||
222 | crgclk->cntrlr = cntrlr; | ||
223 | crgclk->domain = domain; | ||
224 | crgclk->port = port; | ||
225 | clk = clk_register(NULL, &crgclk->hw); | ||
226 | if (IS_ERR(clk)) | ||
227 | pr_err("%s:%d Error!\n", __func__, __LINE__); | ||
228 | else | ||
229 | pr_debug("Registered %s\n", clkp); | ||
230 | |||
231 | clk_register_clkdev(clk, clkp, NULL); | ||
232 | mutex_unlock(&crg11->lock); | ||
233 | return clk; | ||
234 | } | ||
235 | |||
236 | static void __init crg_port_init(struct device_node *node) | ||
237 | { | ||
238 | struct mb86s70_crg11 *crg11; | ||
239 | |||
240 | crg11 = kzalloc(sizeof(*crg11), GFP_KERNEL); | ||
241 | if (!crg11) | ||
242 | return; | ||
243 | |||
244 | mutex_init(&crg11->lock); | ||
245 | |||
246 | of_clk_add_provider(node, crg11_get, crg11); | ||
247 | } | ||
248 | CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init); | ||
249 | |||
250 | struct cl_clk { | ||
251 | struct clk_hw hw; | ||
252 | int cluster; | ||
253 | }; | ||
254 | |||
255 | struct mb86s7x_cpu_freq { | ||
256 | u32 payload_size; | ||
257 | u32 cluster_class; | ||
258 | u32 cluster_id; | ||
259 | u32 cpu_id; | ||
260 | u64 frequency; | ||
261 | }; | ||
262 | |||
263 | static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get) | ||
264 | { | ||
265 | struct cl_clk *clc = to_clc_clk(hw); | ||
266 | struct mb86s7x_cpu_freq cmd; | ||
267 | int code, ret; | ||
268 | |||
269 | cmd.payload_size = sizeof(cmd); | ||
270 | cmd.cluster_class = 0; | ||
271 | cmd.cluster_id = clc->cluster; | ||
272 | cmd.cpu_id = 0; | ||
273 | cmd.frequency = *rate; | ||
274 | |||
275 | if (get) | ||
276 | code = CMD_CPU_CLOCK_RATE_GET_REQ; | ||
277 | else | ||
278 | code = CMD_CPU_CLOCK_RATE_SET_REQ; | ||
279 | |||
280 | pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n", | ||
281 | __func__, __LINE__, cmd.cluster_class, | ||
282 | cmd.cluster_id, cmd.cpu_id, cmd.frequency); | ||
283 | |||
284 | ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd)); | ||
285 | if (ret < 0) { | ||
286 | pr_err("%s:%d failed!\n", __func__, __LINE__); | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n", | ||
291 | __func__, __LINE__, cmd.cluster_class, | ||
292 | cmd.cluster_id, cmd.cpu_id, cmd.frequency); | ||
293 | |||
294 | *rate = cmd.frequency; | ||
295 | } | ||
296 | |||
297 | static unsigned long | ||
298 | clc_recalc_rate(struct clk_hw *hw, unsigned long unused) | ||
299 | { | ||
300 | unsigned long rate; | ||
301 | |||
302 | mhu_cluster_rate(hw, &rate, 1); | ||
303 | return rate; | ||
304 | } | ||
305 | |||
306 | static long | ||
307 | clc_round_rate(struct clk_hw *hw, unsigned long rate, | ||
308 | unsigned long *unused) | ||
309 | { | ||
310 | return rate; | ||
311 | } | ||
312 | |||
313 | static int | ||
314 | clc_set_rate(struct clk_hw *hw, unsigned long rate, | ||
315 | unsigned long unused) | ||
316 | { | ||
317 | unsigned long res = rate; | ||
318 | |||
319 | mhu_cluster_rate(hw, &res, 0); | ||
320 | |||
321 | return (res == rate) ? 0 : -EINVAL; | ||
322 | } | ||
323 | |||
324 | static struct clk_ops clk_clc_ops = { | ||
325 | .recalc_rate = clc_recalc_rate, | ||
326 | .round_rate = clc_round_rate, | ||
327 | .set_rate = clc_set_rate, | ||
328 | }; | ||
329 | |||
330 | static struct clk_hw *mb86s7x_clclk_register(struct device *cpu_dev) | ||
331 | { | ||
332 | struct clk_init_data init; | ||
333 | struct cl_clk *clc; | ||
334 | int ret; | ||
335 | |||
336 | clc = kzalloc(sizeof(*clc), GFP_KERNEL); | ||
337 | if (!clc) | ||
338 | return ERR_PTR(-ENOMEM); | ||
339 | |||
340 | clc->hw.init = &init; | ||
341 | clc->cluster = topology_physical_package_id(cpu_dev->id); | ||
342 | |||
343 | init.name = dev_name(cpu_dev); | ||
344 | init.ops = &clk_clc_ops; | ||
345 | init.flags = CLK_GET_RATE_NOCACHE; | ||
346 | init.num_parents = 0; | ||
347 | |||
348 | ret = devm_clk_hw_register(cpu_dev, &clc->hw); | ||
349 | if (ret) | ||
350 | return ERR_PTR(ret); | ||
351 | return &clc->hw; | ||
352 | } | ||
353 | |||
354 | static int mb86s7x_clclk_of_init(void) | ||
355 | { | ||
356 | int cpu, ret = -ENODEV; | ||
357 | struct device_node *np; | ||
358 | struct clk_hw *hw; | ||
359 | |||
360 | np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0"); | ||
361 | if (!np || !of_device_is_available(np)) | ||
362 | goto exit; | ||
363 | |||
364 | for_each_possible_cpu(cpu) { | ||
365 | struct device *cpu_dev = get_cpu_device(cpu); | ||
366 | |||
367 | if (!cpu_dev) { | ||
368 | pr_err("failed to get cpu%d device\n", cpu); | ||
369 | continue; | ||
370 | } | ||
371 | |||
372 | hw = mb86s7x_clclk_register(cpu_dev); | ||
373 | if (IS_ERR(hw)) { | ||
374 | pr_err("failed to register cpu%d clock\n", cpu); | ||
375 | continue; | ||
376 | } | ||
377 | if (clk_hw_register_clkdev(hw, NULL, dev_name(cpu_dev))) { | ||
378 | pr_err("failed to register cpu%d clock lookup\n", cpu); | ||
379 | continue; | ||
380 | } | ||
381 | pr_debug("registered clk for %s\n", dev_name(cpu_dev)); | ||
382 | } | ||
383 | ret = 0; | ||
384 | |||
385 | platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0); | ||
386 | exit: | ||
387 | of_node_put(np); | ||
388 | return ret; | ||
389 | } | ||
390 | module_init(mb86s7x_clclk_of_init); | ||
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c index b86dac851116..58428d0043fd 100644 --- a/drivers/clk/clk-moxart.c +++ b/drivers/clk/clk-moxart.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | static void __init moxart_of_pll_clk_init(struct device_node *node) | 19 | static void __init moxart_of_pll_clk_init(struct device_node *node) |
20 | { | 20 | { |
21 | static void __iomem *base; | 21 | void __iomem *base; |
22 | struct clk_hw *hw; | 22 | struct clk_hw *hw; |
23 | struct clk *ref_clk; | 23 | struct clk *ref_clk; |
24 | unsigned int mul; | 24 | unsigned int mul; |
@@ -30,7 +30,7 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) | |||
30 | 30 | ||
31 | base = of_iomap(node, 0); | 31 | base = of_iomap(node, 0); |
32 | if (!base) { | 32 | if (!base) { |
33 | pr_err("%s: of_iomap failed\n", node->full_name); | 33 | pr_err("%pOF: of_iomap failed\n", node); |
34 | return; | 34 | return; |
35 | } | 35 | } |
36 | 36 | ||
@@ -39,13 +39,13 @@ static void __init moxart_of_pll_clk_init(struct device_node *node) | |||
39 | 39 | ||
40 | ref_clk = of_clk_get(node, 0); | 40 | ref_clk = of_clk_get(node, 0); |
41 | if (IS_ERR(ref_clk)) { | 41 | if (IS_ERR(ref_clk)) { |
42 | pr_err("%s: of_clk_get failed\n", node->full_name); | 42 | pr_err("%pOF: of_clk_get failed\n", node); |
43 | return; | 43 | return; |
44 | } | 44 | } |
45 | 45 | ||
46 | hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); | 46 | hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); |
47 | if (IS_ERR(hw)) { | 47 | if (IS_ERR(hw)) { |
48 | pr_err("%s: failed to register clock\n", node->full_name); | 48 | pr_err("%pOF: failed to register clock\n", node); |
49 | return; | 49 | return; |
50 | } | 50 | } |
51 | 51 | ||
@@ -57,7 +57,7 @@ CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock", | |||
57 | 57 | ||
58 | static void __init moxart_of_apb_clk_init(struct device_node *node) | 58 | static void __init moxart_of_apb_clk_init(struct device_node *node) |
59 | { | 59 | { |
60 | static void __iomem *base; | 60 | void __iomem *base; |
61 | struct clk_hw *hw; | 61 | struct clk_hw *hw; |
62 | struct clk *pll_clk; | 62 | struct clk *pll_clk; |
63 | unsigned int div, val; | 63 | unsigned int div, val; |
@@ -70,7 +70,7 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) | |||
70 | 70 | ||
71 | base = of_iomap(node, 0); | 71 | base = of_iomap(node, 0); |
72 | if (!base) { | 72 | if (!base) { |
73 | pr_err("%s: of_iomap failed\n", node->full_name); | 73 | pr_err("%pOF: of_iomap failed\n", node); |
74 | return; | 74 | return; |
75 | } | 75 | } |
76 | 76 | ||
@@ -83,13 +83,13 @@ static void __init moxart_of_apb_clk_init(struct device_node *node) | |||
83 | 83 | ||
84 | pll_clk = of_clk_get(node, 0); | 84 | pll_clk = of_clk_get(node, 0); |
85 | if (IS_ERR(pll_clk)) { | 85 | if (IS_ERR(pll_clk)) { |
86 | pr_err("%s: of_clk_get failed\n", node->full_name); | 86 | pr_err("%pOF: of_clk_get failed\n", node); |
87 | return; | 87 | return; |
88 | } | 88 | } |
89 | 89 | ||
90 | hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); | 90 | hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); |
91 | if (IS_ERR(hw)) { | 91 | if (IS_ERR(hw)) { |
92 | pr_err("%s: failed to register clock\n", node->full_name); | 92 | pr_err("%pOF: failed to register clock\n", node); |
93 | return; | 93 | return; |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index f3931e38fac0..b0ea753b8709 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/clk-provider.h> | 14 | #include <linux/clk-provider.h> |
15 | #include <linux/clkdev.h> | ||
15 | #include <linux/fsl/guts.h> | 16 | #include <linux/fsl/guts.h> |
16 | #include <linux/io.h> | 17 | #include <linux/io.h> |
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
@@ -537,6 +538,17 @@ static const struct clockgen_chipinfo chipinfo[] = { | |||
537 | .flags = CG_PLL_8BIT, | 538 | .flags = CG_PLL_8BIT, |
538 | }, | 539 | }, |
539 | { | 540 | { |
541 | .compat = "fsl,ls1088a-clockgen", | ||
542 | .cmux_groups = { | ||
543 | &clockgen2_cmux_cga12 | ||
544 | }, | ||
545 | .cmux_to_group = { | ||
546 | 0, 0, -1 | ||
547 | }, | ||
548 | .pll_mask = 0x07, | ||
549 | .flags = CG_VER3 | CG_LITTLE_ENDIAN, | ||
550 | }, | ||
551 | { | ||
540 | .compat = "fsl,ls1012a-clockgen", | 552 | .compat = "fsl,ls1012a-clockgen", |
541 | .cmux_groups = { | 553 | .cmux_groups = { |
542 | &ls1012a_cmux | 554 | &ls1012a_cmux |
@@ -1113,6 +1125,7 @@ static void __init create_one_pll(struct clockgen *cg, int idx) | |||
1113 | 1125 | ||
1114 | for (i = 0; i < ARRAY_SIZE(pll->div); i++) { | 1126 | for (i = 0; i < ARRAY_SIZE(pll->div); i++) { |
1115 | struct clk *clk; | 1127 | struct clk *clk; |
1128 | int ret; | ||
1116 | 1129 | ||
1117 | snprintf(pll->div[i].name, sizeof(pll->div[i].name), | 1130 | snprintf(pll->div[i].name, sizeof(pll->div[i].name), |
1118 | "cg-pll%d-div%d", idx, i + 1); | 1131 | "cg-pll%d-div%d", idx, i + 1); |
@@ -1126,6 +1139,11 @@ static void __init create_one_pll(struct clockgen *cg, int idx) | |||
1126 | } | 1139 | } |
1127 | 1140 | ||
1128 | pll->div[i].clk = clk; | 1141 | pll->div[i].clk = clk; |
1142 | ret = clk_register_clkdev(clk, pll->div[i].name, NULL); | ||
1143 | if (ret != 0) | ||
1144 | pr_err("%s: %s: register to lookup table failed %ld\n", | ||
1145 | __func__, pll->div[i].name, PTR_ERR(clk)); | ||
1146 | |||
1129 | } | 1147 | } |
1130 | } | 1148 | } |
1131 | 1149 | ||
@@ -1348,8 +1366,7 @@ static void __init clockgen_init(struct device_node *np) | |||
1348 | } | 1366 | } |
1349 | 1367 | ||
1350 | if (i == ARRAY_SIZE(chipinfo)) { | 1368 | if (i == ARRAY_SIZE(chipinfo)) { |
1351 | pr_err("%s: unknown clockgen node %s\n", __func__, | 1369 | pr_err("%s: unknown clockgen node %pOF\n", __func__, np); |
1352 | np->full_name); | ||
1353 | goto err; | 1370 | goto err; |
1354 | } | 1371 | } |
1355 | clockgen.info = chipinfo[i]; | 1372 | clockgen.info = chipinfo[i]; |
@@ -1362,8 +1379,8 @@ static void __init clockgen_init(struct device_node *np) | |||
1362 | if (guts) { | 1379 | if (guts) { |
1363 | clockgen.guts = of_iomap(guts, 0); | 1380 | clockgen.guts = of_iomap(guts, 0); |
1364 | if (!clockgen.guts) { | 1381 | if (!clockgen.guts) { |
1365 | pr_err("%s: Couldn't map %s regs\n", __func__, | 1382 | pr_err("%s: Couldn't map %pOF regs\n", __func__, |
1366 | guts->full_name); | 1383 | guts); |
1367 | } | 1384 | } |
1368 | } | 1385 | } |
1369 | 1386 | ||
@@ -1398,6 +1415,7 @@ CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init); | |||
1398 | CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); | 1415 | CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); |
1399 | CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); | 1416 | CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); |
1400 | CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); | 1417 | CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); |
1418 | CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); | ||
1401 | CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); | 1419 | CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); |
1402 | 1420 | ||
1403 | /* Legacy nodes */ | 1421 | /* Legacy nodes */ |
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 2492442eea77..20d90769cced 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c | |||
@@ -519,6 +519,11 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
519 | SI5351_CLK_INTEGER_MODE, | 519 | SI5351_CLK_INTEGER_MODE, |
520 | (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); | 520 | (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); |
521 | 521 | ||
522 | /* Do a pll soft reset on the affected pll */ | ||
523 | si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, | ||
524 | hwdata->num == 0 ? SI5351_PLL_RESET_A : | ||
525 | SI5351_PLL_RESET_B); | ||
526 | |||
522 | dev_dbg(&hwdata->drvdata->client->dev, | 527 | dev_dbg(&hwdata->drvdata->client->dev, |
523 | "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", | 528 | "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", |
524 | __func__, clk_hw_get_name(hw), | 529 | __func__, clk_hw_get_name(hw), |
@@ -1091,13 +1096,6 @@ static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate, | |||
1091 | si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, | 1096 | si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, |
1092 | SI5351_CLK_POWERDOWN, 0); | 1097 | SI5351_CLK_POWERDOWN, 0); |
1093 | 1098 | ||
1094 | /* | ||
1095 | * Do a pll soft reset on both plls, needed in some cases to get | ||
1096 | * all outputs running. | ||
1097 | */ | ||
1098 | si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, | ||
1099 | SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); | ||
1100 | |||
1101 | dev_dbg(&hwdata->drvdata->client->dev, | 1099 | dev_dbg(&hwdata->drvdata->client->dev, |
1102 | "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", | 1100 | "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n", |
1103 | __func__, clk_hw_get_name(hw), (1 << rdiv), | 1101 | __func__, clk_hw_get_name(hw), (1 << rdiv), |
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 68e2a4e499f1..96c6b6bc8f0e 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c | |||
@@ -1541,8 +1541,8 @@ static void __init stm32f4_rcc_init(struct device_node *np) | |||
1541 | base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock); | 1541 | base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock); |
1542 | 1542 | ||
1543 | if (IS_ERR(clks[idx])) { | 1543 | if (IS_ERR(clks[idx])) { |
1544 | pr_err("%s: Unable to register leaf clock %s\n", | 1544 | pr_err("%pOF: Unable to register leaf clock %s\n", |
1545 | np->full_name, gd->name); | 1545 | np, gd->name); |
1546 | goto fail; | 1546 | goto fail; |
1547 | } | 1547 | } |
1548 | } | 1548 | } |
diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c new file mode 100644 index 000000000000..a94c3f56c590 --- /dev/null +++ b/drivers/clk/clk-stm32h7.c | |||
@@ -0,0 +1,1410 @@ | |||
1 | /* | ||
2 | * Copyright (C) Gabriel Fernandez 2017 | ||
3 | * Author: Gabriel Fernandez <gabriel.fernandez@st.com> | ||
4 | * | ||
5 | * License terms: GPL V2.0. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk.h> | ||
21 | #include <linux/clk-provider.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/mfd/syscon.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/of_address.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/regmap.h> | ||
30 | |||
31 | #include <dt-bindings/clock/stm32h7-clks.h> | ||
32 | |||
33 | /* Reset Clock Control Registers */ | ||
34 | #define RCC_CR 0x00 | ||
35 | #define RCC_CFGR 0x10 | ||
36 | #define RCC_D1CFGR 0x18 | ||
37 | #define RCC_D2CFGR 0x1C | ||
38 | #define RCC_D3CFGR 0x20 | ||
39 | #define RCC_PLLCKSELR 0x28 | ||
40 | #define RCC_PLLCFGR 0x2C | ||
41 | #define RCC_PLL1DIVR 0x30 | ||
42 | #define RCC_PLL1FRACR 0x34 | ||
43 | #define RCC_PLL2DIVR 0x38 | ||
44 | #define RCC_PLL2FRACR 0x3C | ||
45 | #define RCC_PLL3DIVR 0x40 | ||
46 | #define RCC_PLL3FRACR 0x44 | ||
47 | #define RCC_D1CCIPR 0x4C | ||
48 | #define RCC_D2CCIP1R 0x50 | ||
49 | #define RCC_D2CCIP2R 0x54 | ||
50 | #define RCC_D3CCIPR 0x58 | ||
51 | #define RCC_BDCR 0x70 | ||
52 | #define RCC_CSR 0x74 | ||
53 | #define RCC_AHB3ENR 0xD4 | ||
54 | #define RCC_AHB1ENR 0xD8 | ||
55 | #define RCC_AHB2ENR 0xDC | ||
56 | #define RCC_AHB4ENR 0xE0 | ||
57 | #define RCC_APB3ENR 0xE4 | ||
58 | #define RCC_APB1LENR 0xE8 | ||
59 | #define RCC_APB1HENR 0xEC | ||
60 | #define RCC_APB2ENR 0xF0 | ||
61 | #define RCC_APB4ENR 0xF4 | ||
62 | |||
63 | static DEFINE_SPINLOCK(stm32rcc_lock); | ||
64 | |||
65 | static void __iomem *base; | ||
66 | static struct clk_hw **hws; | ||
67 | |||
68 | /* System clock parent */ | ||
69 | static const char * const sys_src[] = { | ||
70 | "hsi_ck", "csi_ck", "hse_ck", "pll1_p" }; | ||
71 | |||
72 | static const char * const tracein_src[] = { | ||
73 | "hsi_ck", "csi_ck", "hse_ck", "pll1_r" }; | ||
74 | |||
75 | static const char * const per_src[] = { | ||
76 | "hsi_ker", "csi_ker", "hse_ck", "disabled" }; | ||
77 | |||
78 | static const char * const pll_src[] = { | ||
79 | "hsi_ck", "csi_ck", "hse_ck", "no clock" }; | ||
80 | |||
81 | static const char * const sdmmc_src[] = { "pll1_q", "pll2_r" }; | ||
82 | |||
83 | static const char * const dsi_src[] = { "ck_dsi_phy", "pll2_q" }; | ||
84 | |||
85 | static const char * const qspi_src[] = { | ||
86 | "hclk", "pll1_q", "pll2_r", "per_ck" }; | ||
87 | |||
88 | static const char * const fmc_src[] = { | ||
89 | "hclk", "pll1_q", "pll2_r", "per_ck" }; | ||
90 | |||
91 | /* Kernel clock parent */ | ||
92 | static const char * const swp_src[] = { "pclk1", "hsi_ker" }; | ||
93 | |||
94 | static const char * const fdcan_src[] = { "hse_ck", "pll1_q", "pll2_q" }; | ||
95 | |||
96 | static const char * const dfsdm1_src[] = { "pclk2", "sys_ck" }; | ||
97 | |||
98 | static const char * const spdifrx_src[] = { | ||
99 | "pll1_q", "pll2_r", "pll3_r", "hsi_ker" }; | ||
100 | |||
101 | static const char *spi_src1[5] = { | ||
102 | "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" }; | ||
103 | |||
104 | static const char * const spi_src2[] = { | ||
105 | "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" }; | ||
106 | |||
107 | static const char * const spi_src3[] = { | ||
108 | "pclk4", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" }; | ||
109 | |||
110 | static const char * const lptim_src1[] = { | ||
111 | "pclk1", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" }; | ||
112 | |||
113 | static const char * const lptim_src2[] = { | ||
114 | "pclk4", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" }; | ||
115 | |||
116 | static const char * const cec_src[] = {"lse_ck", "lsi_ck", "csi_ker_div122" }; | ||
117 | |||
118 | static const char * const usbotg_src[] = {"pll1_q", "pll3_q", "rc48_ck" }; | ||
119 | |||
120 | /* i2c 1,2,3 src */ | ||
121 | static const char * const i2c_src1[] = { | ||
122 | "pclk1", "pll3_r", "hsi_ker", "csi_ker" }; | ||
123 | |||
124 | static const char * const i2c_src2[] = { | ||
125 | "pclk4", "pll3_r", "hsi_ker", "csi_ker" }; | ||
126 | |||
127 | static const char * const rng_src[] = { | ||
128 | "rc48_ck", "pll1_q", "lse_ck", "lsi_ck" }; | ||
129 | |||
130 | /* usart 1,6 src */ | ||
131 | static const char * const usart_src1[] = { | ||
132 | "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" }; | ||
133 | |||
134 | /* usart 2,3,4,5,7,8 src */ | ||
135 | static const char * const usart_src2[] = { | ||
136 | "pclk1", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" }; | ||
137 | |||
138 | static const char *sai_src[5] = { | ||
139 | "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" }; | ||
140 | |||
141 | static const char * const adc_src[] = { "pll2_p", "pll3_r", "per_ck" }; | ||
142 | |||
143 | /* lptim 2,3,4,5 src */ | ||
144 | static const char * const lpuart1_src[] = { | ||
145 | "pclk3", "pll2_q", "pll3_q", "csi_ker", "lse_ck" }; | ||
146 | |||
147 | static const char * const hrtim_src[] = { "tim2_ker", "d1cpre" }; | ||
148 | |||
149 | /* RTC clock parent */ | ||
150 | static const char * const rtc_src[] = { "off", "lse_ck", "lsi_ck", "hse_1M" }; | ||
151 | |||
152 | /* Micro-controller output clock parent */ | ||
153 | static const char * const mco_src1[] = { | ||
154 | "hsi_ck", "lse_ck", "hse_ck", "pll1_q", "rc48_ck" }; | ||
155 | |||
156 | static const char * const mco_src2[] = { | ||
157 | "sys_ck", "pll2_p", "hse_ck", "pll1_p", "csi_ck", "lsi_ck" }; | ||
158 | |||
159 | /* LCD clock */ | ||
160 | static const char * const ltdc_src[] = {"pll3_r"}; | ||
161 | |||
162 | /* Gate clock with ready bit and backup domain management */ | ||
163 | struct stm32_ready_gate { | ||
164 | struct clk_gate gate; | ||
165 | u8 bit_rdy; | ||
166 | }; | ||
167 | |||
168 | #define to_ready_gate_clk(_rgate) container_of(_rgate, struct stm32_ready_gate,\ | ||
169 | gate) | ||
170 | |||
171 | #define RGATE_TIMEOUT 10000 | ||
172 | |||
173 | static int ready_gate_clk_enable(struct clk_hw *hw) | ||
174 | { | ||
175 | struct clk_gate *gate = to_clk_gate(hw); | ||
176 | struct stm32_ready_gate *rgate = to_ready_gate_clk(gate); | ||
177 | int bit_status; | ||
178 | unsigned int timeout = RGATE_TIMEOUT; | ||
179 | |||
180 | if (clk_gate_ops.is_enabled(hw)) | ||
181 | return 0; | ||
182 | |||
183 | clk_gate_ops.enable(hw); | ||
184 | |||
185 | /* We can't use readl_poll_timeout() because we can blocked if | ||
186 | * someone enables this clock before clocksource changes. | ||
187 | * Only jiffies counter is available. Jiffies are incremented by | ||
188 | * interruptions and enable op does not allow to be interrupted. | ||
189 | */ | ||
190 | do { | ||
191 | bit_status = !(readl(gate->reg) & BIT(rgate->bit_rdy)); | ||
192 | |||
193 | if (bit_status) | ||
194 | udelay(100); | ||
195 | |||
196 | } while (bit_status && --timeout); | ||
197 | |||
198 | return bit_status; | ||
199 | } | ||
200 | |||
201 | static void ready_gate_clk_disable(struct clk_hw *hw) | ||
202 | { | ||
203 | struct clk_gate *gate = to_clk_gate(hw); | ||
204 | struct stm32_ready_gate *rgate = to_ready_gate_clk(gate); | ||
205 | int bit_status; | ||
206 | unsigned int timeout = RGATE_TIMEOUT; | ||
207 | |||
208 | if (!clk_gate_ops.is_enabled(hw)) | ||
209 | return; | ||
210 | |||
211 | clk_gate_ops.disable(hw); | ||
212 | |||
213 | do { | ||
214 | bit_status = !!(readl(gate->reg) & BIT(rgate->bit_rdy)); | ||
215 | |||
216 | if (bit_status) | ||
217 | udelay(100); | ||
218 | |||
219 | } while (bit_status && --timeout); | ||
220 | } | ||
221 | |||
222 | static const struct clk_ops ready_gate_clk_ops = { | ||
223 | .enable = ready_gate_clk_enable, | ||
224 | .disable = ready_gate_clk_disable, | ||
225 | .is_enabled = clk_gate_is_enabled, | ||
226 | }; | ||
227 | |||
228 | static struct clk_hw *clk_register_ready_gate(struct device *dev, | ||
229 | const char *name, const char *parent_name, | ||
230 | void __iomem *reg, u8 bit_idx, u8 bit_rdy, | ||
231 | unsigned long flags, spinlock_t *lock) | ||
232 | { | ||
233 | struct stm32_ready_gate *rgate; | ||
234 | struct clk_init_data init = { NULL }; | ||
235 | struct clk_hw *hw; | ||
236 | int ret; | ||
237 | |||
238 | rgate = kzalloc(sizeof(*rgate), GFP_KERNEL); | ||
239 | if (!rgate) | ||
240 | return ERR_PTR(-ENOMEM); | ||
241 | |||
242 | init.name = name; | ||
243 | init.ops = &ready_gate_clk_ops; | ||
244 | init.flags = flags; | ||
245 | init.parent_names = &parent_name; | ||
246 | init.num_parents = 1; | ||
247 | |||
248 | rgate->bit_rdy = bit_rdy; | ||
249 | rgate->gate.lock = lock; | ||
250 | rgate->gate.reg = reg; | ||
251 | rgate->gate.bit_idx = bit_idx; | ||
252 | rgate->gate.hw.init = &init; | ||
253 | |||
254 | hw = &rgate->gate.hw; | ||
255 | ret = clk_hw_register(dev, hw); | ||
256 | if (ret) { | ||
257 | kfree(rgate); | ||
258 | hw = ERR_PTR(ret); | ||
259 | } | ||
260 | |||
261 | return hw; | ||
262 | } | ||
263 | |||
264 | struct gate_cfg { | ||
265 | u32 offset; | ||
266 | u8 bit_idx; | ||
267 | }; | ||
268 | |||
269 | struct muxdiv_cfg { | ||
270 | u32 offset; | ||
271 | u8 shift; | ||
272 | u8 width; | ||
273 | }; | ||
274 | |||
275 | struct composite_clk_cfg { | ||
276 | struct gate_cfg *gate; | ||
277 | struct muxdiv_cfg *mux; | ||
278 | struct muxdiv_cfg *div; | ||
279 | const char *name; | ||
280 | const char * const *parent_name; | ||
281 | int num_parents; | ||
282 | u32 flags; | ||
283 | }; | ||
284 | |||
285 | struct composite_clk_gcfg_t { | ||
286 | u8 flags; | ||
287 | const struct clk_ops *ops; | ||
288 | }; | ||
289 | |||
290 | /* | ||
291 | * General config definition of a composite clock (only clock diviser for rate) | ||
292 | */ | ||
293 | struct composite_clk_gcfg { | ||
294 | struct composite_clk_gcfg_t *mux; | ||
295 | struct composite_clk_gcfg_t *div; | ||
296 | struct composite_clk_gcfg_t *gate; | ||
297 | }; | ||
298 | |||
299 | #define M_CFG_MUX(_mux_ops, _mux_flags)\ | ||
300 | .mux = &(struct composite_clk_gcfg_t) { _mux_flags, _mux_ops} | ||
301 | |||
302 | #define M_CFG_DIV(_rate_ops, _rate_flags)\ | ||
303 | .div = &(struct composite_clk_gcfg_t) {_rate_flags, _rate_ops} | ||
304 | |||
305 | #define M_CFG_GATE(_gate_ops, _gate_flags)\ | ||
306 | .gate = &(struct composite_clk_gcfg_t) { _gate_flags, _gate_ops} | ||
307 | |||
308 | static struct clk_mux *_get_cmux(void __iomem *reg, u8 shift, u8 width, | ||
309 | u32 flags, spinlock_t *lock) | ||
310 | { | ||
311 | struct clk_mux *mux; | ||
312 | |||
313 | mux = kzalloc(sizeof(*mux), GFP_KERNEL); | ||
314 | if (!mux) | ||
315 | return ERR_PTR(-ENOMEM); | ||
316 | |||
317 | mux->reg = reg; | ||
318 | mux->shift = shift; | ||
319 | mux->mask = (1 << width) - 1; | ||
320 | mux->flags = flags; | ||
321 | mux->lock = lock; | ||
322 | |||
323 | return mux; | ||
324 | } | ||
325 | |||
326 | static struct clk_divider *_get_cdiv(void __iomem *reg, u8 shift, u8 width, | ||
327 | u32 flags, spinlock_t *lock) | ||
328 | { | ||
329 | struct clk_divider *div; | ||
330 | |||
331 | div = kzalloc(sizeof(*div), GFP_KERNEL); | ||
332 | |||
333 | if (!div) | ||
334 | return ERR_PTR(-ENOMEM); | ||
335 | |||
336 | div->reg = reg; | ||
337 | div->shift = shift; | ||
338 | div->width = width; | ||
339 | div->flags = flags; | ||
340 | div->lock = lock; | ||
341 | |||
342 | return div; | ||
343 | } | ||
344 | |||
345 | static struct clk_gate *_get_cgate(void __iomem *reg, u8 bit_idx, u32 flags, | ||
346 | spinlock_t *lock) | ||
347 | { | ||
348 | struct clk_gate *gate; | ||
349 | |||
350 | gate = kzalloc(sizeof(*gate), GFP_KERNEL); | ||
351 | if (!gate) | ||
352 | return ERR_PTR(-ENOMEM); | ||
353 | |||
354 | gate->reg = reg; | ||
355 | gate->bit_idx = bit_idx; | ||
356 | gate->flags = flags; | ||
357 | gate->lock = lock; | ||
358 | |||
359 | return gate; | ||
360 | } | ||
361 | |||
362 | struct composite_cfg { | ||
363 | struct clk_hw *mux_hw; | ||
364 | struct clk_hw *div_hw; | ||
365 | struct clk_hw *gate_hw; | ||
366 | |||
367 | const struct clk_ops *mux_ops; | ||
368 | const struct clk_ops *div_ops; | ||
369 | const struct clk_ops *gate_ops; | ||
370 | }; | ||
371 | |||
372 | static void get_cfg_composite_div(const struct composite_clk_gcfg *gcfg, | ||
373 | const struct composite_clk_cfg *cfg, | ||
374 | struct composite_cfg *composite, spinlock_t *lock) | ||
375 | { | ||
376 | struct clk_mux *mux = NULL; | ||
377 | struct clk_divider *div = NULL; | ||
378 | struct clk_gate *gate = NULL; | ||
379 | const struct clk_ops *mux_ops, *div_ops, *gate_ops; | ||
380 | struct clk_hw *mux_hw; | ||
381 | struct clk_hw *div_hw; | ||
382 | struct clk_hw *gate_hw; | ||
383 | |||
384 | mux_ops = div_ops = gate_ops = NULL; | ||
385 | mux_hw = div_hw = gate_hw = NULL; | ||
386 | |||
387 | if (gcfg->mux && gcfg->mux) { | ||
388 | mux = _get_cmux(base + cfg->mux->offset, | ||
389 | cfg->mux->shift, | ||
390 | cfg->mux->width, | ||
391 | gcfg->mux->flags, lock); | ||
392 | |||
393 | if (!IS_ERR(mux)) { | ||
394 | mux_hw = &mux->hw; | ||
395 | mux_ops = gcfg->mux->ops ? | ||
396 | gcfg->mux->ops : &clk_mux_ops; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | if (gcfg->div && cfg->div) { | ||
401 | div = _get_cdiv(base + cfg->div->offset, | ||
402 | cfg->div->shift, | ||
403 | cfg->div->width, | ||
404 | gcfg->div->flags, lock); | ||
405 | |||
406 | if (!IS_ERR(div)) { | ||
407 | div_hw = &div->hw; | ||
408 | div_ops = gcfg->div->ops ? | ||
409 | gcfg->div->ops : &clk_divider_ops; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | if (gcfg->gate && gcfg->gate) { | ||
414 | gate = _get_cgate(base + cfg->gate->offset, | ||
415 | cfg->gate->bit_idx, | ||
416 | gcfg->gate->flags, lock); | ||
417 | |||
418 | if (!IS_ERR(gate)) { | ||
419 | gate_hw = &gate->hw; | ||
420 | gate_ops = gcfg->gate->ops ? | ||
421 | gcfg->gate->ops : &clk_gate_ops; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | composite->mux_hw = mux_hw; | ||
426 | composite->mux_ops = mux_ops; | ||
427 | |||
428 | composite->div_hw = div_hw; | ||
429 | composite->div_ops = div_ops; | ||
430 | |||
431 | composite->gate_hw = gate_hw; | ||
432 | composite->gate_ops = gate_ops; | ||
433 | } | ||
434 | |||
435 | /* Kernel Timer */ | ||
436 | struct timer_ker { | ||
437 | u8 dppre_shift; | ||
438 | struct clk_hw hw; | ||
439 | spinlock_t *lock; | ||
440 | }; | ||
441 | |||
442 | #define to_timer_ker(_hw) container_of(_hw, struct timer_ker, hw) | ||
443 | |||
444 | static unsigned long timer_ker_recalc_rate(struct clk_hw *hw, | ||
445 | unsigned long parent_rate) | ||
446 | { | ||
447 | struct timer_ker *clk_elem = to_timer_ker(hw); | ||
448 | u32 timpre; | ||
449 | u32 dppre_shift = clk_elem->dppre_shift; | ||
450 | u32 prescaler; | ||
451 | u32 mul; | ||
452 | |||
453 | timpre = (readl(base + RCC_CFGR) >> 15) & 0x01; | ||
454 | |||
455 | prescaler = (readl(base + RCC_D2CFGR) >> dppre_shift) & 0x03; | ||
456 | |||
457 | mul = 2; | ||
458 | |||
459 | if (prescaler < 4) | ||
460 | mul = 1; | ||
461 | |||
462 | else if (timpre && prescaler > 4) | ||
463 | mul = 4; | ||
464 | |||
465 | return parent_rate * mul; | ||
466 | } | ||
467 | |||
468 | static const struct clk_ops timer_ker_ops = { | ||
469 | .recalc_rate = timer_ker_recalc_rate, | ||
470 | }; | ||
471 | |||
472 | static struct clk_hw *clk_register_stm32_timer_ker(struct device *dev, | ||
473 | const char *name, const char *parent_name, | ||
474 | unsigned long flags, | ||
475 | u8 dppre_shift, | ||
476 | spinlock_t *lock) | ||
477 | { | ||
478 | struct timer_ker *element; | ||
479 | struct clk_init_data init; | ||
480 | struct clk_hw *hw; | ||
481 | int err; | ||
482 | |||
483 | element = kzalloc(sizeof(*element), GFP_KERNEL); | ||
484 | if (!element) | ||
485 | return ERR_PTR(-ENOMEM); | ||
486 | |||
487 | init.name = name; | ||
488 | init.ops = &timer_ker_ops; | ||
489 | init.flags = flags; | ||
490 | init.parent_names = &parent_name; | ||
491 | init.num_parents = 1; | ||
492 | |||
493 | element->hw.init = &init; | ||
494 | element->lock = lock; | ||
495 | element->dppre_shift = dppre_shift; | ||
496 | |||
497 | hw = &element->hw; | ||
498 | err = clk_hw_register(dev, hw); | ||
499 | |||
500 | if (err) { | ||
501 | kfree(element); | ||
502 | return ERR_PTR(err); | ||
503 | } | ||
504 | |||
505 | return hw; | ||
506 | } | ||
507 | |||
508 | static const struct clk_div_table d1cpre_div_table[] = { | ||
509 | { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1}, | ||
510 | { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1}, | ||
511 | { 8, 2 }, { 9, 4 }, { 10, 8 }, { 11, 16 }, | ||
512 | { 12, 64 }, { 13, 128 }, { 14, 256 }, | ||
513 | { 15, 512 }, | ||
514 | { 0 }, | ||
515 | }; | ||
516 | |||
517 | static const struct clk_div_table ppre_div_table[] = { | ||
518 | { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1}, | ||
519 | { 4, 2 }, { 5, 4 }, { 6, 8 }, { 7, 16 }, | ||
520 | { 0 }, | ||
521 | }; | ||
522 | |||
523 | static void register_core_and_bus_clocks(void) | ||
524 | { | ||
525 | /* CORE AND BUS */ | ||
526 | hws[SYS_D1CPRE] = clk_hw_register_divider_table(NULL, "d1cpre", | ||
527 | "sys_ck", CLK_IGNORE_UNUSED, base + RCC_D1CFGR, 8, 4, 0, | ||
528 | d1cpre_div_table, &stm32rcc_lock); | ||
529 | |||
530 | hws[HCLK] = clk_hw_register_divider_table(NULL, "hclk", "d1cpre", | ||
531 | CLK_IGNORE_UNUSED, base + RCC_D1CFGR, 0, 4, 0, | ||
532 | d1cpre_div_table, &stm32rcc_lock); | ||
533 | |||
534 | /* D1 DOMAIN */ | ||
535 | /* * CPU Systick */ | ||
536 | hws[CPU_SYSTICK] = clk_hw_register_fixed_factor(NULL, "systick", | ||
537 | "d1cpre", 0, 1, 8); | ||
538 | |||
539 | /* * APB3 peripheral */ | ||
540 | hws[PCLK3] = clk_hw_register_divider_table(NULL, "pclk3", "hclk", 0, | ||
541 | base + RCC_D1CFGR, 4, 3, 0, | ||
542 | ppre_div_table, &stm32rcc_lock); | ||
543 | |||
544 | /* D2 DOMAIN */ | ||
545 | /* * APB1 peripheral */ | ||
546 | hws[PCLK1] = clk_hw_register_divider_table(NULL, "pclk1", "hclk", 0, | ||
547 | base + RCC_D2CFGR, 4, 3, 0, | ||
548 | ppre_div_table, &stm32rcc_lock); | ||
549 | |||
550 | /* Timers prescaler clocks */ | ||
551 | clk_register_stm32_timer_ker(NULL, "tim1_ker", "pclk1", 0, | ||
552 | 4, &stm32rcc_lock); | ||
553 | |||
554 | /* * APB2 peripheral */ | ||
555 | hws[PCLK2] = clk_hw_register_divider_table(NULL, "pclk2", "hclk", 0, | ||
556 | base + RCC_D2CFGR, 8, 3, 0, ppre_div_table, | ||
557 | &stm32rcc_lock); | ||
558 | |||
559 | clk_register_stm32_timer_ker(NULL, "tim2_ker", "pclk2", 0, 8, | ||
560 | &stm32rcc_lock); | ||
561 | |||
562 | /* D3 DOMAIN */ | ||
563 | /* * APB4 peripheral */ | ||
564 | hws[PCLK4] = clk_hw_register_divider_table(NULL, "pclk4", "hclk", 0, | ||
565 | base + RCC_D3CFGR, 4, 3, 0, | ||
566 | ppre_div_table, &stm32rcc_lock); | ||
567 | } | ||
568 | |||
569 | /* MUX clock configuration */ | ||
570 | struct stm32_mux_clk { | ||
571 | const char *name; | ||
572 | const char * const *parents; | ||
573 | u8 num_parents; | ||
574 | u32 offset; | ||
575 | u8 shift; | ||
576 | u8 width; | ||
577 | u32 flags; | ||
578 | }; | ||
579 | |||
580 | #define M_MCLOCF(_name, _parents, _mux_offset, _mux_shift, _mux_width, _flags)\ | ||
581 | {\ | ||
582 | .name = _name,\ | ||
583 | .parents = _parents,\ | ||
584 | .num_parents = ARRAY_SIZE(_parents),\ | ||
585 | .offset = _mux_offset,\ | ||
586 | .shift = _mux_shift,\ | ||
587 | .width = _mux_width,\ | ||
588 | .flags = _flags,\ | ||
589 | } | ||
590 | |||
591 | #define M_MCLOC(_name, _parents, _mux_offset, _mux_shift, _mux_width)\ | ||
592 | M_MCLOCF(_name, _parents, _mux_offset, _mux_shift, _mux_width, 0)\ | ||
593 | |||
594 | static const struct stm32_mux_clk stm32_mclk[] __initconst = { | ||
595 | M_MCLOC("per_ck", per_src, RCC_D1CCIPR, 28, 3), | ||
596 | M_MCLOC("pllsrc", pll_src, RCC_PLLCKSELR, 0, 3), | ||
597 | M_MCLOC("sys_ck", sys_src, RCC_CFGR, 0, 3), | ||
598 | M_MCLOC("tracein_ck", tracein_src, RCC_CFGR, 0, 3), | ||
599 | }; | ||
600 | |||
601 | /* Oscillary clock configuration */ | ||
602 | struct stm32_osc_clk { | ||
603 | const char *name; | ||
604 | const char *parent; | ||
605 | u32 gate_offset; | ||
606 | u8 bit_idx; | ||
607 | u8 bit_rdy; | ||
608 | u32 flags; | ||
609 | }; | ||
610 | |||
611 | #define OSC_CLKF(_name, _parent, _gate_offset, _bit_idx, _bit_rdy, _flags)\ | ||
612 | {\ | ||
613 | .name = _name,\ | ||
614 | .parent = _parent,\ | ||
615 | .gate_offset = _gate_offset,\ | ||
616 | .bit_idx = _bit_idx,\ | ||
617 | .bit_rdy = _bit_rdy,\ | ||
618 | .flags = _flags,\ | ||
619 | } | ||
620 | |||
621 | #define OSC_CLK(_name, _parent, _gate_offset, _bit_idx, _bit_rdy)\ | ||
622 | OSC_CLKF(_name, _parent, _gate_offset, _bit_idx, _bit_rdy, 0) | ||
623 | |||
624 | static const struct stm32_osc_clk stm32_oclk[] __initconst = { | ||
625 | OSC_CLKF("hsi_ck", "hsidiv", RCC_CR, 0, 2, CLK_IGNORE_UNUSED), | ||
626 | OSC_CLKF("hsi_ker", "hsidiv", RCC_CR, 1, 2, CLK_IGNORE_UNUSED), | ||
627 | OSC_CLKF("csi_ck", "clk-csi", RCC_CR, 7, 8, CLK_IGNORE_UNUSED), | ||
628 | OSC_CLKF("csi_ker", "clk-csi", RCC_CR, 9, 8, CLK_IGNORE_UNUSED), | ||
629 | OSC_CLKF("rc48_ck", "clk-rc48", RCC_CR, 12, 13, CLK_IGNORE_UNUSED), | ||
630 | OSC_CLKF("lsi_ck", "clk-lsi", RCC_CSR, 0, 1, CLK_IGNORE_UNUSED), | ||
631 | }; | ||
632 | |||
633 | /* PLL configuration */ | ||
634 | struct st32h7_pll_cfg { | ||
635 | u8 bit_idx; | ||
636 | u32 offset_divr; | ||
637 | u8 bit_frac_en; | ||
638 | u32 offset_frac; | ||
639 | u8 divm; | ||
640 | }; | ||
641 | |||
642 | struct stm32_pll_data { | ||
643 | const char *name; | ||
644 | const char *parent_name; | ||
645 | unsigned long flags; | ||
646 | const struct st32h7_pll_cfg *cfg; | ||
647 | }; | ||
648 | |||
649 | static const struct st32h7_pll_cfg stm32h7_pll1 = { | ||
650 | .bit_idx = 24, | ||
651 | .offset_divr = RCC_PLL1DIVR, | ||
652 | .bit_frac_en = 0, | ||
653 | .offset_frac = RCC_PLL1FRACR, | ||
654 | .divm = 4, | ||
655 | }; | ||
656 | |||
657 | static const struct st32h7_pll_cfg stm32h7_pll2 = { | ||
658 | .bit_idx = 26, | ||
659 | .offset_divr = RCC_PLL2DIVR, | ||
660 | .bit_frac_en = 4, | ||
661 | .offset_frac = RCC_PLL2FRACR, | ||
662 | .divm = 12, | ||
663 | }; | ||
664 | |||
665 | static const struct st32h7_pll_cfg stm32h7_pll3 = { | ||
666 | .bit_idx = 28, | ||
667 | .offset_divr = RCC_PLL3DIVR, | ||
668 | .bit_frac_en = 8, | ||
669 | .offset_frac = RCC_PLL3FRACR, | ||
670 | .divm = 20, | ||
671 | }; | ||
672 | |||
673 | static const struct stm32_pll_data stm32_pll[] = { | ||
674 | { "vco1", "pllsrc", CLK_IGNORE_UNUSED, &stm32h7_pll1 }, | ||
675 | { "vco2", "pllsrc", 0, &stm32h7_pll2 }, | ||
676 | { "vco3", "pllsrc", 0, &stm32h7_pll3 }, | ||
677 | }; | ||
678 | |||
679 | struct stm32_fractional_divider { | ||
680 | void __iomem *mreg; | ||
681 | u8 mshift; | ||
682 | u8 mwidth; | ||
683 | u32 mmask; | ||
684 | |||
685 | void __iomem *nreg; | ||
686 | u8 nshift; | ||
687 | u8 nwidth; | ||
688 | |||
689 | void __iomem *freg_status; | ||
690 | u8 freg_bit; | ||
691 | void __iomem *freg_value; | ||
692 | u8 fshift; | ||
693 | u8 fwidth; | ||
694 | |||
695 | u8 flags; | ||
696 | struct clk_hw hw; | ||
697 | spinlock_t *lock; | ||
698 | }; | ||
699 | |||
700 | struct stm32_pll_obj { | ||
701 | spinlock_t *lock; | ||
702 | struct stm32_fractional_divider div; | ||
703 | struct stm32_ready_gate rgate; | ||
704 | struct clk_hw hw; | ||
705 | }; | ||
706 | |||
707 | #define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw) | ||
708 | |||
709 | static int pll_is_enabled(struct clk_hw *hw) | ||
710 | { | ||
711 | struct stm32_pll_obj *clk_elem = to_pll(hw); | ||
712 | struct clk_hw *_hw = &clk_elem->rgate.gate.hw; | ||
713 | |||
714 | __clk_hw_set_clk(_hw, hw); | ||
715 | |||
716 | return ready_gate_clk_ops.is_enabled(_hw); | ||
717 | } | ||
718 | |||
719 | static int pll_enable(struct clk_hw *hw) | ||
720 | { | ||
721 | struct stm32_pll_obj *clk_elem = to_pll(hw); | ||
722 | struct clk_hw *_hw = &clk_elem->rgate.gate.hw; | ||
723 | |||
724 | __clk_hw_set_clk(_hw, hw); | ||
725 | |||
726 | return ready_gate_clk_ops.enable(_hw); | ||
727 | } | ||
728 | |||
729 | static void pll_disable(struct clk_hw *hw) | ||
730 | { | ||
731 | struct stm32_pll_obj *clk_elem = to_pll(hw); | ||
732 | struct clk_hw *_hw = &clk_elem->rgate.gate.hw; | ||
733 | |||
734 | __clk_hw_set_clk(_hw, hw); | ||
735 | |||
736 | ready_gate_clk_ops.disable(_hw); | ||
737 | } | ||
738 | |||
739 | static int pll_frac_is_enabled(struct clk_hw *hw) | ||
740 | { | ||
741 | struct stm32_pll_obj *clk_elem = to_pll(hw); | ||
742 | struct stm32_fractional_divider *fd = &clk_elem->div; | ||
743 | |||
744 | return (readl(fd->freg_status) >> fd->freg_bit) & 0x01; | ||
745 | } | ||
746 | |||
747 | static unsigned long pll_read_frac(struct clk_hw *hw) | ||
748 | { | ||
749 | struct stm32_pll_obj *clk_elem = to_pll(hw); | ||
750 | struct stm32_fractional_divider *fd = &clk_elem->div; | ||
751 | |||
752 | return (readl(fd->freg_value) >> fd->fshift) & | ||
753 | GENMASK(fd->fwidth - 1, 0); | ||
754 | } | ||
755 | |||
756 | static unsigned long pll_fd_recalc_rate(struct clk_hw *hw, | ||
757 | unsigned long parent_rate) | ||
758 | { | ||
759 | struct stm32_pll_obj *clk_elem = to_pll(hw); | ||
760 | struct stm32_fractional_divider *fd = &clk_elem->div; | ||
761 | unsigned long m, n; | ||
762 | u32 val, mask; | ||
763 | u64 rate, rate1 = 0; | ||
764 | |||
765 | val = readl(fd->mreg); | ||
766 | mask = GENMASK(fd->mwidth - 1, 0) << fd->mshift; | ||
767 | m = (val & mask) >> fd->mshift; | ||
768 | |||
769 | val = readl(fd->nreg); | ||
770 | mask = GENMASK(fd->nwidth - 1, 0) << fd->nshift; | ||
771 | n = ((val & mask) >> fd->nshift) + 1; | ||
772 | |||
773 | if (!n || !m) | ||
774 | return parent_rate; | ||
775 | |||
776 | rate = (u64)parent_rate * n; | ||
777 | do_div(rate, m); | ||
778 | |||
779 | if (pll_frac_is_enabled(hw)) { | ||
780 | val = pll_read_frac(hw); | ||
781 | rate1 = (u64)parent_rate * (u64)val; | ||
782 | do_div(rate1, (m * 8191)); | ||
783 | } | ||
784 | |||
785 | return rate + rate1; | ||
786 | } | ||
787 | |||
788 | static const struct clk_ops pll_ops = { | ||
789 | .enable = pll_enable, | ||
790 | .disable = pll_disable, | ||
791 | .is_enabled = pll_is_enabled, | ||
792 | .recalc_rate = pll_fd_recalc_rate, | ||
793 | }; | ||
794 | |||
795 | static struct clk_hw *clk_register_stm32_pll(struct device *dev, | ||
796 | const char *name, | ||
797 | const char *parent, | ||
798 | unsigned long flags, | ||
799 | const struct st32h7_pll_cfg *cfg, | ||
800 | spinlock_t *lock) | ||
801 | { | ||
802 | struct stm32_pll_obj *pll; | ||
803 | struct clk_init_data init = { NULL }; | ||
804 | struct clk_hw *hw; | ||
805 | int ret; | ||
806 | struct stm32_fractional_divider *div = NULL; | ||
807 | struct stm32_ready_gate *rgate; | ||
808 | |||
809 | pll = kzalloc(sizeof(*pll), GFP_KERNEL); | ||
810 | if (!pll) | ||
811 | return ERR_PTR(-ENOMEM); | ||
812 | |||
813 | init.name = name; | ||
814 | init.ops = &pll_ops; | ||
815 | init.flags = flags; | ||
816 | init.parent_names = &parent; | ||
817 | init.num_parents = 1; | ||
818 | pll->hw.init = &init; | ||
819 | |||
820 | hw = &pll->hw; | ||
821 | rgate = &pll->rgate; | ||
822 | |||
823 | rgate->bit_rdy = cfg->bit_idx + 1; | ||
824 | rgate->gate.lock = lock; | ||
825 | rgate->gate.reg = base + RCC_CR; | ||
826 | rgate->gate.bit_idx = cfg->bit_idx; | ||
827 | |||
828 | div = &pll->div; | ||
829 | div->flags = 0; | ||
830 | div->mreg = base + RCC_PLLCKSELR; | ||
831 | div->mshift = cfg->divm; | ||
832 | div->mwidth = 6; | ||
833 | div->nreg = base + cfg->offset_divr; | ||
834 | div->nshift = 0; | ||
835 | div->nwidth = 9; | ||
836 | |||
837 | div->freg_status = base + RCC_PLLCFGR; | ||
838 | div->freg_bit = cfg->bit_frac_en; | ||
839 | div->freg_value = base + cfg->offset_frac; | ||
840 | div->fshift = 3; | ||
841 | div->fwidth = 13; | ||
842 | |||
843 | div->lock = lock; | ||
844 | |||
845 | ret = clk_hw_register(dev, hw); | ||
846 | if (ret) { | ||
847 | kfree(pll); | ||
848 | hw = ERR_PTR(ret); | ||
849 | } | ||
850 | |||
851 | return hw; | ||
852 | } | ||
853 | |||
854 | /* ODF CLOCKS */ | ||
855 | static unsigned long odf_divider_recalc_rate(struct clk_hw *hw, | ||
856 | unsigned long parent_rate) | ||
857 | { | ||
858 | return clk_divider_ops.recalc_rate(hw, parent_rate); | ||
859 | } | ||
860 | |||
861 | static long odf_divider_round_rate(struct clk_hw *hw, unsigned long rate, | ||
862 | unsigned long *prate) | ||
863 | { | ||
864 | return clk_divider_ops.round_rate(hw, rate, prate); | ||
865 | } | ||
866 | |||
867 | static int odf_divider_set_rate(struct clk_hw *hw, unsigned long rate, | ||
868 | unsigned long parent_rate) | ||
869 | { | ||
870 | struct clk_hw *hwp; | ||
871 | int pll_status; | ||
872 | int ret; | ||
873 | |||
874 | hwp = clk_hw_get_parent(hw); | ||
875 | |||
876 | pll_status = pll_is_enabled(hwp); | ||
877 | |||
878 | if (pll_status) | ||
879 | pll_disable(hwp); | ||
880 | |||
881 | ret = clk_divider_ops.set_rate(hw, rate, parent_rate); | ||
882 | |||
883 | if (pll_status) | ||
884 | pll_enable(hwp); | ||
885 | |||
886 | return ret; | ||
887 | } | ||
888 | |||
889 | static const struct clk_ops odf_divider_ops = { | ||
890 | .recalc_rate = odf_divider_recalc_rate, | ||
891 | .round_rate = odf_divider_round_rate, | ||
892 | .set_rate = odf_divider_set_rate, | ||
893 | }; | ||
894 | |||
895 | static int odf_gate_enable(struct clk_hw *hw) | ||
896 | { | ||
897 | struct clk_hw *hwp; | ||
898 | int pll_status; | ||
899 | int ret; | ||
900 | |||
901 | if (clk_gate_ops.is_enabled(hw)) | ||
902 | return 0; | ||
903 | |||
904 | hwp = clk_hw_get_parent(hw); | ||
905 | |||
906 | pll_status = pll_is_enabled(hwp); | ||
907 | |||
908 | if (pll_status) | ||
909 | pll_disable(hwp); | ||
910 | |||
911 | ret = clk_gate_ops.enable(hw); | ||
912 | |||
913 | if (pll_status) | ||
914 | pll_enable(hwp); | ||
915 | |||
916 | return ret; | ||
917 | } | ||
918 | |||
919 | static void odf_gate_disable(struct clk_hw *hw) | ||
920 | { | ||
921 | struct clk_hw *hwp; | ||
922 | int pll_status; | ||
923 | |||
924 | if (!clk_gate_ops.is_enabled(hw)) | ||
925 | return; | ||
926 | |||
927 | hwp = clk_hw_get_parent(hw); | ||
928 | |||
929 | pll_status = pll_is_enabled(hwp); | ||
930 | |||
931 | if (pll_status) | ||
932 | pll_disable(hwp); | ||
933 | |||
934 | clk_gate_ops.disable(hw); | ||
935 | |||
936 | if (pll_status) | ||
937 | pll_enable(hwp); | ||
938 | } | ||
939 | |||
940 | static const struct clk_ops odf_gate_ops = { | ||
941 | .enable = odf_gate_enable, | ||
942 | .disable = odf_gate_disable, | ||
943 | .is_enabled = clk_gate_is_enabled, | ||
944 | }; | ||
945 | |||
946 | static struct composite_clk_gcfg odf_clk_gcfg = { | ||
947 | M_CFG_DIV(&odf_divider_ops, 0), | ||
948 | M_CFG_GATE(&odf_gate_ops, 0), | ||
949 | }; | ||
950 | |||
951 | #define M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\ | ||
952 | _rate_shift, _rate_width, _flags)\ | ||
953 | {\ | ||
954 | .mux = NULL,\ | ||
955 | .div = &(struct muxdiv_cfg) {_rate_offset, _rate_shift, _rate_width},\ | ||
956 | .gate = &(struct gate_cfg) {_gate_offset, _bit_idx },\ | ||
957 | .name = _name,\ | ||
958 | .parent_name = &(const char *) {_parent},\ | ||
959 | .num_parents = 1,\ | ||
960 | .flags = _flags,\ | ||
961 | } | ||
962 | |||
963 | #define M_ODF(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\ | ||
964 | _rate_shift, _rate_width)\ | ||
965 | M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\ | ||
966 | _rate_shift, _rate_width, 0)\ | ||
967 | |||
968 | static const struct composite_clk_cfg stm32_odf[3][3] = { | ||
969 | { | ||
970 | M_ODF_F("pll1_p", "vco1", RCC_PLLCFGR, 16, RCC_PLL1DIVR, 9, 7, | ||
971 | CLK_IGNORE_UNUSED), | ||
972 | M_ODF_F("pll1_q", "vco1", RCC_PLLCFGR, 17, RCC_PLL1DIVR, 16, 7, | ||
973 | CLK_IGNORE_UNUSED), | ||
974 | M_ODF_F("pll1_r", "vco1", RCC_PLLCFGR, 18, RCC_PLL1DIVR, 24, 7, | ||
975 | CLK_IGNORE_UNUSED), | ||
976 | }, | ||
977 | |||
978 | { | ||
979 | M_ODF("pll2_p", "vco2", RCC_PLLCFGR, 19, RCC_PLL2DIVR, 9, 7), | ||
980 | M_ODF("pll2_q", "vco2", RCC_PLLCFGR, 20, RCC_PLL2DIVR, 16, 7), | ||
981 | M_ODF("pll2_r", "vco2", RCC_PLLCFGR, 21, RCC_PLL2DIVR, 24, 7), | ||
982 | }, | ||
983 | { | ||
984 | M_ODF("pll3_p", "vco3", RCC_PLLCFGR, 22, RCC_PLL3DIVR, 9, 7), | ||
985 | M_ODF("pll3_q", "vco3", RCC_PLLCFGR, 23, RCC_PLL3DIVR, 16, 7), | ||
986 | M_ODF("pll3_r", "vco3", RCC_PLLCFGR, 24, RCC_PLL3DIVR, 24, 7), | ||
987 | } | ||
988 | }; | ||
989 | |||
990 | /* PERIF CLOCKS */ | ||
991 | struct pclk_t { | ||
992 | u32 gate_offset; | ||
993 | u8 bit_idx; | ||
994 | const char *name; | ||
995 | const char *parent; | ||
996 | u32 flags; | ||
997 | }; | ||
998 | |||
999 | #define PER_CLKF(_gate_offset, _bit_idx, _name, _parent, _flags)\ | ||
1000 | {\ | ||
1001 | .gate_offset = _gate_offset,\ | ||
1002 | .bit_idx = _bit_idx,\ | ||
1003 | .name = _name,\ | ||
1004 | .parent = _parent,\ | ||
1005 | .flags = _flags,\ | ||
1006 | } | ||
1007 | |||
1008 | #define PER_CLK(_gate_offset, _bit_idx, _name, _parent)\ | ||
1009 | PER_CLKF(_gate_offset, _bit_idx, _name, _parent, 0) | ||
1010 | |||
1011 | static const struct pclk_t pclk[] = { | ||
1012 | PER_CLK(RCC_AHB3ENR, 31, "d1sram1", "hclk"), | ||
1013 | PER_CLK(RCC_AHB3ENR, 30, "itcm", "hclk"), | ||
1014 | PER_CLK(RCC_AHB3ENR, 29, "dtcm2", "hclk"), | ||
1015 | PER_CLK(RCC_AHB3ENR, 28, "dtcm1", "hclk"), | ||
1016 | PER_CLK(RCC_AHB3ENR, 8, "flitf", "hclk"), | ||
1017 | PER_CLK(RCC_AHB3ENR, 5, "jpgdec", "hclk"), | ||
1018 | PER_CLK(RCC_AHB3ENR, 4, "dma2d", "hclk"), | ||
1019 | PER_CLK(RCC_AHB3ENR, 0, "mdma", "hclk"), | ||
1020 | PER_CLK(RCC_AHB1ENR, 28, "usb2ulpi", "hclk"), | ||
1021 | PER_CLK(RCC_AHB1ENR, 26, "usb1ulpi", "hclk"), | ||
1022 | PER_CLK(RCC_AHB1ENR, 17, "eth1rx", "hclk"), | ||
1023 | PER_CLK(RCC_AHB1ENR, 16, "eth1tx", "hclk"), | ||
1024 | PER_CLK(RCC_AHB1ENR, 15, "eth1mac", "hclk"), | ||
1025 | PER_CLK(RCC_AHB1ENR, 14, "art", "hclk"), | ||
1026 | PER_CLK(RCC_AHB1ENR, 1, "dma2", "hclk"), | ||
1027 | PER_CLK(RCC_AHB1ENR, 0, "dma1", "hclk"), | ||
1028 | PER_CLK(RCC_AHB2ENR, 31, "d2sram3", "hclk"), | ||
1029 | PER_CLK(RCC_AHB2ENR, 30, "d2sram2", "hclk"), | ||
1030 | PER_CLK(RCC_AHB2ENR, 29, "d2sram1", "hclk"), | ||
1031 | PER_CLK(RCC_AHB2ENR, 5, "hash", "hclk"), | ||
1032 | PER_CLK(RCC_AHB2ENR, 4, "crypt", "hclk"), | ||
1033 | PER_CLK(RCC_AHB2ENR, 0, "camitf", "hclk"), | ||
1034 | PER_CLK(RCC_AHB4ENR, 28, "bkpram", "hclk"), | ||
1035 | PER_CLK(RCC_AHB4ENR, 25, "hsem", "hclk"), | ||
1036 | PER_CLK(RCC_AHB4ENR, 21, "bdma", "hclk"), | ||
1037 | PER_CLK(RCC_AHB4ENR, 19, "crc", "hclk"), | ||
1038 | PER_CLK(RCC_AHB4ENR, 10, "gpiok", "hclk"), | ||
1039 | PER_CLK(RCC_AHB4ENR, 9, "gpioj", "hclk"), | ||
1040 | PER_CLK(RCC_AHB4ENR, 8, "gpioi", "hclk"), | ||
1041 | PER_CLK(RCC_AHB4ENR, 7, "gpioh", "hclk"), | ||
1042 | PER_CLK(RCC_AHB4ENR, 6, "gpiog", "hclk"), | ||
1043 | PER_CLK(RCC_AHB4ENR, 5, "gpiof", "hclk"), | ||
1044 | PER_CLK(RCC_AHB4ENR, 4, "gpioe", "hclk"), | ||
1045 | PER_CLK(RCC_AHB4ENR, 3, "gpiod", "hclk"), | ||
1046 | PER_CLK(RCC_AHB4ENR, 2, "gpioc", "hclk"), | ||
1047 | PER_CLK(RCC_AHB4ENR, 1, "gpiob", "hclk"), | ||
1048 | PER_CLK(RCC_AHB4ENR, 0, "gpioa", "hclk"), | ||
1049 | PER_CLK(RCC_APB3ENR, 6, "wwdg1", "pclk3"), | ||
1050 | PER_CLK(RCC_APB1LENR, 29, "dac12", "pclk1"), | ||
1051 | PER_CLK(RCC_APB1LENR, 11, "wwdg2", "pclk1"), | ||
1052 | PER_CLK(RCC_APB1LENR, 8, "tim14", "tim1_ker"), | ||
1053 | PER_CLK(RCC_APB1LENR, 7, "tim13", "tim1_ker"), | ||
1054 | PER_CLK(RCC_APB1LENR, 6, "tim12", "tim1_ker"), | ||
1055 | PER_CLK(RCC_APB1LENR, 5, "tim7", "tim1_ker"), | ||
1056 | PER_CLK(RCC_APB1LENR, 4, "tim6", "tim1_ker"), | ||
1057 | PER_CLK(RCC_APB1LENR, 3, "tim5", "tim1_ker"), | ||
1058 | PER_CLK(RCC_APB1LENR, 2, "tim4", "tim1_ker"), | ||
1059 | PER_CLK(RCC_APB1LENR, 1, "tim3", "tim1_ker"), | ||
1060 | PER_CLK(RCC_APB1LENR, 0, "tim2", "tim1_ker"), | ||
1061 | PER_CLK(RCC_APB1HENR, 5, "mdios", "pclk1"), | ||
1062 | PER_CLK(RCC_APB1HENR, 4, "opamp", "pclk1"), | ||
1063 | PER_CLK(RCC_APB1HENR, 1, "crs", "pclk1"), | ||
1064 | PER_CLK(RCC_APB2ENR, 18, "tim17", "tim2_ker"), | ||
1065 | PER_CLK(RCC_APB2ENR, 17, "tim16", "tim2_ker"), | ||
1066 | PER_CLK(RCC_APB2ENR, 16, "tim15", "tim2_ker"), | ||
1067 | PER_CLK(RCC_APB2ENR, 1, "tim8", "tim2_ker"), | ||
1068 | PER_CLK(RCC_APB2ENR, 0, "tim1", "tim2_ker"), | ||
1069 | PER_CLK(RCC_APB4ENR, 26, "tmpsens", "pclk4"), | ||
1070 | PER_CLK(RCC_APB4ENR, 16, "rtcapb", "pclk4"), | ||
1071 | PER_CLK(RCC_APB4ENR, 15, "vref", "pclk4"), | ||
1072 | PER_CLK(RCC_APB4ENR, 14, "comp12", "pclk4"), | ||
1073 | PER_CLK(RCC_APB4ENR, 1, "syscfg", "pclk4"), | ||
1074 | }; | ||
1075 | |||
1076 | /* KERNEL CLOCKS */ | ||
1077 | #define KER_CLKF(_gate_offset, _bit_idx,\ | ||
1078 | _mux_offset, _mux_shift, _mux_width,\ | ||
1079 | _name, _parent_name,\ | ||
1080 | _flags) \ | ||
1081 | { \ | ||
1082 | .gate = &(struct gate_cfg) {_gate_offset, _bit_idx},\ | ||
1083 | .mux = &(struct muxdiv_cfg) {_mux_offset, _mux_shift, _mux_width },\ | ||
1084 | .name = _name, \ | ||
1085 | .parent_name = _parent_name, \ | ||
1086 | .num_parents = ARRAY_SIZE(_parent_name),\ | ||
1087 | .flags = _flags,\ | ||
1088 | } | ||
1089 | |||
1090 | #define KER_CLK(_gate_offset, _bit_idx, _mux_offset, _mux_shift, _mux_width,\ | ||
1091 | _name, _parent_name) \ | ||
1092 | KER_CLKF(_gate_offset, _bit_idx, _mux_offset, _mux_shift, _mux_width,\ | ||
1093 | _name, _parent_name, 0)\ | ||
1094 | |||
1095 | #define KER_CLKF_NOMUX(_gate_offset, _bit_idx,\ | ||
1096 | _name, _parent_name,\ | ||
1097 | _flags) \ | ||
1098 | { \ | ||
1099 | .gate = &(struct gate_cfg) {_gate_offset, _bit_idx},\ | ||
1100 | .mux = NULL,\ | ||
1101 | .name = _name, \ | ||
1102 | .parent_name = _parent_name, \ | ||
1103 | .num_parents = 1,\ | ||
1104 | .flags = _flags,\ | ||
1105 | } | ||
1106 | |||
1107 | static const struct composite_clk_cfg kclk[] = { | ||
1108 | KER_CLK(RCC_AHB3ENR, 16, RCC_D1CCIPR, 16, 1, "sdmmc1", sdmmc_src), | ||
1109 | KER_CLKF(RCC_AHB3ENR, 14, RCC_D1CCIPR, 4, 2, "quadspi", qspi_src, | ||
1110 | CLK_IGNORE_UNUSED), | ||
1111 | KER_CLKF(RCC_AHB3ENR, 12, RCC_D1CCIPR, 0, 2, "fmc", fmc_src, | ||
1112 | CLK_IGNORE_UNUSED), | ||
1113 | KER_CLK(RCC_AHB1ENR, 27, RCC_D2CCIP2R, 20, 2, "usb2otg", usbotg_src), | ||
1114 | KER_CLK(RCC_AHB1ENR, 25, RCC_D2CCIP2R, 20, 2, "usb1otg", usbotg_src), | ||
1115 | KER_CLK(RCC_AHB1ENR, 5, RCC_D3CCIPR, 16, 2, "adc12", adc_src), | ||
1116 | KER_CLK(RCC_AHB2ENR, 9, RCC_D1CCIPR, 16, 1, "sdmmc2", sdmmc_src), | ||
1117 | KER_CLK(RCC_AHB2ENR, 6, RCC_D2CCIP2R, 8, 2, "rng", rng_src), | ||
1118 | KER_CLK(RCC_AHB4ENR, 24, RCC_D3CCIPR, 16, 2, "adc3", adc_src), | ||
1119 | KER_CLKF(RCC_APB3ENR, 4, RCC_D1CCIPR, 8, 1, "dsi", dsi_src, | ||
1120 | CLK_SET_RATE_PARENT), | ||
1121 | KER_CLKF_NOMUX(RCC_APB3ENR, 3, "ltdc", ltdc_src, CLK_SET_RATE_PARENT), | ||
1122 | KER_CLK(RCC_APB1LENR, 31, RCC_D2CCIP2R, 0, 3, "usart8", usart_src2), | ||
1123 | KER_CLK(RCC_APB1LENR, 30, RCC_D2CCIP2R, 0, 3, "usart7", usart_src2), | ||
1124 | KER_CLK(RCC_APB1LENR, 27, RCC_D2CCIP2R, 22, 2, "hdmicec", cec_src), | ||
1125 | KER_CLK(RCC_APB1LENR, 23, RCC_D2CCIP2R, 12, 2, "i2c3", i2c_src1), | ||
1126 | KER_CLK(RCC_APB1LENR, 22, RCC_D2CCIP2R, 12, 2, "i2c2", i2c_src1), | ||
1127 | KER_CLK(RCC_APB1LENR, 21, RCC_D2CCIP2R, 12, 2, "i2c1", i2c_src1), | ||
1128 | KER_CLK(RCC_APB1LENR, 20, RCC_D2CCIP2R, 0, 3, "uart5", usart_src2), | ||
1129 | KER_CLK(RCC_APB1LENR, 19, RCC_D2CCIP2R, 0, 3, "uart4", usart_src2), | ||
1130 | KER_CLK(RCC_APB1LENR, 18, RCC_D2CCIP2R, 0, 3, "usart3", usart_src2), | ||
1131 | KER_CLK(RCC_APB1LENR, 17, RCC_D2CCIP2R, 0, 3, "usart2", usart_src2), | ||
1132 | KER_CLK(RCC_APB1LENR, 16, RCC_D2CCIP1R, 20, 2, "spdifrx", spdifrx_src), | ||
1133 | KER_CLK(RCC_APB1LENR, 15, RCC_D2CCIP1R, 16, 3, "spi3", spi_src1), | ||
1134 | KER_CLK(RCC_APB1LENR, 14, RCC_D2CCIP1R, 16, 3, "spi2", spi_src1), | ||
1135 | KER_CLK(RCC_APB1LENR, 9, RCC_D2CCIP2R, 28, 3, "lptim1", lptim_src1), | ||
1136 | KER_CLK(RCC_APB1HENR, 8, RCC_D2CCIP1R, 28, 2, "fdcan", fdcan_src), | ||
1137 | KER_CLK(RCC_APB1HENR, 2, RCC_D2CCIP1R, 31, 1, "swp", swp_src), | ||
1138 | KER_CLK(RCC_APB2ENR, 29, RCC_CFGR, 14, 1, "hrtim", hrtim_src), | ||
1139 | KER_CLK(RCC_APB2ENR, 28, RCC_D2CCIP1R, 24, 1, "dfsdm1", dfsdm1_src), | ||
1140 | KER_CLKF(RCC_APB2ENR, 24, RCC_D2CCIP1R, 6, 3, "sai3", sai_src, | ||
1141 | CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), | ||
1142 | KER_CLKF(RCC_APB2ENR, 23, RCC_D2CCIP1R, 6, 3, "sai2", sai_src, | ||
1143 | CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), | ||
1144 | KER_CLKF(RCC_APB2ENR, 22, RCC_D2CCIP1R, 0, 3, "sai1", sai_src, | ||
1145 | CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), | ||
1146 | KER_CLK(RCC_APB2ENR, 20, RCC_D2CCIP1R, 16, 3, "spi5", spi_src2), | ||
1147 | KER_CLK(RCC_APB2ENR, 13, RCC_D2CCIP1R, 16, 3, "spi4", spi_src2), | ||
1148 | KER_CLK(RCC_APB2ENR, 12, RCC_D2CCIP1R, 16, 3, "spi1", spi_src1), | ||
1149 | KER_CLK(RCC_APB2ENR, 5, RCC_D2CCIP2R, 3, 3, "usart6", usart_src1), | ||
1150 | KER_CLK(RCC_APB2ENR, 4, RCC_D2CCIP2R, 3, 3, "usart1", usart_src1), | ||
1151 | KER_CLK(RCC_APB4ENR, 21, RCC_D3CCIPR, 24, 3, "sai4b", sai_src), | ||
1152 | KER_CLK(RCC_APB4ENR, 21, RCC_D3CCIPR, 21, 3, "sai4a", sai_src), | ||
1153 | KER_CLK(RCC_APB4ENR, 12, RCC_D3CCIPR, 13, 3, "lptim5", lptim_src2), | ||
1154 | KER_CLK(RCC_APB4ENR, 11, RCC_D3CCIPR, 13, 3, "lptim4", lptim_src2), | ||
1155 | KER_CLK(RCC_APB4ENR, 10, RCC_D3CCIPR, 13, 3, "lptim3", lptim_src2), | ||
1156 | KER_CLK(RCC_APB4ENR, 9, RCC_D3CCIPR, 10, 3, "lptim2", lptim_src2), | ||
1157 | KER_CLK(RCC_APB4ENR, 7, RCC_D3CCIPR, 8, 2, "i2c4", i2c_src2), | ||
1158 | KER_CLK(RCC_APB4ENR, 5, RCC_D3CCIPR, 28, 3, "spi6", spi_src3), | ||
1159 | KER_CLK(RCC_APB4ENR, 3, RCC_D3CCIPR, 0, 3, "lpuart1", lpuart1_src), | ||
1160 | }; | ||
1161 | |||
1162 | static struct composite_clk_gcfg kernel_clk_cfg = { | ||
1163 | M_CFG_MUX(NULL, 0), | ||
1164 | M_CFG_GATE(NULL, 0), | ||
1165 | }; | ||
1166 | |||
1167 | /* RTC clock */ | ||
1168 | /* | ||
1169 | * RTC & LSE registers are protected against parasitic write access. | ||
1170 | * PWR_CR_DBP bit must be set to enable write access to RTC registers. | ||
1171 | */ | ||
1172 | /* STM32_PWR_CR */ | ||
1173 | #define PWR_CR 0x00 | ||
1174 | /* STM32_PWR_CR bit field */ | ||
1175 | #define PWR_CR_DBP BIT(8) | ||
1176 | |||
1177 | static struct composite_clk_gcfg rtc_clk_cfg = { | ||
1178 | M_CFG_MUX(NULL, 0), | ||
1179 | M_CFG_GATE(NULL, 0), | ||
1180 | }; | ||
1181 | |||
1182 | static const struct composite_clk_cfg rtc_clk = | ||
1183 | KER_CLK(RCC_BDCR, 15, RCC_BDCR, 8, 2, "rtc_ck", rtc_src); | ||
1184 | |||
1185 | /* Micro-controller output clock */ | ||
1186 | static struct composite_clk_gcfg mco_clk_cfg = { | ||
1187 | M_CFG_MUX(NULL, 0), | ||
1188 | M_CFG_DIV(NULL, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), | ||
1189 | }; | ||
1190 | |||
1191 | #define M_MCO_F(_name, _parents, _mux_offset, _mux_shift, _mux_width,\ | ||
1192 | _rate_offset, _rate_shift, _rate_width,\ | ||
1193 | _flags)\ | ||
1194 | {\ | ||
1195 | .mux = &(struct muxdiv_cfg) {_mux_offset, _mux_shift, _mux_width },\ | ||
1196 | .div = &(struct muxdiv_cfg) {_rate_offset, _rate_shift, _rate_width},\ | ||
1197 | .gate = NULL,\ | ||
1198 | .name = _name,\ | ||
1199 | .parent_name = _parents,\ | ||
1200 | .num_parents = ARRAY_SIZE(_parents),\ | ||
1201 | .flags = _flags,\ | ||
1202 | } | ||
1203 | |||
1204 | static const struct composite_clk_cfg mco_clk[] = { | ||
1205 | M_MCO_F("mco1", mco_src1, RCC_CFGR, 22, 4, RCC_CFGR, 18, 4, 0), | ||
1206 | M_MCO_F("mco2", mco_src2, RCC_CFGR, 29, 3, RCC_CFGR, 25, 4, 0), | ||
1207 | }; | ||
1208 | |||
1209 | static void __init stm32h7_rcc_init(struct device_node *np) | ||
1210 | { | ||
1211 | struct clk_hw_onecell_data *clk_data; | ||
1212 | struct composite_cfg c_cfg; | ||
1213 | int n; | ||
1214 | const char *hse_clk, *lse_clk, *i2s_clk; | ||
1215 | struct regmap *pdrm; | ||
1216 | |||
1217 | clk_data = kzalloc(sizeof(*clk_data) + | ||
1218 | sizeof(*clk_data->hws) * STM32H7_MAX_CLKS, | ||
1219 | GFP_KERNEL); | ||
1220 | if (!clk_data) | ||
1221 | return; | ||
1222 | |||
1223 | clk_data->num = STM32H7_MAX_CLKS; | ||
1224 | |||
1225 | hws = clk_data->hws; | ||
1226 | |||
1227 | for (n = 0; n < STM32H7_MAX_CLKS; n++) | ||
1228 | hws[n] = ERR_PTR(-ENOENT); | ||
1229 | |||
1230 | /* get RCC base @ from DT */ | ||
1231 | base = of_iomap(np, 0); | ||
1232 | if (!base) { | ||
1233 | pr_err("%s: unable to map resource", np->name); | ||
1234 | goto err_free_clks; | ||
1235 | } | ||
1236 | |||
1237 | pdrm = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); | ||
1238 | if (IS_ERR(pdrm)) | ||
1239 | pr_warn("%s: Unable to get syscfg\n", __func__); | ||
1240 | else | ||
1241 | /* In any case disable backup domain write protection | ||
1242 | * and will never be enabled. | ||
1243 | * Needed by LSE & RTC clocks. | ||
1244 | */ | ||
1245 | regmap_update_bits(pdrm, PWR_CR, PWR_CR_DBP, PWR_CR_DBP); | ||
1246 | |||
1247 | /* Put parent names from DT */ | ||
1248 | hse_clk = of_clk_get_parent_name(np, 0); | ||
1249 | lse_clk = of_clk_get_parent_name(np, 1); | ||
1250 | i2s_clk = of_clk_get_parent_name(np, 2); | ||
1251 | |||
1252 | sai_src[3] = i2s_clk; | ||
1253 | spi_src1[3] = i2s_clk; | ||
1254 | |||
1255 | /* Register Internal oscillators */ | ||
1256 | clk_hw_register_fixed_rate(NULL, "clk-hsi", NULL, 0, 64000000); | ||
1257 | clk_hw_register_fixed_rate(NULL, "clk-csi", NULL, 0, 4000000); | ||
1258 | clk_hw_register_fixed_rate(NULL, "clk-lsi", NULL, 0, 32000); | ||
1259 | clk_hw_register_fixed_rate(NULL, "clk-rc48", NULL, 0, 48000); | ||
1260 | |||
1261 | /* This clock is coming from outside. Frequencies unknown */ | ||
1262 | hws[CK_DSI_PHY] = clk_hw_register_fixed_rate(NULL, "ck_dsi_phy", NULL, | ||
1263 | 0, 0); | ||
1264 | |||
1265 | hws[HSI_DIV] = clk_hw_register_divider(NULL, "hsidiv", "clk-hsi", 0, | ||
1266 | base + RCC_CR, 3, 2, CLK_DIVIDER_POWER_OF_TWO, | ||
1267 | &stm32rcc_lock); | ||
1268 | |||
1269 | hws[HSE_1M] = clk_hw_register_divider(NULL, "hse_1M", "hse_ck", 0, | ||
1270 | base + RCC_CFGR, 8, 6, CLK_DIVIDER_ONE_BASED | | ||
1271 | CLK_DIVIDER_ALLOW_ZERO, | ||
1272 | &stm32rcc_lock); | ||
1273 | |||
1274 | /* Mux system clocks */ | ||
1275 | for (n = 0; n < ARRAY_SIZE(stm32_mclk); n++) | ||
1276 | hws[MCLK_BANK + n] = clk_hw_register_mux(NULL, | ||
1277 | stm32_mclk[n].name, | ||
1278 | stm32_mclk[n].parents, | ||
1279 | stm32_mclk[n].num_parents, | ||
1280 | stm32_mclk[n].flags, | ||
1281 | stm32_mclk[n].offset + base, | ||
1282 | stm32_mclk[n].shift, | ||
1283 | stm32_mclk[n].width, | ||
1284 | 0, | ||
1285 | &stm32rcc_lock); | ||
1286 | |||
1287 | register_core_and_bus_clocks(); | ||
1288 | |||
1289 | /* Oscillary clocks */ | ||
1290 | for (n = 0; n < ARRAY_SIZE(stm32_oclk); n++) | ||
1291 | hws[OSC_BANK + n] = clk_register_ready_gate(NULL, | ||
1292 | stm32_oclk[n].name, | ||
1293 | stm32_oclk[n].parent, | ||
1294 | stm32_oclk[n].gate_offset + base, | ||
1295 | stm32_oclk[n].bit_idx, | ||
1296 | stm32_oclk[n].bit_rdy, | ||
1297 | stm32_oclk[n].flags, | ||
1298 | &stm32rcc_lock); | ||
1299 | |||
1300 | hws[HSE_CK] = clk_register_ready_gate(NULL, | ||
1301 | "hse_ck", | ||
1302 | hse_clk, | ||
1303 | RCC_CR + base, | ||
1304 | 16, 17, | ||
1305 | 0, | ||
1306 | &stm32rcc_lock); | ||
1307 | |||
1308 | hws[LSE_CK] = clk_register_ready_gate(NULL, | ||
1309 | "lse_ck", | ||
1310 | lse_clk, | ||
1311 | RCC_BDCR + base, | ||
1312 | 0, 1, | ||
1313 | 0, | ||
1314 | &stm32rcc_lock); | ||
1315 | |||
1316 | hws[CSI_KER_DIV122 + n] = clk_hw_register_fixed_factor(NULL, | ||
1317 | "csi_ker_div122", "csi_ker", 0, 1, 122); | ||
1318 | |||
1319 | /* PLLs */ | ||
1320 | for (n = 0; n < ARRAY_SIZE(stm32_pll); n++) { | ||
1321 | int odf; | ||
1322 | |||
1323 | /* Register the VCO */ | ||
1324 | clk_register_stm32_pll(NULL, stm32_pll[n].name, | ||
1325 | stm32_pll[n].parent_name, stm32_pll[n].flags, | ||
1326 | stm32_pll[n].cfg, | ||
1327 | &stm32rcc_lock); | ||
1328 | |||
1329 | /* Register the 3 output dividers */ | ||
1330 | for (odf = 0; odf < 3; odf++) { | ||
1331 | int idx = n * 3 + odf; | ||
1332 | |||
1333 | get_cfg_composite_div(&odf_clk_gcfg, &stm32_odf[n][odf], | ||
1334 | &c_cfg, &stm32rcc_lock); | ||
1335 | |||
1336 | hws[ODF_BANK + idx] = clk_hw_register_composite(NULL, | ||
1337 | stm32_odf[n][odf].name, | ||
1338 | stm32_odf[n][odf].parent_name, | ||
1339 | stm32_odf[n][odf].num_parents, | ||
1340 | c_cfg.mux_hw, c_cfg.mux_ops, | ||
1341 | c_cfg.div_hw, c_cfg.div_ops, | ||
1342 | c_cfg.gate_hw, c_cfg.gate_ops, | ||
1343 | stm32_odf[n][odf].flags); | ||
1344 | } | ||
1345 | } | ||
1346 | |||
1347 | /* Peripheral clocks */ | ||
1348 | for (n = 0; n < ARRAY_SIZE(pclk); n++) | ||
1349 | hws[PERIF_BANK + n] = clk_hw_register_gate(NULL, pclk[n].name, | ||
1350 | pclk[n].parent, | ||
1351 | pclk[n].flags, base + pclk[n].gate_offset, | ||
1352 | pclk[n].bit_idx, pclk[n].flags, &stm32rcc_lock); | ||
1353 | |||
1354 | /* Kernel clocks */ | ||
1355 | for (n = 0; n < ARRAY_SIZE(kclk); n++) { | ||
1356 | get_cfg_composite_div(&kernel_clk_cfg, &kclk[n], &c_cfg, | ||
1357 | &stm32rcc_lock); | ||
1358 | |||
1359 | hws[KERN_BANK + n] = clk_hw_register_composite(NULL, | ||
1360 | kclk[n].name, | ||
1361 | kclk[n].parent_name, | ||
1362 | kclk[n].num_parents, | ||
1363 | c_cfg.mux_hw, c_cfg.mux_ops, | ||
1364 | c_cfg.div_hw, c_cfg.div_ops, | ||
1365 | c_cfg.gate_hw, c_cfg.gate_ops, | ||
1366 | kclk[n].flags); | ||
1367 | } | ||
1368 | |||
1369 | /* RTC clock (default state is off) */ | ||
1370 | clk_hw_register_fixed_rate(NULL, "off", NULL, 0, 0); | ||
1371 | |||
1372 | get_cfg_composite_div(&rtc_clk_cfg, &rtc_clk, &c_cfg, &stm32rcc_lock); | ||
1373 | |||
1374 | hws[RTC_CK] = clk_hw_register_composite(NULL, | ||
1375 | rtc_clk.name, | ||
1376 | rtc_clk.parent_name, | ||
1377 | rtc_clk.num_parents, | ||
1378 | c_cfg.mux_hw, c_cfg.mux_ops, | ||
1379 | c_cfg.div_hw, c_cfg.div_ops, | ||
1380 | c_cfg.gate_hw, c_cfg.gate_ops, | ||
1381 | rtc_clk.flags); | ||
1382 | |||
1383 | /* Micro-controller clocks */ | ||
1384 | for (n = 0; n < ARRAY_SIZE(mco_clk); n++) { | ||
1385 | get_cfg_composite_div(&mco_clk_cfg, &mco_clk[n], &c_cfg, | ||
1386 | &stm32rcc_lock); | ||
1387 | |||
1388 | hws[MCO_BANK + n] = clk_hw_register_composite(NULL, | ||
1389 | mco_clk[n].name, | ||
1390 | mco_clk[n].parent_name, | ||
1391 | mco_clk[n].num_parents, | ||
1392 | c_cfg.mux_hw, c_cfg.mux_ops, | ||
1393 | c_cfg.div_hw, c_cfg.div_ops, | ||
1394 | c_cfg.gate_hw, c_cfg.gate_ops, | ||
1395 | mco_clk[n].flags); | ||
1396 | } | ||
1397 | |||
1398 | of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); | ||
1399 | |||
1400 | return; | ||
1401 | |||
1402 | err_free_clks: | ||
1403 | kfree(clk_data); | ||
1404 | } | ||
1405 | |||
1406 | /* The RCC node is a clock and reset controller, and these | ||
1407 | * functionalities are supported by different drivers that | ||
1408 | * matches the same compatible strings. | ||
1409 | */ | ||
1410 | CLK_OF_DECLARE_DRIVER(stm32h7_rcc, "st,stm32h743-rcc", stm32h7_rcc_init); | ||
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index ea7d552a2f2b..decffb3826ec 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #define VC5_PRIM_SRC_SHDN 0x10 | 57 | #define VC5_PRIM_SRC_SHDN 0x10 |
58 | #define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7) | 58 | #define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7) |
59 | #define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6) | 59 | #define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6) |
60 | #define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ BIT(3) | ||
60 | #define VC5_PRIM_SRC_SHDN_SP BIT(1) | 61 | #define VC5_PRIM_SRC_SHDN_SP BIT(1) |
61 | #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0) | 62 | #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0) |
62 | 63 | ||
@@ -122,12 +123,16 @@ | |||
122 | /* flags to describe chip features */ | 123 | /* flags to describe chip features */ |
123 | /* chip has built-in oscilator */ | 124 | /* chip has built-in oscilator */ |
124 | #define VC5_HAS_INTERNAL_XTAL BIT(0) | 125 | #define VC5_HAS_INTERNAL_XTAL BIT(0) |
126 | /* chip has PFD requency doubler */ | ||
127 | #define VC5_HAS_PFD_FREQ_DBL BIT(1) | ||
125 | 128 | ||
126 | /* Supported IDT VC5 models. */ | 129 | /* Supported IDT VC5 models. */ |
127 | enum vc5_model { | 130 | enum vc5_model { |
128 | IDT_VC5_5P49V5923, | 131 | IDT_VC5_5P49V5923, |
132 | IDT_VC5_5P49V5925, | ||
129 | IDT_VC5_5P49V5933, | 133 | IDT_VC5_5P49V5933, |
130 | IDT_VC5_5P49V5935, | 134 | IDT_VC5_5P49V5935, |
135 | IDT_VC6_5P49V6901, | ||
131 | }; | 136 | }; |
132 | 137 | ||
133 | /* Structure to describe features of a particular VC5 model */ | 138 | /* Structure to describe features of a particular VC5 model */ |
@@ -157,6 +162,8 @@ struct vc5_driver_data { | |||
157 | struct clk *pin_clkin; | 162 | struct clk *pin_clkin; |
158 | unsigned char clk_mux_ins; | 163 | unsigned char clk_mux_ins; |
159 | struct clk_hw clk_mux; | 164 | struct clk_hw clk_mux; |
165 | struct clk_hw clk_mul; | ||
166 | struct clk_hw clk_pfd; | ||
160 | struct vc5_hw_data clk_pll; | 167 | struct vc5_hw_data clk_pll; |
161 | struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM]; | 168 | struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM]; |
162 | struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; | 169 | struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; |
@@ -166,6 +173,14 @@ static const char * const vc5_mux_names[] = { | |||
166 | "mux" | 173 | "mux" |
167 | }; | 174 | }; |
168 | 175 | ||
176 | static const char * const vc5_dbl_names[] = { | ||
177 | "dbl" | ||
178 | }; | ||
179 | |||
180 | static const char * const vc5_pfd_names[] = { | ||
181 | "pfd" | ||
182 | }; | ||
183 | |||
169 | static const char * const vc5_pll_names[] = { | 184 | static const char * const vc5_pll_names[] = { |
170 | "pll" | 185 | "pll" |
171 | }; | 186 | }; |
@@ -254,11 +269,64 @@ static int vc5_mux_set_parent(struct clk_hw *hw, u8 index) | |||
254 | return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src); | 269 | return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src); |
255 | } | 270 | } |
256 | 271 | ||
257 | static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw, | 272 | static const struct clk_ops vc5_mux_ops = { |
273 | .set_parent = vc5_mux_set_parent, | ||
274 | .get_parent = vc5_mux_get_parent, | ||
275 | }; | ||
276 | |||
277 | static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw, | ||
258 | unsigned long parent_rate) | 278 | unsigned long parent_rate) |
259 | { | 279 | { |
260 | struct vc5_driver_data *vc5 = | 280 | struct vc5_driver_data *vc5 = |
261 | container_of(hw, struct vc5_driver_data, clk_mux); | 281 | container_of(hw, struct vc5_driver_data, clk_mul); |
282 | unsigned int premul; | ||
283 | |||
284 | regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul); | ||
285 | if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ) | ||
286 | parent_rate *= 2; | ||
287 | |||
288 | return parent_rate; | ||
289 | } | ||
290 | |||
291 | static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate, | ||
292 | unsigned long *parent_rate) | ||
293 | { | ||
294 | if ((*parent_rate == rate) || ((*parent_rate * 2) == rate)) | ||
295 | return rate; | ||
296 | else | ||
297 | return -EINVAL; | ||
298 | } | ||
299 | |||
300 | static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate, | ||
301 | unsigned long parent_rate) | ||
302 | { | ||
303 | struct vc5_driver_data *vc5 = | ||
304 | container_of(hw, struct vc5_driver_data, clk_mul); | ||
305 | u32 mask; | ||
306 | |||
307 | if ((parent_rate * 2) == rate) | ||
308 | mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ; | ||
309 | else | ||
310 | mask = 0; | ||
311 | |||
312 | regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, | ||
313 | VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ, | ||
314 | mask); | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | static const struct clk_ops vc5_dbl_ops = { | ||
320 | .recalc_rate = vc5_dbl_recalc_rate, | ||
321 | .round_rate = vc5_dbl_round_rate, | ||
322 | .set_rate = vc5_dbl_set_rate, | ||
323 | }; | ||
324 | |||
325 | static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw, | ||
326 | unsigned long parent_rate) | ||
327 | { | ||
328 | struct vc5_driver_data *vc5 = | ||
329 | container_of(hw, struct vc5_driver_data, clk_pfd); | ||
262 | unsigned int prediv, div; | 330 | unsigned int prediv, div; |
263 | 331 | ||
264 | regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv); | 332 | regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv); |
@@ -276,7 +344,7 @@ static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw, | |||
276 | return parent_rate / VC5_REF_DIVIDER_REF_DIV(div); | 344 | return parent_rate / VC5_REF_DIVIDER_REF_DIV(div); |
277 | } | 345 | } |
278 | 346 | ||
279 | static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, | 347 | static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate, |
280 | unsigned long *parent_rate) | 348 | unsigned long *parent_rate) |
281 | { | 349 | { |
282 | unsigned long idiv; | 350 | unsigned long idiv; |
@@ -296,11 +364,11 @@ static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, | |||
296 | return *parent_rate / idiv; | 364 | return *parent_rate / idiv; |
297 | } | 365 | } |
298 | 366 | ||
299 | static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, | 367 | static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate, |
300 | unsigned long parent_rate) | 368 | unsigned long parent_rate) |
301 | { | 369 | { |
302 | struct vc5_driver_data *vc5 = | 370 | struct vc5_driver_data *vc5 = |
303 | container_of(hw, struct vc5_driver_data, clk_mux); | 371 | container_of(hw, struct vc5_driver_data, clk_pfd); |
304 | unsigned long idiv; | 372 | unsigned long idiv; |
305 | u8 div; | 373 | u8 div; |
306 | 374 | ||
@@ -328,12 +396,10 @@ static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, | |||
328 | return 0; | 396 | return 0; |
329 | } | 397 | } |
330 | 398 | ||
331 | static const struct clk_ops vc5_mux_ops = { | 399 | static const struct clk_ops vc5_pfd_ops = { |
332 | .set_parent = vc5_mux_set_parent, | 400 | .recalc_rate = vc5_pfd_recalc_rate, |
333 | .get_parent = vc5_mux_get_parent, | 401 | .round_rate = vc5_pfd_round_rate, |
334 | .recalc_rate = vc5_mux_recalc_rate, | 402 | .set_rate = vc5_pfd_set_rate, |
335 | .round_rate = vc5_mux_round_rate, | ||
336 | .set_rate = vc5_mux_set_rate, | ||
337 | }; | 403 | }; |
338 | 404 | ||
339 | /* | 405 | /* |
@@ -426,6 +492,10 @@ static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw, | |||
426 | div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) | | 492 | div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) | |
427 | (od_frc[2] << 6) | (od_frc[3] >> 2); | 493 | (od_frc[2] << 6) | (od_frc[3] >> 2); |
428 | 494 | ||
495 | /* Avoid division by zero if the output is not configured. */ | ||
496 | if (div_int == 0 && div_frc == 0) | ||
497 | return 0; | ||
498 | |||
429 | /* The PLL divider has 12 integer bits and 30 fractional bits */ | 499 | /* The PLL divider has 12 integer bits and 30 fractional bits */ |
430 | return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); | 500 | return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); |
431 | } | 501 | } |
@@ -503,6 +573,25 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) | |||
503 | { | 573 | { |
504 | struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); | 574 | struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); |
505 | struct vc5_driver_data *vc5 = hwdata->vc5; | 575 | struct vc5_driver_data *vc5 = hwdata->vc5; |
576 | const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM | | ||
577 | VC5_OUT_DIV_CONTROL_SEL_EXT | | ||
578 | VC5_OUT_DIV_CONTROL_EN_FOD; | ||
579 | unsigned int src; | ||
580 | int ret; | ||
581 | |||
582 | /* | ||
583 | * If the input mux is disabled, enable it first and | ||
584 | * select source from matching FOD. | ||
585 | */ | ||
586 | regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); | ||
587 | if ((src & mask) == 0) { | ||
588 | src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD; | ||
589 | ret = regmap_update_bits(vc5->regmap, | ||
590 | VC5_OUT_DIV_CONTROL(hwdata->num), | ||
591 | mask | VC5_OUT_DIV_CONTROL_RESET, src); | ||
592 | if (ret) | ||
593 | return ret; | ||
594 | } | ||
506 | 595 | ||
507 | /* Enable the clock buffer */ | 596 | /* Enable the clock buffer */ |
508 | regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), | 597 | regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), |
@@ -516,7 +605,7 @@ static void vc5_clk_out_unprepare(struct clk_hw *hw) | |||
516 | struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); | 605 | struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); |
517 | struct vc5_driver_data *vc5 = hwdata->vc5; | 606 | struct vc5_driver_data *vc5 = hwdata->vc5; |
518 | 607 | ||
519 | /* Enable the clock buffer */ | 608 | /* Disable the clock buffer */ |
520 | regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), | 609 | regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), |
521 | VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0); | 610 | VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0); |
522 | } | 611 | } |
@@ -537,6 +626,9 @@ static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw) | |||
537 | regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); | 626 | regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); |
538 | src &= mask; | 627 | src &= mask; |
539 | 628 | ||
629 | if (src == 0) /* Input mux set to DISABLED */ | ||
630 | return 0; | ||
631 | |||
540 | if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD) | 632 | if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD) |
541 | return 0; | 633 | return 0; |
542 | 634 | ||
@@ -595,7 +687,9 @@ static int vc5_map_index_to_output(const enum vc5_model model, | |||
595 | case IDT_VC5_5P49V5933: | 687 | case IDT_VC5_5P49V5933: |
596 | return (n == 0) ? 0 : 3; | 688 | return (n == 0) ? 0 : 3; |
597 | case IDT_VC5_5P49V5923: | 689 | case IDT_VC5_5P49V5923: |
690 | case IDT_VC5_5P49V5925: | ||
598 | case IDT_VC5_5P49V5935: | 691 | case IDT_VC5_5P49V5935: |
692 | case IDT_VC6_5P49V6901: | ||
599 | default: | 693 | default: |
600 | return n; | 694 | return n; |
601 | } | 695 | } |
@@ -672,12 +766,46 @@ static int vc5_probe(struct i2c_client *client, | |||
672 | goto err_clk; | 766 | goto err_clk; |
673 | } | 767 | } |
674 | 768 | ||
769 | if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) { | ||
770 | /* Register frequency doubler */ | ||
771 | memset(&init, 0, sizeof(init)); | ||
772 | init.name = vc5_dbl_names[0]; | ||
773 | init.ops = &vc5_dbl_ops; | ||
774 | init.flags = CLK_SET_RATE_PARENT; | ||
775 | init.parent_names = vc5_mux_names; | ||
776 | init.num_parents = 1; | ||
777 | vc5->clk_mul.init = &init; | ||
778 | ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul); | ||
779 | if (ret) { | ||
780 | dev_err(&client->dev, "unable to register %s\n", | ||
781 | init.name); | ||
782 | goto err_clk; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | /* Register PFD */ | ||
787 | memset(&init, 0, sizeof(init)); | ||
788 | init.name = vc5_pfd_names[0]; | ||
789 | init.ops = &vc5_pfd_ops; | ||
790 | init.flags = CLK_SET_RATE_PARENT; | ||
791 | if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) | ||
792 | init.parent_names = vc5_dbl_names; | ||
793 | else | ||
794 | init.parent_names = vc5_mux_names; | ||
795 | init.num_parents = 1; | ||
796 | vc5->clk_pfd.init = &init; | ||
797 | ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd); | ||
798 | if (ret) { | ||
799 | dev_err(&client->dev, "unable to register %s\n", init.name); | ||
800 | goto err_clk; | ||
801 | } | ||
802 | |||
675 | /* Register PLL */ | 803 | /* Register PLL */ |
676 | memset(&init, 0, sizeof(init)); | 804 | memset(&init, 0, sizeof(init)); |
677 | init.name = vc5_pll_names[0]; | 805 | init.name = vc5_pll_names[0]; |
678 | init.ops = &vc5_pll_ops; | 806 | init.ops = &vc5_pll_ops; |
679 | init.flags = CLK_SET_RATE_PARENT; | 807 | init.flags = CLK_SET_RATE_PARENT; |
680 | init.parent_names = vc5_mux_names; | 808 | init.parent_names = vc5_pfd_names; |
681 | init.num_parents = 1; | 809 | init.num_parents = 1; |
682 | vc5->clk_pll.num = 0; | 810 | vc5->clk_pll.num = 0; |
683 | vc5->clk_pll.vc5 = vc5; | 811 | vc5->clk_pll.vc5 = vc5; |
@@ -785,6 +913,13 @@ static const struct vc5_chip_info idt_5p49v5923_info = { | |||
785 | .flags = 0, | 913 | .flags = 0, |
786 | }; | 914 | }; |
787 | 915 | ||
916 | static const struct vc5_chip_info idt_5p49v5925_info = { | ||
917 | .model = IDT_VC5_5P49V5925, | ||
918 | .clk_fod_cnt = 4, | ||
919 | .clk_out_cnt = 5, | ||
920 | .flags = 0, | ||
921 | }; | ||
922 | |||
788 | static const struct vc5_chip_info idt_5p49v5933_info = { | 923 | static const struct vc5_chip_info idt_5p49v5933_info = { |
789 | .model = IDT_VC5_5P49V5933, | 924 | .model = IDT_VC5_5P49V5933, |
790 | .clk_fod_cnt = 2, | 925 | .clk_fod_cnt = 2, |
@@ -799,18 +934,29 @@ static const struct vc5_chip_info idt_5p49v5935_info = { | |||
799 | .flags = VC5_HAS_INTERNAL_XTAL, | 934 | .flags = VC5_HAS_INTERNAL_XTAL, |
800 | }; | 935 | }; |
801 | 936 | ||
937 | static const struct vc5_chip_info idt_5p49v6901_info = { | ||
938 | .model = IDT_VC6_5P49V6901, | ||
939 | .clk_fod_cnt = 4, | ||
940 | .clk_out_cnt = 5, | ||
941 | .flags = VC5_HAS_PFD_FREQ_DBL, | ||
942 | }; | ||
943 | |||
802 | static const struct i2c_device_id vc5_id[] = { | 944 | static const struct i2c_device_id vc5_id[] = { |
803 | { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 }, | 945 | { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 }, |
946 | { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 }, | ||
804 | { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 }, | 947 | { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 }, |
805 | { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 }, | 948 | { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 }, |
949 | { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 }, | ||
806 | { } | 950 | { } |
807 | }; | 951 | }; |
808 | MODULE_DEVICE_TABLE(i2c, vc5_id); | 952 | MODULE_DEVICE_TABLE(i2c, vc5_id); |
809 | 953 | ||
810 | static const struct of_device_id clk_vc5_of_match[] = { | 954 | static const struct of_device_id clk_vc5_of_match[] = { |
811 | { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info }, | 955 | { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info }, |
956 | { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info }, | ||
812 | { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info }, | 957 | { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info }, |
813 | { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info }, | 958 | { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info }, |
959 | { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info }, | ||
814 | { }, | 960 | { }, |
815 | }; | 961 | }; |
816 | MODULE_DEVICE_TABLE(of, clk_vc5_of_match); | 962 | MODULE_DEVICE_TABLE(of, clk_vc5_of_match); |
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index bc37030e38ba..4c75821a3933 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c | |||
@@ -192,7 +192,7 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty | |||
192 | 192 | ||
193 | reg = of_iomap(np, 0); | 193 | reg = of_iomap(np, 0); |
194 | if (reg == NULL) { | 194 | if (reg == NULL) { |
195 | pr_err("Unable to map CSR register for %s\n", np->full_name); | 195 | pr_err("Unable to map CSR register for %pOF\n", np); |
196 | return; | 196 | return; |
197 | } | 197 | } |
198 | of_property_read_string(np, "clock-output-names", &clk_name); | 198 | of_property_read_string(np, "clock-output-names", &clk_name); |
@@ -409,12 +409,12 @@ static void xgene_pmdclk_init(struct device_node *np) | |||
409 | /* Parse the DTS register for resource */ | 409 | /* Parse the DTS register for resource */ |
410 | rc = of_address_to_resource(np, 0, &res); | 410 | rc = of_address_to_resource(np, 0, &res); |
411 | if (rc != 0) { | 411 | if (rc != 0) { |
412 | pr_err("no DTS register for %s\n", np->full_name); | 412 | pr_err("no DTS register for %pOF\n", np); |
413 | return; | 413 | return; |
414 | } | 414 | } |
415 | csr_reg = of_iomap(np, 0); | 415 | csr_reg = of_iomap(np, 0); |
416 | if (!csr_reg) { | 416 | if (!csr_reg) { |
417 | pr_err("Unable to map resource for %s\n", np->full_name); | 417 | pr_err("Unable to map resource for %pOF\n", np); |
418 | return; | 418 | return; |
419 | } | 419 | } |
420 | of_property_read_string(np, "clock-output-names", &clk_name); | 420 | of_property_read_string(np, "clock-output-names", &clk_name); |
@@ -703,16 +703,14 @@ static void __init xgene_devclk_init(struct device_node *np) | |||
703 | rc = of_address_to_resource(np, i, &res); | 703 | rc = of_address_to_resource(np, i, &res); |
704 | if (rc != 0) { | 704 | if (rc != 0) { |
705 | if (i == 0) { | 705 | if (i == 0) { |
706 | pr_err("no DTS register for %s\n", | 706 | pr_err("no DTS register for %pOF\n", np); |
707 | np->full_name); | ||
708 | return; | 707 | return; |
709 | } | 708 | } |
710 | break; | 709 | break; |
711 | } | 710 | } |
712 | map_res = of_iomap(np, i); | 711 | map_res = of_iomap(np, i); |
713 | if (map_res == NULL) { | 712 | if (map_res == NULL) { |
714 | pr_err("Unable to map resource %d for %s\n", | 713 | pr_err("Unable to map resource %d for %pOF\n", i, np); |
715 | i, np->full_name); | ||
716 | goto err; | 714 | goto err; |
717 | } | 715 | } |
718 | if (strcmp(res.name, "div-reg") == 0) | 716 | if (strcmp(res.name, "div-reg") == 0) |
@@ -747,8 +745,7 @@ static void __init xgene_devclk_init(struct device_node *np) | |||
747 | pr_debug("Add %s clock\n", clk_name); | 745 | pr_debug("Add %s clock\n", clk_name); |
748 | rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); | 746 | rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); |
749 | if (rc != 0) | 747 | if (rc != 0) |
750 | pr_err("%s: could register provider clk %s\n", __func__, | 748 | pr_err("%s: could register provider clk %pOF\n", __func__, np); |
751 | np->full_name); | ||
752 | 749 | ||
753 | return; | 750 | return; |
754 | 751 | ||
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index fc58c52a26b4..c8d83acda006 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -3132,7 +3132,7 @@ int of_clk_add_provider(struct device_node *np, | |||
3132 | mutex_lock(&of_clk_mutex); | 3132 | mutex_lock(&of_clk_mutex); |
3133 | list_add(&cp->link, &of_clk_providers); | 3133 | list_add(&cp->link, &of_clk_providers); |
3134 | mutex_unlock(&of_clk_mutex); | 3134 | mutex_unlock(&of_clk_mutex); |
3135 | pr_debug("Added clock from %s\n", np->full_name); | 3135 | pr_debug("Added clock from %pOF\n", np); |
3136 | 3136 | ||
3137 | ret = of_clk_set_defaults(np, true); | 3137 | ret = of_clk_set_defaults(np, true); |
3138 | if (ret < 0) | 3138 | if (ret < 0) |
@@ -3167,7 +3167,7 @@ int of_clk_add_hw_provider(struct device_node *np, | |||
3167 | mutex_lock(&of_clk_mutex); | 3167 | mutex_lock(&of_clk_mutex); |
3168 | list_add(&cp->link, &of_clk_providers); | 3168 | list_add(&cp->link, &of_clk_providers); |
3169 | mutex_unlock(&of_clk_mutex); | 3169 | mutex_unlock(&of_clk_mutex); |
3170 | pr_debug("Added clk_hw provider from %s\n", np->full_name); | 3170 | pr_debug("Added clk_hw provider from %pOF\n", np); |
3171 | 3171 | ||
3172 | ret = of_clk_set_defaults(np, true); | 3172 | ret = of_clk_set_defaults(np, true); |
3173 | if (ret < 0) | 3173 | if (ret < 0) |
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index bb8a77a5985f..6b2f29df3f70 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c | |||
@@ -77,8 +77,8 @@ static struct clk *__of_clk_get_by_name(struct device_node *np, | |||
77 | break; | 77 | break; |
78 | } else if (name && index >= 0) { | 78 | } else if (name && index >= 0) { |
79 | if (PTR_ERR(clk) != -EPROBE_DEFER) | 79 | if (PTR_ERR(clk) != -EPROBE_DEFER) |
80 | pr_err("ERROR: could not get clock %s:%s(%i)\n", | 80 | pr_err("ERROR: could not get clock %pOF:%s(%i)\n", |
81 | np->full_name, name ? name : "", index); | 81 | np, name ? name : "", index); |
82 | return clk; | 82 | return clk; |
83 | } | 83 | } |
84 | 84 | ||
diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c index 4181b6808545..e786d717f75d 100644 --- a/drivers/clk/hisilicon/clk-hi6220.c +++ b/drivers/clk/hisilicon/clk-hi6220.c | |||
@@ -55,9 +55,9 @@ static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = { | 57 | static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = { |
58 | { HI6220_WDT0_PCLK, "wdt0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, }, | 58 | { HI6220_WDT0_PCLK, "wdt0_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, }, |
59 | { HI6220_WDT1_PCLK, "wdt1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, }, | 59 | { HI6220_WDT1_PCLK, "wdt1_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, }, |
60 | { HI6220_WDT2_PCLK, "wdt2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, }, | 60 | { HI6220_WDT2_PCLK, "wdt2_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, }, |
61 | { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, }, | 61 | { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, }, |
62 | { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, }, | 62 | { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, }, |
63 | { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, }, | 63 | { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, }, |
diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c index 1e3c9ea5f9dc..7bcaf270db11 100644 --- a/drivers/clk/imx/clk-imx51-imx53.c +++ b/drivers/clk/imx/clk-imx51-imx53.c | |||
@@ -416,10 +416,10 @@ static void __init mx51_clocks_init(struct device_node *np) | |||
416 | 416 | ||
417 | clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, | 417 | clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, |
418 | lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); | 418 | lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); |
419 | clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, | 419 | clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, |
420 | mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); | 420 | mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel), CLK_SET_RATE_PARENT); |
421 | clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, | 421 | clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_flags("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, |
422 | mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); | 422 | mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel), CLK_SET_RATE_PARENT); |
423 | clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, | 423 | clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, |
424 | mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); | 424 | mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); |
425 | clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, | 425 | clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, |
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index 5fd4ddac1bf1..9642cdf0fb88 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c | |||
@@ -71,7 +71,7 @@ static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; | |||
71 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; | 71 | static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; |
72 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; | 72 | static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; |
73 | 73 | ||
74 | static struct clk_div_table clk_enet_ref_table[] = { | 74 | static const struct clk_div_table clk_enet_ref_table[] = { |
75 | { .val = 0, .div = 20, }, | 75 | { .val = 0, .div = 20, }, |
76 | { .val = 1, .div = 10, }, | 76 | { .val = 1, .div = 10, }, |
77 | { .val = 2, .div = 5, }, | 77 | { .val = 2, .div = 5, }, |
@@ -79,14 +79,14 @@ static struct clk_div_table clk_enet_ref_table[] = { | |||
79 | { } | 79 | { } |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static struct clk_div_table post_div_table[] = { | 82 | static const struct clk_div_table post_div_table[] = { |
83 | { .val = 2, .div = 1, }, | 83 | { .val = 2, .div = 1, }, |
84 | { .val = 1, .div = 2, }, | 84 | { .val = 1, .div = 2, }, |
85 | { .val = 0, .div = 4, }, | 85 | { .val = 0, .div = 4, }, |
86 | { } | 86 | { } |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct clk_div_table video_div_table[] = { | 89 | static const struct clk_div_table video_div_table[] = { |
90 | { .val = 0, .div = 1, }, | 90 | { .val = 0, .div = 1, }, |
91 | { .val = 1, .div = 2, }, | 91 | { .val = 1, .div = 2, }, |
92 | { .val = 2, .div = 1, }, | 92 | { .val = 2, .div = 1, }, |
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index b5c96de41ccf..e6d389e333d7 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c | |||
@@ -105,7 +105,7 @@ static int const clks_init_on[] __initconst = { | |||
105 | IMX6SX_CLK_EPIT2, | 105 | IMX6SX_CLK_EPIT2, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static struct clk_div_table clk_enet_ref_table[] = { | 108 | static const struct clk_div_table clk_enet_ref_table[] = { |
109 | { .val = 0, .div = 20, }, | 109 | { .val = 0, .div = 20, }, |
110 | { .val = 1, .div = 10, }, | 110 | { .val = 1, .div = 10, }, |
111 | { .val = 2, .div = 5, }, | 111 | { .val = 2, .div = 5, }, |
@@ -113,14 +113,14 @@ static struct clk_div_table clk_enet_ref_table[] = { | |||
113 | { } | 113 | { } |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static struct clk_div_table post_div_table[] = { | 116 | static const struct clk_div_table post_div_table[] = { |
117 | { .val = 2, .div = 1, }, | 117 | { .val = 2, .div = 1, }, |
118 | { .val = 1, .div = 2, }, | 118 | { .val = 1, .div = 2, }, |
119 | { .val = 0, .div = 4, }, | 119 | { .val = 0, .div = 4, }, |
120 | { } | 120 | { } |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static struct clk_div_table video_div_table[] = { | 123 | static const struct clk_div_table video_div_table[] = { |
124 | { .val = 0, .div = 1, }, | 124 | { .val = 0, .div = 1, }, |
125 | { .val = 1, .div = 2, }, | 125 | { .val = 1, .div = 2, }, |
126 | { .val = 2, .div = 1, }, | 126 | { .val = 2, .div = 1, }, |
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index b4e0dff3c8c2..5e8c18afce9a 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c | |||
@@ -78,7 +78,7 @@ static int const clks_init_on[] __initconst = { | |||
78 | IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG, | 78 | IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static struct clk_div_table clk_enet_ref_table[] = { | 81 | static const struct clk_div_table clk_enet_ref_table[] = { |
82 | { .val = 0, .div = 20, }, | 82 | { .val = 0, .div = 20, }, |
83 | { .val = 1, .div = 10, }, | 83 | { .val = 1, .div = 10, }, |
84 | { .val = 2, .div = 5, }, | 84 | { .val = 2, .div = 5, }, |
@@ -86,14 +86,14 @@ static struct clk_div_table clk_enet_ref_table[] = { | |||
86 | { } | 86 | { } |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct clk_div_table post_div_table[] = { | 89 | static const struct clk_div_table post_div_table[] = { |
90 | { .val = 2, .div = 1, }, | 90 | { .val = 2, .div = 1, }, |
91 | { .val = 1, .div = 2, }, | 91 | { .val = 1, .div = 2, }, |
92 | { .val = 0, .div = 4, }, | 92 | { .val = 0, .div = 4, }, |
93 | { } | 93 | { } |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static struct clk_div_table video_div_table[] = { | 96 | static const struct clk_div_table video_div_table[] = { |
97 | { .val = 0, .div = 1, }, | 97 | { .val = 0, .div = 1, }, |
98 | { .val = 1, .div = 2, }, | 98 | { .val = 1, .div = 2, }, |
99 | { .val = 2, .div = 1, }, | 99 | { .val = 2, .div = 1, }, |
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 3da121826b1b..2305699db467 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c | |||
@@ -27,7 +27,7 @@ static u32 share_count_sai2; | |||
27 | static u32 share_count_sai3; | 27 | static u32 share_count_sai3; |
28 | static u32 share_count_nand; | 28 | static u32 share_count_nand; |
29 | 29 | ||
30 | static struct clk_div_table test_div_table[] = { | 30 | static const struct clk_div_table test_div_table[] = { |
31 | { .val = 3, .div = 1, }, | 31 | { .val = 3, .div = 1, }, |
32 | { .val = 2, .div = 1, }, | 32 | { .val = 2, .div = 1, }, |
33 | { .val = 1, .div = 2, }, | 33 | { .val = 1, .div = 2, }, |
@@ -35,7 +35,7 @@ static struct clk_div_table test_div_table[] = { | |||
35 | { } | 35 | { } |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static struct clk_div_table post_div_table[] = { | 38 | static const struct clk_div_table post_div_table[] = { |
39 | { .val = 3, .div = 4, }, | 39 | { .val = 3, .div = 4, }, |
40 | { .val = 2, .div = 1, }, | 40 | { .val = 2, .div = 1, }, |
41 | { .val = 1, .div = 2, }, | 41 | { .val = 1, .div = 2, }, |
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 59b1863deb88..6dae54325a91 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c | |||
@@ -102,7 +102,7 @@ static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ | |||
102 | static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", }; | 102 | static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", }; |
103 | 103 | ||
104 | 104 | ||
105 | static struct clk_div_table pll4_audio_div_table[] = { | 105 | static const struct clk_div_table pll4_audio_div_table[] = { |
106 | { .val = 0, .div = 1 }, | 106 | { .val = 0, .div = 1 }, |
107 | { .val = 1, .div = 2 }, | 107 | { .val = 1, .div = 2 }, |
108 | { .val = 2, .div = 6 }, | 108 | { .val = 2, .div = 6 }, |
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index edd8e6918050..16e56772d280 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c | |||
@@ -27,7 +27,6 @@ static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw) | |||
27 | static u8 clk_cpumux_get_parent(struct clk_hw *hw) | 27 | static u8 clk_cpumux_get_parent(struct clk_hw *hw) |
28 | { | 28 | { |
29 | struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); | 29 | struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); |
30 | int num_parents = clk_hw_get_num_parents(hw); | ||
31 | unsigned int val; | 30 | unsigned int val; |
32 | 31 | ||
33 | regmap_read(mux->regmap, mux->reg, &val); | 32 | regmap_read(mux->regmap, mux->reg, &val); |
@@ -35,9 +34,6 @@ static u8 clk_cpumux_get_parent(struct clk_hw *hw) | |||
35 | val >>= mux->shift; | 34 | val >>= mux->shift; |
36 | val &= mux->mask; | 35 | val &= mux->mask; |
37 | 36 | ||
38 | if (val >= num_parents) | ||
39 | return -EINVAL; | ||
40 | |||
41 | return val; | 37 | return val; |
42 | } | 38 | } |
43 | 39 | ||
@@ -98,7 +94,7 @@ int __init mtk_clk_register_cpumuxes(struct device_node *node, | |||
98 | 94 | ||
99 | regmap = syscon_node_to_regmap(node); | 95 | regmap = syscon_node_to_regmap(node); |
100 | if (IS_ERR(regmap)) { | 96 | if (IS_ERR(regmap)) { |
101 | pr_err("Cannot find regmap for %s: %ld\n", node->full_name, | 97 | pr_err("Cannot find regmap for %pOF: %ld\n", node, |
102 | PTR_ERR(regmap)); | 98 | PTR_ERR(regmap)); |
103 | return PTR_ERR(regmap); | 99 | return PTR_ERR(regmap); |
104 | } | 100 | } |
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 0541df78141c..9c0ae4278a94 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c | |||
@@ -114,7 +114,7 @@ int mtk_clk_register_gates(struct device_node *node, | |||
114 | 114 | ||
115 | regmap = syscon_node_to_regmap(node); | 115 | regmap = syscon_node_to_regmap(node); |
116 | if (IS_ERR(regmap)) { | 116 | if (IS_ERR(regmap)) { |
117 | pr_err("Cannot find regmap for %s: %ld\n", node->full_name, | 117 | pr_err("Cannot find regmap for %pOF: %ld\n", node, |
118 | PTR_ERR(regmap)); | 118 | PTR_ERR(regmap)); |
119 | return PTR_ERR(regmap); | 119 | return PTR_ERR(regmap); |
120 | } | 120 | } |
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index 309049d41f1b..d3551d5efef2 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c | |||
@@ -72,7 +72,7 @@ void mtk_register_reset_controller(struct device_node *np, | |||
72 | 72 | ||
73 | regmap = syscon_node_to_regmap(np); | 73 | regmap = syscon_node_to_regmap(np); |
74 | if (IS_ERR(regmap)) { | 74 | if (IS_ERR(regmap)) { |
75 | pr_err("Cannot find regmap for %s: %ld\n", np->full_name, | 75 | pr_err("Cannot find regmap for %pOF: %ld\n", np, |
76 | PTR_ERR(regmap)); | 76 | PTR_ERR(regmap)); |
77 | return; | 77 | return; |
78 | } | 78 | } |
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 5588f75a8414..d2d0174a6eca 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig | |||
@@ -6,6 +6,7 @@ config COMMON_CLK_AMLOGIC | |||
6 | config COMMON_CLK_MESON8B | 6 | config COMMON_CLK_MESON8B |
7 | bool | 7 | bool |
8 | depends on COMMON_CLK_AMLOGIC | 8 | depends on COMMON_CLK_AMLOGIC |
9 | select RESET_CONTROLLER | ||
9 | help | 10 | help |
10 | Support for the clock controller on AmLogic S802 (Meson8), | 11 | Support for the clock controller on AmLogic S802 (Meson8), |
11 | S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you | 12 | S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you |
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index 83b6d9d65aa1..b139d41b25da 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o | 5 | obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o |
6 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o | 6 | obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o |
7 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o | 7 | obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o |
diff --git a/drivers/clk/meson/gxbb-aoclk-32k.c b/drivers/clk/meson/gxbb-aoclk-32k.c new file mode 100644 index 000000000000..491634dbc985 --- /dev/null +++ b/drivers/clk/meson/gxbb-aoclk-32k.c | |||
@@ -0,0 +1,194 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 BayLibre, SAS. | ||
3 | * Author: Neil Armstrong <narmstrong@baylibre.com> | ||
4 | * | ||
5 | * SPDX-License-Identifier: GPL-2.0+ | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk-provider.h> | ||
9 | #include <linux/bitfield.h> | ||
10 | #include <linux/regmap.h> | ||
11 | #include "gxbb-aoclk.h" | ||
12 | |||
13 | /* | ||
14 | * The AO Domain embeds a dual/divider to generate a more precise | ||
15 | * 32,768KHz clock for low-power suspend mode and CEC. | ||
16 | * ______ ______ | ||
17 | * | | | | | ||
18 | * ______ | Div1 |-| Cnt1 | ______ | ||
19 | * | | /|______| |______|\ | | | ||
20 | * Xtal-->| Gate |---| ______ ______ X-X--| Gate |--> | ||
21 | * |______| | \| | | |/ | |______| | ||
22 | * | | Div2 |-| Cnt2 | | | ||
23 | * | |______| |______| | | ||
24 | * |_______________________| | ||
25 | * | ||
26 | * The dividing can be switched to single or dual, with a counter | ||
27 | * for each divider to set when the switching is done. | ||
28 | * The entire dividing mechanism can be also bypassed. | ||
29 | */ | ||
30 | |||
31 | #define CLK_CNTL0_N1_MASK GENMASK(11, 0) | ||
32 | #define CLK_CNTL0_N2_MASK GENMASK(23, 12) | ||
33 | #define CLK_CNTL0_DUALDIV_EN BIT(28) | ||
34 | #define CLK_CNTL0_OUT_GATE_EN BIT(30) | ||
35 | #define CLK_CNTL0_IN_GATE_EN BIT(31) | ||
36 | |||
37 | #define CLK_CNTL1_M1_MASK GENMASK(11, 0) | ||
38 | #define CLK_CNTL1_M2_MASK GENMASK(23, 12) | ||
39 | #define CLK_CNTL1_BYPASS_EN BIT(24) | ||
40 | #define CLK_CNTL1_SELECT_OSC BIT(27) | ||
41 | |||
42 | #define PWR_CNTL_ALT_32K_SEL GENMASK(13, 10) | ||
43 | |||
44 | struct cec_32k_freq_table { | ||
45 | unsigned long parent_rate; | ||
46 | unsigned long target_rate; | ||
47 | bool dualdiv; | ||
48 | unsigned int n1; | ||
49 | unsigned int n2; | ||
50 | unsigned int m1; | ||
51 | unsigned int m2; | ||
52 | }; | ||
53 | |||
54 | static const struct cec_32k_freq_table aoclk_cec_32k_table[] = { | ||
55 | [0] = { | ||
56 | .parent_rate = 24000000, | ||
57 | .target_rate = 32768, | ||
58 | .dualdiv = true, | ||
59 | .n1 = 733, | ||
60 | .n2 = 732, | ||
61 | .m1 = 8, | ||
62 | .m2 = 11, | ||
63 | }, | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * If CLK_CNTL0_DUALDIV_EN == 0 | ||
68 | * - will use N1 divider only | ||
69 | * If CLK_CNTL0_DUALDIV_EN == 1 | ||
70 | * - hold M1 cycles of N1 divider then changes to N2 | ||
71 | * - hold M2 cycles of N2 divider then changes to N1 | ||
72 | * Then we can get more accurate division. | ||
73 | */ | ||
74 | static unsigned long aoclk_cec_32k_recalc_rate(struct clk_hw *hw, | ||
75 | unsigned long parent_rate) | ||
76 | { | ||
77 | struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw); | ||
78 | unsigned long n1; | ||
79 | u32 reg0, reg1; | ||
80 | |||
81 | regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, ®0); | ||
82 | regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, ®1); | ||
83 | |||
84 | if (reg1 & CLK_CNTL1_BYPASS_EN) | ||
85 | return parent_rate; | ||
86 | |||
87 | if (reg0 & CLK_CNTL0_DUALDIV_EN) { | ||
88 | unsigned long n2, m1, m2, f1, f2, p1, p2; | ||
89 | |||
90 | n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1; | ||
91 | n2 = FIELD_GET(CLK_CNTL0_N2_MASK, reg0) + 1; | ||
92 | |||
93 | m1 = FIELD_GET(CLK_CNTL1_M1_MASK, reg1) + 1; | ||
94 | m2 = FIELD_GET(CLK_CNTL1_M2_MASK, reg1) + 1; | ||
95 | |||
96 | f1 = DIV_ROUND_CLOSEST(parent_rate, n1); | ||
97 | f2 = DIV_ROUND_CLOSEST(parent_rate, n2); | ||
98 | |||
99 | p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2)); | ||
100 | p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2)); | ||
101 | |||
102 | return DIV_ROUND_UP(100000000, p1 + p2); | ||
103 | } | ||
104 | |||
105 | n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1; | ||
106 | |||
107 | return DIV_ROUND_CLOSEST(parent_rate, n1); | ||
108 | } | ||
109 | |||
110 | static const struct cec_32k_freq_table *find_cec_32k_freq(unsigned long rate, | ||
111 | unsigned long prate) | ||
112 | { | ||
113 | int i; | ||
114 | |||
115 | for (i = 0 ; i < ARRAY_SIZE(aoclk_cec_32k_table) ; ++i) | ||
116 | if (aoclk_cec_32k_table[i].parent_rate == prate && | ||
117 | aoclk_cec_32k_table[i].target_rate == rate) | ||
118 | return &aoclk_cec_32k_table[i]; | ||
119 | |||
120 | return NULL; | ||
121 | } | ||
122 | |||
123 | static long aoclk_cec_32k_round_rate(struct clk_hw *hw, unsigned long rate, | ||
124 | unsigned long *prate) | ||
125 | { | ||
126 | const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate, | ||
127 | *prate); | ||
128 | |||
129 | /* If invalid return first one */ | ||
130 | if (!freq) | ||
131 | return aoclk_cec_32k_table[0].target_rate; | ||
132 | |||
133 | return freq->target_rate; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * From the Amlogic init procedure, the IN and OUT gates needs to be handled | ||
138 | * in the init procedure to avoid any glitches. | ||
139 | */ | ||
140 | |||
141 | static int aoclk_cec_32k_set_rate(struct clk_hw *hw, unsigned long rate, | ||
142 | unsigned long parent_rate) | ||
143 | { | ||
144 | const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate, | ||
145 | parent_rate); | ||
146 | struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw); | ||
147 | u32 reg = 0; | ||
148 | |||
149 | if (!freq) | ||
150 | return -EINVAL; | ||
151 | |||
152 | /* Disable clock */ | ||
153 | regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, | ||
154 | CLK_CNTL0_IN_GATE_EN | CLK_CNTL0_OUT_GATE_EN, 0); | ||
155 | |||
156 | reg = FIELD_PREP(CLK_CNTL0_N1_MASK, freq->n1 - 1); | ||
157 | if (freq->dualdiv) | ||
158 | reg |= CLK_CNTL0_DUALDIV_EN | | ||
159 | FIELD_PREP(CLK_CNTL0_N2_MASK, freq->n2 - 1); | ||
160 | |||
161 | regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, reg); | ||
162 | |||
163 | reg = FIELD_PREP(CLK_CNTL1_M1_MASK, freq->m1 - 1); | ||
164 | if (freq->dualdiv) | ||
165 | reg |= FIELD_PREP(CLK_CNTL1_M2_MASK, freq->m2 - 1); | ||
166 | |||
167 | regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, reg); | ||
168 | |||
169 | /* Enable clock */ | ||
170 | regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, | ||
171 | CLK_CNTL0_IN_GATE_EN, CLK_CNTL0_IN_GATE_EN); | ||
172 | |||
173 | udelay(200); | ||
174 | |||
175 | regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, | ||
176 | CLK_CNTL0_OUT_GATE_EN, CLK_CNTL0_OUT_GATE_EN); | ||
177 | |||
178 | regmap_update_bits(cec_32k->regmap, AO_CRT_CLK_CNTL1, | ||
179 | CLK_CNTL1_SELECT_OSC, CLK_CNTL1_SELECT_OSC); | ||
180 | |||
181 | /* Select 32k from XTAL */ | ||
182 | regmap_update_bits(cec_32k->regmap, | ||
183 | AO_RTI_PWR_CNTL_REG0, | ||
184 | PWR_CNTL_ALT_32K_SEL, | ||
185 | FIELD_PREP(PWR_CNTL_ALT_32K_SEL, 4)); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | const struct clk_ops meson_aoclk_cec_32k_ops = { | ||
191 | .recalc_rate = aoclk_cec_32k_recalc_rate, | ||
192 | .round_rate = aoclk_cec_32k_round_rate, | ||
193 | .set_rate = aoclk_cec_32k_set_rate, | ||
194 | }; | ||
diff --git a/drivers/clk/meson/gxbb-aoclk-regmap.c b/drivers/clk/meson/gxbb-aoclk-regmap.c new file mode 100644 index 000000000000..2515fbfa0467 --- /dev/null +++ b/drivers/clk/meson/gxbb-aoclk-regmap.c | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 BayLibre, SAS. | ||
3 | * Author: Neil Armstrong <narmstrong@baylibre.com> | ||
4 | * | ||
5 | * SPDX-License-Identifier: GPL-2.0+ | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk-provider.h> | ||
9 | #include <linux/bitfield.h> | ||
10 | #include <linux/regmap.h> | ||
11 | #include "gxbb-aoclk.h" | ||
12 | |||
13 | static int aoclk_gate_regmap_enable(struct clk_hw *hw) | ||
14 | { | ||
15 | struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); | ||
16 | |||
17 | return regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0, | ||
18 | BIT(gate->bit_idx), BIT(gate->bit_idx)); | ||
19 | } | ||
20 | |||
21 | static void aoclk_gate_regmap_disable(struct clk_hw *hw) | ||
22 | { | ||
23 | struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); | ||
24 | |||
25 | regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0, | ||
26 | BIT(gate->bit_idx), 0); | ||
27 | } | ||
28 | |||
29 | static int aoclk_gate_regmap_is_enabled(struct clk_hw *hw) | ||
30 | { | ||
31 | struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); | ||
32 | unsigned int val; | ||
33 | int ret; | ||
34 | |||
35 | ret = regmap_read(gate->regmap, AO_RTI_GEN_CNTL_REG0, &val); | ||
36 | if (ret) | ||
37 | return ret; | ||
38 | |||
39 | return (val & BIT(gate->bit_idx)) != 0; | ||
40 | } | ||
41 | |||
42 | const struct clk_ops meson_aoclk_gate_regmap_ops = { | ||
43 | .enable = aoclk_gate_regmap_enable, | ||
44 | .disable = aoclk_gate_regmap_disable, | ||
45 | .is_enabled = aoclk_gate_regmap_is_enabled, | ||
46 | }; | ||
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c index b45c5fba7e35..6c161e0a8e59 100644 --- a/drivers/clk/meson/gxbb-aoclk.c +++ b/drivers/clk/meson/gxbb-aoclk.c | |||
@@ -56,16 +56,20 @@ | |||
56 | #include <linux/of_address.h> | 56 | #include <linux/of_address.h> |
57 | #include <linux/platform_device.h> | 57 | #include <linux/platform_device.h> |
58 | #include <linux/reset-controller.h> | 58 | #include <linux/reset-controller.h> |
59 | #include <linux/mfd/syscon.h> | ||
60 | #include <linux/regmap.h> | ||
59 | #include <linux/init.h> | 61 | #include <linux/init.h> |
62 | #include <linux/delay.h> | ||
60 | #include <dt-bindings/clock/gxbb-aoclkc.h> | 63 | #include <dt-bindings/clock/gxbb-aoclkc.h> |
61 | #include <dt-bindings/reset/gxbb-aoclkc.h> | 64 | #include <dt-bindings/reset/gxbb-aoclkc.h> |
65 | #include "gxbb-aoclk.h" | ||
62 | 66 | ||
63 | static DEFINE_SPINLOCK(gxbb_aoclk_lock); | 67 | static DEFINE_SPINLOCK(gxbb_aoclk_lock); |
64 | 68 | ||
65 | struct gxbb_aoclk_reset_controller { | 69 | struct gxbb_aoclk_reset_controller { |
66 | struct reset_controller_dev reset; | 70 | struct reset_controller_dev reset; |
67 | unsigned int *data; | 71 | unsigned int *data; |
68 | void __iomem *base; | 72 | struct regmap *regmap; |
69 | }; | 73 | }; |
70 | 74 | ||
71 | static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, | 75 | static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, |
@@ -74,9 +78,8 @@ static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, | |||
74 | struct gxbb_aoclk_reset_controller *reset = | 78 | struct gxbb_aoclk_reset_controller *reset = |
75 | container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); | 79 | container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); |
76 | 80 | ||
77 | writel(BIT(reset->data[id]), reset->base); | 81 | return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0, |
78 | 82 | BIT(reset->data[id])); | |
79 | return 0; | ||
80 | } | 83 | } |
81 | 84 | ||
82 | static const struct reset_control_ops gxbb_aoclk_reset_ops = { | 85 | static const struct reset_control_ops gxbb_aoclk_reset_ops = { |
@@ -84,13 +87,12 @@ static const struct reset_control_ops gxbb_aoclk_reset_ops = { | |||
84 | }; | 87 | }; |
85 | 88 | ||
86 | #define GXBB_AO_GATE(_name, _bit) \ | 89 | #define GXBB_AO_GATE(_name, _bit) \ |
87 | static struct clk_gate _name##_ao = { \ | 90 | static struct aoclk_gate_regmap _name##_ao = { \ |
88 | .reg = (void __iomem *)0, \ | ||
89 | .bit_idx = (_bit), \ | 91 | .bit_idx = (_bit), \ |
90 | .lock = &gxbb_aoclk_lock, \ | 92 | .lock = &gxbb_aoclk_lock, \ |
91 | .hw.init = &(struct clk_init_data) { \ | 93 | .hw.init = &(struct clk_init_data) { \ |
92 | .name = #_name "_ao", \ | 94 | .name = #_name "_ao", \ |
93 | .ops = &clk_gate_ops, \ | 95 | .ops = &meson_aoclk_gate_regmap_ops, \ |
94 | .parent_names = (const char *[]){ "clk81" }, \ | 96 | .parent_names = (const char *[]){ "clk81" }, \ |
95 | .num_parents = 1, \ | 97 | .num_parents = 1, \ |
96 | .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ | 98 | .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ |
@@ -104,6 +106,17 @@ GXBB_AO_GATE(uart1, 3); | |||
104 | GXBB_AO_GATE(uart2, 5); | 106 | GXBB_AO_GATE(uart2, 5); |
105 | GXBB_AO_GATE(ir_blaster, 6); | 107 | GXBB_AO_GATE(ir_blaster, 6); |
106 | 108 | ||
109 | static struct aoclk_cec_32k cec_32k_ao = { | ||
110 | .lock = &gxbb_aoclk_lock, | ||
111 | .hw.init = &(struct clk_init_data) { | ||
112 | .name = "cec_32k_ao", | ||
113 | .ops = &meson_aoclk_cec_32k_ops, | ||
114 | .parent_names = (const char *[]){ "xtal" }, | ||
115 | .num_parents = 1, | ||
116 | .flags = CLK_IGNORE_UNUSED, | ||
117 | }, | ||
118 | }; | ||
119 | |||
107 | static unsigned int gxbb_aoclk_reset[] = { | 120 | static unsigned int gxbb_aoclk_reset[] = { |
108 | [RESET_AO_REMOTE] = 16, | 121 | [RESET_AO_REMOTE] = 16, |
109 | [RESET_AO_I2C_MASTER] = 18, | 122 | [RESET_AO_I2C_MASTER] = 18, |
@@ -113,7 +126,7 @@ static unsigned int gxbb_aoclk_reset[] = { | |||
113 | [RESET_AO_IR_BLASTER] = 23, | 126 | [RESET_AO_IR_BLASTER] = 23, |
114 | }; | 127 | }; |
115 | 128 | ||
116 | static struct clk_gate *gxbb_aoclk_gate[] = { | 129 | static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { |
117 | [CLKID_AO_REMOTE] = &remote_ao, | 130 | [CLKID_AO_REMOTE] = &remote_ao, |
118 | [CLKID_AO_I2C_MASTER] = &i2c_master_ao, | 131 | [CLKID_AO_I2C_MASTER] = &i2c_master_ao, |
119 | [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, | 132 | [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, |
@@ -130,30 +143,30 @@ static struct clk_hw_onecell_data gxbb_aoclk_onecell_data = { | |||
130 | [CLKID_AO_UART1] = &uart1_ao.hw, | 143 | [CLKID_AO_UART1] = &uart1_ao.hw, |
131 | [CLKID_AO_UART2] = &uart2_ao.hw, | 144 | [CLKID_AO_UART2] = &uart2_ao.hw, |
132 | [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, | 145 | [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, |
146 | [CLKID_AO_CEC_32K] = &cec_32k_ao.hw, | ||
133 | }, | 147 | }, |
134 | .num = ARRAY_SIZE(gxbb_aoclk_gate), | 148 | .num = 7, |
135 | }; | 149 | }; |
136 | 150 | ||
137 | static int gxbb_aoclkc_probe(struct platform_device *pdev) | 151 | static int gxbb_aoclkc_probe(struct platform_device *pdev) |
138 | { | 152 | { |
139 | struct resource *res; | ||
140 | void __iomem *base; | ||
141 | int ret, clkid; | ||
142 | struct device *dev = &pdev->dev; | ||
143 | struct gxbb_aoclk_reset_controller *rstc; | 153 | struct gxbb_aoclk_reset_controller *rstc; |
154 | struct device *dev = &pdev->dev; | ||
155 | struct regmap *regmap; | ||
156 | int ret, clkid; | ||
144 | 157 | ||
145 | rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); | 158 | rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); |
146 | if (!rstc) | 159 | if (!rstc) |
147 | return -ENOMEM; | 160 | return -ENOMEM; |
148 | 161 | ||
149 | /* Generic clocks */ | 162 | regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); |
150 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 163 | if (IS_ERR(regmap)) { |
151 | base = devm_ioremap_resource(dev, res); | 164 | dev_err(dev, "failed to get regmap\n"); |
152 | if (IS_ERR(base)) | 165 | return -ENODEV; |
153 | return PTR_ERR(base); | 166 | } |
154 | 167 | ||
155 | /* Reset Controller */ | 168 | /* Reset Controller */ |
156 | rstc->base = base; | 169 | rstc->regmap = regmap; |
157 | rstc->data = gxbb_aoclk_reset; | 170 | rstc->data = gxbb_aoclk_reset; |
158 | rstc->reset.ops = &gxbb_aoclk_reset_ops; | 171 | rstc->reset.ops = &gxbb_aoclk_reset_ops; |
159 | rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); | 172 | rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); |
@@ -161,10 +174,10 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) | |||
161 | ret = devm_reset_controller_register(dev, &rstc->reset); | 174 | ret = devm_reset_controller_register(dev, &rstc->reset); |
162 | 175 | ||
163 | /* | 176 | /* |
164 | * Populate base address and register all clks | 177 | * Populate regmap and register all clks |
165 | */ | 178 | */ |
166 | for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) { | 179 | for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { |
167 | gxbb_aoclk_gate[clkid]->reg = base; | 180 | gxbb_aoclk_gate[clkid]->regmap = regmap; |
168 | 181 | ||
169 | ret = devm_clk_hw_register(dev, | 182 | ret = devm_clk_hw_register(dev, |
170 | gxbb_aoclk_onecell_data.hws[clkid]); | 183 | gxbb_aoclk_onecell_data.hws[clkid]); |
@@ -172,12 +185,18 @@ static int gxbb_aoclkc_probe(struct platform_device *pdev) | |||
172 | return ret; | 185 | return ret; |
173 | } | 186 | } |
174 | 187 | ||
188 | /* Specific clocks */ | ||
189 | cec_32k_ao.regmap = regmap; | ||
190 | ret = devm_clk_hw_register(dev, &cec_32k_ao.hw); | ||
191 | if (ret) | ||
192 | return ret; | ||
193 | |||
175 | return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, | 194 | return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, |
176 | &gxbb_aoclk_onecell_data); | 195 | &gxbb_aoclk_onecell_data); |
177 | } | 196 | } |
178 | 197 | ||
179 | static const struct of_device_id gxbb_aoclkc_match_table[] = { | 198 | static const struct of_device_id gxbb_aoclkc_match_table[] = { |
180 | { .compatible = "amlogic,gxbb-aoclkc" }, | 199 | { .compatible = "amlogic,meson-gx-aoclkc" }, |
181 | { } | 200 | { } |
182 | }; | 201 | }; |
183 | 202 | ||
diff --git a/drivers/clk/meson/gxbb-aoclk.h b/drivers/clk/meson/gxbb-aoclk.h new file mode 100644 index 000000000000..e8604c8f7eee --- /dev/null +++ b/drivers/clk/meson/gxbb-aoclk.h | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 BayLibre, SAS | ||
3 | * Author: Neil Armstrong <narmstrong@baylibre.com> | ||
4 | * | ||
5 | * SPDX-License-Identifier: GPL-2.0+ | ||
6 | */ | ||
7 | |||
8 | #ifndef __GXBB_AOCLKC_H | ||
9 | #define __GXBB_AOCLKC_H | ||
10 | |||
11 | /* AO Configuration Clock registers offsets */ | ||
12 | #define AO_RTI_PWR_CNTL_REG1 0x0c | ||
13 | #define AO_RTI_PWR_CNTL_REG0 0x10 | ||
14 | #define AO_RTI_GEN_CNTL_REG0 0x40 | ||
15 | #define AO_OSCIN_CNTL 0x58 | ||
16 | #define AO_CRT_CLK_CNTL1 0x68 | ||
17 | #define AO_RTC_ALT_CLK_CNTL0 0x94 | ||
18 | #define AO_RTC_ALT_CLK_CNTL1 0x98 | ||
19 | |||
20 | struct aoclk_gate_regmap { | ||
21 | struct clk_hw hw; | ||
22 | unsigned bit_idx; | ||
23 | struct regmap *regmap; | ||
24 | spinlock_t *lock; | ||
25 | }; | ||
26 | |||
27 | #define to_aoclk_gate_regmap(_hw) \ | ||
28 | container_of(_hw, struct aoclk_gate_regmap, hw) | ||
29 | |||
30 | extern const struct clk_ops meson_aoclk_gate_regmap_ops; | ||
31 | |||
32 | struct aoclk_cec_32k { | ||
33 | struct clk_hw hw; | ||
34 | struct regmap *regmap; | ||
35 | spinlock_t *lock; | ||
36 | }; | ||
37 | |||
38 | #define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw) | ||
39 | |||
40 | extern const struct clk_ops meson_aoclk_cec_32k_ops; | ||
41 | |||
42 | #endif /* __GXBB_AOCLKC_H */ | ||
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 964489b39f6a..b2d1e8ed7152 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c | |||
@@ -850,13 +850,14 @@ static struct meson_clk_audio_divider gxbb_cts_amclk_div = { | |||
850 | .shift = 0, | 850 | .shift = 0, |
851 | .width = 8, | 851 | .width = 8, |
852 | }, | 852 | }, |
853 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
853 | .lock = &clk_lock, | 854 | .lock = &clk_lock, |
854 | .hw.init = &(struct clk_init_data){ | 855 | .hw.init = &(struct clk_init_data){ |
855 | .name = "cts_amclk_div", | 856 | .name = "cts_amclk_div", |
856 | .ops = &meson_clk_audio_divider_ops, | 857 | .ops = &meson_clk_audio_divider_ops, |
857 | .parent_names = (const char *[]){ "cts_amclk_sel" }, | 858 | .parent_names = (const char *[]){ "cts_amclk_sel" }, |
858 | .num_parents = 1, | 859 | .num_parents = 1, |
859 | .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, | 860 | .flags = CLK_SET_RATE_PARENT, |
860 | }, | 861 | }, |
861 | }; | 862 | }; |
862 | 863 | ||
@@ -880,7 +881,7 @@ static struct clk_mux gxbb_cts_mclk_i958_sel = { | |||
880 | /* Default parent unknown (register reset value: 0) */ | 881 | /* Default parent unknown (register reset value: 0) */ |
881 | .table = (u32[]){ 1, 2, 3 }, | 882 | .table = (u32[]){ 1, 2, 3 }, |
882 | .lock = &clk_lock, | 883 | .lock = &clk_lock, |
883 | .hw.init = &(struct clk_init_data){ | 884 | .hw.init = &(struct clk_init_data) { |
884 | .name = "cts_mclk_i958_sel", | 885 | .name = "cts_mclk_i958_sel", |
885 | .ops = &clk_mux_ops, | 886 | .ops = &clk_mux_ops, |
886 | .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, | 887 | .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, |
@@ -894,12 +895,13 @@ static struct clk_divider gxbb_cts_mclk_i958_div = { | |||
894 | .shift = 16, | 895 | .shift = 16, |
895 | .width = 8, | 896 | .width = 8, |
896 | .lock = &clk_lock, | 897 | .lock = &clk_lock, |
897 | .hw.init = &(struct clk_init_data){ | 898 | .flags = CLK_DIVIDER_ROUND_CLOSEST, |
899 | .hw.init = &(struct clk_init_data) { | ||
898 | .name = "cts_mclk_i958_div", | 900 | .name = "cts_mclk_i958_div", |
899 | .ops = &clk_divider_ops, | 901 | .ops = &clk_divider_ops, |
900 | .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, | 902 | .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, |
901 | .num_parents = 1, | 903 | .num_parents = 1, |
902 | .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, | 904 | .flags = CLK_SET_RATE_PARENT, |
903 | }, | 905 | }, |
904 | }; | 906 | }; |
905 | 907 | ||
@@ -979,6 +981,156 @@ static struct clk_mux gxbb_32k_clk_sel = { | |||
979 | }, | 981 | }, |
980 | }; | 982 | }; |
981 | 983 | ||
984 | static const char * const gxbb_sd_emmc_clk0_parent_names[] = { | ||
985 | "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", | ||
986 | |||
987 | /* | ||
988 | * Following these parent clocks, we should also have had mpll2, mpll3 | ||
989 | * and gp0_pll but these clocks are too precious to be used here. All | ||
990 | * the necessary rates for MMC and NAND operation can be acheived using | ||
991 | * xtal or fclk_div clocks | ||
992 | */ | ||
993 | }; | ||
994 | |||
995 | /* SDIO clock */ | ||
996 | static struct clk_mux gxbb_sd_emmc_a_clk0_sel = { | ||
997 | .reg = (void *)HHI_SD_EMMC_CLK_CNTL, | ||
998 | .mask = 0x7, | ||
999 | .shift = 9, | ||
1000 | .lock = &clk_lock, | ||
1001 | .hw.init = &(struct clk_init_data) { | ||
1002 | .name = "sd_emmc_a_clk0_sel", | ||
1003 | .ops = &clk_mux_ops, | ||
1004 | .parent_names = gxbb_sd_emmc_clk0_parent_names, | ||
1005 | .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), | ||
1006 | .flags = CLK_SET_RATE_PARENT, | ||
1007 | }, | ||
1008 | }; | ||
1009 | |||
1010 | static struct clk_divider gxbb_sd_emmc_a_clk0_div = { | ||
1011 | .reg = (void *)HHI_SD_EMMC_CLK_CNTL, | ||
1012 | .shift = 0, | ||
1013 | .width = 7, | ||
1014 | .lock = &clk_lock, | ||
1015 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
1016 | .hw.init = &(struct clk_init_data) { | ||
1017 | .name = "sd_emmc_a_clk0_div", | ||
1018 | .ops = &clk_divider_ops, | ||
1019 | .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, | ||
1020 | .num_parents = 1, | ||
1021 | .flags = CLK_SET_RATE_PARENT, | ||
1022 | }, | ||
1023 | }; | ||
1024 | |||
1025 | static struct clk_gate gxbb_sd_emmc_a_clk0 = { | ||
1026 | .reg = (void *)HHI_SD_EMMC_CLK_CNTL, | ||
1027 | .bit_idx = 7, | ||
1028 | .lock = &clk_lock, | ||
1029 | .hw.init = &(struct clk_init_data){ | ||
1030 | .name = "sd_emmc_a_clk0", | ||
1031 | .ops = &clk_gate_ops, | ||
1032 | .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, | ||
1033 | .num_parents = 1, | ||
1034 | |||
1035 | /* | ||
1036 | * FIXME: | ||
1037 | * We need CLK_IGNORE_UNUSED because mmc DT node point to xtal | ||
1038 | * instead of this clock. CCF would gate this on boot, killing | ||
1039 | * the mmc controller. Please remove this flag once DT properly | ||
1040 | * point to this clock instead of xtal | ||
1041 | * | ||
1042 | * Same goes for emmc B and C clocks | ||
1043 | */ | ||
1044 | .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, | ||
1045 | }, | ||
1046 | }; | ||
1047 | |||
1048 | /* SDcard clock */ | ||
1049 | static struct clk_mux gxbb_sd_emmc_b_clk0_sel = { | ||
1050 | .reg = (void *)HHI_SD_EMMC_CLK_CNTL, | ||
1051 | .mask = 0x7, | ||
1052 | .shift = 25, | ||
1053 | .lock = &clk_lock, | ||
1054 | .hw.init = &(struct clk_init_data) { | ||
1055 | .name = "sd_emmc_b_clk0_sel", | ||
1056 | .ops = &clk_mux_ops, | ||
1057 | .parent_names = gxbb_sd_emmc_clk0_parent_names, | ||
1058 | .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), | ||
1059 | .flags = CLK_SET_RATE_PARENT, | ||
1060 | }, | ||
1061 | }; | ||
1062 | |||
1063 | static struct clk_divider gxbb_sd_emmc_b_clk0_div = { | ||
1064 | .reg = (void *)HHI_SD_EMMC_CLK_CNTL, | ||
1065 | .shift = 16, | ||
1066 | .width = 7, | ||
1067 | .lock = &clk_lock, | ||
1068 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
1069 | .hw.init = &(struct clk_init_data) { | ||
1070 | .name = "sd_emmc_b_clk0_div", | ||
1071 | .ops = &clk_divider_ops, | ||
1072 | .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, | ||
1073 | .num_parents = 1, | ||
1074 | .flags = CLK_SET_RATE_PARENT, | ||
1075 | }, | ||
1076 | }; | ||
1077 | |||
1078 | static struct clk_gate gxbb_sd_emmc_b_clk0 = { | ||
1079 | .reg = (void *)HHI_SD_EMMC_CLK_CNTL, | ||
1080 | .bit_idx = 23, | ||
1081 | .lock = &clk_lock, | ||
1082 | .hw.init = &(struct clk_init_data){ | ||
1083 | .name = "sd_emmc_b_clk0", | ||
1084 | .ops = &clk_gate_ops, | ||
1085 | .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, | ||
1086 | .num_parents = 1, | ||
1087 | .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, | ||
1088 | }, | ||
1089 | }; | ||
1090 | |||
1091 | /* EMMC/NAND clock */ | ||
1092 | static struct clk_mux gxbb_sd_emmc_c_clk0_sel = { | ||
1093 | .reg = (void *)HHI_NAND_CLK_CNTL, | ||
1094 | .mask = 0x7, | ||
1095 | .shift = 9, | ||
1096 | .lock = &clk_lock, | ||
1097 | .hw.init = &(struct clk_init_data) { | ||
1098 | .name = "sd_emmc_c_clk0_sel", | ||
1099 | .ops = &clk_mux_ops, | ||
1100 | .parent_names = gxbb_sd_emmc_clk0_parent_names, | ||
1101 | .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), | ||
1102 | .flags = CLK_SET_RATE_PARENT, | ||
1103 | }, | ||
1104 | }; | ||
1105 | |||
1106 | static struct clk_divider gxbb_sd_emmc_c_clk0_div = { | ||
1107 | .reg = (void *)HHI_NAND_CLK_CNTL, | ||
1108 | .shift = 0, | ||
1109 | .width = 7, | ||
1110 | .lock = &clk_lock, | ||
1111 | .flags = CLK_DIVIDER_ROUND_CLOSEST, | ||
1112 | .hw.init = &(struct clk_init_data) { | ||
1113 | .name = "sd_emmc_c_clk0_div", | ||
1114 | .ops = &clk_divider_ops, | ||
1115 | .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, | ||
1116 | .num_parents = 1, | ||
1117 | .flags = CLK_SET_RATE_PARENT, | ||
1118 | }, | ||
1119 | }; | ||
1120 | |||
1121 | static struct clk_gate gxbb_sd_emmc_c_clk0 = { | ||
1122 | .reg = (void *)HHI_NAND_CLK_CNTL, | ||
1123 | .bit_idx = 7, | ||
1124 | .lock = &clk_lock, | ||
1125 | .hw.init = &(struct clk_init_data){ | ||
1126 | .name = "sd_emmc_c_clk0", | ||
1127 | .ops = &clk_gate_ops, | ||
1128 | .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, | ||
1129 | .num_parents = 1, | ||
1130 | .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, | ||
1131 | }, | ||
1132 | }; | ||
1133 | |||
982 | /* Everything Else (EE) domain gates */ | 1134 | /* Everything Else (EE) domain gates */ |
983 | static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); | 1135 | static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); |
984 | static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); | 1136 | static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); |
@@ -1188,6 +1340,15 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { | |||
1188 | [CLKID_32K_CLK] = &gxbb_32k_clk.hw, | 1340 | [CLKID_32K_CLK] = &gxbb_32k_clk.hw, |
1189 | [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, | 1341 | [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, |
1190 | [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, | 1342 | [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, |
1343 | [CLKID_SD_EMMC_A_CLK0_SEL] = &gxbb_sd_emmc_a_clk0_sel.hw, | ||
1344 | [CLKID_SD_EMMC_A_CLK0_DIV] = &gxbb_sd_emmc_a_clk0_div.hw, | ||
1345 | [CLKID_SD_EMMC_A_CLK0] = &gxbb_sd_emmc_a_clk0.hw, | ||
1346 | [CLKID_SD_EMMC_B_CLK0_SEL] = &gxbb_sd_emmc_b_clk0_sel.hw, | ||
1347 | [CLKID_SD_EMMC_B_CLK0_DIV] = &gxbb_sd_emmc_b_clk0_div.hw, | ||
1348 | [CLKID_SD_EMMC_B_CLK0] = &gxbb_sd_emmc_b_clk0.hw, | ||
1349 | [CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw, | ||
1350 | [CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw, | ||
1351 | [CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw, | ||
1191 | [NR_CLKS] = NULL, | 1352 | [NR_CLKS] = NULL, |
1192 | }, | 1353 | }, |
1193 | .num = NR_CLKS, | 1354 | .num = NR_CLKS, |
@@ -1311,6 +1472,15 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { | |||
1311 | [CLKID_32K_CLK] = &gxbb_32k_clk.hw, | 1472 | [CLKID_32K_CLK] = &gxbb_32k_clk.hw, |
1312 | [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, | 1473 | [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, |
1313 | [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, | 1474 | [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, |
1475 | [CLKID_SD_EMMC_A_CLK0_SEL] = &gxbb_sd_emmc_a_clk0_sel.hw, | ||
1476 | [CLKID_SD_EMMC_A_CLK0_DIV] = &gxbb_sd_emmc_a_clk0_div.hw, | ||
1477 | [CLKID_SD_EMMC_A_CLK0] = &gxbb_sd_emmc_a_clk0.hw, | ||
1478 | [CLKID_SD_EMMC_B_CLK0_SEL] = &gxbb_sd_emmc_b_clk0_sel.hw, | ||
1479 | [CLKID_SD_EMMC_B_CLK0_DIV] = &gxbb_sd_emmc_b_clk0_div.hw, | ||
1480 | [CLKID_SD_EMMC_B_CLK0] = &gxbb_sd_emmc_b_clk0.hw, | ||
1481 | [CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw, | ||
1482 | [CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw, | ||
1483 | [CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw, | ||
1314 | [NR_CLKS] = NULL, | 1484 | [NR_CLKS] = NULL, |
1315 | }, | 1485 | }, |
1316 | .num = NR_CLKS, | 1486 | .num = NR_CLKS, |
@@ -1427,6 +1597,9 @@ static struct clk_gate *const gxbb_clk_gates[] = { | |||
1427 | &gxbb_cts_amclk, | 1597 | &gxbb_cts_amclk, |
1428 | &gxbb_cts_mclk_i958, | 1598 | &gxbb_cts_mclk_i958, |
1429 | &gxbb_32k_clk, | 1599 | &gxbb_32k_clk, |
1600 | &gxbb_sd_emmc_a_clk0, | ||
1601 | &gxbb_sd_emmc_b_clk0, | ||
1602 | &gxbb_sd_emmc_c_clk0, | ||
1430 | }; | 1603 | }; |
1431 | 1604 | ||
1432 | static struct clk_mux *const gxbb_clk_muxes[] = { | 1605 | static struct clk_mux *const gxbb_clk_muxes[] = { |
@@ -1439,6 +1612,9 @@ static struct clk_mux *const gxbb_clk_muxes[] = { | |||
1439 | &gxbb_cts_mclk_i958_sel, | 1612 | &gxbb_cts_mclk_i958_sel, |
1440 | &gxbb_cts_i958, | 1613 | &gxbb_cts_i958, |
1441 | &gxbb_32k_clk_sel, | 1614 | &gxbb_32k_clk_sel, |
1615 | &gxbb_sd_emmc_a_clk0_sel, | ||
1616 | &gxbb_sd_emmc_b_clk0_sel, | ||
1617 | &gxbb_sd_emmc_c_clk0_sel, | ||
1442 | }; | 1618 | }; |
1443 | 1619 | ||
1444 | static struct clk_divider *const gxbb_clk_dividers[] = { | 1620 | static struct clk_divider *const gxbb_clk_dividers[] = { |
@@ -1448,6 +1624,9 @@ static struct clk_divider *const gxbb_clk_dividers[] = { | |||
1448 | &gxbb_mali_1_div, | 1624 | &gxbb_mali_1_div, |
1449 | &gxbb_cts_mclk_i958_div, | 1625 | &gxbb_cts_mclk_i958_div, |
1450 | &gxbb_32k_clk_div, | 1626 | &gxbb_32k_clk_div, |
1627 | &gxbb_sd_emmc_a_clk0_div, | ||
1628 | &gxbb_sd_emmc_b_clk0_div, | ||
1629 | &gxbb_sd_emmc_c_clk0_div, | ||
1451 | }; | 1630 | }; |
1452 | 1631 | ||
1453 | static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = { | 1632 | static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = { |
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index cb60a516ca82..20ab7190d328 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/clk-provider.h> | 25 | #include <linux/clk-provider.h> |
26 | #include <linux/of_address.h> | 26 | #include <linux/of_address.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/reset-controller.h> | ||
29 | #include <linux/slab.h> | ||
28 | #include <linux/init.h> | 30 | #include <linux/init.h> |
29 | 31 | ||
30 | #include "clkc.h" | 32 | #include "clkc.h" |
@@ -32,6 +34,13 @@ | |||
32 | 34 | ||
33 | static DEFINE_SPINLOCK(clk_lock); | 35 | static DEFINE_SPINLOCK(clk_lock); |
34 | 36 | ||
37 | static void __iomem *clk_base; | ||
38 | |||
39 | struct meson8b_clk_reset { | ||
40 | struct reset_controller_dev reset; | ||
41 | void __iomem *base; | ||
42 | }; | ||
43 | |||
35 | static const struct pll_rate_table sys_pll_rate_table[] = { | 44 | static const struct pll_rate_table sys_pll_rate_table[] = { |
36 | PLL_RATE(312000000, 52, 1, 2), | 45 | PLL_RATE(312000000, 52, 1, 2), |
37 | PLL_RATE(336000000, 56, 1, 2), | 46 | PLL_RATE(336000000, 56, 1, 2), |
@@ -696,20 +705,114 @@ static struct clk_divider *const meson8b_clk_dividers[] = { | |||
696 | &meson8b_mpeg_clk_div, | 705 | &meson8b_mpeg_clk_div, |
697 | }; | 706 | }; |
698 | 707 | ||
708 | static const struct meson8b_clk_reset_line { | ||
709 | u32 reg; | ||
710 | u8 bit_idx; | ||
711 | } meson8b_clk_reset_bits[] = { | ||
712 | [CLKC_RESET_L2_CACHE_SOFT_RESET] = { | ||
713 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30 | ||
714 | }, | ||
715 | [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = { | ||
716 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29 | ||
717 | }, | ||
718 | [CLKC_RESET_SCU_SOFT_RESET] = { | ||
719 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28 | ||
720 | }, | ||
721 | [CLKC_RESET_CPU3_SOFT_RESET] = { | ||
722 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27 | ||
723 | }, | ||
724 | [CLKC_RESET_CPU2_SOFT_RESET] = { | ||
725 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26 | ||
726 | }, | ||
727 | [CLKC_RESET_CPU1_SOFT_RESET] = { | ||
728 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25 | ||
729 | }, | ||
730 | [CLKC_RESET_CPU0_SOFT_RESET] = { | ||
731 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24 | ||
732 | }, | ||
733 | [CLKC_RESET_A5_GLOBAL_RESET] = { | ||
734 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18 | ||
735 | }, | ||
736 | [CLKC_RESET_A5_AXI_SOFT_RESET] = { | ||
737 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17 | ||
738 | }, | ||
739 | [CLKC_RESET_A5_ABP_SOFT_RESET] = { | ||
740 | .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16 | ||
741 | }, | ||
742 | [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = { | ||
743 | .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30 | ||
744 | }, | ||
745 | [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = { | ||
746 | .reg = HHI_VID_CLK_CNTL, .bit_idx = 15 | ||
747 | }, | ||
748 | [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = { | ||
749 | .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7 | ||
750 | }, | ||
751 | [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = { | ||
752 | .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3 | ||
753 | }, | ||
754 | [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = { | ||
755 | .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1 | ||
756 | }, | ||
757 | [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = { | ||
758 | .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0 | ||
759 | }, | ||
760 | }; | ||
761 | |||
762 | static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, | ||
763 | unsigned long id, bool assert) | ||
764 | { | ||
765 | struct meson8b_clk_reset *meson8b_clk_reset = | ||
766 | container_of(rcdev, struct meson8b_clk_reset, reset); | ||
767 | unsigned long flags; | ||
768 | const struct meson8b_clk_reset_line *reset; | ||
769 | u32 val; | ||
770 | |||
771 | if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) | ||
772 | return -EINVAL; | ||
773 | |||
774 | reset = &meson8b_clk_reset_bits[id]; | ||
775 | |||
776 | spin_lock_irqsave(&clk_lock, flags); | ||
777 | |||
778 | val = readl(meson8b_clk_reset->base + reset->reg); | ||
779 | if (assert) | ||
780 | val |= BIT(reset->bit_idx); | ||
781 | else | ||
782 | val &= ~BIT(reset->bit_idx); | ||
783 | writel(val, meson8b_clk_reset->base + reset->reg); | ||
784 | |||
785 | spin_unlock_irqrestore(&clk_lock, flags); | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev, | ||
791 | unsigned long id) | ||
792 | { | ||
793 | return meson8b_clk_reset_update(rcdev, id, true); | ||
794 | } | ||
795 | |||
796 | static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev, | ||
797 | unsigned long id) | ||
798 | { | ||
799 | return meson8b_clk_reset_update(rcdev, id, false); | ||
800 | } | ||
801 | |||
802 | static const struct reset_control_ops meson8b_clk_reset_ops = { | ||
803 | .assert = meson8b_clk_reset_assert, | ||
804 | .deassert = meson8b_clk_reset_deassert, | ||
805 | }; | ||
806 | |||
699 | static int meson8b_clkc_probe(struct platform_device *pdev) | 807 | static int meson8b_clkc_probe(struct platform_device *pdev) |
700 | { | 808 | { |
701 | void __iomem *clk_base; | ||
702 | int ret, clkid, i; | 809 | int ret, clkid, i; |
703 | struct clk_hw *parent_hw; | 810 | struct clk_hw *parent_hw; |
704 | struct clk *parent_clk; | 811 | struct clk *parent_clk; |
705 | struct device *dev = &pdev->dev; | 812 | struct device *dev = &pdev->dev; |
706 | 813 | ||
707 | /* Generic clocks and PLLs */ | 814 | if (!clk_base) |
708 | clk_base = of_iomap(dev->of_node, 1); | ||
709 | if (!clk_base) { | ||
710 | pr_err("%s: Unable to map clk base\n", __func__); | ||
711 | return -ENXIO; | 815 | return -ENXIO; |
712 | } | ||
713 | 816 | ||
714 | /* Populate base address for PLLs */ | 817 | /* Populate base address for PLLs */ |
715 | for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) | 818 | for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) |
@@ -749,7 +852,7 @@ static int meson8b_clkc_probe(struct platform_device *pdev) | |||
749 | /* FIXME convert to devm_clk_register */ | 852 | /* FIXME convert to devm_clk_register */ |
750 | ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]); | 853 | ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]); |
751 | if (ret) | 854 | if (ret) |
752 | goto iounmap; | 855 | return ret; |
753 | } | 856 | } |
754 | 857 | ||
755 | /* | 858 | /* |
@@ -772,15 +875,11 @@ static int meson8b_clkc_probe(struct platform_device *pdev) | |||
772 | if (ret) { | 875 | if (ret) { |
773 | pr_err("%s: failed to register clock notifier for cpu_clk\n", | 876 | pr_err("%s: failed to register clock notifier for cpu_clk\n", |
774 | __func__); | 877 | __func__); |
775 | goto iounmap; | 878 | return ret; |
776 | } | 879 | } |
777 | 880 | ||
778 | return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, | 881 | return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, |
779 | &meson8b_hw_onecell_data); | 882 | &meson8b_hw_onecell_data); |
780 | |||
781 | iounmap: | ||
782 | iounmap(clk_base); | ||
783 | return ret; | ||
784 | } | 883 | } |
785 | 884 | ||
786 | static const struct of_device_id meson8b_clkc_match_table[] = { | 885 | static const struct of_device_id meson8b_clkc_match_table[] = { |
@@ -799,3 +898,39 @@ static struct platform_driver meson8b_driver = { | |||
799 | }; | 898 | }; |
800 | 899 | ||
801 | builtin_platform_driver(meson8b_driver); | 900 | builtin_platform_driver(meson8b_driver); |
901 | |||
902 | static void __init meson8b_clkc_reset_init(struct device_node *np) | ||
903 | { | ||
904 | struct meson8b_clk_reset *rstc; | ||
905 | int ret; | ||
906 | |||
907 | /* Generic clocks, PLLs and some of the reset-bits */ | ||
908 | clk_base = of_iomap(np, 1); | ||
909 | if (!clk_base) { | ||
910 | pr_err("%s: Unable to map clk base\n", __func__); | ||
911 | return; | ||
912 | } | ||
913 | |||
914 | rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); | ||
915 | if (!rstc) | ||
916 | return; | ||
917 | |||
918 | /* Reset Controller */ | ||
919 | rstc->base = clk_base; | ||
920 | rstc->reset.ops = &meson8b_clk_reset_ops; | ||
921 | rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits); | ||
922 | rstc->reset.of_node = np; | ||
923 | ret = reset_controller_register(&rstc->reset); | ||
924 | if (ret) { | ||
925 | pr_err("%s: Failed to register clkc reset controller: %d\n", | ||
926 | __func__, ret); | ||
927 | return; | ||
928 | } | ||
929 | } | ||
930 | |||
931 | CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", | ||
932 | meson8b_clkc_reset_init); | ||
933 | CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", | ||
934 | meson8b_clkc_reset_init); | ||
935 | CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", | ||
936 | meson8b_clkc_reset_init); | ||
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index c139bb3273ca..2eaf8a52e7dd 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h | |||
@@ -37,6 +37,9 @@ | |||
37 | #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */ | 37 | #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */ |
38 | #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */ | 38 | #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */ |
39 | #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ | 39 | #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ |
40 | #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ | ||
41 | #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ | ||
42 | #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ | ||
40 | #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ | 43 | #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ |
41 | #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ | 44 | #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ |
42 | #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ | 45 | #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ |
@@ -68,7 +71,11 @@ | |||
68 | 71 | ||
69 | #define CLK_NR_CLKS 96 | 72 | #define CLK_NR_CLKS 96 |
70 | 73 | ||
71 | /* include the CLKIDs that have been made part of the stable DT binding */ | 74 | /* |
75 | * include the CLKID and RESETID that have | ||
76 | * been made part of the stable DT binding | ||
77 | */ | ||
72 | #include <dt-bindings/clock/meson8b-clkc.h> | 78 | #include <dt-bindings/clock/meson8b-clkc.h> |
79 | #include <dt-bindings/reset/amlogic,meson8b-clkc-reset.h> | ||
73 | 80 | ||
74 | #endif /* __MESON8B_H */ | 81 | #endif /* __MESON8B_H */ |
diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c index 61893fe73251..089927e4cda2 100644 --- a/drivers/clk/mmp/clk.c +++ b/drivers/clk/mmp/clk.c | |||
@@ -9,7 +9,7 @@ | |||
9 | void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, | 9 | void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, |
10 | int nr_clks) | 10 | int nr_clks) |
11 | { | 11 | { |
12 | static struct clk **clk_table; | 12 | struct clk **clk_table; |
13 | 13 | ||
14 | clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); | 14 | clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); |
15 | if (!clk_table) | 15 | if (!clk_table) |
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 5b98ff9076f3..7b359afd620e 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c | |||
@@ -885,7 +885,7 @@ static const struct clk_ops clk_usb_i2c_ops = { | |||
885 | .recalc_rate = clk_usb_i2c_recalc_rate, | 885 | .recalc_rate = clk_usb_i2c_recalc_rate, |
886 | }; | 886 | }; |
887 | 887 | ||
888 | static int clk_gate_enable(struct clk_hw *hw) | 888 | static int lpc32xx_clk_gate_enable(struct clk_hw *hw) |
889 | { | 889 | { |
890 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); | 890 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); |
891 | u32 mask = BIT(clk->bit_idx); | 891 | u32 mask = BIT(clk->bit_idx); |
@@ -894,7 +894,7 @@ static int clk_gate_enable(struct clk_hw *hw) | |||
894 | return regmap_update_bits(clk_regmap, clk->reg, mask, val); | 894 | return regmap_update_bits(clk_regmap, clk->reg, mask, val); |
895 | } | 895 | } |
896 | 896 | ||
897 | static void clk_gate_disable(struct clk_hw *hw) | 897 | static void lpc32xx_clk_gate_disable(struct clk_hw *hw) |
898 | { | 898 | { |
899 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); | 899 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); |
900 | u32 mask = BIT(clk->bit_idx); | 900 | u32 mask = BIT(clk->bit_idx); |
@@ -903,7 +903,7 @@ static void clk_gate_disable(struct clk_hw *hw) | |||
903 | regmap_update_bits(clk_regmap, clk->reg, mask, val); | 903 | regmap_update_bits(clk_regmap, clk->reg, mask, val); |
904 | } | 904 | } |
905 | 905 | ||
906 | static int clk_gate_is_enabled(struct clk_hw *hw) | 906 | static int lpc32xx_clk_gate_is_enabled(struct clk_hw *hw) |
907 | { | 907 | { |
908 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); | 908 | struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); |
909 | u32 val; | 909 | u32 val; |
@@ -916,9 +916,9 @@ static int clk_gate_is_enabled(struct clk_hw *hw) | |||
916 | } | 916 | } |
917 | 917 | ||
918 | static const struct clk_ops lpc32xx_clk_gate_ops = { | 918 | static const struct clk_ops lpc32xx_clk_gate_ops = { |
919 | .enable = clk_gate_enable, | 919 | .enable = lpc32xx_clk_gate_enable, |
920 | .disable = clk_gate_disable, | 920 | .disable = lpc32xx_clk_gate_disable, |
921 | .is_enabled = clk_gate_is_enabled, | 921 | .is_enabled = lpc32xx_clk_gate_is_enabled, |
922 | }; | 922 | }; |
923 | 923 | ||
924 | #define div_mask(width) ((1 << (width)) - 1) | 924 | #define div_mask(width) ((1 << (width)) - 1) |
diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index d990fe44aef3..cc03d5508627 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c | |||
@@ -412,8 +412,6 @@ static const struct clk_ops clk_smd_rpm_ops = { | |||
412 | static const struct clk_ops clk_smd_rpm_branch_ops = { | 412 | static const struct clk_ops clk_smd_rpm_branch_ops = { |
413 | .prepare = clk_smd_rpm_prepare, | 413 | .prepare = clk_smd_rpm_prepare, |
414 | .unprepare = clk_smd_rpm_unprepare, | 414 | .unprepare = clk_smd_rpm_unprepare, |
415 | .round_rate = clk_smd_rpm_round_rate, | ||
416 | .recalc_rate = clk_smd_rpm_recalc_rate, | ||
417 | }; | 415 | }; |
418 | 416 | ||
419 | /* msm8916 */ | 417 | /* msm8916 */ |
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index 2cfe7000fc60..3410ee68d4bc 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c | |||
@@ -1176,7 +1176,7 @@ static struct clk_rcg2 bimc_gpu_clk_src = { | |||
1176 | .parent_names = gcc_xo_gpll0_bimc, | 1176 | .parent_names = gcc_xo_gpll0_bimc, |
1177 | .num_parents = 3, | 1177 | .num_parents = 3, |
1178 | .flags = CLK_GET_RATE_NOCACHE, | 1178 | .flags = CLK_GET_RATE_NOCACHE, |
1179 | .ops = &clk_rcg2_shared_ops, | 1179 | .ops = &clk_rcg2_ops, |
1180 | }, | 1180 | }, |
1181 | }; | 1181 | }; |
1182 | 1182 | ||
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 8abc200d4fd3..7ddec886fcd3 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c | |||
@@ -2730,6 +2730,32 @@ static struct clk_fixed_factor ufs_rx_cfg_clk_src = { | |||
2730 | }, | 2730 | }, |
2731 | }; | 2731 | }; |
2732 | 2732 | ||
2733 | static struct clk_branch gcc_hlos1_vote_lpass_core_smmu_clk = { | ||
2734 | .halt_reg = 0x7d010, | ||
2735 | .halt_check = BRANCH_HALT_VOTED, | ||
2736 | .clkr = { | ||
2737 | .enable_reg = 0x7d010, | ||
2738 | .enable_mask = BIT(0), | ||
2739 | .hw.init = &(struct clk_init_data){ | ||
2740 | .name = "hlos1_vote_lpass_core_smmu_clk", | ||
2741 | .ops = &clk_branch2_ops, | ||
2742 | }, | ||
2743 | }, | ||
2744 | }; | ||
2745 | |||
2746 | static struct clk_branch gcc_hlos1_vote_lpass_adsp_smmu_clk = { | ||
2747 | .halt_reg = 0x7d014, | ||
2748 | .halt_check = BRANCH_HALT_VOTED, | ||
2749 | .clkr = { | ||
2750 | .enable_reg = 0x7d014, | ||
2751 | .enable_mask = BIT(0), | ||
2752 | .hw.init = &(struct clk_init_data){ | ||
2753 | .name = "hlos1_vote_lpass_adsp_smmu_clk", | ||
2754 | .ops = &clk_branch2_ops, | ||
2755 | }, | ||
2756 | }, | ||
2757 | }; | ||
2758 | |||
2733 | static struct clk_branch gcc_ufs_rx_cfg_clk = { | 2759 | static struct clk_branch gcc_ufs_rx_cfg_clk = { |
2734 | .halt_reg = 0x75014, | 2760 | .halt_reg = 0x75014, |
2735 | .clkr = { | 2761 | .clkr = { |
@@ -3307,6 +3333,8 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { | |||
3307 | [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, | 3333 | [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, |
3308 | [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr, | 3334 | [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr, |
3309 | [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr, | 3335 | [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr, |
3336 | [GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK] = &gcc_hlos1_vote_lpass_core_smmu_clk.clkr, | ||
3337 | [GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &gcc_hlos1_vote_lpass_adsp_smmu_clk.clkr, | ||
3310 | [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, | 3338 | [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, |
3311 | [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, | 3339 | [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, |
3312 | [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr, | 3340 | [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr, |
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 78d1df9112ba..acbb38151ba1 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig | |||
@@ -15,6 +15,7 @@ config CLK_RENESAS | |||
15 | select CLK_R8A7794 if ARCH_R8A7794 | 15 | select CLK_R8A7794 if ARCH_R8A7794 |
16 | select CLK_R8A7795 if ARCH_R8A7795 | 16 | select CLK_R8A7795 if ARCH_R8A7795 |
17 | select CLK_R8A7796 if ARCH_R8A7796 | 17 | select CLK_R8A7796 if ARCH_R8A7796 |
18 | select CLK_R8A77995 if ARCH_R8A77995 | ||
18 | select CLK_SH73A0 if ARCH_SH73A0 | 19 | select CLK_SH73A0 if ARCH_SH73A0 |
19 | 20 | ||
20 | if CLK_RENESAS | 21 | if CLK_RENESAS |
@@ -34,94 +35,103 @@ config CLK_EMEV2 | |||
34 | bool "Emma Mobile EV2 clock support" if COMPILE_TEST | 35 | bool "Emma Mobile EV2 clock support" if COMPILE_TEST |
35 | 36 | ||
36 | config CLK_RZA1 | 37 | config CLK_RZA1 |
37 | bool | 38 | bool "RZ/A1H clock support" if COMPILE_TEST |
38 | select CLK_RENESAS_CPG_MSTP | 39 | select CLK_RENESAS_CPG_MSTP |
39 | 40 | ||
40 | config CLK_R8A73A4 | 41 | config CLK_R8A73A4 |
41 | bool | 42 | bool "R-Mobile APE6 clock support" if COMPILE_TEST |
42 | select CLK_RENESAS_CPG_MSTP | 43 | select CLK_RENESAS_CPG_MSTP |
43 | select CLK_RENESAS_DIV6 | 44 | select CLK_RENESAS_DIV6 |
44 | 45 | ||
45 | config CLK_R8A7740 | 46 | config CLK_R8A7740 |
46 | bool | 47 | bool "R-Mobile A1 clock support" if COMPILE_TEST |
47 | select CLK_RENESAS_CPG_MSTP | 48 | select CLK_RENESAS_CPG_MSTP |
48 | select CLK_RENESAS_DIV6 | 49 | select CLK_RENESAS_DIV6 |
49 | 50 | ||
50 | config CLK_R8A7743 | 51 | config CLK_R8A7743 |
51 | bool | 52 | bool "RZ/G1M clock support" if COMPILE_TEST |
52 | select CLK_RCAR_GEN2_CPG | 53 | select CLK_RCAR_GEN2_CPG |
53 | 54 | ||
54 | config CLK_R8A7745 | 55 | config CLK_R8A7745 |
55 | bool | 56 | bool "RZ/G1E clock support" if COMPILE_TEST |
56 | select CLK_RCAR_GEN2_CPG | 57 | select CLK_RCAR_GEN2_CPG |
57 | 58 | ||
58 | config CLK_R8A7778 | 59 | config CLK_R8A7778 |
59 | bool | 60 | bool "R-Car M1A clock support" if COMPILE_TEST |
60 | select CLK_RENESAS_CPG_MSTP | 61 | select CLK_RENESAS_CPG_MSTP |
61 | 62 | ||
62 | config CLK_R8A7779 | 63 | config CLK_R8A7779 |
63 | bool | 64 | bool "R-Car H1 clock support" if COMPILE_TEST |
64 | select CLK_RENESAS_CPG_MSTP | 65 | select CLK_RENESAS_CPG_MSTP |
65 | 66 | ||
66 | config CLK_R8A7790 | 67 | config CLK_R8A7790 |
67 | bool | 68 | bool "R-Car H2 clock support" if COMPILE_TEST |
68 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY | 69 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY |
69 | select CLK_RCAR_GEN2_CPG | 70 | select CLK_RCAR_GEN2_CPG |
70 | select CLK_RENESAS_DIV6 | 71 | select CLK_RENESAS_DIV6 |
71 | 72 | ||
72 | config CLK_R8A7791 | 73 | config CLK_R8A7791 |
73 | bool | 74 | bool "R-Car M2-W/N clock support" if COMPILE_TEST |
74 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY | 75 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY |
75 | select CLK_RCAR_GEN2_CPG | 76 | select CLK_RCAR_GEN2_CPG |
76 | select CLK_RENESAS_DIV6 | 77 | select CLK_RENESAS_DIV6 |
77 | 78 | ||
78 | config CLK_R8A7792 | 79 | config CLK_R8A7792 |
79 | bool | 80 | bool "R-Car V2H clock support" if COMPILE_TEST |
80 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY | 81 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY |
81 | select CLK_RCAR_GEN2_CPG | 82 | select CLK_RCAR_GEN2_CPG |
82 | 83 | ||
83 | config CLK_R8A7794 | 84 | config CLK_R8A7794 |
84 | bool | 85 | bool "R-Car E2 clock support" if COMPILE_TEST |
85 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY | 86 | select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY |
86 | select CLK_RCAR_GEN2_CPG | 87 | select CLK_RCAR_GEN2_CPG |
87 | select CLK_RENESAS_DIV6 | 88 | select CLK_RENESAS_DIV6 |
88 | 89 | ||
89 | config CLK_R8A7795 | 90 | config CLK_R8A7795 |
90 | bool | 91 | bool "R-Car H3 clock support" if COMPILE_TEST |
91 | select CLK_RCAR_GEN3_CPG | 92 | select CLK_RCAR_GEN3_CPG |
92 | 93 | ||
93 | config CLK_R8A7796 | 94 | config CLK_R8A7796 |
94 | bool | 95 | bool "R-Car M3-W clock support" if COMPILE_TEST |
96 | select CLK_RCAR_GEN3_CPG | ||
97 | |||
98 | config CLK_R8A77995 | ||
99 | bool "R-Car D3 clock support" if COMPILE_TEST | ||
95 | select CLK_RCAR_GEN3_CPG | 100 | select CLK_RCAR_GEN3_CPG |
96 | 101 | ||
97 | config CLK_SH73A0 | 102 | config CLK_SH73A0 |
98 | bool | 103 | bool "SH-Mobile AG5 clock support" if COMPILE_TEST |
99 | select CLK_RENESAS_CPG_MSTP | 104 | select CLK_RENESAS_CPG_MSTP |
100 | select CLK_RENESAS_DIV6 | 105 | select CLK_RENESAS_DIV6 |
101 | 106 | ||
102 | 107 | ||
103 | # Family | 108 | # Family |
104 | config CLK_RCAR_GEN2 | 109 | config CLK_RCAR_GEN2 |
105 | bool | 110 | bool "R-Car Gen2 legacy clock support" if COMPILE_TEST |
106 | select CLK_RENESAS_CPG_MSTP | 111 | select CLK_RENESAS_CPG_MSTP |
107 | select CLK_RENESAS_DIV6 | 112 | select CLK_RENESAS_DIV6 |
108 | 113 | ||
109 | config CLK_RCAR_GEN2_CPG | 114 | config CLK_RCAR_GEN2_CPG |
110 | bool | 115 | bool "R-Car Gen2 CPG clock support" if COMPILE_TEST |
111 | select CLK_RENESAS_CPG_MSSR | 116 | select CLK_RENESAS_CPG_MSSR |
112 | 117 | ||
113 | config CLK_RCAR_GEN3_CPG | 118 | config CLK_RCAR_GEN3_CPG |
114 | bool | 119 | bool "R-Car Gen3 CPG clock support" if COMPILE_TEST |
115 | select CLK_RENESAS_CPG_MSSR | 120 | select CLK_RENESAS_CPG_MSSR |
116 | 121 | ||
122 | config CLK_RCAR_USB2_CLOCK_SEL | ||
123 | bool "Renesas R-Car USB2 clock selector support" | ||
124 | depends on ARCH_RENESAS || COMPILE_TEST | ||
125 | help | ||
126 | This is a driver for R-Car USB2 clock selector | ||
117 | 127 | ||
118 | # Generic | 128 | # Generic |
119 | config CLK_RENESAS_CPG_MSSR | 129 | config CLK_RENESAS_CPG_MSSR |
120 | bool | 130 | bool "CPG/MSSR clock support" if COMPILE_TEST |
121 | select CLK_RENESAS_DIV6 | 131 | select CLK_RENESAS_DIV6 |
122 | 132 | ||
123 | config CLK_RENESAS_CPG_MSTP | 133 | config CLK_RENESAS_CPG_MSTP |
124 | bool | 134 | bool "MSTP clock support" if COMPILE_TEST |
125 | 135 | ||
126 | config CLK_RENESAS_DIV6 | 136 | config CLK_RENESAS_DIV6 |
127 | bool "DIV6 clock support" if COMPILE_TEST | 137 | bool "DIV6 clock support" if COMPILE_TEST |
diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 02d04124371f..9bda3ec5b199 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile | |||
@@ -13,12 +13,14 @@ obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o | |||
13 | obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o | 13 | obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o |
14 | obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o | 14 | obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o |
15 | obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o | 15 | obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o |
16 | obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o | ||
16 | obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o | 17 | obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o |
17 | 18 | ||
18 | # Family | 19 | # Family |
19 | obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o | 20 | obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o |
20 | obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o | 21 | obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o |
21 | obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o | 22 | obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o |
23 | obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o | ||
22 | 24 | ||
23 | # Generic | 25 | # Generic |
24 | obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o | 26 | obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o |
diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 0627860233cb..3e0040c0ac87 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c | |||
@@ -29,6 +29,9 @@ | |||
29 | * @hw: handle between common and hardware-specific interfaces | 29 | * @hw: handle between common and hardware-specific interfaces |
30 | * @reg: IO-remapped register | 30 | * @reg: IO-remapped register |
31 | * @div: divisor value (1-64) | 31 | * @div: divisor value (1-64) |
32 | * @src_shift: Shift to access the register bits to select the parent clock | ||
33 | * @src_width: Number of register bits to select the parent clock (may be 0) | ||
34 | * @parents: Array to map from valid parent clocks indices to hardware indices | ||
32 | */ | 35 | */ |
33 | struct div6_clock { | 36 | struct div6_clock { |
34 | struct clk_hw hw; | 37 | struct clk_hw hw; |
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index f1617dd044cb..500a9e4e03c4 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c | |||
@@ -335,7 +335,7 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np) | |||
335 | u32 ncells; | 335 | u32 ncells; |
336 | 336 | ||
337 | if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { | 337 | if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { |
338 | pr_warn("%s lacks #power-domain-cells\n", np->full_name); | 338 | pr_warn("%pOF lacks #power-domain-cells\n", np); |
339 | return; | 339 | return; |
340 | } | 340 | } |
341 | 341 | ||
diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 51a2479ed5d7..0b2e56d0d94b 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c | |||
@@ -407,8 +407,7 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) | |||
407 | 407 | ||
408 | if (rcar_rst_read_mode_pins(&cpg_mode)) { | 408 | if (rcar_rst_read_mode_pins(&cpg_mode)) { |
409 | /* Backward-compatibility with old DT */ | 409 | /* Backward-compatibility with old DT */ |
410 | pr_warn("%s: failed to obtain mode pins from RST\n", | 410 | pr_warn("%pOF: failed to obtain mode pins from RST\n", np); |
411 | np->full_name); | ||
412 | cpg_mode = rcar_gen2_read_mode_pins(); | 411 | cpg_mode = rcar_gen2_read_mode_pins(); |
413 | } | 412 | } |
414 | 413 | ||
diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c index a832b9b6f7b0..7f85bbf20bf7 100644 --- a/drivers/clk/renesas/r8a7792-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c | |||
@@ -118,6 +118,13 @@ static const struct mssr_mod_clk r8a7792_mod_clks[] __initconst = { | |||
118 | DEF_MOD("vin1", 810, R8A7792_CLK_ZG), | 118 | DEF_MOD("vin1", 810, R8A7792_CLK_ZG), |
119 | DEF_MOD("vin0", 811, R8A7792_CLK_ZG), | 119 | DEF_MOD("vin0", 811, R8A7792_CLK_ZG), |
120 | DEF_MOD("etheravb", 812, R8A7792_CLK_HP), | 120 | DEF_MOD("etheravb", 812, R8A7792_CLK_HP), |
121 | DEF_MOD("imr-lx3", 821, R8A7792_CLK_ZG), | ||
122 | DEF_MOD("imr-lsx3-1", 822, R8A7792_CLK_ZG), | ||
123 | DEF_MOD("imr-lsx3-0", 823, R8A7792_CLK_ZG), | ||
124 | DEF_MOD("imr-lsx3-5", 825, R8A7792_CLK_ZG), | ||
125 | DEF_MOD("imr-lsx3-4", 826, R8A7792_CLK_ZG), | ||
126 | DEF_MOD("imr-lsx3-3", 827, R8A7792_CLK_ZG), | ||
127 | DEF_MOD("imr-lsx3-2", 828, R8A7792_CLK_ZG), | ||
121 | DEF_MOD("gyro-adc", 901, R8A7792_CLK_P), | 128 | DEF_MOD("gyro-adc", 901, R8A7792_CLK_P), |
122 | DEF_MOD("gpio7", 904, R8A7792_CLK_CP), | 129 | DEF_MOD("gpio7", 904, R8A7792_CLK_CP), |
123 | DEF_MOD("gpio6", 905, R8A7792_CLK_CP), | 130 | DEF_MOD("gpio6", 905, R8A7792_CLK_CP), |
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index c091a8e024b8..762b2f8824f1 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c | |||
@@ -305,23 +305,23 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { | |||
305 | (((md) & BIT(17)) >> 17)) | 305 | (((md) & BIT(17)) >> 17)) |
306 | 306 | ||
307 | static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { | 307 | static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { |
308 | /* EXTAL div PLL1 mult PLL3 mult */ | 308 | /* EXTAL div PLL1 mult/div PLL3 mult/div */ |
309 | { 1, 192, 192, }, | 309 | { 1, 192, 1, 192, 1, }, |
310 | { 1, 192, 128, }, | 310 | { 1, 192, 1, 128, 1, }, |
311 | { 0, /* Prohibited setting */ }, | 311 | { 0, /* Prohibited setting */ }, |
312 | { 1, 192, 192, }, | 312 | { 1, 192, 1, 192, 1, }, |
313 | { 1, 160, 160, }, | 313 | { 1, 160, 1, 160, 1, }, |
314 | { 1, 160, 106, }, | 314 | { 1, 160, 1, 106, 1, }, |
315 | { 0, /* Prohibited setting */ }, | 315 | { 0, /* Prohibited setting */ }, |
316 | { 1, 160, 160, }, | 316 | { 1, 160, 1, 160, 1, }, |
317 | { 1, 128, 128, }, | 317 | { 1, 128, 1, 128, 1, }, |
318 | { 1, 128, 84, }, | 318 | { 1, 128, 1, 84, 1, }, |
319 | { 0, /* Prohibited setting */ }, | 319 | { 0, /* Prohibited setting */ }, |
320 | { 1, 128, 128, }, | 320 | { 1, 128, 1, 128, 1, }, |
321 | { 2, 192, 192, }, | 321 | { 2, 192, 1, 192, 1, }, |
322 | { 2, 192, 128, }, | 322 | { 2, 192, 1, 128, 1, }, |
323 | { 0, /* Prohibited setting */ }, | 323 | { 0, /* Prohibited setting */ }, |
324 | { 2, 192, 192, }, | 324 | { 2, 192, 1, 192, 1, }, |
325 | }; | 325 | }; |
326 | 326 | ||
327 | static const struct soc_device_attribute r8a7795es1[] __initconst = { | 327 | static const struct soc_device_attribute r8a7795es1[] __initconst = { |
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index acc6d0f153e1..e5e7fb212288 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c | |||
@@ -138,6 +138,7 @@ static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = { | |||
138 | DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), | 138 | DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), |
139 | DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1), | 139 | DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1), |
140 | DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1), | 140 | DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1), |
141 | DEF_MOD("usb3-if0", 328, R8A7796_CLK_S3D1), | ||
141 | DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1), | 142 | DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1), |
142 | DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1), | 143 | DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1), |
143 | DEF_MOD("rwdt", 402, R8A7796_CLK_R), | 144 | DEF_MOD("rwdt", 402, R8A7796_CLK_R), |
@@ -277,23 +278,23 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = { | |||
277 | (((md) & BIT(17)) >> 17)) | 278 | (((md) & BIT(17)) >> 17)) |
278 | 279 | ||
279 | static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { | 280 | static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { |
280 | /* EXTAL div PLL1 mult PLL3 mult */ | 281 | /* EXTAL div PLL1 mult/div PLL3 mult/div */ |
281 | { 1, 192, 192, }, | 282 | { 1, 192, 1, 192, 1, }, |
282 | { 1, 192, 128, }, | 283 | { 1, 192, 1, 128, 1, }, |
283 | { 0, /* Prohibited setting */ }, | 284 | { 0, /* Prohibited setting */ }, |
284 | { 1, 192, 192, }, | 285 | { 1, 192, 1, 192, 1, }, |
285 | { 1, 160, 160, }, | 286 | { 1, 160, 1, 160, 1, }, |
286 | { 1, 160, 106, }, | 287 | { 1, 160, 1, 106, 1, }, |
287 | { 0, /* Prohibited setting */ }, | 288 | { 0, /* Prohibited setting */ }, |
288 | { 1, 160, 160, }, | 289 | { 1, 160, 1, 160, 1, }, |
289 | { 1, 128, 128, }, | 290 | { 1, 128, 1, 128, 1, }, |
290 | { 1, 128, 84, }, | 291 | { 1, 128, 1, 84, 1, }, |
291 | { 0, /* Prohibited setting */ }, | 292 | { 0, /* Prohibited setting */ }, |
292 | { 1, 128, 128, }, | 293 | { 1, 128, 1, 128, 1, }, |
293 | { 2, 192, 192, }, | 294 | { 2, 192, 1, 192, 1, }, |
294 | { 2, 192, 128, }, | 295 | { 2, 192, 1, 128, 1, }, |
295 | { 0, /* Prohibited setting */ }, | 296 | { 0, /* Prohibited setting */ }, |
296 | { 2, 192, 192, }, | 297 | { 2, 192, 1, 192, 1, }, |
297 | }; | 298 | }; |
298 | 299 | ||
299 | static int __init r8a7796_cpg_mssr_init(struct device *dev) | 300 | static int __init r8a7796_cpg_mssr_init(struct device *dev) |
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c new file mode 100644 index 000000000000..e594cf8ee63b --- /dev/null +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * r8a77995 Clock Pulse Generator / Module Standby and Software Reset | ||
3 | * | ||
4 | * Copyright (C) 2017 Glider bvba | ||
5 | * | ||
6 | * Based on r8a7795-cpg-mssr.c | ||
7 | * | ||
8 | * Copyright (C) 2015 Glider bvba | ||
9 | * Copyright (C) 2015 Renesas Electronics Corp. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; version 2 of the License. | ||
14 | */ | ||
15 | |||
16 | #include <linux/device.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/soc/renesas/rcar-rst.h> | ||
20 | |||
21 | #include <dt-bindings/clock/r8a77995-cpg-mssr.h> | ||
22 | |||
23 | #include "renesas-cpg-mssr.h" | ||
24 | #include "rcar-gen3-cpg.h" | ||
25 | |||
26 | enum clk_ids { | ||
27 | /* Core Clock Outputs exported to DT */ | ||
28 | LAST_DT_CORE_CLK = R8A77995_CLK_CP, | ||
29 | |||
30 | /* External Input Clocks */ | ||
31 | CLK_EXTAL, | ||
32 | |||
33 | /* Internal Core Clocks */ | ||
34 | CLK_MAIN, | ||
35 | CLK_PLL0, | ||
36 | CLK_PLL1, | ||
37 | CLK_PLL3, | ||
38 | CLK_PLL0D2, | ||
39 | CLK_PLL0D3, | ||
40 | CLK_PLL0D5, | ||
41 | CLK_PLL1D2, | ||
42 | CLK_PE, | ||
43 | CLK_S0, | ||
44 | CLK_S1, | ||
45 | CLK_S2, | ||
46 | CLK_S3, | ||
47 | CLK_SDSRC, | ||
48 | CLK_SSPSRC, | ||
49 | |||
50 | /* Module Clocks */ | ||
51 | MOD_CLK_BASE | ||
52 | }; | ||
53 | |||
54 | static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { | ||
55 | /* External Clock Inputs */ | ||
56 | DEF_INPUT("extal", CLK_EXTAL), | ||
57 | |||
58 | /* Internal Core Clocks */ | ||
59 | DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), | ||
60 | DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), | ||
61 | DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), | ||
62 | |||
63 | DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 4, 250), | ||
64 | DEF_FIXED(".pll0d2", CLK_PLL0D2, CLK_PLL0, 2, 1), | ||
65 | DEF_FIXED(".pll0d3", CLK_PLL0D3, CLK_PLL0, 3, 1), | ||
66 | DEF_FIXED(".pll0d5", CLK_PLL0D5, CLK_PLL0, 5, 1), | ||
67 | DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), | ||
68 | DEF_FIXED(".pe", CLK_PE, CLK_PLL0D3, 4, 1), | ||
69 | DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), | ||
70 | DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), | ||
71 | DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), | ||
72 | DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), | ||
73 | DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), | ||
74 | |||
75 | /* Core Clock Outputs */ | ||
76 | DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), | ||
77 | DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), | ||
78 | DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1), | ||
79 | DEF_FIXED("zx", R8A77995_CLK_ZX, CLK_PLL1, 3, 1), | ||
80 | DEF_FIXED("s0d1", R8A77995_CLK_S0D1, CLK_S0, 1, 1), | ||
81 | DEF_FIXED("s1d1", R8A77995_CLK_S1D1, CLK_S1, 1, 1), | ||
82 | DEF_FIXED("s1d2", R8A77995_CLK_S1D2, CLK_S1, 2, 1), | ||
83 | DEF_FIXED("s1d4", R8A77995_CLK_S1D4, CLK_S1, 4, 1), | ||
84 | DEF_FIXED("s2d1", R8A77995_CLK_S2D1, CLK_S2, 1, 1), | ||
85 | DEF_FIXED("s2d2", R8A77995_CLK_S2D2, CLK_S2, 2, 1), | ||
86 | DEF_FIXED("s2d4", R8A77995_CLK_S2D4, CLK_S2, 4, 1), | ||
87 | DEF_FIXED("s3d1", R8A77995_CLK_S3D1, CLK_S3, 1, 1), | ||
88 | DEF_FIXED("s3d2", R8A77995_CLK_S3D2, CLK_S3, 2, 1), | ||
89 | DEF_FIXED("s3d4", R8A77995_CLK_S3D4, CLK_S3, 4, 1), | ||
90 | |||
91 | DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1), | ||
92 | DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1), | ||
93 | DEF_FIXED("osc", R8A77995_CLK_OSC, CLK_EXTAL, 384, 1), | ||
94 | DEF_FIXED("r", R8A77995_CLK_R, CLK_EXTAL, 1536, 1), | ||
95 | |||
96 | DEF_GEN3_PE("s1d4c", R8A77995_CLK_S1D4C, CLK_S1, 4, CLK_PE, 2), | ||
97 | DEF_GEN3_PE("s3d1c", R8A77995_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), | ||
98 | DEF_GEN3_PE("s3d2c", R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), | ||
99 | DEF_GEN3_PE("s3d4c", R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), | ||
100 | |||
101 | DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, CLK_SDSRC, 0x268), | ||
102 | |||
103 | DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244), | ||
104 | DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014), | ||
105 | }; | ||
106 | |||
107 | static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = { | ||
108 | DEF_MOD("scif5", 202, R8A77995_CLK_S3D4C), | ||
109 | DEF_MOD("scif4", 203, R8A77995_CLK_S3D4C), | ||
110 | DEF_MOD("scif3", 204, R8A77995_CLK_S3D4C), | ||
111 | DEF_MOD("scif1", 206, R8A77995_CLK_S3D4C), | ||
112 | DEF_MOD("scif0", 207, R8A77995_CLK_S3D4C), | ||
113 | DEF_MOD("msiof3", 208, R8A77995_CLK_MSO), | ||
114 | DEF_MOD("msiof2", 209, R8A77995_CLK_MSO), | ||
115 | DEF_MOD("msiof1", 210, R8A77995_CLK_MSO), | ||
116 | DEF_MOD("msiof0", 211, R8A77995_CLK_MSO), | ||
117 | DEF_MOD("sys-dmac2", 217, R8A77995_CLK_S3D1), | ||
118 | DEF_MOD("sys-dmac1", 218, R8A77995_CLK_S3D1), | ||
119 | DEF_MOD("sys-dmac0", 219, R8A77995_CLK_S3D1), | ||
120 | DEF_MOD("cmt3", 300, R8A77995_CLK_R), | ||
121 | DEF_MOD("cmt2", 301, R8A77995_CLK_R), | ||
122 | DEF_MOD("cmt1", 302, R8A77995_CLK_R), | ||
123 | DEF_MOD("cmt0", 303, R8A77995_CLK_R), | ||
124 | DEF_MOD("scif2", 310, R8A77995_CLK_S3D4C), | ||
125 | DEF_MOD("emmc0", 312, R8A77995_CLK_SD0), | ||
126 | DEF_MOD("usb-dmac0", 330, R8A77995_CLK_S3D1), | ||
127 | DEF_MOD("usb-dmac1", 331, R8A77995_CLK_S3D1), | ||
128 | DEF_MOD("rwdt", 402, R8A77995_CLK_R), | ||
129 | DEF_MOD("intc-ex", 407, R8A77995_CLK_CP), | ||
130 | DEF_MOD("intc-ap", 408, R8A77995_CLK_S3D1), | ||
131 | DEF_MOD("audmac0", 502, R8A77995_CLK_S3D1), | ||
132 | DEF_MOD("hscif3", 517, R8A77995_CLK_S3D1C), | ||
133 | DEF_MOD("hscif0", 520, R8A77995_CLK_S3D1C), | ||
134 | DEF_MOD("thermal", 522, R8A77995_CLK_CP), | ||
135 | DEF_MOD("pwm", 523, R8A77995_CLK_S3D4C), | ||
136 | DEF_MOD("fcpvd1", 602, R8A77995_CLK_S1D2), | ||
137 | DEF_MOD("fcpvd0", 603, R8A77995_CLK_S1D2), | ||
138 | DEF_MOD("fcpvbs", 607, R8A77995_CLK_S0D1), | ||
139 | DEF_MOD("vspd1", 622, R8A77995_CLK_S1D2), | ||
140 | DEF_MOD("vspd0", 623, R8A77995_CLK_S1D2), | ||
141 | DEF_MOD("vspbs", 627, R8A77995_CLK_S0D1), | ||
142 | DEF_MOD("ehci0", 703, R8A77995_CLK_S3D2), | ||
143 | DEF_MOD("hsusb", 704, R8A77995_CLK_S3D2), | ||
144 | DEF_MOD("du1", 723, R8A77995_CLK_S2D1), | ||
145 | DEF_MOD("du0", 724, R8A77995_CLK_S2D1), | ||
146 | DEF_MOD("lvds", 727, R8A77995_CLK_S2D1), | ||
147 | DEF_MOD("vin7", 804, R8A77995_CLK_S1D2), | ||
148 | DEF_MOD("vin6", 805, R8A77995_CLK_S1D2), | ||
149 | DEF_MOD("vin5", 806, R8A77995_CLK_S1D2), | ||
150 | DEF_MOD("vin4", 807, R8A77995_CLK_S1D2), | ||
151 | DEF_MOD("etheravb", 812, R8A77995_CLK_S3D2), | ||
152 | DEF_MOD("imr0", 823, R8A77995_CLK_S1D2), | ||
153 | DEF_MOD("gpio6", 906, R8A77995_CLK_S3D4), | ||
154 | DEF_MOD("gpio5", 907, R8A77995_CLK_S3D4), | ||
155 | DEF_MOD("gpio4", 908, R8A77995_CLK_S3D4), | ||
156 | DEF_MOD("gpio3", 909, R8A77995_CLK_S3D4), | ||
157 | DEF_MOD("gpio2", 910, R8A77995_CLK_S3D4), | ||
158 | DEF_MOD("gpio1", 911, R8A77995_CLK_S3D4), | ||
159 | DEF_MOD("gpio0", 912, R8A77995_CLK_S3D4), | ||
160 | DEF_MOD("can-fd", 914, R8A77995_CLK_S3D2), | ||
161 | DEF_MOD("can-if1", 915, R8A77995_CLK_S3D4), | ||
162 | DEF_MOD("can-if0", 916, R8A77995_CLK_S3D4), | ||
163 | DEF_MOD("i2c3", 928, R8A77995_CLK_S3D2), | ||
164 | DEF_MOD("i2c2", 929, R8A77995_CLK_S3D2), | ||
165 | DEF_MOD("i2c1", 930, R8A77995_CLK_S3D2), | ||
166 | DEF_MOD("i2c0", 931, R8A77995_CLK_S3D2), | ||
167 | DEF_MOD("ssi-all", 1005, R8A77995_CLK_S3D4), | ||
168 | DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), | ||
169 | DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), | ||
170 | DEF_MOD("scu-all", 1017, R8A77995_CLK_S3D4), | ||
171 | DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), | ||
172 | DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), | ||
173 | DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), | ||
174 | DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), | ||
175 | DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), | ||
176 | DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), | ||
177 | }; | ||
178 | |||
179 | static const unsigned int r8a77995_crit_mod_clks[] __initconst = { | ||
180 | MOD_CLK_ID(408), /* INTC-AP (GIC) */ | ||
181 | }; | ||
182 | |||
183 | |||
184 | /* | ||
185 | * CPG Clock Data | ||
186 | */ | ||
187 | |||
188 | /* | ||
189 | * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 | ||
190 | *-------------------------------------------------------------------- | ||
191 | * 0 48 x 1 x250/4 x100/3 x100/3 | ||
192 | * 1 48 x 1 x250/4 x100/3 x116/6 | ||
193 | */ | ||
194 | #define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) | ||
195 | |||
196 | static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = { | ||
197 | /* EXTAL div PLL1 mult/div PLL3 mult/div */ | ||
198 | { 1, 100, 3, 100, 3, }, | ||
199 | { 1, 100, 3, 116, 6, }, | ||
200 | }; | ||
201 | |||
202 | static int __init r8a77995_cpg_mssr_init(struct device *dev) | ||
203 | { | ||
204 | const struct rcar_gen3_cpg_pll_config *cpg_pll_config; | ||
205 | u32 cpg_mode; | ||
206 | int error; | ||
207 | |||
208 | error = rcar_rst_read_mode_pins(&cpg_mode); | ||
209 | if (error) | ||
210 | return error; | ||
211 | |||
212 | cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; | ||
213 | |||
214 | return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode); | ||
215 | } | ||
216 | |||
217 | const struct cpg_mssr_info r8a77995_cpg_mssr_info __initconst = { | ||
218 | /* Core Clocks */ | ||
219 | .core_clks = r8a77995_core_clks, | ||
220 | .num_core_clks = ARRAY_SIZE(r8a77995_core_clks), | ||
221 | .last_dt_core_clk = LAST_DT_CORE_CLK, | ||
222 | .num_total_core_clks = MOD_CLK_BASE, | ||
223 | |||
224 | /* Module Clocks */ | ||
225 | .mod_clks = r8a77995_mod_clks, | ||
226 | .num_mod_clks = ARRAY_SIZE(r8a77995_mod_clks), | ||
227 | .num_hw_mod_clks = 12 * 32, | ||
228 | |||
229 | /* Critical Module Clocks */ | ||
230 | .crit_mod_clks = r8a77995_crit_mod_clks, | ||
231 | .num_crit_mod_clks = ARRAY_SIZE(r8a77995_crit_mod_clks), | ||
232 | |||
233 | /* Callbacks */ | ||
234 | .init = r8a77995_cpg_mssr_init, | ||
235 | .cpg_clk_register = rcar_gen3_cpg_clk_register, | ||
236 | }; | ||
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 3dee900522b7..951105816547 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c | |||
@@ -60,6 +60,7 @@ struct sd_clock { | |||
60 | unsigned int div_num; | 60 | unsigned int div_num; |
61 | unsigned int div_min; | 61 | unsigned int div_min; |
62 | unsigned int div_max; | 62 | unsigned int div_max; |
63 | unsigned int cur_div_idx; | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | /* SDn divider | 66 | /* SDn divider |
@@ -96,21 +97,10 @@ static const struct sd_div_table cpg_sd_div_table[] = { | |||
96 | static int cpg_sd_clock_enable(struct clk_hw *hw) | 97 | static int cpg_sd_clock_enable(struct clk_hw *hw) |
97 | { | 98 | { |
98 | struct sd_clock *clock = to_sd_clock(hw); | 99 | struct sd_clock *clock = to_sd_clock(hw); |
99 | u32 val, sd_fc; | 100 | u32 val = readl(clock->reg); |
100 | unsigned int i; | ||
101 | |||
102 | val = readl(clock->reg); | ||
103 | |||
104 | sd_fc = val & CPG_SD_FC_MASK; | ||
105 | for (i = 0; i < clock->div_num; i++) | ||
106 | if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) | ||
107 | break; | ||
108 | |||
109 | if (i >= clock->div_num) | ||
110 | return -EINVAL; | ||
111 | 101 | ||
112 | val &= ~(CPG_SD_STP_MASK); | 102 | val &= ~(CPG_SD_STP_MASK); |
113 | val |= clock->div_table[i].val & CPG_SD_STP_MASK; | 103 | val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK; |
114 | 104 | ||
115 | writel(val, clock->reg); | 105 | writel(val, clock->reg); |
116 | 106 | ||
@@ -135,21 +125,9 @@ static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, | |||
135 | unsigned long parent_rate) | 125 | unsigned long parent_rate) |
136 | { | 126 | { |
137 | struct sd_clock *clock = to_sd_clock(hw); | 127 | struct sd_clock *clock = to_sd_clock(hw); |
138 | unsigned long rate = parent_rate; | ||
139 | u32 val, sd_fc; | ||
140 | unsigned int i; | ||
141 | 128 | ||
142 | val = readl(clock->reg); | 129 | return DIV_ROUND_CLOSEST(parent_rate, |
143 | 130 | clock->div_table[clock->cur_div_idx].div); | |
144 | sd_fc = val & CPG_SD_FC_MASK; | ||
145 | for (i = 0; i < clock->div_num; i++) | ||
146 | if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) | ||
147 | break; | ||
148 | |||
149 | if (i >= clock->div_num) | ||
150 | return -EINVAL; | ||
151 | |||
152 | return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); | ||
153 | } | 131 | } |
154 | 132 | ||
155 | static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, | 133 | static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, |
@@ -190,6 +168,8 @@ static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, | |||
190 | if (i >= clock->div_num) | 168 | if (i >= clock->div_num) |
191 | return -EINVAL; | 169 | return -EINVAL; |
192 | 170 | ||
171 | clock->cur_div_idx = i; | ||
172 | |||
193 | val = readl(clock->reg); | 173 | val = readl(clock->reg); |
194 | val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); | 174 | val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); |
195 | val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); | 175 | val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); |
@@ -215,6 +195,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, | |||
215 | struct sd_clock *clock; | 195 | struct sd_clock *clock; |
216 | struct clk *clk; | 196 | struct clk *clk; |
217 | unsigned int i; | 197 | unsigned int i; |
198 | u32 sd_fc; | ||
218 | 199 | ||
219 | clock = kzalloc(sizeof(*clock), GFP_KERNEL); | 200 | clock = kzalloc(sizeof(*clock), GFP_KERNEL); |
220 | if (!clock) | 201 | if (!clock) |
@@ -231,6 +212,18 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, | |||
231 | clock->div_table = cpg_sd_div_table; | 212 | clock->div_table = cpg_sd_div_table; |
232 | clock->div_num = ARRAY_SIZE(cpg_sd_div_table); | 213 | clock->div_num = ARRAY_SIZE(cpg_sd_div_table); |
233 | 214 | ||
215 | sd_fc = readl(clock->reg) & CPG_SD_FC_MASK; | ||
216 | for (i = 0; i < clock->div_num; i++) | ||
217 | if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) | ||
218 | break; | ||
219 | |||
220 | if (WARN_ON(i >= clock->div_num)) { | ||
221 | kfree(clock); | ||
222 | return ERR_PTR(-EINVAL); | ||
223 | } | ||
224 | |||
225 | clock->cur_div_idx = i; | ||
226 | |||
234 | clock->div_max = clock->div_table[0].div; | 227 | clock->div_max = clock->div_table[0].div; |
235 | clock->div_min = clock->div_max; | 228 | clock->div_min = clock->div_max; |
236 | for (i = 1; i < clock->div_num; i++) { | 229 | for (i = 1; i < clock->div_num; i++) { |
@@ -279,7 +272,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, | |||
279 | unsigned int div = 1; | 272 | unsigned int div = 1; |
280 | u32 value; | 273 | u32 value; |
281 | 274 | ||
282 | parent = clks[core->parent]; | 275 | parent = clks[core->parent & 0xffff]; /* CLK_TYPE_PE uses high bits */ |
283 | if (IS_ERR(parent)) | 276 | if (IS_ERR(parent)) |
284 | return ERR_CAST(parent); | 277 | return ERR_CAST(parent); |
285 | 278 | ||
@@ -303,6 +296,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, | |||
303 | 296 | ||
304 | case CLK_TYPE_GEN3_PLL1: | 297 | case CLK_TYPE_GEN3_PLL1: |
305 | mult = cpg_pll_config->pll1_mult; | 298 | mult = cpg_pll_config->pll1_mult; |
299 | div = cpg_pll_config->pll1_div; | ||
306 | break; | 300 | break; |
307 | 301 | ||
308 | case CLK_TYPE_GEN3_PLL2: | 302 | case CLK_TYPE_GEN3_PLL2: |
@@ -320,6 +314,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, | |||
320 | 314 | ||
321 | case CLK_TYPE_GEN3_PLL3: | 315 | case CLK_TYPE_GEN3_PLL3: |
322 | mult = cpg_pll_config->pll3_mult; | 316 | mult = cpg_pll_config->pll3_mult; |
317 | div = cpg_pll_config->pll3_div; | ||
323 | break; | 318 | break; |
324 | 319 | ||
325 | case CLK_TYPE_GEN3_PLL4: | 320 | case CLK_TYPE_GEN3_PLL4: |
@@ -360,6 +355,24 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, | |||
360 | parent = clks[cpg_clk_extalr]; | 355 | parent = clks[cpg_clk_extalr]; |
361 | break; | 356 | break; |
362 | 357 | ||
358 | case CLK_TYPE_GEN3_PE: | ||
359 | /* | ||
360 | * Peripheral clock with a fixed divider, selectable between | ||
361 | * clean and spread spectrum parents using MD12 | ||
362 | */ | ||
363 | if (cpg_mode & BIT(12)) { | ||
364 | /* Clean */ | ||
365 | div = core->div & 0xffff; | ||
366 | } else { | ||
367 | /* SCCG */ | ||
368 | parent = clks[core->parent >> 16]; | ||
369 | if (IS_ERR(parent)) | ||
370 | return ERR_CAST(parent); | ||
371 | div = core->div >> 16; | ||
372 | } | ||
373 | mult = 1; | ||
374 | break; | ||
375 | |||
363 | default: | 376 | default: |
364 | return ERR_PTR(-EINVAL); | 377 | return ERR_PTR(-EINVAL); |
365 | } | 378 | } |
diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 073be54b5d03..d756ef8b78eb 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h | |||
@@ -20,15 +20,24 @@ enum rcar_gen3_clk_types { | |||
20 | CLK_TYPE_GEN3_PLL4, | 20 | CLK_TYPE_GEN3_PLL4, |
21 | CLK_TYPE_GEN3_SD, | 21 | CLK_TYPE_GEN3_SD, |
22 | CLK_TYPE_GEN3_R, | 22 | CLK_TYPE_GEN3_R, |
23 | CLK_TYPE_GEN3_PE, | ||
23 | }; | 24 | }; |
24 | 25 | ||
25 | #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ | 26 | #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ |
26 | DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) | 27 | DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) |
27 | 28 | ||
29 | #define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \ | ||
30 | _div_clean) \ | ||
31 | DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE, \ | ||
32 | (_parent_sscg) << 16 | (_parent_clean), \ | ||
33 | .div = (_div_sscg) << 16 | (_div_clean)) | ||
34 | |||
28 | struct rcar_gen3_cpg_pll_config { | 35 | struct rcar_gen3_cpg_pll_config { |
29 | unsigned int extal_div; | 36 | u8 extal_div; |
30 | unsigned int pll1_mult; | 37 | u8 pll1_mult; |
31 | unsigned int pll3_mult; | 38 | u8 pll1_div; |
39 | u8 pll3_mult; | ||
40 | u8 pll3_div; | ||
32 | }; | 41 | }; |
33 | 42 | ||
34 | #define CPG_RCKCR 0x240 | 43 | #define CPG_RCKCR 0x240 |
diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c new file mode 100644 index 000000000000..6cd030a58964 --- /dev/null +++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /* | ||
2 | * Renesas R-Car USB2.0 clock selector | ||
3 | * | ||
4 | * Copyright (C) 2017 Renesas Electronics Corp. | ||
5 | * | ||
6 | * Based on renesas-cpg-mssr.c | ||
7 | * | ||
8 | * Copyright (C) 2015 Glider bvba | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; version 2 of the License. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of_device.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/pm.h> | ||
23 | #include <linux/pm_runtime.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | #define USB20_CLKSET0 0x00 | ||
27 | #define CLKSET0_INTCLK_EN BIT(11) | ||
28 | #define CLKSET0_PRIVATE BIT(0) | ||
29 | #define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE) | ||
30 | |||
31 | struct usb2_clock_sel_priv { | ||
32 | void __iomem *base; | ||
33 | struct clk_hw hw; | ||
34 | bool extal; | ||
35 | bool xtal; | ||
36 | }; | ||
37 | #define to_priv(_hw) container_of(_hw, struct usb2_clock_sel_priv, hw) | ||
38 | |||
39 | static void usb2_clock_sel_enable_extal_only(struct usb2_clock_sel_priv *priv) | ||
40 | { | ||
41 | u16 val = readw(priv->base + USB20_CLKSET0); | ||
42 | |||
43 | pr_debug("%s: enter %d %d %x\n", __func__, | ||
44 | priv->extal, priv->xtal, val); | ||
45 | |||
46 | if (priv->extal && !priv->xtal && val != CLKSET0_EXTAL_ONLY) | ||
47 | writew(CLKSET0_EXTAL_ONLY, priv->base + USB20_CLKSET0); | ||
48 | } | ||
49 | |||
50 | static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv) | ||
51 | { | ||
52 | if (priv->extal && !priv->xtal) | ||
53 | writew(CLKSET0_PRIVATE, priv->base + USB20_CLKSET0); | ||
54 | } | ||
55 | |||
56 | static int usb2_clock_sel_enable(struct clk_hw *hw) | ||
57 | { | ||
58 | usb2_clock_sel_enable_extal_only(to_priv(hw)); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static void usb2_clock_sel_disable(struct clk_hw *hw) | ||
64 | { | ||
65 | usb2_clock_sel_disable_extal_only(to_priv(hw)); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * This module seems a mux, but this driver assumes a gate because | ||
70 | * ehci/ohci platform drivers don't support clk_set_parent() for now. | ||
71 | * If this driver acts as a gate, ehci/ohci-platform drivers don't need | ||
72 | * any modification. | ||
73 | */ | ||
74 | static const struct clk_ops usb2_clock_sel_clock_ops = { | ||
75 | .enable = usb2_clock_sel_enable, | ||
76 | .disable = usb2_clock_sel_disable, | ||
77 | }; | ||
78 | |||
79 | static const struct of_device_id rcar_usb2_clock_sel_match[] = { | ||
80 | { .compatible = "renesas,rcar-gen3-usb2-clock-sel" }, | ||
81 | { } | ||
82 | }; | ||
83 | |||
84 | static int rcar_usb2_clock_sel_suspend(struct device *dev) | ||
85 | { | ||
86 | struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev); | ||
87 | |||
88 | usb2_clock_sel_disable_extal_only(priv); | ||
89 | pm_runtime_put(dev); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static int rcar_usb2_clock_sel_resume(struct device *dev) | ||
95 | { | ||
96 | struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev); | ||
97 | |||
98 | pm_runtime_get_sync(dev); | ||
99 | usb2_clock_sel_enable_extal_only(priv); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static int rcar_usb2_clock_sel_remove(struct platform_device *pdev) | ||
105 | { | ||
106 | struct device *dev = &pdev->dev; | ||
107 | struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev); | ||
108 | |||
109 | of_clk_del_provider(dev->of_node); | ||
110 | clk_hw_unregister(&priv->hw); | ||
111 | pm_runtime_put(dev); | ||
112 | pm_runtime_disable(dev); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) | ||
118 | { | ||
119 | struct device *dev = &pdev->dev; | ||
120 | struct device_node *np = dev->of_node; | ||
121 | struct usb2_clock_sel_priv *priv; | ||
122 | struct resource *res; | ||
123 | struct clk *clk; | ||
124 | struct clk_init_data init; | ||
125 | |||
126 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
127 | if (!priv) | ||
128 | return -ENOMEM; | ||
129 | |||
130 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
131 | priv->base = devm_ioremap_resource(dev, res); | ||
132 | if (IS_ERR(priv->base)) | ||
133 | return PTR_ERR(priv->base); | ||
134 | |||
135 | pm_runtime_enable(dev); | ||
136 | pm_runtime_get_sync(dev); | ||
137 | |||
138 | clk = devm_clk_get(dev, "usb_extal"); | ||
139 | if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { | ||
140 | priv->extal = !!clk_get_rate(clk); | ||
141 | clk_disable_unprepare(clk); | ||
142 | } | ||
143 | clk = devm_clk_get(dev, "usb_xtal"); | ||
144 | if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { | ||
145 | priv->xtal = !!clk_get_rate(clk); | ||
146 | clk_disable_unprepare(clk); | ||
147 | } | ||
148 | |||
149 | if (!priv->extal && !priv->xtal) { | ||
150 | dev_err(dev, "This driver needs usb_extal or usb_xtal\n"); | ||
151 | return -ENOENT; | ||
152 | } | ||
153 | |||
154 | platform_set_drvdata(pdev, priv); | ||
155 | dev_set_drvdata(dev, priv); | ||
156 | |||
157 | init.name = "rcar_usb2_clock_sel"; | ||
158 | init.ops = &usb2_clock_sel_clock_ops; | ||
159 | init.flags = 0; | ||
160 | init.parent_names = NULL; | ||
161 | init.num_parents = 0; | ||
162 | priv->hw.init = &init; | ||
163 | |||
164 | clk = clk_register(NULL, &priv->hw); | ||
165 | if (IS_ERR(clk)) | ||
166 | return PTR_ERR(clk); | ||
167 | |||
168 | return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); | ||
169 | } | ||
170 | |||
171 | static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = { | ||
172 | .suspend = rcar_usb2_clock_sel_suspend, | ||
173 | .resume = rcar_usb2_clock_sel_resume, | ||
174 | }; | ||
175 | |||
176 | static struct platform_driver rcar_usb2_clock_sel_driver = { | ||
177 | .driver = { | ||
178 | .name = "rcar-usb2-clock-sel", | ||
179 | .of_match_table = rcar_usb2_clock_sel_match, | ||
180 | .pm = &rcar_usb2_clock_sel_pm_ops, | ||
181 | }, | ||
182 | .probe = rcar_usb2_clock_sel_probe, | ||
183 | .remove = rcar_usb2_clock_sel_remove, | ||
184 | }; | ||
185 | builtin_platform_driver(rcar_usb2_clock_sel_driver); | ||
186 | |||
187 | MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver"); | ||
188 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 1f607c806f9b..e580a5e6346c 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c | |||
@@ -680,6 +680,12 @@ static const struct of_device_id cpg_mssr_match[] = { | |||
680 | .data = &r8a7796_cpg_mssr_info, | 680 | .data = &r8a7796_cpg_mssr_info, |
681 | }, | 681 | }, |
682 | #endif | 682 | #endif |
683 | #ifdef CONFIG_CLK_R8A77995 | ||
684 | { | ||
685 | .compatible = "renesas,r8a77995-cpg-mssr", | ||
686 | .data = &r8a77995_cpg_mssr_info, | ||
687 | }, | ||
688 | #endif | ||
683 | { /* sentinel */ } | 689 | { /* sentinel */ } |
684 | }; | 690 | }; |
685 | 691 | ||
diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 43d7c7f6832d..94b9071d1061 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h | |||
@@ -138,6 +138,7 @@ extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; | |||
138 | extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; | 138 | extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; |
139 | extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; | 139 | extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; |
140 | extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; | 140 | extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; |
141 | extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; | ||
141 | 142 | ||
142 | 143 | ||
143 | /* | 144 | /* |
diff --git a/drivers/clk/rockchip/clk-rk3128.c b/drivers/clk/rockchip/clk-rk3128.c index e243f2eae68f..62d7854e4b87 100644 --- a/drivers/clk/rockchip/clk-rk3128.c +++ b/drivers/clk/rockchip/clk-rk3128.c | |||
@@ -201,7 +201,7 @@ static struct rockchip_clk_branch rk3128_uart2_fracmux __initdata = | |||
201 | MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, | 201 | MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, |
202 | RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); | 202 | RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); |
203 | 203 | ||
204 | static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { | 204 | static struct rockchip_clk_branch common_clk_branches[] __initdata = { |
205 | /* | 205 | /* |
206 | * Clock-Architecture Diagram 1 | 206 | * Clock-Architecture Diagram 1 |
207 | */ | 207 | */ |
@@ -459,10 +459,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { | |||
459 | RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS, | 459 | RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS, |
460 | RK2928_CLKGATE_CON(10), 15, GFLAGS), | 460 | RK2928_CLKGATE_CON(10), 15, GFLAGS), |
461 | 461 | ||
462 | COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0, | ||
463 | RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
464 | RK2928_CLKGATE_CON(3), 15, GFLAGS), | ||
465 | |||
466 | COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0, | 462 | COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0, |
467 | RK2928_CLKSEL_CON(29), 8, 6, DFLAGS, | 463 | RK2928_CLKSEL_CON(29), 8, 6, DFLAGS, |
468 | RK2928_CLKGATE_CON(1), 0, GFLAGS), | 464 | RK2928_CLKGATE_CON(1), 0, GFLAGS), |
@@ -495,7 +491,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { | |||
495 | GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), | 491 | GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), |
496 | GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS), | 492 | GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS), |
497 | GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), | 493 | GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), |
498 | GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), | ||
499 | 494 | ||
500 | GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), | 495 | GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), |
501 | GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), | 496 | GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), |
@@ -541,7 +536,6 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { | |||
541 | GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS), | 536 | GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS), |
542 | GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), | 537 | GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), |
543 | 538 | ||
544 | GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), | ||
545 | GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), | 539 | GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), |
546 | GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS), | 540 | GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS), |
547 | GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), | 541 | GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), |
@@ -561,6 +555,21 @@ static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { | |||
561 | MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), | 555 | MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), |
562 | }; | 556 | }; |
563 | 557 | ||
558 | static struct rockchip_clk_branch rk3126_clk_branches[] __initdata = { | ||
559 | GATE(0, "pclk_stimer", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS), | ||
560 | GATE(0, "pclk_s_efuse", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), | ||
561 | GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 8, GFLAGS), | ||
562 | }; | ||
563 | |||
564 | static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { | ||
565 | COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0, | ||
566 | RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
567 | RK2928_CLKGATE_CON(3), 15, GFLAGS), | ||
568 | |||
569 | GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), | ||
570 | GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), | ||
571 | }; | ||
572 | |||
564 | static const char *const rk3128_critical_clocks[] __initconst = { | 573 | static const char *const rk3128_critical_clocks[] __initconst = { |
565 | "aclk_cpu", | 574 | "aclk_cpu", |
566 | "hclk_cpu", | 575 | "hclk_cpu", |
@@ -570,7 +579,7 @@ static const char *const rk3128_critical_clocks[] __initconst = { | |||
570 | "pclk_peri", | 579 | "pclk_peri", |
571 | }; | 580 | }; |
572 | 581 | ||
573 | static void __init rk3128_clk_init(struct device_node *np) | 582 | static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np) |
574 | { | 583 | { |
575 | struct rockchip_clk_provider *ctx; | 584 | struct rockchip_clk_provider *ctx; |
576 | void __iomem *reg_base; | 585 | void __iomem *reg_base; |
@@ -578,23 +587,21 @@ static void __init rk3128_clk_init(struct device_node *np) | |||
578 | reg_base = of_iomap(np, 0); | 587 | reg_base = of_iomap(np, 0); |
579 | if (!reg_base) { | 588 | if (!reg_base) { |
580 | pr_err("%s: could not map cru region\n", __func__); | 589 | pr_err("%s: could not map cru region\n", __func__); |
581 | return; | 590 | return ERR_PTR(-ENOMEM); |
582 | } | 591 | } |
583 | 592 | ||
584 | ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); | 593 | ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); |
585 | if (IS_ERR(ctx)) { | 594 | if (IS_ERR(ctx)) { |
586 | pr_err("%s: rockchip clk init failed\n", __func__); | 595 | pr_err("%s: rockchip clk init failed\n", __func__); |
587 | iounmap(reg_base); | 596 | iounmap(reg_base); |
588 | return; | 597 | return ERR_PTR(-ENOMEM); |
589 | } | 598 | } |
590 | 599 | ||
591 | rockchip_clk_register_plls(ctx, rk3128_pll_clks, | 600 | rockchip_clk_register_plls(ctx, rk3128_pll_clks, |
592 | ARRAY_SIZE(rk3128_pll_clks), | 601 | ARRAY_SIZE(rk3128_pll_clks), |
593 | RK3128_GRF_SOC_STATUS0); | 602 | RK3128_GRF_SOC_STATUS0); |
594 | rockchip_clk_register_branches(ctx, rk3128_clk_branches, | 603 | rockchip_clk_register_branches(ctx, common_clk_branches, |
595 | ARRAY_SIZE(rk3128_clk_branches)); | 604 | ARRAY_SIZE(common_clk_branches)); |
596 | rockchip_clk_protect_critical(rk3128_critical_clocks, | ||
597 | ARRAY_SIZE(rk3128_critical_clocks)); | ||
598 | 605 | ||
599 | rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", | 606 | rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", |
600 | mux_armclk_p, ARRAY_SIZE(mux_armclk_p), | 607 | mux_armclk_p, ARRAY_SIZE(mux_armclk_p), |
@@ -606,6 +613,40 @@ static void __init rk3128_clk_init(struct device_node *np) | |||
606 | 613 | ||
607 | rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); | 614 | rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); |
608 | 615 | ||
616 | return ctx; | ||
617 | } | ||
618 | |||
619 | static void __init rk3126_clk_init(struct device_node *np) | ||
620 | { | ||
621 | struct rockchip_clk_provider *ctx; | ||
622 | |||
623 | ctx = rk3128_common_clk_init(np); | ||
624 | if (IS_ERR(ctx)) | ||
625 | return; | ||
626 | |||
627 | rockchip_clk_register_branches(ctx, rk3126_clk_branches, | ||
628 | ARRAY_SIZE(rk3126_clk_branches)); | ||
629 | rockchip_clk_protect_critical(rk3128_critical_clocks, | ||
630 | ARRAY_SIZE(rk3128_critical_clocks)); | ||
631 | |||
632 | rockchip_clk_of_add_provider(np, ctx); | ||
633 | } | ||
634 | |||
635 | CLK_OF_DECLARE(rk3126_cru, "rockchip,rk3126-cru", rk3126_clk_init); | ||
636 | |||
637 | static void __init rk3128_clk_init(struct device_node *np) | ||
638 | { | ||
639 | struct rockchip_clk_provider *ctx; | ||
640 | |||
641 | ctx = rk3128_common_clk_init(np); | ||
642 | if (IS_ERR(ctx)) | ||
643 | return; | ||
644 | |||
645 | rockchip_clk_register_branches(ctx, rk3128_clk_branches, | ||
646 | ARRAY_SIZE(rk3128_clk_branches)); | ||
647 | rockchip_clk_protect_critical(rk3128_critical_clocks, | ||
648 | ARRAY_SIZE(rk3128_critical_clocks)); | ||
649 | |||
609 | rockchip_clk_of_add_provider(np, ctx); | 650 | rockchip_clk_of_add_provider(np, ctx); |
610 | } | 651 | } |
611 | 652 | ||
diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index bb405d9044a3..11e7f2d1c054 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c | |||
@@ -391,7 +391,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { | |||
391 | RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS, | 391 | RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS, |
392 | RK2928_CLKGATE_CON(2), 11, GFLAGS), | 392 | RK2928_CLKGATE_CON(2), 11, GFLAGS), |
393 | 393 | ||
394 | COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0, | 394 | COMPOSITE_NODIV(SCLK_SDIO_SRC, "sclk_sdio_src", mux_mmc_src_p, 0, |
395 | RK2928_CLKSEL_CON(11), 10, 2, MFLAGS, | 395 | RK2928_CLKSEL_CON(11), 10, 2, MFLAGS, |
396 | RK2928_CLKGATE_CON(2), 13, GFLAGS), | 396 | RK2928_CLKGATE_CON(2), 13, GFLAGS), |
397 | DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0, | 397 | DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0, |
diff --git a/drivers/clk/rockchip/clk-rv1108.c b/drivers/clk/rockchip/clk-rv1108.c index 7c05ab366348..089cb17925e5 100644 --- a/drivers/clk/rockchip/clk-rv1108.c +++ b/drivers/clk/rockchip/clk-rv1108.c | |||
@@ -93,9 +93,24 @@ static struct rockchip_pll_rate_table rv1108_pll_rates[] = { | |||
93 | } | 93 | } |
94 | 94 | ||
95 | static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = { | 95 | static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = { |
96 | RV1108_CPUCLK_RATE(816000000, 4), | 96 | RV1108_CPUCLK_RATE(1608000000, 7), |
97 | RV1108_CPUCLK_RATE(600000000, 4), | 97 | RV1108_CPUCLK_RATE(1512000000, 7), |
98 | RV1108_CPUCLK_RATE(312000000, 4), | 98 | RV1108_CPUCLK_RATE(1488000000, 5), |
99 | RV1108_CPUCLK_RATE(1416000000, 5), | ||
100 | RV1108_CPUCLK_RATE(1392000000, 5), | ||
101 | RV1108_CPUCLK_RATE(1296000000, 5), | ||
102 | RV1108_CPUCLK_RATE(1200000000, 5), | ||
103 | RV1108_CPUCLK_RATE(1104000000, 5), | ||
104 | RV1108_CPUCLK_RATE(1008000000, 5), | ||
105 | RV1108_CPUCLK_RATE(912000000, 5), | ||
106 | RV1108_CPUCLK_RATE(816000000, 3), | ||
107 | RV1108_CPUCLK_RATE(696000000, 3), | ||
108 | RV1108_CPUCLK_RATE(600000000, 3), | ||
109 | RV1108_CPUCLK_RATE(500000000, 3), | ||
110 | RV1108_CPUCLK_RATE(408000000, 1), | ||
111 | RV1108_CPUCLK_RATE(312000000, 1), | ||
112 | RV1108_CPUCLK_RATE(216000000, 1), | ||
113 | RV1108_CPUCLK_RATE(96000000, 1), | ||
99 | }; | 114 | }; |
100 | 115 | ||
101 | static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = { | 116 | static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = { |
@@ -105,7 +120,7 @@ static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = { | |||
105 | .mux_core_alt = 1, | 120 | .mux_core_alt = 1, |
106 | .mux_core_main = 0, | 121 | .mux_core_main = 0, |
107 | .mux_core_shift = 8, | 122 | .mux_core_shift = 8, |
108 | .mux_core_mask = 0x1, | 123 | .mux_core_mask = 0x3, |
109 | }; | 124 | }; |
110 | 125 | ||
111 | PNAME(mux_pll_p) = { "xin24m", "xin24m"}; | 126 | PNAME(mux_pll_p) = { "xin24m", "xin24m"}; |
@@ -114,30 +129,42 @@ PNAME(mux_armclk_p) = { "apll_core", "gpll_core", "dpll_core" }; | |||
114 | PNAME(mux_usb480m_pre_p) = { "usbphy", "xin24m" }; | 129 | PNAME(mux_usb480m_pre_p) = { "usbphy", "xin24m" }; |
115 | PNAME(mux_hdmiphy_phy_p) = { "hdmiphy", "xin24m" }; | 130 | PNAME(mux_hdmiphy_phy_p) = { "hdmiphy", "xin24m" }; |
116 | PNAME(mux_dclk_hdmiphy_pre_p) = { "dclk_hdmiphy_src_gpll", "dclk_hdmiphy_src_dpll" }; | 131 | PNAME(mux_dclk_hdmiphy_pre_p) = { "dclk_hdmiphy_src_gpll", "dclk_hdmiphy_src_dpll" }; |
117 | PNAME(mux_pll_src_4plls_p) = { "dpll", "hdmiphy", "gpll", "usb480m" }; | 132 | PNAME(mux_pll_src_4plls_p) = { "dpll", "gpll", "hdmiphy", "usb480m" }; |
118 | PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" }; | 133 | PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" }; |
119 | PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" }; | 134 | PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" }; |
120 | PNAME(mux_pll_src_apll_gpll_p) = { "apll", "gpll" }; | 135 | PNAME(mux_pll_src_apll_gpll_p) = { "apll", "gpll" }; |
121 | PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_dpll", "aclk_peri_src_gpll" }; | 136 | PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_gpll", "aclk_peri_src_dpll" }; |
122 | PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" }; | 137 | PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" }; |
123 | PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" }; | 138 | PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" }; |
124 | PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" }; | 139 | PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" }; |
125 | PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; | 140 | PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; |
126 | PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; | 141 | PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; |
127 | PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; | 142 | PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; |
128 | PNAME(mux_sclk_macphy_p) = { "sclk_macphy_pre", "ext_gmac" }; | 143 | PNAME(mux_sclk_mac_p) = { "sclk_mac_pre", "ext_gmac" }; |
129 | PNAME(mux_i2s0_pre_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; | 144 | PNAME(mux_i2s0_pre_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; |
130 | PNAME(mux_i2s_out_p) = { "i2s0_pre", "xin12m" }; | 145 | PNAME(mux_i2s_out_p) = { "i2s0_pre", "xin12m" }; |
131 | PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "xin12m" }; | 146 | PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "dummy", "xin12m" }; |
132 | PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" }; | 147 | PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "dummy", "xin12m" }; |
148 | PNAME(mux_wifi_src_p) = { "gpll", "xin24m" }; | ||
149 | PNAME(mux_cifout_src_p) = { "hdmiphy", "gpll" }; | ||
150 | PNAME(mux_cifout_p) = { "sclk_cifout_src", "xin24m" }; | ||
151 | PNAME(mux_sclk_cif0_src_p) = { "pclk_vip", "clk_cif0_chn_out", "pclkin_cvbs2cif" }; | ||
152 | PNAME(mux_sclk_cif1_src_p) = { "pclk_vip", "clk_cif1_chn_out", "pclkin_cvbs2cif" }; | ||
153 | PNAME(mux_sclk_cif2_src_p) = { "pclk_vip", "clk_cif2_chn_out", "pclkin_cvbs2cif" }; | ||
154 | PNAME(mux_sclk_cif3_src_p) = { "pclk_vip", "clk_cif3_chn_out", "pclkin_cvbs2cif" }; | ||
155 | PNAME(mux_dsp_src_p) = { "dpll", "gpll", "apll", "usb480m" }; | ||
156 | PNAME(mux_dclk_hdmiphy_p) = { "hdmiphy", "xin24m" }; | ||
157 | PNAME(mux_dclk_vop_p) = { "dclk_hdmiphy", "dclk_vop_src" }; | ||
158 | PNAME(mux_hdmi_cec_src_p) = { "dpll", "gpll", "xin24m" }; | ||
159 | PNAME(mux_cvbs_src_p) = { "apll", "io_cvbs_clkin", "hdmiphy", "gpll" }; | ||
133 | 160 | ||
134 | static struct rockchip_pll_clock rv1108_pll_clks[] __initdata = { | 161 | static struct rockchip_pll_clock rv1108_pll_clks[] __initdata = { |
135 | [apll] = PLL(pll_rk3399, PLL_APLL, "apll", mux_pll_p, 0, RV1108_PLL_CON(0), | 162 | [apll] = PLL(pll_rk3399, PLL_APLL, "apll", mux_pll_p, 0, RV1108_PLL_CON(0), |
136 | RV1108_PLL_CON(3), 8, 31, 0, rv1108_pll_rates), | 163 | RV1108_PLL_CON(3), 8, 0, 0, rv1108_pll_rates), |
137 | [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RV1108_PLL_CON(8), | 164 | [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RV1108_PLL_CON(8), |
138 | RV1108_PLL_CON(11), 8, 31, 0, NULL), | 165 | RV1108_PLL_CON(11), 8, 1, 0, NULL), |
139 | [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RV1108_PLL_CON(16), | 166 | [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RV1108_PLL_CON(16), |
140 | RV1108_PLL_CON(19), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rv1108_pll_rates), | 167 | RV1108_PLL_CON(19), 8, 2, 0, rv1108_pll_rates), |
141 | }; | 168 | }; |
142 | 169 | ||
143 | #define MFLAGS CLK_MUX_HIWORD_MASK | 170 | #define MFLAGS CLK_MUX_HIWORD_MASK |
@@ -170,10 +197,10 @@ static struct rockchip_clk_branch rv1108_i2s2_fracmux __initdata = | |||
170 | RV1108_CLKSEL_CON(7), 12, 2, MFLAGS); | 197 | RV1108_CLKSEL_CON(7), 12, 2, MFLAGS); |
171 | 198 | ||
172 | static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | 199 | static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { |
173 | MUX(0, "hdmi_phy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT, | 200 | MUX(0, "hdmiphy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT, |
174 | RV1108_MISC_CON, 13, 2, MFLAGS), | 201 | RV1108_MISC_CON, 13, 1, MFLAGS), |
175 | MUX(0, "usb480m", mux_usb480m_pre_p, CLK_SET_RATE_PARENT, | 202 | MUX(0, "usb480m", mux_usb480m_pre_p, CLK_SET_RATE_PARENT, |
176 | RV1108_MISC_CON, 15, 2, MFLAGS), | 203 | RV1108_MISC_CON, 15, 1, MFLAGS), |
177 | /* | 204 | /* |
178 | * Clock-Architecture Diagram 2 | 205 | * Clock-Architecture Diagram 2 |
179 | */ | 206 | */ |
@@ -197,50 +224,212 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
197 | RV1108_CLKGATE_CON(11), 1, GFLAGS), | 224 | RV1108_CLKGATE_CON(11), 1, GFLAGS), |
198 | 225 | ||
199 | /* PD_RKVENC */ | 226 | /* PD_RKVENC */ |
227 | COMPOSITE(0, "aclk_rkvenc_pre", mux_pll_src_4plls_p, 0, | ||
228 | RV1108_CLKSEL_CON(37), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
229 | RV1108_CLKGATE_CON(8), 8, GFLAGS), | ||
230 | FACTOR_GATE(0, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0, 1, 4, | ||
231 | RV1108_CLKGATE_CON(8), 10, GFLAGS), | ||
232 | COMPOSITE(SCLK_VENC_CORE, "clk_venc_core", mux_pll_src_4plls_p, 0, | ||
233 | RV1108_CLKSEL_CON(37), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
234 | RV1108_CLKGATE_CON(8), 9, GFLAGS), | ||
235 | GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0, | ||
236 | RV1108_CLKGATE_CON(19), 8, GFLAGS), | ||
237 | GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0, | ||
238 | RV1108_CLKGATE_CON(19), 9, GFLAGS), | ||
239 | GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc_pre", CLK_IGNORE_UNUSED, | ||
240 | RV1108_CLKGATE_CON(19), 11, GFLAGS), | ||
241 | GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc_pre", CLK_IGNORE_UNUSED, | ||
242 | RV1108_CLKGATE_CON(19), 10, GFLAGS), | ||
200 | 243 | ||
201 | /* PD_RKVDEC */ | 244 | /* PD_RKVDEC */ |
245 | COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_4plls_p, 0, | ||
246 | RV1108_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
247 | RV1108_CLKGATE_CON(8), 2, GFLAGS), | ||
248 | FACTOR_GATE(0, "hclk_rkvdec_pre", "sclk_hevc_core", 0, 1, 4, | ||
249 | RV1108_CLKGATE_CON(8), 10, GFLAGS), | ||
250 | COMPOSITE(SCLK_HEVC_CABAC, "clk_hevc_cabac", mux_pll_src_4plls_p, 0, | ||
251 | RV1108_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
252 | RV1108_CLKGATE_CON(8), 1, GFLAGS), | ||
253 | |||
254 | COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, | ||
255 | RV1108_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
256 | RV1108_CLKGATE_CON(8), 0, GFLAGS), | ||
257 | COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, | ||
258 | RV1108_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
259 | RV1108_CLKGATE_CON(8), 3, GFLAGS), | ||
260 | GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, | ||
261 | RV1108_CLKGATE_CON(19), 0, GFLAGS), | ||
262 | GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, | ||
263 | RV1108_CLKGATE_CON(19), 1, GFLAGS), | ||
264 | GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, | ||
265 | RV1108_CLKGATE_CON(19), 2, GFLAGS), | ||
266 | GATE(HCLK_VPU, "hclk_vpu", "hclk_rkvdec_pre", 0, | ||
267 | RV1108_CLKGATE_CON(19), 3, GFLAGS), | ||
268 | GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED, | ||
269 | RV1108_CLKGATE_CON(19), 4, GFLAGS), | ||
270 | GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED, | ||
271 | RV1108_CLKGATE_CON(19), 5, GFLAGS), | ||
272 | GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED, | ||
273 | RV1108_CLKGATE_CON(19), 6, GFLAGS), | ||
202 | 274 | ||
203 | /* PD_PMU_wrapper */ | 275 | /* PD_PMU_wrapper */ |
204 | COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED, | 276 | COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED, |
205 | RV1108_CLKSEL_CON(38), 0, 5, DFLAGS, | 277 | RV1108_CLKSEL_CON(38), 0, 5, DFLAGS, |
206 | RV1108_CLKGATE_CON(8), 12, GFLAGS), | 278 | RV1108_CLKGATE_CON(8), 12, GFLAGS), |
207 | GATE(0, "pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 279 | GATE(0, "pclk_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, |
208 | RV1108_CLKGATE_CON(10), 0, GFLAGS), | 280 | RV1108_CLKGATE_CON(10), 0, GFLAGS), |
209 | GATE(0, "intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 281 | GATE(0, "pclk_intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED, |
210 | RV1108_CLKGATE_CON(10), 1, GFLAGS), | 282 | RV1108_CLKGATE_CON(10), 1, GFLAGS), |
211 | GATE(0, "gpio0_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 283 | GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pmu_24m_ena", 0, |
212 | RV1108_CLKGATE_CON(10), 2, GFLAGS), | 284 | RV1108_CLKGATE_CON(10), 2, GFLAGS), |
213 | GATE(0, "pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 285 | GATE(0, "pclk_pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED, |
214 | RV1108_CLKGATE_CON(10), 3, GFLAGS), | 286 | RV1108_CLKGATE_CON(10), 3, GFLAGS), |
215 | GATE(0, "pmu_noc", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 287 | GATE(0, "pclk_pmu_niu", "pmu_24m_ena", CLK_IGNORE_UNUSED, |
216 | RV1108_CLKGATE_CON(10), 4, GFLAGS), | 288 | RV1108_CLKGATE_CON(10), 4, GFLAGS), |
217 | GATE(0, "i2c0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 289 | GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pmu_24m_ena", 0, |
218 | RV1108_CLKGATE_CON(10), 5, GFLAGS), | 290 | RV1108_CLKGATE_CON(10), 5, GFLAGS), |
219 | GATE(0, "pwm0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED, | 291 | GATE(PCLK_PWM0_PMU, "pclk_pwm0_pmu", "pmu_24m_ena", 0, |
220 | RV1108_CLKGATE_CON(10), 6, GFLAGS), | 292 | RV1108_CLKGATE_CON(10), 6, GFLAGS), |
221 | COMPOSITE(0, "pwm0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, | 293 | COMPOSITE(SCLK_PWM0_PMU, "sclk_pwm0_pmu", mux_pll_src_2plls_p, 0, |
222 | RV1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS, | 294 | RV1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS, |
223 | RV1108_CLKGATE_CON(8), 15, GFLAGS), | 295 | RV1108_CLKGATE_CON(8), 15, GFLAGS), |
224 | COMPOSITE(0, "i2c0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, | 296 | COMPOSITE(SCLK_I2C0_PMU, "sclk_i2c0_pmu", mux_pll_src_2plls_p, 0, |
225 | RV1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS, | 297 | RV1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS, |
226 | RV1108_CLKGATE_CON(8), 14, GFLAGS), | 298 | RV1108_CLKGATE_CON(8), 14, GFLAGS), |
227 | GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, | 299 | GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, |
228 | RV1108_CLKGATE_CON(8), 13, GFLAGS), | 300 | RV1108_CLKGATE_CON(8), 13, GFLAGS), |
229 | 301 | ||
230 | /* | 302 | /* |
303 | * Clock-Architecture Diagram 3 | ||
304 | */ | ||
305 | COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_wifi_src_p, 0, | ||
306 | RV1108_CLKSEL_CON(28), 15, 1, MFLAGS, 8, 6, DFLAGS, | ||
307 | RV1108_CLKGATE_CON(9), 8, GFLAGS), | ||
308 | COMPOSITE_NODIV(0, "sclk_cifout_src", mux_cifout_src_p, 0, | ||
309 | RV1108_CLKSEL_CON(40), 8, 1, MFLAGS, | ||
310 | RV1108_CLKGATE_CON(9), 11, GFLAGS), | ||
311 | COMPOSITE_NOGATE(SCLK_CIFOUT, "sclk_cifout", mux_cifout_p, 0, | ||
312 | RV1108_CLKSEL_CON(40), 12, 1, MFLAGS, 0, 5, DFLAGS), | ||
313 | COMPOSITE_NOMUX(SCLK_MIPI_CSI_OUT, "sclk_mipi_csi_out", "xin24m", 0, | ||
314 | RV1108_CLKSEL_CON(41), 0, 5, DFLAGS, | ||
315 | RV1108_CLKGATE_CON(9), 12, GFLAGS), | ||
316 | |||
317 | GATE(0, "pclk_acodecphy", "pclk_top_pre", CLK_IGNORE_UNUSED, | ||
318 | RV1108_CLKGATE_CON(14), 6, GFLAGS), | ||
319 | GATE(0, "pclk_usbgrf", "pclk_top_pre", CLK_IGNORE_UNUSED, | ||
320 | RV1108_CLKGATE_CON(14), 14, GFLAGS), | ||
321 | |||
322 | GATE(ACLK_CIF0, "aclk_cif0", "aclk_vio1_pre", 0, | ||
323 | RV1108_CLKGATE_CON(18), 10, GFLAGS), | ||
324 | GATE(HCLK_CIF0, "hclk_cif0", "hclk_vio_pre", 0, | ||
325 | RV1108_CLKGATE_CON(18), 10, GFLAGS), | ||
326 | COMPOSITE_NODIV(SCLK_CIF0, "sclk_cif0", mux_sclk_cif0_src_p, 0, | ||
327 | RV1108_CLKSEL_CON(31), 0, 2, MFLAGS, | ||
328 | RV1108_CLKGATE_CON(7), 9, GFLAGS), | ||
329 | GATE(ACLK_CIF1, "aclk_cif1", "aclk_vio1_pre", 0, | ||
330 | RV1108_CLKGATE_CON(17), 6, GFLAGS), | ||
331 | GATE(HCLK_CIF1, "hclk_cif1", "hclk_vio_pre", 0, | ||
332 | RV1108_CLKGATE_CON(17), 7, GFLAGS), | ||
333 | COMPOSITE_NODIV(SCLK_CIF1, "sclk_cif1", mux_sclk_cif1_src_p, 0, | ||
334 | RV1108_CLKSEL_CON(31), 2, 2, MFLAGS, | ||
335 | RV1108_CLKGATE_CON(7), 10, GFLAGS), | ||
336 | GATE(ACLK_CIF2, "aclk_cif2", "aclk_vio1_pre", 0, | ||
337 | RV1108_CLKGATE_CON(17), 8, GFLAGS), | ||
338 | GATE(HCLK_CIF2, "hclk_cif2", "hclk_vio_pre", 0, | ||
339 | RV1108_CLKGATE_CON(17), 9, GFLAGS), | ||
340 | COMPOSITE_NODIV(SCLK_CIF2, "sclk_cif2", mux_sclk_cif2_src_p, 0, | ||
341 | RV1108_CLKSEL_CON(31), 4, 2, MFLAGS, | ||
342 | RV1108_CLKGATE_CON(7), 11, GFLAGS), | ||
343 | GATE(ACLK_CIF3, "aclk_cif3", "aclk_vio1_pre", 0, | ||
344 | RV1108_CLKGATE_CON(17), 10, GFLAGS), | ||
345 | GATE(HCLK_CIF3, "hclk_cif3", "hclk_vio_pre", 0, | ||
346 | RV1108_CLKGATE_CON(17), 11, GFLAGS), | ||
347 | COMPOSITE_NODIV(SCLK_CIF3, "sclk_cif3", mux_sclk_cif3_src_p, 0, | ||
348 | RV1108_CLKSEL_CON(31), 6, 2, MFLAGS, | ||
349 | RV1108_CLKGATE_CON(7), 12, GFLAGS), | ||
350 | GATE(0, "pclk_cif1to4", "pclk_vip", CLK_IGNORE_UNUSED, | ||
351 | RV1108_CLKGATE_CON(7), 8, GFLAGS), | ||
352 | |||
353 | /* PD_DSP_wrapper */ | ||
354 | COMPOSITE(SCLK_DSP, "sclk_dsp", mux_dsp_src_p, 0, | ||
355 | RV1108_CLKSEL_CON(42), 8, 2, MFLAGS, 0, 5, DFLAGS, | ||
356 | RV1108_CLKGATE_CON(9), 0, GFLAGS), | ||
357 | GATE(0, "clk_dsp_sys_wd", "sclk_dsp", CLK_IGNORE_UNUSED, | ||
358 | RV1108_CLKGATE_CON(16), 0, GFLAGS), | ||
359 | GATE(0, "clk_dsp_epp_wd", "sclk_dsp", CLK_IGNORE_UNUSED, | ||
360 | RV1108_CLKGATE_CON(16), 1, GFLAGS), | ||
361 | GATE(0, "clk_dsp_edp_wd", "sclk_dsp", CLK_IGNORE_UNUSED, | ||
362 | RV1108_CLKGATE_CON(16), 2, GFLAGS), | ||
363 | GATE(0, "clk_dsp_iop_wd", "sclk_dsp", CLK_IGNORE_UNUSED, | ||
364 | RV1108_CLKGATE_CON(16), 3, GFLAGS), | ||
365 | GATE(0, "clk_dsp_free", "sclk_dsp", CLK_IGNORE_UNUSED, | ||
366 | RV1108_CLKGATE_CON(16), 13, GFLAGS), | ||
367 | COMPOSITE_NOMUX(SCLK_DSP_IOP, "sclk_dsp_iop", "sclk_dsp", 0, | ||
368 | RV1108_CLKSEL_CON(44), 0, 5, DFLAGS, | ||
369 | RV1108_CLKGATE_CON(9), 1, GFLAGS), | ||
370 | COMPOSITE_NOMUX(SCLK_DSP_EPP, "sclk_dsp_epp", "sclk_dsp", 0, | ||
371 | RV1108_CLKSEL_CON(44), 8, 5, DFLAGS, | ||
372 | RV1108_CLKGATE_CON(9), 2, GFLAGS), | ||
373 | COMPOSITE_NOMUX(SCLK_DSP_EDP, "sclk_dsp_edp", "sclk_dsp", 0, | ||
374 | RV1108_CLKSEL_CON(45), 0, 5, DFLAGS, | ||
375 | RV1108_CLKGATE_CON(9), 3, GFLAGS), | ||
376 | COMPOSITE_NOMUX(SCLK_DSP_EDAP, "sclk_dsp_edap", "sclk_dsp", 0, | ||
377 | RV1108_CLKSEL_CON(45), 8, 5, DFLAGS, | ||
378 | RV1108_CLKGATE_CON(9), 4, GFLAGS), | ||
379 | GATE(0, "pclk_dsp_iop_niu", "sclk_dsp_iop", CLK_IGNORE_UNUSED, | ||
380 | RV1108_CLKGATE_CON(16), 4, GFLAGS), | ||
381 | GATE(0, "aclk_dsp_epp_niu", "sclk_dsp_epp", CLK_IGNORE_UNUSED, | ||
382 | RV1108_CLKGATE_CON(16), 5, GFLAGS), | ||
383 | GATE(0, "aclk_dsp_edp_niu", "sclk_dsp_edp", CLK_IGNORE_UNUSED, | ||
384 | RV1108_CLKGATE_CON(16), 6, GFLAGS), | ||
385 | GATE(0, "pclk_dsp_dbg_niu", "sclk_dsp", CLK_IGNORE_UNUSED, | ||
386 | RV1108_CLKGATE_CON(16), 7, GFLAGS), | ||
387 | GATE(0, "aclk_dsp_edap_niu", "sclk_dsp_edap", CLK_IGNORE_UNUSED, | ||
388 | RV1108_CLKGATE_CON(16), 14, GFLAGS), | ||
389 | COMPOSITE_NOMUX(SCLK_DSP_PFM, "sclk_dsp_pfm", "sclk_dsp", 0, | ||
390 | RV1108_CLKSEL_CON(43), 0, 5, DFLAGS, | ||
391 | RV1108_CLKGATE_CON(9), 5, GFLAGS), | ||
392 | COMPOSITE_NOMUX(PCLK_DSP_CFG, "pclk_dsp_cfg", "sclk_dsp", 0, | ||
393 | RV1108_CLKSEL_CON(43), 8, 5, DFLAGS, | ||
394 | RV1108_CLKGATE_CON(9), 6, GFLAGS), | ||
395 | GATE(0, "pclk_dsp_cfg_niu", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, | ||
396 | RV1108_CLKGATE_CON(16), 8, GFLAGS), | ||
397 | GATE(0, "pclk_dsp_pfm_mon", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, | ||
398 | RV1108_CLKGATE_CON(16), 9, GFLAGS), | ||
399 | GATE(0, "pclk_intc", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, | ||
400 | RV1108_CLKGATE_CON(16), 10, GFLAGS), | ||
401 | GATE(0, "pclk_dsp_grf", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, | ||
402 | RV1108_CLKGATE_CON(16), 11, GFLAGS), | ||
403 | GATE(0, "pclk_mailbox", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, | ||
404 | RV1108_CLKGATE_CON(16), 12, GFLAGS), | ||
405 | GATE(0, "aclk_dsp_epp_perf", "sclk_dsp_epp", CLK_IGNORE_UNUSED, | ||
406 | RV1108_CLKGATE_CON(16), 15, GFLAGS), | ||
407 | GATE(0, "aclk_dsp_edp_perf", "sclk_dsp_edp", CLK_IGNORE_UNUSED, | ||
408 | RV1108_CLKGATE_CON(11), 8, GFLAGS), | ||
409 | |||
410 | /* | ||
231 | * Clock-Architecture Diagram 4 | 411 | * Clock-Architecture Diagram 4 |
232 | */ | 412 | */ |
233 | COMPOSITE(0, "aclk_vio0_2wrap_occ", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, | 413 | COMPOSITE(0, "aclk_vio0_pre", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, |
234 | RV1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, | 414 | RV1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, |
235 | RV1108_CLKGATE_CON(6), 0, GFLAGS), | 415 | RV1108_CLKGATE_CON(6), 0, GFLAGS), |
236 | GATE(0, "aclk_vio0_pre", "aclk_vio0_2wrap_occ", CLK_IGNORE_UNUSED, | 416 | GATE(ACLK_VIO0, "aclk_vio0", "aclk_vio0_pre", 0, |
237 | RV1108_CLKGATE_CON(17), 0, GFLAGS), | 417 | RV1108_CLKGATE_CON(17), 0, GFLAGS), |
238 | COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0, | 418 | COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0, |
239 | RV1108_CLKSEL_CON(29), 0, 5, DFLAGS, | 419 | RV1108_CLKSEL_CON(29), 0, 5, DFLAGS, |
240 | RV1108_CLKGATE_CON(7), 2, GFLAGS), | 420 | RV1108_CLKGATE_CON(7), 2, GFLAGS), |
421 | GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0, | ||
422 | RV1108_CLKGATE_CON(17), 2, GFLAGS), | ||
241 | COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0, | 423 | COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0, |
242 | RV1108_CLKSEL_CON(29), 8, 5, DFLAGS, | 424 | RV1108_CLKSEL_CON(29), 8, 5, DFLAGS, |
243 | RV1108_CLKGATE_CON(7), 3, GFLAGS), | 425 | RV1108_CLKGATE_CON(7), 3, GFLAGS), |
426 | GATE(PCLK_VIO, "pclk_vio", "pclk_vio_pre", 0, | ||
427 | RV1108_CLKGATE_CON(17), 3, GFLAGS), | ||
428 | COMPOSITE(0, "aclk_vio1_pre", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, | ||
429 | RV1108_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
430 | RV1108_CLKGATE_CON(6), 1, GFLAGS), | ||
431 | GATE(ACLK_VIO1, "aclk_vio1", "aclk_vio1_pre", 0, | ||
432 | RV1108_CLKGATE_CON(17), 1, GFLAGS), | ||
244 | 433 | ||
245 | INVERTER(0, "pclk_vip", "ext_vip", | 434 | INVERTER(0, "pclk_vip", "ext_vip", |
246 | RV1108_CLKSEL_CON(31), 8, IFLAGS), | 435 | RV1108_CLKSEL_CON(31), 8, IFLAGS), |
@@ -252,8 +441,63 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
252 | RV1108_CLKGATE_CON(6), 5, GFLAGS), | 441 | RV1108_CLKGATE_CON(6), 5, GFLAGS), |
253 | GATE(0, "dclk_hdmiphy_src_dpll", "dpll", CLK_IGNORE_UNUSED, | 442 | GATE(0, "dclk_hdmiphy_src_dpll", "dpll", CLK_IGNORE_UNUSED, |
254 | RV1108_CLKGATE_CON(6), 4, GFLAGS), | 443 | RV1108_CLKGATE_CON(6), 4, GFLAGS), |
255 | COMPOSITE_NOGATE(0, "dclk_hdmiphy", mux_dclk_hdmiphy_pre_p, 0, | 444 | COMPOSITE_NOGATE(0, "dclk_hdmiphy_pre", mux_dclk_hdmiphy_pre_p, 0, |
256 | RV1108_CLKSEL_CON(32), 6, 2, MFLAGS, 8, 6, DFLAGS), | 445 | RV1108_CLKSEL_CON(32), 6, 1, MFLAGS, 8, 6, DFLAGS), |
446 | COMPOSITE_NOGATE(DCLK_VOP_SRC, "dclk_vop_src", mux_dclk_hdmiphy_pre_p, 0, | ||
447 | RV1108_CLKSEL_CON(32), 6, 1, MFLAGS, 0, 6, DFLAGS), | ||
448 | MUX(DCLK_HDMIPHY, "dclk_hdmiphy", mux_dclk_hdmiphy_p, CLK_SET_RATE_PARENT, | ||
449 | RV1108_CLKSEL_CON(32), 15, 1, MFLAGS), | ||
450 | MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT, | ||
451 | RV1108_CLKSEL_CON(32), 7, 1, MFLAGS), | ||
452 | GATE(ACLK_VOP, "aclk_vop", "aclk_vio0_pre", 0, | ||
453 | RV1108_CLKGATE_CON(18), 0, GFLAGS), | ||
454 | GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, | ||
455 | RV1108_CLKGATE_CON(18), 1, GFLAGS), | ||
456 | GATE(ACLK_IEP, "aclk_iep", "aclk_vio0_pre", 0, | ||
457 | RV1108_CLKGATE_CON(18), 2, GFLAGS), | ||
458 | GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, | ||
459 | RV1108_CLKGATE_CON(18), 3, GFLAGS), | ||
460 | |||
461 | GATE(ACLK_RGA, "aclk_rga", "aclk_vio1_pre", 0, | ||
462 | RV1108_CLKGATE_CON(18), 4, GFLAGS), | ||
463 | GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, | ||
464 | RV1108_CLKGATE_CON(18), 5, GFLAGS), | ||
465 | COMPOSITE(SCLK_RGA, "sclk_rga", mux_pll_src_4plls_p, 0, | ||
466 | RV1108_CLKSEL_CON(33), 6, 2, MFLAGS, 0, 5, DFLAGS, | ||
467 | RV1108_CLKGATE_CON(6), 6, GFLAGS), | ||
468 | |||
469 | COMPOSITE(SCLK_CVBS_HOST, "sclk_cvbs_host", mux_cvbs_src_p, 0, | ||
470 | RV1108_CLKSEL_CON(33), 13, 2, MFLAGS, 8, 5, DFLAGS, | ||
471 | RV1108_CLKGATE_CON(6), 7, GFLAGS), | ||
472 | FACTOR(0, "sclk_cvbs_27m", "sclk_cvbs_host", 0, 1, 2), | ||
473 | |||
474 | GATE(SCLK_HDMI_SFR, "sclk_hdmi_sfr", "xin24m", 0, | ||
475 | RV1108_CLKGATE_CON(6), 8, GFLAGS), | ||
476 | |||
477 | COMPOSITE(SCLK_HDMI_CEC, "sclk_hdmi_cec", mux_hdmi_cec_src_p, 0, | ||
478 | RV1108_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 14, DFLAGS, | ||
479 | RV1108_CLKGATE_CON(6), 9, GFLAGS), | ||
480 | GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vio_pre", 0, | ||
481 | RV1108_CLKGATE_CON(18), 8, GFLAGS), | ||
482 | GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_vio_pre", 0, | ||
483 | RV1108_CLKGATE_CON(18), 9, GFLAGS), | ||
484 | |||
485 | GATE(ACLK_ISP, "aclk_isp", "aclk_vio1_pre", 0, | ||
486 | RV1108_CLKGATE_CON(18), 12, GFLAGS), | ||
487 | GATE(HCLK_ISP, "hclk_isp", "hclk_vio_pre", 0, | ||
488 | RV1108_CLKGATE_CON(18), 11, GFLAGS), | ||
489 | COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_4plls_p, 0, | ||
490 | RV1108_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, | ||
491 | RV1108_CLKGATE_CON(6), 3, GFLAGS), | ||
492 | |||
493 | GATE(0, "clk_dsiphy24m", "xin24m", CLK_IGNORE_UNUSED, | ||
494 | RV1108_CLKGATE_CON(9), 10, GFLAGS), | ||
495 | GATE(0, "pclk_vdacphy", "pclk_top_pre", CLK_IGNORE_UNUSED, | ||
496 | RV1108_CLKGATE_CON(14), 9, GFLAGS), | ||
497 | GATE(0, "pclk_mipi_dsiphy", "pclk_top_pre", CLK_IGNORE_UNUSED, | ||
498 | RV1108_CLKGATE_CON(14), 11, GFLAGS), | ||
499 | GATE(0, "pclk_mipi_csiphy", "pclk_top_pre", CLK_IGNORE_UNUSED, | ||
500 | RV1108_CLKGATE_CON(14), 12, GFLAGS), | ||
257 | 501 | ||
258 | /* | 502 | /* |
259 | * Clock-Architecture Diagram 5 | 503 | * Clock-Architecture Diagram 5 |
@@ -261,10 +505,11 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
261 | 505 | ||
262 | FACTOR(0, "xin12m", "xin24m", 0, 1, 2), | 506 | FACTOR(0, "xin12m", "xin24m", 0, 1, 2), |
263 | 507 | ||
264 | COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, | 508 | |
509 | COMPOSITE(SCLK_I2S0_SRC, "i2s0_src", mux_pll_src_2plls_p, 0, | ||
265 | RV1108_CLKSEL_CON(5), 8, 1, MFLAGS, 0, 7, DFLAGS, | 510 | RV1108_CLKSEL_CON(5), 8, 1, MFLAGS, 0, 7, DFLAGS, |
266 | RV1108_CLKGATE_CON(2), 0, GFLAGS), | 511 | RV1108_CLKGATE_CON(2), 0, GFLAGS), |
267 | COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, | 512 | COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT, |
268 | RV1108_CLKSEL_CON(8), 0, | 513 | RV1108_CLKSEL_CON(8), 0, |
269 | RV1108_CLKGATE_CON(2), 1, GFLAGS, | 514 | RV1108_CLKGATE_CON(2), 1, GFLAGS, |
270 | &rv1108_i2s0_fracmux), | 515 | &rv1108_i2s0_fracmux), |
@@ -274,7 +519,7 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
274 | RV1108_CLKSEL_CON(5), 15, 1, MFLAGS, | 519 | RV1108_CLKSEL_CON(5), 15, 1, MFLAGS, |
275 | RV1108_CLKGATE_CON(2), 3, GFLAGS), | 520 | RV1108_CLKGATE_CON(2), 3, GFLAGS), |
276 | 521 | ||
277 | COMPOSITE(0, "i2s1_src", mux_pll_src_2plls_p, 0, | 522 | COMPOSITE(SCLK_I2S1_SRC, "i2s1_src", mux_pll_src_2plls_p, 0, |
278 | RV1108_CLKSEL_CON(6), 8, 1, MFLAGS, 0, 7, DFLAGS, | 523 | RV1108_CLKSEL_CON(6), 8, 1, MFLAGS, 0, 7, DFLAGS, |
279 | RV1108_CLKGATE_CON(2), 4, GFLAGS), | 524 | RV1108_CLKGATE_CON(2), 4, GFLAGS), |
280 | COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, | 525 | COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, |
@@ -284,7 +529,7 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
284 | GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT, | 529 | GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT, |
285 | RV1108_CLKGATE_CON(2), 6, GFLAGS), | 530 | RV1108_CLKGATE_CON(2), 6, GFLAGS), |
286 | 531 | ||
287 | COMPOSITE(0, "i2s2_src", mux_pll_src_2plls_p, 0, | 532 | COMPOSITE(SCLK_I2S2_SRC, "i2s2_src", mux_pll_src_2plls_p, 0, |
288 | RV1108_CLKSEL_CON(7), 8, 1, MFLAGS, 0, 7, DFLAGS, | 533 | RV1108_CLKSEL_CON(7), 8, 1, MFLAGS, 0, 7, DFLAGS, |
289 | RV1108_CLKGATE_CON(3), 8, GFLAGS), | 534 | RV1108_CLKGATE_CON(3), 8, GFLAGS), |
290 | COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT, | 535 | COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT, |
@@ -303,32 +548,53 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
303 | RV1108_CLKGATE_CON(1), 2, GFLAGS), | 548 | RV1108_CLKGATE_CON(1), 2, GFLAGS), |
304 | COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0, | 549 | COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0, |
305 | RV1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS), | 550 | RV1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS), |
306 | COMPOSITE_NOMUX(0, "hclk_bus_pre", "aclk_bus_2wrap_occ", 0, | 551 | COMPOSITE_NOMUX(HCLK_BUS, "hclk_bus_pre", "aclk_bus_pre", 0, |
307 | RV1108_CLKSEL_CON(3), 0, 5, DFLAGS, | 552 | RV1108_CLKSEL_CON(3), 0, 5, DFLAGS, |
308 | RV1108_CLKGATE_CON(1), 4, GFLAGS), | 553 | RV1108_CLKGATE_CON(1), 4, GFLAGS), |
309 | COMPOSITE_NOMUX(0, "pclken_bus", "aclk_bus_2wrap_occ", 0, | 554 | COMPOSITE_NOMUX(0, "pclk_bus_pre", "aclk_bus_pre", 0, |
310 | RV1108_CLKSEL_CON(3), 8, 5, DFLAGS, | 555 | RV1108_CLKSEL_CON(3), 8, 5, DFLAGS, |
311 | RV1108_CLKGATE_CON(1), 5, GFLAGS), | 556 | RV1108_CLKGATE_CON(1), 5, GFLAGS), |
312 | GATE(0, "pclk_bus_pre", "pclken_bus", CLK_IGNORE_UNUSED, | 557 | GATE(PCLK_BUS, "pclk_bus", "pclk_bus_pre", 0, |
313 | RV1108_CLKGATE_CON(1), 6, GFLAGS), | 558 | RV1108_CLKGATE_CON(1), 6, GFLAGS), |
314 | GATE(0, "pclk_top_pre", "pclken_bus", CLK_IGNORE_UNUSED, | 559 | GATE(0, "pclk_top_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED, |
315 | RV1108_CLKGATE_CON(1), 7, GFLAGS), | 560 | RV1108_CLKGATE_CON(1), 7, GFLAGS), |
316 | GATE(0, "pclk_ddr_pre", "pclken_bus", CLK_IGNORE_UNUSED, | 561 | GATE(0, "pclk_ddr_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED, |
317 | RV1108_CLKGATE_CON(1), 8, GFLAGS), | 562 | RV1108_CLKGATE_CON(1), 8, GFLAGS), |
318 | GATE(0, "clk_timer0", "mux_pll_p", CLK_IGNORE_UNUSED, | 563 | GATE(SCLK_TIMER0, "clk_timer0", "xin24m", 0, |
319 | RV1108_CLKGATE_CON(1), 9, GFLAGS), | 564 | RV1108_CLKGATE_CON(1), 9, GFLAGS), |
320 | GATE(0, "clk_timer1", "mux_pll_p", CLK_IGNORE_UNUSED, | 565 | GATE(SCLK_TIMER1, "clk_timer1", "xin24m", CLK_IGNORE_UNUSED, |
321 | RV1108_CLKGATE_CON(1), 10, GFLAGS), | 566 | RV1108_CLKGATE_CON(1), 10, GFLAGS), |
322 | GATE(0, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 567 | GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED, |
323 | RV1108_CLKGATE_CON(13), 4, GFLAGS), | 568 | RV1108_CLKGATE_CON(13), 4, GFLAGS), |
324 | 569 | ||
325 | COMPOSITE(0, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, | 570 | GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0, |
571 | RV1108_CLKGATE_CON(12), 7, GFLAGS), | ||
572 | GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_bus_pre", 0, | ||
573 | RV1108_CLKGATE_CON(12), 8, GFLAGS), | ||
574 | GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0, | ||
575 | RV1108_CLKGATE_CON(12), 9, GFLAGS), | ||
576 | |||
577 | GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0, | ||
578 | RV1108_CLKGATE_CON(12), 10, GFLAGS), | ||
579 | GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0, | ||
580 | RV1108_CLKGATE_CON(12), 11, GFLAGS), | ||
581 | COMPOSITE(SCLK_CRYPTO, "sclk_crypto", mux_pll_src_2plls_p, 0, | ||
582 | RV1108_CLKSEL_CON(11), 7, 1, MFLAGS, 0, 5, DFLAGS, | ||
583 | RV1108_CLKGATE_CON(2), 12, GFLAGS), | ||
584 | |||
585 | COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_2plls_p, 0, | ||
586 | RV1108_CLKSEL_CON(11), 15, 1, MFLAGS, 8, 5, DFLAGS, | ||
587 | RV1108_CLKGATE_CON(3), 0, GFLAGS), | ||
588 | GATE(PCLK_SPI, "pclk_spi", "pclk_bus_pre", 0, | ||
589 | RV1108_CLKGATE_CON(13), 5, GFLAGS), | ||
590 | |||
591 | COMPOSITE(SCLK_UART0_SRC, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, | ||
326 | RV1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS, | 592 | RV1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS, |
327 | RV1108_CLKGATE_CON(3), 1, GFLAGS), | 593 | RV1108_CLKGATE_CON(3), 1, GFLAGS), |
328 | COMPOSITE(0, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, | 594 | COMPOSITE(SCLK_UART1_SRC, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, |
329 | RV1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS, | 595 | RV1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS, |
330 | RV1108_CLKGATE_CON(3), 3, GFLAGS), | 596 | RV1108_CLKGATE_CON(3), 3, GFLAGS), |
331 | COMPOSITE(0, "uart21_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, | 597 | COMPOSITE(SCLK_UART2_SRC, "uart2_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, |
332 | RV1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS, | 598 | RV1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS, |
333 | RV1108_CLKGATE_CON(3), 5, GFLAGS), | 599 | RV1108_CLKGATE_CON(3), 5, GFLAGS), |
334 | 600 | ||
@@ -344,44 +610,58 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
344 | RV1108_CLKSEL_CON(18), 0, | 610 | RV1108_CLKSEL_CON(18), 0, |
345 | RV1108_CLKGATE_CON(3), 6, GFLAGS, | 611 | RV1108_CLKGATE_CON(3), 6, GFLAGS, |
346 | &rv1108_uart2_fracmux), | 612 | &rv1108_uart2_fracmux), |
347 | GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 613 | GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", 0, |
348 | RV1108_CLKGATE_CON(13), 10, GFLAGS), | 614 | RV1108_CLKGATE_CON(13), 10, GFLAGS), |
349 | GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 615 | GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0, |
350 | RV1108_CLKGATE_CON(13), 11, GFLAGS), | 616 | RV1108_CLKGATE_CON(13), 11, GFLAGS), |
351 | GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 617 | GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", 0, |
352 | RV1108_CLKGATE_CON(13), 12, GFLAGS), | 618 | RV1108_CLKGATE_CON(13), 12, GFLAGS), |
353 | 619 | ||
354 | COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, | 620 | COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_2plls_p, 0, |
355 | RV1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS, | 621 | RV1108_CLKSEL_CON(19), 15, 1, MFLAGS, 8, 7, DFLAGS, |
356 | RV1108_CLKGATE_CON(3), 7, GFLAGS), | 622 | RV1108_CLKGATE_CON(3), 7, GFLAGS), |
357 | COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, | 623 | COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_2plls_p, 0, |
358 | RV1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS, | 624 | RV1108_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS, |
359 | RV1108_CLKGATE_CON(3), 8, GFLAGS), | 625 | RV1108_CLKGATE_CON(3), 8, GFLAGS), |
360 | COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, | 626 | COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_2plls_p, 0, |
361 | RV1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS, | 627 | RV1108_CLKSEL_CON(20), 15, 1, MFLAGS, 8, 7, DFLAGS, |
362 | RV1108_CLKGATE_CON(3), 9, GFLAGS), | 628 | RV1108_CLKGATE_CON(3), 9, GFLAGS), |
363 | GATE(0, "pclk_i2c1", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 629 | GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0, |
364 | RV1108_CLKGATE_CON(13), 0, GFLAGS), | 630 | RV1108_CLKGATE_CON(13), 0, GFLAGS), |
365 | GATE(0, "pclk_i2c2", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 631 | GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0, |
366 | RV1108_CLKGATE_CON(13), 1, GFLAGS), | 632 | RV1108_CLKGATE_CON(13), 1, GFLAGS), |
367 | GATE(0, "pclk_i2c3", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 633 | GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0, |
368 | RV1108_CLKGATE_CON(13), 2, GFLAGS), | 634 | RV1108_CLKGATE_CON(13), 2, GFLAGS), |
369 | COMPOSITE(0, "clk_pwm1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, | 635 | COMPOSITE(SCLK_PWM, "clk_pwm", mux_pll_src_2plls_p, 0, |
370 | RV1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS, | 636 | RV1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS, |
371 | RV1108_CLKGATE_CON(3), 10, GFLAGS), | 637 | RV1108_CLKGATE_CON(3), 10, GFLAGS), |
372 | GATE(0, "pclk_pwm1", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 638 | GATE(PCLK_PWM, "pclk_pwm", "pclk_bus_pre", 0, |
373 | RV1108_CLKGATE_CON(13), 6, GFLAGS), | 639 | RV1108_CLKGATE_CON(13), 6, GFLAGS), |
374 | GATE(0, "pclk_wdt", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 640 | GATE(PCLK_WDT, "pclk_wdt", "pclk_bus_pre", 0, |
375 | RV1108_CLKGATE_CON(13), 3, GFLAGS), | 641 | RV1108_CLKGATE_CON(13), 3, GFLAGS), |
376 | GATE(0, "pclk_gpio1", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 642 | GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_pre", 0, |
377 | RV1108_CLKGATE_CON(13), 7, GFLAGS), | 643 | RV1108_CLKGATE_CON(13), 7, GFLAGS), |
378 | GATE(0, "pclk_gpio2", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 644 | GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_pre", 0, |
379 | RV1108_CLKGATE_CON(13), 8, GFLAGS), | 645 | RV1108_CLKGATE_CON(13), 8, GFLAGS), |
380 | GATE(0, "pclk_gpio3", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 646 | GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_pre", 0, |
381 | RV1108_CLKGATE_CON(13), 9, GFLAGS), | 647 | RV1108_CLKGATE_CON(13), 9, GFLAGS), |
382 | 648 | ||
383 | GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, | 649 | GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, |
384 | RV1108_CLKGATE_CON(14), 0, GFLAGS), | 650 | RV1108_CLKGATE_CON(14), 0, GFLAGS), |
651 | GATE(PCLK_EFUSE0, "pclk_efuse0", "pclk_bus_pre", 0, | ||
652 | RV1108_CLKGATE_CON(12), 12, GFLAGS), | ||
653 | GATE(PCLK_EFUSE1, "pclk_efuse1", "pclk_bus_pre", 0, | ||
654 | RV1108_CLKGATE_CON(12), 13, GFLAGS), | ||
655 | GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_pre", 0, | ||
656 | RV1108_CLKGATE_CON(13), 13, GFLAGS), | ||
657 | COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, | ||
658 | RV1108_CLKSEL_CON(21), 0, 10, DFLAGS, | ||
659 | RV1108_CLKGATE_CON(3), 11, GFLAGS), | ||
660 | GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_pre", 0, | ||
661 | RV1108_CLKGATE_CON(13), 14, GFLAGS), | ||
662 | COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0, | ||
663 | RV1108_CLKSEL_CON(22), 0, 10, DFLAGS, | ||
664 | RV1108_CLKGATE_CON(3), 12, GFLAGS), | ||
385 | 665 | ||
386 | GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0, | 666 | GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0, |
387 | RV1108_CLKGATE_CON(12), 2, GFLAGS), | 667 | RV1108_CLKGATE_CON(12), 2, GFLAGS), |
@@ -397,18 +677,24 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
397 | RV1108_CLKGATE_CON(0), 9, GFLAGS), | 677 | RV1108_CLKGATE_CON(0), 9, GFLAGS), |
398 | GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, | 678 | GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, |
399 | RV1108_CLKGATE_CON(0), 10, GFLAGS), | 679 | RV1108_CLKGATE_CON(0), 10, GFLAGS), |
400 | COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED, | 680 | COMPOSITE_NOGATE(0, "clk_ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED, |
401 | RV1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, | 681 | RV1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, |
402 | DFLAGS | CLK_DIVIDER_POWER_OF_TWO, | 682 | DFLAGS | CLK_DIVIDER_POWER_OF_TWO), |
683 | FACTOR(0, "clk_ddr", "clk_ddrphy_src", 0, 1, 2), | ||
684 | GATE(0, "clk_ddrphy4x", "clk_ddr", CLK_IGNORE_UNUSED, | ||
403 | RV1108_CLKGATE_CON(10), 9, GFLAGS), | 685 | RV1108_CLKGATE_CON(10), 9, GFLAGS), |
404 | GATE(0, "ddrupctl", "ddrphy_pre", CLK_IGNORE_UNUSED, | 686 | GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", CLK_IGNORE_UNUSED, |
405 | RV1108_CLKGATE_CON(12), 4, GFLAGS), | 687 | RV1108_CLKGATE_CON(12), 4, GFLAGS), |
406 | GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED, | 688 | GATE(0, "nclk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED, |
407 | RV1108_CLKGATE_CON(12), 5, GFLAGS), | 689 | RV1108_CLKGATE_CON(12), 5, GFLAGS), |
408 | GATE(0, "ddrmon", "ddrphy_pre", CLK_IGNORE_UNUSED, | 690 | GATE(0, "pclk_ddrmon", "pclk_ddr_pre", CLK_IGNORE_UNUSED, |
409 | RV1108_CLKGATE_CON(12), 6, GFLAGS), | 691 | RV1108_CLKGATE_CON(12), 6, GFLAGS), |
410 | GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED, | 692 | GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED, |
411 | RV1108_CLKGATE_CON(0), 11, GFLAGS), | 693 | RV1108_CLKGATE_CON(0), 11, GFLAGS), |
694 | GATE(0, "pclk_mschniu", "pclk_ddr_pre", CLK_IGNORE_UNUSED, | ||
695 | RV1108_CLKGATE_CON(14), 2, GFLAGS), | ||
696 | GATE(0, "pclk_ddrphy", "pclk_ddr_pre", CLK_IGNORE_UNUSED, | ||
697 | RV1108_CLKGATE_CON(14), 4, GFLAGS), | ||
412 | 698 | ||
413 | /* | 699 | /* |
414 | * Clock-Architecture Diagram 6 | 700 | * Clock-Architecture Diagram 6 |
@@ -418,23 +704,23 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
418 | COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0, | 704 | COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0, |
419 | RV1108_CLKSEL_CON(23), 10, 5, DFLAGS, | 705 | RV1108_CLKSEL_CON(23), 10, 5, DFLAGS, |
420 | RV1108_CLKGATE_CON(4), 5, GFLAGS), | 706 | RV1108_CLKGATE_CON(4), 5, GFLAGS), |
421 | GATE(0, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED, | 707 | GATE(PCLK_PERI, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED, |
422 | RV1108_CLKGATE_CON(15), 13, GFLAGS), | 708 | RV1108_CLKGATE_CON(15), 13, GFLAGS), |
423 | COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0, | 709 | COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0, |
424 | RV1108_CLKSEL_CON(23), 5, 5, DFLAGS, | 710 | RV1108_CLKSEL_CON(23), 5, 5, DFLAGS, |
425 | RV1108_CLKGATE_CON(4), 4, GFLAGS), | 711 | RV1108_CLKGATE_CON(4), 4, GFLAGS), |
426 | GATE(0, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED, | 712 | GATE(HCLK_PERI, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED, |
427 | RV1108_CLKGATE_CON(15), 12, GFLAGS), | 713 | RV1108_CLKGATE_CON(15), 12, GFLAGS), |
428 | 714 | ||
429 | GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED, | 715 | GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED, |
430 | RV1108_CLKGATE_CON(4), 1, GFLAGS), | 716 | RV1108_CLKGATE_CON(4), 1, GFLAGS), |
431 | GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED, | 717 | GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED, |
432 | RV1108_CLKGATE_CON(4), 2, GFLAGS), | 718 | RV1108_CLKGATE_CON(4), 2, GFLAGS), |
433 | COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED, | 719 | COMPOSITE(ACLK_PERI, "aclk_periph", mux_aclk_peri_src_p, 0, |
434 | RV1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS, | 720 | RV1108_CLKSEL_CON(23), 15, 1, MFLAGS, 0, 5, DFLAGS, |
435 | RV1108_CLKGATE_CON(15), 11, GFLAGS), | 721 | RV1108_CLKGATE_CON(15), 11, GFLAGS), |
436 | 722 | ||
437 | COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, | 723 | COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, |
438 | RV1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS, | 724 | RV1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS, |
439 | RV1108_CLKGATE_CON(5), 0, GFLAGS), | 725 | RV1108_CLKGATE_CON(5), 0, GFLAGS), |
440 | 726 | ||
@@ -454,23 +740,31 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
454 | GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 2, GFLAGS), | 740 | GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 2, GFLAGS), |
455 | 741 | ||
456 | COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0, | 742 | COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0, |
457 | RV1108_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 5, DFLAGS, | 743 | RV1108_CLKSEL_CON(27), 14, 1, MFLAGS, 8, 5, DFLAGS, |
458 | RV1108_CLKGATE_CON(5), 3, GFLAGS), | 744 | RV1108_CLKGATE_CON(5), 3, GFLAGS), |
459 | GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 3, GFLAGS), | 745 | GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 3, GFLAGS), |
460 | 746 | ||
747 | GATE(HCLK_HOST0, "hclk_host0", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 6, GFLAGS), | ||
748 | GATE(0, "hclk_host0_arb", "hclk_periph", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(15), 7, GFLAGS), | ||
749 | GATE(HCLK_OTG, "hclk_otg", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 8, GFLAGS), | ||
750 | GATE(0, "hclk_otg_pmu", "hclk_periph", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(15), 9, GFLAGS), | ||
751 | GATE(SCLK_USBPHY, "clk_usbphy", "xin24m", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(5), 5, GFLAGS), | ||
752 | |||
461 | COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0, | 753 | COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0, |
462 | RV1108_CLKSEL_CON(27), 7, 2, MFLAGS, 0, 7, DFLAGS, | 754 | RV1108_CLKSEL_CON(27), 7, 1, MFLAGS, 0, 7, DFLAGS, |
463 | RV1108_CLKGATE_CON(5), 4, GFLAGS), | 755 | RV1108_CLKGATE_CON(5), 4, GFLAGS), |
464 | GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 10, GFLAGS), | 756 | GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 10, GFLAGS), |
465 | 757 | ||
466 | COMPOSITE(0, "sclk_macphy_pre", mux_pll_src_apll_gpll_p, 0, | 758 | COMPOSITE(SCLK_MAC_PRE, "sclk_mac_pre", mux_pll_src_apll_gpll_p, 0, |
467 | RV1108_CLKSEL_CON(24), 12, 2, MFLAGS, 0, 5, DFLAGS, | 759 | RV1108_CLKSEL_CON(24), 12, 1, MFLAGS, 0, 5, DFLAGS, |
468 | RV1108_CLKGATE_CON(4), 10, GFLAGS), | 760 | RV1108_CLKGATE_CON(4), 10, GFLAGS), |
469 | MUX(0, "sclk_macphy", mux_sclk_macphy_p, CLK_SET_RATE_PARENT, | 761 | MUX(SCLK_MAC, "sclk_mac", mux_sclk_mac_p, CLK_SET_RATE_PARENT, |
470 | RV1108_CLKSEL_CON(24), 8, 2, MFLAGS), | 762 | RV1108_CLKSEL_CON(24), 8, 1, MFLAGS), |
471 | GATE(0, "sclk_macphy_rx", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS), | 763 | GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS), |
472 | GATE(0, "sclk_mac_ref", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS), | 764 | GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS), |
473 | GATE(0, "sclk_mac_refout", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS), | 765 | GATE(SCLK_MAC_REFOUT, "sclk_mac_refout", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS), |
766 | GATE(ACLK_GMAC, "aclk_gmac", "aclk_periph", 0, RV1108_CLKGATE_CON(15), 4, GFLAGS), | ||
767 | GATE(PCLK_GMAC, "pclk_gmac", "pclk_periph", 0, RV1108_CLKGATE_CON(15), 5, GFLAGS), | ||
474 | 768 | ||
475 | MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RV1108_SDMMC_CON0, 1), | 769 | MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RV1108_SDMMC_CON0, 1), |
476 | MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RV1108_SDMMC_CON1, 1), | 770 | MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RV1108_SDMMC_CON1, 1), |
@@ -484,10 +778,16 @@ static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { | |||
484 | 778 | ||
485 | static const char *const rv1108_critical_clocks[] __initconst = { | 779 | static const char *const rv1108_critical_clocks[] __initconst = { |
486 | "aclk_core", | 780 | "aclk_core", |
487 | "aclk_bus_src_gpll", | 781 | "aclk_bus", |
782 | "hclk_bus", | ||
783 | "pclk_bus", | ||
488 | "aclk_periph", | 784 | "aclk_periph", |
489 | "hclk_periph", | 785 | "hclk_periph", |
490 | "pclk_periph", | 786 | "pclk_periph", |
787 | "nclk_ddrupctl", | ||
788 | "pclk_ddrmon", | ||
789 | "pclk_acodecphy", | ||
790 | "pclk_pmu", | ||
491 | }; | 791 | }; |
492 | 792 | ||
493 | static void __init rv1108_clk_init(struct device_node *np) | 793 | static void __init rv1108_clk_init(struct device_node *np) |
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index fe1d393cf678..35dbd63c2f49 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mfd/syscon.h> | 29 | #include <linux/mfd/syscon.h> |
30 | #include <linux/regmap.h> | 30 | #include <linux/regmap.h> |
31 | #include <linux/reboot.h> | 31 | #include <linux/reboot.h> |
32 | #include <linux/rational.h> | ||
32 | #include "clk.h" | 33 | #include "clk.h" |
33 | 34 | ||
34 | /** | 35 | /** |
@@ -164,6 +165,40 @@ static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb, | |||
164 | return notifier_from_errno(ret); | 165 | return notifier_from_errno(ret); |
165 | } | 166 | } |
166 | 167 | ||
168 | /** | ||
169 | * fractional divider must set that denominator is 20 times larger than | ||
170 | * numerator to generate precise clock frequency. | ||
171 | */ | ||
172 | static void rockchip_fractional_approximation(struct clk_hw *hw, | ||
173 | unsigned long rate, unsigned long *parent_rate, | ||
174 | unsigned long *m, unsigned long *n) | ||
175 | { | ||
176 | struct clk_fractional_divider *fd = to_clk_fd(hw); | ||
177 | unsigned long p_rate, p_parent_rate; | ||
178 | struct clk_hw *p_parent; | ||
179 | unsigned long scale; | ||
180 | |||
181 | p_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); | ||
182 | if ((rate * 20 > p_rate) && (p_rate % rate != 0)) { | ||
183 | p_parent = clk_hw_get_parent(clk_hw_get_parent(hw)); | ||
184 | p_parent_rate = clk_hw_get_rate(p_parent); | ||
185 | *parent_rate = p_parent_rate; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Get rate closer to *parent_rate to guarantee there is no overflow | ||
190 | * for m and n. In the result it will be the nearest rate left shifted | ||
191 | * by (scale - fd->nwidth) bits. | ||
192 | */ | ||
193 | scale = fls_long(*parent_rate / rate - 1); | ||
194 | if (scale > fd->nwidth) | ||
195 | rate <<= scale - fd->nwidth; | ||
196 | |||
197 | rational_best_approximation(rate, *parent_rate, | ||
198 | GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), | ||
199 | m, n); | ||
200 | } | ||
201 | |||
167 | static struct clk *rockchip_clk_register_frac_branch( | 202 | static struct clk *rockchip_clk_register_frac_branch( |
168 | struct rockchip_clk_provider *ctx, const char *name, | 203 | struct rockchip_clk_provider *ctx, const char *name, |
169 | const char *const *parent_names, u8 num_parents, | 204 | const char *const *parent_names, u8 num_parents, |
@@ -210,6 +245,7 @@ static struct clk *rockchip_clk_register_frac_branch( | |||
210 | div->nwidth = 16; | 245 | div->nwidth = 16; |
211 | div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; | 246 | div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; |
212 | div->lock = lock; | 247 | div->lock = lock; |
248 | div->approximation = rockchip_fractional_approximation; | ||
213 | div_ops = &clk_fractional_divider_ops; | 249 | div_ops = &clk_fractional_divider_ops; |
214 | 250 | ||
215 | clk = clk_register_composite(NULL, name, parent_names, num_parents, | 251 | clk = clk_register_composite(NULL, name, parent_names, num_parents, |
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index 1fab56f396d4..b117783ed404 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c | |||
@@ -180,7 +180,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) | |||
180 | } | 180 | } |
181 | clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", | 181 | clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", |
182 | mout_audss_p, ARRAY_SIZE(mout_audss_p), | 182 | mout_audss_p, ARRAY_SIZE(mout_audss_p), |
183 | CLK_SET_RATE_NO_REPARENT, | 183 | CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, |
184 | reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); | 184 | reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); |
185 | 185 | ||
186 | cdclk = devm_clk_get(&pdev->dev, "cdclk"); | 186 | cdclk = devm_clk_get(&pdev->dev, "cdclk"); |
@@ -195,11 +195,11 @@ static int exynos_audss_clk_probe(struct platform_device *pdev) | |||
195 | reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); | 195 | reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); |
196 | 196 | ||
197 | clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp", | 197 | clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp", |
198 | "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, | 198 | "mout_audss", CLK_SET_RATE_PARENT, |
199 | 0, &lock); | 199 | reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); |
200 | 200 | ||
201 | clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, | 201 | clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, |
202 | "dout_aud_bus", "dout_srp", 0, | 202 | "dout_aud_bus", "dout_srp", CLK_SET_RATE_PARENT, |
203 | reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); | 203 | reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); |
204 | 204 | ||
205 | clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s", | 205 | clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s", |
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9a6476aa7d81..25601967d1cd 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c | |||
@@ -537,8 +537,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { | |||
537 | 537 | ||
538 | MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", | 538 | MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", |
539 | mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), | 539 | mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), |
540 | MUX(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, | 540 | MUX_F(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, |
541 | SRC_TOP7, 20, 2), | 541 | SRC_TOP7, 20, 2, CLK_SET_RATE_PARENT, 0), |
542 | MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), | 542 | MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), |
543 | MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), | 543 | MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), |
544 | 544 | ||
@@ -547,8 +547,8 @@ static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = { | |||
547 | MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), | 547 | MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), |
548 | MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), | 548 | MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), |
549 | 549 | ||
550 | MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p, | 550 | MUX_F(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p, |
551 | SRC_TOP9, 8, 1), | 551 | SRC_TOP9, 8, 1, CLK_SET_RATE_PARENT, 0), |
552 | MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, | 552 | MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, |
553 | SRC_TOP9, 16, 1), | 553 | SRC_TOP9, 16, 1), |
554 | MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, | 554 | MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, |
@@ -590,6 +590,8 @@ static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = { | |||
590 | GATE_BUS_TOP, 24, 0, 0), | 590 | GATE_BUS_TOP, 24, 0, 0), |
591 | GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", | 591 | GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", |
592 | GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), | 592 | GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), |
593 | GATE(CLK_MAU_EPLL, "mau_epll", "mout_user_mau_epll", | ||
594 | SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), | ||
593 | }; | 595 | }; |
594 | 596 | ||
595 | static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = { | 597 | static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = { |
@@ -629,6 +631,11 @@ static const struct samsung_div_clock exynos5420_div_clks[] __initconst = { | |||
629 | "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3), | 631 | "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3), |
630 | }; | 632 | }; |
631 | 633 | ||
634 | static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = { | ||
635 | GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", | ||
636 | SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), | ||
637 | }; | ||
638 | |||
632 | static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { | 639 | static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { |
633 | MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p, | 640 | MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p, |
634 | SRC_TOP7, 4, 1), | 641 | SRC_TOP7, 4, 1), |
@@ -706,7 +713,8 @@ static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { | |||
706 | MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), | 713 | MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), |
707 | MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), | 714 | MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), |
708 | MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), | 715 | MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), |
709 | MUX(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), | 716 | MUX_F(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1, |
717 | CLK_SET_RATE_PARENT, 0), | ||
710 | MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), | 718 | MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), |
711 | MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), | 719 | MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), |
712 | 720 | ||
@@ -1001,9 +1009,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = { | |||
1001 | GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", | 1009 | GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", |
1002 | SRC_MASK_TOP2, 24, CLK_IS_CRITICAL, 0), | 1010 | SRC_MASK_TOP2, 24, CLK_IS_CRITICAL, 0), |
1003 | 1011 | ||
1004 | GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", | ||
1005 | SRC_MASK_TOP7, 20, 0, 0), | ||
1006 | |||
1007 | /* sclk */ | 1012 | /* sclk */ |
1008 | GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", | 1013 | GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", |
1009 | GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), | 1014 | GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), |
@@ -1440,6 +1445,8 @@ static void __init exynos5x_clk_init(struct device_node *np, | |||
1440 | ARRAY_SIZE(exynos5420_mux_clks)); | 1445 | ARRAY_SIZE(exynos5420_mux_clks)); |
1441 | samsung_clk_register_div(ctx, exynos5420_div_clks, | 1446 | samsung_clk_register_div(ctx, exynos5420_div_clks, |
1442 | ARRAY_SIZE(exynos5420_div_clks)); | 1447 | ARRAY_SIZE(exynos5420_div_clks)); |
1448 | samsung_clk_register_gate(ctx, exynos5420_gate_clks, | ||
1449 | ARRAY_SIZE(exynos5420_gate_clks)); | ||
1443 | } else { | 1450 | } else { |
1444 | samsung_clk_register_fixed_factor( | 1451 | samsung_clk_register_fixed_factor( |
1445 | ctx, exynos5800_fixed_factor_clks, | 1452 | ctx, exynos5800_fixed_factor_clks, |
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 7342928c35cd..6427d0ebe2de 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig | |||
@@ -11,6 +11,19 @@ config SUN50I_A64_CCU | |||
11 | default ARM64 && ARCH_SUNXI | 11 | default ARM64 && ARCH_SUNXI |
12 | depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST | 12 | depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST |
13 | 13 | ||
14 | config SUN4I_A10_CCU | ||
15 | bool "Support for the Allwinner A10/A20 CCU" | ||
16 | select SUNXI_CCU_DIV | ||
17 | select SUNXI_CCU_MULT | ||
18 | select SUNXI_CCU_NK | ||
19 | select SUNXI_CCU_NKM | ||
20 | select SUNXI_CCU_NM | ||
21 | select SUNXI_CCU_MP | ||
22 | select SUNXI_CCU_PHASE | ||
23 | default MACH_SUN4I | ||
24 | default MACH_SUN7I | ||
25 | depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST | ||
26 | |||
14 | config SUN5I_CCU | 27 | config SUN5I_CCU |
15 | bool "Support for the Allwinner sun5i family CCM" | 28 | bool "Support for the Allwinner sun5i family CCM" |
16 | default MACH_SUN5I | 29 | default MACH_SUN5I |
@@ -48,6 +61,11 @@ config SUN8I_V3S_CCU | |||
48 | config SUN8I_DE2_CCU | 61 | config SUN8I_DE2_CCU |
49 | bool "Support for the Allwinner SoCs DE2 CCU" | 62 | bool "Support for the Allwinner SoCs DE2 CCU" |
50 | 63 | ||
64 | config SUN8I_R40_CCU | ||
65 | bool "Support for the Allwinner R40 CCU" | ||
66 | default MACH_SUN8I | ||
67 | depends on MACH_SUN8I || COMPILE_TEST | ||
68 | |||
51 | config SUN9I_A80_CCU | 69 | config SUN9I_A80_CCU |
52 | bool "Support for the Allwinner A80 CCU" | 70 | bool "Support for the Allwinner A80 CCU" |
53 | default MACH_SUN9I | 71 | default MACH_SUN9I |
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 45a5910379a5..85a0633c1eac 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile | |||
@@ -20,6 +20,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_mp.o | |||
20 | 20 | ||
21 | # SoC support | 21 | # SoC support |
22 | obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o | 22 | obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o |
23 | obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o | ||
23 | obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o | 24 | obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o |
24 | obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o | 25 | obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o |
25 | obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o | 26 | obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o |
@@ -29,6 +30,7 @@ obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o | |||
29 | obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o | 30 | obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o |
30 | obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o | 31 | obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o |
31 | obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o | 32 | obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o |
33 | obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o | ||
32 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o | 34 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o |
33 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o | 35 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o |
34 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o | 36 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o |
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c new file mode 100644 index 000000000000..286b0049b7b6 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c | |||
@@ -0,0 +1,1456 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 Priit Laes <plaes@plaes.org>. | ||
3 | * Copyright (c) 2017 Maxime Ripard. | ||
4 | * Copyright (c) 2017 Jonathan Liu. | ||
5 | * | ||
6 | * This software is licensed under the terms of the GNU General Public | ||
7 | * License version 2, as published by the Free Software Foundation, and | ||
8 | * may be copied, distributed, and modified under those terms. | ||
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 | |||
16 | #include <linux/clk-provider.h> | ||
17 | #include <linux/of_address.h> | ||
18 | |||
19 | #include "ccu_common.h" | ||
20 | #include "ccu_reset.h" | ||
21 | |||
22 | #include "ccu_div.h" | ||
23 | #include "ccu_gate.h" | ||
24 | #include "ccu_mp.h" | ||
25 | #include "ccu_mult.h" | ||
26 | #include "ccu_nk.h" | ||
27 | #include "ccu_nkm.h" | ||
28 | #include "ccu_nkmp.h" | ||
29 | #include "ccu_nm.h" | ||
30 | #include "ccu_phase.h" | ||
31 | |||
32 | #include "ccu-sun4i-a10.h" | ||
33 | |||
34 | static struct ccu_nkmp pll_core_clk = { | ||
35 | .enable = BIT(31), | ||
36 | .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), | ||
37 | .k = _SUNXI_CCU_MULT(4, 2), | ||
38 | .m = _SUNXI_CCU_DIV(0, 2), | ||
39 | .p = _SUNXI_CCU_DIV(16, 2), | ||
40 | .common = { | ||
41 | .reg = 0x000, | ||
42 | .hw.init = CLK_HW_INIT("pll-core", | ||
43 | "hosc", | ||
44 | &ccu_nkmp_ops, | ||
45 | 0), | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from | ||
51 | * the base (2x, 4x and 8x), and one variable divider (the one true | ||
52 | * pll audio). | ||
53 | * | ||
54 | * We don't have any need for the variable divider for now, so we just | ||
55 | * hardcode it to match with the clock names. | ||
56 | */ | ||
57 | #define SUN4I_PLL_AUDIO_REG 0x008 | ||
58 | static struct ccu_nm pll_audio_base_clk = { | ||
59 | .enable = BIT(31), | ||
60 | .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0), | ||
61 | .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0), | ||
62 | .common = { | ||
63 | .reg = 0x008, | ||
64 | .hw.init = CLK_HW_INIT("pll-audio-base", | ||
65 | "hosc", | ||
66 | &ccu_nm_ops, | ||
67 | 0), | ||
68 | }, | ||
69 | |||
70 | }; | ||
71 | |||
72 | static struct ccu_mult pll_video0_clk = { | ||
73 | .enable = BIT(31), | ||
74 | .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127), | ||
75 | .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14), | ||
76 | 270000000, 297000000), | ||
77 | .common = { | ||
78 | .reg = 0x010, | ||
79 | .features = (CCU_FEATURE_FRACTIONAL | | ||
80 | CCU_FEATURE_ALL_PREDIV), | ||
81 | .prediv = 8, | ||
82 | .hw.init = CLK_HW_INIT("pll-video0", | ||
83 | "hosc", | ||
84 | &ccu_mult_ops, | ||
85 | 0), | ||
86 | }, | ||
87 | }; | ||
88 | |||
89 | static struct ccu_nkmp pll_ve_sun4i_clk = { | ||
90 | .enable = BIT(31), | ||
91 | .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), | ||
92 | .k = _SUNXI_CCU_MULT(4, 2), | ||
93 | .m = _SUNXI_CCU_DIV(0, 2), | ||
94 | .p = _SUNXI_CCU_DIV(16, 2), | ||
95 | .common = { | ||
96 | .reg = 0x018, | ||
97 | .hw.init = CLK_HW_INIT("pll-ve", | ||
98 | "hosc", | ||
99 | &ccu_nkmp_ops, | ||
100 | 0), | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static struct ccu_nk pll_ve_sun7i_clk = { | ||
105 | .enable = BIT(31), | ||
106 | .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), | ||
107 | .k = _SUNXI_CCU_MULT(4, 2), | ||
108 | .common = { | ||
109 | .reg = 0x018, | ||
110 | .hw.init = CLK_HW_INIT("pll-ve", | ||
111 | "hosc", | ||
112 | &ccu_nk_ops, | ||
113 | 0), | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static struct ccu_nk pll_ddr_base_clk = { | ||
118 | .enable = BIT(31), | ||
119 | .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), | ||
120 | .k = _SUNXI_CCU_MULT(4, 2), | ||
121 | .common = { | ||
122 | .reg = 0x020, | ||
123 | .hw.init = CLK_HW_INIT("pll-ddr-base", | ||
124 | "hosc", | ||
125 | &ccu_nk_ops, | ||
126 | 0), | ||
127 | }, | ||
128 | }; | ||
129 | |||
130 | static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, | ||
131 | CLK_IS_CRITICAL); | ||
132 | |||
133 | static struct ccu_div pll_ddr_other_clk = { | ||
134 | .div = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
135 | .common = { | ||
136 | .reg = 0x020, | ||
137 | .hw.init = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base", | ||
138 | &ccu_div_ops, | ||
139 | 0), | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | static struct ccu_nk pll_periph_base_clk = { | ||
144 | .enable = BIT(31), | ||
145 | .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), | ||
146 | .k = _SUNXI_CCU_MULT(4, 2), | ||
147 | .common = { | ||
148 | .reg = 0x028, | ||
149 | .hw.init = CLK_HW_INIT("pll-periph-base", | ||
150 | "hosc", | ||
151 | &ccu_nk_ops, | ||
152 | 0), | ||
153 | }, | ||
154 | }; | ||
155 | |||
156 | static CLK_FIXED_FACTOR(pll_periph_clk, "pll-periph", "pll-periph-base", | ||
157 | 2, 1, CLK_SET_RATE_PARENT); | ||
158 | |||
159 | /* Not documented on A10 */ | ||
160 | static struct ccu_div pll_periph_sata_clk = { | ||
161 | .enable = BIT(14), | ||
162 | .div = _SUNXI_CCU_DIV(0, 2), | ||
163 | .fixed_post_div = 6, | ||
164 | .common = { | ||
165 | .reg = 0x028, | ||
166 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
167 | .hw.init = CLK_HW_INIT("pll-periph-sata", | ||
168 | "pll-periph-base", | ||
169 | &ccu_div_ops, 0), | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static struct ccu_mult pll_video1_clk = { | ||
174 | .enable = BIT(31), | ||
175 | .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127), | ||
176 | .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14), | ||
177 | 270000000, 297000000), | ||
178 | .common = { | ||
179 | .reg = 0x030, | ||
180 | .features = (CCU_FEATURE_FRACTIONAL | | ||
181 | CCU_FEATURE_ALL_PREDIV), | ||
182 | .prediv = 8, | ||
183 | .hw.init = CLK_HW_INIT("pll-video1", | ||
184 | "hosc", | ||
185 | &ccu_mult_ops, | ||
186 | 0), | ||
187 | }, | ||
188 | }; | ||
189 | |||
190 | /* Not present on A10 */ | ||
191 | static struct ccu_nk pll_gpu_clk = { | ||
192 | .enable = BIT(31), | ||
193 | .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), | ||
194 | .k = _SUNXI_CCU_MULT(4, 2), | ||
195 | .common = { | ||
196 | .reg = 0x040, | ||
197 | .hw.init = CLK_HW_INIT("pll-gpu", | ||
198 | "hosc", | ||
199 | &ccu_nk_ops, | ||
200 | 0), | ||
201 | }, | ||
202 | }; | ||
203 | |||
204 | static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0); | ||
205 | |||
206 | static const char *const cpu_parents[] = { "osc32k", "hosc", | ||
207 | "pll-core", "pll-periph" }; | ||
208 | static const struct ccu_mux_fixed_prediv cpu_predivs[] = { | ||
209 | { .index = 3, .div = 3, }, | ||
210 | }; | ||
211 | |||
212 | #define SUN4I_AHB_REG 0x054 | ||
213 | static struct ccu_mux cpu_clk = { | ||
214 | .mux = { | ||
215 | .shift = 16, | ||
216 | .width = 2, | ||
217 | .fixed_predivs = cpu_predivs, | ||
218 | .n_predivs = ARRAY_SIZE(cpu_predivs), | ||
219 | }, | ||
220 | .common = { | ||
221 | .reg = 0x054, | ||
222 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
223 | .hw.init = CLK_HW_INIT_PARENTS("cpu", | ||
224 | cpu_parents, | ||
225 | &ccu_mux_ops, | ||
226 | CLK_IS_CRITICAL), | ||
227 | } | ||
228 | }; | ||
229 | |||
230 | static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0); | ||
231 | |||
232 | static struct ccu_div ahb_sun4i_clk = { | ||
233 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
234 | .common = { | ||
235 | .reg = 0x054, | ||
236 | .hw.init = CLK_HW_INIT("ahb", "axi", &ccu_div_ops, 0), | ||
237 | }, | ||
238 | }; | ||
239 | |||
240 | static const char *const ahb_sun7i_parents[] = { "axi", "pll-periph", | ||
241 | "pll-periph" }; | ||
242 | static const struct ccu_mux_fixed_prediv ahb_sun7i_predivs[] = { | ||
243 | { .index = 1, .div = 2, }, | ||
244 | { /* Sentinel */ }, | ||
245 | }; | ||
246 | static struct ccu_div ahb_sun7i_clk = { | ||
247 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
248 | .mux = { | ||
249 | .shift = 6, | ||
250 | .width = 2, | ||
251 | .fixed_predivs = ahb_sun7i_predivs, | ||
252 | .n_predivs = ARRAY_SIZE(ahb_sun7i_predivs), | ||
253 | }, | ||
254 | |||
255 | .common = { | ||
256 | .reg = 0x054, | ||
257 | .hw.init = CLK_HW_INIT_PARENTS("ahb", | ||
258 | ahb_sun7i_parents, | ||
259 | &ccu_div_ops, | ||
260 | 0), | ||
261 | }, | ||
262 | }; | ||
263 | |||
264 | static struct clk_div_table apb0_div_table[] = { | ||
265 | { .val = 0, .div = 2 }, | ||
266 | { .val = 1, .div = 2 }, | ||
267 | { .val = 2, .div = 4 }, | ||
268 | { .val = 3, .div = 8 }, | ||
269 | { /* Sentinel */ }, | ||
270 | }; | ||
271 | static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb", | ||
272 | 0x054, 8, 2, apb0_div_table, 0); | ||
273 | |||
274 | static const char *const apb1_parents[] = { "hosc", "pll-periph", "osc32k" }; | ||
275 | static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058, | ||
276 | 0, 5, /* M */ | ||
277 | 16, 2, /* P */ | ||
278 | 24, 2, /* mux */ | ||
279 | 0); | ||
280 | |||
281 | /* Not present on A20 */ | ||
282 | static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "ahb", | ||
283 | 0x05c, BIT(31), 0); | ||
284 | |||
285 | static SUNXI_CCU_GATE(ahb_otg_clk, "ahb-otg", "ahb", | ||
286 | 0x060, BIT(0), 0); | ||
287 | static SUNXI_CCU_GATE(ahb_ehci0_clk, "ahb-ehci0", "ahb", | ||
288 | 0x060, BIT(1), 0); | ||
289 | static SUNXI_CCU_GATE(ahb_ohci0_clk, "ahb-ohci0", "ahb", | ||
290 | 0x060, BIT(2), 0); | ||
291 | static SUNXI_CCU_GATE(ahb_ehci1_clk, "ahb-ehci1", "ahb", | ||
292 | 0x060, BIT(3), 0); | ||
293 | static SUNXI_CCU_GATE(ahb_ohci1_clk, "ahb-ohci1", "ahb", | ||
294 | 0x060, BIT(4), 0); | ||
295 | static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb", | ||
296 | 0x060, BIT(5), 0); | ||
297 | static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb", | ||
298 | 0x060, BIT(6), 0); | ||
299 | static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb", | ||
300 | 0x060, BIT(7), 0); | ||
301 | static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb", | ||
302 | 0x060, BIT(8), 0); | ||
303 | static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb", | ||
304 | 0x060, BIT(9), 0); | ||
305 | static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb", | ||
306 | 0x060, BIT(10), 0); | ||
307 | static SUNXI_CCU_GATE(ahb_mmc3_clk, "ahb-mmc3", "ahb", | ||
308 | 0x060, BIT(11), 0); | ||
309 | static SUNXI_CCU_GATE(ahb_ms_clk, "ahb-ms", "ahb", | ||
310 | 0x060, BIT(12), 0); | ||
311 | static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb", | ||
312 | 0x060, BIT(13), 0); | ||
313 | static SUNXI_CCU_GATE(ahb_sdram_clk, "ahb-sdram", "ahb", | ||
314 | 0x060, BIT(14), CLK_IS_CRITICAL); | ||
315 | |||
316 | static SUNXI_CCU_GATE(ahb_ace_clk, "ahb-ace", "ahb", | ||
317 | 0x060, BIT(16), 0); | ||
318 | static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb", | ||
319 | 0x060, BIT(17), 0); | ||
320 | static SUNXI_CCU_GATE(ahb_ts_clk, "ahb-ts", "ahb", | ||
321 | 0x060, BIT(18), 0); | ||
322 | static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb", | ||
323 | 0x060, BIT(20), 0); | ||
324 | static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb", | ||
325 | 0x060, BIT(21), 0); | ||
326 | static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb", | ||
327 | 0x060, BIT(22), 0); | ||
328 | static SUNXI_CCU_GATE(ahb_spi3_clk, "ahb-spi3", "ahb", | ||
329 | 0x060, BIT(23), 0); | ||
330 | static SUNXI_CCU_GATE(ahb_pata_clk, "ahb-pata", "ahb", | ||
331 | 0x060, BIT(24), 0); | ||
332 | /* Not documented on A20 */ | ||
333 | static SUNXI_CCU_GATE(ahb_sata_clk, "ahb-sata", "ahb", | ||
334 | 0x060, BIT(25), 0); | ||
335 | /* Not present on A20 */ | ||
336 | static SUNXI_CCU_GATE(ahb_gps_clk, "ahb-gps", "ahb", | ||
337 | 0x060, BIT(26), 0); | ||
338 | /* Not present on A10 */ | ||
339 | static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer", "ahb", | ||
340 | 0x060, BIT(28), 0); | ||
341 | |||
342 | static SUNXI_CCU_GATE(ahb_ve_clk, "ahb-ve", "ahb", | ||
343 | 0x064, BIT(0), 0); | ||
344 | static SUNXI_CCU_GATE(ahb_tvd_clk, "ahb-tvd", "ahb", | ||
345 | 0x064, BIT(1), 0); | ||
346 | static SUNXI_CCU_GATE(ahb_tve0_clk, "ahb-tve0", "ahb", | ||
347 | 0x064, BIT(2), 0); | ||
348 | static SUNXI_CCU_GATE(ahb_tve1_clk, "ahb-tve1", "ahb", | ||
349 | 0x064, BIT(3), 0); | ||
350 | static SUNXI_CCU_GATE(ahb_lcd0_clk, "ahb-lcd0", "ahb", | ||
351 | 0x064, BIT(4), 0); | ||
352 | static SUNXI_CCU_GATE(ahb_lcd1_clk, "ahb-lcd1", "ahb", | ||
353 | 0x064, BIT(5), 0); | ||
354 | static SUNXI_CCU_GATE(ahb_csi0_clk, "ahb-csi0", "ahb", | ||
355 | 0x064, BIT(8), 0); | ||
356 | static SUNXI_CCU_GATE(ahb_csi1_clk, "ahb-csi1", "ahb", | ||
357 | 0x064, BIT(9), 0); | ||
358 | /* Not present on A10 */ | ||
359 | static SUNXI_CCU_GATE(ahb_hdmi1_clk, "ahb-hdmi1", "ahb", | ||
360 | 0x064, BIT(10), 0); | ||
361 | static SUNXI_CCU_GATE(ahb_hdmi0_clk, "ahb-hdmi0", "ahb", | ||
362 | 0x064, BIT(11), 0); | ||
363 | static SUNXI_CCU_GATE(ahb_de_be0_clk, "ahb-de-be0", "ahb", | ||
364 | 0x064, BIT(12), 0); | ||
365 | static SUNXI_CCU_GATE(ahb_de_be1_clk, "ahb-de-be1", "ahb", | ||
366 | 0x064, BIT(13), 0); | ||
367 | static SUNXI_CCU_GATE(ahb_de_fe0_clk, "ahb-de-fe0", "ahb", | ||
368 | 0x064, BIT(14), 0); | ||
369 | static SUNXI_CCU_GATE(ahb_de_fe1_clk, "ahb-de-fe1", "ahb", | ||
370 | 0x064, BIT(15), 0); | ||
371 | /* Not present on A10 */ | ||
372 | static SUNXI_CCU_GATE(ahb_gmac_clk, "ahb-gmac", "ahb", | ||
373 | 0x064, BIT(17), 0); | ||
374 | static SUNXI_CCU_GATE(ahb_mp_clk, "ahb-mp", "ahb", | ||
375 | 0x064, BIT(18), 0); | ||
376 | static SUNXI_CCU_GATE(ahb_gpu_clk, "ahb-gpu", "ahb", | ||
377 | 0x064, BIT(20), 0); | ||
378 | |||
379 | static SUNXI_CCU_GATE(apb0_codec_clk, "apb0-codec", "apb0", | ||
380 | 0x068, BIT(0), 0); | ||
381 | static SUNXI_CCU_GATE(apb0_spdif_clk, "apb0-spdif", "apb0", | ||
382 | 0x068, BIT(1), 0); | ||
383 | static SUNXI_CCU_GATE(apb0_ac97_clk, "apb0-ac97", "apb0", | ||
384 | 0x068, BIT(2), 0); | ||
385 | static SUNXI_CCU_GATE(apb0_i2s0_clk, "apb0-i2s0", "apb0", | ||
386 | 0x068, BIT(3), 0); | ||
387 | /* Not present on A10 */ | ||
388 | static SUNXI_CCU_GATE(apb0_i2s1_clk, "apb0-i2s1", "apb0", | ||
389 | 0x068, BIT(4), 0); | ||
390 | static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", | ||
391 | 0x068, BIT(5), 0); | ||
392 | static SUNXI_CCU_GATE(apb0_ir0_clk, "apb0-ir0", "apb0", | ||
393 | 0x068, BIT(6), 0); | ||
394 | static SUNXI_CCU_GATE(apb0_ir1_clk, "apb0-ir1", "apb0", | ||
395 | 0x068, BIT(7), 0); | ||
396 | /* Not present on A10 */ | ||
397 | static SUNXI_CCU_GATE(apb0_i2s2_clk, "apb0-i2s2", "apb0", | ||
398 | 0x068, BIT(8), 0); | ||
399 | static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad", "apb0", | ||
400 | 0x068, BIT(10), 0); | ||
401 | |||
402 | static SUNXI_CCU_GATE(apb1_i2c0_clk, "apb1-i2c0", "apb1", | ||
403 | 0x06c, BIT(0), 0); | ||
404 | static SUNXI_CCU_GATE(apb1_i2c1_clk, "apb1-i2c1", "apb1", | ||
405 | 0x06c, BIT(1), 0); | ||
406 | static SUNXI_CCU_GATE(apb1_i2c2_clk, "apb1-i2c2", "apb1", | ||
407 | 0x06c, BIT(2), 0); | ||
408 | /* Not present on A10 */ | ||
409 | static SUNXI_CCU_GATE(apb1_i2c3_clk, "apb1-i2c3", "apb1", | ||
410 | 0x06c, BIT(3), 0); | ||
411 | static SUNXI_CCU_GATE(apb1_can_clk, "apb1-can", "apb1", | ||
412 | 0x06c, BIT(4), 0); | ||
413 | static SUNXI_CCU_GATE(apb1_scr_clk, "apb1-scr", "apb1", | ||
414 | 0x06c, BIT(5), 0); | ||
415 | static SUNXI_CCU_GATE(apb1_ps20_clk, "apb1-ps20", "apb1", | ||
416 | 0x06c, BIT(6), 0); | ||
417 | static SUNXI_CCU_GATE(apb1_ps21_clk, "apb1-ps21", "apb1", | ||
418 | 0x06c, BIT(7), 0); | ||
419 | /* Not present on A10 */ | ||
420 | static SUNXI_CCU_GATE(apb1_i2c4_clk, "apb1-i2c4", "apb1", | ||
421 | 0x06c, BIT(15), 0); | ||
422 | static SUNXI_CCU_GATE(apb1_uart0_clk, "apb1-uart0", "apb1", | ||
423 | 0x06c, BIT(16), 0); | ||
424 | static SUNXI_CCU_GATE(apb1_uart1_clk, "apb1-uart1", "apb1", | ||
425 | 0x06c, BIT(17), 0); | ||
426 | static SUNXI_CCU_GATE(apb1_uart2_clk, "apb1-uart2", "apb1", | ||
427 | 0x06c, BIT(18), 0); | ||
428 | static SUNXI_CCU_GATE(apb1_uart3_clk, "apb1-uart3", "apb1", | ||
429 | 0x06c, BIT(19), 0); | ||
430 | static SUNXI_CCU_GATE(apb1_uart4_clk, "apb1-uart4", "apb1", | ||
431 | 0x06c, BIT(20), 0); | ||
432 | static SUNXI_CCU_GATE(apb1_uart5_clk, "apb1-uart5", "apb1", | ||
433 | 0x06c, BIT(21), 0); | ||
434 | static SUNXI_CCU_GATE(apb1_uart6_clk, "apb1-uart6", "apb1", | ||
435 | 0x06c, BIT(22), 0); | ||
436 | static SUNXI_CCU_GATE(apb1_uart7_clk, "apb1-uart7", "apb1", | ||
437 | 0x06c, BIT(23), 0); | ||
438 | |||
439 | static const char *const mod0_default_parents[] = { "hosc", "pll-periph", | ||
440 | "pll-ddr-other" }; | ||
441 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, | ||
442 | 0, 4, /* M */ | ||
443 | 16, 2, /* P */ | ||
444 | 24, 2, /* mux */ | ||
445 | BIT(31), /* gate */ | ||
446 | 0); | ||
447 | |||
448 | /* Undocumented on A10 */ | ||
449 | static SUNXI_CCU_MP_WITH_MUX_GATE(ms_clk, "ms", mod0_default_parents, 0x084, | ||
450 | 0, 4, /* M */ | ||
451 | 16, 2, /* P */ | ||
452 | 24, 2, /* mux */ | ||
453 | BIT(31), /* gate */ | ||
454 | 0); | ||
455 | |||
456 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, | ||
457 | 0, 4, /* M */ | ||
458 | 16, 2, /* P */ | ||
459 | 24, 2, /* mux */ | ||
460 | BIT(31), /* gate */ | ||
461 | 0); | ||
462 | |||
463 | /* MMC output and sample clocks are not present on A10 */ | ||
464 | static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", | ||
465 | 0x088, 8, 3, 0); | ||
466 | static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", | ||
467 | 0x088, 20, 3, 0); | ||
468 | |||
469 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, | ||
470 | 0, 4, /* M */ | ||
471 | 16, 2, /* P */ | ||
472 | 24, 2, /* mux */ | ||
473 | BIT(31), /* gate */ | ||
474 | 0); | ||
475 | |||
476 | /* MMC output and sample clocks are not present on A10 */ | ||
477 | static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", | ||
478 | 0x08c, 8, 3, 0); | ||
479 | static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", | ||
480 | 0x08c, 20, 3, 0); | ||
481 | |||
482 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, | ||
483 | 0, 4, /* M */ | ||
484 | 16, 2, /* P */ | ||
485 | 24, 2, /* mux */ | ||
486 | BIT(31), /* gate */ | ||
487 | 0); | ||
488 | |||
489 | /* MMC output and sample clocks are not present on A10 */ | ||
490 | static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", | ||
491 | 0x090, 8, 3, 0); | ||
492 | static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", | ||
493 | 0x090, 20, 3, 0); | ||
494 | |||
495 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094, | ||
496 | 0, 4, /* M */ | ||
497 | 16, 2, /* P */ | ||
498 | 24, 2, /* mux */ | ||
499 | BIT(31), /* gate */ | ||
500 | 0); | ||
501 | |||
502 | /* MMC output and sample clocks are not present on A10 */ | ||
503 | static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3", | ||
504 | 0x094, 8, 3, 0); | ||
505 | static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3", | ||
506 | 0x094, 20, 3, 0); | ||
507 | |||
508 | static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098, | ||
509 | 0, 4, /* M */ | ||
510 | 16, 2, /* P */ | ||
511 | 24, 2, /* mux */ | ||
512 | BIT(31), /* gate */ | ||
513 | 0); | ||
514 | |||
515 | static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c, | ||
516 | 0, 4, /* M */ | ||
517 | 16, 2, /* P */ | ||
518 | 24, 2, /* mux */ | ||
519 | BIT(31), /* gate */ | ||
520 | 0); | ||
521 | |||
522 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, | ||
523 | 0, 4, /* M */ | ||
524 | 16, 2, /* P */ | ||
525 | 24, 2, /* mux */ | ||
526 | BIT(31), /* gate */ | ||
527 | 0); | ||
528 | |||
529 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, | ||
530 | 0, 4, /* M */ | ||
531 | 16, 2, /* P */ | ||
532 | 24, 2, /* mux */ | ||
533 | BIT(31), /* gate */ | ||
534 | 0); | ||
535 | |||
536 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8, | ||
537 | 0, 4, /* M */ | ||
538 | 16, 2, /* P */ | ||
539 | 24, 2, /* mux */ | ||
540 | BIT(31), /* gate */ | ||
541 | 0); | ||
542 | |||
543 | /* Undocumented on A10 */ | ||
544 | static SUNXI_CCU_MP_WITH_MUX_GATE(pata_clk, "pata", mod0_default_parents, 0x0ac, | ||
545 | 0, 4, /* M */ | ||
546 | 16, 2, /* P */ | ||
547 | 24, 2, /* mux */ | ||
548 | BIT(31), /* gate */ | ||
549 | 0); | ||
550 | |||
551 | /* TODO: Check whether A10 actually supports osc32k as 4th parent? */ | ||
552 | static const char *const ir_parents_sun4i[] = { "hosc", "pll-periph", | ||
553 | "pll-ddr-other" }; | ||
554 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun4i_clk, "ir0", ir_parents_sun4i, 0x0b0, | ||
555 | 0, 4, /* M */ | ||
556 | 16, 2, /* P */ | ||
557 | 24, 2, /* mux */ | ||
558 | BIT(31), /* gate */ | ||
559 | 0); | ||
560 | |||
561 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun4i_clk, "ir1", ir_parents_sun4i, 0x0b4, | ||
562 | 0, 4, /* M */ | ||
563 | 16, 2, /* P */ | ||
564 | 24, 2, /* mux */ | ||
565 | BIT(31), /* gate */ | ||
566 | 0); | ||
567 | static const char *const ir_parents_sun7i[] = { "hosc", "pll-periph", | ||
568 | "pll-ddr-other", "osc32k" }; | ||
569 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun7i_clk, "ir0", ir_parents_sun7i, 0x0b0, | ||
570 | 0, 4, /* M */ | ||
571 | 16, 2, /* P */ | ||
572 | 24, 2, /* mux */ | ||
573 | BIT(31), /* gate */ | ||
574 | 0); | ||
575 | |||
576 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun7i_clk, "ir1", ir_parents_sun7i, 0x0b4, | ||
577 | 0, 4, /* M */ | ||
578 | 16, 2, /* P */ | ||
579 | 24, 2, /* mux */ | ||
580 | BIT(31), /* gate */ | ||
581 | 0); | ||
582 | |||
583 | static const char *const audio_parents[] = { "pll-audio-8x", "pll-audio-4x", | ||
584 | "pll-audio-2x", "pll-audio" }; | ||
585 | static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", audio_parents, | ||
586 | 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
587 | |||
588 | static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", audio_parents, | ||
589 | 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
590 | |||
591 | /* Undocumented on A10 */ | ||
592 | static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", audio_parents, | ||
593 | 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
594 | |||
595 | static const char *const keypad_parents[] = { "hosc", "losc"}; | ||
596 | static const u8 keypad_table[] = { 0, 2 }; | ||
597 | static struct ccu_mp keypad_clk = { | ||
598 | .enable = BIT(31), | ||
599 | .m = _SUNXI_CCU_DIV(0, 5), | ||
600 | .p = _SUNXI_CCU_DIV(16, 2), | ||
601 | .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table), | ||
602 | .common = { | ||
603 | .reg = 0x0c4, | ||
604 | .hw.init = CLK_HW_INIT_PARENTS("keypad", | ||
605 | keypad_parents, | ||
606 | &ccu_mp_ops, | ||
607 | 0), | ||
608 | }, | ||
609 | }; | ||
610 | |||
611 | /* | ||
612 | * SATA supports external clock as parent via BIT(24) and is probably an | ||
613 | * optional crystal or oscillator that can be connected to the | ||
614 | * SATA-CLKM / SATA-CLKP pins. | ||
615 | */ | ||
616 | static const char *const sata_parents[] = {"pll-periph-sata", "sata-ext"}; | ||
617 | static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents, | ||
618 | 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT); | ||
619 | |||
620 | |||
621 | static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "pll-periph", | ||
622 | 0x0cc, BIT(6), 0); | ||
623 | static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "pll-periph", | ||
624 | 0x0cc, BIT(7), 0); | ||
625 | static SUNXI_CCU_GATE(usb_phy_clk, "usb-phy", "pll-periph", | ||
626 | 0x0cc, BIT(8), 0); | ||
627 | |||
628 | /* TODO: GPS CLK 0x0d0 */ | ||
629 | |||
630 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0d4, | ||
631 | 0, 4, /* M */ | ||
632 | 16, 2, /* P */ | ||
633 | 24, 2, /* mux */ | ||
634 | BIT(31), /* gate */ | ||
635 | 0); | ||
636 | |||
637 | /* Not present on A10 */ | ||
638 | static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", audio_parents, | ||
639 | 0x0d8, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
640 | |||
641 | /* Not present on A10 */ | ||
642 | static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", audio_parents, | ||
643 | 0x0dc, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
644 | |||
645 | static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr", | ||
646 | 0x100, BIT(0), 0); | ||
647 | static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "pll-ddr", | ||
648 | 0x100, BIT(1), 0); | ||
649 | static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "pll-ddr", | ||
650 | 0x100, BIT(2), 0); | ||
651 | static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "pll-ddr", | ||
652 | 0x100, BIT(3), 0); | ||
653 | static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "pll-ddr", | ||
654 | 0x100, BIT(4), 0); | ||
655 | static SUNXI_CCU_GATE(dram_tve0_clk, "dram-tve0", "pll-ddr", | ||
656 | 0x100, BIT(5), 0); | ||
657 | static SUNXI_CCU_GATE(dram_tve1_clk, "dram-tve1", "pll-ddr", | ||
658 | 0x100, BIT(6), 0); | ||
659 | |||
660 | /* Clock seems to be critical only on sun4i */ | ||
661 | static SUNXI_CCU_GATE(dram_out_clk, "dram-out", "pll-ddr", | ||
662 | 0x100, BIT(15), CLK_IS_CRITICAL); | ||
663 | static SUNXI_CCU_GATE(dram_de_fe1_clk, "dram-de-fe1", "pll-ddr", | ||
664 | 0x100, BIT(24), 0); | ||
665 | static SUNXI_CCU_GATE(dram_de_fe0_clk, "dram-de-fe0", "pll-ddr", | ||
666 | 0x100, BIT(25), 0); | ||
667 | static SUNXI_CCU_GATE(dram_de_be0_clk, "dram-de-be0", "pll-ddr", | ||
668 | 0x100, BIT(26), 0); | ||
669 | static SUNXI_CCU_GATE(dram_de_be1_clk, "dram-de-be1", "pll-ddr", | ||
670 | 0x100, BIT(27), 0); | ||
671 | static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "pll-ddr", | ||
672 | 0x100, BIT(28), 0); | ||
673 | static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr", | ||
674 | 0x100, BIT(29), 0); | ||
675 | |||
676 | static const char *const de_parents[] = { "pll-video0", "pll-video1", | ||
677 | "pll-ddr-other" }; | ||
678 | static SUNXI_CCU_M_WITH_MUX_GATE(de_be0_clk, "de-be0", de_parents, | ||
679 | 0x104, 0, 4, 24, 2, BIT(31), 0); | ||
680 | |||
681 | static SUNXI_CCU_M_WITH_MUX_GATE(de_be1_clk, "de-be1", de_parents, | ||
682 | 0x108, 0, 4, 24, 2, BIT(31), 0); | ||
683 | |||
684 | static SUNXI_CCU_M_WITH_MUX_GATE(de_fe0_clk, "de-fe0", de_parents, | ||
685 | 0x10c, 0, 4, 24, 2, BIT(31), 0); | ||
686 | |||
687 | static SUNXI_CCU_M_WITH_MUX_GATE(de_fe1_clk, "de-fe1", de_parents, | ||
688 | 0x110, 0, 4, 24, 2, BIT(31), 0); | ||
689 | |||
690 | /* Undocumented on A10 */ | ||
691 | static SUNXI_CCU_M_WITH_MUX_GATE(de_mp_clk, "de-mp", de_parents, | ||
692 | 0x114, 0, 4, 24, 2, BIT(31), 0); | ||
693 | |||
694 | static const char *const disp_parents[] = { "pll-video0", "pll-video1", | ||
695 | "pll-video0-2x", "pll-video1-2x" }; | ||
696 | static SUNXI_CCU_MUX_WITH_GATE(tcon0_ch0_clk, "tcon0-ch0-sclk", disp_parents, | ||
697 | 0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
698 | static SUNXI_CCU_MUX_WITH_GATE(tcon1_ch0_clk, "tcon1-ch0-sclk", disp_parents, | ||
699 | 0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
700 | |||
701 | static const char *const csi_sclk_parents[] = { "pll-video0", "pll-ve", | ||
702 | "pll-ddr-other", "pll-periph" }; | ||
703 | |||
704 | static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", | ||
705 | csi_sclk_parents, | ||
706 | 0x120, 0, 4, 24, 2, BIT(31), 0); | ||
707 | |||
708 | /* TVD clock setup for A10 */ | ||
709 | static const char *const tvd_parents[] = { "pll-video0", "pll-video1" }; | ||
710 | static SUNXI_CCU_MUX_WITH_GATE(tvd_sun4i_clk, "tvd", tvd_parents, | ||
711 | 0x128, 24, 1, BIT(31), 0); | ||
712 | |||
713 | /* TVD clock setup for A20 */ | ||
714 | static SUNXI_CCU_MP_WITH_MUX_GATE(tvd_sclk2_sun7i_clk, | ||
715 | "tvd-sclk2", tvd_parents, | ||
716 | 0x128, | ||
717 | 0, 4, /* M */ | ||
718 | 16, 4, /* P */ | ||
719 | 8, 1, /* mux */ | ||
720 | BIT(15), /* gate */ | ||
721 | 0); | ||
722 | |||
723 | static SUNXI_CCU_M_WITH_GATE(tvd_sclk1_sun7i_clk, "tvd-sclk1", "tvd-sclk2", | ||
724 | 0x128, 0, 4, BIT(31), 0); | ||
725 | |||
726 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon0_ch1_sclk2_clk, "tcon0-ch1-sclk2", | ||
727 | disp_parents, | ||
728 | 0x12c, 0, 4, 24, 2, BIT(31), | ||
729 | CLK_SET_RATE_PARENT); | ||
730 | |||
731 | static SUNXI_CCU_M_WITH_GATE(tcon0_ch1_clk, | ||
732 | "tcon0-ch1-sclk1", "tcon0-ch1-sclk2", | ||
733 | 0x12c, 11, 1, BIT(15), | ||
734 | CLK_SET_RATE_PARENT); | ||
735 | |||
736 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_ch1_sclk2_clk, "tcon1-ch1-sclk2", | ||
737 | disp_parents, | ||
738 | 0x130, 0, 4, 24, 2, BIT(31), | ||
739 | CLK_SET_RATE_PARENT); | ||
740 | |||
741 | static SUNXI_CCU_M_WITH_GATE(tcon1_ch1_clk, | ||
742 | "tcon1-ch1-sclk1", "tcon1-ch1-sclk2", | ||
743 | 0x130, 11, 1, BIT(15), | ||
744 | CLK_SET_RATE_PARENT); | ||
745 | |||
746 | static const char *const csi_parents[] = { "hosc", "pll-video0", "pll-video1", | ||
747 | "pll-video0-2x", "pll-video1-2x"}; | ||
748 | static const u8 csi_table[] = { 0, 1, 2, 5, 6}; | ||
749 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_clk, "csi0", | ||
750 | csi_parents, csi_table, | ||
751 | 0x134, 0, 5, 24, 3, BIT(31), 0); | ||
752 | |||
753 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_clk, "csi1", | ||
754 | csi_parents, csi_table, | ||
755 | 0x138, 0, 5, 24, 3, BIT(31), 0); | ||
756 | |||
757 | static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, 16, 8, BIT(31), 0); | ||
758 | |||
759 | static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", | ||
760 | 0x140, BIT(31), CLK_SET_RATE_PARENT); | ||
761 | |||
762 | static SUNXI_CCU_GATE(avs_clk, "avs", "hosc", 0x144, BIT(31), 0); | ||
763 | |||
764 | static const char *const ace_parents[] = { "pll-ve", "pll-ddr-other" }; | ||
765 | static SUNXI_CCU_M_WITH_MUX_GATE(ace_clk, "ace", ace_parents, | ||
766 | 0x148, 0, 4, 24, 1, BIT(31), 0); | ||
767 | |||
768 | static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", disp_parents, | ||
769 | 0x150, 0, 4, 24, 2, BIT(31), | ||
770 | CLK_SET_RATE_PARENT); | ||
771 | |||
772 | static const char *const gpu_parents_sun4i[] = { "pll-video0", "pll-ve", | ||
773 | "pll-ddr-other", | ||
774 | "pll-video1" }; | ||
775 | static SUNXI_CCU_M_WITH_MUX_GATE(gpu_sun4i_clk, "gpu", gpu_parents_sun4i, | ||
776 | 0x154, 0, 4, 24, 2, BIT(31), | ||
777 | CLK_SET_RATE_PARENT); | ||
778 | |||
779 | static const char *const gpu_parents_sun7i[] = { "pll-video0", "pll-ve", | ||
780 | "pll-ddr-other", "pll-video1", | ||
781 | "pll-gpu" }; | ||
782 | static const u8 gpu_table_sun7i[] = { 0, 1, 2, 3, 4 }; | ||
783 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_sun7i_clk, "gpu", | ||
784 | gpu_parents_sun7i, gpu_table_sun7i, | ||
785 | 0x154, 0, 4, 24, 3, BIT(31), | ||
786 | CLK_SET_RATE_PARENT); | ||
787 | |||
788 | static const char *const mbus_sun4i_parents[] = { "hosc", "pll-periph", | ||
789 | "pll-ddr-other" }; | ||
790 | static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun4i_clk, "mbus", mbus_sun4i_parents, | ||
791 | 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), | ||
792 | 0); | ||
793 | static const char *const mbus_sun7i_parents[] = { "hosc", "pll-periph-base", | ||
794 | "pll-ddr-other" }; | ||
795 | static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun7i_clk, "mbus", mbus_sun7i_parents, | ||
796 | 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), | ||
797 | CLK_IS_CRITICAL); | ||
798 | |||
799 | static SUNXI_CCU_GATE(hdmi1_slow_clk, "hdmi1-slow", "hosc", 0x178, BIT(31), 0); | ||
800 | |||
801 | static const char *const hdmi1_parents[] = { "pll-video0", "pll-video1" }; | ||
802 | static const u8 hdmi1_table[] = { 0, 1}; | ||
803 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi1_clk, "hdmi1", | ||
804 | hdmi1_parents, hdmi1_table, | ||
805 | 0x17c, 0, 4, 24, 2, BIT(31), | ||
806 | CLK_SET_RATE_PARENT); | ||
807 | |||
808 | static const char *const out_parents[] = { "hosc", "osc32k", "hosc" }; | ||
809 | static const struct ccu_mux_fixed_prediv clk_out_predivs[] = { | ||
810 | { .index = 0, .div = 750, }, | ||
811 | }; | ||
812 | |||
813 | static struct ccu_mp out_a_clk = { | ||
814 | .enable = BIT(31), | ||
815 | .m = _SUNXI_CCU_DIV(8, 5), | ||
816 | .p = _SUNXI_CCU_DIV(20, 2), | ||
817 | .mux = { | ||
818 | .shift = 24, | ||
819 | .width = 2, | ||
820 | .fixed_predivs = clk_out_predivs, | ||
821 | .n_predivs = ARRAY_SIZE(clk_out_predivs), | ||
822 | }, | ||
823 | .common = { | ||
824 | .reg = 0x1f0, | ||
825 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
826 | .hw.init = CLK_HW_INIT_PARENTS("out-a", | ||
827 | out_parents, | ||
828 | &ccu_mp_ops, | ||
829 | 0), | ||
830 | }, | ||
831 | }; | ||
832 | static struct ccu_mp out_b_clk = { | ||
833 | .enable = BIT(31), | ||
834 | .m = _SUNXI_CCU_DIV(8, 5), | ||
835 | .p = _SUNXI_CCU_DIV(20, 2), | ||
836 | .mux = { | ||
837 | .shift = 24, | ||
838 | .width = 2, | ||
839 | .fixed_predivs = clk_out_predivs, | ||
840 | .n_predivs = ARRAY_SIZE(clk_out_predivs), | ||
841 | }, | ||
842 | .common = { | ||
843 | .reg = 0x1f4, | ||
844 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
845 | .hw.init = CLK_HW_INIT_PARENTS("out-b", | ||
846 | out_parents, | ||
847 | &ccu_mp_ops, | ||
848 | 0), | ||
849 | }, | ||
850 | }; | ||
851 | |||
852 | static struct ccu_common *sun4i_sun7i_ccu_clks[] = { | ||
853 | &hosc_clk.common, | ||
854 | &pll_core_clk.common, | ||
855 | &pll_audio_base_clk.common, | ||
856 | &pll_video0_clk.common, | ||
857 | &pll_ve_sun4i_clk.common, | ||
858 | &pll_ve_sun7i_clk.common, | ||
859 | &pll_ddr_base_clk.common, | ||
860 | &pll_ddr_clk.common, | ||
861 | &pll_ddr_other_clk.common, | ||
862 | &pll_periph_base_clk.common, | ||
863 | &pll_periph_sata_clk.common, | ||
864 | &pll_video1_clk.common, | ||
865 | &pll_gpu_clk.common, | ||
866 | &cpu_clk.common, | ||
867 | &axi_clk.common, | ||
868 | &axi_dram_clk.common, | ||
869 | &ahb_sun4i_clk.common, | ||
870 | &ahb_sun7i_clk.common, | ||
871 | &apb0_clk.common, | ||
872 | &apb1_clk.common, | ||
873 | &ahb_otg_clk.common, | ||
874 | &ahb_ehci0_clk.common, | ||
875 | &ahb_ohci0_clk.common, | ||
876 | &ahb_ehci1_clk.common, | ||
877 | &ahb_ohci1_clk.common, | ||
878 | &ahb_ss_clk.common, | ||
879 | &ahb_dma_clk.common, | ||
880 | &ahb_bist_clk.common, | ||
881 | &ahb_mmc0_clk.common, | ||
882 | &ahb_mmc1_clk.common, | ||
883 | &ahb_mmc2_clk.common, | ||
884 | &ahb_mmc3_clk.common, | ||
885 | &ahb_ms_clk.common, | ||
886 | &ahb_nand_clk.common, | ||
887 | &ahb_sdram_clk.common, | ||
888 | &ahb_ace_clk.common, | ||
889 | &ahb_emac_clk.common, | ||
890 | &ahb_ts_clk.common, | ||
891 | &ahb_spi0_clk.common, | ||
892 | &ahb_spi1_clk.common, | ||
893 | &ahb_spi2_clk.common, | ||
894 | &ahb_spi3_clk.common, | ||
895 | &ahb_pata_clk.common, | ||
896 | &ahb_sata_clk.common, | ||
897 | &ahb_gps_clk.common, | ||
898 | &ahb_hstimer_clk.common, | ||
899 | &ahb_ve_clk.common, | ||
900 | &ahb_tvd_clk.common, | ||
901 | &ahb_tve0_clk.common, | ||
902 | &ahb_tve1_clk.common, | ||
903 | &ahb_lcd0_clk.common, | ||
904 | &ahb_lcd1_clk.common, | ||
905 | &ahb_csi0_clk.common, | ||
906 | &ahb_csi1_clk.common, | ||
907 | &ahb_hdmi1_clk.common, | ||
908 | &ahb_hdmi0_clk.common, | ||
909 | &ahb_de_be0_clk.common, | ||
910 | &ahb_de_be1_clk.common, | ||
911 | &ahb_de_fe0_clk.common, | ||
912 | &ahb_de_fe1_clk.common, | ||
913 | &ahb_gmac_clk.common, | ||
914 | &ahb_mp_clk.common, | ||
915 | &ahb_gpu_clk.common, | ||
916 | &apb0_codec_clk.common, | ||
917 | &apb0_spdif_clk.common, | ||
918 | &apb0_ac97_clk.common, | ||
919 | &apb0_i2s0_clk.common, | ||
920 | &apb0_i2s1_clk.common, | ||
921 | &apb0_pio_clk.common, | ||
922 | &apb0_ir0_clk.common, | ||
923 | &apb0_ir1_clk.common, | ||
924 | &apb0_i2s2_clk.common, | ||
925 | &apb0_keypad_clk.common, | ||
926 | &apb1_i2c0_clk.common, | ||
927 | &apb1_i2c1_clk.common, | ||
928 | &apb1_i2c2_clk.common, | ||
929 | &apb1_i2c3_clk.common, | ||
930 | &apb1_can_clk.common, | ||
931 | &apb1_scr_clk.common, | ||
932 | &apb1_ps20_clk.common, | ||
933 | &apb1_ps21_clk.common, | ||
934 | &apb1_i2c4_clk.common, | ||
935 | &apb1_uart0_clk.common, | ||
936 | &apb1_uart1_clk.common, | ||
937 | &apb1_uart2_clk.common, | ||
938 | &apb1_uart3_clk.common, | ||
939 | &apb1_uart4_clk.common, | ||
940 | &apb1_uart5_clk.common, | ||
941 | &apb1_uart6_clk.common, | ||
942 | &apb1_uart7_clk.common, | ||
943 | &nand_clk.common, | ||
944 | &ms_clk.common, | ||
945 | &mmc0_clk.common, | ||
946 | &mmc0_output_clk.common, | ||
947 | &mmc0_sample_clk.common, | ||
948 | &mmc1_clk.common, | ||
949 | &mmc1_output_clk.common, | ||
950 | &mmc1_sample_clk.common, | ||
951 | &mmc2_clk.common, | ||
952 | &mmc2_output_clk.common, | ||
953 | &mmc2_sample_clk.common, | ||
954 | &mmc3_clk.common, | ||
955 | &mmc3_output_clk.common, | ||
956 | &mmc3_sample_clk.common, | ||
957 | &ts_clk.common, | ||
958 | &ss_clk.common, | ||
959 | &spi0_clk.common, | ||
960 | &spi1_clk.common, | ||
961 | &spi2_clk.common, | ||
962 | &pata_clk.common, | ||
963 | &ir0_sun4i_clk.common, | ||
964 | &ir1_sun4i_clk.common, | ||
965 | &ir0_sun7i_clk.common, | ||
966 | &ir1_sun7i_clk.common, | ||
967 | &i2s0_clk.common, | ||
968 | &ac97_clk.common, | ||
969 | &spdif_clk.common, | ||
970 | &keypad_clk.common, | ||
971 | &sata_clk.common, | ||
972 | &usb_ohci0_clk.common, | ||
973 | &usb_ohci1_clk.common, | ||
974 | &usb_phy_clk.common, | ||
975 | &spi3_clk.common, | ||
976 | &i2s1_clk.common, | ||
977 | &i2s2_clk.common, | ||
978 | &dram_ve_clk.common, | ||
979 | &dram_csi0_clk.common, | ||
980 | &dram_csi1_clk.common, | ||
981 | &dram_ts_clk.common, | ||
982 | &dram_tvd_clk.common, | ||
983 | &dram_tve0_clk.common, | ||
984 | &dram_tve1_clk.common, | ||
985 | &dram_out_clk.common, | ||
986 | &dram_de_fe1_clk.common, | ||
987 | &dram_de_fe0_clk.common, | ||
988 | &dram_de_be0_clk.common, | ||
989 | &dram_de_be1_clk.common, | ||
990 | &dram_mp_clk.common, | ||
991 | &dram_ace_clk.common, | ||
992 | &de_be0_clk.common, | ||
993 | &de_be1_clk.common, | ||
994 | &de_fe0_clk.common, | ||
995 | &de_fe1_clk.common, | ||
996 | &de_mp_clk.common, | ||
997 | &tcon0_ch0_clk.common, | ||
998 | &tcon1_ch0_clk.common, | ||
999 | &csi_sclk_clk.common, | ||
1000 | &tvd_sun4i_clk.common, | ||
1001 | &tvd_sclk1_sun7i_clk.common, | ||
1002 | &tvd_sclk2_sun7i_clk.common, | ||
1003 | &tcon0_ch1_sclk2_clk.common, | ||
1004 | &tcon0_ch1_clk.common, | ||
1005 | &tcon1_ch1_sclk2_clk.common, | ||
1006 | &tcon1_ch1_clk.common, | ||
1007 | &csi0_clk.common, | ||
1008 | &csi1_clk.common, | ||
1009 | &ve_clk.common, | ||
1010 | &codec_clk.common, | ||
1011 | &avs_clk.common, | ||
1012 | &ace_clk.common, | ||
1013 | &hdmi_clk.common, | ||
1014 | &gpu_sun4i_clk.common, | ||
1015 | &gpu_sun7i_clk.common, | ||
1016 | &mbus_sun4i_clk.common, | ||
1017 | &mbus_sun7i_clk.common, | ||
1018 | &hdmi1_slow_clk.common, | ||
1019 | &hdmi1_clk.common, | ||
1020 | &out_a_clk.common, | ||
1021 | &out_b_clk.common | ||
1022 | }; | ||
1023 | |||
1024 | /* Post-divider for pll-audio is hardcoded to 4 */ | ||
1025 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | ||
1026 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | ||
1027 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | ||
1028 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | ||
1029 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | ||
1030 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | ||
1031 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | ||
1032 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | ||
1033 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | ||
1034 | "pll-video0", 1, 2, CLK_SET_RATE_PARENT); | ||
1035 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | ||
1036 | "pll-video1", 1, 2, CLK_SET_RATE_PARENT); | ||
1037 | |||
1038 | |||
1039 | static struct clk_hw_onecell_data sun4i_a10_hw_clks = { | ||
1040 | .hws = { | ||
1041 | [CLK_HOSC] = &hosc_clk.common.hw, | ||
1042 | [CLK_PLL_CORE] = &pll_core_clk.common.hw, | ||
1043 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
1044 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
1045 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
1046 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
1047 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
1048 | [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, | ||
1049 | [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, | ||
1050 | [CLK_PLL_VE] = &pll_ve_sun4i_clk.common.hw, | ||
1051 | [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw, | ||
1052 | [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, | ||
1053 | [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw, | ||
1054 | [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw, | ||
1055 | [CLK_PLL_PERIPH] = &pll_periph_clk.hw, | ||
1056 | [CLK_PLL_PERIPH_SATA] = &pll_periph_sata_clk.common.hw, | ||
1057 | [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, | ||
1058 | [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, | ||
1059 | [CLK_CPU] = &cpu_clk.common.hw, | ||
1060 | [CLK_AXI] = &axi_clk.common.hw, | ||
1061 | [CLK_AXI_DRAM] = &axi_dram_clk.common.hw, | ||
1062 | [CLK_AHB] = &ahb_sun4i_clk.common.hw, | ||
1063 | [CLK_APB0] = &apb0_clk.common.hw, | ||
1064 | [CLK_APB1] = &apb1_clk.common.hw, | ||
1065 | [CLK_AHB_OTG] = &ahb_otg_clk.common.hw, | ||
1066 | [CLK_AHB_EHCI0] = &ahb_ehci0_clk.common.hw, | ||
1067 | [CLK_AHB_OHCI0] = &ahb_ohci0_clk.common.hw, | ||
1068 | [CLK_AHB_EHCI1] = &ahb_ehci1_clk.common.hw, | ||
1069 | [CLK_AHB_OHCI1] = &ahb_ohci1_clk.common.hw, | ||
1070 | [CLK_AHB_SS] = &ahb_ss_clk.common.hw, | ||
1071 | [CLK_AHB_DMA] = &ahb_dma_clk.common.hw, | ||
1072 | [CLK_AHB_BIST] = &ahb_bist_clk.common.hw, | ||
1073 | [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw, | ||
1074 | [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw, | ||
1075 | [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw, | ||
1076 | [CLK_AHB_MMC3] = &ahb_mmc3_clk.common.hw, | ||
1077 | [CLK_AHB_MS] = &ahb_ms_clk.common.hw, | ||
1078 | [CLK_AHB_NAND] = &ahb_nand_clk.common.hw, | ||
1079 | [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw, | ||
1080 | [CLK_AHB_ACE] = &ahb_ace_clk.common.hw, | ||
1081 | [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw, | ||
1082 | [CLK_AHB_TS] = &ahb_ts_clk.common.hw, | ||
1083 | [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw, | ||
1084 | [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw, | ||
1085 | [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw, | ||
1086 | [CLK_AHB_SPI3] = &ahb_spi3_clk.common.hw, | ||
1087 | [CLK_AHB_PATA] = &ahb_pata_clk.common.hw, | ||
1088 | [CLK_AHB_SATA] = &ahb_sata_clk.common.hw, | ||
1089 | [CLK_AHB_GPS] = &ahb_gps_clk.common.hw, | ||
1090 | [CLK_AHB_VE] = &ahb_ve_clk.common.hw, | ||
1091 | [CLK_AHB_TVD] = &ahb_tvd_clk.common.hw, | ||
1092 | [CLK_AHB_TVE0] = &ahb_tve0_clk.common.hw, | ||
1093 | [CLK_AHB_TVE1] = &ahb_tve1_clk.common.hw, | ||
1094 | [CLK_AHB_LCD0] = &ahb_lcd0_clk.common.hw, | ||
1095 | [CLK_AHB_LCD1] = &ahb_lcd1_clk.common.hw, | ||
1096 | [CLK_AHB_CSI0] = &ahb_csi0_clk.common.hw, | ||
1097 | [CLK_AHB_CSI1] = &ahb_csi1_clk.common.hw, | ||
1098 | [CLK_AHB_HDMI0] = &ahb_hdmi0_clk.common.hw, | ||
1099 | [CLK_AHB_DE_BE0] = &ahb_de_be0_clk.common.hw, | ||
1100 | [CLK_AHB_DE_BE1] = &ahb_de_be1_clk.common.hw, | ||
1101 | [CLK_AHB_DE_FE0] = &ahb_de_fe0_clk.common.hw, | ||
1102 | [CLK_AHB_DE_FE1] = &ahb_de_fe1_clk.common.hw, | ||
1103 | [CLK_AHB_MP] = &ahb_mp_clk.common.hw, | ||
1104 | [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw, | ||
1105 | [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw, | ||
1106 | [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw, | ||
1107 | [CLK_APB0_AC97] = &apb0_ac97_clk.common.hw, | ||
1108 | [CLK_APB0_I2S0] = &apb0_i2s0_clk.common.hw, | ||
1109 | [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, | ||
1110 | [CLK_APB0_IR0] = &apb0_ir0_clk.common.hw, | ||
1111 | [CLK_APB0_IR1] = &apb0_ir1_clk.common.hw, | ||
1112 | [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw, | ||
1113 | [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw, | ||
1114 | [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw, | ||
1115 | [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw, | ||
1116 | [CLK_APB1_CAN] = &apb1_can_clk.common.hw, | ||
1117 | [CLK_APB1_SCR] = &apb1_scr_clk.common.hw, | ||
1118 | [CLK_APB1_PS20] = &apb1_ps20_clk.common.hw, | ||
1119 | [CLK_APB1_PS21] = &apb1_ps21_clk.common.hw, | ||
1120 | [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw, | ||
1121 | [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw, | ||
1122 | [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw, | ||
1123 | [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw, | ||
1124 | [CLK_APB1_UART4] = &apb1_uart4_clk.common.hw, | ||
1125 | [CLK_APB1_UART5] = &apb1_uart5_clk.common.hw, | ||
1126 | [CLK_APB1_UART6] = &apb1_uart6_clk.common.hw, | ||
1127 | [CLK_APB1_UART7] = &apb1_uart7_clk.common.hw, | ||
1128 | [CLK_NAND] = &nand_clk.common.hw, | ||
1129 | [CLK_MS] = &ms_clk.common.hw, | ||
1130 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
1131 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
1132 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
1133 | [CLK_MMC3] = &mmc3_clk.common.hw, | ||
1134 | [CLK_TS] = &ts_clk.common.hw, | ||
1135 | [CLK_SS] = &ss_clk.common.hw, | ||
1136 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
1137 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
1138 | [CLK_SPI2] = &spi2_clk.common.hw, | ||
1139 | [CLK_PATA] = &pata_clk.common.hw, | ||
1140 | [CLK_IR0] = &ir0_sun4i_clk.common.hw, | ||
1141 | [CLK_IR1] = &ir1_sun4i_clk.common.hw, | ||
1142 | [CLK_I2S0] = &i2s0_clk.common.hw, | ||
1143 | [CLK_AC97] = &ac97_clk.common.hw, | ||
1144 | [CLK_SPDIF] = &spdif_clk.common.hw, | ||
1145 | [CLK_KEYPAD] = &keypad_clk.common.hw, | ||
1146 | [CLK_SATA] = &sata_clk.common.hw, | ||
1147 | [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, | ||
1148 | [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, | ||
1149 | [CLK_USB_PHY] = &usb_phy_clk.common.hw, | ||
1150 | /* CLK_GPS is unimplemented */ | ||
1151 | [CLK_SPI3] = &spi3_clk.common.hw, | ||
1152 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
1153 | [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw, | ||
1154 | [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw, | ||
1155 | [CLK_DRAM_TS] = &dram_ts_clk.common.hw, | ||
1156 | [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw, | ||
1157 | [CLK_DRAM_TVE0] = &dram_tve0_clk.common.hw, | ||
1158 | [CLK_DRAM_TVE1] = &dram_tve1_clk.common.hw, | ||
1159 | [CLK_DRAM_OUT] = &dram_out_clk.common.hw, | ||
1160 | [CLK_DRAM_DE_FE1] = &dram_de_fe1_clk.common.hw, | ||
1161 | [CLK_DRAM_DE_FE0] = &dram_de_fe0_clk.common.hw, | ||
1162 | [CLK_DRAM_DE_BE0] = &dram_de_be0_clk.common.hw, | ||
1163 | [CLK_DRAM_DE_BE1] = &dram_de_be1_clk.common.hw, | ||
1164 | [CLK_DRAM_MP] = &dram_mp_clk.common.hw, | ||
1165 | [CLK_DRAM_ACE] = &dram_ace_clk.common.hw, | ||
1166 | [CLK_DE_BE0] = &de_be0_clk.common.hw, | ||
1167 | [CLK_DE_BE1] = &de_be1_clk.common.hw, | ||
1168 | [CLK_DE_FE0] = &de_fe0_clk.common.hw, | ||
1169 | [CLK_DE_FE1] = &de_fe1_clk.common.hw, | ||
1170 | [CLK_DE_MP] = &de_mp_clk.common.hw, | ||
1171 | [CLK_TCON0_CH0] = &tcon0_ch0_clk.common.hw, | ||
1172 | [CLK_TCON1_CH0] = &tcon1_ch0_clk.common.hw, | ||
1173 | [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, | ||
1174 | [CLK_TVD] = &tvd_sun4i_clk.common.hw, | ||
1175 | [CLK_TCON0_CH1_SCLK2] = &tcon0_ch1_sclk2_clk.common.hw, | ||
1176 | [CLK_TCON0_CH1] = &tcon0_ch1_clk.common.hw, | ||
1177 | [CLK_TCON1_CH1_SCLK2] = &tcon1_ch1_sclk2_clk.common.hw, | ||
1178 | [CLK_TCON1_CH1] = &tcon1_ch1_clk.common.hw, | ||
1179 | [CLK_CSI0] = &csi0_clk.common.hw, | ||
1180 | [CLK_CSI1] = &csi1_clk.common.hw, | ||
1181 | [CLK_VE] = &ve_clk.common.hw, | ||
1182 | [CLK_CODEC] = &codec_clk.common.hw, | ||
1183 | [CLK_AVS] = &avs_clk.common.hw, | ||
1184 | [CLK_ACE] = &ace_clk.common.hw, | ||
1185 | [CLK_HDMI] = &hdmi_clk.common.hw, | ||
1186 | [CLK_GPU] = &gpu_sun7i_clk.common.hw, | ||
1187 | [CLK_MBUS] = &mbus_sun4i_clk.common.hw, | ||
1188 | }, | ||
1189 | .num = CLK_NUMBER_SUN4I, | ||
1190 | }; | ||
1191 | static struct clk_hw_onecell_data sun7i_a20_hw_clks = { | ||
1192 | .hws = { | ||
1193 | [CLK_HOSC] = &hosc_clk.common.hw, | ||
1194 | [CLK_PLL_CORE] = &pll_core_clk.common.hw, | ||
1195 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
1196 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
1197 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
1198 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
1199 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
1200 | [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, | ||
1201 | [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, | ||
1202 | [CLK_PLL_VE] = &pll_ve_sun7i_clk.common.hw, | ||
1203 | [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw, | ||
1204 | [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, | ||
1205 | [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw, | ||
1206 | [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw, | ||
1207 | [CLK_PLL_PERIPH] = &pll_periph_clk.hw, | ||
1208 | [CLK_PLL_PERIPH_SATA] = &pll_periph_sata_clk.common.hw, | ||
1209 | [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, | ||
1210 | [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, | ||
1211 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, | ||
1212 | [CLK_CPU] = &cpu_clk.common.hw, | ||
1213 | [CLK_AXI] = &axi_clk.common.hw, | ||
1214 | [CLK_AHB] = &ahb_sun7i_clk.common.hw, | ||
1215 | [CLK_APB0] = &apb0_clk.common.hw, | ||
1216 | [CLK_APB1] = &apb1_clk.common.hw, | ||
1217 | [CLK_AHB_OTG] = &ahb_otg_clk.common.hw, | ||
1218 | [CLK_AHB_EHCI0] = &ahb_ehci0_clk.common.hw, | ||
1219 | [CLK_AHB_OHCI0] = &ahb_ohci0_clk.common.hw, | ||
1220 | [CLK_AHB_EHCI1] = &ahb_ehci1_clk.common.hw, | ||
1221 | [CLK_AHB_OHCI1] = &ahb_ohci1_clk.common.hw, | ||
1222 | [CLK_AHB_SS] = &ahb_ss_clk.common.hw, | ||
1223 | [CLK_AHB_DMA] = &ahb_dma_clk.common.hw, | ||
1224 | [CLK_AHB_BIST] = &ahb_bist_clk.common.hw, | ||
1225 | [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw, | ||
1226 | [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw, | ||
1227 | [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw, | ||
1228 | [CLK_AHB_MMC3] = &ahb_mmc3_clk.common.hw, | ||
1229 | [CLK_AHB_MS] = &ahb_ms_clk.common.hw, | ||
1230 | [CLK_AHB_NAND] = &ahb_nand_clk.common.hw, | ||
1231 | [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw, | ||
1232 | [CLK_AHB_ACE] = &ahb_ace_clk.common.hw, | ||
1233 | [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw, | ||
1234 | [CLK_AHB_TS] = &ahb_ts_clk.common.hw, | ||
1235 | [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw, | ||
1236 | [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw, | ||
1237 | [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw, | ||
1238 | [CLK_AHB_SPI3] = &ahb_spi3_clk.common.hw, | ||
1239 | [CLK_AHB_PATA] = &ahb_pata_clk.common.hw, | ||
1240 | [CLK_AHB_SATA] = &ahb_sata_clk.common.hw, | ||
1241 | [CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw, | ||
1242 | [CLK_AHB_VE] = &ahb_ve_clk.common.hw, | ||
1243 | [CLK_AHB_TVD] = &ahb_tvd_clk.common.hw, | ||
1244 | [CLK_AHB_TVE0] = &ahb_tve0_clk.common.hw, | ||
1245 | [CLK_AHB_TVE1] = &ahb_tve1_clk.common.hw, | ||
1246 | [CLK_AHB_LCD0] = &ahb_lcd0_clk.common.hw, | ||
1247 | [CLK_AHB_LCD1] = &ahb_lcd1_clk.common.hw, | ||
1248 | [CLK_AHB_CSI0] = &ahb_csi0_clk.common.hw, | ||
1249 | [CLK_AHB_CSI1] = &ahb_csi1_clk.common.hw, | ||
1250 | [CLK_AHB_HDMI1] = &ahb_hdmi1_clk.common.hw, | ||
1251 | [CLK_AHB_HDMI0] = &ahb_hdmi0_clk.common.hw, | ||
1252 | [CLK_AHB_DE_BE0] = &ahb_de_be0_clk.common.hw, | ||
1253 | [CLK_AHB_DE_BE1] = &ahb_de_be1_clk.common.hw, | ||
1254 | [CLK_AHB_DE_FE0] = &ahb_de_fe0_clk.common.hw, | ||
1255 | [CLK_AHB_DE_FE1] = &ahb_de_fe1_clk.common.hw, | ||
1256 | [CLK_AHB_GMAC] = &ahb_gmac_clk.common.hw, | ||
1257 | [CLK_AHB_MP] = &ahb_mp_clk.common.hw, | ||
1258 | [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw, | ||
1259 | [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw, | ||
1260 | [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw, | ||
1261 | [CLK_APB0_AC97] = &apb0_ac97_clk.common.hw, | ||
1262 | [CLK_APB0_I2S0] = &apb0_i2s0_clk.common.hw, | ||
1263 | [CLK_APB0_I2S1] = &apb0_i2s1_clk.common.hw, | ||
1264 | [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, | ||
1265 | [CLK_APB0_IR0] = &apb0_ir0_clk.common.hw, | ||
1266 | [CLK_APB0_IR1] = &apb0_ir1_clk.common.hw, | ||
1267 | [CLK_APB0_I2S2] = &apb0_i2s2_clk.common.hw, | ||
1268 | [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw, | ||
1269 | [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw, | ||
1270 | [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw, | ||
1271 | [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw, | ||
1272 | [CLK_APB1_I2C3] = &apb1_i2c3_clk.common.hw, | ||
1273 | [CLK_APB1_CAN] = &apb1_can_clk.common.hw, | ||
1274 | [CLK_APB1_SCR] = &apb1_scr_clk.common.hw, | ||
1275 | [CLK_APB1_PS20] = &apb1_ps20_clk.common.hw, | ||
1276 | [CLK_APB1_PS21] = &apb1_ps21_clk.common.hw, | ||
1277 | [CLK_APB1_I2C4] = &apb1_i2c4_clk.common.hw, | ||
1278 | [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw, | ||
1279 | [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw, | ||
1280 | [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw, | ||
1281 | [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw, | ||
1282 | [CLK_APB1_UART4] = &apb1_uart4_clk.common.hw, | ||
1283 | [CLK_APB1_UART5] = &apb1_uart5_clk.common.hw, | ||
1284 | [CLK_APB1_UART6] = &apb1_uart6_clk.common.hw, | ||
1285 | [CLK_APB1_UART7] = &apb1_uart7_clk.common.hw, | ||
1286 | [CLK_NAND] = &nand_clk.common.hw, | ||
1287 | [CLK_MS] = &ms_clk.common.hw, | ||
1288 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
1289 | [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, | ||
1290 | [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, | ||
1291 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
1292 | [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, | ||
1293 | [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, | ||
1294 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
1295 | [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, | ||
1296 | [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, | ||
1297 | [CLK_MMC3] = &mmc3_clk.common.hw, | ||
1298 | [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw, | ||
1299 | [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw, | ||
1300 | [CLK_TS] = &ts_clk.common.hw, | ||
1301 | [CLK_SS] = &ss_clk.common.hw, | ||
1302 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
1303 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
1304 | [CLK_SPI2] = &spi2_clk.common.hw, | ||
1305 | [CLK_PATA] = &pata_clk.common.hw, | ||
1306 | [CLK_IR0] = &ir0_sun7i_clk.common.hw, | ||
1307 | [CLK_IR1] = &ir1_sun7i_clk.common.hw, | ||
1308 | [CLK_I2S0] = &i2s0_clk.common.hw, | ||
1309 | [CLK_AC97] = &ac97_clk.common.hw, | ||
1310 | [CLK_SPDIF] = &spdif_clk.common.hw, | ||
1311 | [CLK_KEYPAD] = &keypad_clk.common.hw, | ||
1312 | [CLK_SATA] = &sata_clk.common.hw, | ||
1313 | [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, | ||
1314 | [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, | ||
1315 | [CLK_USB_PHY] = &usb_phy_clk.common.hw, | ||
1316 | /* CLK_GPS is unimplemented */ | ||
1317 | [CLK_SPI3] = &spi3_clk.common.hw, | ||
1318 | [CLK_I2S1] = &i2s1_clk.common.hw, | ||
1319 | [CLK_I2S2] = &i2s2_clk.common.hw, | ||
1320 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
1321 | [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw, | ||
1322 | [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw, | ||
1323 | [CLK_DRAM_TS] = &dram_ts_clk.common.hw, | ||
1324 | [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw, | ||
1325 | [CLK_DRAM_TVE0] = &dram_tve0_clk.common.hw, | ||
1326 | [CLK_DRAM_TVE1] = &dram_tve1_clk.common.hw, | ||
1327 | [CLK_DRAM_OUT] = &dram_out_clk.common.hw, | ||
1328 | [CLK_DRAM_DE_FE1] = &dram_de_fe1_clk.common.hw, | ||
1329 | [CLK_DRAM_DE_FE0] = &dram_de_fe0_clk.common.hw, | ||
1330 | [CLK_DRAM_DE_BE0] = &dram_de_be0_clk.common.hw, | ||
1331 | [CLK_DRAM_DE_BE1] = &dram_de_be1_clk.common.hw, | ||
1332 | [CLK_DRAM_MP] = &dram_mp_clk.common.hw, | ||
1333 | [CLK_DRAM_ACE] = &dram_ace_clk.common.hw, | ||
1334 | [CLK_DE_BE0] = &de_be0_clk.common.hw, | ||
1335 | [CLK_DE_BE1] = &de_be1_clk.common.hw, | ||
1336 | [CLK_DE_FE0] = &de_fe0_clk.common.hw, | ||
1337 | [CLK_DE_FE1] = &de_fe1_clk.common.hw, | ||
1338 | [CLK_DE_MP] = &de_mp_clk.common.hw, | ||
1339 | [CLK_TCON0_CH0] = &tcon0_ch0_clk.common.hw, | ||
1340 | [CLK_TCON1_CH0] = &tcon1_ch0_clk.common.hw, | ||
1341 | [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, | ||
1342 | [CLK_TVD_SCLK2] = &tvd_sclk2_sun7i_clk.common.hw, | ||
1343 | [CLK_TVD] = &tvd_sclk1_sun7i_clk.common.hw, | ||
1344 | [CLK_TCON0_CH1_SCLK2] = &tcon0_ch1_sclk2_clk.common.hw, | ||
1345 | [CLK_TCON0_CH1] = &tcon0_ch1_clk.common.hw, | ||
1346 | [CLK_TCON1_CH1_SCLK2] = &tcon1_ch1_sclk2_clk.common.hw, | ||
1347 | [CLK_TCON1_CH1] = &tcon1_ch1_clk.common.hw, | ||
1348 | [CLK_CSI0] = &csi0_clk.common.hw, | ||
1349 | [CLK_CSI1] = &csi1_clk.common.hw, | ||
1350 | [CLK_VE] = &ve_clk.common.hw, | ||
1351 | [CLK_CODEC] = &codec_clk.common.hw, | ||
1352 | [CLK_AVS] = &avs_clk.common.hw, | ||
1353 | [CLK_ACE] = &ace_clk.common.hw, | ||
1354 | [CLK_HDMI] = &hdmi_clk.common.hw, | ||
1355 | [CLK_GPU] = &gpu_sun7i_clk.common.hw, | ||
1356 | [CLK_MBUS] = &mbus_sun7i_clk.common.hw, | ||
1357 | [CLK_HDMI1_SLOW] = &hdmi1_slow_clk.common.hw, | ||
1358 | [CLK_HDMI1] = &hdmi1_clk.common.hw, | ||
1359 | [CLK_OUT_A] = &out_a_clk.common.hw, | ||
1360 | [CLK_OUT_B] = &out_b_clk.common.hw, | ||
1361 | }, | ||
1362 | .num = CLK_NUMBER_SUN7I, | ||
1363 | }; | ||
1364 | |||
1365 | static struct ccu_reset_map sunxi_a10_a20_ccu_resets[] = { | ||
1366 | [RST_USB_PHY0] = { 0x0cc, BIT(0) }, | ||
1367 | [RST_USB_PHY1] = { 0x0cc, BIT(1) }, | ||
1368 | [RST_USB_PHY2] = { 0x0cc, BIT(2) }, | ||
1369 | [RST_GPS] = { 0x0d0, BIT(0) }, | ||
1370 | [RST_DE_BE0] = { 0x104, BIT(30) }, | ||
1371 | [RST_DE_BE1] = { 0x108, BIT(30) }, | ||
1372 | [RST_DE_FE0] = { 0x10c, BIT(30) }, | ||
1373 | [RST_DE_FE1] = { 0x110, BIT(30) }, | ||
1374 | [RST_DE_MP] = { 0x114, BIT(30) }, | ||
1375 | [RST_TVE0] = { 0x118, BIT(29) }, | ||
1376 | [RST_TCON0] = { 0x118, BIT(30) }, | ||
1377 | [RST_TVE1] = { 0x11c, BIT(29) }, | ||
1378 | [RST_TCON1] = { 0x11c, BIT(30) }, | ||
1379 | [RST_CSI0] = { 0x134, BIT(30) }, | ||
1380 | [RST_CSI1] = { 0x138, BIT(30) }, | ||
1381 | [RST_VE] = { 0x13c, BIT(0) }, | ||
1382 | [RST_ACE] = { 0x148, BIT(16) }, | ||
1383 | [RST_LVDS] = { 0x14c, BIT(0) }, | ||
1384 | [RST_GPU] = { 0x154, BIT(30) }, | ||
1385 | [RST_HDMI_H] = { 0x170, BIT(0) }, | ||
1386 | [RST_HDMI_SYS] = { 0x170, BIT(1) }, | ||
1387 | [RST_HDMI_AUDIO_DMA] = { 0x170, BIT(2) }, | ||
1388 | }; | ||
1389 | |||
1390 | static const struct sunxi_ccu_desc sun4i_a10_ccu_desc = { | ||
1391 | .ccu_clks = sun4i_sun7i_ccu_clks, | ||
1392 | .num_ccu_clks = ARRAY_SIZE(sun4i_sun7i_ccu_clks), | ||
1393 | |||
1394 | .hw_clks = &sun4i_a10_hw_clks, | ||
1395 | |||
1396 | .resets = sunxi_a10_a20_ccu_resets, | ||
1397 | .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets), | ||
1398 | }; | ||
1399 | |||
1400 | static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = { | ||
1401 | .ccu_clks = sun4i_sun7i_ccu_clks, | ||
1402 | .num_ccu_clks = ARRAY_SIZE(sun4i_sun7i_ccu_clks), | ||
1403 | |||
1404 | .hw_clks = &sun7i_a20_hw_clks, | ||
1405 | |||
1406 | .resets = sunxi_a10_a20_ccu_resets, | ||
1407 | .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets), | ||
1408 | }; | ||
1409 | |||
1410 | static void __init sun4i_ccu_init(struct device_node *node, | ||
1411 | const struct sunxi_ccu_desc *desc) | ||
1412 | { | ||
1413 | void __iomem *reg; | ||
1414 | u32 val; | ||
1415 | |||
1416 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
1417 | if (IS_ERR(reg)) { | ||
1418 | pr_err("%s: Could not map the clock registers\n", | ||
1419 | of_node_full_name(node)); | ||
1420 | return; | ||
1421 | } | ||
1422 | |||
1423 | /* Force the PLL-Audio-1x divider to 4 */ | ||
1424 | val = readl(reg + SUN4I_PLL_AUDIO_REG); | ||
1425 | val &= ~GENMASK(29, 26); | ||
1426 | writel(val | (4 << 26), reg + SUN4I_PLL_AUDIO_REG); | ||
1427 | |||
1428 | /* | ||
1429 | * Use the peripheral PLL6 as the AHB parent, instead of CPU / | ||
1430 | * AXI which have rate changes due to cpufreq. | ||
1431 | * | ||
1432 | * This is especially a big deal for the HS timer whose parent | ||
1433 | * clock is AHB. | ||
1434 | * | ||
1435 | * NB! These bits are undocumented in A10 manual. | ||
1436 | */ | ||
1437 | val = readl(reg + SUN4I_AHB_REG); | ||
1438 | val &= ~GENMASK(7, 6); | ||
1439 | writel(val | (2 << 6), reg + SUN4I_AHB_REG); | ||
1440 | |||
1441 | sunxi_ccu_probe(node, reg, desc); | ||
1442 | } | ||
1443 | |||
1444 | static void __init sun4i_a10_ccu_setup(struct device_node *node) | ||
1445 | { | ||
1446 | sun4i_ccu_init(node, &sun4i_a10_ccu_desc); | ||
1447 | } | ||
1448 | CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu", | ||
1449 | sun4i_a10_ccu_setup); | ||
1450 | |||
1451 | static void __init sun7i_a20_ccu_setup(struct device_node *node) | ||
1452 | { | ||
1453 | sun4i_ccu_init(node, &sun7i_a20_ccu_desc); | ||
1454 | } | ||
1455 | CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu", | ||
1456 | sun7i_a20_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.h b/drivers/clk/sunxi-ng/ccu-sun4i-a10.h new file mode 100644 index 000000000000..c5947c7c050e --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Priit Laes | ||
3 | * | ||
4 | * Priit Laes <plaes@plaes.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #ifndef _CCU_SUN4I_A10_H_ | ||
18 | #define _CCU_SUN4I_A10_H_ | ||
19 | |||
20 | #include <dt-bindings/clock/sun4i-a10-ccu.h> | ||
21 | #include <dt-bindings/clock/sun7i-a20-ccu.h> | ||
22 | #include <dt-bindings/reset/sun4i-a10-ccu.h> | ||
23 | |||
24 | /* The HOSC is exported */ | ||
25 | #define CLK_PLL_CORE 2 | ||
26 | #define CLK_PLL_AUDIO_BASE 3 | ||
27 | #define CLK_PLL_AUDIO 4 | ||
28 | #define CLK_PLL_AUDIO_2X 5 | ||
29 | #define CLK_PLL_AUDIO_4X 6 | ||
30 | #define CLK_PLL_AUDIO_8X 7 | ||
31 | #define CLK_PLL_VIDEO0 8 | ||
32 | #define CLK_PLL_VIDEO0_2X 9 | ||
33 | #define CLK_PLL_VE 10 | ||
34 | #define CLK_PLL_DDR_BASE 11 | ||
35 | #define CLK_PLL_DDR 12 | ||
36 | #define CLK_PLL_DDR_OTHER 13 | ||
37 | #define CLK_PLL_PERIPH_BASE 14 | ||
38 | #define CLK_PLL_PERIPH 15 | ||
39 | #define CLK_PLL_PERIPH_SATA 16 | ||
40 | #define CLK_PLL_VIDEO1 17 | ||
41 | #define CLK_PLL_VIDEO1_2X 18 | ||
42 | #define CLK_PLL_GPU 19 | ||
43 | |||
44 | /* The CPU clock is exported */ | ||
45 | #define CLK_AXI 21 | ||
46 | #define CLK_AXI_DRAM 22 | ||
47 | #define CLK_AHB 23 | ||
48 | #define CLK_APB0 24 | ||
49 | #define CLK_APB1 25 | ||
50 | |||
51 | /* AHB gates are exported (23..68) */ | ||
52 | /* APB0 gates are exported (69..78) */ | ||
53 | /* APB1 gates are exported (79..95) */ | ||
54 | /* IP module clocks are exported (96..128) */ | ||
55 | /* DRAM gates are exported (129..142)*/ | ||
56 | /* Media (display engine clocks & etc) are exported (143..169) */ | ||
57 | |||
58 | #define CLK_NUMBER_SUN4I (CLK_MBUS + 1) | ||
59 | #define CLK_NUMBER_SUN7I (CLK_OUT_B + 1) | ||
60 | |||
61 | #endif /* _CCU_SUN4I_A10_H_ */ | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index 31d7ffda9aab..ab9e850b3707 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c | |||
@@ -976,8 +976,7 @@ static void __init sun5i_ccu_init(struct device_node *node, | |||
976 | 976 | ||
977 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 977 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
978 | if (IS_ERR(reg)) { | 978 | if (IS_ERR(reg)) { |
979 | pr_err("%s: Could not map the clock registers\n", | 979 | pr_err("%pOF: Could not map the clock registers\n", node); |
980 | of_node_full_name(node)); | ||
981 | return; | 980 | return; |
982 | } | 981 | } |
983 | 982 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 4d6078fca9ac..8af434815fba 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c | |||
@@ -1217,8 +1217,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node) | |||
1217 | 1217 | ||
1218 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 1218 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
1219 | if (IS_ERR(reg)) { | 1219 | if (IS_ERR(reg)) { |
1220 | pr_err("%s: Could not map the clock registers\n", | 1220 | pr_err("%pOF: Could not map the clock registers\n", node); |
1221 | of_node_full_name(node)); | ||
1222 | return; | 1221 | return; |
1223 | } | 1222 | } |
1224 | 1223 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index 8a753ed0426d..d93b452f0df9 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c | |||
@@ -716,8 +716,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node) | |||
716 | 716 | ||
717 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 717 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
718 | if (IS_ERR(reg)) { | 718 | if (IS_ERR(reg)) { |
719 | pr_err("%s: Could not map the clock registers\n", | 719 | pr_err("%pOF: Could not map the clock registers\n", node); |
720 | of_node_full_name(node)); | ||
721 | return; | 720 | return; |
722 | } | 721 | } |
723 | 722 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 10b38dc46f75..13eb5b23c5e7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c | |||
@@ -777,8 +777,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node) | |||
777 | 777 | ||
778 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 778 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
779 | if (IS_ERR(reg)) { | 779 | if (IS_ERR(reg)) { |
780 | pr_err("%s: Could not map the clock registers\n", | 780 | pr_err("%pOF: Could not map the clock registers\n", node); |
781 | of_node_full_name(node)); | ||
782 | return; | 781 | return; |
783 | } | 782 | } |
784 | 783 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 62e4f0d2b2fc..1729ff6a5aae 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c | |||
@@ -135,7 +135,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", | |||
135 | static const char * const cpux_parents[] = { "osc32k", "osc24M", | 135 | static const char * const cpux_parents[] = { "osc32k", "osc24M", |
136 | "pll-cpux" , "pll-cpux" }; | 136 | "pll-cpux" , "pll-cpux" }; |
137 | static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, | 137 | static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, |
138 | 0x050, 16, 2, CLK_IS_CRITICAL); | 138 | 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT); |
139 | 139 | ||
140 | static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); | 140 | static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); |
141 | 141 | ||
@@ -1103,6 +1103,13 @@ static const struct sunxi_ccu_desc sun50i_h5_ccu_desc = { | |||
1103 | .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets), | 1103 | .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets), |
1104 | }; | 1104 | }; |
1105 | 1105 | ||
1106 | static struct ccu_pll_nb sun8i_h3_pll_cpu_nb = { | ||
1107 | .common = &pll_cpux_clk.common, | ||
1108 | /* copy from pll_cpux_clk */ | ||
1109 | .enable = BIT(31), | ||
1110 | .lock = BIT(28), | ||
1111 | }; | ||
1112 | |||
1106 | static struct ccu_mux_nb sun8i_h3_cpu_nb = { | 1113 | static struct ccu_mux_nb sun8i_h3_cpu_nb = { |
1107 | .common = &cpux_clk.common, | 1114 | .common = &cpux_clk.common, |
1108 | .cm = &cpux_clk.mux, | 1115 | .cm = &cpux_clk.mux, |
@@ -1118,8 +1125,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, | |||
1118 | 1125 | ||
1119 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 1126 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
1120 | if (IS_ERR(reg)) { | 1127 | if (IS_ERR(reg)) { |
1121 | pr_err("%s: Could not map the clock registers\n", | 1128 | pr_err("%pOF: Could not map the clock registers\n", node); |
1122 | of_node_full_name(node)); | ||
1123 | return; | 1129 | return; |
1124 | } | 1130 | } |
1125 | 1131 | ||
@@ -1130,6 +1136,10 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, | |||
1130 | 1136 | ||
1131 | sunxi_ccu_probe(node, reg, desc); | 1137 | sunxi_ccu_probe(node, reg, desc); |
1132 | 1138 | ||
1139 | /* Gate then ungate PLL CPU after any rate changes */ | ||
1140 | ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb); | ||
1141 | |||
1142 | /* Reparent CPU during PLL CPU rate changes */ | ||
1133 | ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, | 1143 | ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, |
1134 | &sun8i_h3_cpu_nb); | 1144 | &sun8i_h3_cpu_nb); |
1135 | } | 1145 | } |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index e54816ec1dbe..71feb7b24e8a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c | |||
@@ -290,8 +290,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, | |||
290 | 290 | ||
291 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 291 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
292 | if (IS_ERR(reg)) { | 292 | if (IS_ERR(reg)) { |
293 | pr_err("%s: Could not map the clock registers\n", | 293 | pr_err("%pOF: Could not map the clock registers\n", node); |
294 | of_node_full_name(node)); | ||
295 | return; | 294 | return; |
296 | } | 295 | } |
297 | 296 | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h index a7a407f12b56..fb01bffb929d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef _CCU_SUN8I_R_H | 15 | #ifndef _CCU_SUN8I_R_H |
16 | #define _CCU_SUN8I_R_H_ | 16 | #define _CCU_SUN8I_R_H |
17 | 17 | ||
18 | #include <dt-bindings/clock/sun8i-r-ccu.h> | 18 | #include <dt-bindings/clock/sun8i-r-ccu.h> |
19 | #include <dt-bindings/reset/sun8i-r-ccu.h> | 19 | #include <dt-bindings/reset/sun8i-r-ccu.h> |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c new file mode 100644 index 000000000000..933f2e68f42a --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c | |||
@@ -0,0 +1,1290 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io> | ||
3 | * | ||
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 | ||
6 | * may be copied, distributed, and modified under those terms. | ||
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/clk-provider.h> | ||
15 | #include <linux/of_address.h> | ||
16 | |||
17 | #include "ccu_common.h" | ||
18 | #include "ccu_reset.h" | ||
19 | |||
20 | #include "ccu_div.h" | ||
21 | #include "ccu_gate.h" | ||
22 | #include "ccu_mp.h" | ||
23 | #include "ccu_mult.h" | ||
24 | #include "ccu_nk.h" | ||
25 | #include "ccu_nkm.h" | ||
26 | #include "ccu_nkmp.h" | ||
27 | #include "ccu_nm.h" | ||
28 | #include "ccu_phase.h" | ||
29 | |||
30 | #include "ccu-sun8i-r40.h" | ||
31 | |||
32 | /* TODO: The result of N*K is required to be in [10, 88] range. */ | ||
33 | static struct ccu_nkmp pll_cpu_clk = { | ||
34 | .enable = BIT(31), | ||
35 | .lock = BIT(28), | ||
36 | .n = _SUNXI_CCU_MULT(8, 5), | ||
37 | .k = _SUNXI_CCU_MULT(4, 2), | ||
38 | .m = _SUNXI_CCU_DIV(0, 2), | ||
39 | .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), | ||
40 | .common = { | ||
41 | .reg = 0x000, | ||
42 | .hw.init = CLK_HW_INIT("pll-cpu", | ||
43 | "osc24M", | ||
44 | &ccu_nkmp_ops, | ||
45 | CLK_SET_RATE_UNGATE), | ||
46 | }, | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from | ||
51 | * the base (2x, 4x and 8x), and one variable divider (the one true | ||
52 | * pll audio). | ||
53 | * | ||
54 | * We don't have any need for the variable divider for now, so we just | ||
55 | * hardcode it to match with the clock names | ||
56 | */ | ||
57 | #define SUN8I_R40_PLL_AUDIO_REG 0x008 | ||
58 | |||
59 | static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | ||
60 | "osc24M", 0x008, | ||
61 | 8, 7, /* N */ | ||
62 | 0, 5, /* M */ | ||
63 | BIT(31), /* gate */ | ||
64 | BIT(28), /* lock */ | ||
65 | CLK_SET_RATE_UNGATE); | ||
66 | |||
67 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
68 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", | ||
69 | "osc24M", 0x0010, | ||
70 | 8, 7, /* N */ | ||
71 | 0, 4, /* M */ | ||
72 | BIT(24), /* frac enable */ | ||
73 | BIT(25), /* frac select */ | ||
74 | 270000000, /* frac rate 0 */ | ||
75 | 297000000, /* frac rate 1 */ | ||
76 | BIT(31), /* gate */ | ||
77 | BIT(28), /* lock */ | ||
78 | CLK_SET_RATE_UNGATE); | ||
79 | |||
80 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
81 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | ||
82 | "osc24M", 0x0018, | ||
83 | 8, 7, /* N */ | ||
84 | 0, 4, /* M */ | ||
85 | BIT(24), /* frac enable */ | ||
86 | BIT(25), /* frac select */ | ||
87 | 270000000, /* frac rate 0 */ | ||
88 | 297000000, /* frac rate 1 */ | ||
89 | BIT(31), /* gate */ | ||
90 | BIT(28), /* lock */ | ||
91 | CLK_SET_RATE_UNGATE); | ||
92 | |||
93 | /* TODO: The result of N*K is required to be in [10, 77] range. */ | ||
94 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0", | ||
95 | "osc24M", 0x020, | ||
96 | 8, 5, /* N */ | ||
97 | 4, 2, /* K */ | ||
98 | 0, 2, /* M */ | ||
99 | BIT(31), /* gate */ | ||
100 | BIT(28), /* lock */ | ||
101 | CLK_SET_RATE_UNGATE); | ||
102 | |||
103 | /* TODO: The result of N*K is required to be in [21, 58] range. */ | ||
104 | static struct ccu_nk pll_periph0_clk = { | ||
105 | .enable = BIT(31), | ||
106 | .lock = BIT(28), | ||
107 | .n = _SUNXI_CCU_MULT(8, 5), | ||
108 | .k = _SUNXI_CCU_MULT(4, 2), | ||
109 | .fixed_post_div = 2, | ||
110 | .common = { | ||
111 | .reg = 0x028, | ||
112 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
113 | .hw.init = CLK_HW_INIT("pll-periph0", "osc24M", | ||
114 | &ccu_nk_ops, | ||
115 | CLK_SET_RATE_UNGATE), | ||
116 | }, | ||
117 | }; | ||
118 | |||
119 | static struct ccu_div pll_periph0_sata_clk = { | ||
120 | .enable = BIT(24), | ||
121 | .div = _SUNXI_CCU_DIV(0, 2), | ||
122 | /* | ||
123 | * The formula of pll-periph0 (1x) is 24MHz*N*K/2, and the formula | ||
124 | * of pll-periph0-sata is 24MHz*N*K/M/6, so the postdiv here is | ||
125 | * 6/2 = 3. | ||
126 | */ | ||
127 | .fixed_post_div = 3, | ||
128 | .common = { | ||
129 | .reg = 0x028, | ||
130 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
131 | .hw.init = CLK_HW_INIT("pll-periph0-sata", | ||
132 | "pll-periph0", | ||
133 | &ccu_div_ops, 0), | ||
134 | }, | ||
135 | }; | ||
136 | |||
137 | /* TODO: The result of N*K is required to be in [21, 58] range. */ | ||
138 | static struct ccu_nk pll_periph1_clk = { | ||
139 | .enable = BIT(31), | ||
140 | .lock = BIT(28), | ||
141 | .n = _SUNXI_CCU_MULT(8, 5), | ||
142 | .k = _SUNXI_CCU_MULT(4, 2), | ||
143 | .fixed_post_div = 2, | ||
144 | .common = { | ||
145 | .reg = 0x02c, | ||
146 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
147 | .hw.init = CLK_HW_INIT("pll-periph1", "osc24M", | ||
148 | &ccu_nk_ops, | ||
149 | CLK_SET_RATE_UNGATE), | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
154 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", | ||
155 | "osc24M", 0x030, | ||
156 | 8, 7, /* N */ | ||
157 | 0, 4, /* M */ | ||
158 | BIT(24), /* frac enable */ | ||
159 | BIT(25), /* frac select */ | ||
160 | 270000000, /* frac rate 0 */ | ||
161 | 297000000, /* frac rate 1 */ | ||
162 | BIT(31), /* gate */ | ||
163 | BIT(28), /* lock */ | ||
164 | CLK_SET_RATE_UNGATE); | ||
165 | |||
166 | static struct ccu_nkm pll_sata_clk = { | ||
167 | .enable = BIT(31), | ||
168 | .lock = BIT(28), | ||
169 | .n = _SUNXI_CCU_MULT(8, 5), | ||
170 | .k = _SUNXI_CCU_MULT(4, 2), | ||
171 | .m = _SUNXI_CCU_DIV(0, 2), | ||
172 | .fixed_post_div = 6, | ||
173 | .common = { | ||
174 | .reg = 0x034, | ||
175 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
176 | .hw.init = CLK_HW_INIT("pll-sata", "osc24M", | ||
177 | &ccu_nkm_ops, | ||
178 | CLK_SET_RATE_UNGATE), | ||
179 | }, | ||
180 | }; | ||
181 | |||
182 | static const char * const pll_sata_out_parents[] = { "pll-sata", | ||
183 | "pll-periph0-sata" }; | ||
184 | static SUNXI_CCU_MUX_WITH_GATE(pll_sata_out_clk, "pll-sata-out", | ||
185 | pll_sata_out_parents, 0x034, | ||
186 | 30, 1, /* mux */ | ||
187 | BIT(14), /* gate */ | ||
188 | CLK_SET_RATE_PARENT); | ||
189 | |||
190 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
191 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", | ||
192 | "osc24M", 0x038, | ||
193 | 8, 7, /* N */ | ||
194 | 0, 4, /* M */ | ||
195 | BIT(24), /* frac enable */ | ||
196 | BIT(25), /* frac select */ | ||
197 | 270000000, /* frac rate 0 */ | ||
198 | 297000000, /* frac rate 1 */ | ||
199 | BIT(31), /* gate */ | ||
200 | BIT(28), /* lock */ | ||
201 | CLK_SET_RATE_UNGATE); | ||
202 | |||
203 | /* | ||
204 | * The MIPI PLL has 2 modes: "MIPI" and "HDMI". | ||
205 | * | ||
206 | * The MIPI mode is a standard NKM-style clock. The HDMI mode is an | ||
207 | * integer / fractional clock with switchable multipliers and dividers. | ||
208 | * This is not supported here. We hardcode the PLL to MIPI mode. | ||
209 | * | ||
210 | * TODO: In the MIPI mode, M/N is required to be equal or lesser than 3, | ||
211 | * which cannot be implemented now. | ||
212 | */ | ||
213 | #define SUN8I_R40_PLL_MIPI_REG 0x040 | ||
214 | |||
215 | static const char * const pll_mipi_parents[] = { "pll-video0" }; | ||
216 | static struct ccu_nkm pll_mipi_clk = { | ||
217 | .enable = BIT(31) | BIT(23) | BIT(22), | ||
218 | .lock = BIT(28), | ||
219 | .n = _SUNXI_CCU_MULT(8, 4), | ||
220 | .k = _SUNXI_CCU_MULT_MIN(4, 2, 2), | ||
221 | .m = _SUNXI_CCU_DIV(0, 4), | ||
222 | .mux = _SUNXI_CCU_MUX(21, 1), | ||
223 | .common = { | ||
224 | .reg = 0x040, | ||
225 | .hw.init = CLK_HW_INIT_PARENTS("pll-mipi", | ||
226 | pll_mipi_parents, | ||
227 | &ccu_nkm_ops, | ||
228 | CLK_SET_RATE_UNGATE) | ||
229 | }, | ||
230 | }; | ||
231 | |||
232 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
233 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", | ||
234 | "osc24M", 0x048, | ||
235 | 8, 7, /* N */ | ||
236 | 0, 4, /* M */ | ||
237 | BIT(24), /* frac enable */ | ||
238 | BIT(25), /* frac select */ | ||
239 | 270000000, /* frac rate 0 */ | ||
240 | 297000000, /* frac rate 1 */ | ||
241 | BIT(31), /* gate */ | ||
242 | BIT(28), /* lock */ | ||
243 | CLK_SET_RATE_UNGATE); | ||
244 | |||
245 | /* TODO: The N factor is required to be in [16, 75] range. */ | ||
246 | static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1", | ||
247 | "osc24M", 0x04c, | ||
248 | 8, 7, /* N */ | ||
249 | 0, 2, /* M */ | ||
250 | BIT(31), /* gate */ | ||
251 | BIT(28), /* lock */ | ||
252 | CLK_SET_RATE_UNGATE); | ||
253 | |||
254 | static const char * const cpu_parents[] = { "osc32k", "osc24M", | ||
255 | "pll-cpu", "pll-cpu" }; | ||
256 | static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents, | ||
257 | 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT); | ||
258 | |||
259 | static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0); | ||
260 | |||
261 | static const char * const ahb1_parents[] = { "osc32k", "osc24M", | ||
262 | "axi", "pll-periph0" }; | ||
263 | static const struct ccu_mux_var_prediv ahb1_predivs[] = { | ||
264 | { .index = 3, .shift = 6, .width = 2 }, | ||
265 | }; | ||
266 | static struct ccu_div ahb1_clk = { | ||
267 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
268 | |||
269 | .mux = { | ||
270 | .shift = 12, | ||
271 | .width = 2, | ||
272 | |||
273 | .var_predivs = ahb1_predivs, | ||
274 | .n_var_predivs = ARRAY_SIZE(ahb1_predivs), | ||
275 | }, | ||
276 | |||
277 | .common = { | ||
278 | .reg = 0x054, | ||
279 | .features = CCU_FEATURE_VARIABLE_PREDIV, | ||
280 | .hw.init = CLK_HW_INIT_PARENTS("ahb1", | ||
281 | ahb1_parents, | ||
282 | &ccu_div_ops, | ||
283 | 0), | ||
284 | }, | ||
285 | }; | ||
286 | |||
287 | static struct clk_div_table apb1_div_table[] = { | ||
288 | { .val = 0, .div = 2 }, | ||
289 | { .val = 1, .div = 2 }, | ||
290 | { .val = 2, .div = 4 }, | ||
291 | { .val = 3, .div = 8 }, | ||
292 | { /* Sentinel */ }, | ||
293 | }; | ||
294 | static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", | ||
295 | 0x054, 8, 2, apb1_div_table, 0); | ||
296 | |||
297 | static const char * const apb2_parents[] = { "osc32k", "osc24M", | ||
298 | "pll-periph0-2x", | ||
299 | "pll-periph0-2x" }; | ||
300 | static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, | ||
301 | 0, 5, /* M */ | ||
302 | 16, 2, /* P */ | ||
303 | 24, 2, /* mux */ | ||
304 | 0); | ||
305 | |||
306 | static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", | ||
307 | 0x060, BIT(1), 0); | ||
308 | static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb1", | ||
309 | 0x060, BIT(5), 0); | ||
310 | static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", | ||
311 | 0x060, BIT(6), 0); | ||
312 | static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", | ||
313 | 0x060, BIT(8), 0); | ||
314 | static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", | ||
315 | 0x060, BIT(9), 0); | ||
316 | static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", | ||
317 | 0x060, BIT(10), 0); | ||
318 | static SUNXI_CCU_GATE(bus_mmc3_clk, "bus-mmc3", "ahb1", | ||
319 | 0x060, BIT(11), 0); | ||
320 | static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", | ||
321 | 0x060, BIT(13), 0); | ||
322 | static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", | ||
323 | 0x060, BIT(14), 0); | ||
324 | static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb1", | ||
325 | 0x060, BIT(17), 0); | ||
326 | static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb1", | ||
327 | 0x060, BIT(18), 0); | ||
328 | static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", | ||
329 | 0x060, BIT(19), 0); | ||
330 | static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", | ||
331 | 0x060, BIT(20), 0); | ||
332 | static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", | ||
333 | 0x060, BIT(21), 0); | ||
334 | static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb1", | ||
335 | 0x060, BIT(22), 0); | ||
336 | static SUNXI_CCU_GATE(bus_spi3_clk, "bus-spi3", "ahb1", | ||
337 | 0x060, BIT(23), 0); | ||
338 | static SUNXI_CCU_GATE(bus_sata_clk, "bus-sata", "ahb1", | ||
339 | 0x060, BIT(24), 0); | ||
340 | static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", | ||
341 | 0x060, BIT(25), 0); | ||
342 | static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1", | ||
343 | 0x060, BIT(26), 0); | ||
344 | static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb1", | ||
345 | 0x060, BIT(27), 0); | ||
346 | static SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb1", | ||
347 | 0x060, BIT(28), 0); | ||
348 | static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1", | ||
349 | 0x060, BIT(29), 0); | ||
350 | static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb1", | ||
351 | 0x060, BIT(30), 0); | ||
352 | static SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "ahb1", | ||
353 | 0x060, BIT(31), 0); | ||
354 | |||
355 | static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", | ||
356 | 0x064, BIT(0), 0); | ||
357 | static SUNXI_CCU_GATE(bus_mp_clk, "bus-mp", "ahb1", | ||
358 | 0x064, BIT(2), 0); | ||
359 | static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "ahb1", | ||
360 | 0x064, BIT(5), 0); | ||
361 | static SUNXI_CCU_GATE(bus_csi0_clk, "bus-csi0", "ahb1", | ||
362 | 0x064, BIT(8), 0); | ||
363 | static SUNXI_CCU_GATE(bus_csi1_clk, "bus-csi1", "ahb1", | ||
364 | 0x064, BIT(9), 0); | ||
365 | static SUNXI_CCU_GATE(bus_hdmi0_clk, "bus-hdmi0", "ahb1", | ||
366 | 0x064, BIT(10), 0); | ||
367 | static SUNXI_CCU_GATE(bus_hdmi1_clk, "bus-hdmi1", "ahb1", | ||
368 | 0x064, BIT(11), 0); | ||
369 | static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1", | ||
370 | 0x064, BIT(12), 0); | ||
371 | static SUNXI_CCU_GATE(bus_tve0_clk, "bus-tve0", "ahb1", | ||
372 | 0x064, BIT(13), 0); | ||
373 | static SUNXI_CCU_GATE(bus_tve1_clk, "bus-tve1", "ahb1", | ||
374 | 0x064, BIT(14), 0); | ||
375 | static SUNXI_CCU_GATE(bus_tve_top_clk, "bus-tve-top", "ahb1", | ||
376 | 0x064, BIT(15), 0); | ||
377 | static SUNXI_CCU_GATE(bus_gmac_clk, "bus-gmac", "ahb1", | ||
378 | 0x064, BIT(17), 0); | ||
379 | static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", | ||
380 | 0x064, BIT(20), 0); | ||
381 | static SUNXI_CCU_GATE(bus_tvd0_clk, "bus-tvd0", "ahb1", | ||
382 | 0x064, BIT(21), 0); | ||
383 | static SUNXI_CCU_GATE(bus_tvd1_clk, "bus-tvd1", "ahb1", | ||
384 | 0x064, BIT(22), 0); | ||
385 | static SUNXI_CCU_GATE(bus_tvd2_clk, "bus-tvd2", "ahb1", | ||
386 | 0x064, BIT(23), 0); | ||
387 | static SUNXI_CCU_GATE(bus_tvd3_clk, "bus-tvd3", "ahb1", | ||
388 | 0x064, BIT(24), 0); | ||
389 | static SUNXI_CCU_GATE(bus_tvd_top_clk, "bus-tvd-top", "ahb1", | ||
390 | 0x064, BIT(25), 0); | ||
391 | static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb1", | ||
392 | 0x064, BIT(26), 0); | ||
393 | static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb1", | ||
394 | 0x064, BIT(27), 0); | ||
395 | static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb1", | ||
396 | 0x064, BIT(28), 0); | ||
397 | static SUNXI_CCU_GATE(bus_tcon_tv1_clk, "bus-tcon-tv1", "ahb1", | ||
398 | 0x064, BIT(29), 0); | ||
399 | static SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top", "ahb1", | ||
400 | 0x064, BIT(30), 0); | ||
401 | |||
402 | static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1", | ||
403 | 0x068, BIT(0), 0); | ||
404 | static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", | ||
405 | 0x068, BIT(1), 0); | ||
406 | static SUNXI_CCU_GATE(bus_ac97_clk, "bus-ac97", "apb1", | ||
407 | 0x068, BIT(2), 0); | ||
408 | static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", | ||
409 | 0x068, BIT(5), 0); | ||
410 | static SUNXI_CCU_GATE(bus_ir0_clk, "bus-ir0", "apb1", | ||
411 | 0x068, BIT(6), 0); | ||
412 | static SUNXI_CCU_GATE(bus_ir1_clk, "bus-ir1", "apb1", | ||
413 | 0x068, BIT(7), 0); | ||
414 | static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", | ||
415 | 0x068, BIT(8), 0); | ||
416 | static SUNXI_CCU_GATE(bus_keypad_clk, "bus-keypad", "apb1", | ||
417 | 0x068, BIT(10), 0); | ||
418 | static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", | ||
419 | 0x068, BIT(12), 0); | ||
420 | static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", | ||
421 | 0x068, BIT(13), 0); | ||
422 | static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", | ||
423 | 0x068, BIT(14), 0); | ||
424 | |||
425 | static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", | ||
426 | 0x06c, BIT(0), 0); | ||
427 | static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", | ||
428 | 0x06c, BIT(1), 0); | ||
429 | static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", | ||
430 | 0x06c, BIT(2), 0); | ||
431 | static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", | ||
432 | 0x06c, BIT(3), 0); | ||
433 | /* | ||
434 | * In datasheet here's "Reserved", however the gate exists in BSP soucre | ||
435 | * code. | ||
436 | */ | ||
437 | static SUNXI_CCU_GATE(bus_can_clk, "bus-can", "apb2", | ||
438 | 0x06c, BIT(4), 0); | ||
439 | static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", | ||
440 | 0x06c, BIT(5), 0); | ||
441 | static SUNXI_CCU_GATE(bus_ps20_clk, "bus-ps20", "apb2", | ||
442 | 0x06c, BIT(6), 0); | ||
443 | static SUNXI_CCU_GATE(bus_ps21_clk, "bus-ps21", "apb2", | ||
444 | 0x06c, BIT(7), 0); | ||
445 | static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb2", | ||
446 | 0x06c, BIT(15), 0); | ||
447 | static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", | ||
448 | 0x06c, BIT(16), 0); | ||
449 | static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", | ||
450 | 0x06c, BIT(17), 0); | ||
451 | static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", | ||
452 | 0x06c, BIT(18), 0); | ||
453 | static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", | ||
454 | 0x06c, BIT(19), 0); | ||
455 | static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", | ||
456 | 0x06c, BIT(20), 0); | ||
457 | static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb2", | ||
458 | 0x06c, BIT(21), 0); | ||
459 | static SUNXI_CCU_GATE(bus_uart6_clk, "bus-uart6", "apb2", | ||
460 | 0x06c, BIT(22), 0); | ||
461 | static SUNXI_CCU_GATE(bus_uart7_clk, "bus-uart7", "apb2", | ||
462 | 0x06c, BIT(23), 0); | ||
463 | |||
464 | static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1", | ||
465 | 0x070, BIT(7), 0); | ||
466 | |||
467 | static const char * const ths_parents[] = { "osc24M" }; | ||
468 | static struct ccu_div ths_clk = { | ||
469 | .enable = BIT(31), | ||
470 | .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
471 | .mux = _SUNXI_CCU_MUX(24, 2), | ||
472 | .common = { | ||
473 | .reg = 0x074, | ||
474 | .hw.init = CLK_HW_INIT_PARENTS("ths", | ||
475 | ths_parents, | ||
476 | &ccu_div_ops, | ||
477 | 0), | ||
478 | }, | ||
479 | }; | ||
480 | |||
481 | static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0", | ||
482 | "pll-periph1" }; | ||
483 | static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, | ||
484 | 0, 4, /* M */ | ||
485 | 16, 2, /* P */ | ||
486 | 24, 2, /* mux */ | ||
487 | BIT(31), /* gate */ | ||
488 | 0); | ||
489 | |||
490 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, | ||
491 | 0, 4, /* M */ | ||
492 | 16, 2, /* P */ | ||
493 | 24, 2, /* mux */ | ||
494 | BIT(31), /* gate */ | ||
495 | 0); | ||
496 | |||
497 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, | ||
498 | 0, 4, /* M */ | ||
499 | 16, 2, /* P */ | ||
500 | 24, 2, /* mux */ | ||
501 | BIT(31), /* gate */ | ||
502 | 0); | ||
503 | |||
504 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, | ||
505 | 0, 4, /* M */ | ||
506 | 16, 2, /* P */ | ||
507 | 24, 2, /* mux */ | ||
508 | BIT(31), /* gate */ | ||
509 | 0); | ||
510 | |||
511 | static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094, | ||
512 | 0, 4, /* M */ | ||
513 | 16, 2, /* P */ | ||
514 | 24, 2, /* mux */ | ||
515 | BIT(31), /* gate */ | ||
516 | 0); | ||
517 | |||
518 | static const char * const ts_parents[] = { "osc24M", "pll-periph0", }; | ||
519 | static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x098, | ||
520 | 0, 4, /* M */ | ||
521 | 16, 2, /* P */ | ||
522 | 24, 4, /* mux */ | ||
523 | BIT(31), /* gate */ | ||
524 | 0); | ||
525 | |||
526 | static const char * const ce_parents[] = { "osc24M", "pll-periph0-2x", | ||
527 | "pll-periph1-2x" }; | ||
528 | static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c, | ||
529 | 0, 4, /* M */ | ||
530 | 16, 2, /* P */ | ||
531 | 24, 2, /* mux */ | ||
532 | BIT(31), /* gate */ | ||
533 | 0); | ||
534 | |||
535 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, | ||
536 | 0, 4, /* M */ | ||
537 | 16, 2, /* P */ | ||
538 | 24, 2, /* mux */ | ||
539 | BIT(31), /* gate */ | ||
540 | 0); | ||
541 | |||
542 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, | ||
543 | 0, 4, /* M */ | ||
544 | 16, 2, /* P */ | ||
545 | 24, 2, /* mux */ | ||
546 | BIT(31), /* gate */ | ||
547 | 0); | ||
548 | |||
549 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8, | ||
550 | 0, 4, /* M */ | ||
551 | 16, 2, /* P */ | ||
552 | 24, 2, /* mux */ | ||
553 | BIT(31), /* gate */ | ||
554 | 0); | ||
555 | |||
556 | static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac, | ||
557 | 0, 4, /* M */ | ||
558 | 16, 2, /* P */ | ||
559 | 24, 2, /* mux */ | ||
560 | BIT(31), /* gate */ | ||
561 | 0); | ||
562 | |||
563 | static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x", | ||
564 | "pll-audio-2x", "pll-audio" }; | ||
565 | static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents, | ||
566 | 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
567 | |||
568 | static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents, | ||
569 | 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
570 | |||
571 | static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", i2s_parents, | ||
572 | 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
573 | |||
574 | static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", i2s_parents, | ||
575 | 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
576 | |||
577 | static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_parents, | ||
578 | 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); | ||
579 | |||
580 | static const char * const keypad_parents[] = { "osc24M", "osc32k" }; | ||
581 | static const u8 keypad_table[] = { 0, 2 }; | ||
582 | static struct ccu_mp keypad_clk = { | ||
583 | .enable = BIT(31), | ||
584 | .m = _SUNXI_CCU_DIV(0, 5), | ||
585 | .p = _SUNXI_CCU_DIV(16, 2), | ||
586 | .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table), | ||
587 | .common = { | ||
588 | .reg = 0x0c4, | ||
589 | .hw.init = CLK_HW_INIT_PARENTS("keypad", | ||
590 | keypad_parents, | ||
591 | &ccu_mp_ops, | ||
592 | 0), | ||
593 | } | ||
594 | }; | ||
595 | |||
596 | static const char * const sata_parents[] = { "pll-sata-out", "sata-ext" }; | ||
597 | static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents, | ||
598 | 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT); | ||
599 | |||
600 | /* | ||
601 | * There are 3 OHCI 12M clock source selection bits in this register. | ||
602 | * We will force them to 0 (12M divided from 48M). | ||
603 | */ | ||
604 | #define SUN8I_R40_USB_CLK_REG 0x0cc | ||
605 | |||
606 | static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", | ||
607 | 0x0cc, BIT(8), 0); | ||
608 | static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", | ||
609 | 0x0cc, BIT(9), 0); | ||
610 | static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M", | ||
611 | 0x0cc, BIT(10), 0); | ||
612 | static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", | ||
613 | 0x0cc, BIT(16), 0); | ||
614 | static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", | ||
615 | 0x0cc, BIT(17), 0); | ||
616 | static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc12M", | ||
617 | 0x0cc, BIT(18), 0); | ||
618 | |||
619 | static const char * const ir_parents[] = { "osc24M", "pll-periph0", | ||
620 | "pll-periph1", "osc32k" }; | ||
621 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_clk, "ir0", ir_parents, 0x0d0, | ||
622 | 0, 4, /* M */ | ||
623 | 16, 2, /* P */ | ||
624 | 24, 2, /* mux */ | ||
625 | BIT(31), /* gate */ | ||
626 | 0); | ||
627 | |||
628 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_clk, "ir1", ir_parents, 0x0d4, | ||
629 | 0, 4, /* M */ | ||
630 | 16, 2, /* P */ | ||
631 | 24, 2, /* mux */ | ||
632 | BIT(31), /* gate */ | ||
633 | 0); | ||
634 | |||
635 | static const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1" }; | ||
636 | static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents, | ||
637 | 0x0f4, 0, 2, 20, 2, CLK_IS_CRITICAL); | ||
638 | |||
639 | static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", | ||
640 | 0x100, BIT(0), 0); | ||
641 | static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "dram", | ||
642 | 0x100, BIT(1), 0); | ||
643 | static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "dram", | ||
644 | 0x100, BIT(2), 0); | ||
645 | static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram", | ||
646 | 0x100, BIT(3), 0); | ||
647 | static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "dram", | ||
648 | 0x100, BIT(4), 0); | ||
649 | static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "dram", | ||
650 | 0x100, BIT(5), 0); | ||
651 | static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram", | ||
652 | 0x100, BIT(6), 0); | ||
653 | |||
654 | static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; | ||
655 | static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, | ||
656 | 0x104, 0, 4, 24, 3, BIT(31), 0); | ||
657 | static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents, | ||
658 | 0x108, 0, 4, 24, 3, BIT(31), 0); | ||
659 | |||
660 | static const char * const tcon_parents[] = { "pll-video0", "pll-video1", | ||
661 | "pll-video0-2x", "pll-video1-2x", | ||
662 | "pll-mipi" }; | ||
663 | static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents, | ||
664 | 0x110, 24, 3, BIT(31), CLK_SET_RATE_PARENT); | ||
665 | static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents, | ||
666 | 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT); | ||
667 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents, | ||
668 | 0x118, 0, 4, 24, 3, BIT(31), 0); | ||
669 | static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents, | ||
670 | 0x11c, 0, 4, 24, 3, BIT(31), 0); | ||
671 | |||
672 | static const char * const deinterlace_parents[] = { "pll-periph0", | ||
673 | "pll-periph1" }; | ||
674 | static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", | ||
675 | deinterlace_parents, 0x124, 0, 4, 24, 3, | ||
676 | BIT(31), 0); | ||
677 | |||
678 | static const char * const csi_mclk_parents[] = { "osc24M", "pll-video1", | ||
679 | "pll-periph1" }; | ||
680 | static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk", csi_mclk_parents, | ||
681 | 0x130, 0, 5, 8, 3, BIT(15), 0); | ||
682 | |||
683 | static const char * const csi_sclk_parents[] = { "pll-periph0", "pll-periph1" }; | ||
684 | static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents, | ||
685 | 0x134, 16, 4, 24, 3, BIT(31), 0); | ||
686 | |||
687 | static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents, | ||
688 | 0x134, 0, 5, 8, 3, BIT(15), 0); | ||
689 | |||
690 | static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", | ||
691 | 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); | ||
692 | |||
693 | static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", | ||
694 | 0x140, BIT(31), CLK_SET_RATE_PARENT); | ||
695 | static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", | ||
696 | 0x144, BIT(31), 0); | ||
697 | |||
698 | static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; | ||
699 | static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, | ||
700 | 0x150, 0, 4, 24, 2, BIT(31), 0); | ||
701 | |||
702 | static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", | ||
703 | 0x154, BIT(31), 0); | ||
704 | |||
705 | /* | ||
706 | * In the SoC's user manual, the P factor is mentioned, but not used in | ||
707 | * the frequency formula. | ||
708 | * | ||
709 | * Here the factor is included, according to the BSP kernel source, | ||
710 | * which contains the P factor of this clock. | ||
711 | */ | ||
712 | static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x", | ||
713 | "pll-ddr0" }; | ||
714 | static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x15c, | ||
715 | 0, 4, /* M */ | ||
716 | 16, 2, /* P */ | ||
717 | 24, 2, /* mux */ | ||
718 | BIT(31), /* gate */ | ||
719 | CLK_IS_CRITICAL); | ||
720 | |||
721 | static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-video1", | ||
722 | "pll-periph0" }; | ||
723 | static SUNXI_CCU_M_WITH_MUX_GATE(dsi_dphy_clk, "dsi-dphy", dsi_dphy_parents, | ||
724 | 0x168, 0, 4, 8, 2, BIT(15), 0); | ||
725 | |||
726 | static SUNXI_CCU_M_WITH_MUX_GATE(tve0_clk, "tve0", tcon_parents, | ||
727 | 0x180, 0, 4, 24, 3, BIT(31), 0); | ||
728 | static SUNXI_CCU_M_WITH_MUX_GATE(tve1_clk, "tve1", tcon_parents, | ||
729 | 0x184, 0, 4, 24, 3, BIT(31), 0); | ||
730 | |||
731 | static const char * const tvd_parents[] = { "pll-video0", "pll-video1", | ||
732 | "pll-video0-2x", "pll-video1-2x" }; | ||
733 | static SUNXI_CCU_M_WITH_MUX_GATE(tvd0_clk, "tvd0", tvd_parents, | ||
734 | 0x188, 0, 4, 24, 3, BIT(31), 0); | ||
735 | static SUNXI_CCU_M_WITH_MUX_GATE(tvd1_clk, "tvd1", tvd_parents, | ||
736 | 0x18c, 0, 4, 24, 3, BIT(31), 0); | ||
737 | static SUNXI_CCU_M_WITH_MUX_GATE(tvd2_clk, "tvd2", tvd_parents, | ||
738 | 0x190, 0, 4, 24, 3, BIT(31), 0); | ||
739 | static SUNXI_CCU_M_WITH_MUX_GATE(tvd3_clk, "tvd3", tvd_parents, | ||
740 | 0x194, 0, 4, 24, 3, BIT(31), 0); | ||
741 | |||
742 | static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", | ||
743 | 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT); | ||
744 | |||
745 | static const char * const out_parents[] = { "osc24M", "osc32k", "osc24M" }; | ||
746 | static const struct ccu_mux_fixed_prediv out_predivs[] = { | ||
747 | { .index = 0, .div = 750, }, | ||
748 | }; | ||
749 | |||
750 | static struct ccu_mp outa_clk = { | ||
751 | .enable = BIT(31), | ||
752 | .m = _SUNXI_CCU_DIV(8, 5), | ||
753 | .p = _SUNXI_CCU_DIV(20, 2), | ||
754 | .mux = { | ||
755 | .shift = 24, | ||
756 | .width = 2, | ||
757 | .fixed_predivs = out_predivs, | ||
758 | .n_predivs = ARRAY_SIZE(out_predivs), | ||
759 | }, | ||
760 | .common = { | ||
761 | .reg = 0x1f0, | ||
762 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
763 | .hw.init = CLK_HW_INIT_PARENTS("outa", out_parents, | ||
764 | &ccu_mp_ops, 0), | ||
765 | } | ||
766 | }; | ||
767 | |||
768 | static struct ccu_mp outb_clk = { | ||
769 | .enable = BIT(31), | ||
770 | .m = _SUNXI_CCU_DIV(8, 5), | ||
771 | .p = _SUNXI_CCU_DIV(20, 2), | ||
772 | .mux = { | ||
773 | .shift = 24, | ||
774 | .width = 2, | ||
775 | .fixed_predivs = out_predivs, | ||
776 | .n_predivs = ARRAY_SIZE(out_predivs), | ||
777 | }, | ||
778 | .common = { | ||
779 | .reg = 0x1f4, | ||
780 | .features = CCU_FEATURE_FIXED_PREDIV, | ||
781 | .hw.init = CLK_HW_INIT_PARENTS("outb", out_parents, | ||
782 | &ccu_mp_ops, 0), | ||
783 | } | ||
784 | }; | ||
785 | |||
786 | static struct ccu_common *sun8i_r40_ccu_clks[] = { | ||
787 | &pll_cpu_clk.common, | ||
788 | &pll_audio_base_clk.common, | ||
789 | &pll_video0_clk.common, | ||
790 | &pll_ve_clk.common, | ||
791 | &pll_ddr0_clk.common, | ||
792 | &pll_periph0_clk.common, | ||
793 | &pll_periph0_sata_clk.common, | ||
794 | &pll_periph1_clk.common, | ||
795 | &pll_video1_clk.common, | ||
796 | &pll_sata_clk.common, | ||
797 | &pll_sata_out_clk.common, | ||
798 | &pll_gpu_clk.common, | ||
799 | &pll_mipi_clk.common, | ||
800 | &pll_de_clk.common, | ||
801 | &pll_ddr1_clk.common, | ||
802 | &cpu_clk.common, | ||
803 | &axi_clk.common, | ||
804 | &ahb1_clk.common, | ||
805 | &apb1_clk.common, | ||
806 | &apb2_clk.common, | ||
807 | &bus_mipi_dsi_clk.common, | ||
808 | &bus_ce_clk.common, | ||
809 | &bus_dma_clk.common, | ||
810 | &bus_mmc0_clk.common, | ||
811 | &bus_mmc1_clk.common, | ||
812 | &bus_mmc2_clk.common, | ||
813 | &bus_mmc3_clk.common, | ||
814 | &bus_nand_clk.common, | ||
815 | &bus_dram_clk.common, | ||
816 | &bus_emac_clk.common, | ||
817 | &bus_ts_clk.common, | ||
818 | &bus_hstimer_clk.common, | ||
819 | &bus_spi0_clk.common, | ||
820 | &bus_spi1_clk.common, | ||
821 | &bus_spi2_clk.common, | ||
822 | &bus_spi3_clk.common, | ||
823 | &bus_sata_clk.common, | ||
824 | &bus_otg_clk.common, | ||
825 | &bus_ehci0_clk.common, | ||
826 | &bus_ehci1_clk.common, | ||
827 | &bus_ehci2_clk.common, | ||
828 | &bus_ohci0_clk.common, | ||
829 | &bus_ohci1_clk.common, | ||
830 | &bus_ohci2_clk.common, | ||
831 | &bus_ve_clk.common, | ||
832 | &bus_mp_clk.common, | ||
833 | &bus_deinterlace_clk.common, | ||
834 | &bus_csi0_clk.common, | ||
835 | &bus_csi1_clk.common, | ||
836 | &bus_hdmi0_clk.common, | ||
837 | &bus_hdmi1_clk.common, | ||
838 | &bus_de_clk.common, | ||
839 | &bus_tve0_clk.common, | ||
840 | &bus_tve1_clk.common, | ||
841 | &bus_tve_top_clk.common, | ||
842 | &bus_gmac_clk.common, | ||
843 | &bus_gpu_clk.common, | ||
844 | &bus_tvd0_clk.common, | ||
845 | &bus_tvd1_clk.common, | ||
846 | &bus_tvd2_clk.common, | ||
847 | &bus_tvd3_clk.common, | ||
848 | &bus_tvd_top_clk.common, | ||
849 | &bus_tcon_lcd0_clk.common, | ||
850 | &bus_tcon_lcd1_clk.common, | ||
851 | &bus_tcon_tv0_clk.common, | ||
852 | &bus_tcon_tv1_clk.common, | ||
853 | &bus_tcon_top_clk.common, | ||
854 | &bus_codec_clk.common, | ||
855 | &bus_spdif_clk.common, | ||
856 | &bus_ac97_clk.common, | ||
857 | &bus_pio_clk.common, | ||
858 | &bus_ir0_clk.common, | ||
859 | &bus_ir1_clk.common, | ||
860 | &bus_ths_clk.common, | ||
861 | &bus_keypad_clk.common, | ||
862 | &bus_i2s0_clk.common, | ||
863 | &bus_i2s1_clk.common, | ||
864 | &bus_i2s2_clk.common, | ||
865 | &bus_i2c0_clk.common, | ||
866 | &bus_i2c1_clk.common, | ||
867 | &bus_i2c2_clk.common, | ||
868 | &bus_i2c3_clk.common, | ||
869 | &bus_can_clk.common, | ||
870 | &bus_scr_clk.common, | ||
871 | &bus_ps20_clk.common, | ||
872 | &bus_ps21_clk.common, | ||
873 | &bus_i2c4_clk.common, | ||
874 | &bus_uart0_clk.common, | ||
875 | &bus_uart1_clk.common, | ||
876 | &bus_uart2_clk.common, | ||
877 | &bus_uart3_clk.common, | ||
878 | &bus_uart4_clk.common, | ||
879 | &bus_uart5_clk.common, | ||
880 | &bus_uart6_clk.common, | ||
881 | &bus_uart7_clk.common, | ||
882 | &bus_dbg_clk.common, | ||
883 | &ths_clk.common, | ||
884 | &nand_clk.common, | ||
885 | &mmc0_clk.common, | ||
886 | &mmc1_clk.common, | ||
887 | &mmc2_clk.common, | ||
888 | &mmc3_clk.common, | ||
889 | &ts_clk.common, | ||
890 | &ce_clk.common, | ||
891 | &spi0_clk.common, | ||
892 | &spi1_clk.common, | ||
893 | &spi2_clk.common, | ||
894 | &spi3_clk.common, | ||
895 | &i2s0_clk.common, | ||
896 | &i2s1_clk.common, | ||
897 | &i2s2_clk.common, | ||
898 | &ac97_clk.common, | ||
899 | &spdif_clk.common, | ||
900 | &keypad_clk.common, | ||
901 | &sata_clk.common, | ||
902 | &usb_phy0_clk.common, | ||
903 | &usb_phy1_clk.common, | ||
904 | &usb_phy2_clk.common, | ||
905 | &usb_ohci0_clk.common, | ||
906 | &usb_ohci1_clk.common, | ||
907 | &usb_ohci2_clk.common, | ||
908 | &ir0_clk.common, | ||
909 | &ir1_clk.common, | ||
910 | &dram_clk.common, | ||
911 | &dram_ve_clk.common, | ||
912 | &dram_csi0_clk.common, | ||
913 | &dram_csi1_clk.common, | ||
914 | &dram_ts_clk.common, | ||
915 | &dram_tvd_clk.common, | ||
916 | &dram_mp_clk.common, | ||
917 | &dram_deinterlace_clk.common, | ||
918 | &de_clk.common, | ||
919 | &mp_clk.common, | ||
920 | &tcon_lcd0_clk.common, | ||
921 | &tcon_lcd1_clk.common, | ||
922 | &tcon_tv0_clk.common, | ||
923 | &tcon_tv1_clk.common, | ||
924 | &deinterlace_clk.common, | ||
925 | &csi1_mclk_clk.common, | ||
926 | &csi_sclk_clk.common, | ||
927 | &csi0_mclk_clk.common, | ||
928 | &ve_clk.common, | ||
929 | &codec_clk.common, | ||
930 | &avs_clk.common, | ||
931 | &hdmi_clk.common, | ||
932 | &hdmi_slow_clk.common, | ||
933 | &mbus_clk.common, | ||
934 | &dsi_dphy_clk.common, | ||
935 | &tve0_clk.common, | ||
936 | &tve1_clk.common, | ||
937 | &tvd0_clk.common, | ||
938 | &tvd1_clk.common, | ||
939 | &tvd2_clk.common, | ||
940 | &tvd3_clk.common, | ||
941 | &gpu_clk.common, | ||
942 | &outa_clk.common, | ||
943 | &outb_clk.common, | ||
944 | }; | ||
945 | |||
946 | /* Fixed Factor clocks */ | ||
947 | static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); | ||
948 | |||
949 | /* We hardcode the divider to 4 for now */ | ||
950 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | ||
951 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | ||
952 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | ||
953 | "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); | ||
954 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | ||
955 | "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); | ||
956 | static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", | ||
957 | "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); | ||
958 | static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", | ||
959 | "pll-periph0", 1, 2, 0); | ||
960 | static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", | ||
961 | "pll-periph1", 1, 2, 0); | ||
962 | static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", | ||
963 | "pll-video0", 1, 2, 0); | ||
964 | static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", | ||
965 | "pll-video1", 1, 2, 0); | ||
966 | |||
967 | static struct clk_hw_onecell_data sun8i_r40_hw_clks = { | ||
968 | .hws = { | ||
969 | [CLK_OSC_12M] = &osc12M_clk.hw, | ||
970 | [CLK_PLL_CPU] = &pll_cpu_clk.common.hw, | ||
971 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
972 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
973 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
974 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
975 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
976 | [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, | ||
977 | [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, | ||
978 | [CLK_PLL_VE] = &pll_ve_clk.common.hw, | ||
979 | [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, | ||
980 | [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw, | ||
981 | [CLK_PLL_PERIPH0_SATA] = &pll_periph0_sata_clk.common.hw, | ||
982 | [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw, | ||
983 | [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw, | ||
984 | [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw, | ||
985 | [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, | ||
986 | [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, | ||
987 | [CLK_PLL_SATA] = &pll_sata_clk.common.hw, | ||
988 | [CLK_PLL_SATA_OUT] = &pll_sata_out_clk.common.hw, | ||
989 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, | ||
990 | [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, | ||
991 | [CLK_PLL_DE] = &pll_de_clk.common.hw, | ||
992 | [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw, | ||
993 | [CLK_CPU] = &cpu_clk.common.hw, | ||
994 | [CLK_AXI] = &axi_clk.common.hw, | ||
995 | [CLK_AHB1] = &ahb1_clk.common.hw, | ||
996 | [CLK_APB1] = &apb1_clk.common.hw, | ||
997 | [CLK_APB2] = &apb2_clk.common.hw, | ||
998 | [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, | ||
999 | [CLK_BUS_CE] = &bus_ce_clk.common.hw, | ||
1000 | [CLK_BUS_DMA] = &bus_dma_clk.common.hw, | ||
1001 | [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, | ||
1002 | [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, | ||
1003 | [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, | ||
1004 | [CLK_BUS_MMC3] = &bus_mmc3_clk.common.hw, | ||
1005 | [CLK_BUS_NAND] = &bus_nand_clk.common.hw, | ||
1006 | [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, | ||
1007 | [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, | ||
1008 | [CLK_BUS_TS] = &bus_ts_clk.common.hw, | ||
1009 | [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, | ||
1010 | [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, | ||
1011 | [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, | ||
1012 | [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw, | ||
1013 | [CLK_BUS_SPI3] = &bus_spi3_clk.common.hw, | ||
1014 | [CLK_BUS_SATA] = &bus_sata_clk.common.hw, | ||
1015 | [CLK_BUS_OTG] = &bus_otg_clk.common.hw, | ||
1016 | [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, | ||
1017 | [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw, | ||
1018 | [CLK_BUS_EHCI2] = &bus_ehci2_clk.common.hw, | ||
1019 | [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, | ||
1020 | [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw, | ||
1021 | [CLK_BUS_OHCI2] = &bus_ohci2_clk.common.hw, | ||
1022 | [CLK_BUS_VE] = &bus_ve_clk.common.hw, | ||
1023 | [CLK_BUS_MP] = &bus_mp_clk.common.hw, | ||
1024 | [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw, | ||
1025 | [CLK_BUS_CSI0] = &bus_csi0_clk.common.hw, | ||
1026 | [CLK_BUS_CSI1] = &bus_csi1_clk.common.hw, | ||
1027 | [CLK_BUS_HDMI0] = &bus_hdmi0_clk.common.hw, | ||
1028 | [CLK_BUS_HDMI1] = &bus_hdmi1_clk.common.hw, | ||
1029 | [CLK_BUS_DE] = &bus_de_clk.common.hw, | ||
1030 | [CLK_BUS_TVE0] = &bus_tve0_clk.common.hw, | ||
1031 | [CLK_BUS_TVE1] = &bus_tve1_clk.common.hw, | ||
1032 | [CLK_BUS_TVE_TOP] = &bus_tve_top_clk.common.hw, | ||
1033 | [CLK_BUS_GMAC] = &bus_gmac_clk.common.hw, | ||
1034 | [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, | ||
1035 | [CLK_BUS_TVD0] = &bus_tvd0_clk.common.hw, | ||
1036 | [CLK_BUS_TVD1] = &bus_tvd1_clk.common.hw, | ||
1037 | [CLK_BUS_TVD2] = &bus_tvd2_clk.common.hw, | ||
1038 | [CLK_BUS_TVD3] = &bus_tvd3_clk.common.hw, | ||
1039 | [CLK_BUS_TVD_TOP] = &bus_tvd_top_clk.common.hw, | ||
1040 | [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, | ||
1041 | [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw, | ||
1042 | [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, | ||
1043 | [CLK_BUS_TCON_TV1] = &bus_tcon_tv1_clk.common.hw, | ||
1044 | [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, | ||
1045 | [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, | ||
1046 | [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, | ||
1047 | [CLK_BUS_AC97] = &bus_ac97_clk.common.hw, | ||
1048 | [CLK_BUS_PIO] = &bus_pio_clk.common.hw, | ||
1049 | [CLK_BUS_IR0] = &bus_ir0_clk.common.hw, | ||
1050 | [CLK_BUS_IR1] = &bus_ir1_clk.common.hw, | ||
1051 | [CLK_BUS_THS] = &bus_ths_clk.common.hw, | ||
1052 | [CLK_BUS_KEYPAD] = &bus_keypad_clk.common.hw, | ||
1053 | [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, | ||
1054 | [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, | ||
1055 | [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, | ||
1056 | [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, | ||
1057 | [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, | ||
1058 | [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, | ||
1059 | [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw, | ||
1060 | [CLK_BUS_CAN] = &bus_can_clk.common.hw, | ||
1061 | [CLK_BUS_SCR] = &bus_scr_clk.common.hw, | ||
1062 | [CLK_BUS_PS20] = &bus_ps20_clk.common.hw, | ||
1063 | [CLK_BUS_PS21] = &bus_ps21_clk.common.hw, | ||
1064 | [CLK_BUS_I2C4] = &bus_i2c4_clk.common.hw, | ||
1065 | [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, | ||
1066 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, | ||
1067 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, | ||
1068 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, | ||
1069 | [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, | ||
1070 | [CLK_BUS_UART5] = &bus_uart5_clk.common.hw, | ||
1071 | [CLK_BUS_UART6] = &bus_uart6_clk.common.hw, | ||
1072 | [CLK_BUS_UART7] = &bus_uart7_clk.common.hw, | ||
1073 | [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, | ||
1074 | [CLK_THS] = &ths_clk.common.hw, | ||
1075 | [CLK_NAND] = &nand_clk.common.hw, | ||
1076 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
1077 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
1078 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
1079 | [CLK_MMC3] = &mmc3_clk.common.hw, | ||
1080 | [CLK_TS] = &ts_clk.common.hw, | ||
1081 | [CLK_CE] = &ce_clk.common.hw, | ||
1082 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
1083 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
1084 | [CLK_SPI2] = &spi2_clk.common.hw, | ||
1085 | [CLK_SPI3] = &spi3_clk.common.hw, | ||
1086 | [CLK_I2S0] = &i2s0_clk.common.hw, | ||
1087 | [CLK_I2S1] = &i2s1_clk.common.hw, | ||
1088 | [CLK_I2S2] = &i2s2_clk.common.hw, | ||
1089 | [CLK_AC97] = &ac97_clk.common.hw, | ||
1090 | [CLK_SPDIF] = &spdif_clk.common.hw, | ||
1091 | [CLK_KEYPAD] = &keypad_clk.common.hw, | ||
1092 | [CLK_SATA] = &sata_clk.common.hw, | ||
1093 | [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, | ||
1094 | [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, | ||
1095 | [CLK_USB_PHY2] = &usb_phy2_clk.common.hw, | ||
1096 | [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, | ||
1097 | [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, | ||
1098 | [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, | ||
1099 | [CLK_IR0] = &ir0_clk.common.hw, | ||
1100 | [CLK_IR1] = &ir1_clk.common.hw, | ||
1101 | [CLK_DRAM] = &dram_clk.common.hw, | ||
1102 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
1103 | [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw, | ||
1104 | [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw, | ||
1105 | [CLK_DRAM_TS] = &dram_ts_clk.common.hw, | ||
1106 | [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw, | ||
1107 | [CLK_DRAM_MP] = &dram_mp_clk.common.hw, | ||
1108 | [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw, | ||
1109 | [CLK_DE] = &de_clk.common.hw, | ||
1110 | [CLK_MP] = &mp_clk.common.hw, | ||
1111 | [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, | ||
1112 | [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw, | ||
1113 | [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, | ||
1114 | [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, | ||
1115 | [CLK_DEINTERLACE] = &deinterlace_clk.common.hw, | ||
1116 | [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw, | ||
1117 | [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, | ||
1118 | [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw, | ||
1119 | [CLK_VE] = &ve_clk.common.hw, | ||
1120 | [CLK_CODEC] = &codec_clk.common.hw, | ||
1121 | [CLK_AVS] = &avs_clk.common.hw, | ||
1122 | [CLK_HDMI] = &hdmi_clk.common.hw, | ||
1123 | [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw, | ||
1124 | [CLK_MBUS] = &mbus_clk.common.hw, | ||
1125 | [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw, | ||
1126 | [CLK_TVE0] = &tve0_clk.common.hw, | ||
1127 | [CLK_TVE1] = &tve1_clk.common.hw, | ||
1128 | [CLK_TVD0] = &tvd0_clk.common.hw, | ||
1129 | [CLK_TVD1] = &tvd1_clk.common.hw, | ||
1130 | [CLK_TVD2] = &tvd2_clk.common.hw, | ||
1131 | [CLK_TVD3] = &tvd3_clk.common.hw, | ||
1132 | [CLK_GPU] = &gpu_clk.common.hw, | ||
1133 | [CLK_OUTA] = &outa_clk.common.hw, | ||
1134 | [CLK_OUTB] = &outb_clk.common.hw, | ||
1135 | }, | ||
1136 | .num = CLK_NUMBER, | ||
1137 | }; | ||
1138 | |||
1139 | static struct ccu_reset_map sun8i_r40_ccu_resets[] = { | ||
1140 | [RST_USB_PHY0] = { 0x0cc, BIT(0) }, | ||
1141 | [RST_USB_PHY1] = { 0x0cc, BIT(1) }, | ||
1142 | [RST_USB_PHY2] = { 0x0cc, BIT(2) }, | ||
1143 | |||
1144 | [RST_DRAM] = { 0x0f4, BIT(31) }, | ||
1145 | [RST_MBUS] = { 0x0fc, BIT(31) }, | ||
1146 | |||
1147 | [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, | ||
1148 | [RST_BUS_CE] = { 0x2c0, BIT(5) }, | ||
1149 | [RST_BUS_DMA] = { 0x2c0, BIT(6) }, | ||
1150 | [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, | ||
1151 | [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, | ||
1152 | [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, | ||
1153 | [RST_BUS_MMC3] = { 0x2c0, BIT(11) }, | ||
1154 | [RST_BUS_NAND] = { 0x2c0, BIT(13) }, | ||
1155 | [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, | ||
1156 | [RST_BUS_EMAC] = { 0x2c0, BIT(17) }, | ||
1157 | [RST_BUS_TS] = { 0x2c0, BIT(18) }, | ||
1158 | [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, | ||
1159 | [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, | ||
1160 | [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, | ||
1161 | [RST_BUS_SPI2] = { 0x2c0, BIT(22) }, | ||
1162 | [RST_BUS_SPI3] = { 0x2c0, BIT(23) }, | ||
1163 | [RST_BUS_SATA] = { 0x2c0, BIT(24) }, | ||
1164 | [RST_BUS_OTG] = { 0x2c0, BIT(25) }, | ||
1165 | [RST_BUS_EHCI0] = { 0x2c0, BIT(26) }, | ||
1166 | [RST_BUS_EHCI1] = { 0x2c0, BIT(27) }, | ||
1167 | [RST_BUS_EHCI2] = { 0x2c0, BIT(28) }, | ||
1168 | [RST_BUS_OHCI0] = { 0x2c0, BIT(29) }, | ||
1169 | [RST_BUS_OHCI1] = { 0x2c0, BIT(30) }, | ||
1170 | [RST_BUS_OHCI2] = { 0x2c0, BIT(31) }, | ||
1171 | |||
1172 | [RST_BUS_VE] = { 0x2c4, BIT(0) }, | ||
1173 | [RST_BUS_MP] = { 0x2c4, BIT(2) }, | ||
1174 | [RST_BUS_DEINTERLACE] = { 0x2c4, BIT(5) }, | ||
1175 | [RST_BUS_CSI0] = { 0x2c4, BIT(8) }, | ||
1176 | [RST_BUS_CSI1] = { 0x2c4, BIT(9) }, | ||
1177 | [RST_BUS_HDMI0] = { 0x2c4, BIT(10) }, | ||
1178 | [RST_BUS_HDMI1] = { 0x2c4, BIT(11) }, | ||
1179 | [RST_BUS_DE] = { 0x2c4, BIT(12) }, | ||
1180 | [RST_BUS_TVE0] = { 0x2c4, BIT(13) }, | ||
1181 | [RST_BUS_TVE1] = { 0x2c4, BIT(14) }, | ||
1182 | [RST_BUS_TVE_TOP] = { 0x2c4, BIT(15) }, | ||
1183 | [RST_BUS_GMAC] = { 0x2c4, BIT(17) }, | ||
1184 | [RST_BUS_GPU] = { 0x2c4, BIT(20) }, | ||
1185 | [RST_BUS_TVD0] = { 0x2c4, BIT(21) }, | ||
1186 | [RST_BUS_TVD1] = { 0x2c4, BIT(22) }, | ||
1187 | [RST_BUS_TVD2] = { 0x2c4, BIT(23) }, | ||
1188 | [RST_BUS_TVD3] = { 0x2c4, BIT(24) }, | ||
1189 | [RST_BUS_TVD_TOP] = { 0x2c4, BIT(25) }, | ||
1190 | [RST_BUS_TCON_LCD0] = { 0x2c4, BIT(26) }, | ||
1191 | [RST_BUS_TCON_LCD1] = { 0x2c4, BIT(27) }, | ||
1192 | [RST_BUS_TCON_TV0] = { 0x2c4, BIT(28) }, | ||
1193 | [RST_BUS_TCON_TV1] = { 0x2c4, BIT(29) }, | ||
1194 | [RST_BUS_TCON_TOP] = { 0x2c4, BIT(30) }, | ||
1195 | [RST_BUS_DBG] = { 0x2c4, BIT(31) }, | ||
1196 | |||
1197 | [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, | ||
1198 | |||
1199 | [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, | ||
1200 | [RST_BUS_SPDIF] = { 0x2d0, BIT(1) }, | ||
1201 | [RST_BUS_AC97] = { 0x2d0, BIT(2) }, | ||
1202 | [RST_BUS_IR0] = { 0x2d0, BIT(6) }, | ||
1203 | [RST_BUS_IR1] = { 0x2d0, BIT(7) }, | ||
1204 | [RST_BUS_THS] = { 0x2d0, BIT(8) }, | ||
1205 | [RST_BUS_KEYPAD] = { 0x2d0, BIT(10) }, | ||
1206 | [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, | ||
1207 | [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, | ||
1208 | [RST_BUS_I2S2] = { 0x2d0, BIT(14) }, | ||
1209 | |||
1210 | [RST_BUS_I2C0] = { 0x2d8, BIT(0) }, | ||
1211 | [RST_BUS_I2C1] = { 0x2d8, BIT(1) }, | ||
1212 | [RST_BUS_I2C2] = { 0x2d8, BIT(2) }, | ||
1213 | [RST_BUS_I2C3] = { 0x2d8, BIT(3) }, | ||
1214 | [RST_BUS_CAN] = { 0x2d8, BIT(4) }, | ||
1215 | [RST_BUS_SCR] = { 0x2d8, BIT(5) }, | ||
1216 | [RST_BUS_PS20] = { 0x2d8, BIT(6) }, | ||
1217 | [RST_BUS_PS21] = { 0x2d8, BIT(7) }, | ||
1218 | [RST_BUS_I2C4] = { 0x2d8, BIT(15) }, | ||
1219 | [RST_BUS_UART0] = { 0x2d8, BIT(16) }, | ||
1220 | [RST_BUS_UART1] = { 0x2d8, BIT(17) }, | ||
1221 | [RST_BUS_UART2] = { 0x2d8, BIT(18) }, | ||
1222 | [RST_BUS_UART3] = { 0x2d8, BIT(19) }, | ||
1223 | [RST_BUS_UART4] = { 0x2d8, BIT(20) }, | ||
1224 | [RST_BUS_UART5] = { 0x2d8, BIT(21) }, | ||
1225 | [RST_BUS_UART6] = { 0x2d8, BIT(22) }, | ||
1226 | [RST_BUS_UART7] = { 0x2d8, BIT(23) }, | ||
1227 | }; | ||
1228 | |||
1229 | static const struct sunxi_ccu_desc sun8i_r40_ccu_desc = { | ||
1230 | .ccu_clks = sun8i_r40_ccu_clks, | ||
1231 | .num_ccu_clks = ARRAY_SIZE(sun8i_r40_ccu_clks), | ||
1232 | |||
1233 | .hw_clks = &sun8i_r40_hw_clks, | ||
1234 | |||
1235 | .resets = sun8i_r40_ccu_resets, | ||
1236 | .num_resets = ARRAY_SIZE(sun8i_r40_ccu_resets), | ||
1237 | }; | ||
1238 | |||
1239 | static struct ccu_pll_nb sun8i_r40_pll_cpu_nb = { | ||
1240 | .common = &pll_cpu_clk.common, | ||
1241 | /* copy from pll_cpu_clk */ | ||
1242 | .enable = BIT(31), | ||
1243 | .lock = BIT(28), | ||
1244 | }; | ||
1245 | |||
1246 | static struct ccu_mux_nb sun8i_r40_cpu_nb = { | ||
1247 | .common = &cpu_clk.common, | ||
1248 | .cm = &cpu_clk.mux, | ||
1249 | .delay_us = 1, /* > 8 clock cycles at 24 MHz */ | ||
1250 | .bypass_index = 1, /* index of 24 MHz oscillator */ | ||
1251 | }; | ||
1252 | |||
1253 | static void __init sun8i_r40_ccu_setup(struct device_node *node) | ||
1254 | { | ||
1255 | void __iomem *reg; | ||
1256 | u32 val; | ||
1257 | |||
1258 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
1259 | if (IS_ERR(reg)) { | ||
1260 | pr_err("%s: Could not map the clock registers\n", | ||
1261 | of_node_full_name(node)); | ||
1262 | return; | ||
1263 | } | ||
1264 | |||
1265 | /* Force the PLL-Audio-1x divider to 4 */ | ||
1266 | val = readl(reg + SUN8I_R40_PLL_AUDIO_REG); | ||
1267 | val &= ~GENMASK(19, 16); | ||
1268 | writel(val | (3 << 16), reg + SUN8I_R40_PLL_AUDIO_REG); | ||
1269 | |||
1270 | /* Force PLL-MIPI to MIPI mode */ | ||
1271 | val = readl(reg + SUN8I_R40_PLL_MIPI_REG); | ||
1272 | val &= ~BIT(16); | ||
1273 | writel(val, reg + SUN8I_R40_PLL_MIPI_REG); | ||
1274 | |||
1275 | /* Force OHCI 12M parent to 12M divided from 48M */ | ||
1276 | val = readl(reg + SUN8I_R40_USB_CLK_REG); | ||
1277 | val &= ~GENMASK(25, 20); | ||
1278 | writel(val, reg + SUN8I_R40_USB_CLK_REG); | ||
1279 | |||
1280 | sunxi_ccu_probe(node, reg, &sun8i_r40_ccu_desc); | ||
1281 | |||
1282 | /* Gate then ungate PLL CPU after any rate changes */ | ||
1283 | ccu_pll_notifier_register(&sun8i_r40_pll_cpu_nb); | ||
1284 | |||
1285 | /* Reparent CPU during PLL CPU rate changes */ | ||
1286 | ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, | ||
1287 | &sun8i_r40_cpu_nb); | ||
1288 | } | ||
1289 | CLK_OF_DECLARE(sun8i_r40_ccu, "allwinner,sun8i-r40-ccu", | ||
1290 | sun8i_r40_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h new file mode 100644 index 000000000000..0db8e1e97af8 --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright 2017 Icenowy Zheng <icenowy@aosc.io> | ||
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 | * 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 | #ifndef _CCU_SUN8I_R40_H_ | ||
16 | #define _CCU_SUN8I_R40_H_ | ||
17 | |||
18 | #include <dt-bindings/clock/sun8i-r40-ccu.h> | ||
19 | #include <dt-bindings/reset/sun8i-r40-ccu.h> | ||
20 | |||
21 | #define CLK_OSC_12M 0 | ||
22 | #define CLK_PLL_CPU 1 | ||
23 | #define CLK_PLL_AUDIO_BASE 2 | ||
24 | #define CLK_PLL_AUDIO 3 | ||
25 | #define CLK_PLL_AUDIO_2X 4 | ||
26 | #define CLK_PLL_AUDIO_4X 5 | ||
27 | #define CLK_PLL_AUDIO_8X 6 | ||
28 | #define CLK_PLL_VIDEO0 7 | ||
29 | #define CLK_PLL_VIDEO0_2X 8 | ||
30 | #define CLK_PLL_VE 9 | ||
31 | #define CLK_PLL_DDR0 10 | ||
32 | #define CLK_PLL_PERIPH0 11 | ||
33 | #define CLK_PLL_PERIPH0_SATA 12 | ||
34 | #define CLK_PLL_PERIPH0_2X 13 | ||
35 | #define CLK_PLL_PERIPH1 14 | ||
36 | #define CLK_PLL_PERIPH1_2X 15 | ||
37 | #define CLK_PLL_VIDEO1 16 | ||
38 | #define CLK_PLL_VIDEO1_2X 17 | ||
39 | #define CLK_PLL_SATA 18 | ||
40 | #define CLK_PLL_SATA_OUT 19 | ||
41 | #define CLK_PLL_GPU 20 | ||
42 | #define CLK_PLL_MIPI 21 | ||
43 | #define CLK_PLL_DE 22 | ||
44 | #define CLK_PLL_DDR1 23 | ||
45 | |||
46 | /* The CPU clock is exported */ | ||
47 | |||
48 | #define CLK_AXI 25 | ||
49 | #define CLK_AHB1 26 | ||
50 | #define CLK_APB1 27 | ||
51 | #define CLK_APB2 28 | ||
52 | |||
53 | /* All the bus gates are exported */ | ||
54 | |||
55 | /* The first bunch of module clocks are exported */ | ||
56 | |||
57 | #define CLK_DRAM 132 | ||
58 | |||
59 | /* All the DRAM gates are exported */ | ||
60 | |||
61 | /* Some more module clocks are exported */ | ||
62 | |||
63 | #define CLK_MBUS 155 | ||
64 | |||
65 | /* Another bunch of module clocks are exported */ | ||
66 | |||
67 | #define CLK_NUMBER (CLK_OUTB + 1) | ||
68 | |||
69 | #endif /* _CCU_SUN8I_R40_H_ */ | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index a34a78d7fb28..621b1cd996db 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | |||
@@ -575,8 +575,7 @@ static void __init sun8i_v3s_ccu_setup(struct device_node *node) | |||
575 | 575 | ||
576 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | 576 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); |
577 | if (IS_ERR(reg)) { | 577 | if (IS_ERR(reg)) { |
578 | pr_err("%s: Could not map the clock registers\n", | 578 | pr_err("%pOF: Could not map the clock registers\n", node); |
579 | of_node_full_name(node)); | ||
580 | return; | 579 | return; |
581 | } | 580 | } |
582 | 581 | ||
diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index c0e5c10d0091..baa3cf96507b 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c | |||
@@ -21,10 +21,18 @@ static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux, | |||
21 | { | 21 | { |
22 | struct ccu_div *cd = data; | 22 | struct ccu_div *cd = data; |
23 | 23 | ||
24 | return divider_round_rate_parent(&cd->common.hw, parent, | 24 | if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) |
25 | rate *= cd->fixed_post_div; | ||
26 | |||
27 | rate = divider_round_rate_parent(&cd->common.hw, parent, | ||
25 | rate, parent_rate, | 28 | rate, parent_rate, |
26 | cd->div.table, cd->div.width, | 29 | cd->div.table, cd->div.width, |
27 | cd->div.flags); | 30 | cd->div.flags); |
31 | |||
32 | if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
33 | rate /= cd->fixed_post_div; | ||
34 | |||
35 | return rate; | ||
28 | } | 36 | } |
29 | 37 | ||
30 | static void ccu_div_disable(struct clk_hw *hw) | 38 | static void ccu_div_disable(struct clk_hw *hw) |
@@ -62,8 +70,13 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw, | |||
62 | parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, | 70 | parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, |
63 | parent_rate); | 71 | parent_rate); |
64 | 72 | ||
65 | return divider_recalc_rate(hw, parent_rate, val, cd->div.table, | 73 | val = divider_recalc_rate(hw, parent_rate, val, cd->div.table, |
66 | cd->div.flags); | 74 | cd->div.flags); |
75 | |||
76 | if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
77 | val /= cd->fixed_post_div; | ||
78 | |||
79 | return val; | ||
67 | } | 80 | } |
68 | 81 | ||
69 | static int ccu_div_determine_rate(struct clk_hw *hw, | 82 | static int ccu_div_determine_rate(struct clk_hw *hw, |
@@ -86,6 +99,9 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, | |||
86 | parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, | 99 | parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, |
87 | parent_rate); | 100 | parent_rate); |
88 | 101 | ||
102 | if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
103 | rate *= cd->fixed_post_div; | ||
104 | |||
89 | val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width, | 105 | val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width, |
90 | cd->div.flags); | 106 | cd->div.flags); |
91 | 107 | ||
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h index 08d074451204..f3a5028dcd14 100644 --- a/drivers/clk/sunxi-ng/ccu_div.h +++ b/drivers/clk/sunxi-ng/ccu_div.h | |||
@@ -86,9 +86,10 @@ struct ccu_div_internal { | |||
86 | struct ccu_div { | 86 | struct ccu_div { |
87 | u32 enable; | 87 | u32 enable; |
88 | 88 | ||
89 | struct ccu_div_internal div; | 89 | struct ccu_div_internal div; |
90 | struct ccu_mux_internal mux; | 90 | struct ccu_mux_internal mux; |
91 | struct ccu_common common; | 91 | struct ccu_common common; |
92 | unsigned int fixed_post_div; | ||
92 | }; | 93 | }; |
93 | 94 | ||
94 | #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \ | 95 | #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \ |
diff --git a/drivers/clk/sunxi-ng/ccu_frac.c b/drivers/clk/sunxi-ng/ccu_frac.c index 8b5eb7756bf7..d1d168d4c4f0 100644 --- a/drivers/clk/sunxi-ng/ccu_frac.c +++ b/drivers/clk/sunxi-ng/ccu_frac.c | |||
@@ -67,25 +67,25 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, | |||
67 | { | 67 | { |
68 | u32 reg; | 68 | u32 reg; |
69 | 69 | ||
70 | printk("%s: Read fractional\n", clk_hw_get_name(&common->hw)); | 70 | pr_debug("%s: Read fractional\n", clk_hw_get_name(&common->hw)); |
71 | 71 | ||
72 | if (!(common->features & CCU_FEATURE_FRACTIONAL)) | 72 | if (!(common->features & CCU_FEATURE_FRACTIONAL)) |
73 | return 0; | 73 | return 0; |
74 | 74 | ||
75 | printk("%s: clock is fractional (rates %lu and %lu)\n", | 75 | pr_debug("%s: clock is fractional (rates %lu and %lu)\n", |
76 | clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]); | 76 | clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]); |
77 | 77 | ||
78 | reg = readl(common->base + common->reg); | 78 | reg = readl(common->base + common->reg); |
79 | 79 | ||
80 | printk("%s: clock reg is 0x%x (select is 0x%x)\n", | 80 | pr_debug("%s: clock reg is 0x%x (select is 0x%x)\n", |
81 | clk_hw_get_name(&common->hw), reg, cf->select); | 81 | clk_hw_get_name(&common->hw), reg, cf->select); |
82 | 82 | ||
83 | return (reg & cf->select) ? cf->rates[1] : cf->rates[0]; | 83 | return (reg & cf->select) ? cf->rates[1] : cf->rates[0]; |
84 | } | 84 | } |
85 | 85 | ||
86 | int ccu_frac_helper_set_rate(struct ccu_common *common, | 86 | int ccu_frac_helper_set_rate(struct ccu_common *common, |
87 | struct ccu_frac_internal *cf, | 87 | struct ccu_frac_internal *cf, |
88 | unsigned long rate) | 88 | unsigned long rate, u32 lock) |
89 | { | 89 | { |
90 | unsigned long flags; | 90 | unsigned long flags; |
91 | u32 reg, sel; | 91 | u32 reg, sel; |
@@ -106,5 +106,7 @@ int ccu_frac_helper_set_rate(struct ccu_common *common, | |||
106 | writel(reg | sel, common->base + common->reg); | 106 | writel(reg | sel, common->base + common->reg); |
107 | spin_unlock_irqrestore(common->lock, flags); | 107 | spin_unlock_irqrestore(common->lock, flags); |
108 | 108 | ||
109 | ccu_helper_wait_for_lock(common, lock); | ||
110 | |||
109 | return 0; | 111 | return 0; |
110 | } | 112 | } |
diff --git a/drivers/clk/sunxi-ng/ccu_frac.h b/drivers/clk/sunxi-ng/ccu_frac.h index 7b1ee380156f..efe2dd6bac01 100644 --- a/drivers/clk/sunxi-ng/ccu_frac.h +++ b/drivers/clk/sunxi-ng/ccu_frac.h | |||
@@ -48,6 +48,6 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common, | |||
48 | 48 | ||
49 | int ccu_frac_helper_set_rate(struct ccu_common *common, | 49 | int ccu_frac_helper_set_rate(struct ccu_common *common, |
50 | struct ccu_frac_internal *cf, | 50 | struct ccu_frac_internal *cf, |
51 | unsigned long rate); | 51 | unsigned long rate, u32 lock); |
52 | 52 | ||
53 | #endif /* _CCU_FRAC_H_ */ | 53 | #endif /* _CCU_FRAC_H_ */ |
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 20d0300867f2..12e0783caee6 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c | |||
@@ -111,10 +111,14 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, | |||
111 | unsigned long flags; | 111 | unsigned long flags; |
112 | u32 reg; | 112 | u32 reg; |
113 | 113 | ||
114 | if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) | 114 | if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) { |
115 | return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate); | 115 | ccu_frac_helper_enable(&cm->common, &cm->frac); |
116 | else | 116 | |
117 | return ccu_frac_helper_set_rate(&cm->common, &cm->frac, | ||
118 | rate, cm->lock); | ||
119 | } else { | ||
117 | ccu_frac_helper_disable(&cm->common, &cm->frac); | 120 | ccu_frac_helper_disable(&cm->common, &cm->frac); |
121 | } | ||
118 | 122 | ||
119 | parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, | 123 | parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, |
120 | parent_rate); | 124 | parent_rate); |
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 44b16dc8fea6..841840e35e61 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c | |||
@@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, | |||
75 | unsigned long parent_rate) | 75 | unsigned long parent_rate) |
76 | { | 76 | { |
77 | struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); | 77 | struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); |
78 | unsigned long n, m, k; | 78 | unsigned long n, m, k, rate; |
79 | u32 reg; | 79 | u32 reg; |
80 | 80 | ||
81 | reg = readl(nkm->common.base + nkm->common.reg); | 81 | reg = readl(nkm->common.base + nkm->common.reg); |
@@ -98,7 +98,12 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, | |||
98 | if (!m) | 98 | if (!m) |
99 | m++; | 99 | m++; |
100 | 100 | ||
101 | return parent_rate * n * k / m; | 101 | rate = parent_rate * n * k / m; |
102 | |||
103 | if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
104 | rate /= nkm->fixed_post_div; | ||
105 | |||
106 | return rate; | ||
102 | } | 107 | } |
103 | 108 | ||
104 | static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, | 109 | static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, |
@@ -117,9 +122,17 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, | |||
117 | _nkm.min_m = 1; | 122 | _nkm.min_m = 1; |
118 | _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; | 123 | _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; |
119 | 124 | ||
125 | if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
126 | rate *= nkm->fixed_post_div; | ||
127 | |||
120 | ccu_nkm_find_best(*parent_rate, rate, &_nkm); | 128 | ccu_nkm_find_best(*parent_rate, rate, &_nkm); |
121 | 129 | ||
122 | return *parent_rate * _nkm.n * _nkm.k / _nkm.m; | 130 | rate = *parent_rate * _nkm.n * _nkm.k / _nkm.m; |
131 | |||
132 | if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
133 | rate /= nkm->fixed_post_div; | ||
134 | |||
135 | return rate; | ||
123 | } | 136 | } |
124 | 137 | ||
125 | static int ccu_nkm_determine_rate(struct clk_hw *hw, | 138 | static int ccu_nkm_determine_rate(struct clk_hw *hw, |
@@ -139,6 +152,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
139 | unsigned long flags; | 152 | unsigned long flags; |
140 | u32 reg; | 153 | u32 reg; |
141 | 154 | ||
155 | if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) | ||
156 | rate *= nkm->fixed_post_div; | ||
157 | |||
142 | _nkm.min_n = nkm->n.min ?: 1; | 158 | _nkm.min_n = nkm->n.min ?: 1; |
143 | _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width; | 159 | _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width; |
144 | _nkm.min_k = nkm->k.min ?: 1; | 160 | _nkm.min_k = nkm->k.min ?: 1; |
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h index 34580894f4d1..cc6efb70a102 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.h +++ b/drivers/clk/sunxi-ng/ccu_nkm.h | |||
@@ -34,6 +34,8 @@ struct ccu_nkm { | |||
34 | struct ccu_div_internal m; | 34 | struct ccu_div_internal m; |
35 | struct ccu_mux_internal mux; | 35 | struct ccu_mux_internal mux; |
36 | 36 | ||
37 | unsigned int fixed_post_div; | ||
38 | |||
37 | struct ccu_common common; | 39 | struct ccu_common common; |
38 | }; | 40 | }; |
39 | 41 | ||
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index 5e5e90a4a50c..a32158e8f2e3 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c | |||
@@ -117,10 +117,23 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate, | |||
117 | unsigned long flags; | 117 | unsigned long flags; |
118 | u32 reg; | 118 | u32 reg; |
119 | 119 | ||
120 | if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) | 120 | if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { |
121 | return ccu_frac_helper_set_rate(&nm->common, &nm->frac, rate); | 121 | spin_lock_irqsave(nm->common.lock, flags); |
122 | else | 122 | |
123 | /* most SoCs require M to be 0 if fractional mode is used */ | ||
124 | reg = readl(nm->common.base + nm->common.reg); | ||
125 | reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift); | ||
126 | writel(reg, nm->common.base + nm->common.reg); | ||
127 | |||
128 | spin_unlock_irqrestore(nm->common.lock, flags); | ||
129 | |||
130 | ccu_frac_helper_enable(&nm->common, &nm->frac); | ||
131 | |||
132 | return ccu_frac_helper_set_rate(&nm->common, &nm->frac, | ||
133 | rate, nm->lock); | ||
134 | } else { | ||
123 | ccu_frac_helper_disable(&nm->common, &nm->frac); | 135 | ccu_frac_helper_disable(&nm->common, &nm->frac); |
136 | } | ||
124 | 137 | ||
125 | _nm.min_n = nm->n.min ?: 1; | 138 | _nm.min_n = nm->n.min ?: 1; |
126 | _nm.max_n = nm->n.max ?: 1 << nm->n.width; | 139 | _nm.max_n = nm->n.max ?: 1 << nm->n.width; |
diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index 63fdb790df29..bee305bdddbe 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c | |||
@@ -78,6 +78,10 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) | |||
78 | clk_parent = APB1; | 78 | clk_parent = APB1; |
79 | else if (index >= 96 && index <= 127) | 79 | else if (index >= 96 && index <= 127) |
80 | clk_parent = APB2; | 80 | clk_parent = APB2; |
81 | else { | ||
82 | WARN_ON(true); | ||
83 | continue; | ||
84 | } | ||
81 | 85 | ||
82 | clk_reg = reg + 4 * (index / 32); | 86 | clk_reg = reg + 4 * (index / 32); |
83 | clk_bit = index % 32; | 87 | clk_bit = index % 32; |
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index f2c9274b8bd5..aa4add580516 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c | |||
@@ -666,15 +666,14 @@ static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, | |||
666 | 666 | ||
667 | reg = of_iomap(node, 0); | 667 | reg = of_iomap(node, 0); |
668 | if (!reg) { | 668 | if (!reg) { |
669 | pr_err("Could not map registers for mux-clk: %s\n", | 669 | pr_err("Could not map registers for mux-clk: %pOF\n", node); |
670 | of_node_full_name(node)); | ||
671 | return NULL; | 670 | return NULL; |
672 | } | 671 | } |
673 | 672 | ||
674 | i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); | 673 | i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); |
675 | if (of_property_read_string(node, "clock-output-names", &clk_name)) { | 674 | if (of_property_read_string(node, "clock-output-names", &clk_name)) { |
676 | pr_err("%s: could not read clock-output-names from \"%s\"\n", | 675 | pr_err("%s: could not read clock-output-names from \"%pOF\"\n", |
677 | __func__, of_node_full_name(node)); | 676 | __func__, node); |
678 | goto out_unmap; | 677 | goto out_unmap; |
679 | } | 678 | } |
680 | 679 | ||
@@ -797,16 +796,15 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, | |||
797 | 796 | ||
798 | reg = of_iomap(node, 0); | 797 | reg = of_iomap(node, 0); |
799 | if (!reg) { | 798 | if (!reg) { |
800 | pr_err("Could not map registers for mux-clk: %s\n", | 799 | pr_err("Could not map registers for mux-clk: %pOF\n", node); |
801 | of_node_full_name(node)); | ||
802 | return; | 800 | return; |
803 | } | 801 | } |
804 | 802 | ||
805 | clk_parent = of_clk_get_parent_name(node, 0); | 803 | clk_parent = of_clk_get_parent_name(node, 0); |
806 | 804 | ||
807 | if (of_property_read_string(node, "clock-output-names", &clk_name)) { | 805 | if (of_property_read_string(node, "clock-output-names", &clk_name)) { |
808 | pr_err("%s: could not read clock-output-names from \"%s\"\n", | 806 | pr_err("%s: could not read clock-output-names from \"%pOF\"\n", |
809 | __func__, of_node_full_name(node)); | 807 | __func__, node); |
810 | goto out_unmap; | 808 | goto out_unmap; |
811 | } | 809 | } |
812 | 810 | ||
@@ -1010,8 +1008,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, | |||
1010 | 1008 | ||
1011 | reg = of_iomap(node, 0); | 1009 | reg = of_iomap(node, 0); |
1012 | if (!reg) { | 1010 | if (!reg) { |
1013 | pr_err("Could not map registers for divs-clk: %s\n", | 1011 | pr_err("Could not map registers for divs-clk: %pOF\n", node); |
1014 | of_node_full_name(node)); | ||
1015 | return NULL; | 1012 | return NULL; |
1016 | } | 1013 | } |
1017 | 1014 | ||
diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c index 74e7544f861b..11a5066e5c27 100644 --- a/drivers/clk/tegra/clk-emc.c +++ b/drivers/clk/tegra/clk-emc.c | |||
@@ -378,7 +378,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, | |||
378 | 378 | ||
379 | err = of_property_read_u32(node, "clock-frequency", &tmp); | 379 | err = of_property_read_u32(node, "clock-frequency", &tmp); |
380 | if (err) { | 380 | if (err) { |
381 | pr_err("timing %s: failed to read rate\n", node->full_name); | 381 | pr_err("timing %pOF: failed to read rate\n", node); |
382 | return err; | 382 | return err; |
383 | } | 383 | } |
384 | 384 | ||
@@ -386,8 +386,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, | |||
386 | 386 | ||
387 | err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp); | 387 | err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp); |
388 | if (err) { | 388 | if (err) { |
389 | pr_err("timing %s: failed to read parent rate\n", | 389 | pr_err("timing %pOF: failed to read parent rate\n", node); |
390 | node->full_name); | ||
391 | return err; | 390 | return err; |
392 | } | 391 | } |
393 | 392 | ||
@@ -395,8 +394,7 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, | |||
395 | 394 | ||
396 | timing->parent = of_clk_get_by_name(node, "emc-parent"); | 395 | timing->parent = of_clk_get_by_name(node, "emc-parent"); |
397 | if (IS_ERR(timing->parent)) { | 396 | if (IS_ERR(timing->parent)) { |
398 | pr_err("timing %s: failed to get parent clock\n", | 397 | pr_err("timing %pOF: failed to get parent clock\n", node); |
399 | node->full_name); | ||
400 | return PTR_ERR(timing->parent); | 398 | return PTR_ERR(timing->parent); |
401 | } | 399 | } |
402 | 400 | ||
@@ -409,8 +407,8 @@ static int load_one_timing_from_dt(struct tegra_clk_emc *tegra, | |||
409 | } | 407 | } |
410 | } | 408 | } |
411 | if (timing->parent_index == 0xff) { | 409 | if (timing->parent_index == 0xff) { |
412 | pr_err("timing %s: %s is not a valid parent\n", | 410 | pr_err("timing %pOF: %s is not a valid parent\n", |
413 | node->full_name, __clk_get_name(timing->parent)); | 411 | node, __clk_get_name(timing->parent)); |
414 | clk_put(timing->parent); | 412 | clk_put(timing->parent); |
415 | return -EINVAL; | 413 | return -EINVAL; |
416 | } | 414 | } |
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 159a854779e6..7c369e21c91c 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c | |||
@@ -363,7 +363,7 @@ static void _clk_pll_enable(struct clk_hw *hw) | |||
363 | val = pll_readl(pll->params->iddq_reg, pll); | 363 | val = pll_readl(pll->params->iddq_reg, pll); |
364 | val &= ~BIT(pll->params->iddq_bit_idx); | 364 | val &= ~BIT(pll->params->iddq_bit_idx); |
365 | pll_writel(val, pll->params->iddq_reg, pll); | 365 | pll_writel(val, pll->params->iddq_reg, pll); |
366 | udelay(2); | 366 | udelay(5); |
367 | } | 367 | } |
368 | 368 | ||
369 | if (pll->params->reset_reg) { | 369 | if (pll->params->reset_reg) { |
@@ -418,6 +418,26 @@ static void _clk_pll_disable(struct clk_hw *hw) | |||
418 | } | 418 | } |
419 | } | 419 | } |
420 | 420 | ||
421 | static void pll_clk_start_ss(struct tegra_clk_pll *pll) | ||
422 | { | ||
423 | if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { | ||
424 | u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); | ||
425 | |||
426 | val |= pll->params->ssc_ctrl_en_mask; | ||
427 | pll_writel(val, pll->params->ssc_ctrl_reg, pll); | ||
428 | } | ||
429 | } | ||
430 | |||
431 | static void pll_clk_stop_ss(struct tegra_clk_pll *pll) | ||
432 | { | ||
433 | if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { | ||
434 | u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); | ||
435 | |||
436 | val &= ~pll->params->ssc_ctrl_en_mask; | ||
437 | pll_writel(val, pll->params->ssc_ctrl_reg, pll); | ||
438 | } | ||
439 | } | ||
440 | |||
421 | static int clk_pll_enable(struct clk_hw *hw) | 441 | static int clk_pll_enable(struct clk_hw *hw) |
422 | { | 442 | { |
423 | struct tegra_clk_pll *pll = to_clk_pll(hw); | 443 | struct tegra_clk_pll *pll = to_clk_pll(hw); |
@@ -431,6 +451,8 @@ static int clk_pll_enable(struct clk_hw *hw) | |||
431 | 451 | ||
432 | ret = clk_pll_wait_for_lock(pll); | 452 | ret = clk_pll_wait_for_lock(pll); |
433 | 453 | ||
454 | pll_clk_start_ss(pll); | ||
455 | |||
434 | if (pll->lock) | 456 | if (pll->lock) |
435 | spin_unlock_irqrestore(pll->lock, flags); | 457 | spin_unlock_irqrestore(pll->lock, flags); |
436 | 458 | ||
@@ -445,6 +467,8 @@ static void clk_pll_disable(struct clk_hw *hw) | |||
445 | if (pll->lock) | 467 | if (pll->lock) |
446 | spin_lock_irqsave(pll->lock, flags); | 468 | spin_lock_irqsave(pll->lock, flags); |
447 | 469 | ||
470 | pll_clk_stop_ss(pll); | ||
471 | |||
448 | _clk_pll_disable(hw); | 472 | _clk_pll_disable(hw); |
449 | 473 | ||
450 | if (pll->lock) | 474 | if (pll->lock) |
@@ -666,6 +690,8 @@ static void _get_pll_mnp(struct tegra_clk_pll *pll, | |||
666 | struct tegra_clk_pll_params *params = pll->params; | 690 | struct tegra_clk_pll_params *params = pll->params; |
667 | struct div_nmp *div_nmp = params->div_nmp; | 691 | struct div_nmp *div_nmp = params->div_nmp; |
668 | 692 | ||
693 | *cfg = (struct tegra_clk_pll_freq_table) { }; | ||
694 | |||
669 | if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && | 695 | if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && |
670 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & | 696 | (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & |
671 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { | 697 | PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { |
@@ -716,26 +742,6 @@ static void _update_pll_cpcon(struct tegra_clk_pll *pll, | |||
716 | pll_writel_misc(val, pll); | 742 | pll_writel_misc(val, pll); |
717 | } | 743 | } |
718 | 744 | ||
719 | static void pll_clk_start_ss(struct tegra_clk_pll *pll) | ||
720 | { | ||
721 | if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { | ||
722 | u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); | ||
723 | |||
724 | val |= pll->params->ssc_ctrl_en_mask; | ||
725 | pll_writel(val, pll->params->ssc_ctrl_reg, pll); | ||
726 | } | ||
727 | } | ||
728 | |||
729 | static void pll_clk_stop_ss(struct tegra_clk_pll *pll) | ||
730 | { | ||
731 | if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { | ||
732 | u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); | ||
733 | |||
734 | val &= ~pll->params->ssc_ctrl_en_mask; | ||
735 | pll_writel(val, pll->params->ssc_ctrl_reg, pll); | ||
736 | } | ||
737 | } | ||
738 | |||
739 | static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, | 745 | static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, |
740 | unsigned long rate) | 746 | unsigned long rate) |
741 | { | 747 | { |
@@ -2251,7 +2257,7 @@ tegra_clk_register_pllu_tegra114(const char *name, const char *parent_name, | |||
2251 | } | 2257 | } |
2252 | #endif | 2258 | #endif |
2253 | 2259 | ||
2254 | #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) | 2260 | #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) || defined(CONFIG_ARCH_TEGRA_210_SOC) |
2255 | static const struct clk_ops tegra_clk_pllss_ops = { | 2261 | static const struct clk_ops tegra_clk_pllss_ops = { |
2256 | .is_enabled = clk_pll_is_enabled, | 2262 | .is_enabled = clk_pll_is_enabled, |
2257 | .enable = clk_pll_enable, | 2263 | .enable = clk_pll_enable, |
@@ -2349,7 +2355,6 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name, | |||
2349 | struct tegra_clk_pll_params *pll_params, | 2355 | struct tegra_clk_pll_params *pll_params, |
2350 | spinlock_t *lock, unsigned long parent_rate) | 2356 | spinlock_t *lock, unsigned long parent_rate) |
2351 | { | 2357 | { |
2352 | u32 val; | ||
2353 | struct tegra_clk_pll *pll; | 2358 | struct tegra_clk_pll *pll; |
2354 | struct clk *clk; | 2359 | struct clk *clk; |
2355 | 2360 | ||
@@ -2363,26 +2368,8 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name, | |||
2363 | if (IS_ERR(pll)) | 2368 | if (IS_ERR(pll)) |
2364 | return ERR_CAST(pll); | 2369 | return ERR_CAST(pll); |
2365 | 2370 | ||
2366 | /* program minimum rate by default */ | ||
2367 | |||
2368 | val = pll_readl_base(pll); | ||
2369 | if (val & PLL_BASE_ENABLE) | ||
2370 | WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) & | ||
2371 | BIT(pll_params->iddq_bit_idx)); | ||
2372 | else { | ||
2373 | val = 0x4 << divm_shift(pll); | ||
2374 | val |= 0x41 << divn_shift(pll); | ||
2375 | pll_writel_base(val, pll); | ||
2376 | } | ||
2377 | |||
2378 | /* disable lock override */ | ||
2379 | |||
2380 | val = pll_readl_misc(pll); | ||
2381 | val &= ~BIT(29); | ||
2382 | pll_writel_misc(val, pll); | ||
2383 | |||
2384 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | 2371 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, |
2385 | &tegra_clk_pllre_ops); | 2372 | &tegra_clk_pll_ops); |
2386 | if (IS_ERR(clk)) | 2373 | if (IS_ERR(clk)) |
2387 | kfree(pll); | 2374 | kfree(pll); |
2388 | 2375 | ||
@@ -2604,46 +2591,6 @@ struct clk *tegra_clk_register_pllc_tegra210(const char *name, | |||
2604 | return clk; | 2591 | return clk; |
2605 | } | 2592 | } |
2606 | 2593 | ||
2607 | struct clk *tegra_clk_register_pllxc_tegra210(const char *name, | ||
2608 | const char *parent_name, void __iomem *clk_base, | ||
2609 | void __iomem *pmc, unsigned long flags, | ||
2610 | struct tegra_clk_pll_params *pll_params, | ||
2611 | spinlock_t *lock) | ||
2612 | { | ||
2613 | struct tegra_clk_pll *pll; | ||
2614 | struct clk *clk, *parent; | ||
2615 | unsigned long parent_rate; | ||
2616 | |||
2617 | parent = __clk_lookup(parent_name); | ||
2618 | if (!parent) { | ||
2619 | WARN(1, "parent clk %s of %s must be registered first\n", | ||
2620 | name, parent_name); | ||
2621 | return ERR_PTR(-EINVAL); | ||
2622 | } | ||
2623 | |||
2624 | if (!pll_params->pdiv_tohw) | ||
2625 | return ERR_PTR(-EINVAL); | ||
2626 | |||
2627 | parent_rate = clk_get_rate(parent); | ||
2628 | |||
2629 | pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); | ||
2630 | |||
2631 | if (pll_params->adjust_vco) | ||
2632 | pll_params->vco_min = pll_params->adjust_vco(pll_params, | ||
2633 | parent_rate); | ||
2634 | |||
2635 | pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); | ||
2636 | if (IS_ERR(pll)) | ||
2637 | return ERR_CAST(pll); | ||
2638 | |||
2639 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | ||
2640 | &tegra_clk_pll_ops); | ||
2641 | if (IS_ERR(clk)) | ||
2642 | kfree(pll); | ||
2643 | |||
2644 | return clk; | ||
2645 | } | ||
2646 | |||
2647 | struct clk *tegra_clk_register_pllss_tegra210(const char *name, | 2594 | struct clk *tegra_clk_register_pllss_tegra210(const char *name, |
2648 | const char *parent_name, void __iomem *clk_base, | 2595 | const char *parent_name, void __iomem *clk_base, |
2649 | unsigned long flags, | 2596 | unsigned long flags, |
@@ -2652,10 +2599,8 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, | |||
2652 | { | 2599 | { |
2653 | struct tegra_clk_pll *pll; | 2600 | struct tegra_clk_pll *pll; |
2654 | struct clk *clk, *parent; | 2601 | struct clk *clk, *parent; |
2655 | struct tegra_clk_pll_freq_table cfg; | ||
2656 | unsigned long parent_rate; | 2602 | unsigned long parent_rate; |
2657 | u32 val; | 2603 | u32 val; |
2658 | int i; | ||
2659 | 2604 | ||
2660 | if (!pll_params->div_nmp) | 2605 | if (!pll_params->div_nmp) |
2661 | return ERR_PTR(-EINVAL); | 2606 | return ERR_PTR(-EINVAL); |
@@ -2667,13 +2612,11 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, | |||
2667 | return ERR_PTR(-EINVAL); | 2612 | return ERR_PTR(-EINVAL); |
2668 | } | 2613 | } |
2669 | 2614 | ||
2670 | pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); | 2615 | val = readl_relaxed(clk_base + pll_params->base_reg); |
2671 | if (IS_ERR(pll)) | 2616 | if (val & PLLSS_REF_SRC_SEL_MASK) { |
2672 | return ERR_CAST(pll); | 2617 | WARN(1, "not supported reference clock for %s\n", name); |
2673 | 2618 | return ERR_PTR(-EINVAL); | |
2674 | val = pll_readl_base(pll); | 2619 | } |
2675 | val &= ~PLLSS_REF_SRC_SEL_MASK; | ||
2676 | pll_writel_base(val, pll); | ||
2677 | 2620 | ||
2678 | parent_rate = clk_get_rate(parent); | 2621 | parent_rate = clk_get_rate(parent); |
2679 | 2622 | ||
@@ -2683,36 +2626,10 @@ struct clk *tegra_clk_register_pllss_tegra210(const char *name, | |||
2683 | pll_params->vco_min = pll_params->adjust_vco(pll_params, | 2626 | pll_params->vco_min = pll_params->adjust_vco(pll_params, |
2684 | parent_rate); | 2627 | parent_rate); |
2685 | 2628 | ||
2686 | /* initialize PLL to minimum rate */ | 2629 | pll_params->flags |= TEGRA_PLL_BYPASS; |
2687 | 2630 | pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); | |
2688 | cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); | 2631 | if (IS_ERR(pll)) |
2689 | cfg.n = cfg.m * pll_params->vco_min / parent_rate; | 2632 | return ERR_CAST(pll); |
2690 | |||
2691 | for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) | ||
2692 | ; | ||
2693 | if (!i) { | ||
2694 | kfree(pll); | ||
2695 | return ERR_PTR(-EINVAL); | ||
2696 | } | ||
2697 | |||
2698 | cfg.p = pll_params->pdiv_tohw[i-1].hw_val; | ||
2699 | |||
2700 | _update_pll_mnp(pll, &cfg); | ||
2701 | |||
2702 | pll_writel_misc(PLLSS_MISC_DEFAULT, pll); | ||
2703 | |||
2704 | val = pll_readl_base(pll); | ||
2705 | if (val & PLL_BASE_ENABLE) { | ||
2706 | if (val & BIT(pll_params->iddq_bit_idx)) { | ||
2707 | WARN(1, "%s is on but IDDQ set\n", name); | ||
2708 | kfree(pll); | ||
2709 | return ERR_PTR(-EINVAL); | ||
2710 | } | ||
2711 | } else | ||
2712 | val |= BIT(pll_params->iddq_bit_idx); | ||
2713 | |||
2714 | val &= ~PLLSS_LOCK_OVERRIDE; | ||
2715 | pll_writel_base(val, pll); | ||
2716 | 2633 | ||
2717 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, | 2634 | clk = _tegra_clk_register_pll(pll, name, parent_name, flags, |
2718 | &tegra_clk_pll_ops); | 2635 | &tegra_clk_pll_ops); |
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 294bfe40a4f5..848255cc0209 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c | |||
@@ -216,7 +216,8 @@ | |||
216 | _clk_num, _clk_id) \ | 216 | _clk_num, _clk_id) \ |
217 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ | 217 | TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ |
218 | 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ | 218 | 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ |
219 | _clk_num, 0, _clk_id, _parents##_idx, 0, NULL) | 219 | _clk_num, TEGRA_PERIPH_ON_APB, _clk_id, \ |
220 | _parents##_idx, 0, NULL) | ||
220 | 221 | ||
221 | #define XUSB(_name, _parents, _offset, \ | 222 | #define XUSB(_name, _parents, _offset, \ |
222 | _clk_num, _gate_flags, _clk_id) \ | 223 | _clk_num, _gate_flags, _clk_id) \ |
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c index 474de0f0c26d..4f6fd307cb70 100644 --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c | |||
@@ -232,8 +232,15 @@ static void __init tegra_super_clk_init(void __iomem *clk_base, | |||
232 | if (!dt_clk) | 232 | if (!dt_clk) |
233 | return; | 233 | return; |
234 | 234 | ||
235 | clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, | 235 | #if defined(CONFIG_ARCH_TEGRA_210_SOC) |
236 | pmc_base, CLK_IGNORE_UNUSED, params, NULL); | 236 | if (gen_info->gen == gen5) |
237 | clk = tegra_clk_register_pllc_tegra210("pll_x", "pll_ref", | ||
238 | clk_base, pmc_base, CLK_IGNORE_UNUSED, params, NULL); | ||
239 | else | ||
240 | #endif | ||
241 | clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, | ||
242 | pmc_base, CLK_IGNORE_UNUSED, params, NULL); | ||
243 | |||
237 | *dt_clk = clk; | 244 | *dt_clk = clk; |
238 | 245 | ||
239 | /* PLLX_OUT0 */ | 246 | /* PLLX_OUT0 */ |
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 1024e853ea65..6d7a613f2656 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c | |||
@@ -146,7 +146,7 @@ | |||
146 | #define PLLD_SDM_EN_MASK BIT(16) | 146 | #define PLLD_SDM_EN_MASK BIT(16) |
147 | 147 | ||
148 | #define PLLD2_SDM_EN_MASK BIT(31) | 148 | #define PLLD2_SDM_EN_MASK BIT(31) |
149 | #define PLLD2_SSC_EN_MASK BIT(30) | 149 | #define PLLD2_SSC_EN_MASK 0 |
150 | 150 | ||
151 | #define PLLDP_SS_CFG 0x598 | 151 | #define PLLDP_SS_CFG 0x598 |
152 | #define PLLDP_SDM_EN_MASK BIT(31) | 152 | #define PLLDP_SDM_EN_MASK BIT(31) |
@@ -241,6 +241,9 @@ | |||
241 | #define PLL_SDM_COEFF BIT(13) | 241 | #define PLL_SDM_COEFF BIT(13) |
242 | #define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU)) | 242 | #define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU)) |
243 | #define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat) | 243 | #define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat) |
244 | /* This macro returns ndiv effective scaled to SDM range */ | ||
245 | #define sdin_get_n_eff(cfg) ((cfg)->n * PLL_SDM_COEFF + ((cfg)->sdm_data ? \ | ||
246 | (PLL_SDM_COEFF/2 + sdin_data_to_din((cfg)->sdm_data)) : 0)) | ||
244 | 247 | ||
245 | /* Tegra CPU clock and reset control regs */ | 248 | /* Tegra CPU clock and reset control regs */ |
246 | #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 | 249 | #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 |
@@ -715,8 +718,6 @@ static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss, | |||
715 | plldss->params->defaults_set = true; | 718 | plldss->params->defaults_set = true; |
716 | 719 | ||
717 | if (val & PLL_ENABLE) { | 720 | if (val & PLL_ENABLE) { |
718 | pr_warn("%s already enabled. Postponing set full defaults\n", | ||
719 | pll_name); | ||
720 | 721 | ||
721 | /* | 722 | /* |
722 | * PLL is ON: check if defaults already set, then set those | 723 | * PLL is ON: check if defaults already set, then set those |
@@ -755,6 +756,10 @@ static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss, | |||
755 | (~PLLDSS_MISC1_CFG_EN_SDM)); | 756 | (~PLLDSS_MISC1_CFG_EN_SDM)); |
756 | } | 757 | } |
757 | 758 | ||
759 | if (!plldss->params->defaults_set) | ||
760 | pr_warn("%s already enabled. Postponing set full defaults\n", | ||
761 | pll_name); | ||
762 | |||
758 | /* Enable lock detect */ | 763 | /* Enable lock detect */ |
759 | if (val & PLLDSS_BASE_LOCK_OVERRIDE) { | 764 | if (val & PLLDSS_BASE_LOCK_OVERRIDE) { |
760 | val &= ~PLLDSS_BASE_LOCK_OVERRIDE; | 765 | val &= ~PLLDSS_BASE_LOCK_OVERRIDE; |
@@ -1288,8 +1293,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw, | |||
1288 | s -= PLL_SDM_COEFF / 2; | 1293 | s -= PLL_SDM_COEFF / 2; |
1289 | cfg->sdm_data = sdin_din_to_data(s); | 1294 | cfg->sdm_data = sdin_din_to_data(s); |
1290 | } | 1295 | } |
1291 | cfg->output_rate *= cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + | 1296 | cfg->output_rate *= sdin_get_n_eff(cfg); |
1292 | sdin_data_to_din(cfg->sdm_data); | ||
1293 | cfg->output_rate /= p * cfg->m * PLL_SDM_COEFF; | 1297 | cfg->output_rate /= p * cfg->m * PLL_SDM_COEFF; |
1294 | } else { | 1298 | } else { |
1295 | cfg->output_rate *= cfg->n; | 1299 | cfg->output_rate *= cfg->n; |
@@ -1314,8 +1318,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw, | |||
1314 | */ | 1318 | */ |
1315 | static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg) | 1319 | static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg) |
1316 | { | 1320 | { |
1317 | cfg->n = cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + | 1321 | cfg->n = sdin_get_n_eff(cfg); |
1318 | sdin_data_to_din(cfg->sdm_data); | ||
1319 | cfg->m *= PLL_SDM_COEFF; | 1322 | cfg->m *= PLL_SDM_COEFF; |
1320 | } | 1323 | } |
1321 | 1324 | ||
@@ -2204,7 +2207,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = { | |||
2204 | [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, | 2207 | [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, |
2205 | [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, | 2208 | [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, |
2206 | [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, | 2209 | [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, |
2207 | [tegra_clk_vfir] = { .dt_id = TEGRA210_CLK_VFIR, .present = true }, | ||
2208 | [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true }, | 2210 | [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true }, |
2209 | [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true }, | 2211 | [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true }, |
2210 | [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true }, | 2212 | [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true }, |
@@ -2470,15 +2472,14 @@ static void tegra210_utmi_param_configure(void) | |||
2470 | reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); | 2472 | reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); |
2471 | 2473 | ||
2472 | reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); | 2474 | reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); |
2473 | |||
2474 | reg |= | 2475 | reg |= |
2475 | UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].active_delay_count); | 2476 | UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].active_delay_count); |
2476 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); | 2477 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); |
2477 | 2478 | ||
2478 | /* Program UTMIP PLL delay and oscillator frequency counts */ | 2479 | /* Program UTMIP PLL delay and oscillator frequency counts */ |
2479 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); | 2480 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); |
2480 | reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); | ||
2481 | 2481 | ||
2482 | reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); | ||
2482 | reg |= | 2483 | reg |= |
2483 | UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].enable_delay_count); | 2484 | UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].enable_delay_count); |
2484 | 2485 | ||
@@ -2494,7 +2495,8 @@ static void tegra210_utmi_param_configure(void) | |||
2494 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; | 2495 | reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; |
2495 | reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; | 2496 | reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; |
2496 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); | 2497 | writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); |
2497 | udelay(1); | 2498 | |
2499 | udelay(20); | ||
2498 | 2500 | ||
2499 | /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */ | 2501 | /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */ |
2500 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); | 2502 | reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); |
@@ -2552,6 +2554,7 @@ static int tegra210_enable_pllu(void) | |||
2552 | reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); | 2554 | reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); |
2553 | reg &= ~BIT(pllu.params->iddq_bit_idx); | 2555 | reg &= ~BIT(pllu.params->iddq_bit_idx); |
2554 | writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); | 2556 | writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); |
2557 | udelay(5); | ||
2555 | 2558 | ||
2556 | reg = readl_relaxed(clk_base + PLLU_BASE); | 2559 | reg = readl_relaxed(clk_base + PLLU_BASE); |
2557 | reg &= ~GENMASK(20, 0); | 2560 | reg &= ~GENMASK(20, 0); |
@@ -2559,6 +2562,7 @@ static int tegra210_enable_pllu(void) | |||
2559 | reg |= fentry->n << 8; | 2562 | reg |= fentry->n << 8; |
2560 | reg |= fentry->p << 16; | 2563 | reg |= fentry->p << 16; |
2561 | writel(reg, clk_base + PLLU_BASE); | 2564 | writel(reg, clk_base + PLLU_BASE); |
2565 | udelay(1); | ||
2562 | reg |= PLL_ENABLE; | 2566 | reg |= PLL_ENABLE; |
2563 | writel(reg, clk_base + PLLU_BASE); | 2567 | writel(reg, clk_base + PLLU_BASE); |
2564 | 2568 | ||
@@ -2699,7 +2703,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base, | |||
2699 | struct clk *clk; | 2703 | struct clk *clk; |
2700 | 2704 | ||
2701 | /* PLLC */ | 2705 | /* PLLC */ |
2702 | clk = tegra_clk_register_pllxc_tegra210("pll_c", "pll_ref", clk_base, | 2706 | clk = tegra_clk_register_pllc_tegra210("pll_c", "pll_ref", clk_base, |
2703 | pmc, 0, &pll_c_params, NULL); | 2707 | pmc, 0, &pll_c_params, NULL); |
2704 | if (!WARN_ON(IS_ERR(clk))) | 2708 | if (!WARN_ON(IS_ERR(clk))) |
2705 | clk_register_clkdev(clk, "pll_c", NULL); | 2709 | clk_register_clkdev(clk, "pll_c", NULL); |
@@ -2798,14 +2802,14 @@ static void __init tegra210_pll_init(void __iomem *clk_base, | |||
2798 | /* PLLU_60M */ | 2802 | /* PLLU_60M */ |
2799 | clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2", | 2803 | clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2", |
2800 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, | 2804 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, |
2801 | 23, 0, NULL); | 2805 | 23, 0, &pll_u_lock); |
2802 | clk_register_clkdev(clk, "pll_u_60M", NULL); | 2806 | clk_register_clkdev(clk, "pll_u_60M", NULL); |
2803 | clks[TEGRA210_CLK_PLL_U_60M] = clk; | 2807 | clks[TEGRA210_CLK_PLL_U_60M] = clk; |
2804 | 2808 | ||
2805 | /* PLLU_48M */ | 2809 | /* PLLU_48M */ |
2806 | clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1", | 2810 | clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1", |
2807 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, | 2811 | CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, |
2808 | 25, 0, NULL); | 2812 | 25, 0, &pll_u_lock); |
2809 | clk_register_clkdev(clk, "pll_u_48M", NULL); | 2813 | clk_register_clkdev(clk, "pll_u_48M", NULL); |
2810 | clks[TEGRA210_CLK_PLL_U_48M] = clk; | 2814 | clks[TEGRA210_CLK_PLL_U_48M] = clk; |
2811 | 2815 | ||
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index 945b07093afa..872f1189ad7f 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h | |||
@@ -362,12 +362,6 @@ struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name, | |||
362 | struct tegra_clk_pll_params *pll_params, | 362 | struct tegra_clk_pll_params *pll_params, |
363 | spinlock_t *lock); | 363 | spinlock_t *lock); |
364 | 364 | ||
365 | struct clk *tegra_clk_register_pllxc_tegra210(const char *name, | ||
366 | const char *parent_name, void __iomem *clk_base, | ||
367 | void __iomem *pmc, unsigned long flags, | ||
368 | struct tegra_clk_pll_params *pll_params, | ||
369 | spinlock_t *lock); | ||
370 | |||
371 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, | 365 | struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, |
372 | void __iomem *clk_base, void __iomem *pmc, | 366 | void __iomem *clk_base, void __iomem *pmc, |
373 | unsigned long flags, | 367 | unsigned long flags, |
diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index 255cafb18336..d6036c788fab 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c | |||
@@ -222,7 +222,7 @@ static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock, | |||
222 | 222 | ||
223 | /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ | 223 | /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ |
224 | postfix = strrchr(name, '.'); | 224 | postfix = strrchr(name, '.'); |
225 | if (strlen(postfix) > 1) { | 225 | if (postfix && strlen(postfix) > 1) { |
226 | if (strlen(postfix) > ADPLL_MAX_CON_ID) | 226 | if (strlen(postfix) > ADPLL_MAX_CON_ID) |
227 | dev_warn(d->dev, "clock %s con_id lookup may fail\n", | 227 | dev_warn(d->dev, "clock %s con_id lookup may fail\n", |
228 | name); | 228 | name); |
@@ -486,7 +486,7 @@ static u8 ti_adpll_get_parent(struct clk_hw *hw) | |||
486 | return 0; | 486 | return 0; |
487 | } | 487 | } |
488 | 488 | ||
489 | static struct clk_ops ti_adpll_ops = { | 489 | static const struct clk_ops ti_adpll_ops = { |
490 | .prepare = ti_adpll_prepare, | 490 | .prepare = ti_adpll_prepare, |
491 | .unprepare = ti_adpll_unprepare, | 491 | .unprepare = ti_adpll_unprepare, |
492 | .is_prepared = ti_adpll_is_prepared, | 492 | .is_prepared = ti_adpll_is_prepared, |
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index 06f486b3488c..83b148f8037c 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c | |||
@@ -304,7 +304,7 @@ static void omap2_apll_disable(struct clk_hw *hw) | |||
304 | ti_clk_ll_ops->clk_writel(v, &ad->control_reg); | 304 | ti_clk_ll_ops->clk_writel(v, &ad->control_reg); |
305 | } | 305 | } |
306 | 306 | ||
307 | static struct clk_ops omap2_apll_ops = { | 307 | static const struct clk_ops omap2_apll_ops = { |
308 | .enable = &omap2_apll_enable, | 308 | .enable = &omap2_apll_enable, |
309 | .disable = &omap2_apll_disable, | 309 | .disable = &omap2_apll_disable, |
310 | .is_enabled = &omap2_apll_is_enabled, | 310 | .is_enabled = &omap2_apll_is_enabled, |
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index fbedc6a9fed0..07a805125e98 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c | |||
@@ -138,8 +138,8 @@ static void __init of_ti_clockdomain_setup(struct device_node *node) | |||
138 | for (i = 0; i < num_clks; i++) { | 138 | for (i = 0; i < num_clks; i++) { |
139 | clk = of_clk_get(node, i); | 139 | clk = of_clk_get(node, i); |
140 | if (IS_ERR(clk)) { | 140 | if (IS_ERR(clk)) { |
141 | pr_err("%s: Failed get %s' clock nr %d (%ld)\n", | 141 | pr_err("%s: Failed get %pOF' clock nr %d (%ld)\n", |
142 | __func__, node->full_name, i, PTR_ERR(clk)); | 142 | __func__, node, i, PTR_ERR(clk)); |
143 | continue; | 143 | continue; |
144 | } | 144 | } |
145 | clk_hw = __clk_get_hw(clk); | 145 | clk_hw = __clk_get_hw(clk); |
diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index 66a0d0ed8b55..071af44b1ba8 100644 --- a/drivers/clk/ti/fapll.c +++ b/drivers/clk/ti/fapll.c | |||
@@ -268,7 +268,7 @@ static int ti_fapll_set_rate(struct clk_hw *hw, unsigned long rate, | |||
268 | return 0; | 268 | return 0; |
269 | } | 269 | } |
270 | 270 | ||
271 | static struct clk_ops ti_fapll_ops = { | 271 | static const struct clk_ops ti_fapll_ops = { |
272 | .enable = ti_fapll_enable, | 272 | .enable = ti_fapll_enable, |
273 | .disable = ti_fapll_disable, | 273 | .disable = ti_fapll_disable, |
274 | .is_enabled = ti_fapll_is_enabled, | 274 | .is_enabled = ti_fapll_is_enabled, |
@@ -478,7 +478,7 @@ static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate, | |||
478 | return 0; | 478 | return 0; |
479 | } | 479 | } |
480 | 480 | ||
481 | static struct clk_ops ti_fapll_synt_ops = { | 481 | static const struct clk_ops ti_fapll_synt_ops = { |
482 | .enable = ti_fapll_synth_enable, | 482 | .enable = ti_fapll_synth_enable, |
483 | .disable = ti_fapll_synth_disable, | 483 | .disable = ti_fapll_synth_disable, |
484 | .is_enabled = ti_fapll_synth_is_enabled, | 484 | .is_enabled = ti_fapll_synth_is_enabled, |
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c index 2cf386347f0c..e09f3dd46318 100644 --- a/drivers/clk/uniphier/clk-uniphier-core.c +++ b/drivers/clk/uniphier/clk-uniphier-core.c | |||
@@ -111,10 +111,6 @@ static int uniphier_clk_remove(struct platform_device *pdev) | |||
111 | static const struct of_device_id uniphier_clk_match[] = { | 111 | static const struct of_device_id uniphier_clk_match[] = { |
112 | /* System clock */ | 112 | /* System clock */ |
113 | { | 113 | { |
114 | .compatible = "socionext,uniphier-sld3-clock", | ||
115 | .data = uniphier_sld3_sys_clk_data, | ||
116 | }, | ||
117 | { | ||
118 | .compatible = "socionext,uniphier-ld4-clock", | 114 | .compatible = "socionext,uniphier-ld4-clock", |
119 | .data = uniphier_ld4_sys_clk_data, | 115 | .data = uniphier_ld4_sys_clk_data, |
120 | }, | 116 | }, |
@@ -142,22 +138,22 @@ static const struct of_device_id uniphier_clk_match[] = { | |||
142 | .compatible = "socionext,uniphier-ld20-clock", | 138 | .compatible = "socionext,uniphier-ld20-clock", |
143 | .data = uniphier_ld20_sys_clk_data, | 139 | .data = uniphier_ld20_sys_clk_data, |
144 | }, | 140 | }, |
145 | /* Media I/O clock, SD clock */ | ||
146 | { | 141 | { |
147 | .compatible = "socionext,uniphier-sld3-mio-clock", | 142 | .compatible = "socionext,uniphier-pxs3-clock", |
148 | .data = uniphier_sld3_mio_clk_data, | 143 | .data = uniphier_pxs3_sys_clk_data, |
149 | }, | 144 | }, |
145 | /* Media I/O clock, SD clock */ | ||
150 | { | 146 | { |
151 | .compatible = "socionext,uniphier-ld4-mio-clock", | 147 | .compatible = "socionext,uniphier-ld4-mio-clock", |
152 | .data = uniphier_sld3_mio_clk_data, | 148 | .data = uniphier_ld4_mio_clk_data, |
153 | }, | 149 | }, |
154 | { | 150 | { |
155 | .compatible = "socionext,uniphier-pro4-mio-clock", | 151 | .compatible = "socionext,uniphier-pro4-mio-clock", |
156 | .data = uniphier_sld3_mio_clk_data, | 152 | .data = uniphier_ld4_mio_clk_data, |
157 | }, | 153 | }, |
158 | { | 154 | { |
159 | .compatible = "socionext,uniphier-sld8-mio-clock", | 155 | .compatible = "socionext,uniphier-sld8-mio-clock", |
160 | .data = uniphier_sld3_mio_clk_data, | 156 | .data = uniphier_ld4_mio_clk_data, |
161 | }, | 157 | }, |
162 | { | 158 | { |
163 | .compatible = "socionext,uniphier-pro5-sd-clock", | 159 | .compatible = "socionext,uniphier-pro5-sd-clock", |
@@ -169,12 +165,16 @@ static const struct of_device_id uniphier_clk_match[] = { | |||
169 | }, | 165 | }, |
170 | { | 166 | { |
171 | .compatible = "socionext,uniphier-ld11-mio-clock", | 167 | .compatible = "socionext,uniphier-ld11-mio-clock", |
172 | .data = uniphier_sld3_mio_clk_data, | 168 | .data = uniphier_ld4_mio_clk_data, |
173 | }, | 169 | }, |
174 | { | 170 | { |
175 | .compatible = "socionext,uniphier-ld20-sd-clock", | 171 | .compatible = "socionext,uniphier-ld20-sd-clock", |
176 | .data = uniphier_pro5_sd_clk_data, | 172 | .data = uniphier_pro5_sd_clk_data, |
177 | }, | 173 | }, |
174 | { | ||
175 | .compatible = "socionext,uniphier-pxs3-sd-clock", | ||
176 | .data = uniphier_pro5_sd_clk_data, | ||
177 | }, | ||
178 | /* Peripheral clock */ | 178 | /* Peripheral clock */ |
179 | { | 179 | { |
180 | .compatible = "socionext,uniphier-ld4-peri-clock", | 180 | .compatible = "socionext,uniphier-ld4-peri-clock", |
@@ -204,6 +204,10 @@ static const struct of_device_id uniphier_clk_match[] = { | |||
204 | .compatible = "socionext,uniphier-ld20-peri-clock", | 204 | .compatible = "socionext,uniphier-ld20-peri-clock", |
205 | .data = uniphier_pro4_peri_clk_data, | 205 | .data = uniphier_pro4_peri_clk_data, |
206 | }, | 206 | }, |
207 | { | ||
208 | .compatible = "socionext,uniphier-pxs3-peri-clock", | ||
209 | .data = uniphier_pro4_peri_clk_data, | ||
210 | }, | ||
207 | { /* sentinel */ } | 211 | { /* sentinel */ } |
208 | }; | 212 | }; |
209 | 213 | ||
diff --git a/drivers/clk/uniphier/clk-uniphier-mio.c b/drivers/clk/uniphier/clk-uniphier-mio.c index 218d20f099ce..16e4d303f535 100644 --- a/drivers/clk/uniphier/clk-uniphier-mio.c +++ b/drivers/clk/uniphier/clk-uniphier-mio.c | |||
@@ -76,7 +76,7 @@ | |||
76 | #define UNIPHIER_MIO_CLK_DMAC(idx) \ | 76 | #define UNIPHIER_MIO_CLK_DMAC(idx) \ |
77 | UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25) | 77 | UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25) |
78 | 78 | ||
79 | const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = { | 79 | const struct uniphier_clk_data uniphier_ld4_mio_clk_data[] = { |
80 | UNIPHIER_MIO_CLK_SD_FIXED, | 80 | UNIPHIER_MIO_CLK_SD_FIXED, |
81 | UNIPHIER_MIO_CLK_SD(0, 0), | 81 | UNIPHIER_MIO_CLK_SD(0, 0), |
82 | UNIPHIER_MIO_CLK_SD(1, 1), | 82 | UNIPHIER_MIO_CLK_SD(1, 1), |
@@ -85,11 +85,9 @@ const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = { | |||
85 | UNIPHIER_MIO_CLK_USB2(8, 0), | 85 | UNIPHIER_MIO_CLK_USB2(8, 0), |
86 | UNIPHIER_MIO_CLK_USB2(9, 1), | 86 | UNIPHIER_MIO_CLK_USB2(9, 1), |
87 | UNIPHIER_MIO_CLK_USB2(10, 2), | 87 | UNIPHIER_MIO_CLK_USB2(10, 2), |
88 | UNIPHIER_MIO_CLK_USB2(11, 3), | ||
89 | UNIPHIER_MIO_CLK_USB2_PHY(12, 0), | 88 | UNIPHIER_MIO_CLK_USB2_PHY(12, 0), |
90 | UNIPHIER_MIO_CLK_USB2_PHY(13, 1), | 89 | UNIPHIER_MIO_CLK_USB2_PHY(13, 1), |
91 | UNIPHIER_MIO_CLK_USB2_PHY(14, 2), | 90 | UNIPHIER_MIO_CLK_USB2_PHY(14, 2), |
92 | UNIPHIER_MIO_CLK_USB2_PHY(15, 3), | ||
93 | { /* sentinel */ } | 91 | { /* sentinel */ } |
94 | }; | 92 | }; |
95 | 93 | ||
diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c index ad0218182a9f..0e396f3da526 100644 --- a/drivers/clk/uniphier/clk-uniphier-sys.c +++ b/drivers/clk/uniphier/clk-uniphier-sys.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #include "clk-uniphier.h" | 18 | #include "clk-uniphier.h" |
19 | 19 | ||
20 | #define UNIPHIER_SLD3_SYS_CLK_SD \ | 20 | #define UNIPHIER_LD4_SYS_CLK_SD \ |
21 | UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \ | 21 | UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \ |
22 | UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2) | 22 | UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2) |
23 | 23 | ||
@@ -30,7 +30,7 @@ | |||
30 | UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) | 30 | UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) |
31 | 31 | ||
32 | /* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ | 32 | /* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ |
33 | #define UNIPHIER_SLD3_SYS_CLK_NAND(idx) \ | 33 | #define UNIPHIER_LD4_SYS_CLK_NAND(idx) \ |
34 | UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \ | 34 | UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \ |
35 | UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) | 35 | UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) |
36 | 36 | ||
@@ -45,7 +45,7 @@ | |||
45 | #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ | 45 | #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ |
46 | UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) | 46 | UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) |
47 | 47 | ||
48 | #define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \ | 48 | #define UNIPHIER_LD4_SYS_CLK_STDMAC(idx) \ |
49 | UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10) | 49 | UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10) |
50 | 50 | ||
51 | #define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \ | 51 | #define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \ |
@@ -57,19 +57,23 @@ | |||
57 | #define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \ | 57 | #define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \ |
58 | UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch)) | 58 | UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch)) |
59 | 59 | ||
60 | const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = { | 60 | #define UNIPHIER_LD11_SYS_CLK_AIO(idx) \ |
61 | UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ | 61 | UNIPHIER_CLK_FACTOR("aio-io200m", -1, "spll", 1, 10), \ |
62 | UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512), /* 288 MHz */ | 62 | UNIPHIER_CLK_GATE("aio", (idx), "aio-io200m", 0x2108, 0) |
63 | UNIPHIER_CLK_FACTOR("a2pll", -1, "ref", 24, 1), /* 589.824 MHz */ | 63 | |
64 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ | 64 | #define UNIPHIER_LD11_SYS_CLK_EVEA(idx) \ |
65 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), | 65 | UNIPHIER_CLK_FACTOR("evea-io100m", -1, "spll", 1, 20), \ |
66 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), | 66 | UNIPHIER_CLK_GATE("evea", (idx), "evea-io100m", 0x2108, 1) |
67 | UNIPHIER_SLD3_SYS_CLK_NAND(2), | 67 | |
68 | UNIPHIER_SLD3_SYS_CLK_SD, | 68 | #define UNIPHIER_LD11_SYS_CLK_EXIV(idx) \ |
69 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 69 | UNIPHIER_CLK_FACTOR("exiv-io200m", -1, "spll", 1, 10), \ |
70 | UNIPHIER_SLD3_SYS_CLK_STDMAC(8), | 70 | UNIPHIER_CLK_GATE("exiv", (idx), "exiv-io200m", 0x2110, 2) |
71 | { /* sentinel */ } | 71 | |
72 | }; | 72 | #define UNIPHIER_PRO4_SYS_CLK_ETHER(idx) \ |
73 | UNIPHIER_CLK_GATE("ether", (idx), NULL, 0x2104, 12) | ||
74 | |||
75 | #define UNIPHIER_LD11_SYS_CLK_ETHER(idx) \ | ||
76 | UNIPHIER_CLK_GATE("ether", (idx), NULL, 0x210c, 6) | ||
73 | 77 | ||
74 | const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = { | 78 | const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = { |
75 | UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ | 79 | UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ |
@@ -78,10 +82,10 @@ const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = { | |||
78 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ | 82 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ |
79 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), | 83 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), |
80 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), | 84 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), |
81 | UNIPHIER_SLD3_SYS_CLK_NAND(2), | 85 | UNIPHIER_LD4_SYS_CLK_NAND(2), |
82 | UNIPHIER_SLD3_SYS_CLK_SD, | 86 | UNIPHIER_LD4_SYS_CLK_SD, |
83 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 87 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), |
84 | UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ | 88 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ |
85 | { /* sentinel */ } | 89 | { /* sentinel */ } |
86 | }; | 90 | }; |
87 | 91 | ||
@@ -92,10 +96,11 @@ const struct uniphier_clk_data uniphier_pro4_sys_clk_data[] = { | |||
92 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ | 96 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ |
93 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), | 97 | UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), |
94 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), | 98 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), |
95 | UNIPHIER_SLD3_SYS_CLK_NAND(2), | 99 | UNIPHIER_LD4_SYS_CLK_NAND(2), |
96 | UNIPHIER_SLD3_SYS_CLK_SD, | 100 | UNIPHIER_LD4_SYS_CLK_SD, |
97 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 101 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), |
98 | UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */ | 102 | UNIPHIER_PRO4_SYS_CLK_ETHER(6), |
103 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */ | ||
99 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ | 104 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ |
100 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), | 105 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), |
101 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), | 106 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), |
@@ -108,10 +113,10 @@ const struct uniphier_clk_data uniphier_sld8_sys_clk_data[] = { | |||
108 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ | 113 | UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ |
109 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), | 114 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), |
110 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), | 115 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), |
111 | UNIPHIER_SLD3_SYS_CLK_NAND(2), | 116 | UNIPHIER_LD4_SYS_CLK_NAND(2), |
112 | UNIPHIER_SLD3_SYS_CLK_SD, | 117 | UNIPHIER_LD4_SYS_CLK_SD, |
113 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), | 118 | UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), |
114 | UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ | 119 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ |
115 | { /* sentinel */ } | 120 | { /* sentinel */ } |
116 | }; | 121 | }; |
117 | 122 | ||
@@ -123,7 +128,7 @@ const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = { | |||
123 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), | 128 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), |
124 | UNIPHIER_PRO5_SYS_CLK_NAND(2), | 129 | UNIPHIER_PRO5_SYS_CLK_NAND(2), |
125 | UNIPHIER_PRO5_SYS_CLK_SD, | 130 | UNIPHIER_PRO5_SYS_CLK_SD, |
126 | UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */ | 131 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */ |
127 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ | 132 | UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ |
128 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), | 133 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), |
129 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), | 134 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), |
@@ -136,7 +141,8 @@ const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = { | |||
136 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), | 141 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), |
137 | UNIPHIER_PRO5_SYS_CLK_NAND(2), | 142 | UNIPHIER_PRO5_SYS_CLK_NAND(2), |
138 | UNIPHIER_PRO5_SYS_CLK_SD, | 143 | UNIPHIER_PRO5_SYS_CLK_SD, |
139 | UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, RLE */ | 144 | UNIPHIER_PRO4_SYS_CLK_ETHER(6), |
145 | UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, RLE */ | ||
140 | /* GIO is always clock-enabled: no function for 0x2104 bit6 */ | 146 | /* GIO is always clock-enabled: no function for 0x2104 bit6 */ |
141 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), | 147 | UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), |
142 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), | 148 | UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), |
@@ -156,8 +162,12 @@ const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = { | |||
156 | UNIPHIER_LD11_SYS_CLK_NAND(2), | 162 | UNIPHIER_LD11_SYS_CLK_NAND(2), |
157 | UNIPHIER_LD11_SYS_CLK_EMMC(4), | 163 | UNIPHIER_LD11_SYS_CLK_EMMC(4), |
158 | /* Index 5 reserved for eMMC PHY */ | 164 | /* Index 5 reserved for eMMC PHY */ |
165 | UNIPHIER_LD11_SYS_CLK_ETHER(6), | ||
159 | UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */ | 166 | UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */ |
160 | UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25), | 167 | UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25), |
168 | UNIPHIER_LD11_SYS_CLK_AIO(40), | ||
169 | UNIPHIER_LD11_SYS_CLK_EVEA(41), | ||
170 | UNIPHIER_LD11_SYS_CLK_EXIV(42), | ||
161 | /* CPU gears */ | 171 | /* CPU gears */ |
162 | UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), | 172 | UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), |
163 | UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8), | 173 | UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8), |
@@ -185,6 +195,7 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { | |||
185 | UNIPHIER_LD11_SYS_CLK_EMMC(4), | 195 | UNIPHIER_LD11_SYS_CLK_EMMC(4), |
186 | /* Index 5 reserved for eMMC PHY */ | 196 | /* Index 5 reserved for eMMC PHY */ |
187 | UNIPHIER_LD20_SYS_CLK_SD, | 197 | UNIPHIER_LD20_SYS_CLK_SD, |
198 | UNIPHIER_LD11_SYS_CLK_ETHER(6), | ||
188 | UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */ | 199 | UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */ |
189 | /* GIO is always clock-enabled: no function for 0x210c bit5 */ | 200 | /* GIO is always clock-enabled: no function for 0x210c bit5 */ |
190 | /* | 201 | /* |
@@ -194,6 +205,9 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { | |||
194 | UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), | 205 | UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), |
195 | UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12), | 206 | UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12), |
196 | UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13), | 207 | UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13), |
208 | UNIPHIER_LD11_SYS_CLK_AIO(40), | ||
209 | UNIPHIER_LD11_SYS_CLK_EVEA(41), | ||
210 | UNIPHIER_LD11_SYS_CLK_EXIV(42), | ||
197 | /* CPU gears */ | 211 | /* CPU gears */ |
198 | UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), | 212 | UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), |
199 | UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), | 213 | UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), |
@@ -209,3 +223,33 @@ const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = { | |||
209 | "spll/4", "spll/8", "s2pll/4", "s2pll/8"), | 223 | "spll/4", "spll/8", "s2pll/4", "s2pll/8"), |
210 | { /* sentinel */ } | 224 | { /* sentinel */ } |
211 | }; | 225 | }; |
226 | |||
227 | const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = { | ||
228 | UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 104, 1), /* ARM: 2600 MHz */ | ||
229 | UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1), /* 2000 MHz */ | ||
230 | UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1), /* IPP: 2400 MHz */ | ||
231 | UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), | ||
232 | UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), | ||
233 | UNIPHIER_LD20_SYS_CLK_SD, | ||
234 | UNIPHIER_LD11_SYS_CLK_NAND(2), | ||
235 | UNIPHIER_LD11_SYS_CLK_EMMC(4), | ||
236 | UNIPHIER_CLK_GATE("usb30", 12, NULL, 0x2104, 4), /* =GIO0 */ | ||
237 | UNIPHIER_CLK_GATE("usb31-0", 13, NULL, 0x2104, 5), /* =GIO1 */ | ||
238 | UNIPHIER_CLK_GATE("usb31-1", 14, NULL, 0x2104, 6), /* =GIO1-1 */ | ||
239 | UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 16), | ||
240 | UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 18), | ||
241 | UNIPHIER_CLK_GATE("usb30-phy2", 18, NULL, 0x210c, 20), | ||
242 | UNIPHIER_CLK_GATE("usb31-phy0", 20, NULL, 0x210c, 17), | ||
243 | UNIPHIER_CLK_GATE("usb31-phy1", 21, NULL, 0x210c, 19), | ||
244 | /* CPU gears */ | ||
245 | UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), | ||
246 | UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), | ||
247 | UNIPHIER_CLK_DIV4("s2pll", 2, 3, 4, 8), | ||
248 | UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8, | ||
249 | "cpll/2", "spll/2", "cpll/3", "spll/3", | ||
250 | "spll/4", "spll/8", "cpll/4", "cpll/8"), | ||
251 | UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8, | ||
252 | "s2pll/2", "spll/2", "s2pll/3", "spll/3", | ||
253 | "spll/4", "spll/8", "s2pll/4", "s2pll/8"), | ||
254 | { /* sentinel */ } | ||
255 | }; | ||
diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h index 01c16ecec48f..d10a009ada96 100644 --- a/drivers/clk/uniphier/clk-uniphier.h +++ b/drivers/clk/uniphier/clk-uniphier.h | |||
@@ -147,7 +147,6 @@ struct clk_hw *uniphier_clk_register_mux(struct device *dev, | |||
147 | const char *name, | 147 | const char *name, |
148 | const struct uniphier_clk_mux_data *data); | 148 | const struct uniphier_clk_mux_data *data); |
149 | 149 | ||
150 | extern const struct uniphier_clk_data uniphier_sld3_sys_clk_data[]; | ||
151 | extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[]; | 150 | extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[]; |
152 | extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[]; | 151 | extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[]; |
153 | extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[]; | 152 | extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[]; |
@@ -155,7 +154,8 @@ extern const struct uniphier_clk_data uniphier_pro5_sys_clk_data[]; | |||
155 | extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[]; | 154 | extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[]; |
156 | extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[]; | 155 | extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[]; |
157 | extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[]; | 156 | extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[]; |
158 | extern const struct uniphier_clk_data uniphier_sld3_mio_clk_data[]; | 157 | extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[]; |
158 | extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[]; | ||
159 | extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[]; | 159 | extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[]; |
160 | extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[]; | 160 | extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[]; |
161 | extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[]; | 161 | extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[]; |
diff --git a/drivers/clk/ux500/clk-prcc.c b/drivers/clk/ux500/clk-prcc.c index 0e950769ed03..f50592775c9d 100644 --- a/drivers/clk/ux500/clk-prcc.c +++ b/drivers/clk/ux500/clk-prcc.c | |||
@@ -79,13 +79,13 @@ static int clk_prcc_is_enabled(struct clk_hw *hw) | |||
79 | return clk->is_enabled; | 79 | return clk->is_enabled; |
80 | } | 80 | } |
81 | 81 | ||
82 | static struct clk_ops clk_prcc_pclk_ops = { | 82 | static const struct clk_ops clk_prcc_pclk_ops = { |
83 | .enable = clk_prcc_pclk_enable, | 83 | .enable = clk_prcc_pclk_enable, |
84 | .disable = clk_prcc_pclk_disable, | 84 | .disable = clk_prcc_pclk_disable, |
85 | .is_enabled = clk_prcc_is_enabled, | 85 | .is_enabled = clk_prcc_is_enabled, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct clk_ops clk_prcc_kclk_ops = { | 88 | static const struct clk_ops clk_prcc_kclk_ops = { |
89 | .enable = clk_prcc_kclk_enable, | 89 | .enable = clk_prcc_kclk_enable, |
90 | .disable = clk_prcc_kclk_disable, | 90 | .disable = clk_prcc_kclk_disable, |
91 | .is_enabled = clk_prcc_is_enabled, | 91 | .is_enabled = clk_prcc_is_enabled, |
@@ -96,7 +96,7 @@ static struct clk *clk_reg_prcc(const char *name, | |||
96 | resource_size_t phy_base, | 96 | resource_size_t phy_base, |
97 | u32 cg_sel, | 97 | u32 cg_sel, |
98 | unsigned long flags, | 98 | unsigned long flags, |
99 | struct clk_ops *clk_prcc_ops) | 99 | const struct clk_ops *clk_prcc_ops) |
100 | { | 100 | { |
101 | struct clk_prcc *clk; | 101 | struct clk_prcc *clk; |
102 | struct clk_init_data clk_prcc_init; | 102 | struct clk_init_data clk_prcc_init; |
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 7f343821f4e4..6e3e16b2e5ca 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c | |||
@@ -186,7 +186,7 @@ static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) | |||
186 | clk->is_prepared = 0; | 186 | clk->is_prepared = 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | static struct clk_ops clk_prcmu_scalable_ops = { | 189 | static const struct clk_ops clk_prcmu_scalable_ops = { |
190 | .prepare = clk_prcmu_prepare, | 190 | .prepare = clk_prcmu_prepare, |
191 | .unprepare = clk_prcmu_unprepare, | 191 | .unprepare = clk_prcmu_unprepare, |
192 | .is_prepared = clk_prcmu_is_prepared, | 192 | .is_prepared = clk_prcmu_is_prepared, |
@@ -198,7 +198,7 @@ static struct clk_ops clk_prcmu_scalable_ops = { | |||
198 | .set_rate = clk_prcmu_set_rate, | 198 | .set_rate = clk_prcmu_set_rate, |
199 | }; | 199 | }; |
200 | 200 | ||
201 | static struct clk_ops clk_prcmu_gate_ops = { | 201 | static const struct clk_ops clk_prcmu_gate_ops = { |
202 | .prepare = clk_prcmu_prepare, | 202 | .prepare = clk_prcmu_prepare, |
203 | .unprepare = clk_prcmu_unprepare, | 203 | .unprepare = clk_prcmu_unprepare, |
204 | .is_prepared = clk_prcmu_is_prepared, | 204 | .is_prepared = clk_prcmu_is_prepared, |
@@ -208,19 +208,19 @@ static struct clk_ops clk_prcmu_gate_ops = { | |||
208 | .recalc_rate = clk_prcmu_recalc_rate, | 208 | .recalc_rate = clk_prcmu_recalc_rate, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | static struct clk_ops clk_prcmu_scalable_rate_ops = { | 211 | static const struct clk_ops clk_prcmu_scalable_rate_ops = { |
212 | .is_enabled = clk_prcmu_is_enabled, | 212 | .is_enabled = clk_prcmu_is_enabled, |
213 | .recalc_rate = clk_prcmu_recalc_rate, | 213 | .recalc_rate = clk_prcmu_recalc_rate, |
214 | .round_rate = clk_prcmu_round_rate, | 214 | .round_rate = clk_prcmu_round_rate, |
215 | .set_rate = clk_prcmu_set_rate, | 215 | .set_rate = clk_prcmu_set_rate, |
216 | }; | 216 | }; |
217 | 217 | ||
218 | static struct clk_ops clk_prcmu_rate_ops = { | 218 | static const struct clk_ops clk_prcmu_rate_ops = { |
219 | .is_enabled = clk_prcmu_is_enabled, | 219 | .is_enabled = clk_prcmu_is_enabled, |
220 | .recalc_rate = clk_prcmu_recalc_rate, | 220 | .recalc_rate = clk_prcmu_recalc_rate, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | static struct clk_ops clk_prcmu_opp_gate_ops = { | 223 | static const struct clk_ops clk_prcmu_opp_gate_ops = { |
224 | .prepare = clk_prcmu_opp_prepare, | 224 | .prepare = clk_prcmu_opp_prepare, |
225 | .unprepare = clk_prcmu_opp_unprepare, | 225 | .unprepare = clk_prcmu_opp_unprepare, |
226 | .is_prepared = clk_prcmu_is_prepared, | 226 | .is_prepared = clk_prcmu_is_prepared, |
@@ -230,7 +230,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { | |||
230 | .recalc_rate = clk_prcmu_recalc_rate, | 230 | .recalc_rate = clk_prcmu_recalc_rate, |
231 | }; | 231 | }; |
232 | 232 | ||
233 | static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { | 233 | static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = { |
234 | .prepare = clk_prcmu_opp_volt_prepare, | 234 | .prepare = clk_prcmu_opp_volt_prepare, |
235 | .unprepare = clk_prcmu_opp_volt_unprepare, | 235 | .unprepare = clk_prcmu_opp_volt_unprepare, |
236 | .is_prepared = clk_prcmu_is_prepared, | 236 | .is_prepared = clk_prcmu_is_prepared, |
@@ -247,7 +247,7 @@ static struct clk *clk_reg_prcmu(const char *name, | |||
247 | u8 cg_sel, | 247 | u8 cg_sel, |
248 | unsigned long rate, | 248 | unsigned long rate, |
249 | unsigned long flags, | 249 | unsigned long flags, |
250 | struct clk_ops *clk_prcmu_ops) | 250 | const struct clk_ops *clk_prcmu_ops) |
251 | { | 251 | { |
252 | struct clk_prcmu *clk; | 252 | struct clk_prcmu *clk; |
253 | struct clk_init_data clk_prcmu_init; | 253 | struct clk_init_data clk_prcmu_init; |
diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c index 266ddea630d2..8a4e93ce1e42 100644 --- a/drivers/clk/ux500/clk-sysctrl.c +++ b/drivers/clk/ux500/clk-sysctrl.c | |||
@@ -98,18 +98,18 @@ static u8 clk_sysctrl_get_parent(struct clk_hw *hw) | |||
98 | return clk->parent_index; | 98 | return clk->parent_index; |
99 | } | 99 | } |
100 | 100 | ||
101 | static struct clk_ops clk_sysctrl_gate_ops = { | 101 | static const struct clk_ops clk_sysctrl_gate_ops = { |
102 | .prepare = clk_sysctrl_prepare, | 102 | .prepare = clk_sysctrl_prepare, |
103 | .unprepare = clk_sysctrl_unprepare, | 103 | .unprepare = clk_sysctrl_unprepare, |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { | 106 | static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { |
107 | .prepare = clk_sysctrl_prepare, | 107 | .prepare = clk_sysctrl_prepare, |
108 | .unprepare = clk_sysctrl_unprepare, | 108 | .unprepare = clk_sysctrl_unprepare, |
109 | .recalc_rate = clk_sysctrl_recalc_rate, | 109 | .recalc_rate = clk_sysctrl_recalc_rate, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static struct clk_ops clk_sysctrl_set_parent_ops = { | 112 | static const struct clk_ops clk_sysctrl_set_parent_ops = { |
113 | .set_parent = clk_sysctrl_set_parent, | 113 | .set_parent = clk_sysctrl_set_parent, |
114 | .get_parent = clk_sysctrl_get_parent, | 114 | .get_parent = clk_sysctrl_get_parent, |
115 | }; | 115 | }; |
@@ -124,7 +124,7 @@ static struct clk *clk_reg_sysctrl(struct device *dev, | |||
124 | unsigned long rate, | 124 | unsigned long rate, |
125 | unsigned long enable_delay_us, | 125 | unsigned long enable_delay_us, |
126 | unsigned long flags, | 126 | unsigned long flags, |
127 | struct clk_ops *clk_sysctrl_ops) | 127 | const struct clk_ops *clk_sysctrl_ops) |
128 | { | 128 | { |
129 | struct clk_sysctrl *clk; | 129 | struct clk_sysctrl *clk; |
130 | struct clk_init_data clk_sysctrl_init; | 130 | struct clk_init_data clk_sysctrl_init; |
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 7e5add7d7752..e7a868b83fe5 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c | |||
@@ -61,7 +61,7 @@ static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, | |||
61 | return regmap_write(osc->reg, 0, rate); | 61 | return regmap_write(osc->reg, 0, rate); |
62 | } | 62 | } |
63 | 63 | ||
64 | static struct clk_ops vexpress_osc_ops = { | 64 | static const struct clk_ops vexpress_osc_ops = { |
65 | .recalc_rate = vexpress_osc_recalc_rate, | 65 | .recalc_rate = vexpress_osc_recalc_rate, |
66 | .round_rate = vexpress_osc_round_rate, | 66 | .round_rate = vexpress_osc_round_rate, |
67 | .set_rate = vexpress_osc_set_rate, | 67 | .set_rate = vexpress_osc_set_rate, |
diff --git a/drivers/clk/zte/clk-zx296718.c b/drivers/clk/zte/clk-zx296718.c index 27f853d4c76b..354dd508c516 100644 --- a/drivers/clk/zte/clk-zx296718.c +++ b/drivers/clk/zte/clk-zx296718.c | |||
@@ -451,7 +451,7 @@ static struct zx_clk_fixed_factor top_ffactor_clk[] = { | |||
451 | FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT), | 451 | FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT), |
452 | }; | 452 | }; |
453 | 453 | ||
454 | static struct clk_div_table noc_div_table[] = { | 454 | static const struct clk_div_table noc_div_table[] = { |
455 | { .val = 1, .div = 2, }, | 455 | { .val = 1, .div = 2, }, |
456 | { .val = 3, .div = 4, }, | 456 | { .val = 3, .div = 4, }, |
457 | }; | 457 | }; |
@@ -644,7 +644,7 @@ static int __init top_clocks_init(struct device_node *np) | |||
644 | return 0; | 644 | return 0; |
645 | } | 645 | } |
646 | 646 | ||
647 | static struct clk_div_table common_even_div_table[] = { | 647 | static const struct clk_div_table common_even_div_table[] = { |
648 | { .val = 0, .div = 1, }, | 648 | { .val = 0, .div = 1, }, |
649 | { .val = 1, .div = 2, }, | 649 | { .val = 1, .div = 2, }, |
650 | { .val = 3, .div = 4, }, | 650 | { .val = 3, .div = 4, }, |
@@ -656,7 +656,7 @@ static struct clk_div_table common_even_div_table[] = { | |||
656 | { .val = 15, .div = 16, }, | 656 | { .val = 15, .div = 16, }, |
657 | }; | 657 | }; |
658 | 658 | ||
659 | static struct clk_div_table common_div_table[] = { | 659 | static const struct clk_div_table common_div_table[] = { |
660 | { .val = 0, .div = 1, }, | 660 | { .val = 0, .div = 1, }, |
661 | { .val = 1, .div = 2, }, | 661 | { .val = 1, .div = 2, }, |
662 | { .val = 2, .div = 3, }, | 662 | { .val = 2, .div = 3, }, |
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index 1f5c42254798..75b07cf5eed0 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h | |||
@@ -233,6 +233,8 @@ | |||
233 | #define GCC_PCIE_CLKREF_CLK 216 | 233 | #define GCC_PCIE_CLKREF_CLK 216 |
234 | #define GCC_RX2_USB2_CLKREF_CLK 217 | 234 | #define GCC_RX2_USB2_CLKREF_CLK 217 |
235 | #define GCC_RX1_USB2_CLKREF_CLK 218 | 235 | #define GCC_RX1_USB2_CLKREF_CLK 218 |
236 | #define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 219 | ||
237 | #define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 220 | ||
236 | 238 | ||
237 | #define GCC_SYSTEM_NOC_BCR 0 | 239 | #define GCC_SYSTEM_NOC_BCR 0 |
238 | #define GCC_CONFIG_NOC_BCR 1 | 240 | #define GCC_CONFIG_NOC_BCR 1 |
diff --git a/include/dt-bindings/clock/r8a77995-cpg-mssr.h b/include/dt-bindings/clock/r8a77995-cpg-mssr.h new file mode 100644 index 000000000000..4e8ae3dee590 --- /dev/null +++ b/include/dt-bindings/clock/r8a77995-cpg-mssr.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Glider bvba | ||
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_R8A77995_CPG_MSSR_H__ | ||
10 | #define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ | ||
11 | |||
12 | #include <dt-bindings/clock/renesas-cpg-mssr.h> | ||
13 | |||
14 | /* r8a77995 CPG Core Clocks */ | ||
15 | #define R8A77995_CLK_Z2 0 | ||
16 | #define R8A77995_CLK_ZG 1 | ||
17 | #define R8A77995_CLK_ZTR 2 | ||
18 | #define R8A77995_CLK_ZT 3 | ||
19 | #define R8A77995_CLK_ZX 4 | ||
20 | #define R8A77995_CLK_S0D1 5 | ||
21 | #define R8A77995_CLK_S1D1 6 | ||
22 | #define R8A77995_CLK_S1D2 7 | ||
23 | #define R8A77995_CLK_S1D4 8 | ||
24 | #define R8A77995_CLK_S2D1 9 | ||
25 | #define R8A77995_CLK_S2D2 10 | ||
26 | #define R8A77995_CLK_S2D4 11 | ||
27 | #define R8A77995_CLK_S3D1 12 | ||
28 | #define R8A77995_CLK_S3D2 13 | ||
29 | #define R8A77995_CLK_S3D4 14 | ||
30 | #define R8A77995_CLK_S1D4C 15 | ||
31 | #define R8A77995_CLK_S3D1C 16 | ||
32 | #define R8A77995_CLK_S3D2C 17 | ||
33 | #define R8A77995_CLK_S3D4C 18 | ||
34 | #define R8A77995_CLK_LB 19 | ||
35 | #define R8A77995_CLK_CL 20 | ||
36 | #define R8A77995_CLK_ZB3 21 | ||
37 | #define R8A77995_CLK_ZB3D2 22 | ||
38 | #define R8A77995_CLK_CR 23 | ||
39 | #define R8A77995_CLK_CRD2 24 | ||
40 | #define R8A77995_CLK_SD0H 25 | ||
41 | #define R8A77995_CLK_SD0 26 | ||
42 | #define R8A77995_CLK_SSP2 27 | ||
43 | #define R8A77995_CLK_SSP1 28 | ||
44 | #define R8A77995_CLK_RPC 29 | ||
45 | #define R8A77995_CLK_RPCD2 30 | ||
46 | #define R8A77995_CLK_ZA2 31 | ||
47 | #define R8A77995_CLK_ZA8 32 | ||
48 | #define R8A77995_CLK_Z2D 33 | ||
49 | #define R8A77995_CLK_CANFD 34 | ||
50 | #define R8A77995_CLK_MSO 35 | ||
51 | #define R8A77995_CLK_R 36 | ||
52 | #define R8A77995_CLK_OSC 37 | ||
53 | #define R8A77995_CLK_LV0 38 | ||
54 | #define R8A77995_CLK_LV1 39 | ||
55 | #define R8A77995_CLK_CP 40 | ||
56 | |||
57 | #endif /* __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ */ | ||
diff --git a/include/dt-bindings/clock/rk3228-cru.h b/include/dt-bindings/clock/rk3228-cru.h index 56f841c22801..55655ab0a4c4 100644 --- a/include/dt-bindings/clock/rk3228-cru.h +++ b/include/dt-bindings/clock/rk3228-cru.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #define SCLK_EMMC_DRV 117 | 49 | #define SCLK_EMMC_DRV 117 |
50 | #define SCLK_SDMMC_SAMPLE 118 | 50 | #define SCLK_SDMMC_SAMPLE 118 |
51 | #define SCLK_SDIO_SAMPLE 119 | 51 | #define SCLK_SDIO_SAMPLE 119 |
52 | #define SCLK_SDIO_SRC 120 | ||
52 | #define SCLK_EMMC_SAMPLE 121 | 53 | #define SCLK_EMMC_SAMPLE 121 |
53 | #define SCLK_VOP 122 | 54 | #define SCLK_VOP 122 |
54 | #define SCLK_HDMI_HDCP 123 | 55 | #define SCLK_HDMI_HDCP 123 |
diff --git a/include/dt-bindings/clock/rv1108-cru.h b/include/dt-bindings/clock/rv1108-cru.h index f269d833e41a..d8d0e0456dc2 100644 --- a/include/dt-bindings/clock/rv1108-cru.h +++ b/include/dt-bindings/clock/rv1108-cru.h | |||
@@ -67,9 +67,9 @@ | |||
67 | #define SCLK_SPI 108 | 67 | #define SCLK_SPI 108 |
68 | #define SCLK_SARADC 109 | 68 | #define SCLK_SARADC 109 |
69 | #define SCLK_TSADC 110 | 69 | #define SCLK_TSADC 110 |
70 | #define SCLK_MACPHY_PRE 111 | 70 | #define SCLK_MAC_PRE 111 |
71 | #define SCLK_MACPHY 112 | 71 | #define SCLK_MAC 112 |
72 | #define SCLK_MACPHY_RX 113 | 72 | #define SCLK_MAC_RX 113 |
73 | #define SCLK_MAC_REF 114 | 73 | #define SCLK_MAC_REF 114 |
74 | #define SCLK_MAC_REFOUT 115 | 74 | #define SCLK_MAC_REFOUT 115 |
75 | #define SCLK_DSP_PFM 116 | 75 | #define SCLK_DSP_PFM 116 |
@@ -110,6 +110,7 @@ | |||
110 | #define ACLK_CIF2 207 | 110 | #define ACLK_CIF2 207 |
111 | #define ACLK_CIF3 208 | 111 | #define ACLK_CIF3 208 |
112 | #define ACLK_PERI 209 | 112 | #define ACLK_PERI 209 |
113 | #define ACLK_GMAC 210 | ||
113 | 114 | ||
114 | /* pclk gates */ | 115 | /* pclk gates */ |
115 | #define PCLK_GPIO1 256 | 116 | #define PCLK_GPIO1 256 |
@@ -141,6 +142,7 @@ | |||
141 | #define PCLK_EFUSE0 282 | 142 | #define PCLK_EFUSE0 282 |
142 | #define PCLK_EFUSE1 283 | 143 | #define PCLK_EFUSE1 283 |
143 | #define PCLK_WDT 284 | 144 | #define PCLK_WDT 284 |
145 | #define PCLK_GMAC 285 | ||
144 | 146 | ||
145 | /* hclk gates */ | 147 | /* hclk gates */ |
146 | #define HCLK_I2S0_8CH 320 | 148 | #define HCLK_I2S0_8CH 320 |
diff --git a/include/dt-bindings/clock/stm32h7-clks.h b/include/dt-bindings/clock/stm32h7-clks.h new file mode 100644 index 000000000000..6637272b3242 --- /dev/null +++ b/include/dt-bindings/clock/stm32h7-clks.h | |||
@@ -0,0 +1,165 @@ | |||
1 | /* SYS, CORE AND BUS CLOCKS */ | ||
2 | #define SYS_D1CPRE 0 | ||
3 | #define HCLK 1 | ||
4 | #define PCLK1 2 | ||
5 | #define PCLK2 3 | ||
6 | #define PCLK3 4 | ||
7 | #define PCLK4 5 | ||
8 | #define HSI_DIV 6 | ||
9 | #define HSE_1M 7 | ||
10 | #define I2S_CKIN 8 | ||
11 | #define CK_DSI_PHY 9 | ||
12 | #define HSE_CK 10 | ||
13 | #define LSE_CK 11 | ||
14 | #define CSI_KER_DIV122 12 | ||
15 | #define RTC_CK 13 | ||
16 | #define CPU_SYSTICK 14 | ||
17 | |||
18 | /* OSCILLATOR BANK */ | ||
19 | #define OSC_BANK 18 | ||
20 | #define HSI_CK 18 | ||
21 | #define HSI_KER_CK 19 | ||
22 | #define CSI_CK 20 | ||
23 | #define CSI_KER_CK 21 | ||
24 | #define RC48_CK 22 | ||
25 | #define LSI_CK 23 | ||
26 | |||
27 | /* MCLOCK BANK */ | ||
28 | #define MCLK_BANK 28 | ||
29 | #define PER_CK 28 | ||
30 | #define PLLSRC 29 | ||
31 | #define SYS_CK 30 | ||
32 | #define TRACEIN_CK 31 | ||
33 | |||
34 | /* ODF BANK */ | ||
35 | #define ODF_BANK 32 | ||
36 | #define PLL1_P 32 | ||
37 | #define PLL1_Q 33 | ||
38 | #define PLL1_R 34 | ||
39 | #define PLL2_P 35 | ||
40 | #define PLL2_Q 36 | ||
41 | #define PLL2_R 37 | ||
42 | #define PLL3_P 38 | ||
43 | #define PLL3_Q 39 | ||
44 | #define PLL3_R 40 | ||
45 | |||
46 | /* MCO BANK */ | ||
47 | #define MCO_BANK 41 | ||
48 | #define MCO1 41 | ||
49 | #define MCO2 42 | ||
50 | |||
51 | /* PERIF BANK */ | ||
52 | #define PERIF_BANK 50 | ||
53 | #define D1SRAM1_CK 50 | ||
54 | #define ITCM_CK 51 | ||
55 | #define DTCM2_CK 52 | ||
56 | #define DTCM1_CK 53 | ||
57 | #define FLITF_CK 54 | ||
58 | #define JPGDEC_CK 55 | ||
59 | #define DMA2D_CK 56 | ||
60 | #define MDMA_CK 57 | ||
61 | #define USB2ULPI_CK 58 | ||
62 | #define USB1ULPI_CK 59 | ||
63 | #define ETH1RX_CK 60 | ||
64 | #define ETH1TX_CK 61 | ||
65 | #define ETH1MAC_CK 62 | ||
66 | #define ART_CK 63 | ||
67 | #define DMA2_CK 64 | ||
68 | #define DMA1_CK 65 | ||
69 | #define D2SRAM3_CK 66 | ||
70 | #define D2SRAM2_CK 67 | ||
71 | #define D2SRAM1_CK 68 | ||
72 | #define HASH_CK 69 | ||
73 | #define CRYPT_CK 70 | ||
74 | #define CAMITF_CK 71 | ||
75 | #define BKPRAM_CK 72 | ||
76 | #define HSEM_CK 73 | ||
77 | #define BDMA_CK 74 | ||
78 | #define CRC_CK 75 | ||
79 | #define GPIOK_CK 76 | ||
80 | #define GPIOJ_CK 77 | ||
81 | #define GPIOI_CK 78 | ||
82 | #define GPIOH_CK 79 | ||
83 | #define GPIOG_CK 80 | ||
84 | #define GPIOF_CK 81 | ||
85 | #define GPIOE_CK 82 | ||
86 | #define GPIOD_CK 83 | ||
87 | #define GPIOC_CK 84 | ||
88 | #define GPIOB_CK 85 | ||
89 | #define GPIOA_CK 86 | ||
90 | #define WWDG1_CK 87 | ||
91 | #define DAC12_CK 88 | ||
92 | #define WWDG2_CK 89 | ||
93 | #define TIM14_CK 90 | ||
94 | #define TIM13_CK 91 | ||
95 | #define TIM12_CK 92 | ||
96 | #define TIM7_CK 93 | ||
97 | #define TIM6_CK 94 | ||
98 | #define TIM5_CK 95 | ||
99 | #define TIM4_CK 96 | ||
100 | #define TIM3_CK 97 | ||
101 | #define TIM2_CK 98 | ||
102 | #define MDIOS_CK 99 | ||
103 | #define OPAMP_CK 100 | ||
104 | #define CRS_CK 101 | ||
105 | #define TIM17_CK 102 | ||
106 | #define TIM16_CK 103 | ||
107 | #define TIM15_CK 104 | ||
108 | #define TIM8_CK 105 | ||
109 | #define TIM1_CK 106 | ||
110 | #define TMPSENS_CK 107 | ||
111 | #define RTCAPB_CK 108 | ||
112 | #define VREF_CK 109 | ||
113 | #define COMP12_CK 110 | ||
114 | #define SYSCFG_CK 111 | ||
115 | |||
116 | /* KERNEL BANK */ | ||
117 | #define KERN_BANK 120 | ||
118 | #define SDMMC1_CK 120 | ||
119 | #define QUADSPI_CK 121 | ||
120 | #define FMC_CK 122 | ||
121 | #define USB2OTG_CK 123 | ||
122 | #define USB1OTG_CK 124 | ||
123 | #define ADC12_CK 125 | ||
124 | #define SDMMC2_CK 126 | ||
125 | #define RNG_CK 127 | ||
126 | #define ADC3_CK 128 | ||
127 | #define DSI_CK 129 | ||
128 | #define LTDC_CK 130 | ||
129 | #define USART8_CK 131 | ||
130 | #define USART7_CK 132 | ||
131 | #define HDMICEC_CK 133 | ||
132 | #define I2C3_CK 134 | ||
133 | #define I2C2_CK 135 | ||
134 | #define I2C1_CK 136 | ||
135 | #define UART5_CK 137 | ||
136 | #define UART4_CK 138 | ||
137 | #define USART3_CK 139 | ||
138 | #define USART2_CK 140 | ||
139 | #define SPDIFRX_CK 141 | ||
140 | #define SPI3_CK 142 | ||
141 | #define SPI2_CK 143 | ||
142 | #define LPTIM1_CK 144 | ||
143 | #define FDCAN_CK 145 | ||
144 | #define SWP_CK 146 | ||
145 | #define HRTIM_CK 147 | ||
146 | #define DFSDM1_CK 148 | ||
147 | #define SAI3_CK 149 | ||
148 | #define SAI2_CK 150 | ||
149 | #define SAI1_CK 151 | ||
150 | #define SPI5_CK 152 | ||
151 | #define SPI4_CK 153 | ||
152 | #define SPI1_CK 154 | ||
153 | #define USART6_CK 155 | ||
154 | #define USART1_CK 156 | ||
155 | #define SAI4B_CK 157 | ||
156 | #define SAI4A_CK 158 | ||
157 | #define LPTIM5_CK 159 | ||
158 | #define LPTIM4_CK 160 | ||
159 | #define LPTIM3_CK 161 | ||
160 | #define LPTIM2_CK 162 | ||
161 | #define I2C4_CK 163 | ||
162 | #define SPI6_CK 164 | ||
163 | #define LPUART1_CK 165 | ||
164 | |||
165 | #define STM32H7_MAX_CLKS 166 | ||
diff --git a/include/dt-bindings/clock/sun4i-a10-ccu.h b/include/dt-bindings/clock/sun4i-a10-ccu.h new file mode 100644 index 000000000000..c5a53f38d654 --- /dev/null +++ b/include/dt-bindings/clock/sun4i-a10-ccu.h | |||
@@ -0,0 +1,200 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Priit Laes <plaes@plaes.org> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
39 | * OTHER DEALINGS IN THE SOFTWARE. | ||
40 | */ | ||
41 | |||
42 | #ifndef _DT_BINDINGS_CLK_SUN4I_A10_H_ | ||
43 | #define _DT_BINDINGS_CLK_SUN4I_A10_H_ | ||
44 | |||
45 | #define CLK_HOSC 1 | ||
46 | #define CLK_CPU 20 | ||
47 | |||
48 | /* AHB Gates */ | ||
49 | #define CLK_AHB_OTG 26 | ||
50 | #define CLK_AHB_EHCI0 27 | ||
51 | #define CLK_AHB_OHCI0 28 | ||
52 | #define CLK_AHB_EHCI1 29 | ||
53 | #define CLK_AHB_OHCI1 30 | ||
54 | #define CLK_AHB_SS 31 | ||
55 | #define CLK_AHB_DMA 32 | ||
56 | #define CLK_AHB_BIST 33 | ||
57 | #define CLK_AHB_MMC0 34 | ||
58 | #define CLK_AHB_MMC1 35 | ||
59 | #define CLK_AHB_MMC2 36 | ||
60 | #define CLK_AHB_MMC3 37 | ||
61 | #define CLK_AHB_MS 38 | ||
62 | #define CLK_AHB_NAND 39 | ||
63 | #define CLK_AHB_SDRAM 40 | ||
64 | #define CLK_AHB_ACE 41 | ||
65 | #define CLK_AHB_EMAC 42 | ||
66 | #define CLK_AHB_TS 43 | ||
67 | #define CLK_AHB_SPI0 44 | ||
68 | #define CLK_AHB_SPI1 45 | ||
69 | #define CLK_AHB_SPI2 46 | ||
70 | #define CLK_AHB_SPI3 47 | ||
71 | #define CLK_AHB_PATA 48 | ||
72 | #define CLK_AHB_SATA 49 | ||
73 | #define CLK_AHB_GPS 50 | ||
74 | #define CLK_AHB_HSTIMER 51 | ||
75 | #define CLK_AHB_VE 52 | ||
76 | #define CLK_AHB_TVD 53 | ||
77 | #define CLK_AHB_TVE0 54 | ||
78 | #define CLK_AHB_TVE1 55 | ||
79 | #define CLK_AHB_LCD0 56 | ||
80 | #define CLK_AHB_LCD1 57 | ||
81 | #define CLK_AHB_CSI0 58 | ||
82 | #define CLK_AHB_CSI1 59 | ||
83 | #define CLK_AHB_HDMI0 60 | ||
84 | #define CLK_AHB_HDMI1 61 | ||
85 | #define CLK_AHB_DE_BE0 62 | ||
86 | #define CLK_AHB_DE_BE1 63 | ||
87 | #define CLK_AHB_DE_FE0 64 | ||
88 | #define CLK_AHB_DE_FE1 65 | ||
89 | #define CLK_AHB_GMAC 66 | ||
90 | #define CLK_AHB_MP 67 | ||
91 | #define CLK_AHB_GPU 68 | ||
92 | |||
93 | /* APB0 Gates */ | ||
94 | #define CLK_APB0_CODEC 69 | ||
95 | #define CLK_APB0_SPDIF 70 | ||
96 | #define CLK_APB0_I2S0 71 | ||
97 | #define CLK_APB0_AC97 72 | ||
98 | #define CLK_APB0_I2S1 73 | ||
99 | #define CLK_APB0_PIO 74 | ||
100 | #define CLK_APB0_IR0 75 | ||
101 | #define CLK_APB0_IR1 76 | ||
102 | #define CLK_APB0_I2S2 77 | ||
103 | #define CLK_APB0_KEYPAD 78 | ||
104 | |||
105 | /* APB1 Gates */ | ||
106 | #define CLK_APB1_I2C0 79 | ||
107 | #define CLK_APB1_I2C1 80 | ||
108 | #define CLK_APB1_I2C2 81 | ||
109 | #define CLK_APB1_I2C3 82 | ||
110 | #define CLK_APB1_CAN 83 | ||
111 | #define CLK_APB1_SCR 84 | ||
112 | #define CLK_APB1_PS20 85 | ||
113 | #define CLK_APB1_PS21 86 | ||
114 | #define CLK_APB1_I2C4 87 | ||
115 | #define CLK_APB1_UART0 88 | ||
116 | #define CLK_APB1_UART1 89 | ||
117 | #define CLK_APB1_UART2 90 | ||
118 | #define CLK_APB1_UART3 91 | ||
119 | #define CLK_APB1_UART4 92 | ||
120 | #define CLK_APB1_UART5 93 | ||
121 | #define CLK_APB1_UART6 94 | ||
122 | #define CLK_APB1_UART7 95 | ||
123 | |||
124 | /* IP clocks */ | ||
125 | #define CLK_NAND 96 | ||
126 | #define CLK_MS 97 | ||
127 | #define CLK_MMC0 98 | ||
128 | #define CLK_MMC0_OUTPUT 99 | ||
129 | #define CLK_MMC0_SAMPLE 100 | ||
130 | #define CLK_MMC1 101 | ||
131 | #define CLK_MMC1_OUTPUT 102 | ||
132 | #define CLK_MMC1_SAMPLE 103 | ||
133 | #define CLK_MMC2 104 | ||
134 | #define CLK_MMC2_OUTPUT 105 | ||
135 | #define CLK_MMC2_SAMPLE 106 | ||
136 | #define CLK_MMC3 107 | ||
137 | #define CLK_MMC3_OUTPUT 108 | ||
138 | #define CLK_MMC3_SAMPLE 109 | ||
139 | #define CLK_TS 110 | ||
140 | #define CLK_SS 111 | ||
141 | #define CLK_SPI0 112 | ||
142 | #define CLK_SPI1 113 | ||
143 | #define CLK_SPI2 114 | ||
144 | #define CLK_PATA 115 | ||
145 | #define CLK_IR0 116 | ||
146 | #define CLK_IR1 117 | ||
147 | #define CLK_I2S0 118 | ||
148 | #define CLK_AC97 119 | ||
149 | #define CLK_SPDIF 120 | ||
150 | #define CLK_KEYPAD 121 | ||
151 | #define CLK_SATA 122 | ||
152 | #define CLK_USB_OHCI0 123 | ||
153 | #define CLK_USB_OHCI1 124 | ||
154 | #define CLK_USB_PHY 125 | ||
155 | #define CLK_GPS 126 | ||
156 | #define CLK_SPI3 127 | ||
157 | #define CLK_I2S1 128 | ||
158 | #define CLK_I2S2 129 | ||
159 | |||
160 | /* DRAM Gates */ | ||
161 | #define CLK_DRAM_VE 130 | ||
162 | #define CLK_DRAM_CSI0 131 | ||
163 | #define CLK_DRAM_CSI1 132 | ||
164 | #define CLK_DRAM_TS 133 | ||
165 | #define CLK_DRAM_TVD 134 | ||
166 | #define CLK_DRAM_TVE0 135 | ||
167 | #define CLK_DRAM_TVE1 136 | ||
168 | #define CLK_DRAM_OUT 137 | ||
169 | #define CLK_DRAM_DE_FE1 138 | ||
170 | #define CLK_DRAM_DE_FE0 139 | ||
171 | #define CLK_DRAM_DE_BE0 140 | ||
172 | #define CLK_DRAM_DE_BE1 141 | ||
173 | #define CLK_DRAM_MP 142 | ||
174 | #define CLK_DRAM_ACE 143 | ||
175 | |||
176 | /* Display Engine Clocks */ | ||
177 | #define CLK_DE_BE0 144 | ||
178 | #define CLK_DE_BE1 145 | ||
179 | #define CLK_DE_FE0 146 | ||
180 | #define CLK_DE_FE1 147 | ||
181 | #define CLK_DE_MP 148 | ||
182 | #define CLK_TCON0_CH0 149 | ||
183 | #define CLK_TCON1_CH0 150 | ||
184 | #define CLK_CSI_SCLK 151 | ||
185 | #define CLK_TVD_SCLK2 152 | ||
186 | #define CLK_TVD 153 | ||
187 | #define CLK_TCON0_CH1_SCLK2 154 | ||
188 | #define CLK_TCON0_CH1 155 | ||
189 | #define CLK_TCON1_CH1_SCLK2 156 | ||
190 | #define CLK_TCON1_CH1 157 | ||
191 | #define CLK_CSI0 158 | ||
192 | #define CLK_CSI1 159 | ||
193 | #define CLK_CODEC 160 | ||
194 | #define CLK_VE 161 | ||
195 | #define CLK_AVS 162 | ||
196 | #define CLK_ACE 163 | ||
197 | #define CLK_HDMI 164 | ||
198 | #define CLK_GPU 165 | ||
199 | |||
200 | #endif /* _DT_BINDINGS_CLK_SUN4I_A10_H_ */ | ||
diff --git a/include/dt-bindings/clock/sun7i-a20-ccu.h b/include/dt-bindings/clock/sun7i-a20-ccu.h new file mode 100644 index 000000000000..045a5178da0c --- /dev/null +++ b/include/dt-bindings/clock/sun7i-a20-ccu.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Priit Laes <plaes@plaes.org> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
39 | * OTHER DEALINGS IN THE SOFTWARE. | ||
40 | */ | ||
41 | |||
42 | #ifndef _DT_BINDINGS_CLK_SUN7I_A20_H_ | ||
43 | #define _DT_BINDINGS_CLK_SUN7I_A20_H_ | ||
44 | |||
45 | #include <dt-bindings/clock/sun4i-a10-ccu.h> | ||
46 | |||
47 | #define CLK_MBUS 166 | ||
48 | #define CLK_HDMI1_SLOW 167 | ||
49 | #define CLK_HDMI1 168 | ||
50 | #define CLK_OUT_A 169 | ||
51 | #define CLK_OUT_B 170 | ||
52 | |||
53 | #endif /* _DT_BINDINGS_CLK_SUN7I_A20_H_ */ | ||
diff --git a/include/dt-bindings/clock/sun8i-r40-ccu.h b/include/dt-bindings/clock/sun8i-r40-ccu.h new file mode 100644 index 000000000000..4fa5f69fc297 --- /dev/null +++ b/include/dt-bindings/clock/sun8i-r40-ccu.h | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_ | ||
44 | #define _DT_BINDINGS_CLK_SUN8I_R40_H_ | ||
45 | |||
46 | #define CLK_CPU 24 | ||
47 | |||
48 | #define CLK_BUS_MIPI_DSI 29 | ||
49 | #define CLK_BUS_CE 30 | ||
50 | #define CLK_BUS_DMA 31 | ||
51 | #define CLK_BUS_MMC0 32 | ||
52 | #define CLK_BUS_MMC1 33 | ||
53 | #define CLK_BUS_MMC2 34 | ||
54 | #define CLK_BUS_MMC3 35 | ||
55 | #define CLK_BUS_NAND 36 | ||
56 | #define CLK_BUS_DRAM 37 | ||
57 | #define CLK_BUS_EMAC 38 | ||
58 | #define CLK_BUS_TS 39 | ||
59 | #define CLK_BUS_HSTIMER 40 | ||
60 | #define CLK_BUS_SPI0 41 | ||
61 | #define CLK_BUS_SPI1 42 | ||
62 | #define CLK_BUS_SPI2 43 | ||
63 | #define CLK_BUS_SPI3 44 | ||
64 | #define CLK_BUS_SATA 45 | ||
65 | #define CLK_BUS_OTG 46 | ||
66 | #define CLK_BUS_EHCI0 47 | ||
67 | #define CLK_BUS_EHCI1 48 | ||
68 | #define CLK_BUS_EHCI2 49 | ||
69 | #define CLK_BUS_OHCI0 50 | ||
70 | #define CLK_BUS_OHCI1 51 | ||
71 | #define CLK_BUS_OHCI2 52 | ||
72 | #define CLK_BUS_VE 53 | ||
73 | #define CLK_BUS_MP 54 | ||
74 | #define CLK_BUS_DEINTERLACE 55 | ||
75 | #define CLK_BUS_CSI0 56 | ||
76 | #define CLK_BUS_CSI1 57 | ||
77 | #define CLK_BUS_HDMI1 58 | ||
78 | #define CLK_BUS_HDMI0 59 | ||
79 | #define CLK_BUS_DE 60 | ||
80 | #define CLK_BUS_TVE0 61 | ||
81 | #define CLK_BUS_TVE1 62 | ||
82 | #define CLK_BUS_TVE_TOP 63 | ||
83 | #define CLK_BUS_GMAC 64 | ||
84 | #define CLK_BUS_GPU 65 | ||
85 | #define CLK_BUS_TVD0 66 | ||
86 | #define CLK_BUS_TVD1 67 | ||
87 | #define CLK_BUS_TVD2 68 | ||
88 | #define CLK_BUS_TVD3 69 | ||
89 | #define CLK_BUS_TVD_TOP 70 | ||
90 | #define CLK_BUS_TCON_LCD0 71 | ||
91 | #define CLK_BUS_TCON_LCD1 72 | ||
92 | #define CLK_BUS_TCON_TV0 73 | ||
93 | #define CLK_BUS_TCON_TV1 74 | ||
94 | #define CLK_BUS_TCON_TOP 75 | ||
95 | #define CLK_BUS_CODEC 76 | ||
96 | #define CLK_BUS_SPDIF 77 | ||
97 | #define CLK_BUS_AC97 78 | ||
98 | #define CLK_BUS_PIO 79 | ||
99 | #define CLK_BUS_IR0 80 | ||
100 | #define CLK_BUS_IR1 81 | ||
101 | #define CLK_BUS_THS 82 | ||
102 | #define CLK_BUS_KEYPAD 83 | ||
103 | #define CLK_BUS_I2S0 84 | ||
104 | #define CLK_BUS_I2S1 85 | ||
105 | #define CLK_BUS_I2S2 86 | ||
106 | #define CLK_BUS_I2C0 87 | ||
107 | #define CLK_BUS_I2C1 88 | ||
108 | #define CLK_BUS_I2C2 89 | ||
109 | #define CLK_BUS_I2C3 90 | ||
110 | #define CLK_BUS_CAN 91 | ||
111 | #define CLK_BUS_SCR 92 | ||
112 | #define CLK_BUS_PS20 93 | ||
113 | #define CLK_BUS_PS21 94 | ||
114 | #define CLK_BUS_I2C4 95 | ||
115 | #define CLK_BUS_UART0 96 | ||
116 | #define CLK_BUS_UART1 97 | ||
117 | #define CLK_BUS_UART2 98 | ||
118 | #define CLK_BUS_UART3 99 | ||
119 | #define CLK_BUS_UART4 100 | ||
120 | #define CLK_BUS_UART5 101 | ||
121 | #define CLK_BUS_UART6 102 | ||
122 | #define CLK_BUS_UART7 103 | ||
123 | #define CLK_BUS_DBG 104 | ||
124 | |||
125 | #define CLK_THS 105 | ||
126 | #define CLK_NAND 106 | ||
127 | #define CLK_MMC0 107 | ||
128 | #define CLK_MMC1 108 | ||
129 | #define CLK_MMC2 109 | ||
130 | #define CLK_MMC3 110 | ||
131 | #define CLK_TS 111 | ||
132 | #define CLK_CE 112 | ||
133 | #define CLK_SPI0 113 | ||
134 | #define CLK_SPI1 114 | ||
135 | #define CLK_SPI2 115 | ||
136 | #define CLK_SPI3 116 | ||
137 | #define CLK_I2S0 117 | ||
138 | #define CLK_I2S1 118 | ||
139 | #define CLK_I2S2 119 | ||
140 | #define CLK_AC97 120 | ||
141 | #define CLK_SPDIF 121 | ||
142 | #define CLK_KEYPAD 122 | ||
143 | #define CLK_SATA 123 | ||
144 | #define CLK_USB_PHY0 124 | ||
145 | #define CLK_USB_PHY1 125 | ||
146 | #define CLK_USB_PHY2 126 | ||
147 | #define CLK_USB_OHCI0 127 | ||
148 | #define CLK_USB_OHCI1 128 | ||
149 | #define CLK_USB_OHCI2 129 | ||
150 | #define CLK_IR0 130 | ||
151 | #define CLK_IR1 131 | ||
152 | |||
153 | #define CLK_DRAM_VE 133 | ||
154 | #define CLK_DRAM_CSI0 134 | ||
155 | #define CLK_DRAM_CSI1 135 | ||
156 | #define CLK_DRAM_TS 136 | ||
157 | #define CLK_DRAM_TVD 137 | ||
158 | #define CLK_DRAM_MP 138 | ||
159 | #define CLK_DRAM_DEINTERLACE 139 | ||
160 | #define CLK_DE 140 | ||
161 | #define CLK_MP 141 | ||
162 | #define CLK_TCON_LCD0 142 | ||
163 | #define CLK_TCON_LCD1 143 | ||
164 | #define CLK_TCON_TV0 144 | ||
165 | #define CLK_TCON_TV1 145 | ||
166 | #define CLK_DEINTERLACE 146 | ||
167 | #define CLK_CSI1_MCLK 147 | ||
168 | #define CLK_CSI_SCLK 148 | ||
169 | #define CLK_CSI0_MCLK 149 | ||
170 | #define CLK_VE 150 | ||
171 | #define CLK_CODEC 151 | ||
172 | #define CLK_AVS 152 | ||
173 | #define CLK_HDMI 153 | ||
174 | #define CLK_HDMI_SLOW 154 | ||
175 | |||
176 | #define CLK_DSI_DPHY 156 | ||
177 | #define CLK_TVE0 157 | ||
178 | #define CLK_TVE1 158 | ||
179 | #define CLK_TVD0 159 | ||
180 | #define CLK_TVD1 160 | ||
181 | #define CLK_TVD2 161 | ||
182 | #define CLK_TVD3 162 | ||
183 | #define CLK_GPU 163 | ||
184 | #define CLK_OUTA 164 | ||
185 | #define CLK_OUTB 165 | ||
186 | |||
187 | #endif /* _DT_BINDINGS_CLK_SUN8I_R40_H_ */ | ||
diff --git a/include/dt-bindings/mfd/stm32h7-rcc.h b/include/dt-bindings/mfd/stm32h7-rcc.h new file mode 100644 index 000000000000..461a8e04453a --- /dev/null +++ b/include/dt-bindings/mfd/stm32h7-rcc.h | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * This header provides constants for the STM32H7 RCC IP | ||
3 | */ | ||
4 | |||
5 | #ifndef _DT_BINDINGS_MFD_STM32H7_RCC_H | ||
6 | #define _DT_BINDINGS_MFD_STM32H7_RCC_H | ||
7 | |||
8 | /* AHB3 */ | ||
9 | #define STM32H7_RCC_AHB3_MDMA 0 | ||
10 | #define STM32H7_RCC_AHB3_DMA2D 4 | ||
11 | #define STM32H7_RCC_AHB3_JPGDEC 5 | ||
12 | #define STM32H7_RCC_AHB3_FMC 12 | ||
13 | #define STM32H7_RCC_AHB3_QUADSPI 14 | ||
14 | #define STM32H7_RCC_AHB3_SDMMC1 16 | ||
15 | #define STM32H7_RCC_AHB3_CPU 31 | ||
16 | |||
17 | #define STM32H7_AHB3_RESET(bit) (STM32H7_RCC_AHB3_##bit + (0x7C * 8)) | ||
18 | |||
19 | /* AHB1 */ | ||
20 | #define STM32H7_RCC_AHB1_DMA1 0 | ||
21 | #define STM32H7_RCC_AHB1_DMA2 1 | ||
22 | #define STM32H7_RCC_AHB1_ADC12 5 | ||
23 | #define STM32H7_RCC_AHB1_ART 14 | ||
24 | #define STM32H7_RCC_AHB1_ETH1MAC 15 | ||
25 | #define STM32H7_RCC_AHB1_USB1OTG 25 | ||
26 | #define STM32H7_RCC_AHB1_USB2OTG 27 | ||
27 | |||
28 | #define STM32H7_AHB1_RESET(bit) (STM32H7_RCC_AHB1_##bit + (0x80 * 8)) | ||
29 | |||
30 | /* AHB2 */ | ||
31 | #define STM32H7_RCC_AHB2_CAMITF 0 | ||
32 | #define STM32H7_RCC_AHB2_CRYPT 4 | ||
33 | #define STM32H7_RCC_AHB2_HASH 5 | ||
34 | #define STM32H7_RCC_AHB2_RNG 6 | ||
35 | #define STM32H7_RCC_AHB2_SDMMC2 9 | ||
36 | |||
37 | #define STM32H7_AHB2_RESET(bit) (STM32H7_RCC_AHB2_##bit + (0x84 * 8)) | ||
38 | |||
39 | /* AHB4 */ | ||
40 | #define STM32H7_RCC_AHB4_GPIOA 0 | ||
41 | #define STM32H7_RCC_AHB4_GPIOB 1 | ||
42 | #define STM32H7_RCC_AHB4_GPIOC 2 | ||
43 | #define STM32H7_RCC_AHB4_GPIOD 3 | ||
44 | #define STM32H7_RCC_AHB4_GPIOE 4 | ||
45 | #define STM32H7_RCC_AHB4_GPIOF 5 | ||
46 | #define STM32H7_RCC_AHB4_GPIOG 6 | ||
47 | #define STM32H7_RCC_AHB4_GPIOH 7 | ||
48 | #define STM32H7_RCC_AHB4_GPIOI 8 | ||
49 | #define STM32H7_RCC_AHB4_GPIOJ 9 | ||
50 | #define STM32H7_RCC_AHB4_GPIOK 10 | ||
51 | #define STM32H7_RCC_AHB4_CRC 19 | ||
52 | #define STM32H7_RCC_AHB4_BDMA 21 | ||
53 | #define STM32H7_RCC_AHB4_ADC3 24 | ||
54 | #define STM32H7_RCC_AHB4_HSEM 25 | ||
55 | |||
56 | #define STM32H7_AHB4_RESET(bit) (STM32H7_RCC_AHB4_##bit + (0x88 * 8)) | ||
57 | |||
58 | /* APB3 */ | ||
59 | #define STM32H7_RCC_APB3_LTDC 3 | ||
60 | #define STM32H7_RCC_APB3_DSI 4 | ||
61 | |||
62 | #define STM32H7_APB3_RESET(bit) (STM32H7_RCC_APB3_##bit + (0x8C * 8)) | ||
63 | |||
64 | /* APB1L */ | ||
65 | #define STM32H7_RCC_APB1L_TIM2 0 | ||
66 | #define STM32H7_RCC_APB1L_TIM3 1 | ||
67 | #define STM32H7_RCC_APB1L_TIM4 2 | ||
68 | #define STM32H7_RCC_APB1L_TIM5 3 | ||
69 | #define STM32H7_RCC_APB1L_TIM6 4 | ||
70 | #define STM32H7_RCC_APB1L_TIM7 5 | ||
71 | #define STM32H7_RCC_APB1L_TIM12 6 | ||
72 | #define STM32H7_RCC_APB1L_TIM13 7 | ||
73 | #define STM32H7_RCC_APB1L_TIM14 8 | ||
74 | #define STM32H7_RCC_APB1L_LPTIM1 9 | ||
75 | #define STM32H7_RCC_APB1L_SPI2 14 | ||
76 | #define STM32H7_RCC_APB1L_SPI3 15 | ||
77 | #define STM32H7_RCC_APB1L_SPDIF_RX 16 | ||
78 | #define STM32H7_RCC_APB1L_USART2 17 | ||
79 | #define STM32H7_RCC_APB1L_USART3 18 | ||
80 | #define STM32H7_RCC_APB1L_UART4 19 | ||
81 | #define STM32H7_RCC_APB1L_UART5 20 | ||
82 | #define STM32H7_RCC_APB1L_I2C1 21 | ||
83 | #define STM32H7_RCC_APB1L_I2C2 22 | ||
84 | #define STM32H7_RCC_APB1L_I2C3 23 | ||
85 | #define STM32H7_RCC_APB1L_HDMICEC 27 | ||
86 | #define STM32H7_RCC_APB1L_DAC12 29 | ||
87 | #define STM32H7_RCC_APB1L_USART7 30 | ||
88 | #define STM32H7_RCC_APB1L_USART8 31 | ||
89 | |||
90 | #define STM32H7_APB1L_RESET(bit) (STM32H7_RCC_APB1L_##bit + (0x90 * 8)) | ||
91 | |||
92 | /* APB1H */ | ||
93 | #define STM32H7_RCC_APB1H_CRS 1 | ||
94 | #define STM32H7_RCC_APB1H_SWP 2 | ||
95 | #define STM32H7_RCC_APB1H_OPAMP 4 | ||
96 | #define STM32H7_RCC_APB1H_MDIOS 5 | ||
97 | #define STM32H7_RCC_APB1H_FDCAN 8 | ||
98 | |||
99 | #define STM32H7_APB1H_RESET(bit) (STM32H7_RCC_APB1H_##bit + (0x94 * 8)) | ||
100 | |||
101 | /* APB2 */ | ||
102 | #define STM32H7_RCC_APB2_TIM1 0 | ||
103 | #define STM32H7_RCC_APB2_TIM8 1 | ||
104 | #define STM32H7_RCC_APB2_USART1 4 | ||
105 | #define STM32H7_RCC_APB2_USART6 5 | ||
106 | #define STM32H7_RCC_APB2_SPI1 12 | ||
107 | #define STM32H7_RCC_APB2_SPI4 13 | ||
108 | #define STM32H7_RCC_APB2_TIM15 16 | ||
109 | #define STM32H7_RCC_APB2_TIM16 17 | ||
110 | #define STM32H7_RCC_APB2_TIM17 18 | ||
111 | #define STM32H7_RCC_APB2_SPI5 20 | ||
112 | #define STM32H7_RCC_APB2_SAI1 22 | ||
113 | #define STM32H7_RCC_APB2_SAI2 23 | ||
114 | #define STM32H7_RCC_APB2_SAI3 24 | ||
115 | #define STM32H7_RCC_APB2_DFSDM1 28 | ||
116 | #define STM32H7_RCC_APB2_HRTIM 29 | ||
117 | |||
118 | #define STM32H7_APB2_RESET(bit) (STM32H7_RCC_APB2_##bit + (0x98 * 8)) | ||
119 | |||
120 | /* APB4 */ | ||
121 | #define STM32H7_RCC_APB4_SYSCFG 1 | ||
122 | #define STM32H7_RCC_APB4_LPUART1 3 | ||
123 | #define STM32H7_RCC_APB4_SPI6 5 | ||
124 | #define STM32H7_RCC_APB4_I2C4 7 | ||
125 | #define STM32H7_RCC_APB4_LPTIM2 9 | ||
126 | #define STM32H7_RCC_APB4_LPTIM3 10 | ||
127 | #define STM32H7_RCC_APB4_LPTIM4 11 | ||
128 | #define STM32H7_RCC_APB4_LPTIM5 12 | ||
129 | #define STM32H7_RCC_APB4_COMP12 14 | ||
130 | #define STM32H7_RCC_APB4_VREF 15 | ||
131 | #define STM32H7_RCC_APB4_SAI4 21 | ||
132 | #define STM32H7_RCC_APB4_TMPSENS 26 | ||
133 | |||
134 | #define STM32H7_APB4_RESET(bit) (STM32H7_RCC_APB4_##bit + (0x9C * 8)) | ||
135 | |||
136 | #endif /* _DT_BINDINGS_MFD_STM32H7_RCC_H */ | ||
diff --git a/include/dt-bindings/reset/sun4i-a10-ccu.h b/include/dt-bindings/reset/sun4i-a10-ccu.h new file mode 100644 index 000000000000..5f4480bedc8a --- /dev/null +++ b/include/dt-bindings/reset/sun4i-a10-ccu.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Priit Laes <plaes@plaes.org> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_RST_SUN4I_A10_H | ||
44 | #define _DT_BINDINGS_RST_SUN4I_A10_H | ||
45 | |||
46 | #define RST_USB_PHY0 1 | ||
47 | #define RST_USB_PHY1 2 | ||
48 | #define RST_USB_PHY2 3 | ||
49 | #define RST_GPS 4 | ||
50 | #define RST_DE_BE0 5 | ||
51 | #define RST_DE_BE1 6 | ||
52 | #define RST_DE_FE0 7 | ||
53 | #define RST_DE_FE1 8 | ||
54 | #define RST_DE_MP 9 | ||
55 | #define RST_TVE0 10 | ||
56 | #define RST_TCON0 11 | ||
57 | #define RST_TVE1 12 | ||
58 | #define RST_TCON1 13 | ||
59 | #define RST_CSI0 14 | ||
60 | #define RST_CSI1 15 | ||
61 | #define RST_VE 16 | ||
62 | #define RST_ACE 17 | ||
63 | #define RST_LVDS 18 | ||
64 | #define RST_GPU 19 | ||
65 | #define RST_HDMI_H 20 | ||
66 | #define RST_HDMI_SYS 21 | ||
67 | #define RST_HDMI_AUDIO_DMA 22 | ||
68 | |||
69 | #endif /* DT_BINDINGS_RST_SUN4I_A10_H */ | ||
diff --git a/include/dt-bindings/reset/sun8i-r40-ccu.h b/include/dt-bindings/reset/sun8i-r40-ccu.h new file mode 100644 index 000000000000..c5ebcf6672e4 --- /dev/null +++ b/include/dt-bindings/reset/sun8i-r40-ccu.h | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> | ||
3 | * | ||
4 | * This file is dual-licensed: you can use it either under the terms | ||
5 | * of the GPL or the X11 license, at your option. Note that this dual | ||
6 | * licensing only applies to this file, and not this project as a | ||
7 | * whole. | ||
8 | * | ||
9 | * a) This file is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of the | ||
12 | * License, or (at your option) any later version. | ||
13 | * | ||
14 | * This file is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * Or, alternatively, | ||
20 | * | ||
21 | * b) Permission is hereby granted, free of charge, to any person | ||
22 | * obtaining a copy of this software and associated documentation | ||
23 | * files (the "Software"), to deal in the Software without | ||
24 | * restriction, including without limitation the rights to use, | ||
25 | * copy, modify, merge, publish, distribute, sublicense, and/or | ||
26 | * sell copies of the Software, and to permit persons to whom the | ||
27 | * Software is furnished to do so, subject to the following | ||
28 | * conditions: | ||
29 | * | ||
30 | * The above copyright notice and this permission notice shall be | ||
31 | * included in all copies or substantial portions of the Software. | ||
32 | * | ||
33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
34 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
35 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
36 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
37 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
38 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
39 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
40 | * OTHER DEALINGS IN THE SOFTWARE. | ||
41 | */ | ||
42 | |||
43 | #ifndef _DT_BINDINGS_RST_SUN8I_R40_H_ | ||
44 | #define _DT_BINDINGS_RST_SUN8I_R40_H_ | ||
45 | |||
46 | #define RST_USB_PHY0 0 | ||
47 | #define RST_USB_PHY1 1 | ||
48 | #define RST_USB_PHY2 2 | ||
49 | |||
50 | #define RST_DRAM 3 | ||
51 | #define RST_MBUS 4 | ||
52 | |||
53 | #define RST_BUS_MIPI_DSI 5 | ||
54 | #define RST_BUS_CE 6 | ||
55 | #define RST_BUS_DMA 7 | ||
56 | #define RST_BUS_MMC0 8 | ||
57 | #define RST_BUS_MMC1 9 | ||
58 | #define RST_BUS_MMC2 10 | ||
59 | #define RST_BUS_MMC3 11 | ||
60 | #define RST_BUS_NAND 12 | ||
61 | #define RST_BUS_DRAM 13 | ||
62 | #define RST_BUS_EMAC 14 | ||
63 | #define RST_BUS_TS 15 | ||
64 | #define RST_BUS_HSTIMER 16 | ||
65 | #define RST_BUS_SPI0 17 | ||
66 | #define RST_BUS_SPI1 18 | ||
67 | #define RST_BUS_SPI2 19 | ||
68 | #define RST_BUS_SPI3 20 | ||
69 | #define RST_BUS_SATA 21 | ||
70 | #define RST_BUS_OTG 22 | ||
71 | #define RST_BUS_EHCI0 23 | ||
72 | #define RST_BUS_EHCI1 24 | ||
73 | #define RST_BUS_EHCI2 25 | ||
74 | #define RST_BUS_OHCI0 26 | ||
75 | #define RST_BUS_OHCI1 27 | ||
76 | #define RST_BUS_OHCI2 28 | ||
77 | #define RST_BUS_VE 29 | ||
78 | #define RST_BUS_MP 30 | ||
79 | #define RST_BUS_DEINTERLACE 31 | ||
80 | #define RST_BUS_CSI0 32 | ||
81 | #define RST_BUS_CSI1 33 | ||
82 | #define RST_BUS_HDMI0 34 | ||
83 | #define RST_BUS_HDMI1 35 | ||
84 | #define RST_BUS_DE 36 | ||
85 | #define RST_BUS_TVE0 37 | ||
86 | #define RST_BUS_TVE1 38 | ||
87 | #define RST_BUS_TVE_TOP 39 | ||
88 | #define RST_BUS_GMAC 40 | ||
89 | #define RST_BUS_GPU 41 | ||
90 | #define RST_BUS_TVD0 42 | ||
91 | #define RST_BUS_TVD1 43 | ||
92 | #define RST_BUS_TVD2 44 | ||
93 | #define RST_BUS_TVD3 45 | ||
94 | #define RST_BUS_TVD_TOP 46 | ||
95 | #define RST_BUS_TCON_LCD0 47 | ||
96 | #define RST_BUS_TCON_LCD1 48 | ||
97 | #define RST_BUS_TCON_TV0 49 | ||
98 | #define RST_BUS_TCON_TV1 50 | ||
99 | #define RST_BUS_TCON_TOP 51 | ||
100 | #define RST_BUS_DBG 52 | ||
101 | #define RST_BUS_LVDS 53 | ||
102 | #define RST_BUS_CODEC 54 | ||
103 | #define RST_BUS_SPDIF 55 | ||
104 | #define RST_BUS_AC97 56 | ||
105 | #define RST_BUS_IR0 57 | ||
106 | #define RST_BUS_IR1 58 | ||
107 | #define RST_BUS_THS 59 | ||
108 | #define RST_BUS_KEYPAD 60 | ||
109 | #define RST_BUS_I2S0 61 | ||
110 | #define RST_BUS_I2S1 62 | ||
111 | #define RST_BUS_I2S2 63 | ||
112 | #define RST_BUS_I2C0 64 | ||
113 | #define RST_BUS_I2C1 65 | ||
114 | #define RST_BUS_I2C2 66 | ||
115 | #define RST_BUS_I2C3 67 | ||
116 | #define RST_BUS_CAN 68 | ||
117 | #define RST_BUS_SCR 69 | ||
118 | #define RST_BUS_PS20 70 | ||
119 | #define RST_BUS_PS21 71 | ||
120 | #define RST_BUS_I2C4 72 | ||
121 | #define RST_BUS_UART0 73 | ||
122 | #define RST_BUS_UART1 74 | ||
123 | #define RST_BUS_UART2 75 | ||
124 | #define RST_BUS_UART3 76 | ||
125 | #define RST_BUS_UART4 77 | ||
126 | #define RST_BUS_UART5 78 | ||
127 | #define RST_BUS_UART6 79 | ||
128 | #define RST_BUS_UART7 80 | ||
129 | |||
130 | #endif /* _DT_BINDINGS_RST_SUN8I_R40_H_ */ | ||
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c59c62571e4f..5100ec1b5d55 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -343,6 +343,7 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, | |||
343 | u8 clk_gate_flags, spinlock_t *lock); | 343 | u8 clk_gate_flags, spinlock_t *lock); |
344 | void clk_unregister_gate(struct clk *clk); | 344 | void clk_unregister_gate(struct clk *clk); |
345 | void clk_hw_unregister_gate(struct clk_hw *hw); | 345 | void clk_hw_unregister_gate(struct clk_hw *hw); |
346 | int clk_gate_is_enabled(struct clk_hw *hw); | ||
346 | 347 | ||
347 | struct clk_div_table { | 348 | struct clk_div_table { |
348 | unsigned int val; | 349 | unsigned int val; |
@@ -565,6 +566,9 @@ struct clk_fractional_divider { | |||
565 | u8 nwidth; | 566 | u8 nwidth; |
566 | u32 nmask; | 567 | u32 nmask; |
567 | u8 flags; | 568 | u8 flags; |
569 | void (*approximation)(struct clk_hw *hw, | ||
570 | unsigned long rate, unsigned long *parent_rate, | ||
571 | unsigned long *m, unsigned long *n); | ||
568 | spinlock_t *lock; | 572 | spinlock_t *lock; |
569 | }; | 573 | }; |
570 | 574 | ||
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 17f413bbbedf..6aca5ce8a99a 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h | |||
@@ -185,4 +185,29 @@ | |||
185 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ | 185 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ |
186 | #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ | 186 | #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ |
187 | 187 | ||
188 | #define AT91_PMC_AUDIO_PLL0 0x14c | ||
189 | #define AT91_PMC_AUDIO_PLL_PLLEN (1 << 0) | ||
190 | #define AT91_PMC_AUDIO_PLL_PADEN (1 << 1) | ||
191 | #define AT91_PMC_AUDIO_PLL_PMCEN (1 << 2) | ||
192 | #define AT91_PMC_AUDIO_PLL_RESETN (1 << 3) | ||
193 | #define AT91_PMC_AUDIO_PLL_ND_OFFSET 8 | ||
194 | #define AT91_PMC_AUDIO_PLL_ND_MASK (0x7f << AT91_PMC_AUDIO_PLL_ND_OFFSET) | ||
195 | #define AT91_PMC_AUDIO_PLL_ND(n) ((n) << AT91_PMC_AUDIO_PLL_ND_OFFSET) | ||
196 | #define AT91_PMC_AUDIO_PLL_QDPMC_OFFSET 16 | ||
197 | #define AT91_PMC_AUDIO_PLL_QDPMC_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) | ||
198 | #define AT91_PMC_AUDIO_PLL_QDPMC(n) ((n) << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) | ||
199 | |||
200 | #define AT91_PMC_AUDIO_PLL1 0x150 | ||
201 | #define AT91_PMC_AUDIO_PLL_FRACR_MASK 0x3fffff | ||
202 | #define AT91_PMC_AUDIO_PLL_QDPAD_OFFSET 24 | ||
203 | #define AT91_PMC_AUDIO_PLL_QDPAD_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET) | ||
204 | #define AT91_PMC_AUDIO_PLL_QDPAD(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET) | ||
205 | #define AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET AT91_PMC_AUDIO_PLL_QDPAD_OFFSET | ||
206 | #define AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK (0x3 << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET) | ||
207 | #define AT91_PMC_AUDIO_PLL_QDPAD_DIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET) | ||
208 | #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET 26 | ||
209 | #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX 0x1f | ||
210 | #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK (AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET) | ||
211 | #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET) | ||
212 | |||
188 | #endif | 213 | #endif |
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index 0cd7caaed9c4..8445edd06737 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c | |||
@@ -32,7 +32,6 @@ struct atmel_classd { | |||
32 | struct regmap *regmap; | 32 | struct regmap *regmap; |
33 | struct clk *pclk; | 33 | struct clk *pclk; |
34 | struct clk *gclk; | 34 | struct clk *gclk; |
35 | struct clk *aclk; | ||
36 | int irq; | 35 | int irq; |
37 | const struct atmel_classd_pdata *pdata; | 36 | const struct atmel_classd_pdata *pdata; |
38 | }; | 37 | }; |
@@ -330,11 +329,6 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream, | |||
330 | { | 329 | { |
331 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 330 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
332 | struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); | 331 | struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); |
333 | int ret; | ||
334 | |||
335 | ret = clk_prepare_enable(dd->aclk); | ||
336 | if (ret) | ||
337 | return ret; | ||
338 | 332 | ||
339 | return clk_prepare_enable(dd->gclk); | 333 | return clk_prepare_enable(dd->gclk); |
340 | } | 334 | } |
@@ -357,31 +351,31 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai, | |||
357 | return 0; | 351 | return 0; |
358 | } | 352 | } |
359 | 353 | ||
360 | #define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) | 354 | #define CLASSD_GCLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) |
361 | #define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) | 355 | #define CLASSD_GCLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) |
362 | 356 | ||
363 | static struct { | 357 | static struct { |
364 | int rate; | 358 | int rate; |
365 | int sample_rate; | 359 | int sample_rate; |
366 | int dsp_clk; | 360 | int dsp_clk; |
367 | unsigned long aclk_rate; | 361 | unsigned long gclk_rate; |
368 | } const sample_rates[] = { | 362 | } const sample_rates[] = { |
369 | { 8000, CLASSD_INTPMR_FRAME_8K, | 363 | { 8000, CLASSD_INTPMR_FRAME_8K, |
370 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, | 364 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, |
371 | { 16000, CLASSD_INTPMR_FRAME_16K, | 365 | { 16000, CLASSD_INTPMR_FRAME_16K, |
372 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, | 366 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, |
373 | { 32000, CLASSD_INTPMR_FRAME_32K, | 367 | { 32000, CLASSD_INTPMR_FRAME_32K, |
374 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, | 368 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, |
375 | { 48000, CLASSD_INTPMR_FRAME_48K, | 369 | { 48000, CLASSD_INTPMR_FRAME_48K, |
376 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, | 370 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, |
377 | { 96000, CLASSD_INTPMR_FRAME_96K, | 371 | { 96000, CLASSD_INTPMR_FRAME_96K, |
378 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, | 372 | CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, |
379 | { 22050, CLASSD_INTPMR_FRAME_22K, | 373 | { 22050, CLASSD_INTPMR_FRAME_22K, |
380 | CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, | 374 | CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, |
381 | { 44100, CLASSD_INTPMR_FRAME_44K, | 375 | { 44100, CLASSD_INTPMR_FRAME_44K, |
382 | CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, | 376 | CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, |
383 | { 88200, CLASSD_INTPMR_FRAME_88K, | 377 | { 88200, CLASSD_INTPMR_FRAME_88K, |
384 | CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, | 378 | CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, |
385 | }; | 379 | }; |
386 | 380 | ||
387 | static int | 381 | static int |
@@ -410,13 +404,12 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, | |||
410 | } | 404 | } |
411 | 405 | ||
412 | dev_dbg(codec->dev, | 406 | dev_dbg(codec->dev, |
413 | "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n", | 407 | "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n", |
414 | sample_rates[best].rate, sample_rates[best].aclk_rate); | 408 | sample_rates[best].rate, sample_rates[best].gclk_rate); |
415 | 409 | ||
416 | clk_disable_unprepare(dd->gclk); | 410 | clk_disable_unprepare(dd->gclk); |
417 | clk_disable_unprepare(dd->aclk); | ||
418 | 411 | ||
419 | ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate); | 412 | ret = clk_set_rate(dd->gclk, sample_rates[best].gclk_rate); |
420 | if (ret) | 413 | if (ret) |
421 | return ret; | 414 | return ret; |
422 | 415 | ||
@@ -426,10 +419,6 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, | |||
426 | 419 | ||
427 | snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val); | 420 | snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val); |
428 | 421 | ||
429 | ret = clk_prepare_enable(dd->aclk); | ||
430 | if (ret) | ||
431 | return ret; | ||
432 | |||
433 | return clk_prepare_enable(dd->gclk); | 422 | return clk_prepare_enable(dd->gclk); |
434 | } | 423 | } |
435 | 424 | ||
@@ -441,7 +430,6 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream, | |||
441 | struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); | 430 | struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); |
442 | 431 | ||
443 | clk_disable_unprepare(dd->gclk); | 432 | clk_disable_unprepare(dd->gclk); |
444 | clk_disable_unprepare(dd->aclk); | ||
445 | } | 433 | } |
446 | 434 | ||
447 | static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, | 435 | static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, |
@@ -596,13 +584,6 @@ static int atmel_classd_probe(struct platform_device *pdev) | |||
596 | return ret; | 584 | return ret; |
597 | } | 585 | } |
598 | 586 | ||
599 | dd->aclk = devm_clk_get(dev, "aclk"); | ||
600 | if (IS_ERR(dd->aclk)) { | ||
601 | ret = PTR_ERR(dd->aclk); | ||
602 | dev_err(dev, "failed to get audio clock: %d\n", ret); | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 587 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
607 | io_base = devm_ioremap_resource(dev, res); | 588 | io_base = devm_ioremap_resource(dev, res); |
608 | if (IS_ERR(io_base)) { | 589 | if (IS_ERR(io_base)) { |