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)) { |
