The bulk of the changes are updates and fixes to existing clk provider
drivers, along with a pretty standard number of new drivers. The core recieved a small number of updates as well. Core changes of note: * Removed CLK_IS_ROOT flag New clk provider drivers: * Renesas r8a7796 Clock Pulse Generator / Module Standby and Software Reset * Allwinner sun8i H3 Clock Controller Unit * AmLogic meson8b clock controller (rewritten) * AmLogic gxbb clock controller * Support for some new ICs was added by simple changes to static data tables for chips sharing the same family Driver updates of note: * the Allwinner sunxi clock driver infrastucture was rewritten to comform to the state of the art at drivers/clk/sunxi-ng. The old implementation is still supported for backwards compatibility with the DT ABI -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJXm9LNAAoJEKI6nJvDJaTUHYcP/1oKTHA4uSPux2+5l9vApEJc eSV0oSEP/zDDwYfV4xRt1byAOtzHe3R4p5zDGShnk3+CCwXbQSLGmFJFmZDoSs5E ulftXA8uRV4ac0SEh86BOlstdJHGOVo7Q38XtdPvgKRTv58+ZqHuFcvB726bWY/I GMzVTkpugbn5U7e3MLM58gkBoqa8BS9uIdsf5q/JIxdpe+VgUtjmioH9Rz6G5U5Y T6ObeU6HNusDaz6kUJIiAEkl4UNHk+aebnY7FTbwd9JGGySp5nEknVY7tSMeC6iU hG/knzdMiasa5yv0xdW3/OxnKCQtEeuPPHnJDSXWc9yb20vNs2QhRtd8uckMGHOH X7fXq9xoLxDH81AggW188g7+xfhx7J+ASpjHmHs74itUIoqhhy61PM3I95yQ8m6s QDkInqSszFd2C7OiYsy6m5XS0K8g0jyA2tzWhxlIZNVAl7yP71+HVLJ45NNKCPkb oYbMx4ho538Tl6+c6HHJG0vC3XWSdHbvwMOKyE9k/GyrIJ7FxLZS3BLOYPm6u9t4 9n041MbtBb/UrWVi8kMSdmBjIIs6VSGjq5gwRFAqoPQt3VkPuy0IfnwIpjdE1aFz PbDJQF4ze7D3JgH2rWtivXbCTRthTANmoar299xjSwwb99TSlP2IABY3cNnJrhPr 9/PGShM3hqRpBEUnEmt+ =1dpY -----END PGP SIGNATURE----- Merge tag 'clk-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Michael Turquette: "The bulk of the changes are updates and fixes to existing clk provider drivers, along with a pretty standard number of new drivers. The core recieved a small number of updates as well. Core changes of note: - removed CLK_IS_ROOT flag New clk provider drivers: - Renesas r8a7796 clock pulse generator / module standby and software reset - Allwinner sun8i H3 clock controller unit - AmLogic meson8b clock controller (rewritten) - AmLogic gxbb clock controller - support for some new ICs was added by simple changes to static data tables for chips sharing the same family Driver updates of note: - the Allwinner sunxi clock driver infrastucture was rewritten to comform to the state of the art at drivers/clk/sunxi-ng. The old implementation is still supported for backwards compatibility with the DT ABI" * tag 'clk-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (162 commits) clk: Makefile: re-sort and clean up Revert "clk: gxbb: expose CLKID_MMC_PCLK" clk: samsung: Allow modular build of the Audio Subsystem CLKCON driver clk: samsung: make clk-s5pv210-audss explicitly non-modular clk: exynos5433: remove CLK_IGNORE_UNUSED flag from SPI clocks clk: oxnas: Add hardware dependencies clk: imx7d: do not set parent of ethernet time/ref clocks ARM: dt: sun8i: switch the H3 to the new CCU driver clk: sunxi-ng: h3: Fix Kconfig symbol typo clk: sunxi-ng: h3: Fix audio clock divider offset clk: sunxi-ng: Add H3 clocks clk: sunxi-ng: Add N-K-M-P factor clock clk: sunxi-ng: Add N-K-M Factor clock clk: sunxi-ng: Add N-M-factor clock support clk: sunxi-ng: Add N-K-factor clock support clk: sunxi-ng: Add M-P factor clock support clk: sunxi-ng: Add divider clk: sunxi-ng: Add phase clock support clk: sunxi-ng: Add mux clock support clk: sunxi-ng: Add gate clock support ...
This commit is contained in:
commit
1056c9bd27
@ -0,0 +1,36 @@
|
||||
* Amlogic GXBB Clock and Reset Unit
|
||||
|
||||
The Amlogic GXBB clock controller generates and supplies clock to various
|
||||
controllers within the SoC.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be "amlogic,gxbb-clkc"
|
||||
- reg: physical base address of the clock controller and length of memory
|
||||
mapped region.
|
||||
|
||||
- #clock-cells: should be 1.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. All available clocks are defined as
|
||||
preprocessor macros in the dt-bindings/clock/gxbb-clkc.h header and can be
|
||||
used in device tree sources.
|
||||
|
||||
Example: Clock controller node:
|
||||
|
||||
clkc: clock-controller@c883c000 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "amlogic,gxbb-clkc";
|
||||
reg = <0x0 0xc883c000 0x0 0x3db>;
|
||||
};
|
||||
|
||||
Example: UART controller node that consumes the clock generated by the clock
|
||||
controller:
|
||||
|
||||
uart_AO: serial@c81004c0 {
|
||||
compatible = "amlogic,meson-uart";
|
||||
reg = <0xc81004c0 0x14>;
|
||||
interrupts = <0 90 1>;
|
||||
clocks = <&clkc CLKID_CLK81>;
|
||||
status = "disabled";
|
||||
};
|
@ -14,6 +14,10 @@ Required properties:
|
||||
Optional properties:
|
||||
- clock-output-names : From common clock binding.
|
||||
|
||||
Some clocks that require special treatments are also handled by that
|
||||
driver, with the compatibles:
|
||||
- allwinner,sun4i-a10-pll3-2x-clk
|
||||
|
||||
Example:
|
||||
clock {
|
||||
compatible = "fixed-factor-clock";
|
||||
|
@ -13,7 +13,8 @@ They provide the following functionalities:
|
||||
|
||||
Required Properties:
|
||||
- compatible: Must be one of:
|
||||
- "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC
|
||||
- "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3)
|
||||
- "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W)
|
||||
|
||||
- reg: Base address and length of the memory resource used by the CPG/MSSR
|
||||
block
|
||||
@ -21,8 +22,8 @@ Required Properties:
|
||||
- clocks: References to external parent clocks, one entry for each entry in
|
||||
clock-names
|
||||
- clock-names: List of external parent clock names. Valid names are:
|
||||
- "extal" (r8a7795)
|
||||
- "extalr" (r8a7795)
|
||||
- "extal" (r8a7795, r8a7796)
|
||||
- "extalr" (r8a7795, r8a7796)
|
||||
|
||||
- #clock-cells: Must be 2
|
||||
- For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
|
||||
|
@ -17,6 +17,7 @@ Required Properties:
|
||||
- "renesas,r8a7779-mstp-clocks" for R8A7779 (R-Car H1) MSTP gate clocks
|
||||
- "renesas,r8a7790-mstp-clocks" for R8A7790 (R-Car H2) MSTP gate clocks
|
||||
- "renesas,r8a7791-mstp-clocks" for R8A7791 (R-Car M2-W) MSTP gate clocks
|
||||
- "renesas,r8a7792-mstp-clocks" for R8A7792 (R-Car V2H) MSTP gate clocks
|
||||
- "renesas,r8a7793-mstp-clocks" for R8A7793 (R-Car M2-N) MSTP gate clocks
|
||||
- "renesas,r8a7794-mstp-clocks" for R8A7794 (R-Car E2) MSTP gate clocks
|
||||
- "renesas,sh73a0-mstp-clocks" for SH73A0 (SH-MobileAG5) MSTP gate clocks
|
||||
|
@ -10,6 +10,7 @@ Required Properties:
|
||||
- compatible: Must be one of
|
||||
- "renesas,r8a7790-cpg-clocks" for the r8a7790 CPG
|
||||
- "renesas,r8a7791-cpg-clocks" for the r8a7791 CPG
|
||||
- "renesas,r8a7792-cpg-clocks" for the r8a7792 CPG
|
||||
- "renesas,r8a7793-cpg-clocks" for the r8a7793 CPG
|
||||
- "renesas,r8a7794-cpg-clocks" for the r8a7794 CPG
|
||||
and "renesas,rcar-gen2-cpg-clocks" as a fallback.
|
||||
|
24
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
Normal file
24
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
Normal file
@ -0,0 +1,24 @@
|
||||
Allwinner Clock Control Unit Binding
|
||||
------------------------------------
|
||||
|
||||
Required properties :
|
||||
- compatible: must contain one of the following compatible:
|
||||
- "allwinner,sun8i-h3-ccu"
|
||||
|
||||
- reg: Must contain the registers base address and length
|
||||
- clocks: phandle to the oscillators feeding the CCU. Two are needed:
|
||||
- "hosc": the high frequency oscillator (usually at 24MHz)
|
||||
- "losc": the low frequency oscillator (usually at 32kHz)
|
||||
- clock-names: Must contain the clock names described just above
|
||||
- #clock-cells : must contain 1
|
||||
- #reset-cells : must contain 1
|
||||
|
||||
Example:
|
||||
ccu: clock@01c20000 {
|
||||
compatible = "allwinner,sun8i-h3-ccu";
|
||||
reg = <0x01c20000 0x400>;
|
||||
clocks = <&osc24M>, <&osc32k>;
|
||||
clock-names = "hosc", "losc";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
@ -42,8 +42,10 @@
|
||||
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
#include <dt-bindings/clock/sun8i-h3-ccu.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/pinctrl/sun4i-a10.h>
|
||||
#include <dt-bindings/reset/sun8i-h3-ccu.h>
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
@ -104,191 +106,6 @@
|
||||
clock-output-names = "osc32k";
|
||||
};
|
||||
|
||||
pll1: clk@01c20000 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun8i-a23-pll1-clk";
|
||||
reg = <0x01c20000 0x4>;
|
||||
clocks = <&osc24M>;
|
||||
clock-output-names = "pll1";
|
||||
};
|
||||
|
||||
/* dummy clock until actually implemented */
|
||||
pll5: pll5_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <0>;
|
||||
clock-output-names = "pll5";
|
||||
};
|
||||
|
||||
pll6: clk@01c20028 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "allwinner,sun6i-a31-pll6-clk";
|
||||
reg = <0x01c20028 0x4>;
|
||||
clocks = <&osc24M>;
|
||||
clock-output-names = "pll6", "pll6x2";
|
||||
};
|
||||
|
||||
pll6d2: pll6d2_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-factor-clock";
|
||||
clock-div = <2>;
|
||||
clock-mult = <1>;
|
||||
clocks = <&pll6 0>;
|
||||
clock-output-names = "pll6d2";
|
||||
};
|
||||
|
||||
/* dummy clock until pll6 can be reused */
|
||||
pll8: pll8_clk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <1>;
|
||||
clock-output-names = "pll8";
|
||||
};
|
||||
|
||||
cpu: cpu_clk@01c20050 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-cpu-clk";
|
||||
reg = <0x01c20050 0x4>;
|
||||
clocks = <&osc32k>, <&osc24M>, <&pll1>, <&pll1>;
|
||||
clock-output-names = "cpu";
|
||||
};
|
||||
|
||||
axi: axi_clk@01c20050 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-axi-clk";
|
||||
reg = <0x01c20050 0x4>;
|
||||
clocks = <&cpu>;
|
||||
clock-output-names = "axi";
|
||||
};
|
||||
|
||||
ahb1: ahb1_clk@01c20054 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun6i-a31-ahb1-clk";
|
||||
reg = <0x01c20054 0x4>;
|
||||
clocks = <&osc32k>, <&osc24M>, <&axi>, <&pll6 0>;
|
||||
clock-output-names = "ahb1";
|
||||
};
|
||||
|
||||
ahb2: ahb2_clk@01c2005c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun8i-h3-ahb2-clk";
|
||||
reg = <0x01c2005c 0x4>;
|
||||
clocks = <&ahb1>, <&pll6d2>;
|
||||
clock-output-names = "ahb2";
|
||||
};
|
||||
|
||||
apb1: apb1_clk@01c20054 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-apb0-clk";
|
||||
reg = <0x01c20054 0x4>;
|
||||
clocks = <&ahb1>;
|
||||
clock-output-names = "apb1";
|
||||
};
|
||||
|
||||
apb2: apb2_clk@01c20058 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun4i-a10-apb1-clk";
|
||||
reg = <0x01c20058 0x4>;
|
||||
clocks = <&osc32k>, <&osc24M>, <&pll6 0>, <&pll6 0>;
|
||||
clock-output-names = "apb2";
|
||||
};
|
||||
|
||||
bus_gates: clk@01c20060 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "allwinner,sun8i-h3-bus-gates-clk";
|
||||
reg = <0x01c20060 0x14>;
|
||||
clocks = <&ahb1>, <&ahb2>, <&apb1>, <&apb2>;
|
||||
clock-names = "ahb1", "ahb2", "apb1", "apb2";
|
||||
clock-indices = <5>, <6>, <8>,
|
||||
<9>, <10>, <13>,
|
||||
<14>, <17>, <18>,
|
||||
<19>, <20>,
|
||||
<21>, <23>,
|
||||
<24>, <25>,
|
||||
<26>, <27>,
|
||||
<28>, <29>,
|
||||
<30>, <31>, <32>,
|
||||
<35>, <36>, <37>,
|
||||
<40>, <41>, <43>,
|
||||
<44>, <52>, <53>,
|
||||
<54>, <64>,
|
||||
<65>, <69>, <72>,
|
||||
<76>, <77>, <78>,
|
||||
<96>, <97>, <98>,
|
||||
<112>, <113>,
|
||||
<114>, <115>,
|
||||
<116>, <128>, <135>;
|
||||
clock-output-names = "bus_ce", "bus_dma", "bus_mmc0",
|
||||
"bus_mmc1", "bus_mmc2", "bus_nand",
|
||||
"bus_sdram", "bus_gmac", "bus_ts",
|
||||
"bus_hstimer", "bus_spi0",
|
||||
"bus_spi1", "bus_otg",
|
||||
"bus_otg_ehci0", "bus_ehci1",
|
||||
"bus_ehci2", "bus_ehci3",
|
||||
"bus_otg_ohci0", "bus_ohci1",
|
||||
"bus_ohci2", "bus_ohci3", "bus_ve",
|
||||
"bus_lcd0", "bus_lcd1", "bus_deint",
|
||||
"bus_csi", "bus_tve", "bus_hdmi",
|
||||
"bus_de", "bus_gpu", "bus_msgbox",
|
||||
"bus_spinlock", "bus_codec",
|
||||
"bus_spdif", "bus_pio", "bus_ths",
|
||||
"bus_i2s0", "bus_i2s1", "bus_i2s2",
|
||||
"bus_i2c0", "bus_i2c1", "bus_i2c2",
|
||||
"bus_uart0", "bus_uart1",
|
||||
"bus_uart2", "bus_uart3",
|
||||
"bus_scr", "bus_ephy", "bus_dbg";
|
||||
};
|
||||
|
||||
mmc0_clk: clk@01c20088 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "allwinner,sun4i-a10-mmc-clk";
|
||||
reg = <0x01c20088 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 0>, <&pll8>;
|
||||
clock-output-names = "mmc0",
|
||||
"mmc0_output",
|
||||
"mmc0_sample";
|
||||
};
|
||||
|
||||
mmc1_clk: clk@01c2008c {
|
||||
#clock-cells = <1>;
|
||||
compatible = "allwinner,sun4i-a10-mmc-clk";
|
||||
reg = <0x01c2008c 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 0>, <&pll8>;
|
||||
clock-output-names = "mmc1",
|
||||
"mmc1_output",
|
||||
"mmc1_sample";
|
||||
};
|
||||
|
||||
mmc2_clk: clk@01c20090 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "allwinner,sun4i-a10-mmc-clk";
|
||||
reg = <0x01c20090 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 0>, <&pll8>;
|
||||
clock-output-names = "mmc2",
|
||||
"mmc2_output",
|
||||
"mmc2_sample";
|
||||
};
|
||||
|
||||
usb_clk: clk@01c200cc {
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
compatible = "allwinner,sun8i-h3-usb-clk";
|
||||
reg = <0x01c200cc 0x4>;
|
||||
clocks = <&osc24M>;
|
||||
clock-output-names = "usb_phy0", "usb_phy1",
|
||||
"usb_phy2", "usb_phy3",
|
||||
"usb_ohci0", "usb_ohci1",
|
||||
"usb_ohci2", "usb_ohci3";
|
||||
};
|
||||
|
||||
mbus_clk: clk@01c2015c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "allwinner,sun8i-a23-mbus-clk";
|
||||
reg = <0x01c2015c 0x4>;
|
||||
clocks = <&osc24M>, <&pll6 1>, <&pll5>;
|
||||
clock-output-names = "mbus";
|
||||
};
|
||||
|
||||
apb0: apb0_clk {
|
||||
compatible = "fixed-factor-clock";
|
||||
#clock-cells = <0>;
|
||||
@ -327,23 +144,23 @@
|
||||
compatible = "allwinner,sun8i-h3-dma";
|
||||
reg = <0x01c02000 0x1000>;
|
||||
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 6>;
|
||||
resets = <&ahb_rst 6>;
|
||||
clocks = <&ccu CLK_BUS_DMA>;
|
||||
resets = <&ccu RST_BUS_DMA>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
mmc0: mmc@01c0f000 {
|
||||
compatible = "allwinner,sun5i-a13-mmc";
|
||||
reg = <0x01c0f000 0x1000>;
|
||||
clocks = <&bus_gates 8>,
|
||||
<&mmc0_clk 0>,
|
||||
<&mmc0_clk 1>,
|
||||
<&mmc0_clk 2>;
|
||||
clocks = <&ccu CLK_BUS_MMC0>,
|
||||
<&ccu CLK_MMC0>,
|
||||
<&ccu CLK_MMC0_OUTPUT>,
|
||||
<&ccu CLK_MMC0_SAMPLE>;
|
||||
clock-names = "ahb",
|
||||
"mmc",
|
||||
"output",
|
||||
"sample";
|
||||
resets = <&ahb_rst 8>;
|
||||
resets = <&ccu RST_BUS_MMC0>;
|
||||
reset-names = "ahb";
|
||||
interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
@ -354,15 +171,15 @@
|
||||
mmc1: mmc@01c10000 {
|
||||
compatible = "allwinner,sun5i-a13-mmc";
|
||||
reg = <0x01c10000 0x1000>;
|
||||
clocks = <&bus_gates 9>,
|
||||
<&mmc1_clk 0>,
|
||||
<&mmc1_clk 1>,
|
||||
<&mmc1_clk 2>;
|
||||
clocks = <&ccu CLK_BUS_MMC1>,
|
||||
<&ccu CLK_MMC1>,
|
||||
<&ccu CLK_MMC1_OUTPUT>,
|
||||
<&ccu CLK_MMC1_SAMPLE>;
|
||||
clock-names = "ahb",
|
||||
"mmc",
|
||||
"output",
|
||||
"sample";
|
||||
resets = <&ahb_rst 9>;
|
||||
resets = <&ccu RST_BUS_MMC1>;
|
||||
reset-names = "ahb";
|
||||
interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
@ -373,15 +190,15 @@
|
||||
mmc2: mmc@01c11000 {
|
||||
compatible = "allwinner,sun5i-a13-mmc";
|
||||
reg = <0x01c11000 0x1000>;
|
||||
clocks = <&bus_gates 10>,
|
||||
<&mmc2_clk 0>,
|
||||
<&mmc2_clk 1>,
|
||||
<&mmc2_clk 2>;
|
||||
clocks = <&ccu CLK_BUS_MMC2>,
|
||||
<&ccu CLK_MMC2>,
|
||||
<&ccu CLK_MMC2_OUTPUT>,
|
||||
<&ccu CLK_MMC2_SAMPLE>;
|
||||
clock-names = "ahb",
|
||||
"mmc",
|
||||
"output",
|
||||
"sample";
|
||||
resets = <&ahb_rst 10>;
|
||||
resets = <&ccu RST_BUS_MMC2>;
|
||||
reset-names = "ahb";
|
||||
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
|
||||
status = "disabled";
|
||||
@ -401,18 +218,18 @@
|
||||
"pmu1",
|
||||
"pmu2",
|
||||
"pmu3";
|
||||
clocks = <&usb_clk 8>,
|
||||
<&usb_clk 9>,
|
||||
<&usb_clk 10>,
|
||||
<&usb_clk 11>;
|
||||
clocks = <&ccu CLK_USB_PHY0>,
|
||||
<&ccu CLK_USB_PHY1>,
|
||||
<&ccu CLK_USB_PHY2>,
|
||||
<&ccu CLK_USB_PHY3>;
|
||||
clock-names = "usb0_phy",
|
||||
"usb1_phy",
|
||||
"usb2_phy",
|
||||
"usb3_phy";
|
||||
resets = <&usb_clk 0>,
|
||||
<&usb_clk 1>,
|
||||
<&usb_clk 2>,
|
||||
<&usb_clk 3>;
|
||||
resets = <&ccu RST_USB_PHY0>,
|
||||
<&ccu RST_USB_PHY1>,
|
||||
<&ccu RST_USB_PHY2>,
|
||||
<&ccu RST_USB_PHY3>;
|
||||
reset-names = "usb0_reset",
|
||||
"usb1_reset",
|
||||
"usb2_reset",
|
||||
@ -425,8 +242,8 @@
|
||||
compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
|
||||
reg = <0x01c1b000 0x100>;
|
||||
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 25>, <&bus_gates 29>;
|
||||
resets = <&ahb_rst 25>, <&ahb_rst 29>;
|
||||
clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>;
|
||||
resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>;
|
||||
phys = <&usbphy 1>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
@ -436,9 +253,9 @@
|
||||
compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
|
||||
reg = <0x01c1b400 0x100>;
|
||||
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 29>, <&bus_gates 25>,
|
||||
<&usb_clk 17>;
|
||||
resets = <&ahb_rst 29>, <&ahb_rst 25>;
|
||||
clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>,
|
||||
<&ccu CLK_USB_OHCI1>;
|
||||
resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>;
|
||||
phys = <&usbphy 1>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
@ -448,8 +265,8 @@
|
||||
compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
|
||||
reg = <0x01c1c000 0x100>;
|
||||
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 26>, <&bus_gates 30>;
|
||||
resets = <&ahb_rst 26>, <&ahb_rst 30>;
|
||||
clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>;
|
||||
resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
|
||||
phys = <&usbphy 2>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
@ -459,9 +276,9 @@
|
||||
compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
|
||||
reg = <0x01c1c400 0x100>;
|
||||
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 30>, <&bus_gates 26>,
|
||||
<&usb_clk 18>;
|
||||
resets = <&ahb_rst 30>, <&ahb_rst 26>;
|
||||
clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>,
|
||||
<&ccu CLK_USB_OHCI2>;
|
||||
resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>;
|
||||
phys = <&usbphy 2>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
@ -471,8 +288,8 @@
|
||||
compatible = "allwinner,sun8i-h3-ehci", "generic-ehci";
|
||||
reg = <0x01c1d000 0x100>;
|
||||
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 27>, <&bus_gates 31>;
|
||||
resets = <&ahb_rst 27>, <&ahb_rst 31>;
|
||||
clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>;
|
||||
resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>;
|
||||
phys = <&usbphy 3>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
@ -482,20 +299,29 @@
|
||||
compatible = "allwinner,sun8i-h3-ohci", "generic-ohci";
|
||||
reg = <0x01c1d400 0x100>;
|
||||
interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 31>, <&bus_gates 27>,
|
||||
<&usb_clk 19>;
|
||||
resets = <&ahb_rst 31>, <&ahb_rst 27>;
|
||||
clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>,
|
||||
<&ccu CLK_USB_OHCI3>;
|
||||
resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>;
|
||||
phys = <&usbphy 3>;
|
||||
phy-names = "usb";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ccu: clock@01c20000 {
|
||||
compatible = "allwinner,sun8i-h3-ccu";
|
||||
reg = <0x01c20000 0x400>;
|
||||
clocks = <&osc24M>, <&osc32k>;
|
||||
clock-names = "hosc", "losc";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
pio: pinctrl@01c20800 {
|
||||
compatible = "allwinner,sun8i-h3-pinctrl";
|
||||
reg = <0x01c20800 0x400>;
|
||||
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&bus_gates 69>;
|
||||
clocks = <&ccu CLK_BUS_PIO>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <3>;
|
||||
interrupt-controller;
|
||||
@ -542,24 +368,6 @@
|
||||
};
|
||||
};
|
||||
|
||||
ahb_rst: reset@01c202c0 {
|
||||
#reset-cells = <1>;
|
||||
compatible = "allwinner,sun6i-a31-ahb1-reset";
|
||||
reg = <0x01c202c0 0xc>;
|
||||
};
|
||||
|
||||
apb1_rst: reset@01c202d0 {
|
||||
#reset-cells = <1>;
|
||||
compatible = "allwinner,sun6i-a31-clock-reset";
|
||||
reg = <0x01c202d0 0x4>;
|
||||
};
|
||||
|
||||
apb2_rst: reset@01c202d8 {
|
||||
#reset-cells = <1>;
|
||||
compatible = "allwinner,sun6i-a31-clock-reset";
|
||||
reg = <0x01c202d8 0x4>;
|
||||
};
|
||||
|
||||
timer@01c20c00 {
|
||||
compatible = "allwinner,sun4i-a10-timer";
|
||||
reg = <0x01c20c00 0xa0>;
|
||||
@ -580,8 +388,8 @@
|
||||
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clocks = <&bus_gates 112>;
|
||||
resets = <&apb2_rst 16>;
|
||||
clocks = <&ccu CLK_BUS_UART0>;
|
||||
resets = <&ccu RST_BUS_UART0>;
|
||||
dmas = <&dma 6>, <&dma 6>;
|
||||
dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
@ -593,8 +401,8 @@
|
||||
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clocks = <&bus_gates 113>;
|
||||
resets = <&apb2_rst 17>;
|
||||
clocks = <&ccu CLK_BUS_UART1>;
|
||||
resets = <&ccu RST_BUS_UART1>;
|
||||
dmas = <&dma 7>, <&dma 7>;
|
||||
dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
@ -606,8 +414,8 @@
|
||||
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clocks = <&bus_gates 114>;
|
||||
resets = <&apb2_rst 18>;
|
||||
clocks = <&ccu CLK_BUS_UART2>;
|
||||
resets = <&ccu RST_BUS_UART2>;
|
||||
dmas = <&dma 8>, <&dma 8>;
|
||||
dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
@ -619,8 +427,8 @@
|
||||
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clocks = <&bus_gates 115>;
|
||||
resets = <&apb2_rst 19>;
|
||||
clocks = <&ccu CLK_BUS_UART3>;
|
||||
resets = <&ccu RST_BUS_UART3>;
|
||||
dmas = <&dma 9>, <&dma 9>;
|
||||
dma-names = "rx", "tx";
|
||||
status = "disabled";
|
||||
|
@ -49,10 +49,10 @@ config COMMON_CLK_MAX77802
|
||||
This driver supports Maxim 77802 crystal oscillator clock.
|
||||
|
||||
config COMMON_CLK_RK808
|
||||
tristate "Clock driver for RK808"
|
||||
tristate "Clock driver for RK808/RK818"
|
||||
depends on MFD_RK808
|
||||
---help---
|
||||
This driver supports RK808 crystal oscillator clock. These
|
||||
This driver supports RK808 and RK818 crystal oscillator clock. These
|
||||
multi-function devices have two fixed-rate oscillators,
|
||||
clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
|
||||
by control register.
|
||||
@ -203,16 +203,19 @@ config COMMON_CLK_PIC32
|
||||
|
||||
config COMMON_CLK_OXNAS
|
||||
bool "Clock driver for the OXNAS SoC Family"
|
||||
depends on ARCH_OXNAS || COMPILE_TEST
|
||||
select MFD_SYSCON
|
||||
---help---
|
||||
Support for the OXNAS SoC Family clocks.
|
||||
|
||||
source "drivers/clk/bcm/Kconfig"
|
||||
source "drivers/clk/hisilicon/Kconfig"
|
||||
source "drivers/clk/meson/Kconfig"
|
||||
source "drivers/clk/mvebu/Kconfig"
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
source "drivers/clk/renesas/Kconfig"
|
||||
source "drivers/clk/samsung/Kconfig"
|
||||
source "drivers/clk/sunxi-ng/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
|
||||
|
@ -16,13 +16,14 @@ obj-$(CONFIG_COMMON_CLK) += clk-conf.o
|
||||
endif
|
||||
|
||||
# hardware specific clock types
|
||||
# please keep this section sorted lexicographically by file/directory path name
|
||||
# please keep this section sorted lexicographically by file path name
|
||||
obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
|
||||
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
|
||||
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
|
||||
obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o
|
||||
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
|
||||
obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
|
||||
obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
|
||||
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
|
||||
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
|
||||
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
|
||||
obj-$(CONFIG_MACH_LOONGSON32) += clk-ls1x.o
|
||||
@ -35,6 +36,7 @@ obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
|
||||
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
|
||||
obj-$(CONFIG_COMMON_CLK_OXNAS) += clk-oxnas.o
|
||||
obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o
|
||||
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
||||
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
|
||||
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
|
||||
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
|
||||
@ -42,7 +44,6 @@ obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o
|
||||
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
|
||||
obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o
|
||||
obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
|
||||
obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
|
||||
obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o
|
||||
obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
|
||||
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
|
||||
@ -50,35 +51,39 @@ obj-$(CONFIG_ARCH_U300) += clk-u300.o
|
||||
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
|
||||
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
|
||||
obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
|
||||
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
||||
|
||||
# please keep this section sorted lexicographically by directory path name
|
||||
obj-$(CONFIG_COMMON_CLK_AT91) += at91/
|
||||
obj-$(CONFIG_ARCH_ARTPEC) += axis/
|
||||
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
|
||||
obj-y += bcm/
|
||||
obj-$(CONFIG_ARCH_BERLIN) += berlin/
|
||||
obj-$(CONFIG_H8300) += h8300/
|
||||
obj-$(CONFIG_ARCH_HISI) += hisilicon/
|
||||
obj-$(CONFIG_ARCH_MXC) += imx/
|
||||
obj-$(CONFIG_MACH_INGENIC) += ingenic/
|
||||
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/
|
||||
obj-$(CONFIG_MACH_PIC32) += microchip/
|
||||
ifeq ($(CONFIG_COMMON_CLK), y)
|
||||
obj-$(CONFIG_ARCH_MMP) += mmp/
|
||||
endif
|
||||
obj-y += mvebu/
|
||||
obj-$(CONFIG_ARCH_MESON) += meson/
|
||||
obj-$(CONFIG_ARCH_MXS) += mxs/
|
||||
obj-$(CONFIG_MACH_PISTACHIO) += pistachio/
|
||||
obj-$(CONFIG_COMMON_CLK_NXP) += nxp/
|
||||
obj-$(CONFIG_MACH_PISTACHIO) += pistachio/
|
||||
obj-$(CONFIG_COMMON_CLK_PXA) += pxa/
|
||||
obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += renesas/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += renesas/
|
||||
obj-$(CONFIG_ARCH_SIRF) += sirf/
|
||||
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
|
||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-$(CONFIG_ARCH_STI) += st/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi-ng/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-y += ti/
|
||||
obj-$(CONFIG_ARCH_U8500) += ux500/
|
||||
@ -86,5 +91,3 @@ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
|
||||
obj-$(CONFIG_X86) += x86/
|
||||
obj-$(CONFIG_ARCH_ZX) += zte/
|
||||
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
|
||||
obj-$(CONFIG_H8300) += h8300/
|
||||
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
|
||||
|
@ -267,7 +267,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char
|
||||
return clk;
|
||||
}
|
||||
|
||||
void __init of_sama5d2_clk_generated_setup(struct device_node *np)
|
||||
static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
|
||||
{
|
||||
int num;
|
||||
u32 id;
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "clk-iproc.h"
|
||||
|
||||
#define IPROC_CLK_MAX_FREQ_POLICY 0x3
|
||||
#define IPROC_CLK_POLICY_FREQ_OFFSET 0x008
|
||||
#define IPROC_CLK_POLICY_FREQ_POLICY_FREQ_SHIFT 8
|
||||
@ -242,7 +244,6 @@ static const struct clk_ops iproc_arm_pll_ops = {
|
||||
void __init iproc_armpll_setup(struct device_node *node)
|
||||
{
|
||||
int ret;
|
||||
struct clk *clk;
|
||||
struct iproc_arm_pll *pll;
|
||||
struct clk_init_data init;
|
||||
const char *parent_name;
|
||||
@ -263,18 +264,18 @@ void __init iproc_armpll_setup(struct device_node *node)
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
pll->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (WARN_ON(IS_ERR(clk)))
|
||||
ret = clk_hw_register(NULL, &pll->hw);
|
||||
if (WARN_ON(ret))
|
||||
goto err_iounmap;
|
||||
|
||||
ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll->hw);
|
||||
if (WARN_ON(ret))
|
||||
goto err_clk_unregister;
|
||||
|
||||
return;
|
||||
|
||||
err_clk_unregister:
|
||||
clk_unregister(clk);
|
||||
clk_hw_unregister(&pll->hw);
|
||||
err_iounmap:
|
||||
iounmap(pll->base);
|
||||
err_free_pll:
|
||||
|
@ -37,7 +37,7 @@ struct iproc_asiu {
|
||||
void __iomem *div_base;
|
||||
void __iomem *gate_base;
|
||||
|
||||
struct clk_onecell_data clk_data;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct iproc_asiu_clk *clks;
|
||||
};
|
||||
|
||||
@ -197,11 +197,11 @@ void __init iproc_asiu_setup(struct device_node *node,
|
||||
if (WARN_ON(!asiu))
|
||||
return;
|
||||
|
||||
asiu->clk_data.clk_num = num_clks;
|
||||
asiu->clk_data.clks = kcalloc(num_clks, sizeof(*asiu->clk_data.clks),
|
||||
GFP_KERNEL);
|
||||
if (WARN_ON(!asiu->clk_data.clks))
|
||||
asiu->clk_data = kzalloc(sizeof(*asiu->clk_data->hws) * num_clks +
|
||||
sizeof(*asiu->clk_data), GFP_KERNEL);
|
||||
if (WARN_ON(!asiu->clk_data))
|
||||
goto err_clks;
|
||||
asiu->clk_data->num = num_clks;
|
||||
|
||||
asiu->clks = kcalloc(num_clks, sizeof(*asiu->clks), GFP_KERNEL);
|
||||
if (WARN_ON(!asiu->clks))
|
||||
@ -217,7 +217,6 @@ void __init iproc_asiu_setup(struct device_node *node,
|
||||
|
||||
for (i = 0; i < num_clks; i++) {
|
||||
struct clk_init_data init;
|
||||
struct clk *clk;
|
||||
const char *parent_name;
|
||||
struct iproc_asiu_clk *asiu_clk;
|
||||
const char *clk_name;
|
||||
@ -240,22 +239,22 @@ void __init iproc_asiu_setup(struct device_node *node,
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
asiu_clk->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &asiu_clk->hw);
|
||||
if (WARN_ON(IS_ERR(clk)))
|
||||
ret = clk_hw_register(NULL, &asiu_clk->hw);
|
||||
if (WARN_ON(ret))
|
||||
goto err_clk_register;
|
||||
asiu->clk_data.clks[i] = clk;
|
||||
asiu->clk_data->hws[i] = &asiu_clk->hw;
|
||||
}
|
||||
|
||||
ret = of_clk_add_provider(node, of_clk_src_onecell_get,
|
||||
&asiu->clk_data);
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
|
||||
asiu->clk_data);
|
||||
if (WARN_ON(ret))
|
||||
goto err_clk_register;
|
||||
|
||||
return;
|
||||
|
||||
err_clk_register:
|
||||
for (i = 0; i < num_clks; i++)
|
||||
clk_unregister(asiu->clk_data.clks[i]);
|
||||
while (--i >= 0)
|
||||
clk_hw_unregister(asiu->clk_data->hws[i]);
|
||||
iounmap(asiu->gate_base);
|
||||
|
||||
err_iomap_gate:
|
||||
@ -265,7 +264,7 @@ err_iomap_div:
|
||||
kfree(asiu->clks);
|
||||
|
||||
err_asiu_clks:
|
||||
kfree(asiu->clk_data.clks);
|
||||
kfree(asiu->clk_data);
|
||||
|
||||
err_clks:
|
||||
kfree(asiu);
|
||||
|
@ -89,7 +89,7 @@ struct iproc_pll {
|
||||
const struct iproc_pll_vco_param *vco_param;
|
||||
unsigned int num_vco_entries;
|
||||
|
||||
struct clk_onecell_data clk_data;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct iproc_clk *clks;
|
||||
};
|
||||
|
||||
@ -625,7 +625,6 @@ void __init iproc_pll_clk_setup(struct device_node *node,
|
||||
unsigned int num_clks)
|
||||
{
|
||||
int i, ret;
|
||||
struct clk *clk;
|
||||
struct iproc_pll *pll;
|
||||
struct iproc_clk *iclk;
|
||||
struct clk_init_data init;
|
||||
@ -638,11 +637,11 @@ void __init iproc_pll_clk_setup(struct device_node *node,
|
||||
if (WARN_ON(!pll))
|
||||
return;
|
||||
|
||||
pll->clk_data.clk_num = num_clks;
|
||||
pll->clk_data.clks = kcalloc(num_clks, sizeof(*pll->clk_data.clks),
|
||||
GFP_KERNEL);
|
||||
if (WARN_ON(!pll->clk_data.clks))
|
||||
pll->clk_data = kzalloc(sizeof(*pll->clk_data->hws) * num_clks +
|
||||
sizeof(*pll->clk_data), GFP_KERNEL);
|
||||
if (WARN_ON(!pll->clk_data))
|
||||
goto err_clk_data;
|
||||
pll->clk_data->num = num_clks;
|
||||
|
||||
pll->clks = kcalloc(num_clks, sizeof(*pll->clks), GFP_KERNEL);
|
||||
if (WARN_ON(!pll->clks))
|
||||
@ -694,11 +693,11 @@ void __init iproc_pll_clk_setup(struct device_node *node,
|
||||
|
||||
iproc_pll_sw_cfg(pll);
|
||||
|
||||
clk = clk_register(NULL, &iclk->hw);
|
||||
if (WARN_ON(IS_ERR(clk)))
|
||||
ret = clk_hw_register(NULL, &iclk->hw);
|
||||
if (WARN_ON(ret))
|
||||
goto err_pll_register;
|
||||
|
||||
pll->clk_data.clks[0] = clk;
|
||||
pll->clk_data->hws[0] = &iclk->hw;
|
||||
|
||||
/* now initialize and register all leaf clocks */
|
||||
for (i = 1; i < num_clks; i++) {
|
||||
@ -724,22 +723,23 @@ void __init iproc_pll_clk_setup(struct device_node *node,
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
iclk->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &iclk->hw);
|
||||
if (WARN_ON(IS_ERR(clk)))
|
||||
ret = clk_hw_register(NULL, &iclk->hw);
|
||||
if (WARN_ON(ret))
|
||||
goto err_clk_register;
|
||||
|
||||
pll->clk_data.clks[i] = clk;
|
||||
pll->clk_data->hws[i] = &iclk->hw;
|
||||
}
|
||||
|
||||
ret = of_clk_add_provider(node, of_clk_src_onecell_get, &pll->clk_data);
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
|
||||
pll->clk_data);
|
||||
if (WARN_ON(ret))
|
||||
goto err_clk_register;
|
||||
|
||||
return;
|
||||
|
||||
err_clk_register:
|
||||
for (i = 0; i < num_clks; i++)
|
||||
clk_unregister(pll->clk_data.clks[i]);
|
||||
while (--i >= 0)
|
||||
clk_hw_unregister(pll->clk_data->hws[i]);
|
||||
|
||||
err_pll_register:
|
||||
if (pll->status_base != pll->control_base)
|
||||
@ -759,7 +759,7 @@ err_pll_iomap:
|
||||
kfree(pll->clks);
|
||||
|
||||
err_clks:
|
||||
kfree(pll->clk_data.clks);
|
||||
kfree(pll->clk_data);
|
||||
|
||||
err_clk_data:
|
||||
kfree(pll);
|
||||
|
@ -55,7 +55,7 @@ static int __set_clk_parents(struct device_node *node, bool clk_supplier)
|
||||
}
|
||||
clk = of_clk_get_from_provider(&clkspec);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_warn("clk: couldn't get parent clock %d for %s\n",
|
||||
pr_warn("clk: couldn't get assigned clock %d for %s\n",
|
||||
index, node->full_name);
|
||||
rc = PTR_ERR(clk);
|
||||
goto err;
|
||||
|
@ -142,6 +142,11 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id set_rate_parent_matches[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
|
||||
{ /* Sentinel */ },
|
||||
};
|
||||
|
||||
/**
|
||||
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
|
||||
*/
|
||||
@ -150,6 +155,7 @@ void __init of_fixed_factor_clk_setup(struct device_node *node)
|
||||
struct clk *clk;
|
||||
const char *clk_name = node->name;
|
||||
const char *parent_name;
|
||||
unsigned long flags = 0;
|
||||
u32 div, mult;
|
||||
|
||||
if (of_property_read_u32(node, "clock-div", &div)) {
|
||||
@ -167,7 +173,10 @@ void __init of_fixed_factor_clk_setup(struct device_node *node)
|
||||
of_property_read_string(node, "clock-output-names", &clk_name);
|
||||
parent_name = of_clk_get_parent_name(node, 0);
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0,
|
||||
if (of_match_node(set_rate_parent_matches, node))
|
||||
flags |= CLK_SET_RATE_PARENT;
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags,
|
||||
mult, div);
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
|
@ -145,6 +145,17 @@ void clk_unregister_fixed_rate(struct clk *clk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate);
|
||||
|
||||
void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_fixed_rate *fixed;
|
||||
|
||||
fixed = to_clk_fixed_rate(hw);
|
||||
|
||||
clk_hw_unregister(hw);
|
||||
kfree(fixed);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/**
|
||||
* of_fixed_clk_setup() - Setup function for simple fixed rate clock
|
||||
|
@ -275,7 +275,6 @@ static const struct clk_ops periclk_ops = {
|
||||
static __init struct clk *hb_clk_init(struct device_node *node, const struct clk_ops *ops)
|
||||
{
|
||||
u32 reg;
|
||||
struct clk *clk;
|
||||
struct hb_clk *hb_clk;
|
||||
const char *clk_name = node->name;
|
||||
const char *parent_name;
|
||||
@ -308,13 +307,13 @@ static __init struct clk *hb_clk_init(struct device_node *node, const struct clk
|
||||
|
||||
hb_clk->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &hb_clk->hw);
|
||||
if (WARN_ON(IS_ERR(clk))) {
|
||||
rc = clk_hw_register(NULL, &hb_clk->hw);
|
||||
if (WARN_ON(rc)) {
|
||||
kfree(hb_clk);
|
||||
return NULL;
|
||||
}
|
||||
rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
return clk;
|
||||
rc = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &hb_clk->hw);
|
||||
return hb_clk->hw.clk;
|
||||
}
|
||||
|
||||
static void __init hb_pll_init(struct device_node *node)
|
||||
|
@ -52,14 +52,28 @@ static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *best_parent_rate,
|
||||
u8 width, unsigned long flags)
|
||||
{
|
||||
struct clk_multiplier *mult = to_clk_multiplier(hw);
|
||||
unsigned long orig_parent_rate = *best_parent_rate;
|
||||
unsigned long parent_rate, current_rate, best_rate = ~0;
|
||||
unsigned int i, bestmult = 0;
|
||||
unsigned int maxmult = (1 << width) - 1;
|
||||
|
||||
if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
|
||||
return rate / *best_parent_rate;
|
||||
if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
|
||||
bestmult = rate / orig_parent_rate;
|
||||
|
||||
for (i = 1; i < ((1 << width) - 1); i++) {
|
||||
/* Make sure we don't end up with a 0 multiplier */
|
||||
if ((bestmult == 0) &&
|
||||
!(mult->flags & CLK_MULTIPLIER_ZERO_BYPASS))
|
||||
bestmult = 1;
|
||||
|
||||
/* Make sure we don't overflow the multiplier */
|
||||
if (bestmult > maxmult)
|
||||
bestmult = maxmult;
|
||||
|
||||
return bestmult;
|
||||
}
|
||||
|
||||
for (i = 1; i < maxmult; i++) {
|
||||
if (rate == orig_parent_rate * i) {
|
||||
/*
|
||||
* This is the best case for us if we have a
|
||||
|
@ -253,11 +253,11 @@ static const struct clk_ops pll_clk_ops = {
|
||||
.recalc_rate = pll_clk_recalc_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
static struct clk_hw * __init
|
||||
pll_clk_register(struct device *dev, const char *name,
|
||||
const char *parent_name, u32 id)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
struct clk_pll *pll;
|
||||
struct clk_init_data init;
|
||||
|
||||
@ -281,11 +281,13 @@ pll_clk_register(struct device *dev, const char *name,
|
||||
|
||||
pr_debug("register PLL1 clock \"%s\"\n", name);
|
||||
|
||||
clk = clk_register(dev, &pll->hw);
|
||||
if (IS_ERR(clk))
|
||||
ret = clk_hw_register(dev, &pll->hw);
|
||||
if (ret) {
|
||||
kfree(pll);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return &pll->hw;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -345,11 +347,11 @@ static const struct clk_ops src_clk_ops = {
|
||||
.recalc_rate = src_clk_recalc_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
static struct clk_hw * __init
|
||||
src_clk_register(struct device *dev, const char *name,
|
||||
const char *parent_name, u8 id)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
struct clk_src *sclk;
|
||||
struct clk_init_data init;
|
||||
|
||||
@ -376,11 +378,13 @@ src_clk_register(struct device *dev, const char *name,
|
||||
pr_debug("register clock \"%s\" ID: %d group: %d bits: %08x\n",
|
||||
name, id, sclk->group1, sclk->clkbit);
|
||||
|
||||
clk = clk_register(dev, &sclk->hw);
|
||||
if (IS_ERR(clk))
|
||||
ret = clk_hw_register(dev, &sclk->hw);
|
||||
if (ret) {
|
||||
kfree(sclk);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return &sclk->hw;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
@ -508,7 +512,7 @@ device_initcall(nomadik_src_clk_init_debugfs);
|
||||
|
||||
static void __init of_nomadik_pll_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk = ERR_PTR(-EINVAL);
|
||||
struct clk_hw *hw;
|
||||
const char *clk_name = np->name;
|
||||
const char *parent_name;
|
||||
u32 pll_id;
|
||||
@ -522,16 +526,16 @@ static void __init of_nomadik_pll_setup(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
parent_name = of_clk_get_parent_name(np, 0);
|
||||
clk = pll_clk_register(NULL, clk_name, parent_name, pll_id);
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
hw = pll_clk_register(NULL, clk_name, parent_name, pll_id);
|
||||
if (!IS_ERR(hw))
|
||||
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
|
||||
}
|
||||
CLK_OF_DECLARE(nomadik_pll_clk,
|
||||
"st,nomadik-pll-clock", of_nomadik_pll_setup);
|
||||
|
||||
static void __init of_nomadik_hclk_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk = ERR_PTR(-EINVAL);
|
||||
struct clk_hw *hw;
|
||||
const char *clk_name = np->name;
|
||||
const char *parent_name;
|
||||
|
||||
@ -542,20 +546,20 @@ static void __init of_nomadik_hclk_setup(struct device_node *np)
|
||||
/*
|
||||
* The HCLK divides PLL1 with 1 (passthru), 2, 3 or 4.
|
||||
*/
|
||||
clk = clk_register_divider(NULL, clk_name, parent_name,
|
||||
hw = clk_hw_register_divider(NULL, clk_name, parent_name,
|
||||
0, src_base + SRC_CR,
|
||||
13, 2,
|
||||
CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
|
||||
&src_lock);
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
if (!IS_ERR(hw))
|
||||
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
|
||||
}
|
||||
CLK_OF_DECLARE(nomadik_hclk_clk,
|
||||
"st,nomadik-hclk-clock", of_nomadik_hclk_setup);
|
||||
|
||||
static void __init of_nomadik_src_clk_setup(struct device_node *np)
|
||||
{
|
||||
struct clk *clk = ERR_PTR(-EINVAL);
|
||||
struct clk_hw *hw;
|
||||
const char *clk_name = np->name;
|
||||
const char *parent_name;
|
||||
u32 clk_id;
|
||||
@ -569,9 +573,9 @@ static void __init of_nomadik_src_clk_setup(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
parent_name = of_clk_get_parent_name(np, 0);
|
||||
clk = src_clk_register(NULL, clk_name, parent_name, clk_id);
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
hw = src_clk_register(NULL, clk_name, parent_name, clk_id);
|
||||
if (!IS_ERR(hw))
|
||||
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
|
||||
}
|
||||
CLK_OF_DECLARE(nomadik_src_clk,
|
||||
"st,nomadik-src-clock", of_nomadik_src_clk_setup);
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/stringify.h>
|
||||
@ -170,26 +170,17 @@ static int oxnas_stdclk_probe(struct platform_device *pdev)
|
||||
clk_oxnas->onecell_data);
|
||||
}
|
||||
|
||||
static int oxnas_stdclk_remove(struct platform_device *pdev)
|
||||
{
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id oxnas_stdclk_dt_ids[] = {
|
||||
{ .compatible = "oxsemi,ox810se-stdclk" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, oxnas_stdclk_dt_ids);
|
||||
|
||||
static struct platform_driver oxnas_stdclk_driver = {
|
||||
.probe = oxnas_stdclk_probe,
|
||||
.remove = oxnas_stdclk_remove,
|
||||
.driver = {
|
||||
.name = "oxnas-stdclk",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = oxnas_stdclk_dt_ids,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(oxnas_stdclk_driver);
|
||||
builtin_platform_driver(oxnas_stdclk_driver);
|
||||
|
@ -137,7 +137,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct s2mps11_clk *s2mps11_clks;
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
unsigned int s2mps11_reg;
|
||||
int i, ret = 0;
|
||||
enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data;
|
||||
@ -147,15 +147,12 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
|
||||
if (!s2mps11_clks)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL);
|
||||
clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data) +
|
||||
sizeof(*clk_data->hws) * S2MPS11_CLKS_NUM,
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM,
|
||||
sizeof(struct clk *), GFP_KERNEL);
|
||||
if (!clk_data->clks)
|
||||
return -ENOMEM;
|
||||
|
||||
switch (hwid) {
|
||||
case S2MPS11X:
|
||||
s2mps11_reg = S2MPS11_REG_RTC_CTRL;
|
||||
@ -196,18 +193,18 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
|
||||
goto err_reg;
|
||||
}
|
||||
|
||||
s2mps11_clks[i].lookup = clkdev_create(s2mps11_clks[i].clk,
|
||||
s2mps11_clks[i].lookup = clkdev_hw_create(&s2mps11_clks[i].hw,
|
||||
s2mps11_clks_init[i].name, NULL);
|
||||
if (!s2mps11_clks[i].lookup) {
|
||||
ret = -ENOMEM;
|
||||
goto err_reg;
|
||||
}
|
||||
clk_data->clks[i] = s2mps11_clks[i].clk;
|
||||
clk_data->hws[i] = &s2mps11_clks[i].hw;
|
||||
}
|
||||
|
||||
clk_data->clk_num = S2MPS11_CLKS_NUM;
|
||||
of_clk_add_provider(s2mps11_clks->clk_np, of_clk_src_onecell_get,
|
||||
clk_data);
|
||||
clk_data->num = S2MPS11_CLKS_NUM;
|
||||
of_clk_add_hw_provider(s2mps11_clks->clk_np, of_clk_hw_onecell_get,
|
||||
clk_data);
|
||||
|
||||
platform_set_drvdata(pdev, s2mps11_clks);
|
||||
|
||||
|
@ -136,7 +136,7 @@ static const u64 stm32f42xx_gate_map[] = { 0x000000f17ef417ffull,
|
||||
0x0000000000000001ull,
|
||||
0x04777f33f6fec9ffull };
|
||||
|
||||
static struct clk *clks[MAX_CLKS];
|
||||
static struct clk_hw *clks[MAX_CLKS];
|
||||
static DEFINE_SPINLOCK(stm32f4_clk_lock);
|
||||
static void __iomem *base;
|
||||
|
||||
@ -281,7 +281,7 @@ static int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary)
|
||||
(BIT_ULL_WORD(secondary) >= 2 ? hweight64(table[2]) : 0);
|
||||
}
|
||||
|
||||
static struct clk *
|
||||
static struct clk_hw *
|
||||
stm32f4_rcc_lookup_clk(struct of_phandle_args *clkspec, void *data)
|
||||
{
|
||||
int i = stm32f4_rcc_lookup_clk_idx(clkspec->args[0], clkspec->args[1]);
|
||||
@ -346,9 +346,9 @@ static void __init stm32f4_rcc_init(struct device_node *np)
|
||||
clk_register_apb_mul(NULL, "apb2_mul", "apb2_div",
|
||||
CLK_SET_RATE_PARENT, 15);
|
||||
|
||||
clks[SYSTICK] = clk_register_fixed_factor(NULL, "systick", "ahb_div",
|
||||
clks[SYSTICK] = clk_hw_register_fixed_factor(NULL, "systick", "ahb_div",
|
||||
0, 1, 8);
|
||||
clks[FCLK] = clk_register_fixed_factor(NULL, "fclk", "ahb_div",
|
||||
clks[FCLK] = clk_hw_register_fixed_factor(NULL, "fclk", "ahb_div",
|
||||
0, 1, 1);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(stm32f4_gates); n++) {
|
||||
@ -360,18 +360,18 @@ static void __init stm32f4_rcc_init(struct device_node *np)
|
||||
if (idx < 0)
|
||||
goto fail;
|
||||
|
||||
clks[idx] = clk_register_gate(
|
||||
clks[idx] = clk_hw_register_gate(
|
||||
NULL, gd->name, gd->parent_name, gd->flags,
|
||||
base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock);
|
||||
|
||||
if (IS_ERR(clks[n])) {
|
||||
if (IS_ERR(clks[idx])) {
|
||||
pr_err("%s: Unable to register leaf clock %s\n",
|
||||
np->full_name, gd->name);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
of_clk_add_provider(np, stm32f4_rcc_lookup_clk, NULL);
|
||||
of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL);
|
||||
return;
|
||||
fail:
|
||||
iounmap(base);
|
||||
|
@ -689,7 +689,7 @@ static const struct clk_ops syscon_clk_ops = {
|
||||
.set_rate = syscon_clk_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
static struct clk_hw * __init
|
||||
syscon_clk_register(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
bool hw_ctrld,
|
||||
@ -697,9 +697,10 @@ syscon_clk_register(struct device *dev, const char *name,
|
||||
void __iomem *en_reg, u8 en_bit,
|
||||
u16 clk_val)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
struct clk_syscon *sclk;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
sclk = kzalloc(sizeof(struct clk_syscon), GFP_KERNEL);
|
||||
if (!sclk) {
|
||||
@ -722,11 +723,14 @@ syscon_clk_register(struct device *dev, const char *name,
|
||||
sclk->en_bit = en_bit;
|
||||
sclk->clk_val = clk_val;
|
||||
|
||||
clk = clk_register(dev, &sclk->hw);
|
||||
if (IS_ERR(clk))
|
||||
hw = &sclk->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret) {
|
||||
kfree(sclk);
|
||||
hw = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return hw;
|
||||
}
|
||||
|
||||
#define U300_CLK_TYPE_SLOW 0
|
||||
@ -868,7 +872,7 @@ static struct u300_clock const u300_clk_lookup[] __initconst = {
|
||||
|
||||
static void __init of_u300_syscon_clk_init(struct device_node *np)
|
||||
{
|
||||
struct clk *clk = ERR_PTR(-EINVAL);
|
||||
struct clk_hw *hw = ERR_PTR(-EINVAL);
|
||||
const char *clk_name = np->name;
|
||||
const char *parent_name;
|
||||
void __iomem *res_reg;
|
||||
@ -911,16 +915,15 @@ static void __init of_u300_syscon_clk_init(struct device_node *np)
|
||||
const struct u300_clock *u3clk = &u300_clk_lookup[i];
|
||||
|
||||
if (u3clk->type == clk_type && u3clk->id == clk_id)
|
||||
clk = syscon_clk_register(NULL,
|
||||
clk_name, parent_name,
|
||||
0, u3clk->hw_ctrld,
|
||||
res_reg, u3clk->id,
|
||||
en_reg, u3clk->id,
|
||||
u3clk->clk_val);
|
||||
hw = syscon_clk_register(NULL, clk_name, parent_name,
|
||||
0, u3clk->hw_ctrld,
|
||||
res_reg, u3clk->id,
|
||||
en_reg, u3clk->id,
|
||||
u3clk->clk_val);
|
||||
}
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
if (!IS_ERR(hw)) {
|
||||
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
|
||||
|
||||
/*
|
||||
* Some few system clocks - device tree does not
|
||||
@ -928,11 +931,11 @@ static void __init of_u300_syscon_clk_init(struct device_node *np)
|
||||
* for now we add these three clocks here.
|
||||
*/
|
||||
if (clk_type == U300_CLK_TYPE_REST && clk_id == 5)
|
||||
clk_register_clkdev(clk, NULL, "pl172");
|
||||
clk_hw_register_clkdev(hw, NULL, "pl172");
|
||||
if (clk_type == U300_CLK_TYPE_REST && clk_id == 9)
|
||||
clk_register_clkdev(clk, NULL, "semi");
|
||||
clk_hw_register_clkdev(hw, NULL, "semi");
|
||||
if (clk_type == U300_CLK_TYPE_REST && clk_id == 12)
|
||||
clk_register_clkdev(clk, NULL, "intcon");
|
||||
clk_hw_register_clkdev(hw, NULL, "intcon");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,13 +1114,14 @@ static const struct clk_ops mclk_ops = {
|
||||
.set_rate = mclk_clk_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
static struct clk_hw * __init
|
||||
mclk_clk_register(struct device *dev, const char *name,
|
||||
const char *parent_name, bool is_mspro)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
struct clk_mclk *mclk;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
mclk = kzalloc(sizeof(struct clk_mclk), GFP_KERNEL);
|
||||
if (!mclk) {
|
||||
@ -1133,23 +1137,26 @@ mclk_clk_register(struct device *dev, const char *name,
|
||||
mclk->hw.init = &init;
|
||||
mclk->is_mspro = is_mspro;
|
||||
|
||||
clk = clk_register(dev, &mclk->hw);
|
||||
if (IS_ERR(clk))
|
||||
hw = &mclk->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret) {
|
||||
kfree(mclk);
|
||||
hw = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return hw;
|
||||
}
|
||||
|
||||
static void __init of_u300_syscon_mclk_init(struct device_node *np)
|
||||
{
|
||||
struct clk *clk = ERR_PTR(-EINVAL);
|
||||
struct clk_hw *hw;
|
||||
const char *clk_name = np->name;
|
||||
const char *parent_name;
|
||||
|
||||
parent_name = of_clk_get_parent_name(np, 0);
|
||||
clk = mclk_clk_register(NULL, clk_name, parent_name, false);
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
hw = mclk_clk_register(NULL, clk_name, parent_name, false);
|
||||
if (!IS_ERR(hw))
|
||||
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
|
||||
}
|
||||
|
||||
static const struct of_device_id u300_clk_match[] __initconst = {
|
||||
|
@ -383,51 +383,49 @@ static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
u32 *multiplier, u32 *divisor1, u32 *divisor2)
|
||||
/*
|
||||
* M * parent [O1] => / P [O2] => / D [O3]
|
||||
* Where O1 is 900MHz...3GHz;
|
||||
* O2 is 600MHz >= (M * parent) / P >= 300MHz;
|
||||
* M is 36...120 [25MHz parent]; D is 1 or 2 or 4 or 8.
|
||||
* Possible ranges (O3):
|
||||
* D = 8: 37,5MHz...75MHz
|
||||
* D = 4: 75MHz...150MHz
|
||||
* D = 2: 150MHz...300MHz
|
||||
* D = 1: 300MHz...600MHz
|
||||
*/
|
||||
static int wm8650_find_pll_bits(unsigned long rate,
|
||||
unsigned long parent_rate, u32 *multiplier, u32 *divisor1,
|
||||
u32 *divisor2)
|
||||
{
|
||||
u32 mul, div1;
|
||||
int div2;
|
||||
u32 best_mul, best_div1, best_div2;
|
||||
unsigned long tclk, rate_err, best_err;
|
||||
unsigned long O1, min_err, rate_err;
|
||||
|
||||
best_err = (unsigned long)-1;
|
||||
|
||||
/* Find the closest match (lower or equal to requested) */
|
||||
for (div1 = 5; div1 >= 3; div1--)
|
||||
for (div2 = 3; div2 >= 0; div2--)
|
||||
for (mul = 3; mul <= 1023; mul++) {
|
||||
tclk = parent_rate * mul / (div1 * (1 << div2));
|
||||
if (tclk > rate)
|
||||
continue;
|
||||
/* error will always be +ve */
|
||||
rate_err = rate - tclk;
|
||||
if (rate_err == 0) {
|
||||
*multiplier = mul;
|
||||
*divisor1 = div1;
|
||||
*divisor2 = div2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rate_err < best_err) {
|
||||
best_err = rate_err;
|
||||
best_mul = mul;
|
||||
best_div1 = div1;
|
||||
best_div2 = div2;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_err == (unsigned long)-1) {
|
||||
pr_warn("%s: impossible rate %lu\n", __func__, rate);
|
||||
if (!parent_rate || (rate < 37500000) || (rate > 600000000))
|
||||
return -EINVAL;
|
||||
|
||||
*divisor2 = rate <= 75000000 ? 3 : rate <= 150000000 ? 2 :
|
||||
rate <= 300000000 ? 1 : 0;
|
||||
/*
|
||||
* Divisor P cannot be calculated. Test all divisors and find where M
|
||||
* will be as close as possible to the requested rate.
|
||||
*/
|
||||
min_err = ULONG_MAX;
|
||||
for (*divisor1 = 5; *divisor1 >= 3; (*divisor1)--) {
|
||||
O1 = rate * *divisor1 * (1 << (*divisor2));
|
||||
rate_err = O1 % parent_rate;
|
||||
if (rate_err < min_err) {
|
||||
*multiplier = O1 / parent_rate;
|
||||
if (rate_err == 0)
|
||||
return 0;
|
||||
|
||||
min_err = rate_err;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we got here, it wasn't an exact match */
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
|
||||
rate - best_err);
|
||||
*multiplier = best_mul;
|
||||
*divisor1 = best_div1;
|
||||
*divisor2 = best_div2;
|
||||
if ((*multiplier < 3) || (*multiplier > 1023))
|
||||
return -EINVAL;
|
||||
|
||||
pr_warn("%s: rate error is %lu\n", __func__, min_err);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -464,7 +462,6 @@ static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
{
|
||||
u32 mul;
|
||||
int div1, div2;
|
||||
u32 best_mul, best_div1, best_div2;
|
||||
unsigned long tclk, rate_err, best_err;
|
||||
|
||||
best_err = (unsigned long)-1;
|
||||
@ -488,9 +485,9 @@ static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
|
||||
if (rate_err < best_err) {
|
||||
best_err = rate_err;
|
||||
best_mul = mul;
|
||||
best_div1 = div1;
|
||||
best_div2 = div2;
|
||||
*multiplier = mul;
|
||||
*divisor1 = div1;
|
||||
*divisor2 = div2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,10 +500,7 @@ static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
|
||||
rate - best_err);
|
||||
|
||||
*filter = wm8750_get_filter(parent_rate, best_div1);
|
||||
*multiplier = best_mul;
|
||||
*divisor1 = best_div1;
|
||||
*divisor2 = best_div2;
|
||||
*filter = wm8750_get_filter(parent_rate, *divisor1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -516,7 +510,6 @@ static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
{
|
||||
u32 mul;
|
||||
int div1, div2;
|
||||
u32 best_mul, best_div1, best_div2;
|
||||
unsigned long tclk, rate_err, best_err;
|
||||
|
||||
best_err = (unsigned long)-1;
|
||||
@ -540,9 +533,9 @@ static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
|
||||
if (rate_err < best_err) {
|
||||
best_err = rate_err;
|
||||
best_mul = mul;
|
||||
best_div1 = div1;
|
||||
best_div2 = div2;
|
||||
*multiplier = mul;
|
||||
*divisor1 = div1;
|
||||
*divisor2 = div2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,10 +548,6 @@ static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate,
|
||||
pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate,
|
||||
rate - best_err);
|
||||
|
||||
*multiplier = best_mul;
|
||||
*divisor1 = best_div1;
|
||||
*divisor2 = best_div2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -172,104 +172,6 @@ static bool clk_core_is_enabled(struct clk_core *core)
|
||||
return core->ops->is_enabled(core->hw);
|
||||
}
|
||||
|
||||
static void clk_unprepare_unused_subtree(struct clk_core *core)
|
||||
{
|
||||
struct clk_core *child;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
hlist_for_each_entry(child, &core->children, child_node)
|
||||
clk_unprepare_unused_subtree(child);
|
||||
|
||||
if (core->prepare_count)
|
||||
return;
|
||||
|
||||
if (core->flags & CLK_IGNORE_UNUSED)
|
||||
return;
|
||||
|
||||
if (clk_core_is_prepared(core)) {
|
||||
trace_clk_unprepare(core);
|
||||
if (core->ops->unprepare_unused)
|
||||
core->ops->unprepare_unused(core->hw);
|
||||
else if (core->ops->unprepare)
|
||||
core->ops->unprepare(core->hw);
|
||||
trace_clk_unprepare_complete(core);
|
||||
}
|
||||
}
|
||||
|
||||
static void clk_disable_unused_subtree(struct clk_core *core)
|
||||
{
|
||||
struct clk_core *child;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
hlist_for_each_entry(child, &core->children, child_node)
|
||||
clk_disable_unused_subtree(child);
|
||||
|
||||
flags = clk_enable_lock();
|
||||
|
||||
if (core->enable_count)
|
||||
goto unlock_out;
|
||||
|
||||
if (core->flags & CLK_IGNORE_UNUSED)
|
||||
goto unlock_out;
|
||||
|
||||
/*
|
||||
* some gate clocks have special needs during the disable-unused
|
||||
* sequence. call .disable_unused if available, otherwise fall
|
||||
* back to .disable
|
||||
*/
|
||||
if (clk_core_is_enabled(core)) {
|
||||
trace_clk_disable(core);
|
||||
if (core->ops->disable_unused)
|
||||
core->ops->disable_unused(core->hw);
|
||||
else if (core->ops->disable)
|
||||
core->ops->disable(core->hw);
|
||||
trace_clk_disable_complete(core);
|
||||
}
|
||||
|
||||
unlock_out:
|
||||
clk_enable_unlock(flags);
|
||||
}
|
||||
|
||||
static bool clk_ignore_unused;
|
||||
static int __init clk_ignore_unused_setup(char *__unused)
|
||||
{
|
||||
clk_ignore_unused = true;
|
||||
return 1;
|
||||
}
|
||||
__setup("clk_ignore_unused", clk_ignore_unused_setup);
|
||||
|
||||
static int clk_disable_unused(void)
|
||||
{
|
||||
struct clk_core *core;
|
||||
|
||||
if (clk_ignore_unused) {
|
||||
pr_warn("clk: Not disabling unused clocks\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
hlist_for_each_entry(core, &clk_root_list, child_node)
|
||||
clk_disable_unused_subtree(core);
|
||||
|
||||
hlist_for_each_entry(core, &clk_orphan_list, child_node)
|
||||
clk_disable_unused_subtree(core);
|
||||
|
||||
hlist_for_each_entry(core, &clk_root_list, child_node)
|
||||
clk_unprepare_unused_subtree(core);
|
||||
|
||||
hlist_for_each_entry(core, &clk_orphan_list, child_node)
|
||||
clk_unprepare_unused_subtree(core);
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall_sync(clk_disable_unused);
|
||||
|
||||
/*** helper functions ***/
|
||||
|
||||
const char *__clk_get_name(const struct clk *clk)
|
||||
@ -591,6 +493,13 @@ static void clk_core_unprepare(struct clk_core *core)
|
||||
clk_core_unprepare(core->parent);
|
||||
}
|
||||
|
||||
static void clk_core_unprepare_lock(struct clk_core *core)
|
||||
{
|
||||
clk_prepare_lock();
|
||||
clk_core_unprepare(core);
|
||||
clk_prepare_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_unprepare - undo preparation of a clock source
|
||||
* @clk: the clk being unprepared
|
||||
@ -607,9 +516,7 @@ void clk_unprepare(struct clk *clk)
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
return;
|
||||
|
||||
clk_prepare_lock();
|
||||
clk_core_unprepare(clk->core);
|
||||
clk_prepare_unlock();
|
||||
clk_core_unprepare_lock(clk->core);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unprepare);
|
||||
|
||||
@ -645,6 +552,17 @@ static int clk_core_prepare(struct clk_core *core)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_core_prepare_lock(struct clk_core *core)
|
||||
{
|
||||
int ret;
|
||||
|
||||
clk_prepare_lock();
|
||||
ret = clk_core_prepare(core);
|
||||
clk_prepare_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_prepare - prepare a clock source
|
||||
* @clk: the clk being prepared
|
||||
@ -659,16 +577,10 @@ static int clk_core_prepare(struct clk_core *core)
|
||||
*/
|
||||
int clk_prepare(struct clk *clk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
clk_prepare_lock();
|
||||
ret = clk_core_prepare(clk->core);
|
||||
clk_prepare_unlock();
|
||||
|
||||
return ret;
|
||||
return clk_core_prepare_lock(clk->core);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_prepare);
|
||||
|
||||
@ -688,16 +600,25 @@ static void clk_core_disable(struct clk_core *core)
|
||||
if (--core->enable_count > 0)
|
||||
return;
|
||||
|
||||
trace_clk_disable(core);
|
||||
trace_clk_disable_rcuidle(core);
|
||||
|
||||
if (core->ops->disable)
|
||||
core->ops->disable(core->hw);
|
||||
|
||||
trace_clk_disable_complete(core);
|
||||
trace_clk_disable_complete_rcuidle(core);
|
||||
|
||||
clk_core_disable(core->parent);
|
||||
}
|
||||
|
||||
static void clk_core_disable_lock(struct clk_core *core)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
flags = clk_enable_lock();
|
||||
clk_core_disable(core);
|
||||
clk_enable_unlock(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_disable - gate a clock
|
||||
* @clk: the clk being gated
|
||||
@ -712,14 +633,10 @@ static void clk_core_disable(struct clk_core *core)
|
||||
*/
|
||||
void clk_disable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
return;
|
||||
|
||||
flags = clk_enable_lock();
|
||||
clk_core_disable(clk->core);
|
||||
clk_enable_unlock(flags);
|
||||
clk_core_disable_lock(clk->core);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_disable);
|
||||
|
||||
@ -741,12 +658,12 @@ static int clk_core_enable(struct clk_core *core)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
trace_clk_enable(core);
|
||||
trace_clk_enable_rcuidle(core);
|
||||
|
||||
if (core->ops->enable)
|
||||
ret = core->ops->enable(core->hw);
|
||||
|
||||
trace_clk_enable_complete(core);
|
||||
trace_clk_enable_complete_rcuidle(core);
|
||||
|
||||
if (ret) {
|
||||
clk_core_disable(core->parent);
|
||||
@ -758,6 +675,18 @@ static int clk_core_enable(struct clk_core *core)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_core_enable_lock(struct clk_core *core)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
flags = clk_enable_lock();
|
||||
ret = clk_core_enable(core);
|
||||
clk_enable_unlock(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_enable - ungate a clock
|
||||
* @clk: the clk being ungated
|
||||
@ -773,19 +702,136 @@ static int clk_core_enable(struct clk_core *core)
|
||||
*/
|
||||
int clk_enable(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
flags = clk_enable_lock();
|
||||
ret = clk_core_enable(clk->core);
|
||||
clk_enable_unlock(flags);
|
||||
return clk_core_enable_lock(clk->core);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_enable);
|
||||
|
||||
static int clk_core_prepare_enable(struct clk_core *core)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_core_prepare_lock(core);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_core_enable_lock(core);
|
||||
if (ret)
|
||||
clk_core_unprepare_lock(core);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_enable);
|
||||
|
||||
static void clk_core_disable_unprepare(struct clk_core *core)
|
||||
{
|
||||
clk_core_disable_lock(core);
|
||||
clk_core_unprepare_lock(core);
|
||||
}
|
||||
|
||||
static void clk_unprepare_unused_subtree(struct clk_core *core)
|
||||
{
|
||||
struct clk_core *child;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
hlist_for_each_entry(child, &core->children, child_node)
|
||||
clk_unprepare_unused_subtree(child);
|
||||
|
||||
if (core->prepare_count)
|
||||
return;
|
||||
|
||||
if (core->flags & CLK_IGNORE_UNUSED)
|
||||
return;
|
||||
|
||||
if (clk_core_is_prepared(core)) {
|
||||
trace_clk_unprepare(core);
|
||||
if (core->ops->unprepare_unused)
|
||||
core->ops->unprepare_unused(core->hw);
|
||||
else if (core->ops->unprepare)
|
||||
core->ops->unprepare(core->hw);
|
||||
trace_clk_unprepare_complete(core);
|
||||
}
|
||||
}
|
||||
|
||||
static void clk_disable_unused_subtree(struct clk_core *core)
|
||||
{
|
||||
struct clk_core *child;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
hlist_for_each_entry(child, &core->children, child_node)
|
||||
clk_disable_unused_subtree(child);
|
||||
|
||||
if (core->flags & CLK_OPS_PARENT_ENABLE)
|
||||
clk_core_prepare_enable(core->parent);
|
||||
|
||||
flags = clk_enable_lock();
|
||||
|
||||
if (core->enable_count)
|
||||
goto unlock_out;
|
||||
|
||||
if (core->flags & CLK_IGNORE_UNUSED)
|
||||
goto unlock_out;
|
||||
|
||||
/*
|
||||
* some gate clocks have special needs during the disable-unused
|
||||
* sequence. call .disable_unused if available, otherwise fall
|
||||
* back to .disable
|
||||
*/
|
||||
if (clk_core_is_enabled(core)) {
|
||||
trace_clk_disable(core);
|
||||
if (core->ops->disable_unused)
|
||||
core->ops->disable_unused(core->hw);
|
||||
else if (core->ops->disable)
|
||||
core->ops->disable(core->hw);
|
||||
trace_clk_disable_complete(core);
|
||||
}
|
||||
|
||||
unlock_out:
|
||||
clk_enable_unlock(flags);
|
||||
if (core->flags & CLK_OPS_PARENT_ENABLE)
|
||||
clk_core_disable_unprepare(core->parent);
|
||||
}
|
||||
|
||||
static bool clk_ignore_unused;
|
||||
static int __init clk_ignore_unused_setup(char *__unused)
|
||||
{
|
||||
clk_ignore_unused = true;
|
||||
return 1;
|
||||
}
|
||||
__setup("clk_ignore_unused", clk_ignore_unused_setup);
|
||||
|
||||
static int clk_disable_unused(void)
|
||||
{
|
||||
struct clk_core *core;
|
||||
|
||||
if (clk_ignore_unused) {
|
||||
pr_warn("clk: Not disabling unused clocks\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
hlist_for_each_entry(core, &clk_root_list, child_node)
|
||||
clk_disable_unused_subtree(core);
|
||||
|
||||
hlist_for_each_entry(core, &clk_orphan_list, child_node)
|
||||
clk_disable_unused_subtree(core);
|
||||
|
||||
hlist_for_each_entry(core, &clk_root_list, child_node)
|
||||
clk_unprepare_unused_subtree(core);
|
||||
|
||||
hlist_for_each_entry(core, &clk_orphan_list, child_node)
|
||||
clk_unprepare_unused_subtree(core);
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall_sync(clk_disable_unused);
|
||||
|
||||
static int clk_core_round_rate_nolock(struct clk_core *core,
|
||||
struct clk_rate_request *req)
|
||||
@ -828,9 +874,7 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
|
||||
/**
|
||||
* __clk_determine_rate - get the closest rate actually supported by a clock
|
||||
* @hw: determine the rate of this clock
|
||||
* @rate: target rate
|
||||
* @min_rate: returned rate must be greater than this rate
|
||||
* @max_rate: returned rate must be less than this rate
|
||||
* @req: target rate request
|
||||
*
|
||||
* Useful for clk_ops such as .set_rate and .determine_rate.
|
||||
*/
|
||||
@ -1128,7 +1172,9 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core,
|
||||
struct clk_core *old_parent = core->parent;
|
||||
|
||||
/*
|
||||
* Migrate prepare state between parents and prevent race with
|
||||
* 1. enable parents for CLK_OPS_PARENT_ENABLE clock
|
||||
*
|
||||
* 2. Migrate prepare state between parents and prevent race with
|
||||
* clk_enable().
|
||||
*
|
||||
* If the clock is not prepared, then a race with
|
||||
@ -1144,12 +1190,17 @@ static struct clk_core *__clk_set_parent_before(struct clk_core *core,
|
||||
*
|
||||
* See also: Comment for clk_set_parent() below.
|
||||
*/
|
||||
|
||||
/* enable old_parent & parent if CLK_OPS_PARENT_ENABLE is set */
|
||||
if (core->flags & CLK_OPS_PARENT_ENABLE) {
|
||||
clk_core_prepare_enable(old_parent);
|
||||
clk_core_prepare_enable(parent);
|
||||
}
|
||||
|
||||
/* migrate prepare count if > 0 */
|
||||
if (core->prepare_count) {
|
||||
clk_core_prepare(parent);
|
||||
flags = clk_enable_lock();
|
||||
clk_core_enable(parent);
|
||||
clk_core_enable(core);
|
||||
clk_enable_unlock(flags);
|
||||
clk_core_prepare_enable(parent);
|
||||
clk_core_enable_lock(core);
|
||||
}
|
||||
|
||||
/* update the clk tree topology */
|
||||
@ -1164,18 +1215,19 @@ static void __clk_set_parent_after(struct clk_core *core,
|
||||
struct clk_core *parent,
|
||||
struct clk_core *old_parent)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Finish the migration of prepare state and undo the changes done
|
||||
* for preventing a race with clk_enable().
|
||||
*/
|
||||
if (core->prepare_count) {
|
||||
flags = clk_enable_lock();
|
||||
clk_core_disable(core);
|
||||
clk_core_disable(old_parent);
|
||||
clk_enable_unlock(flags);
|
||||
clk_core_unprepare(old_parent);
|
||||
clk_core_disable_lock(core);
|
||||
clk_core_disable_unprepare(old_parent);
|
||||
}
|
||||
|
||||
/* re-balance ref counting if CLK_OPS_PARENT_ENABLE is set */
|
||||
if (core->flags & CLK_OPS_PARENT_ENABLE) {
|
||||
clk_core_disable_unprepare(parent);
|
||||
clk_core_disable_unprepare(old_parent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1422,13 +1474,17 @@ static void clk_change_rate(struct clk_core *core)
|
||||
unsigned long best_parent_rate = 0;
|
||||
bool skip_set_rate = false;
|
||||
struct clk_core *old_parent;
|
||||
struct clk_core *parent = NULL;
|
||||
|
||||
old_rate = core->rate;
|
||||
|
||||
if (core->new_parent)
|
||||
if (core->new_parent) {
|
||||
parent = core->new_parent;
|
||||
best_parent_rate = core->new_parent->rate;
|
||||
else if (core->parent)
|
||||
} else if (core->parent) {
|
||||
parent = core->parent;
|
||||
best_parent_rate = core->parent->rate;
|
||||
}
|
||||
|
||||
if (core->flags & CLK_SET_RATE_UNGATE) {
|
||||
unsigned long flags;
|
||||
@ -1456,6 +1512,9 @@ static void clk_change_rate(struct clk_core *core)
|
||||
__clk_set_parent_after(core, core->new_parent, old_parent);
|
||||
}
|
||||
|
||||
if (core->flags & CLK_OPS_PARENT_ENABLE)
|
||||
clk_core_prepare_enable(parent);
|
||||
|
||||
trace_clk_set_rate(core, core->new_rate);
|
||||
|
||||
if (!skip_set_rate && core->ops->set_rate)
|
||||
@ -1474,6 +1533,9 @@ static void clk_change_rate(struct clk_core *core)
|
||||
clk_core_unprepare(core);
|
||||
}
|
||||
|
||||
if (core->flags & CLK_OPS_PARENT_ENABLE)
|
||||
clk_core_disable_unprepare(parent);
|
||||
|
||||
if (core->notifier_count && old_rate != core->rate)
|
||||
__clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
|
||||
|
||||
@ -1501,7 +1563,6 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
|
||||
{
|
||||
struct clk_core *top, *fail_clk;
|
||||
unsigned long rate = req_rate;
|
||||
int ret = 0;
|
||||
|
||||
if (!core)
|
||||
return 0;
|
||||
@ -1532,7 +1593,7 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
|
||||
|
||||
core->req_rate = req_rate;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,6 +38,11 @@
|
||||
|
||||
#define HI3519_NR_CLKS 128
|
||||
|
||||
struct hi3519_crg_data {
|
||||
struct hisi_clock_data *clk_data;
|
||||
struct hisi_reset_controller *rstc;
|
||||
};
|
||||
|
||||
static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = {
|
||||
{ HI3519_FIXED_24M, "24m", NULL, 0, 24000000, },
|
||||
{ HI3519_FIXED_50M, "50m", NULL, 0, 50000000, },
|
||||
@ -80,33 +85,105 @@ static const struct hisi_gate_clock hi3519_gate_clks[] = {
|
||||
CLK_SET_RATE_PARENT, 0xe4, 18, 0, },
|
||||
};
|
||||
|
||||
static int hi3519_clk_probe(struct platform_device *pdev)
|
||||
static struct hisi_clock_data *hi3519_clk_register(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct hisi_clock_data *clk_data;
|
||||
struct hisi_reset_controller *rstc;
|
||||
int ret;
|
||||
|
||||
rstc = hisi_reset_init(np);
|
||||
if (!rstc)
|
||||
return -ENOMEM;
|
||||
clk_data = hisi_clk_alloc(pdev, HI3519_NR_CLKS);
|
||||
if (!clk_data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_data = hisi_clk_init(np, HI3519_NR_CLKS);
|
||||
if (!clk_data) {
|
||||
hisi_reset_exit(rstc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
|
||||
ret = hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
|
||||
ARRAY_SIZE(hi3519_fixed_rate_clks),
|
||||
clk_data);
|
||||
hisi_clk_register_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks),
|
||||
clk_data);
|
||||
hisi_clk_register_gate(hi3519_gate_clks,
|
||||
ARRAY_SIZE(hi3519_gate_clks), clk_data);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
ret = hisi_clk_register_mux(hi3519_mux_clks,
|
||||
ARRAY_SIZE(hi3519_mux_clks),
|
||||
clk_data);
|
||||
if (ret)
|
||||
goto unregister_fixed_rate;
|
||||
|
||||
ret = hisi_clk_register_gate(hi3519_gate_clks,
|
||||
ARRAY_SIZE(hi3519_gate_clks),
|
||||
clk_data);
|
||||
if (ret)
|
||||
goto unregister_mux;
|
||||
|
||||
ret = of_clk_add_provider(pdev->dev.of_node,
|
||||
of_clk_src_onecell_get, &clk_data->clk_data);
|
||||
if (ret)
|
||||
goto unregister_gate;
|
||||
|
||||
return clk_data;
|
||||
|
||||
unregister_fixed_rate:
|
||||
hisi_clk_unregister_fixed_rate(hi3519_fixed_rate_clks,
|
||||
ARRAY_SIZE(hi3519_fixed_rate_clks),
|
||||
clk_data);
|
||||
|
||||
unregister_mux:
|
||||
hisi_clk_unregister_mux(hi3519_mux_clks,
|
||||
ARRAY_SIZE(hi3519_mux_clks),
|
||||
clk_data);
|
||||
unregister_gate:
|
||||
hisi_clk_unregister_gate(hi3519_gate_clks,
|
||||
ARRAY_SIZE(hi3519_gate_clks),
|
||||
clk_data);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static void hi3519_clk_unregister(struct platform_device *pdev)
|
||||
{
|
||||
struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
|
||||
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
|
||||
hisi_clk_unregister_gate(hi3519_gate_clks,
|
||||
ARRAY_SIZE(hi3519_mux_clks),
|
||||
crg->clk_data);
|
||||
hisi_clk_unregister_mux(hi3519_mux_clks,
|
||||
ARRAY_SIZE(hi3519_mux_clks),
|
||||
crg->clk_data);
|
||||
hisi_clk_unregister_fixed_rate(hi3519_fixed_rate_clks,
|
||||
ARRAY_SIZE(hi3519_fixed_rate_clks),
|
||||
crg->clk_data);
|
||||
}
|
||||
|
||||
static int hi3519_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct hi3519_crg_data *crg;
|
||||
|
||||
crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL);
|
||||
if (!crg)
|
||||
return -ENOMEM;
|
||||
|
||||
crg->rstc = hisi_reset_init(pdev);
|
||||
if (!crg->rstc)
|
||||
return -ENOMEM;
|
||||
|
||||
crg->clk_data = hi3519_clk_register(pdev);
|
||||
if (IS_ERR(crg->clk_data)) {
|
||||
hisi_reset_exit(crg->rstc);
|
||||
return PTR_ERR(crg->clk_data);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, crg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hi3519_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
|
||||
|
||||
hisi_reset_exit(crg->rstc);
|
||||
hi3519_clk_unregister(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct of_device_id hi3519_clk_match_table[] = {
|
||||
{ .compatible = "hisilicon,hi3519-crg" },
|
||||
{ }
|
||||
@ -115,6 +192,7 @@ MODULE_DEVICE_TABLE(of, hi3519_clk_match_table);
|
||||
|
||||
static struct platform_driver hi3519_clk_driver = {
|
||||
.probe = hi3519_clk_probe,
|
||||
.remove = hi3519_clk_remove,
|
||||
.driver = {
|
||||
.name = "hi3519-clk",
|
||||
.of_match_table = hi3519_clk_match_table,
|
||||
@ -127,5 +205,11 @@ static int __init hi3519_clk_init(void)
|
||||
}
|
||||
core_initcall(hi3519_clk_init);
|
||||
|
||||
static void __exit hi3519_clk_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&hi3519_clk_driver);
|
||||
}
|
||||
module_exit(hi3519_clk_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver");
|
||||
|
@ -34,8 +34,8 @@ static struct hisi_fixed_rate_clock hi6220_fixed_rate_clks[] __initdata = {
|
||||
{ HI6220_PLL_BBP, "bbppll0", NULL, 0, 245760000, },
|
||||
{ HI6220_PLL_GPU, "gpupll", NULL, 0, 1000000000,},
|
||||
{ HI6220_PLL1_DDR, "ddrpll1", NULL, 0, 1066000000,},
|
||||
{ HI6220_PLL_SYS, "syspll", NULL, 0, 1200000000,},
|
||||
{ HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, 0, 1200000000,},
|
||||
{ HI6220_PLL_SYS, "syspll", NULL, 0, 1190400000,},
|
||||
{ HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, 0, 1190400000,},
|
||||
{ HI6220_DDR_SRC, "ddr_sel_src", NULL, 0, 1200000000,},
|
||||
{ HI6220_PLL_MEDIA, "media_pll", NULL, 0, 1440000000,},
|
||||
{ HI6220_PLL_DDR, "ddrpll0", NULL, 0, 1600000000,},
|
||||
@ -68,6 +68,8 @@ static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = {
|
||||
{ HI6220_TIMER7_PCLK, "timer7_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 22, 0, },
|
||||
{ HI6220_TIMER8_PCLK, "timer8_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 23, 0, },
|
||||
{ HI6220_UART0_PCLK, "uart0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 24, 0, },
|
||||
{ HI6220_RTC0_PCLK, "rtc0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 25, 0, },
|
||||
{ HI6220_RTC1_PCLK, "rtc1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 26, 0, },
|
||||
};
|
||||
|
||||
static void __init hi6220_clk_ao_init(struct device_node *np)
|
||||
|
@ -37,6 +37,35 @@
|
||||
|
||||
static DEFINE_SPINLOCK(hisi_clk_lock);
|
||||
|
||||
struct hisi_clock_data *hisi_clk_alloc(struct platform_device *pdev,
|
||||
int nr_clks)
|
||||
{
|
||||
struct hisi_clock_data *clk_data;
|
||||
struct resource *res;
|
||||
struct clk **clk_table;
|
||||
|
||||
clk_data = devm_kmalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return NULL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
clk_data->base = devm_ioremap(&pdev->dev,
|
||||
res->start, resource_size(res));
|
||||
if (!clk_data->base)
|
||||
return NULL;
|
||||
|
||||
clk_table = devm_kmalloc(&pdev->dev, sizeof(struct clk *) * nr_clks,
|
||||
GFP_KERNEL);
|
||||
if (!clk_table)
|
||||
return NULL;
|
||||
|
||||
clk_data->clk_data.clks = clk_table;
|
||||
clk_data->clk_data.clk_num = nr_clks;
|
||||
|
||||
return clk_data;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_alloc);
|
||||
|
||||
struct hisi_clock_data *hisi_clk_init(struct device_node *np,
|
||||
int nr_clks)
|
||||
{
|
||||
@ -73,7 +102,7 @@ err:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_init);
|
||||
|
||||
void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
|
||||
int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
|
||||
int nums, struct hisi_clock_data *data)
|
||||
{
|
||||
struct clk *clk;
|
||||
@ -87,14 +116,22 @@ void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register clock %s\n",
|
||||
__func__, clks[i].name);
|
||||
continue;
|
||||
goto err;
|
||||
}
|
||||
data->clk_data.clks[clks[i].id] = clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
while (i--)
|
||||
clk_unregister_fixed_rate(data->clk_data.clks[clks[i].id]);
|
||||
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_rate);
|
||||
|
||||
void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
|
||||
int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
|
||||
int nums,
|
||||
struct hisi_clock_data *data)
|
||||
{
|
||||
@ -109,14 +146,22 @@ void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register clock %s\n",
|
||||
__func__, clks[i].name);
|
||||
continue;
|
||||
goto err;
|
||||
}
|
||||
data->clk_data.clks[clks[i].id] = clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
while (i--)
|
||||
clk_unregister_fixed_factor(data->clk_data.clks[clks[i].id]);
|
||||
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_factor);
|
||||
|
||||
void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
|
||||
int hisi_clk_register_mux(const struct hisi_mux_clock *clks,
|
||||
int nums, struct hisi_clock_data *data)
|
||||
{
|
||||
struct clk *clk;
|
||||
@ -135,7 +180,7 @@ void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register clock %s\n",
|
||||
__func__, clks[i].name);
|
||||
continue;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (clks[i].alias)
|
||||
@ -143,10 +188,18 @@ void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
|
||||
|
||||
data->clk_data.clks[clks[i].id] = clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
while (i--)
|
||||
clk_unregister_mux(data->clk_data.clks[clks[i].id]);
|
||||
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_register_mux);
|
||||
|
||||
void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
|
||||
int hisi_clk_register_divider(const struct hisi_divider_clock *clks,
|
||||
int nums, struct hisi_clock_data *data)
|
||||
{
|
||||
struct clk *clk;
|
||||
@ -165,7 +218,7 @@ void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register clock %s\n",
|
||||
__func__, clks[i].name);
|
||||
continue;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (clks[i].alias)
|
||||
@ -173,10 +226,18 @@ void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
|
||||
|
||||
data->clk_data.clks[clks[i].id] = clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
while (i--)
|
||||
clk_unregister_divider(data->clk_data.clks[clks[i].id]);
|
||||
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_register_divider);
|
||||
|
||||
void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
|
||||
int hisi_clk_register_gate(const struct hisi_gate_clock *clks,
|
||||
int nums, struct hisi_clock_data *data)
|
||||
{
|
||||
struct clk *clk;
|
||||
@ -194,7 +255,7 @@ void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register clock %s\n",
|
||||
__func__, clks[i].name);
|
||||
continue;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (clks[i].alias)
|
||||
@ -202,6 +263,14 @@ void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
|
||||
|
||||
data->clk_data.clks[clks[i].id] = clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
while (i--)
|
||||
clk_unregister_gate(data->clk_data.clks[clks[i].id]);
|
||||
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_clk_register_gate);
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
struct platform_device;
|
||||
|
||||
struct hisi_clock_data {
|
||||
struct clk_onecell_data clk_data;
|
||||
void __iomem *base;
|
||||
@ -110,19 +112,41 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags, void __iomem *reg,
|
||||
u8 shift, u8 width, u32 mask_bit, spinlock_t *lock);
|
||||
|
||||
struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int);
|
||||
struct hisi_clock_data *hisi_clk_init(struct device_node *, int);
|
||||
void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
|
||||
int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
|
||||
int, struct hisi_clock_data *);
|
||||
void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
|
||||
int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
|
||||
int, struct hisi_clock_data *);
|
||||
void hisi_clk_register_mux(const struct hisi_mux_clock *, int,
|
||||
int hisi_clk_register_mux(const struct hisi_mux_clock *, int,
|
||||
struct hisi_clock_data *);
|
||||
void hisi_clk_register_divider(const struct hisi_divider_clock *,
|
||||
int hisi_clk_register_divider(const struct hisi_divider_clock *,
|
||||
int, struct hisi_clock_data *);
|
||||
void hisi_clk_register_gate(const struct hisi_gate_clock *,
|
||||
int hisi_clk_register_gate(const struct hisi_gate_clock *,
|
||||
int, struct hisi_clock_data *);
|
||||
void hisi_clk_register_gate_sep(const struct hisi_gate_clock *,
|
||||
int, struct hisi_clock_data *);
|
||||
void hi6220_clk_register_divider(const struct hi6220_divider_clock *,
|
||||
int, struct hisi_clock_data *);
|
||||
|
||||
#define hisi_clk_unregister(type) \
|
||||
static inline \
|
||||
void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \
|
||||
int nums, struct hisi_clock_data *data) \
|
||||
{ \
|
||||
struct clk **clocks = data->clk_data.clks; \
|
||||
int i; \
|
||||
for (i = 0; i < nums; i++) { \
|
||||
int id = clks[i].id; \
|
||||
if (clocks[id]) \
|
||||
clk_unregister_##type(clocks[id]); \
|
||||
} \
|
||||
}
|
||||
|
||||
hisi_clk_unregister(fixed_rate)
|
||||
hisi_clk_unregister(fixed_factor)
|
||||
hisi_clk_unregister(mux)
|
||||
hisi_clk_unregister(divider)
|
||||
hisi_clk_unregister(gate)
|
||||
|
||||
#endif /* __HISI_CLK_H */
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define div_mask(width) ((1 << (width)) - 1)
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
@ -98,25 +99,25 @@ static const struct reset_control_ops hisi_reset_ops = {
|
||||
.deassert = hisi_reset_deassert,
|
||||
};
|
||||
|
||||
struct hisi_reset_controller *hisi_reset_init(struct device_node *np)
|
||||
struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
|
||||
{
|
||||
struct hisi_reset_controller *rstc;
|
||||
struct resource *res;
|
||||
|
||||
rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
|
||||
rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL);
|
||||
if (!rstc)
|
||||
return NULL;
|
||||
|
||||
rstc->membase = of_iomap(np, 0);
|
||||
if (!rstc->membase) {
|
||||
kfree(rstc);
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rstc->membase = devm_ioremap(&pdev->dev,
|
||||
res->start, resource_size(res));
|
||||
if (!rstc->membase)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spin_lock_init(&rstc->lock);
|
||||
|
||||
rstc->rcdev.owner = THIS_MODULE;
|
||||
rstc->rcdev.ops = &hisi_reset_ops;
|
||||
rstc->rcdev.of_node = np;
|
||||
rstc->rcdev.of_node = pdev->dev.of_node;
|
||||
rstc->rcdev.of_reset_n_cells = 2;
|
||||
rstc->rcdev.of_xlate = hisi_reset_of_xlate;
|
||||
reset_controller_register(&rstc->rcdev);
|
||||
@ -128,7 +129,5 @@ EXPORT_SYMBOL_GPL(hisi_reset_init);
|
||||
void hisi_reset_exit(struct hisi_reset_controller *rstc)
|
||||
{
|
||||
reset_controller_unregister(&rstc->rcdev);
|
||||
iounmap(rstc->membase);
|
||||
kfree(rstc);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_reset_exit);
|
||||
|
@ -22,10 +22,11 @@ struct device_node;
|
||||
struct hisi_reset_controller;
|
||||
|
||||
#ifdef CONFIG_RESET_CONTROLLER
|
||||
struct hisi_reset_controller *hisi_reset_init(struct device_node *np);
|
||||
struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev);
|
||||
void hisi_reset_exit(struct hisi_reset_controller *rstc);
|
||||
#else
|
||||
static inline hisi_reset_controller *hisi_reset_init(struct device_node *np)
|
||||
static inline
|
||||
struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -192,13 +192,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
clk[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
|
||||
|
||||
/* type name parent_name base div_mask */
|
||||
clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
|
||||
clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
|
||||
clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
|
||||
clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
|
||||
clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
|
||||
clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
|
||||
clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
|
||||
clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
|
||||
clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
|
||||
clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
|
||||
clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
|
||||
clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
|
||||
clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3);
|
||||
clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
|
||||
|
||||
clk[IMX6QDL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clk[IMX6QDL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
@ -218,13 +218,13 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
|
||||
|
||||
/* type name parent_name base div_mask */
|
||||
clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
|
||||
clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
|
||||
clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
|
||||
clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
|
||||
clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
|
||||
clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
|
||||
clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3);
|
||||
clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
|
||||
|
||||
clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
@ -174,13 +174,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
|
||||
|
||||
/* type name parent_name base div_mask */
|
||||
clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
|
||||
clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
|
||||
clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
|
||||
clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
|
||||
clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
|
||||
clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
|
||||
clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
|
||||
clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
|
||||
clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
|
||||
clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
|
||||
clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
|
||||
clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
|
||||
clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3);
|
||||
clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
|
||||
|
||||
clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
@ -130,13 +130,13 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
|
||||
clks[IMX6UL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
|
||||
|
||||
clks[IMX6UL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f);
|
||||
clks[IMX6UL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1);
|
||||
clks[IMX6UL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3);
|
||||
clks[IMX6UL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f);
|
||||
clks[IMX6UL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f);
|
||||
clks[IMX6UL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3);
|
||||
clks[IMX6UL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3);
|
||||
clks[IMX6UL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
|
||||
clks[IMX6UL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
|
||||
clks[IMX6UL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
|
||||
clks[IMX6UL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
|
||||
clks[IMX6UL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
|
||||
clks[IMX6UL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3);
|
||||
clks[IMX6UL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
|
||||
|
||||
clks[IMX6UL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX6UL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
@ -305,8 +305,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16);
|
||||
clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
|
||||
clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20);
|
||||
clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x68, 24);
|
||||
clks[IMX6UL_CLK_GPT2_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x68, 26);
|
||||
clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt2_bus", "perclk", base + 0x68, 24);
|
||||
clks[IMX6UL_CLK_GPT2_SERIAL] = imx_clk_gate2("gpt2_serial", "perclk", base + 0x68, 26);
|
||||
clks[IMX6UL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28);
|
||||
clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28);
|
||||
clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30);
|
||||
|
@ -65,7 +65,7 @@ static const char *dram_phym_sel[] = { "pll_dram_main_clk",
|
||||
"dram_phym_alt_clk", };
|
||||
|
||||
static const char *dram_sel[] = { "pll_dram_main_clk",
|
||||
"dram_alt_clk", };
|
||||
"dram_alt_root_clk", };
|
||||
|
||||
static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
|
||||
"pll_sys_main_clk", "pll_enet_500m_clk",
|
||||
@ -361,6 +361,14 @@ static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src
|
||||
static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", };
|
||||
static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", };
|
||||
|
||||
static int const clks_init_on[] __initconst = {
|
||||
IMX7D_ARM_A7_ROOT_CLK, IMX7D_MAIN_AXI_ROOT_CLK,
|
||||
IMX7D_PLL_SYS_MAIN_480M_CLK, IMX7D_NAND_USDHC_BUS_ROOT_CLK,
|
||||
IMX7D_DRAM_PHYM_ROOT_CLK, IMX7D_DRAM_ROOT_CLK,
|
||||
IMX7D_DRAM_PHYM_ALT_ROOT_CLK, IMX7D_DRAM_ALT_ROOT_CLK,
|
||||
IMX7D_AHB_CHANNEL_ROOT_CLK,
|
||||
};
|
||||
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
static struct clk ** const uart_clks[] __initconst = {
|
||||
@ -395,12 +403,12 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
||||
clks[IMX7D_PLL_AUDIO_MAIN_SRC] = imx_clk_mux("pll_audio_main_src", base + 0xf0, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
|
||||
clks[IMX7D_PLL_VIDEO_MAIN_SRC] = imx_clk_mux("pll_video_main_src", base + 0x130, 14, 2, pll_bypass_src_sel, ARRAY_SIZE(pll_bypass_src_sel));
|
||||
|
||||
clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "pll_arm_main_src", base + 0x60, 0x7f);
|
||||
clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_dram_main", "pll_dram_main_src", base + 0x70, 0x7f);
|
||||
clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "pll_sys_main_src", base + 0xb0, 0x1);
|
||||
clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "pll_enet_main_src", base + 0xe0, 0x0);
|
||||
clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "pll_audio_main_src", base + 0xf0, 0x7f);
|
||||
clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "pll_video_main_src", base + 0x130, 0x7f);
|
||||
clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "osc", base + 0x60, 0x7f);
|
||||
clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_dram_main", "osc", base + 0x70, 0x7f);
|
||||
clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1);
|
||||
clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0);
|
||||
clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "osc", base + 0xf0, 0x7f);
|
||||
clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "osc", base + 0x130, 0x7f);
|
||||
|
||||
clks[IMX7D_PLL_ARM_MAIN_BYPASS] = imx_clk_mux_flags("pll_arm_main_bypass", base + 0x60, 16, 1, pll_arm_bypass_sel, ARRAY_SIZE(pll_arm_bypass_sel), CLK_SET_RATE_PARENT);
|
||||
clks[IMX7D_PLL_DRAM_MAIN_BYPASS] = imx_clk_mux_flags("pll_dram_main_bypass", base + 0x70, 16, 1, pll_dram_bypass_sel, ARRAY_SIZE(pll_dram_bypass_sel), CLK_SET_RATE_PARENT);
|
||||
@ -474,363 +482,363 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
|
||||
clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
|
||||
clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
|
||||
clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
|
||||
clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
|
||||
clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
|
||||
clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
|
||||
clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
|
||||
clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
|
||||
clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
|
||||
clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
|
||||
clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
|
||||
clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
|
||||
clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
|
||||
clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
|
||||
clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
|
||||
clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
|
||||
clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
|
||||
clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
|
||||
clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
|
||||
clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
|
||||
clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
|
||||
clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
|
||||
clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
|
||||
clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
|
||||
clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
|
||||
clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
|
||||
clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
|
||||
clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
|
||||
clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
|
||||
clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
|
||||
clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
|
||||
clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
|
||||
clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
|
||||
clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
|
||||
clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
|
||||
clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
|
||||
clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
|
||||
clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
|
||||
clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
|
||||
clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
|
||||
clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
|
||||
clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
|
||||
clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
|
||||
clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
|
||||
clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
|
||||
clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
|
||||
clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
|
||||
clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
|
||||
clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
|
||||
clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
|
||||
clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
|
||||
clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
|
||||
clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
|
||||
clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
|
||||
clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
|
||||
clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
|
||||
clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
|
||||
clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
|
||||
clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
|
||||
clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux2("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
|
||||
clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
|
||||
clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux2("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
|
||||
clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
|
||||
clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
|
||||
clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux2("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux2("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
|
||||
clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux2("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
|
||||
clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux2("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
|
||||
clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
|
||||
clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux2("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
|
||||
clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
|
||||
clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux2("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
|
||||
clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
|
||||
clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux2("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
|
||||
clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux2("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
|
||||
clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux2("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
|
||||
clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux2("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
|
||||
clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux2("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
|
||||
clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux2("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
|
||||
clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux2("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
|
||||
clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux2("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux2("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
|
||||
clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux2("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
|
||||
clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux2("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
|
||||
clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux2("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
|
||||
clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux2("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
|
||||
clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux2("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
|
||||
clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux2("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
|
||||
clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux2("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
|
||||
clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux2("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
|
||||
clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux2("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
|
||||
clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux2("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
|
||||
clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux2("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
|
||||
clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux2("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
|
||||
clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux2("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
|
||||
clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux2("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
|
||||
clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux2("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
|
||||
clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux2("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
|
||||
clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux2("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
|
||||
clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux2("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
|
||||
clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux2("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
|
||||
clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux2("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
|
||||
clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux2("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
|
||||
clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux2("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
|
||||
clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux2("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
|
||||
clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux2("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
|
||||
clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux2("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
|
||||
clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux2("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
|
||||
clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux2("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux2("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux2("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
|
||||
clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux2("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
|
||||
clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux2("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
|
||||
clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux2("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
|
||||
clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux2("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
|
||||
clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux2("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
|
||||
clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux2("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
|
||||
clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux2("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
|
||||
clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux2("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
|
||||
clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux2("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux2("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
|
||||
clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux2("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
|
||||
clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux2("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
|
||||
clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux2("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
|
||||
|
||||
clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
|
||||
clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate("axi_cg", "axi_src", base + 0x8800, 28);
|
||||
clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
|
||||
clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate("ahb_cg", "ahb_src", base + 0x9000, 28);
|
||||
clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate("dram_phym_cg", "dram_phym_src", base + 0x9800, 28);
|
||||
clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate("dram_cg", "dram_src", base + 0x9880, 28);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate("dram_alt_cg", "dram_alt_src", base + 0xa080, 28);
|
||||
clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28);
|
||||
clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate("sai1_cg", "sai1_src", base + 0xa500, 28);
|
||||
clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate("sai2_cg", "sai2_src", base + 0xa580, 28);
|
||||
clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate("sai3_cg", "sai3_src", base + 0xa600, 28);
|
||||
clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate("spdif_cg", "spdif_src", base + 0xa680, 28);
|
||||
clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate("enet1_time_cg", "enet1_time_src", base + 0xa780, 28);
|
||||
clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate("enet2_time_cg", "enet2_time_src", base + 0xa880, 28);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28);
|
||||
clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate("eim_cg", "eim_src", base + 0xa980, 28);
|
||||
clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate("nand_cg", "nand_src", base + 0xaa00, 28);
|
||||
clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate("qspi_cg", "qspi_src", base + 0xaa80, 28);
|
||||
clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate("usdhc1_cg", "usdhc1_src", base + 0xab00, 28);
|
||||
clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate("usdhc2_cg", "usdhc2_src", base + 0xab80, 28);
|
||||
clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate("usdhc3_cg", "usdhc3_src", base + 0xac00, 28);
|
||||
clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate("can1_cg", "can1_src", base + 0xac80, 28);
|
||||
clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate("can2_cg", "can2_src", base + 0xad00, 28);
|
||||
clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate("i2c1_cg", "i2c1_src", base + 0xad80, 28);
|
||||
clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate("i2c2_cg", "i2c2_src", base + 0xae00, 28);
|
||||
clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate("i2c3_cg", "i2c3_src", base + 0xae80, 28);
|
||||
clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate("i2c4_cg", "i2c4_src", base + 0xaf00, 28);
|
||||
clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate("uart1_cg", "uart1_src", base + 0xaf80, 28);
|
||||
clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate("uart2_cg", "uart2_src", base + 0xb000, 28);
|
||||
clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate("uart3_cg", "uart3_src", base + 0xb080, 28);
|
||||
clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate("uart4_cg", "uart4_src", base + 0xb100, 28);
|
||||
clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate("uart5_cg", "uart5_src", base + 0xb180, 28);
|
||||
clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate("uart6_cg", "uart6_src", base + 0xb200, 28);
|
||||
clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate("uart7_cg", "uart7_src", base + 0xb280, 28);
|
||||
clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate("ecspi1_cg", "ecspi1_src", base + 0xb300, 28);
|
||||
clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate("ecspi2_cg", "ecspi2_src", base + 0xb380, 28);
|
||||
clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate("ecspi3_cg", "ecspi3_src", base + 0xb400, 28);
|
||||
clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate("ecspi4_cg", "ecspi4_src", base + 0xb480, 28);
|
||||
clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate("pwm1_cg", "pwm1_src", base + 0xb500, 28);
|
||||
clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate("pwm2_cg", "pwm2_src", base + 0xb580, 28);
|
||||
clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate("pwm3_cg", "pwm3_src", base + 0xb600, 28);
|
||||
clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate("pwm4_cg", "pwm4_src", base + 0xb680, 28);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate("flextimer1_cg", "flextimer1_src", base + 0xb700, 28);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate("flextimer2_cg", "flextimer2_src", base + 0xb780, 28);
|
||||
clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate("sim1_cg", "sim1_src", base + 0xb800, 28);
|
||||
clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate("sim2_cg", "sim2_src", base + 0xb880, 28);
|
||||
clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate("gpt1_cg", "gpt1_src", base + 0xb900, 28);
|
||||
clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate("gpt2_cg", "gpt2_src", base + 0xb980, 28);
|
||||
clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate("gpt3_cg", "gpt3_src", base + 0xbA00, 28);
|
||||
clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate("gpt4_cg", "gpt4_src", base + 0xbA80, 28);
|
||||
clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate("trace_cg", "trace_src", base + 0xbb00, 28);
|
||||
clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate("wdog_cg", "wdog_src", base + 0xbb80, 28);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28);
|
||||
clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate("wrclk_cg", "wrclk_src", base + 0xbd00, 28);
|
||||
clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate("clko1_cg", "clko1_src", base + 0xbd80, 28);
|
||||
clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate("clko2_cg", "clko2_src", base + 0xbe00, 28);
|
||||
clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
|
||||
clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate3("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate3("axi_cg", "axi_src", base + 0x8800, 28);
|
||||
clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate3("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
|
||||
clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate3("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate3("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate3("ahb_cg", "ahb_src", base + 0x9000, 28);
|
||||
clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate3("dram_phym_cg", "dram_phym_src", base + 0x9800, 28);
|
||||
clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate3("dram_cg", "dram_src", base + 0x9880, 28);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate3("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate3("dram_alt_cg", "dram_alt_src", base + 0xa080, 28);
|
||||
clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate3("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate3("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate3("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate3("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate3("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate3("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate3("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate3("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28);
|
||||
clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate3("sai1_cg", "sai1_src", base + 0xa500, 28);
|
||||
clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate3("sai2_cg", "sai2_src", base + 0xa580, 28);
|
||||
clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate3("sai3_cg", "sai3_src", base + 0xa600, 28);
|
||||
clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate3("spdif_cg", "spdif_src", base + 0xa680, 28);
|
||||
clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate3("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate3("enet1_time_cg", "enet1_time_src", base + 0xa780, 28);
|
||||
clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate3("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate3("enet2_time_cg", "enet2_time_src", base + 0xa880, 28);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate3("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28);
|
||||
clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate3("eim_cg", "eim_src", base + 0xa980, 28);
|
||||
clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate3("nand_cg", "nand_src", base + 0xaa00, 28);
|
||||
clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate3("qspi_cg", "qspi_src", base + 0xaa80, 28);
|
||||
clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate3("usdhc1_cg", "usdhc1_src", base + 0xab00, 28);
|
||||
clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate3("usdhc2_cg", "usdhc2_src", base + 0xab80, 28);
|
||||
clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate3("usdhc3_cg", "usdhc3_src", base + 0xac00, 28);
|
||||
clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate3("can1_cg", "can1_src", base + 0xac80, 28);
|
||||
clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate3("can2_cg", "can2_src", base + 0xad00, 28);
|
||||
clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate3("i2c1_cg", "i2c1_src", base + 0xad80, 28);
|
||||
clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate3("i2c2_cg", "i2c2_src", base + 0xae00, 28);
|
||||
clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate3("i2c3_cg", "i2c3_src", base + 0xae80, 28);
|
||||
clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate3("i2c4_cg", "i2c4_src", base + 0xaf00, 28);
|
||||
clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate3("uart1_cg", "uart1_src", base + 0xaf80, 28);
|
||||
clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate3("uart2_cg", "uart2_src", base + 0xb000, 28);
|
||||
clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate3("uart3_cg", "uart3_src", base + 0xb080, 28);
|
||||
clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate3("uart4_cg", "uart4_src", base + 0xb100, 28);
|
||||
clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate3("uart5_cg", "uart5_src", base + 0xb180, 28);
|
||||
clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate3("uart6_cg", "uart6_src", base + 0xb200, 28);
|
||||
clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate3("uart7_cg", "uart7_src", base + 0xb280, 28);
|
||||
clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate3("ecspi1_cg", "ecspi1_src", base + 0xb300, 28);
|
||||
clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate3("ecspi2_cg", "ecspi2_src", base + 0xb380, 28);
|
||||
clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate3("ecspi3_cg", "ecspi3_src", base + 0xb400, 28);
|
||||
clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate3("ecspi4_cg", "ecspi4_src", base + 0xb480, 28);
|
||||
clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate3("pwm1_cg", "pwm1_src", base + 0xb500, 28);
|
||||
clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate3("pwm2_cg", "pwm2_src", base + 0xb580, 28);
|
||||
clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate3("pwm3_cg", "pwm3_src", base + 0xb600, 28);
|
||||
clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate3("pwm4_cg", "pwm4_src", base + 0xb680, 28);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate3("flextimer1_cg", "flextimer1_src", base + 0xb700, 28);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate3("flextimer2_cg", "flextimer2_src", base + 0xb780, 28);
|
||||
clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate3("sim1_cg", "sim1_src", base + 0xb800, 28);
|
||||
clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate3("sim2_cg", "sim2_src", base + 0xb880, 28);
|
||||
clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate3("gpt1_cg", "gpt1_src", base + 0xb900, 28);
|
||||
clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate3("gpt2_cg", "gpt2_src", base + 0xb980, 28);
|
||||
clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate3("gpt3_cg", "gpt3_src", base + 0xbA00, 28);
|
||||
clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate3("gpt4_cg", "gpt4_src", base + 0xbA80, 28);
|
||||
clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate3("trace_cg", "trace_src", base + 0xbb00, 28);
|
||||
clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate3("wdog_cg", "wdog_src", base + 0xbb80, 28);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate3("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate3("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28);
|
||||
clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate3("wrclk_cg", "wrclk_src", base + 0xbd00, 28);
|
||||
clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate3("clko1_cg", "clko1_src", base + 0xbd80, 28);
|
||||
clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate3("clko2_cg", "clko2_src", base + 0xbe00, 28);
|
||||
|
||||
clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider("axi_pre_div", "axi_cg", base + 0x8800, 16, 3);
|
||||
clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3);
|
||||
clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3);
|
||||
clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3);
|
||||
clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3);
|
||||
clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3);
|
||||
clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3);
|
||||
clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3);
|
||||
clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3);
|
||||
clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3);
|
||||
clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider("eim_pre_div", "eim_cg", base + 0xa980, 16, 3);
|
||||
clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3);
|
||||
clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3);
|
||||
clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3);
|
||||
clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3);
|
||||
clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3);
|
||||
clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider("can1_pre_div", "can1_cg", base + 0xac80, 16, 3);
|
||||
clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider("can2_pre_div", "can2_cg", base + 0xad00, 16, 3);
|
||||
clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3);
|
||||
clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3);
|
||||
clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3);
|
||||
clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3);
|
||||
clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3);
|
||||
clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3);
|
||||
clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3);
|
||||
clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3);
|
||||
clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3);
|
||||
clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3);
|
||||
clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3);
|
||||
clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3);
|
||||
clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3);
|
||||
clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3);
|
||||
clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3);
|
||||
clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3);
|
||||
clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3);
|
||||
clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3);
|
||||
clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3);
|
||||
clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3);
|
||||
clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3);
|
||||
clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3);
|
||||
clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3);
|
||||
clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3);
|
||||
clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3);
|
||||
clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3);
|
||||
clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3);
|
||||
clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3);
|
||||
clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3);
|
||||
clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider2("axi_pre_div", "axi_cg", base + 0x8800, 16, 3);
|
||||
clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider2("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3);
|
||||
clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider2("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider2("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider2("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider2("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider2("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3);
|
||||
clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider2("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider2("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider2("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider2("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider2("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider2("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider2("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider2("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3);
|
||||
clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider2("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3);
|
||||
clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider2("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3);
|
||||
clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider2("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3);
|
||||
clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider2("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3);
|
||||
clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider2("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3);
|
||||
clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider2("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3);
|
||||
clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider2("eim_pre_div", "eim_cg", base + 0xa980, 16, 3);
|
||||
clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider2("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3);
|
||||
clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider2("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3);
|
||||
clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider2("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3);
|
||||
clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider2("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3);
|
||||
clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider2("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3);
|
||||
clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider2("can1_pre_div", "can1_cg", base + 0xac80, 16, 3);
|
||||
clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider2("can2_pre_div", "can2_cg", base + 0xad00, 16, 3);
|
||||
clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider2("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3);
|
||||
clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider2("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3);
|
||||
clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider2("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3);
|
||||
clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider2("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3);
|
||||
clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider2("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3);
|
||||
clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider2("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3);
|
||||
clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider2("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3);
|
||||
clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider2("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3);
|
||||
clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider2("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3);
|
||||
clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider2("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3);
|
||||
clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider2("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3);
|
||||
clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider2("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3);
|
||||
clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider2("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3);
|
||||
clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider2("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3);
|
||||
clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider2("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3);
|
||||
clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider2("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3);
|
||||
clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider2("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3);
|
||||
clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider2("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3);
|
||||
clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider2("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider2("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider2("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3);
|
||||
clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider2("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3);
|
||||
clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider2("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3);
|
||||
clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider2("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3);
|
||||
clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider2("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3);
|
||||
clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider2("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3);
|
||||
clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider2("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3);
|
||||
clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider2("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3);
|
||||
clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider2("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider2("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider2("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3);
|
||||
clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider2("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3);
|
||||
clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider2("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3);
|
||||
clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider2("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3);
|
||||
|
||||
clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
|
||||
clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
|
||||
clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
|
||||
clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6);
|
||||
clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
|
||||
clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6);
|
||||
clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6);
|
||||
clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6);
|
||||
clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6);
|
||||
clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6);
|
||||
clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6);
|
||||
clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
|
||||
clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
|
||||
clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6);
|
||||
clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
|
||||
clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6);
|
||||
clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6);
|
||||
clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6);
|
||||
clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6);
|
||||
clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6);
|
||||
clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6);
|
||||
clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6);
|
||||
clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6);
|
||||
clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6);
|
||||
clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6);
|
||||
clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6);
|
||||
clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6);
|
||||
clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6);
|
||||
clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6);
|
||||
clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6);
|
||||
clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6);
|
||||
clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6);
|
||||
clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6);
|
||||
clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6);
|
||||
clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6);
|
||||
clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6);
|
||||
clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6);
|
||||
clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6);
|
||||
clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6);
|
||||
clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6);
|
||||
clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6);
|
||||
clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6);
|
||||
clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6);
|
||||
clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6);
|
||||
clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6);
|
||||
clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6);
|
||||
clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6);
|
||||
clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6);
|
||||
clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
|
||||
clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
|
||||
clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider2("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
|
||||
clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider2("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
|
||||
clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
|
||||
clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider2("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6);
|
||||
clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider2("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
|
||||
clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider2("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider2("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider2("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider2("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider2("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider2("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider2("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider2("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6);
|
||||
clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider2("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6);
|
||||
clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider2("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6);
|
||||
clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider2("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6);
|
||||
clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider2("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6);
|
||||
clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider2("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider2("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6);
|
||||
clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider2("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
|
||||
clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
|
||||
clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider2("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6);
|
||||
clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
|
||||
clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider2("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6);
|
||||
clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider2("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6);
|
||||
clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider2("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6);
|
||||
clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider2("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6);
|
||||
clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider2("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6);
|
||||
clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider2("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6);
|
||||
clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider2("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6);
|
||||
clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider2("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6);
|
||||
clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider2("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6);
|
||||
clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider2("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6);
|
||||
clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider2("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6);
|
||||
clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider2("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6);
|
||||
clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider2("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6);
|
||||
clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider2("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6);
|
||||
clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider2("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6);
|
||||
clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider2("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6);
|
||||
clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider2("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6);
|
||||
clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider2("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6);
|
||||
clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider2("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6);
|
||||
clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider2("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6);
|
||||
clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider2("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6);
|
||||
clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider2("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6);
|
||||
clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider2("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6);
|
||||
clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider2("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider2("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider2("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6);
|
||||
clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider2("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6);
|
||||
clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider2("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6);
|
||||
clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider2("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6);
|
||||
clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider2("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6);
|
||||
clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider2("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6);
|
||||
clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider2("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6);
|
||||
clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider2("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6);
|
||||
clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider2("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider2("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider2("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6);
|
||||
clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider2("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6);
|
||||
clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
|
||||
clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
|
||||
|
||||
clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
|
||||
clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate2("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
|
||||
clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate2("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
|
||||
clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate2("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
|
||||
clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate2("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
|
||||
clks[IMX7D_OCRAM_CLK] = imx_clk_gate2("ocram_clk", "axi_post_div", base + 0x4110, 0);
|
||||
clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate2("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate2("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate2("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
|
||||
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2("dram_root_clk", "dram_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate2("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate2("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate2("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate2("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate2("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate2("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate2("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate2("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
|
||||
clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0);
|
||||
clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0);
|
||||
clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0);
|
||||
clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate2("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
|
||||
clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate2("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
|
||||
clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate2("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate2("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
|
||||
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate2("eim_root_clk", "eim_post_div", base + 0x4160, 0);
|
||||
clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate2("nand_root_clk", "nand_post_div", base + 0x4140, 0);
|
||||
clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate2("qspi_root_clk", "qspi_post_div", base + 0x4150, 0);
|
||||
clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate2("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0);
|
||||
clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate2("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0);
|
||||
clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate2("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0);
|
||||
clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate2("can1_root_clk", "can1_post_div", base + 0x4740, 0);
|
||||
clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate2("can2_root_clk", "can2_post_div", base + 0x4750, 0);
|
||||
clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate2("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0);
|
||||
clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate2("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0);
|
||||
clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate2("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0);
|
||||
clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate2("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0);
|
||||
clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate2("uart1_root_clk", "uart1_post_div", base + 0x4940, 0);
|
||||
clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate2("uart2_root_clk", "uart2_post_div", base + 0x4950, 0);
|
||||
clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate2("uart3_root_clk", "uart3_post_div", base + 0x4960, 0);
|
||||
clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate2("uart4_root_clk", "uart4_post_div", base + 0x4970, 0);
|
||||
clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate2("uart5_root_clk", "uart5_post_div", base + 0x4980, 0);
|
||||
clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate2("uart6_root_clk", "uart6_post_div", base + 0x4990, 0);
|
||||
clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate2("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0);
|
||||
clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate2("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0);
|
||||
clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate2("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0);
|
||||
clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate2("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0);
|
||||
clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate2("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0);
|
||||
clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate2("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0);
|
||||
clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate2("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0);
|
||||
clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate2("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0);
|
||||
clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate2("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate2("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate2("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0);
|
||||
clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate2("sim1_root_clk", "sim1_post_div", base + 0x4900, 0);
|
||||
clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate2("sim2_root_clk", "sim2_post_div", base + 0x4910, 0);
|
||||
clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate2("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0);
|
||||
clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate2("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0);
|
||||
clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate2("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0);
|
||||
clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate2("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0);
|
||||
clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate2("trace_root_clk", "trace_post_div", base + 0x4300, 0);
|
||||
clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate2("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0);
|
||||
clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate2("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0);
|
||||
clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate2("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0);
|
||||
clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate2("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate2("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate2("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
|
||||
clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate2("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
|
||||
clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate2("adc_root_clk", "ipg_root_clk", base + 0x4200, 0);
|
||||
clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate4("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
|
||||
clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
|
||||
clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate4("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
|
||||
clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate4("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
|
||||
clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
|
||||
clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
|
||||
clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "axi_post_div", base + 0x4110, 0);
|
||||
clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
|
||||
clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate4("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate4("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
|
||||
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
|
||||
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
|
||||
clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
|
||||
clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
|
||||
clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
|
||||
clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
|
||||
clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate4("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0);
|
||||
clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
|
||||
clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
|
||||
clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
|
||||
clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate4("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0);
|
||||
clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate4("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0);
|
||||
clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate4("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0);
|
||||
clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
|
||||
clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
|
||||
clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
|
||||
clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
|
||||
clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
|
||||
clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
|
||||
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0);
|
||||
clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate4("nand_root_clk", "nand_post_div", base + 0x4140, 0);
|
||||
clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate4("qspi_root_clk", "qspi_post_div", base + 0x4150, 0);
|
||||
clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate4("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0);
|
||||
clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate4("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0);
|
||||
clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate4("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0);
|
||||
clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate4("can1_root_clk", "can1_post_div", base + 0x4740, 0);
|
||||
clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate4("can2_root_clk", "can2_post_div", base + 0x4750, 0);
|
||||
clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate4("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0);
|
||||
clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate4("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0);
|
||||
clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate4("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0);
|
||||
clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate4("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0);
|
||||
clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate4("uart1_root_clk", "uart1_post_div", base + 0x4940, 0);
|
||||
clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate4("uart2_root_clk", "uart2_post_div", base + 0x4950, 0);
|
||||
clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate4("uart3_root_clk", "uart3_post_div", base + 0x4960, 0);
|
||||
clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate4("uart4_root_clk", "uart4_post_div", base + 0x4970, 0);
|
||||
clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate4("uart5_root_clk", "uart5_post_div", base + 0x4980, 0);
|
||||
clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate4("uart6_root_clk", "uart6_post_div", base + 0x4990, 0);
|
||||
clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate4("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0);
|
||||
clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate4("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0);
|
||||
clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate4("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0);
|
||||
clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate4("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0);
|
||||
clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate4("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0);
|
||||
clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate4("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0);
|
||||
clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate4("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0);
|
||||
clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate4("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0);
|
||||
clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate4("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0);
|
||||
clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate4("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0);
|
||||
clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate4("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0);
|
||||
clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate4("sim1_root_clk", "sim1_post_div", base + 0x4900, 0);
|
||||
clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate4("sim2_root_clk", "sim2_post_div", base + 0x4910, 0);
|
||||
clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate4("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0);
|
||||
clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate4("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0);
|
||||
clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate4("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0);
|
||||
clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate4("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0);
|
||||
clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate4("trace_root_clk", "trace_post_div", base + 0x4300, 0);
|
||||
clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate4("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0);
|
||||
clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate4("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0);
|
||||
clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate4("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0);
|
||||
clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
|
||||
clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
|
||||
clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
|
||||
clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
|
||||
clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate4("adc_root_clk", "ipg_root_clk", base + 0x4200, 0);
|
||||
|
||||
clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
|
||||
|
||||
@ -846,28 +854,13 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
|
||||
/* TO BE FIXED LATER
|
||||
* Enable all clock to bring up imx7, otherwise system will be halt and block
|
||||
* the other part upstream Because imx7d clock design changed, clock framework
|
||||
* need do a little modify.
|
||||
* Dong Aisheng is working on this. After that, this part need be changed.
|
||||
*/
|
||||
for (i = 0; i < IMX7D_CLK_END; i++)
|
||||
clk_prepare_enable(clks[i]);
|
||||
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
|
||||
clk_prepare_enable(clks[clks_init_on[i]]);
|
||||
|
||||
/* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
|
||||
clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
|
||||
|
||||
/*
|
||||
* init enet clock source:
|
||||
* AXI clock source is 250MHz
|
||||
* Phy refrence clock is 25MHz
|
||||
* 1588 time clock source is 100MHz
|
||||
*/
|
||||
clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_250M_CLK]);
|
||||
clk_set_parent(clks[IMX7D_ENET_PHY_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_25M_CLK]);
|
||||
clk_set_parent(clks[IMX7D_ENET1_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
|
||||
clk_set_parent(clks[IMX7D_ENET2_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
|
||||
|
||||
/* set uart module clock's parent clock source that must be great then 80MHz */
|
||||
clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
|
||||
|
@ -29,8 +29,8 @@
|
||||
* struct clk_pllv3 - IMX PLL clock version 3
|
||||
* @clk_hw: clock source
|
||||
* @base: base address of PLL registers
|
||||
* @powerup_set: set POWER bit to power up the PLL
|
||||
* @powerdown: pll powerdown offset bit
|
||||
* @power_bit: pll power bit mask
|
||||
* @powerup_set: set power_bit to power up the PLL
|
||||
* @div_mask: mask of divider bits
|
||||
* @div_shift: shift of divider bits
|
||||
*
|
||||
@ -40,8 +40,8 @@
|
||||
struct clk_pllv3 {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
u32 power_bit;
|
||||
bool powerup_set;
|
||||
u32 powerdown;
|
||||
u32 div_mask;
|
||||
u32 div_shift;
|
||||
unsigned long ref_clock;
|
||||
@ -52,7 +52,7 @@ struct clk_pllv3 {
|
||||
static int clk_pllv3_wait_lock(struct clk_pllv3 *pll)
|
||||
{
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(10);
|
||||
u32 val = readl_relaxed(pll->base) & pll->powerdown;
|
||||
u32 val = readl_relaxed(pll->base) & pll->power_bit;
|
||||
|
||||
/* No need to wait for lock when pll is not powered up */
|
||||
if ((pll->powerup_set && !val) || (!pll->powerup_set && val))
|
||||
@ -77,9 +77,9 @@ static int clk_pllv3_prepare(struct clk_hw *hw)
|
||||
|
||||
val = readl_relaxed(pll->base);
|
||||
if (pll->powerup_set)
|
||||
val |= BM_PLL_POWER;
|
||||
val |= pll->power_bit;
|
||||
else
|
||||
val &= ~BM_PLL_POWER;
|
||||
val &= ~pll->power_bit;
|
||||
writel_relaxed(val, pll->base);
|
||||
|
||||
return clk_pllv3_wait_lock(pll);
|
||||
@ -92,9 +92,9 @@ static void clk_pllv3_unprepare(struct clk_hw *hw)
|
||||
|
||||
val = readl_relaxed(pll->base);
|
||||
if (pll->powerup_set)
|
||||
val &= ~BM_PLL_POWER;
|
||||
val &= ~pll->power_bit;
|
||||
else
|
||||
val |= BM_PLL_POWER;
|
||||
val |= pll->power_bit;
|
||||
writel_relaxed(val, pll->base);
|
||||
}
|
||||
|
||||
@ -218,8 +218,12 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
|
||||
u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET);
|
||||
u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET);
|
||||
u32 div = readl_relaxed(pll->base) & pll->div_mask;
|
||||
u64 temp64 = (u64)parent_rate;
|
||||
|
||||
return (parent_rate * div) + ((parent_rate / mfd) * mfn);
|
||||
temp64 *= mfn;
|
||||
do_div(temp64, mfd);
|
||||
|
||||
return (parent_rate * div) + (u32)temp64;
|
||||
}
|
||||
|
||||
static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
@ -243,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
do_div(temp64, parent_rate);
|
||||
mfn = temp64;
|
||||
|
||||
return parent_rate * div + parent_rate / mfd * mfn;
|
||||
return parent_rate * div + parent_rate * mfn / mfd;
|
||||
}
|
||||
|
||||
static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
@ -312,7 +316,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
if (!pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pll->powerdown = BM_PLL_POWER;
|
||||
pll->power_bit = BM_PLL_POWER;
|
||||
|
||||
switch (type) {
|
||||
case IMX_PLLV3_SYS:
|
||||
@ -328,7 +332,7 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
ops = &clk_pllv3_av_ops;
|
||||
break;
|
||||
case IMX_PLLV3_ENET_IMX7:
|
||||
pll->powerdown = IMX7_ENET_PLL_POWER;
|
||||
pll->power_bit = IMX7_ENET_PLL_POWER;
|
||||
pll->ref_clock = 1000000000;
|
||||
ops = &clk_pllv3_enet_ops;
|
||||
break;
|
||||
|
@ -315,12 +315,12 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
|
||||
|
||||
clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
|
||||
|
||||
clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7));
|
||||
clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8));
|
||||
clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9));
|
||||
clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10));
|
||||
clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9));
|
||||
clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10));
|
||||
clk[VF610_CLK_UART0] = imx_clk_gate2_cgr("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7), 0x2);
|
||||
clk[VF610_CLK_UART1] = imx_clk_gate2_cgr("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8), 0x2);
|
||||
clk[VF610_CLK_UART2] = imx_clk_gate2_cgr("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9), 0x2);
|
||||
clk[VF610_CLK_UART3] = imx_clk_gate2_cgr("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10), 0x2);
|
||||
clk[VF610_CLK_UART4] = imx_clk_gate2_cgr("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9), 0x2);
|
||||
clk[VF610_CLK_UART5] = imx_clk_gate2_cgr("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10), 0x2);
|
||||
|
||||
clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
|
||||
clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
|
||||
|
@ -51,28 +51,6 @@ struct clk * imx_obtain_fixed_clock(
|
||||
struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u32 exclusive_mask);
|
||||
|
||||
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate2_shared(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned int *share_count)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0, &imx_ccm_lock, share_count);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 cgr_val)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, cgr_val, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
struct clk *imx_clk_pfd(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx);
|
||||
|
||||
@ -97,6 +75,13 @@ static inline struct clk *imx_clk_fixed(const char *name, int rate)
|
||||
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_fixed_factor(const char *name,
|
||||
const char *parent, unsigned int mult, unsigned int div)
|
||||
{
|
||||
return clk_register_fixed_factor(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT, mult, div);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width)
|
||||
{
|
||||
@ -112,6 +97,14 @@ static inline struct clk *imx_clk_divider_flags(const char *name,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width)
|
||||
{
|
||||
return clk_register_divider(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
@ -126,6 +119,44 @@ static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
|
||||
shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate2_shared(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned int *share_count)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0x3, 0, &imx_ccm_lock, share_count);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate2_cgr(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift, u8 cgr_val)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, cgr_val, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_register_gate(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char **parents, int num_parents)
|
||||
{
|
||||
@ -134,6 +165,14 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
|
||||
width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char **parents, int num_parents)
|
||||
{
|
||||
return clk_register_mux(NULL, name, parents, num_parents,
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width, const char **parents,
|
||||
int num_parents, unsigned long flags)
|
||||
@ -143,13 +182,6 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
|
||||
&imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_fixed_factor(const char *name,
|
||||
const char *parent, unsigned int mult, unsigned int div)
|
||||
{
|
||||
return clk_register_fixed_factor(NULL, name, parent,
|
||||
CLK_SET_RATE_PARENT, mult, div);
|
||||
}
|
||||
|
||||
struct clk *imx_clk_cpu(const char *name, const char *parent_name,
|
||||
struct clk *div, struct clk *mux, struct clk *pll,
|
||||
struct clk *step);
|
||||
|
19
drivers/clk/meson/Kconfig
Normal file
19
drivers/clk/meson/Kconfig
Normal file
@ -0,0 +1,19 @@
|
||||
config COMMON_CLK_AMLOGIC
|
||||
bool
|
||||
depends on OF
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
|
||||
config COMMON_CLK_MESON8B
|
||||
bool
|
||||
depends on COMMON_CLK_AMLOGIC
|
||||
help
|
||||
Support for the clock controller on AmLogic S805 devices, aka
|
||||
meson8b. Say Y if you want peripherals and CPU frequency scaling to
|
||||
work.
|
||||
|
||||
config COMMON_CLK_GXBB
|
||||
bool
|
||||
depends on COMMON_CLK_AMLOGIC
|
||||
help
|
||||
Support for the clock controller on AmLogic S905 devices, aka gxbb.
|
||||
Say Y if you want peripherals and CPU frequency scaling to work.
|
@ -2,5 +2,6 @@
|
||||
# Makefile for Meson specific clk
|
||||
#
|
||||
|
||||
obj-y += clkc.o clk-pll.o clk-cpu.o
|
||||
obj-y += meson8b-clkc.o
|
||||
obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o
|
||||
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b-clkc.o
|
||||
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o
|
||||
|
@ -51,13 +51,6 @@
|
||||
|
||||
#include "clkc.h"
|
||||
|
||||
struct meson_clk_cpu {
|
||||
struct notifier_block clk_nb;
|
||||
const struct clk_div_table *div_table;
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
u16 reg_off;
|
||||
};
|
||||
#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
|
||||
#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
|
||||
|
||||
@ -119,6 +112,7 @@ static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
|
||||
return parent_rate / div;
|
||||
}
|
||||
|
||||
/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
|
||||
static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
|
||||
struct clk_notifier_data *ndata)
|
||||
{
|
||||
@ -140,6 +134,7 @@ static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
|
||||
static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
|
||||
struct clk_notifier_data *ndata)
|
||||
{
|
||||
@ -161,7 +156,7 @@ static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
|
||||
* PLL clock is to be changed. We use the xtal input as temporary parent
|
||||
* while the PLL frequency is stabilized.
|
||||
*/
|
||||
static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
|
||||
int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
struct clk_notifier_data *ndata = data;
|
||||
@ -176,68 +171,8 @@ static int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
|
||||
return notifier_from_errno(ret);
|
||||
}
|
||||
|
||||
static const struct clk_ops meson_clk_cpu_ops = {
|
||||
const struct clk_ops meson_clk_cpu_ops = {
|
||||
.recalc_rate = meson_clk_cpu_recalc_rate,
|
||||
.round_rate = meson_clk_cpu_round_rate,
|
||||
.set_rate = meson_clk_cpu_set_rate,
|
||||
};
|
||||
|
||||
struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
|
||||
void __iomem *reg_base,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk *pclk;
|
||||
struct meson_clk_cpu *clk_cpu;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
clk_cpu = kzalloc(sizeof(*clk_cpu), GFP_KERNEL);
|
||||
if (!clk_cpu)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_cpu->base = reg_base;
|
||||
clk_cpu->reg_off = clk_conf->reg_off;
|
||||
clk_cpu->div_table = clk_conf->conf.div_table;
|
||||
clk_cpu->clk_nb.notifier_call = meson_clk_cpu_notifier_cb;
|
||||
|
||||
init.name = clk_conf->clk_name;
|
||||
init.ops = &meson_clk_cpu_ops;
|
||||
init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
|
||||
init.flags |= CLK_SET_RATE_PARENT;
|
||||
init.parent_names = clk_conf->clks_parent;
|
||||
init.num_parents = 1;
|
||||
|
||||
clk_cpu->hw.init = &init;
|
||||
|
||||
pclk = __clk_lookup(clk_conf->clks_parent[0]);
|
||||
if (!pclk) {
|
||||
pr_err("%s: could not lookup parent clock %s\n",
|
||||
__func__, clk_conf->clks_parent[0]);
|
||||
ret = -EINVAL;
|
||||
goto free_clk;
|
||||
}
|
||||
|
||||
ret = clk_notifier_register(pclk, &clk_cpu->clk_nb);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to register clock notifier for %s\n",
|
||||
__func__, clk_conf->clk_name);
|
||||
goto free_clk;
|
||||
}
|
||||
|
||||
clk = clk_register(NULL, &clk_cpu->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
ret = PTR_ERR(clk);
|
||||
goto unregister_clk_nb;
|
||||
}
|
||||
|
||||
return clk;
|
||||
|
||||
unregister_clk_nb:
|
||||
clk_notifier_unregister(pclk, &clk_cpu->clk_nb);
|
||||
free_clk:
|
||||
kfree(clk_cpu);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
|
94
drivers/clk/meson/clk-mpll.c
Normal file
94
drivers/clk/meson/clk-mpll.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright (c) 2016 AmLogic, Inc.
|
||||
* Author: Michael Turquette <mturquette@baylibre.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2016 AmLogic, Inc.
|
||||
* Author: Michael Turquette <mturquette@baylibre.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MultiPhase Locked Loops are outputs from a PLL with additional frequency
|
||||
* scaling capabilities. MPLL rates are calculated as:
|
||||
*
|
||||
* f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384)
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include "clkc.h"
|
||||
|
||||
#define SDM_MAX 16384
|
||||
|
||||
#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
|
||||
|
||||
static unsigned long mpll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
|
||||
struct parm *p;
|
||||
unsigned long rate = 0;
|
||||
unsigned long reg, sdm, n2;
|
||||
|
||||
p = &mpll->sdm;
|
||||
reg = readl(mpll->base + p->reg_off);
|
||||
sdm = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
p = &mpll->n2;
|
||||
reg = readl(mpll->base + p->reg_off);
|
||||
n2 = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
rate = (parent_rate * SDM_MAX) / ((SDM_MAX * n2) + sdm);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_clk_mpll_ro_ops = {
|
||||
.recalc_rate = mpll_recalc_rate,
|
||||
};
|
@ -44,13 +44,6 @@
|
||||
#define MESON_PLL_RESET BIT(29)
|
||||
#define MESON_PLL_LOCK BIT(31)
|
||||
|
||||
struct meson_clk_pll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
struct pll_conf *conf;
|
||||
unsigned int rate_count;
|
||||
spinlock_t *lock;
|
||||
};
|
||||
#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
|
||||
|
||||
static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
@ -60,22 +53,36 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
struct parm *p;
|
||||
unsigned long parent_rate_mhz = parent_rate / 1000000;
|
||||
unsigned long rate_mhz;
|
||||
u16 n, m, od;
|
||||
u16 n, m, frac = 0, od, od2 = 0;
|
||||
u32 reg;
|
||||
|
||||
p = &pll->conf->n;
|
||||
p = &pll->n;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
n = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
p = &pll->conf->m;
|
||||
p = &pll->m;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
m = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
p = &pll->conf->od;
|
||||
p = &pll->od;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
od = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
rate_mhz = (parent_rate_mhz * m / n) >> od;
|
||||
p = &pll->od2;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
od2 = PARM_GET(p->width, p->shift, reg);
|
||||
}
|
||||
|
||||
p = &pll->frac;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
frac = PARM_GET(p->width, p->shift, reg);
|
||||
rate_mhz = (parent_rate_mhz * m + \
|
||||
(parent_rate_mhz * frac >> 12)) * 2 / n;
|
||||
rate_mhz = rate_mhz >> od >> od2;
|
||||
} else
|
||||
rate_mhz = (parent_rate_mhz * m / n) >> od >> od2;
|
||||
|
||||
return rate_mhz * 1000000;
|
||||
}
|
||||
@ -84,7 +91,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
|
||||
const struct pll_rate_table *rate_table = pll->conf->rate_table;
|
||||
const struct pll_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
@ -99,7 +106,7 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
static const struct pll_rate_table *meson_clk_get_pll_settings(struct meson_clk_pll *pll,
|
||||
unsigned long rate)
|
||||
{
|
||||
const struct pll_rate_table *rate_table = pll->conf->rate_table;
|
||||
const struct pll_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
@ -145,24 +152,38 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return -EINVAL;
|
||||
|
||||
/* PLL reset */
|
||||
p = &pll->conf->n;
|
||||
p = &pll->n;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
|
||||
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
|
||||
p = &pll->conf->m;
|
||||
p = &pll->m;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
|
||||
p = &pll->conf->od;
|
||||
p = &pll->od;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
|
||||
p = &pll->conf->n;
|
||||
p = &pll->od2;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->od2);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
}
|
||||
|
||||
p = &pll->frac;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->frac);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
}
|
||||
|
||||
p = &pll->n;
|
||||
ret = meson_clk_pll_wait_lock(pll, p);
|
||||
if (ret) {
|
||||
pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
|
||||
@ -173,55 +194,12 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct clk_ops meson_clk_pll_ops = {
|
||||
const struct clk_ops meson_clk_pll_ops = {
|
||||
.recalc_rate = meson_clk_pll_recalc_rate,
|
||||
.round_rate = meson_clk_pll_round_rate,
|
||||
.set_rate = meson_clk_pll_set_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops meson_clk_pll_ro_ops = {
|
||||
const struct clk_ops meson_clk_pll_ro_ops = {
|
||||
.recalc_rate = meson_clk_pll_recalc_rate,
|
||||
};
|
||||
|
||||
struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
|
||||
void __iomem *reg_base,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct meson_clk_pll *clk_pll;
|
||||
struct clk_init_data init;
|
||||
|
||||
clk_pll = kzalloc(sizeof(*clk_pll), GFP_KERNEL);
|
||||
if (!clk_pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_pll->base = reg_base + clk_conf->reg_off;
|
||||
clk_pll->lock = lock;
|
||||
clk_pll->conf = clk_conf->conf.pll;
|
||||
|
||||
init.name = clk_conf->clk_name;
|
||||
init.flags = clk_conf->flags | CLK_GET_RATE_NOCACHE;
|
||||
|
||||
init.parent_names = &clk_conf->clks_parent[0];
|
||||
init.num_parents = 1;
|
||||
init.ops = &meson_clk_pll_ro_ops;
|
||||
|
||||
/* If no rate_table is specified we assume the PLL is read-only */
|
||||
if (clk_pll->conf->rate_table) {
|
||||
int len;
|
||||
|
||||
for (len = 0; clk_pll->conf->rate_table[len].rate != 0; )
|
||||
len++;
|
||||
|
||||
clk_pll->rate_count = len;
|
||||
init.ops = &meson_clk_pll_ops;
|
||||
}
|
||||
|
||||
clk_pll->hw.init = &init;
|
||||
|
||||
clk = clk_register(NULL, &clk_pll->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(clk_pll);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
@ -1,249 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Endless Mobile, Inc.
|
||||
* Author: Carlo Caione <carlo@endlessm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "clkc.h"
|
||||
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
||||
static struct clk **clks;
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
struct clk ** __init meson_clk_init(struct device_node *np,
|
||||
unsigned long nr_clks)
|
||||
{
|
||||
clks = kcalloc(nr_clks, sizeof(*clks), GFP_KERNEL);
|
||||
if (!clks)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = nr_clks;
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
|
||||
return clks;
|
||||
}
|
||||
|
||||
static void meson_clk_add_lookup(struct clk *clk, unsigned int id)
|
||||
{
|
||||
if (clks && id)
|
||||
clks[id] = clk;
|
||||
}
|
||||
|
||||
static struct clk * __init
|
||||
meson_clk_register_composite(const struct clk_conf *clk_conf,
|
||||
void __iomem *clk_base)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_mux *mux = NULL;
|
||||
struct clk_divider *div = NULL;
|
||||
struct clk_gate *gate = NULL;
|
||||
const struct clk_ops *mux_ops = NULL;
|
||||
const struct composite_conf *composite_conf;
|
||||
|
||||
composite_conf = clk_conf->conf.composite;
|
||||
|
||||
if (clk_conf->num_parents > 1) {
|
||||
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mux->reg = clk_base + clk_conf->reg_off
|
||||
+ composite_conf->mux_parm.reg_off;
|
||||
mux->shift = composite_conf->mux_parm.shift;
|
||||
mux->mask = BIT(composite_conf->mux_parm.width) - 1;
|
||||
mux->flags = composite_conf->mux_flags;
|
||||
mux->lock = &clk_lock;
|
||||
mux->table = composite_conf->mux_table;
|
||||
mux_ops = (composite_conf->mux_flags & CLK_MUX_READ_ONLY) ?
|
||||
&clk_mux_ro_ops : &clk_mux_ops;
|
||||
}
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&composite_conf->div_parm)) {
|
||||
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||
if (!div) {
|
||||
clk = ERR_PTR(-ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
div->reg = clk_base + clk_conf->reg_off
|
||||
+ composite_conf->div_parm.reg_off;
|
||||
div->shift = composite_conf->div_parm.shift;
|
||||
div->width = composite_conf->div_parm.width;
|
||||
div->lock = &clk_lock;
|
||||
div->flags = composite_conf->div_flags;
|
||||
div->table = composite_conf->div_table;
|
||||
}
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&composite_conf->gate_parm)) {
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate) {
|
||||
clk = ERR_PTR(-ENOMEM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
gate->reg = clk_base + clk_conf->reg_off
|
||||
+ composite_conf->div_parm.reg_off;
|
||||
gate->bit_idx = composite_conf->gate_parm.shift;
|
||||
gate->flags = composite_conf->gate_flags;
|
||||
gate->lock = &clk_lock;
|
||||
}
|
||||
|
||||
clk = clk_register_composite(NULL, clk_conf->clk_name,
|
||||
clk_conf->clks_parent,
|
||||
clk_conf->num_parents,
|
||||
mux ? &mux->hw : NULL, mux_ops,
|
||||
div ? &div->hw : NULL, &clk_divider_ops,
|
||||
gate ? &gate->hw : NULL, &clk_gate_ops,
|
||||
clk_conf->flags);
|
||||
if (IS_ERR(clk))
|
||||
goto error;
|
||||
|
||||
return clk;
|
||||
|
||||
error:
|
||||
kfree(gate);
|
||||
kfree(div);
|
||||
kfree(mux);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static struct clk * __init
|
||||
meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
|
||||
void __iomem *clk_base)
|
||||
{
|
||||
struct clk *clk;
|
||||
const struct fixed_fact_conf *fixed_fact_conf;
|
||||
const struct parm *p;
|
||||
unsigned int mult, div;
|
||||
u32 reg;
|
||||
|
||||
fixed_fact_conf = &clk_conf->conf.fixed_fact;
|
||||
|
||||
mult = clk_conf->conf.fixed_fact.mult;
|
||||
div = clk_conf->conf.fixed_fact.div;
|
||||
|
||||
if (!mult) {
|
||||
mult = 1;
|
||||
p = &fixed_fact_conf->mult_parm;
|
||||
if (MESON_PARM_APPLICABLE(p)) {
|
||||
reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
|
||||
mult = PARM_GET(p->width, p->shift, reg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!div) {
|
||||
div = 1;
|
||||
p = &fixed_fact_conf->div_parm;
|
||||
if (MESON_PARM_APPLICABLE(p)) {
|
||||
reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
|
||||
mult = PARM_GET(p->width, p->shift, reg);
|
||||
}
|
||||
}
|
||||
|
||||
clk = clk_register_fixed_factor(NULL,
|
||||
clk_conf->clk_name,
|
||||
clk_conf->clks_parent[0],
|
||||
clk_conf->flags,
|
||||
mult, div);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static struct clk * __init
|
||||
meson_clk_register_fixed_rate(const struct clk_conf *clk_conf,
|
||||
void __iomem *clk_base)
|
||||
{
|
||||
struct clk *clk;
|
||||
const struct fixed_rate_conf *fixed_rate_conf;
|
||||
const struct parm *r;
|
||||
unsigned long rate;
|
||||
u32 reg;
|
||||
|
||||
fixed_rate_conf = &clk_conf->conf.fixed_rate;
|
||||
rate = fixed_rate_conf->rate;
|
||||
|
||||
if (!rate) {
|
||||
r = &fixed_rate_conf->rate_parm;
|
||||
reg = readl(clk_base + clk_conf->reg_off + r->reg_off);
|
||||
rate = PARM_GET(r->width, r->shift, reg);
|
||||
}
|
||||
|
||||
rate *= 1000000;
|
||||
|
||||
clk = clk_register_fixed_rate(NULL,
|
||||
clk_conf->clk_name,
|
||||
clk_conf->num_parents
|
||||
? clk_conf->clks_parent[0] : NULL,
|
||||
clk_conf->flags, rate);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
void __init meson_clk_register_clks(const struct clk_conf *clk_confs,
|
||||
unsigned int nr_confs,
|
||||
void __iomem *clk_base)
|
||||
{
|
||||
unsigned int i;
|
||||
struct clk *clk = NULL;
|
||||
|
||||
for (i = 0; i < nr_confs; i++) {
|
||||
const struct clk_conf *clk_conf = &clk_confs[i];
|
||||
|
||||
switch (clk_conf->clk_type) {
|
||||
case CLK_FIXED_RATE:
|
||||
clk = meson_clk_register_fixed_rate(clk_conf,
|
||||
clk_base);
|
||||
break;
|
||||
case CLK_FIXED_FACTOR:
|
||||
clk = meson_clk_register_fixed_factor(clk_conf,
|
||||
clk_base);
|
||||
break;
|
||||
case CLK_COMPOSITE:
|
||||
clk = meson_clk_register_composite(clk_conf,
|
||||
clk_base);
|
||||
break;
|
||||
case CLK_CPU:
|
||||
clk = meson_clk_register_cpu(clk_conf, clk_base,
|
||||
&clk_lock);
|
||||
break;
|
||||
case CLK_PLL:
|
||||
clk = meson_clk_register_pll(clk_conf, clk_base,
|
||||
&clk_lock);
|
||||
break;
|
||||
default:
|
||||
clk = NULL;
|
||||
}
|
||||
|
||||
if (!clk) {
|
||||
pr_err("%s: unknown clock type %d\n", __func__,
|
||||
clk_conf->clk_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_ERR(clk)) {
|
||||
pr_warn("%s: Unable to create %s clock\n", __func__,
|
||||
clk_conf->clk_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
meson_clk_add_lookup(clk, clk_conf->clk_id);
|
||||
}
|
||||
}
|
@ -34,19 +34,16 @@ struct parm {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
};
|
||||
#define PARM(_r, _s, _w) \
|
||||
{ \
|
||||
.reg_off = (_r), \
|
||||
.shift = (_s), \
|
||||
.width = (_w), \
|
||||
} \
|
||||
|
||||
struct pll_rate_table {
|
||||
unsigned long rate;
|
||||
u16 m;
|
||||
u16 n;
|
||||
u16 od;
|
||||
u16 od2;
|
||||
u16 frac;
|
||||
};
|
||||
|
||||
#define PLL_RATE(_r, _m, _n, _od) \
|
||||
{ \
|
||||
.rate = (_r), \
|
||||
@ -55,133 +52,69 @@ struct pll_rate_table {
|
||||
.od = (_od), \
|
||||
} \
|
||||
|
||||
struct pll_conf {
|
||||
const struct pll_rate_table *rate_table;
|
||||
struct parm m;
|
||||
struct parm n;
|
||||
struct parm od;
|
||||
};
|
||||
|
||||
struct fixed_fact_conf {
|
||||
unsigned int div;
|
||||
unsigned int mult;
|
||||
struct parm div_parm;
|
||||
struct parm mult_parm;
|
||||
};
|
||||
|
||||
struct fixed_rate_conf {
|
||||
unsigned long rate;
|
||||
struct parm rate_parm;
|
||||
};
|
||||
|
||||
struct composite_conf {
|
||||
struct parm mux_parm;
|
||||
struct parm div_parm;
|
||||
struct parm gate_parm;
|
||||
struct clk_div_table *div_table;
|
||||
u32 *mux_table;
|
||||
u8 mux_flags;
|
||||
u8 div_flags;
|
||||
u8 gate_flags;
|
||||
};
|
||||
|
||||
#define PNAME(x) static const char *x[]
|
||||
|
||||
enum clk_type {
|
||||
CLK_FIXED_FACTOR,
|
||||
CLK_FIXED_RATE,
|
||||
CLK_COMPOSITE,
|
||||
CLK_CPU,
|
||||
CLK_PLL,
|
||||
};
|
||||
|
||||
struct clk_conf {
|
||||
u16 reg_off;
|
||||
enum clk_type clk_type;
|
||||
unsigned int clk_id;
|
||||
const char *clk_name;
|
||||
const char **clks_parent;
|
||||
int num_parents;
|
||||
unsigned long flags;
|
||||
union {
|
||||
struct fixed_fact_conf fixed_fact;
|
||||
struct fixed_rate_conf fixed_rate;
|
||||
const struct composite_conf *composite;
|
||||
struct pll_conf *pll;
|
||||
const struct clk_div_table *div_table;
|
||||
} conf;
|
||||
};
|
||||
|
||||
#define FIXED_RATE_P(_ro, _ci, _cn, _f, _c) \
|
||||
#define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac) \
|
||||
{ \
|
||||
.reg_off = (_ro), \
|
||||
.clk_type = CLK_FIXED_RATE, \
|
||||
.clk_id = (_ci), \
|
||||
.clk_name = (_cn), \
|
||||
.flags = (_f), \
|
||||
.conf.fixed_rate.rate_parm = _c, \
|
||||
.rate = (_r), \
|
||||
.m = (_m), \
|
||||
.n = (_n), \
|
||||
.od = (_od), \
|
||||
.od2 = (_od2), \
|
||||
.frac = (_frac), \
|
||||
} \
|
||||
|
||||
#define FIXED_RATE(_ci, _cn, _f, _r) \
|
||||
{ \
|
||||
.clk_type = CLK_FIXED_RATE, \
|
||||
.clk_id = (_ci), \
|
||||
.clk_name = (_cn), \
|
||||
.flags = (_f), \
|
||||
.conf.fixed_rate.rate = (_r), \
|
||||
} \
|
||||
struct meson_clk_pll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
struct parm m;
|
||||
struct parm n;
|
||||
struct parm frac;
|
||||
struct parm od;
|
||||
struct parm od2;
|
||||
const struct pll_rate_table *rate_table;
|
||||
unsigned int rate_count;
|
||||
spinlock_t *lock;
|
||||
};
|
||||
|
||||
#define PLL(_ro, _ci, _cn, _cp, _f, _c) \
|
||||
{ \
|
||||
.reg_off = (_ro), \
|
||||
.clk_type = CLK_PLL, \
|
||||
.clk_id = (_ci), \
|
||||
.clk_name = (_cn), \
|
||||
.clks_parent = (_cp), \
|
||||
.num_parents = ARRAY_SIZE(_cp), \
|
||||
.flags = (_f), \
|
||||
.conf.pll = (_c), \
|
||||
} \
|
||||
#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
|
||||
|
||||
#define FIXED_FACTOR_DIV(_ci, _cn, _cp, _f, _d) \
|
||||
{ \
|
||||
.clk_type = CLK_FIXED_FACTOR, \
|
||||
.clk_id = (_ci), \
|
||||
.clk_name = (_cn), \
|
||||
.clks_parent = (_cp), \
|
||||
.num_parents = ARRAY_SIZE(_cp), \
|
||||
.conf.fixed_fact.div = (_d), \
|
||||
} \
|
||||
struct meson_clk_cpu {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
u16 reg_off;
|
||||
struct notifier_block clk_nb;
|
||||
const struct clk_div_table *div_table;
|
||||
};
|
||||
|
||||
#define CPU(_ro, _ci, _cn, _cp, _dt) \
|
||||
{ \
|
||||
.reg_off = (_ro), \
|
||||
.clk_type = CLK_CPU, \
|
||||
.clk_id = (_ci), \
|
||||
.clk_name = (_cn), \
|
||||
.clks_parent = (_cp), \
|
||||
.num_parents = ARRAY_SIZE(_cp), \
|
||||
.conf.div_table = (_dt), \
|
||||
} \
|
||||
int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
|
||||
void *data);
|
||||
|
||||
#define COMPOSITE(_ro, _ci, _cn, _cp, _f, _c) \
|
||||
{ \
|
||||
.reg_off = (_ro), \
|
||||
.clk_type = CLK_COMPOSITE, \
|
||||
.clk_id = (_ci), \
|
||||
.clk_name = (_cn), \
|
||||
.clks_parent = (_cp), \
|
||||
.num_parents = ARRAY_SIZE(_cp), \
|
||||
.flags = (_f), \
|
||||
.conf.composite = (_c), \
|
||||
} \
|
||||
struct meson_clk_mpll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
struct parm sdm;
|
||||
struct parm n2;
|
||||
/* FIXME ssen gate control? */
|
||||
spinlock_t *lock;
|
||||
};
|
||||
|
||||
struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks);
|
||||
void meson_clk_register_clks(const struct clk_conf *clk_confs,
|
||||
unsigned int nr_confs, void __iomem *clk_base);
|
||||
struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf,
|
||||
void __iomem *reg_base, spinlock_t *lock);
|
||||
struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf,
|
||||
void __iomem *reg_base, spinlock_t *lock);
|
||||
#define MESON_GATE(_name, _reg, _bit) \
|
||||
struct clk_gate gxbb_##_name = { \
|
||||
.reg = (void __iomem *) _reg, \
|
||||
.bit_idx = (_bit), \
|
||||
.lock = &clk_lock, \
|
||||
.hw.init = &(struct clk_init_data) { \
|
||||
.name = #_name, \
|
||||
.ops = &clk_gate_ops, \
|
||||
.parent_names = (const char *[]){ "clk81" }, \
|
||||
.num_parents = 1, \
|
||||
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
|
||||
}, \
|
||||
};
|
||||
|
||||
/* clk_ops */
|
||||
extern const struct clk_ops meson_clk_pll_ro_ops;
|
||||
extern const struct clk_ops meson_clk_pll_ops;
|
||||
extern const struct clk_ops meson_clk_cpu_ops;
|
||||
extern const struct clk_ops meson_clk_mpll_ro_ops;
|
||||
|
||||
#endif /* __CLKC_H */
|
||||
|
944
drivers/clk/meson/gxbb.c
Normal file
944
drivers/clk/meson/gxbb.c
Normal file
@ -0,0 +1,944 @@
|
||||
/*
|
||||
* AmLogic S905 / GXBB Clock Controller Driver
|
||||
*
|
||||
* Copyright (c) 2016 AmLogic, Inc.
|
||||
* Michael Turquette <mturquette@baylibre.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "clkc.h"
|
||||
#include "gxbb.h"
|
||||
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
||||
static const struct pll_rate_table sys_pll_rate_table[] = {
|
||||
PLL_RATE(24000000, 56, 1, 2),
|
||||
PLL_RATE(48000000, 64, 1, 2),
|
||||
PLL_RATE(72000000, 72, 1, 2),
|
||||
PLL_RATE(96000000, 64, 1, 2),
|
||||
PLL_RATE(120000000, 80, 1, 2),
|
||||
PLL_RATE(144000000, 96, 1, 2),
|
||||
PLL_RATE(168000000, 56, 1, 1),
|
||||
PLL_RATE(192000000, 64, 1, 1),
|
||||
PLL_RATE(216000000, 72, 1, 1),
|
||||
PLL_RATE(240000000, 80, 1, 1),
|
||||
PLL_RATE(264000000, 88, 1, 1),
|
||||
PLL_RATE(288000000, 96, 1, 1),
|
||||
PLL_RATE(312000000, 52, 1, 2),
|
||||
PLL_RATE(336000000, 56, 1, 2),
|
||||
PLL_RATE(360000000, 60, 1, 2),
|
||||
PLL_RATE(384000000, 64, 1, 2),
|
||||
PLL_RATE(408000000, 68, 1, 2),
|
||||
PLL_RATE(432000000, 72, 1, 2),
|
||||
PLL_RATE(456000000, 76, 1, 2),
|
||||
PLL_RATE(480000000, 80, 1, 2),
|
||||
PLL_RATE(504000000, 84, 1, 2),
|
||||
PLL_RATE(528000000, 88, 1, 2),
|
||||
PLL_RATE(552000000, 92, 1, 2),
|
||||
PLL_RATE(576000000, 96, 1, 2),
|
||||
PLL_RATE(600000000, 50, 1, 1),
|
||||
PLL_RATE(624000000, 52, 1, 1),
|
||||
PLL_RATE(648000000, 54, 1, 1),
|
||||
PLL_RATE(672000000, 56, 1, 1),
|
||||
PLL_RATE(696000000, 58, 1, 1),
|
||||
PLL_RATE(720000000, 60, 1, 1),
|
||||
PLL_RATE(744000000, 62, 1, 1),
|
||||
PLL_RATE(768000000, 64, 1, 1),
|
||||
PLL_RATE(792000000, 66, 1, 1),
|
||||
PLL_RATE(816000000, 68, 1, 1),
|
||||
PLL_RATE(840000000, 70, 1, 1),
|
||||
PLL_RATE(864000000, 72, 1, 1),
|
||||
PLL_RATE(888000000, 74, 1, 1),
|
||||
PLL_RATE(912000000, 76, 1, 1),
|
||||
PLL_RATE(936000000, 78, 1, 1),
|
||||
PLL_RATE(960000000, 80, 1, 1),
|
||||
PLL_RATE(984000000, 82, 1, 1),
|
||||
PLL_RATE(1008000000, 84, 1, 1),
|
||||
PLL_RATE(1032000000, 86, 1, 1),
|
||||
PLL_RATE(1056000000, 88, 1, 1),
|
||||
PLL_RATE(1080000000, 90, 1, 1),
|
||||
PLL_RATE(1104000000, 92, 1, 1),
|
||||
PLL_RATE(1128000000, 94, 1, 1),
|
||||
PLL_RATE(1152000000, 96, 1, 1),
|
||||
PLL_RATE(1176000000, 98, 1, 1),
|
||||
PLL_RATE(1200000000, 50, 1, 0),
|
||||
PLL_RATE(1224000000, 51, 1, 0),
|
||||
PLL_RATE(1248000000, 52, 1, 0),
|
||||
PLL_RATE(1272000000, 53, 1, 0),
|
||||
PLL_RATE(1296000000, 54, 1, 0),
|
||||
PLL_RATE(1320000000, 55, 1, 0),
|
||||
PLL_RATE(1344000000, 56, 1, 0),
|
||||
PLL_RATE(1368000000, 57, 1, 0),
|
||||
PLL_RATE(1392000000, 58, 1, 0),
|
||||
PLL_RATE(1416000000, 59, 1, 0),
|
||||
PLL_RATE(1440000000, 60, 1, 0),
|
||||
PLL_RATE(1464000000, 61, 1, 0),
|
||||
PLL_RATE(1488000000, 62, 1, 0),
|
||||
PLL_RATE(1512000000, 63, 1, 0),
|
||||
PLL_RATE(1536000000, 64, 1, 0),
|
||||
PLL_RATE(1560000000, 65, 1, 0),
|
||||
PLL_RATE(1584000000, 66, 1, 0),
|
||||
PLL_RATE(1608000000, 67, 1, 0),
|
||||
PLL_RATE(1632000000, 68, 1, 0),
|
||||
PLL_RATE(1656000000, 68, 1, 0),
|
||||
PLL_RATE(1680000000, 68, 1, 0),
|
||||
PLL_RATE(1704000000, 68, 1, 0),
|
||||
PLL_RATE(1728000000, 69, 1, 0),
|
||||
PLL_RATE(1752000000, 69, 1, 0),
|
||||
PLL_RATE(1776000000, 69, 1, 0),
|
||||
PLL_RATE(1800000000, 69, 1, 0),
|
||||
PLL_RATE(1824000000, 70, 1, 0),
|
||||
PLL_RATE(1848000000, 70, 1, 0),
|
||||
PLL_RATE(1872000000, 70, 1, 0),
|
||||
PLL_RATE(1896000000, 70, 1, 0),
|
||||
PLL_RATE(1920000000, 71, 1, 0),
|
||||
PLL_RATE(1944000000, 71, 1, 0),
|
||||
PLL_RATE(1968000000, 71, 1, 0),
|
||||
PLL_RATE(1992000000, 71, 1, 0),
|
||||
PLL_RATE(2016000000, 72, 1, 0),
|
||||
PLL_RATE(2040000000, 72, 1, 0),
|
||||
PLL_RATE(2064000000, 72, 1, 0),
|
||||
PLL_RATE(2088000000, 72, 1, 0),
|
||||
PLL_RATE(2112000000, 73, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct pll_rate_table gp0_pll_rate_table[] = {
|
||||
PLL_RATE(96000000, 32, 1, 3),
|
||||
PLL_RATE(99000000, 33, 1, 3),
|
||||
PLL_RATE(102000000, 34, 1, 3),
|
||||
PLL_RATE(105000000, 35, 1, 3),
|
||||
PLL_RATE(108000000, 36, 1, 3),
|
||||
PLL_RATE(111000000, 37, 1, 3),
|
||||
PLL_RATE(114000000, 38, 1, 3),
|
||||
PLL_RATE(117000000, 39, 1, 3),
|
||||
PLL_RATE(120000000, 40, 1, 3),
|
||||
PLL_RATE(123000000, 41, 1, 3),
|
||||
PLL_RATE(126000000, 42, 1, 3),
|
||||
PLL_RATE(129000000, 43, 1, 3),
|
||||
PLL_RATE(132000000, 44, 1, 3),
|
||||
PLL_RATE(135000000, 45, 1, 3),
|
||||
PLL_RATE(138000000, 46, 1, 3),
|
||||
PLL_RATE(141000000, 47, 1, 3),
|
||||
PLL_RATE(144000000, 48, 1, 3),
|
||||
PLL_RATE(147000000, 49, 1, 3),
|
||||
PLL_RATE(150000000, 50, 1, 3),
|
||||
PLL_RATE(153000000, 51, 1, 3),
|
||||
PLL_RATE(156000000, 52, 1, 3),
|
||||
PLL_RATE(159000000, 53, 1, 3),
|
||||
PLL_RATE(162000000, 54, 1, 3),
|
||||
PLL_RATE(165000000, 55, 1, 3),
|
||||
PLL_RATE(168000000, 56, 1, 3),
|
||||
PLL_RATE(171000000, 57, 1, 3),
|
||||
PLL_RATE(174000000, 58, 1, 3),
|
||||
PLL_RATE(177000000, 59, 1, 3),
|
||||
PLL_RATE(180000000, 60, 1, 3),
|
||||
PLL_RATE(183000000, 61, 1, 3),
|
||||
PLL_RATE(186000000, 62, 1, 3),
|
||||
PLL_RATE(192000000, 32, 1, 2),
|
||||
PLL_RATE(198000000, 33, 1, 2),
|
||||
PLL_RATE(204000000, 34, 1, 2),
|
||||
PLL_RATE(210000000, 35, 1, 2),
|
||||
PLL_RATE(216000000, 36, 1, 2),
|
||||
PLL_RATE(222000000, 37, 1, 2),
|
||||
PLL_RATE(228000000, 38, 1, 2),
|
||||
PLL_RATE(234000000, 39, 1, 2),
|
||||
PLL_RATE(240000000, 40, 1, 2),
|
||||
PLL_RATE(246000000, 41, 1, 2),
|
||||
PLL_RATE(252000000, 42, 1, 2),
|
||||
PLL_RATE(258000000, 43, 1, 2),
|
||||
PLL_RATE(264000000, 44, 1, 2),
|
||||
PLL_RATE(270000000, 45, 1, 2),
|
||||
PLL_RATE(276000000, 46, 1, 2),
|
||||
PLL_RATE(282000000, 47, 1, 2),
|
||||
PLL_RATE(288000000, 48, 1, 2),
|
||||
PLL_RATE(294000000, 49, 1, 2),
|
||||
PLL_RATE(300000000, 50, 1, 2),
|
||||
PLL_RATE(306000000, 51, 1, 2),
|
||||
PLL_RATE(312000000, 52, 1, 2),
|
||||
PLL_RATE(318000000, 53, 1, 2),
|
||||
PLL_RATE(324000000, 54, 1, 2),
|
||||
PLL_RATE(330000000, 55, 1, 2),
|
||||
PLL_RATE(336000000, 56, 1, 2),
|
||||
PLL_RATE(342000000, 57, 1, 2),
|
||||
PLL_RATE(348000000, 58, 1, 2),
|
||||
PLL_RATE(354000000, 59, 1, 2),
|
||||
PLL_RATE(360000000, 60, 1, 2),
|
||||
PLL_RATE(366000000, 61, 1, 2),
|
||||
PLL_RATE(372000000, 62, 1, 2),
|
||||
PLL_RATE(384000000, 32, 1, 1),
|
||||
PLL_RATE(396000000, 33, 1, 1),
|
||||
PLL_RATE(408000000, 34, 1, 1),
|
||||
PLL_RATE(420000000, 35, 1, 1),
|
||||
PLL_RATE(432000000, 36, 1, 1),
|
||||
PLL_RATE(444000000, 37, 1, 1),
|
||||
PLL_RATE(456000000, 38, 1, 1),
|
||||
PLL_RATE(468000000, 39, 1, 1),
|
||||
PLL_RATE(480000000, 40, 1, 1),
|
||||
PLL_RATE(492000000, 41, 1, 1),
|
||||
PLL_RATE(504000000, 42, 1, 1),
|
||||
PLL_RATE(516000000, 43, 1, 1),
|
||||
PLL_RATE(528000000, 44, 1, 1),
|
||||
PLL_RATE(540000000, 45, 1, 1),
|
||||
PLL_RATE(552000000, 46, 1, 1),
|
||||
PLL_RATE(564000000, 47, 1, 1),
|
||||
PLL_RATE(576000000, 48, 1, 1),
|
||||
PLL_RATE(588000000, 49, 1, 1),
|
||||
PLL_RATE(600000000, 50, 1, 1),
|
||||
PLL_RATE(612000000, 51, 1, 1),
|
||||
PLL_RATE(624000000, 52, 1, 1),
|
||||
PLL_RATE(636000000, 53, 1, 1),
|
||||
PLL_RATE(648000000, 54, 1, 1),
|
||||
PLL_RATE(660000000, 55, 1, 1),
|
||||
PLL_RATE(672000000, 56, 1, 1),
|
||||
PLL_RATE(684000000, 57, 1, 1),
|
||||
PLL_RATE(696000000, 58, 1, 1),
|
||||
PLL_RATE(708000000, 59, 1, 1),
|
||||
PLL_RATE(720000000, 60, 1, 1),
|
||||
PLL_RATE(732000000, 61, 1, 1),
|
||||
PLL_RATE(744000000, 62, 1, 1),
|
||||
PLL_RATE(768000000, 32, 1, 0),
|
||||
PLL_RATE(792000000, 33, 1, 0),
|
||||
PLL_RATE(816000000, 34, 1, 0),
|
||||
PLL_RATE(840000000, 35, 1, 0),
|
||||
PLL_RATE(864000000, 36, 1, 0),
|
||||
PLL_RATE(888000000, 37, 1, 0),
|
||||
PLL_RATE(912000000, 38, 1, 0),
|
||||
PLL_RATE(936000000, 39, 1, 0),
|
||||
PLL_RATE(960000000, 40, 1, 0),
|
||||
PLL_RATE(984000000, 41, 1, 0),
|
||||
PLL_RATE(1008000000, 42, 1, 0),
|
||||
PLL_RATE(1032000000, 43, 1, 0),
|
||||
PLL_RATE(1056000000, 44, 1, 0),
|
||||
PLL_RATE(1080000000, 45, 1, 0),
|
||||
PLL_RATE(1104000000, 46, 1, 0),
|
||||
PLL_RATE(1128000000, 47, 1, 0),
|
||||
PLL_RATE(1152000000, 48, 1, 0),
|
||||
PLL_RATE(1176000000, 49, 1, 0),
|
||||
PLL_RATE(1200000000, 50, 1, 0),
|
||||
PLL_RATE(1224000000, 51, 1, 0),
|
||||
PLL_RATE(1248000000, 52, 1, 0),
|
||||
PLL_RATE(1272000000, 53, 1, 0),
|
||||
PLL_RATE(1296000000, 54, 1, 0),
|
||||
PLL_RATE(1320000000, 55, 1, 0),
|
||||
PLL_RATE(1344000000, 56, 1, 0),
|
||||
PLL_RATE(1368000000, 57, 1, 0),
|
||||
PLL_RATE(1392000000, 58, 1, 0),
|
||||
PLL_RATE(1416000000, 59, 1, 0),
|
||||
PLL_RATE(1440000000, 60, 1, 0),
|
||||
PLL_RATE(1464000000, 61, 1, 0),
|
||||
PLL_RATE(1488000000, 62, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct clk_div_table cpu_div_table[] = {
|
||||
{ .val = 1, .div = 1 },
|
||||
{ .val = 2, .div = 2 },
|
||||
{ .val = 3, .div = 3 },
|
||||
{ .val = 2, .div = 4 },
|
||||
{ .val = 3, .div = 6 },
|
||||
{ .val = 4, .div = 8 },
|
||||
{ .val = 5, .div = 10 },
|
||||
{ .val = 6, .div = 12 },
|
||||
{ .val = 7, .div = 14 },
|
||||
{ .val = 8, .div = 16 },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static struct meson_clk_pll gxbb_fixed_pll = {
|
||||
.m = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll gxbb_hdmi_pll = {
|
||||
.m = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 0,
|
||||
.width = 12,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.od2 = {
|
||||
.reg_off = HHI_HDMI_PLL_CNTL2,
|
||||
.shift = 22,
|
||||
.width = 2,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll gxbb_sys_pll = {
|
||||
.m = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_SYS_PLL_CNTL,
|
||||
.shift = 10,
|
||||
.width = 2,
|
||||
},
|
||||
.rate_table = sys_pll_rate_table,
|
||||
.rate_count = ARRAY_SIZE(sys_pll_rate_table),
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll gxbb_gp0_pll = {
|
||||
.m = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = HHI_GP0_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.rate_table = gp0_pll_rate_table,
|
||||
.rate_count = ARRAY_SIZE(gp0_pll_rate_table),
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor gxbb_fclk_div2 = {
|
||||
.mult = 1,
|
||||
.div = 2,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div2",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor gxbb_fclk_div3 = {
|
||||
.mult = 1,
|
||||
.div = 3,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div3",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor gxbb_fclk_div4 = {
|
||||
.mult = 1,
|
||||
.div = 4,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div4",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor gxbb_fclk_div5 = {
|
||||
.mult = 1,
|
||||
.div = 5,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div5",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor gxbb_fclk_div7 = {
|
||||
.mult = 1,
|
||||
.div = 7,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div7",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_mpll gxbb_mpll0 = {
|
||||
.sdm = {
|
||||
.reg_off = HHI_MPLL_CNTL7,
|
||||
.shift = 0,
|
||||
.width = 14,
|
||||
},
|
||||
.n2 = {
|
||||
.reg_off = HHI_MPLL_CNTL7,
|
||||
.shift = 16,
|
||||
.width = 9,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpll0",
|
||||
.ops = &meson_clk_mpll_ro_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_mpll gxbb_mpll1 = {
|
||||
.sdm = {
|
||||
.reg_off = HHI_MPLL_CNTL8,
|
||||
.shift = 0,
|
||||
.width = 14,
|
||||
},
|
||||
.n2 = {
|
||||
.reg_off = HHI_MPLL_CNTL8,
|
||||
.shift = 16,
|
||||
.width = 9,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpll1",
|
||||
.ops = &meson_clk_mpll_ro_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_mpll gxbb_mpll2 = {
|
||||
.sdm = {
|
||||
.reg_off = HHI_MPLL_CNTL9,
|
||||
.shift = 0,
|
||||
.width = 14,
|
||||
},
|
||||
.n2 = {
|
||||
.reg_off = HHI_MPLL_CNTL9,
|
||||
.shift = 16,
|
||||
.width = 9,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpll2",
|
||||
.ops = &meson_clk_mpll_ro_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
|
||||
* post-dividers and should be modeled with their respective PLLs via the
|
||||
* forthcoming coordinated clock rates feature
|
||||
*/
|
||||
static struct meson_clk_cpu gxbb_cpu_clk = {
|
||||
.reg_off = HHI_SYS_CPU_CLK_CNTL1,
|
||||
.div_table = cpu_div_table,
|
||||
.clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk",
|
||||
.ops = &meson_clk_cpu_ops,
|
||||
.parent_names = (const char *[]){ "sys_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static u32 mux_table_clk81[] = { 6, 5, 7 };
|
||||
|
||||
static struct clk_mux gxbb_mpeg_clk_sel = {
|
||||
.reg = (void *)HHI_MPEG_CLK_CNTL,
|
||||
.mask = 0x7,
|
||||
.shift = 12,
|
||||
.flags = CLK_MUX_READ_ONLY,
|
||||
.table = mux_table_clk81,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpeg_clk_sel",
|
||||
.ops = &clk_mux_ro_ops,
|
||||
/*
|
||||
* FIXME bits 14:12 selects from 8 possible parents:
|
||||
* xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
|
||||
* fclk_div4, fclk_div3, fclk_div5
|
||||
*/
|
||||
.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
|
||||
"fclk_div5" },
|
||||
.num_parents = 3,
|
||||
.flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_divider gxbb_mpeg_clk_div = {
|
||||
.reg = (void *)HHI_MPEG_CLK_CNTL,
|
||||
.shift = 0,
|
||||
.width = 7,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpeg_clk_div",
|
||||
.ops = &clk_divider_ops,
|
||||
.parent_names = (const char *[]){ "mpeg_clk_sel" },
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
|
||||
/* the mother of dragons^W gates */
|
||||
static struct clk_gate gxbb_clk81 = {
|
||||
.reg = (void *)HHI_MPEG_CLK_CNTL,
|
||||
.bit_idx = 7,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "clk81",
|
||||
.ops = &clk_gate_ops,
|
||||
.parent_names = (const char *[]){ "mpeg_clk_div" },
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED | CLK_IS_CRITICAL),
|
||||
},
|
||||
};
|
||||
|
||||
/* Everything Else (EE) domain gates */
|
||||
static MESON_GATE(ddr, HHI_GCLK_MPEG0, 0);
|
||||
static MESON_GATE(dos, HHI_GCLK_MPEG0, 1);
|
||||
static MESON_GATE(isa, HHI_GCLK_MPEG0, 5);
|
||||
static MESON_GATE(pl301, HHI_GCLK_MPEG0, 6);
|
||||
static MESON_GATE(periphs, HHI_GCLK_MPEG0, 7);
|
||||
static MESON_GATE(spicc, HHI_GCLK_MPEG0, 8);
|
||||
static MESON_GATE(i2c, HHI_GCLK_MPEG0, 9);
|
||||
static MESON_GATE(sar_adc, HHI_GCLK_MPEG0, 10);
|
||||
static MESON_GATE(smart_card, HHI_GCLK_MPEG0, 11);
|
||||
static MESON_GATE(rng0, HHI_GCLK_MPEG0, 12);
|
||||
static MESON_GATE(uart0, HHI_GCLK_MPEG0, 13);
|
||||
static MESON_GATE(sdhc, HHI_GCLK_MPEG0, 14);
|
||||
static MESON_GATE(stream, HHI_GCLK_MPEG0, 15);
|
||||
static MESON_GATE(async_fifo, HHI_GCLK_MPEG0, 16);
|
||||
static MESON_GATE(sdio, HHI_GCLK_MPEG0, 17);
|
||||
static MESON_GATE(abuf, HHI_GCLK_MPEG0, 18);
|
||||
static MESON_GATE(hiu_iface, HHI_GCLK_MPEG0, 19);
|
||||
static MESON_GATE(assist_misc, HHI_GCLK_MPEG0, 23);
|
||||
static MESON_GATE(spi, HHI_GCLK_MPEG0, 30);
|
||||
|
||||
static MESON_GATE(i2s_spdif, HHI_GCLK_MPEG1, 2);
|
||||
static MESON_GATE(eth, HHI_GCLK_MPEG1, 3);
|
||||
static MESON_GATE(demux, HHI_GCLK_MPEG1, 4);
|
||||
static MESON_GATE(aiu_glue, HHI_GCLK_MPEG1, 6);
|
||||
static MESON_GATE(iec958, HHI_GCLK_MPEG1, 7);
|
||||
static MESON_GATE(i2s_out, HHI_GCLK_MPEG1, 8);
|
||||
static MESON_GATE(amclk, HHI_GCLK_MPEG1, 9);
|
||||
static MESON_GATE(aififo2, HHI_GCLK_MPEG1, 10);
|
||||
static MESON_GATE(mixer, HHI_GCLK_MPEG1, 11);
|
||||
static MESON_GATE(mixer_iface, HHI_GCLK_MPEG1, 12);
|
||||
static MESON_GATE(adc, HHI_GCLK_MPEG1, 13);
|
||||
static MESON_GATE(blkmv, HHI_GCLK_MPEG1, 14);
|
||||
static MESON_GATE(aiu, HHI_GCLK_MPEG1, 15);
|
||||
static MESON_GATE(uart1, HHI_GCLK_MPEG1, 16);
|
||||
static MESON_GATE(g2d, HHI_GCLK_MPEG1, 20);
|
||||
static MESON_GATE(usb0, HHI_GCLK_MPEG1, 21);
|
||||
static MESON_GATE(usb1, HHI_GCLK_MPEG1, 22);
|
||||
static MESON_GATE(reset, HHI_GCLK_MPEG1, 23);
|
||||
static MESON_GATE(nand, HHI_GCLK_MPEG1, 24);
|
||||
static MESON_GATE(dos_parser, HHI_GCLK_MPEG1, 25);
|
||||
static MESON_GATE(usb, HHI_GCLK_MPEG1, 26);
|
||||
static MESON_GATE(vdin1, HHI_GCLK_MPEG1, 28);
|
||||
static MESON_GATE(ahb_arb0, HHI_GCLK_MPEG1, 29);
|
||||
static MESON_GATE(efuse, HHI_GCLK_MPEG1, 30);
|
||||
static MESON_GATE(boot_rom, HHI_GCLK_MPEG1, 31);
|
||||
|
||||
static MESON_GATE(ahb_data_bus, HHI_GCLK_MPEG2, 1);
|
||||
static MESON_GATE(ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
|
||||
static MESON_GATE(hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
|
||||
static MESON_GATE(hdmi_pclk, HHI_GCLK_MPEG2, 4);
|
||||
static MESON_GATE(usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
|
||||
static MESON_GATE(usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
|
||||
static MESON_GATE(mmc_pclk, HHI_GCLK_MPEG2, 11);
|
||||
static MESON_GATE(dvin, HHI_GCLK_MPEG2, 12);
|
||||
static MESON_GATE(uart2, HHI_GCLK_MPEG2, 15);
|
||||
static MESON_GATE(sana, HHI_GCLK_MPEG2, 22);
|
||||
static MESON_GATE(vpu_intr, HHI_GCLK_MPEG2, 25);
|
||||
static MESON_GATE(sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
|
||||
static MESON_GATE(clk81_a53, HHI_GCLK_MPEG2, 29);
|
||||
|
||||
static MESON_GATE(vclk2_venci0, HHI_GCLK_OTHER, 1);
|
||||
static MESON_GATE(vclk2_venci1, HHI_GCLK_OTHER, 2);
|
||||
static MESON_GATE(vclk2_vencp0, HHI_GCLK_OTHER, 3);
|
||||
static MESON_GATE(vclk2_vencp1, HHI_GCLK_OTHER, 4);
|
||||
static MESON_GATE(gclk_venci_int0, HHI_GCLK_OTHER, 8);
|
||||
static MESON_GATE(gclk_vencp_int, HHI_GCLK_OTHER, 9);
|
||||
static MESON_GATE(dac_clk, HHI_GCLK_OTHER, 10);
|
||||
static MESON_GATE(aoclk_gate, HHI_GCLK_OTHER, 14);
|
||||
static MESON_GATE(iec958_gate, HHI_GCLK_OTHER, 16);
|
||||
static MESON_GATE(enc480p, HHI_GCLK_OTHER, 20);
|
||||
static MESON_GATE(rng1, HHI_GCLK_OTHER, 21);
|
||||
static MESON_GATE(gclk_venci_int1, HHI_GCLK_OTHER, 22);
|
||||
static MESON_GATE(vclk2_venclmcc, HHI_GCLK_OTHER, 24);
|
||||
static MESON_GATE(vclk2_vencl, HHI_GCLK_OTHER, 25);
|
||||
static MESON_GATE(vclk_other, HHI_GCLK_OTHER, 26);
|
||||
static MESON_GATE(edp, HHI_GCLK_OTHER, 31);
|
||||
|
||||
/* Always On (AO) domain gates */
|
||||
|
||||
static MESON_GATE(ao_media_cpu, HHI_GCLK_AO, 0);
|
||||
static MESON_GATE(ao_ahb_sram, HHI_GCLK_AO, 1);
|
||||
static MESON_GATE(ao_ahb_bus, HHI_GCLK_AO, 2);
|
||||
static MESON_GATE(ao_iface, HHI_GCLK_AO, 3);
|
||||
static MESON_GATE(ao_i2c, HHI_GCLK_AO, 4);
|
||||
|
||||
/* Array of all clocks provided by this provider */
|
||||
|
||||
static struct clk_hw_onecell_data gxbb_hw_onecell_data = {
|
||||
.hws = {
|
||||
[CLKID_SYS_PLL] = &gxbb_sys_pll.hw,
|
||||
[CLKID_CPUCLK] = &gxbb_cpu_clk.hw,
|
||||
[CLKID_HDMI_PLL] = &gxbb_hdmi_pll.hw,
|
||||
[CLKID_FIXED_PLL] = &gxbb_fixed_pll.hw,
|
||||
[CLKID_FCLK_DIV2] = &gxbb_fclk_div2.hw,
|
||||
[CLKID_FCLK_DIV3] = &gxbb_fclk_div3.hw,
|
||||
[CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw,
|
||||
[CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw,
|
||||
[CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw,
|
||||
[CLKID_GP0_PLL] = &gxbb_gp0_pll.hw,
|
||||
[CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw,
|
||||
[CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw,
|
||||
[CLKID_CLK81] = &gxbb_clk81.hw,
|
||||
[CLKID_MPLL0] = &gxbb_mpll0.hw,
|
||||
[CLKID_MPLL1] = &gxbb_mpll1.hw,
|
||||
[CLKID_MPLL2] = &gxbb_mpll2.hw,
|
||||
[CLKID_DDR] = &gxbb_ddr.hw,
|
||||
[CLKID_DOS] = &gxbb_dos.hw,
|
||||
[CLKID_ISA] = &gxbb_isa.hw,
|
||||
[CLKID_PL301] = &gxbb_pl301.hw,
|
||||
[CLKID_PERIPHS] = &gxbb_periphs.hw,
|
||||
[CLKID_SPICC] = &gxbb_spicc.hw,
|
||||
[CLKID_I2C] = &gxbb_i2c.hw,
|
||||
[CLKID_SAR_ADC] = &gxbb_sar_adc.hw,
|
||||
[CLKID_SMART_CARD] = &gxbb_smart_card.hw,
|
||||
[CLKID_RNG0] = &gxbb_rng0.hw,
|
||||
[CLKID_UART0] = &gxbb_uart0.hw,
|
||||
[CLKID_SDHC] = &gxbb_sdhc.hw,
|
||||
[CLKID_STREAM] = &gxbb_stream.hw,
|
||||
[CLKID_ASYNC_FIFO] = &gxbb_async_fifo.hw,
|
||||
[CLKID_SDIO] = &gxbb_sdio.hw,
|
||||
[CLKID_ABUF] = &gxbb_abuf.hw,
|
||||
[CLKID_HIU_IFACE] = &gxbb_hiu_iface.hw,
|
||||
[CLKID_ASSIST_MISC] = &gxbb_assist_misc.hw,
|
||||
[CLKID_SPI] = &gxbb_spi.hw,
|
||||
[CLKID_I2S_SPDIF] = &gxbb_i2s_spdif.hw,
|
||||
[CLKID_ETH] = &gxbb_eth.hw,
|
||||
[CLKID_DEMUX] = &gxbb_demux.hw,
|
||||
[CLKID_AIU_GLUE] = &gxbb_aiu_glue.hw,
|
||||
[CLKID_IEC958] = &gxbb_iec958.hw,
|
||||
[CLKID_I2S_OUT] = &gxbb_i2s_out.hw,
|
||||
[CLKID_AMCLK] = &gxbb_amclk.hw,
|
||||
[CLKID_AIFIFO2] = &gxbb_aififo2.hw,
|
||||
[CLKID_MIXER] = &gxbb_mixer.hw,
|
||||
[CLKID_MIXER_IFACE] = &gxbb_mixer_iface.hw,
|
||||
[CLKID_ADC] = &gxbb_adc.hw,
|
||||
[CLKID_BLKMV] = &gxbb_blkmv.hw,
|
||||
[CLKID_AIU] = &gxbb_aiu.hw,
|
||||
[CLKID_UART1] = &gxbb_uart1.hw,
|
||||
[CLKID_G2D] = &gxbb_g2d.hw,
|
||||
[CLKID_USB0] = &gxbb_usb0.hw,
|
||||
[CLKID_USB1] = &gxbb_usb1.hw,
|
||||
[CLKID_RESET] = &gxbb_reset.hw,
|
||||
[CLKID_NAND] = &gxbb_nand.hw,
|
||||
[CLKID_DOS_PARSER] = &gxbb_dos_parser.hw,
|
||||
[CLKID_USB] = &gxbb_usb.hw,
|
||||
[CLKID_VDIN1] = &gxbb_vdin1.hw,
|
||||
[CLKID_AHB_ARB0] = &gxbb_ahb_arb0.hw,
|
||||
[CLKID_EFUSE] = &gxbb_efuse.hw,
|
||||
[CLKID_BOOT_ROM] = &gxbb_boot_rom.hw,
|
||||
[CLKID_AHB_DATA_BUS] = &gxbb_ahb_data_bus.hw,
|
||||
[CLKID_AHB_CTRL_BUS] = &gxbb_ahb_ctrl_bus.hw,
|
||||
[CLKID_HDMI_INTR_SYNC] = &gxbb_hdmi_intr_sync.hw,
|
||||
[CLKID_HDMI_PCLK] = &gxbb_hdmi_pclk.hw,
|
||||
[CLKID_USB1_DDR_BRIDGE] = &gxbb_usb1_ddr_bridge.hw,
|
||||
[CLKID_USB0_DDR_BRIDGE] = &gxbb_usb0_ddr_bridge.hw,
|
||||
[CLKID_MMC_PCLK] = &gxbb_mmc_pclk.hw,
|
||||
[CLKID_DVIN] = &gxbb_dvin.hw,
|
||||
[CLKID_UART2] = &gxbb_uart2.hw,
|
||||
[CLKID_SANA] = &gxbb_sana.hw,
|
||||
[CLKID_VPU_INTR] = &gxbb_vpu_intr.hw,
|
||||
[CLKID_SEC_AHB_AHB3_BRIDGE] = &gxbb_sec_ahb_ahb3_bridge.hw,
|
||||
[CLKID_CLK81_A53] = &gxbb_clk81_a53.hw,
|
||||
[CLKID_VCLK2_VENCI0] = &gxbb_vclk2_venci0.hw,
|
||||
[CLKID_VCLK2_VENCI1] = &gxbb_vclk2_venci1.hw,
|
||||
[CLKID_VCLK2_VENCP0] = &gxbb_vclk2_vencp0.hw,
|
||||
[CLKID_VCLK2_VENCP1] = &gxbb_vclk2_vencp1.hw,
|
||||
[CLKID_GCLK_VENCI_INT0] = &gxbb_gclk_venci_int0.hw,
|
||||
[CLKID_GCLK_VENCI_INT] = &gxbb_gclk_vencp_int.hw,
|
||||
[CLKID_DAC_CLK] = &gxbb_dac_clk.hw,
|
||||
[CLKID_AOCLK_GATE] = &gxbb_aoclk_gate.hw,
|
||||
[CLKID_IEC958_GATE] = &gxbb_iec958_gate.hw,
|
||||
[CLKID_ENC480P] = &gxbb_enc480p.hw,
|
||||
[CLKID_RNG1] = &gxbb_rng1.hw,
|
||||
[CLKID_GCLK_VENCI_INT1] = &gxbb_gclk_venci_int1.hw,
|
||||
[CLKID_VCLK2_VENCLMCC] = &gxbb_vclk2_venclmcc.hw,
|
||||
[CLKID_VCLK2_VENCL] = &gxbb_vclk2_vencl.hw,
|
||||
[CLKID_VCLK_OTHER] = &gxbb_vclk_other.hw,
|
||||
[CLKID_EDP] = &gxbb_edp.hw,
|
||||
[CLKID_AO_MEDIA_CPU] = &gxbb_ao_media_cpu.hw,
|
||||
[CLKID_AO_AHB_SRAM] = &gxbb_ao_ahb_sram.hw,
|
||||
[CLKID_AO_AHB_BUS] = &gxbb_ao_ahb_bus.hw,
|
||||
[CLKID_AO_IFACE] = &gxbb_ao_iface.hw,
|
||||
[CLKID_AO_I2C] = &gxbb_ao_i2c.hw,
|
||||
},
|
||||
.num = NR_CLKS,
|
||||
};
|
||||
|
||||
/* Convenience tables to populate base addresses in .probe */
|
||||
|
||||
static struct meson_clk_pll *const gxbb_clk_plls[] = {
|
||||
&gxbb_fixed_pll,
|
||||
&gxbb_hdmi_pll,
|
||||
&gxbb_sys_pll,
|
||||
&gxbb_gp0_pll,
|
||||
};
|
||||
|
||||
static struct meson_clk_mpll *const gxbb_clk_mplls[] = {
|
||||
&gxbb_mpll0,
|
||||
&gxbb_mpll1,
|
||||
&gxbb_mpll2,
|
||||
};
|
||||
|
||||
static struct clk_gate *gxbb_clk_gates[] = {
|
||||
&gxbb_clk81,
|
||||
&gxbb_ddr,
|
||||
&gxbb_dos,
|
||||
&gxbb_isa,
|
||||
&gxbb_pl301,
|
||||
&gxbb_periphs,
|
||||
&gxbb_spicc,
|
||||
&gxbb_i2c,
|
||||
&gxbb_sar_adc,
|
||||
&gxbb_smart_card,
|
||||
&gxbb_rng0,
|
||||
&gxbb_uart0,
|
||||
&gxbb_sdhc,
|
||||
&gxbb_stream,
|
||||
&gxbb_async_fifo,
|
||||
&gxbb_sdio,
|
||||
&gxbb_abuf,
|
||||
&gxbb_hiu_iface,
|
||||
&gxbb_assist_misc,
|
||||
&gxbb_spi,
|
||||
&gxbb_i2s_spdif,
|
||||
&gxbb_eth,
|
||||
&gxbb_demux,
|
||||
&gxbb_aiu_glue,
|
||||
&gxbb_iec958,
|
||||
&gxbb_i2s_out,
|
||||
&gxbb_amclk,
|
||||
&gxbb_aififo2,
|
||||
&gxbb_mixer,
|
||||
&gxbb_mixer_iface,
|
||||
&gxbb_adc,
|
||||
&gxbb_blkmv,
|
||||
&gxbb_aiu,
|
||||
&gxbb_uart1,
|
||||
&gxbb_g2d,
|
||||
&gxbb_usb0,
|
||||
&gxbb_usb1,
|
||||
&gxbb_reset,
|
||||
&gxbb_nand,
|
||||
&gxbb_dos_parser,
|
||||
&gxbb_usb,
|
||||
&gxbb_vdin1,
|
||||
&gxbb_ahb_arb0,
|
||||
&gxbb_efuse,
|
||||
&gxbb_boot_rom,
|
||||
&gxbb_ahb_data_bus,
|
||||
&gxbb_ahb_ctrl_bus,
|
||||
&gxbb_hdmi_intr_sync,
|
||||
&gxbb_hdmi_pclk,
|
||||
&gxbb_usb1_ddr_bridge,
|
||||
&gxbb_usb0_ddr_bridge,
|
||||
&gxbb_mmc_pclk,
|
||||
&gxbb_dvin,
|
||||
&gxbb_uart2,
|
||||
&gxbb_sana,
|
||||
&gxbb_vpu_intr,
|
||||
&gxbb_sec_ahb_ahb3_bridge,
|
||||
&gxbb_clk81_a53,
|
||||
&gxbb_vclk2_venci0,
|
||||
&gxbb_vclk2_venci1,
|
||||
&gxbb_vclk2_vencp0,
|
||||
&gxbb_vclk2_vencp1,
|
||||
&gxbb_gclk_venci_int0,
|
||||
&gxbb_gclk_vencp_int,
|
||||
&gxbb_dac_clk,
|
||||
&gxbb_aoclk_gate,
|
||||
&gxbb_iec958_gate,
|
||||
&gxbb_enc480p,
|
||||
&gxbb_rng1,
|
||||
&gxbb_gclk_venci_int1,
|
||||
&gxbb_vclk2_venclmcc,
|
||||
&gxbb_vclk2_vencl,
|
||||
&gxbb_vclk_other,
|
||||
&gxbb_edp,
|
||||
&gxbb_ao_media_cpu,
|
||||
&gxbb_ao_ahb_sram,
|
||||
&gxbb_ao_ahb_bus,
|
||||
&gxbb_ao_iface,
|
||||
&gxbb_ao_i2c,
|
||||
};
|
||||
|
||||
static int gxbb_clkc_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *clk_base;
|
||||
int ret, clkid, i;
|
||||
struct clk_hw *parent_hw;
|
||||
struct clk *parent_clk;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
/* Generic clocks and PLLs */
|
||||
clk_base = of_iomap(dev->of_node, 0);
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map clk base\n", __func__);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Populate base address for PLLs */
|
||||
for (i = 0; i < ARRAY_SIZE(gxbb_clk_plls); i++)
|
||||
gxbb_clk_plls[i]->base = clk_base;
|
||||
|
||||
/* Populate base address for MPLLs */
|
||||
for (i = 0; i < ARRAY_SIZE(gxbb_clk_mplls); i++)
|
||||
gxbb_clk_mplls[i]->base = clk_base;
|
||||
|
||||
/* Populate the base address for CPU clk */
|
||||
gxbb_cpu_clk.base = clk_base;
|
||||
|
||||
/* Populate the base address for the MPEG clks */
|
||||
gxbb_mpeg_clk_sel.reg = clk_base + (u64)gxbb_mpeg_clk_sel.reg;
|
||||
gxbb_mpeg_clk_div.reg = clk_base + (u64)gxbb_mpeg_clk_div.reg;
|
||||
|
||||
/* Populate base address for gates */
|
||||
for (i = 0; i < ARRAY_SIZE(gxbb_clk_gates); i++)
|
||||
gxbb_clk_gates[i]->reg = clk_base +
|
||||
(u64)gxbb_clk_gates[i]->reg;
|
||||
|
||||
/*
|
||||
* register all clks
|
||||
*/
|
||||
for (clkid = 0; clkid < NR_CLKS; clkid++) {
|
||||
ret = devm_clk_hw_register(dev, gxbb_hw_onecell_data.hws[clkid]);
|
||||
if (ret)
|
||||
goto iounmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register CPU clk notifier
|
||||
*
|
||||
* FIXME this is wrong for a lot of reasons. First, the muxes should be
|
||||
* struct clk_hw objects. Second, we shouldn't program the muxes in
|
||||
* notifier handlers. The tricky programming sequence will be handled
|
||||
* by the forthcoming coordinated clock rates mechanism once that
|
||||
* feature is released.
|
||||
*
|
||||
* Furthermore, looking up the parent this way is terrible. At some
|
||||
* point we will stop allocating a default struct clk when registering
|
||||
* a new clk_hw, and this hack will no longer work. Releasing the ccr
|
||||
* feature before that time solves the problem :-)
|
||||
*/
|
||||
parent_hw = clk_hw_get_parent(&gxbb_cpu_clk.hw);
|
||||
parent_clk = parent_hw->clk;
|
||||
ret = clk_notifier_register(parent_clk, &gxbb_cpu_clk.clk_nb);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to register clock notifier for cpu_clk\n",
|
||||
__func__);
|
||||
goto iounmap;
|
||||
}
|
||||
|
||||
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
|
||||
&gxbb_hw_onecell_data);
|
||||
|
||||
iounmap:
|
||||
iounmap(clk_base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id gxbb_clkc_match_table[] = {
|
||||
{ .compatible = "amlogic,gxbb-clkc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver gxbb_driver = {
|
||||
.probe = gxbb_clkc_probe,
|
||||
.driver = {
|
||||
.name = "gxbb-clkc",
|
||||
.of_match_table = gxbb_clkc_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init gxbb_clkc_init(void)
|
||||
{
|
||||
return platform_driver_register(&gxbb_driver);
|
||||
}
|
||||
device_initcall(gxbb_clkc_init);
|
271
drivers/clk/meson/gxbb.h
Normal file
271
drivers/clk/meson/gxbb.h
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright (c) 2016 AmLogic, Inc.
|
||||
* Author: Michael Turquette <mturquette@baylibre.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright (c) 2016 BayLibre, Inc.
|
||||
* Author: Michael Turquette <mturquette@baylibre.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __GXBB_H
|
||||
#define __GXBB_H
|
||||
|
||||
/*
|
||||
* Clock controller register offsets
|
||||
*
|
||||
* Register offsets from the data sheet are listed in comment blocks below.
|
||||
* Those offsets must be multiplied by 4 before adding them to the base address
|
||||
* to get the right value
|
||||
*/
|
||||
#define SCR 0x2C /* 0x0b offset in data sheet */
|
||||
#define TIMEOUT_VALUE 0x3c /* 0x0f offset in data sheet */
|
||||
|
||||
#define HHI_GP0_PLL_CNTL 0x40 /* 0x10 offset in data sheet */
|
||||
#define HHI_GP0_PLL_CNTL2 0x44 /* 0x11 offset in data sheet */
|
||||
#define HHI_GP0_PLL_CNTL3 0x48 /* 0x12 offset in data sheet */
|
||||
#define HHI_GP0_PLL_CNTL4 0x4c /* 0x13 offset in data sheet */
|
||||
|
||||
#define HHI_XTAL_DIVN_CNTL 0xbc /* 0x2f offset in data sheet */
|
||||
#define HHI_TIMER90K 0xec /* 0x3b offset in data sheet */
|
||||
|
||||
#define HHI_MEM_PD_REG0 0x100 /* 0x40 offset in data sheet */
|
||||
#define HHI_MEM_PD_REG1 0x104 /* 0x41 offset in data sheet */
|
||||
#define HHI_VPU_MEM_PD_REG1 0x108 /* 0x42 offset in data sheet */
|
||||
#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
|
||||
#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
|
||||
|
||||
#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
|
||||
#define HHI_GCLK_MPEG1 0x144 /* 0x51 offset in data sheet */
|
||||
#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
|
||||
#define HHI_GCLK_OTHER 0x150 /* 0x54 offset in data sheet */
|
||||
#define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
|
||||
#define HHI_SYS_OSCIN_CNTL 0x158 /* 0x56 offset in data sheet */
|
||||
#define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
|
||||
#define HHI_SYS_CPU_RESET_CNTL 0x160 /* 0x58 offset in data sheet */
|
||||
#define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */
|
||||
|
||||
#define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
|
||||
#define HHI_AUD_CLK_CNTL 0x178 /* 0x5e offset in data sheet */
|
||||
#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
|
||||
#define HHI_AUD_CLK_CNTL2 0x190 /* 0x64 offset in data sheet */
|
||||
#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
|
||||
#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
|
||||
#define HHI_VID_PLL_CLK_DIV 0x1a0 /* 0x68 offset in data sheet */
|
||||
#define HHI_AUD_CLK_CNTL3 0x1a4 /* 0x69 offset in data sheet */
|
||||
#define HHI_MALI_CLK_CNTL 0x1b0 /* 0x6c offset in data sheet */
|
||||
#define HHI_VPU_CLK_CNTL 0x1bC /* 0x6f offset in data sheet */
|
||||
|
||||
#define HHI_HDMI_CLK_CNTL 0x1CC /* 0x73 offset in data sheet */
|
||||
#define HHI_VDEC_CLK_CNTL 0x1E0 /* 0x78 offset in data sheet */
|
||||
#define HHI_VDEC2_CLK_CNTL 0x1E4 /* 0x79 offset in data sheet */
|
||||
#define HHI_VDEC3_CLK_CNTL 0x1E8 /* 0x7a offset in data sheet */
|
||||
#define HHI_VDEC4_CLK_CNTL 0x1EC /* 0x7b offset in data sheet */
|
||||
#define HHI_HDCP22_CLK_CNTL 0x1F0 /* 0x7c offset in data sheet */
|
||||
#define HHI_VAPBCLK_CNTL 0x1F4 /* 0x7d offset in data sheet */
|
||||
|
||||
#define HHI_VPU_CLKB_CNTL 0x20C /* 0x83 offset in data sheet */
|
||||
#define HHI_USB_CLK_CNTL 0x220 /* 0x88 offset in data sheet */
|
||||
#define HHI_32K_CLK_CNTL 0x224 /* 0x89 offset in data sheet */
|
||||
#define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */
|
||||
#define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */
|
||||
|
||||
#define HHI_PCM_CLK_CNTL 0x258 /* 0x96 offset in data sheet */
|
||||
#define HHI_NAND_CLK_CNTL 0x25C /* 0x97 offset in data sheet */
|
||||
#define HHI_SD_EMMC_CLK_CNTL 0x264 /* 0x99 offset in data sheet */
|
||||
|
||||
#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL2 0x284 /* 0xa1 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL3 0x288 /* 0xa2 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL4 0x28C /* 0xa3 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL5 0x290 /* 0xa4 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL6 0x294 /* 0xa5 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL7 0x298 /* MP0, 0xa6 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL8 0x29C /* MP1, 0xa7 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL9 0x2A0 /* MP2, 0xa8 offset in data sheet */
|
||||
#define HHI_MPLL_CNTL10 0x2A4 /* MP2, 0xa9 offset in data sheet */
|
||||
|
||||
#define HHI_MPLL3_CNTL0 0x2E0 /* 0xb8 offset in data sheet */
|
||||
#define HHI_MPLL3_CNTL1 0x2E4 /* 0xb9 offset in data sheet */
|
||||
#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
|
||||
#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
|
||||
|
||||
#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
|
||||
#define HHI_SYS_PLL_CNTL2 0x304 /* 0xc1 offset in data sheet */
|
||||
#define HHI_SYS_PLL_CNTL3 0x308 /* 0xc2 offset in data sheet */
|
||||
#define HHI_SYS_PLL_CNTL4 0x30c /* 0xc3 offset in data sheet */
|
||||
#define HHI_SYS_PLL_CNTL5 0x310 /* 0xc4 offset in data sheet */
|
||||
#define HHI_DPLL_TOP_I 0x318 /* 0xc6 offset in data sheet */
|
||||
#define HHI_DPLL_TOP2_I 0x31C /* 0xc7 offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL_I 0x338 /* 0xce offset in data sheet */
|
||||
#define HHI_HDMI_PLL_CNTL7 0x33C /* 0xcf offset in data sheet */
|
||||
|
||||
#define HHI_HDMI_PHY_CNTL0 0x3A0 /* 0xe8 offset in data sheet */
|
||||
#define HHI_HDMI_PHY_CNTL1 0x3A4 /* 0xe9 offset in data sheet */
|
||||
#define HHI_HDMI_PHY_CNTL2 0x3A8 /* 0xea offset in data sheet */
|
||||
#define HHI_HDMI_PHY_CNTL3 0x3AC /* 0xeb offset in data sheet */
|
||||
|
||||
#define HHI_VID_LOCK_CLK_CNTL 0x3C8 /* 0xf2 offset in data sheet */
|
||||
#define HHI_BT656_CLK_CNTL 0x3D4 /* 0xf5 offset in data sheet */
|
||||
#define HHI_SAR_CLK_CNTL 0x3D8 /* 0xf6 offset in data sheet */
|
||||
|
||||
/*
|
||||
* CLKID index values
|
||||
*
|
||||
* These indices are entirely contrived and do not map onto the hardware.
|
||||
* Migrate them out of this header and into the DT header file when they need
|
||||
* to be exposed to client nodes in DT: include/dt-bindings/clock/gxbb-clkc.h
|
||||
*/
|
||||
#define CLKID_SYS_PLL 0
|
||||
/* CLKID_CPUCLK */
|
||||
#define CLKID_HDMI_PLL 2
|
||||
#define CLKID_FIXED_PLL 3
|
||||
#define CLKID_FCLK_DIV2 4
|
||||
#define CLKID_FCLK_DIV3 5
|
||||
#define CLKID_FCLK_DIV4 6
|
||||
#define CLKID_FCLK_DIV5 7
|
||||
#define CLKID_FCLK_DIV7 8
|
||||
#define CLKID_GP0_PLL 9
|
||||
#define CLKID_MPEG_SEL 10
|
||||
#define CLKID_MPEG_DIV 11
|
||||
/* CLKID_CLK81 */
|
||||
#define CLKID_MPLL0 13
|
||||
#define CLKID_MPLL1 14
|
||||
#define CLKID_MPLL2 15
|
||||
#define CLKID_DDR 16
|
||||
#define CLKID_DOS 17
|
||||
#define CLKID_ISA 18
|
||||
#define CLKID_PL301 19
|
||||
#define CLKID_PERIPHS 20
|
||||
#define CLKID_SPICC 21
|
||||
#define CLKID_I2C 22
|
||||
#define CLKID_SAR_ADC 23
|
||||
#define CLKID_SMART_CARD 24
|
||||
#define CLKID_RNG0 25
|
||||
#define CLKID_UART0 26
|
||||
#define CLKID_SDHC 27
|
||||
#define CLKID_STREAM 28
|
||||
#define CLKID_ASYNC_FIFO 29
|
||||
#define CLKID_SDIO 30
|
||||
#define CLKID_ABUF 31
|
||||
#define CLKID_HIU_IFACE 32
|
||||
#define CLKID_ASSIST_MISC 33
|
||||
#define CLKID_SPI 34
|
||||
#define CLKID_I2S_SPDIF 35
|
||||
#define CLKID_ETH 36
|
||||
#define CLKID_DEMUX 37
|
||||
#define CLKID_AIU_GLUE 38
|
||||
#define CLKID_IEC958 39
|
||||
#define CLKID_I2S_OUT 40
|
||||
#define CLKID_AMCLK 41
|
||||
#define CLKID_AIFIFO2 42
|
||||
#define CLKID_MIXER 43
|
||||
#define CLKID_MIXER_IFACE 44
|
||||
#define CLKID_ADC 45
|
||||
#define CLKID_BLKMV 46
|
||||
#define CLKID_AIU 47
|
||||
#define CLKID_UART1 48
|
||||
#define CLKID_G2D 49
|
||||
#define CLKID_USB0 50
|
||||
#define CLKID_USB1 51
|
||||
#define CLKID_RESET 52
|
||||
#define CLKID_NAND 53
|
||||
#define CLKID_DOS_PARSER 54
|
||||
#define CLKID_USB 55
|
||||
#define CLKID_VDIN1 56
|
||||
#define CLKID_AHB_ARB0 57
|
||||
#define CLKID_EFUSE 58
|
||||
#define CLKID_BOOT_ROM 59
|
||||
#define CLKID_AHB_DATA_BUS 60
|
||||
#define CLKID_AHB_CTRL_BUS 61
|
||||
#define CLKID_HDMI_INTR_SYNC 62
|
||||
#define CLKID_HDMI_PCLK 63
|
||||
#define CLKID_USB1_DDR_BRIDGE 64
|
||||
#define CLKID_USB0_DDR_BRIDGE 65
|
||||
#define CLKID_MMC_PCLK 66
|
||||
#define CLKID_DVIN 67
|
||||
#define CLKID_UART2 68
|
||||
#define CLKID_SANA 69
|
||||
#define CLKID_VPU_INTR 70
|
||||
#define CLKID_SEC_AHB_AHB3_BRIDGE 71
|
||||
#define CLKID_CLK81_A53 72
|
||||
#define CLKID_VCLK2_VENCI0 73
|
||||
#define CLKID_VCLK2_VENCI1 74
|
||||
#define CLKID_VCLK2_VENCP0 75
|
||||
#define CLKID_VCLK2_VENCP1 76
|
||||
#define CLKID_GCLK_VENCI_INT0 77
|
||||
#define CLKID_GCLK_VENCI_INT 78
|
||||
#define CLKID_DAC_CLK 79
|
||||
#define CLKID_AOCLK_GATE 80
|
||||
#define CLKID_IEC958_GATE 81
|
||||
#define CLKID_ENC480P 82
|
||||
#define CLKID_RNG1 83
|
||||
#define CLKID_GCLK_VENCI_INT1 84
|
||||
#define CLKID_VCLK2_VENCLMCC 85
|
||||
#define CLKID_VCLK2_VENCL 86
|
||||
#define CLKID_VCLK_OTHER 87
|
||||
#define CLKID_EDP 88
|
||||
#define CLKID_AO_MEDIA_CPU 89
|
||||
#define CLKID_AO_AHB_SRAM 90
|
||||
#define CLKID_AO_AHB_BUS 91
|
||||
#define CLKID_AO_IFACE 92
|
||||
#define CLKID_AO_I2C 93
|
||||
|
||||
#define NR_CLKS 94
|
||||
|
||||
/* include the CLKIDs that have been made part of the stable DT binding */
|
||||
#include <dt-bindings/clock/gxbb-clkc.h>
|
||||
|
||||
#endif /* __GXBB_H */
|
@ -1,7 +1,12 @@
|
||||
/*
|
||||
* AmLogic S805 / Meson8b Clock Controller Driver
|
||||
*
|
||||
* Copyright (c) 2015 Endless Mobile, Inc.
|
||||
* Author: Carlo Caione <carlo@endlessm.com>
|
||||
*
|
||||
* Copyright (c) 2016 BayLibre, Inc.
|
||||
* Michael Turquette <mturquette@baylibre.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
@ -15,23 +20,33 @@
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
#include <dt-bindings/clock/meson8b-clkc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "clkc.h"
|
||||
|
||||
#define MESON8B_REG_CTL0_ADDR 0x0000
|
||||
#define MESON8B_REG_SYS_CPU_CNTL1 0x015c
|
||||
#define MESON8B_REG_HHI_MPEG 0x0174
|
||||
#define MESON8B_REG_MALI 0x01b0
|
||||
/*
|
||||
* Clock controller register offsets
|
||||
*
|
||||
* Register offsets from the HardKernel[0] data sheet are listed in comment
|
||||
* blocks below. Those offsets must be multiplied by 4 before adding them to
|
||||
* the base address to get the right value
|
||||
*
|
||||
* [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
|
||||
*/
|
||||
#define MESON8B_REG_SYS_CPU_CNTL1 0x015c /* 0x57 offset in data sheet */
|
||||
#define MESON8B_REG_HHI_MPEG 0x0174 /* 0x5d offset in data sheet */
|
||||
#define MESON8B_REG_MALI 0x01b0 /* 0x6c offset in data sheet */
|
||||
#define MESON8B_REG_PLL_FIXED 0x0280
|
||||
#define MESON8B_REG_PLL_SYS 0x0300
|
||||
#define MESON8B_REG_PLL_VID 0x0320
|
||||
|
||||
static DEFINE_SPINLOCK(clk_lock);
|
||||
|
||||
static const struct pll_rate_table sys_pll_rate_table[] = {
|
||||
PLL_RATE(312000000, 52, 1, 2),
|
||||
PLL_RATE(336000000, 56, 1, 2),
|
||||
@ -102,95 +117,331 @@ static const struct clk_div_table cpu_div_table[] = {
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
PNAME(p_xtal) = { "xtal" };
|
||||
PNAME(p_fclk_div) = { "fixed_pll" };
|
||||
PNAME(p_cpu_clk) = { "sys_pll" };
|
||||
PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" };
|
||||
PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5",
|
||||
"fclk_div7", "zero" };
|
||||
static struct clk_fixed_rate meson8b_xtal = {
|
||||
.fixed_rate = 24000000,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "xtal",
|
||||
.num_parents = 0,
|
||||
.ops = &clk_fixed_rate_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll meson8b_fixed_pll = {
|
||||
.m = {
|
||||
.reg_off = MESON8B_REG_PLL_FIXED,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = MESON8B_REG_PLL_FIXED,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = MESON8B_REG_PLL_FIXED,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll meson8b_vid_pll = {
|
||||
.m = {
|
||||
.reg_off = MESON8B_REG_PLL_VID,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = MESON8B_REG_PLL_VID,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = MESON8B_REG_PLL_VID,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll meson8b_sys_pll = {
|
||||
.m = {
|
||||
.reg_off = MESON8B_REG_PLL_SYS,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = MESON8B_REG_PLL_SYS,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.od = {
|
||||
.reg_off = MESON8B_REG_PLL_SYS,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
.rate_table = sys_pll_rate_table,
|
||||
.rate_count = ARRAY_SIZE(sys_pll_rate_table),
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor meson8b_fclk_div2 = {
|
||||
.mult = 1,
|
||||
.div = 2,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div2",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor meson8b_fclk_div3 = {
|
||||
.mult = 1,
|
||||
.div = 3,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div3",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor meson8b_fclk_div4 = {
|
||||
.mult = 1,
|
||||
.div = 4,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div4",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor meson8b_fclk_div5 = {
|
||||
.mult = 1,
|
||||
.div = 5,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div5",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor meson8b_fclk_div7 = {
|
||||
.mult = 1,
|
||||
.div = 7,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fclk_div7",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_names = (const char *[]){ "fixed_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
|
||||
* post-dividers and should be modeled with their respective PLLs via the
|
||||
* forthcoming coordinated clock rates feature
|
||||
*/
|
||||
static struct meson_clk_cpu meson8b_cpu_clk = {
|
||||
.reg_off = MESON8B_REG_SYS_CPU_CNTL1,
|
||||
.div_table = cpu_div_table,
|
||||
.clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk",
|
||||
.ops = &meson_clk_cpu_ops,
|
||||
.parent_names = (const char *[]){ "sys_pll" },
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static u32 mux_table_clk81[] = { 6, 5, 7 };
|
||||
static u32 mux_table_mali[] = { 6, 5, 7, 4, 0 };
|
||||
|
||||
static struct pll_conf pll_confs = {
|
||||
.m = PARM(0x00, 0, 9),
|
||||
.n = PARM(0x00, 9, 5),
|
||||
.od = PARM(0x00, 16, 2),
|
||||
struct clk_mux meson8b_mpeg_clk_sel = {
|
||||
.reg = (void *)MESON8B_REG_HHI_MPEG,
|
||||
.mask = 0x7,
|
||||
.shift = 12,
|
||||
.flags = CLK_MUX_READ_ONLY,
|
||||
.table = mux_table_clk81,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpeg_clk_sel",
|
||||
.ops = &clk_mux_ro_ops,
|
||||
/*
|
||||
* FIXME bits 14:12 selects from 8 possible parents:
|
||||
* xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
|
||||
* fclk_div4, fclk_div3, fclk_div5
|
||||
*/
|
||||
.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
|
||||
"fclk_div5" },
|
||||
.num_parents = 3,
|
||||
.flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
|
||||
static struct pll_conf sys_pll_conf = {
|
||||
.m = PARM(0x00, 0, 9),
|
||||
.n = PARM(0x00, 9, 5),
|
||||
.od = PARM(0x00, 16, 2),
|
||||
.rate_table = sys_pll_rate_table,
|
||||
struct clk_divider meson8b_mpeg_clk_div = {
|
||||
.reg = (void *)MESON8B_REG_HHI_MPEG,
|
||||
.shift = 0,
|
||||
.width = 7,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpeg_clk_div",
|
||||
.ops = &clk_divider_ops,
|
||||
.parent_names = (const char *[]){ "mpeg_clk_sel" },
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct composite_conf clk81_conf __initconst = {
|
||||
.mux_table = mux_table_clk81,
|
||||
.mux_flags = CLK_MUX_READ_ONLY,
|
||||
.mux_parm = PARM(0x00, 12, 3),
|
||||
.div_parm = PARM(0x00, 0, 7),
|
||||
.gate_parm = PARM(0x00, 7, 1),
|
||||
struct clk_gate meson8b_clk81 = {
|
||||
.reg = (void *)MESON8B_REG_HHI_MPEG,
|
||||
.bit_idx = 7,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "clk81",
|
||||
.ops = &clk_gate_ops,
|
||||
.parent_names = (const char *[]){ "mpeg_clk_div" },
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct composite_conf mali_conf __initconst = {
|
||||
.mux_table = mux_table_mali,
|
||||
.mux_parm = PARM(0x00, 9, 3),
|
||||
.div_parm = PARM(0x00, 0, 7),
|
||||
.gate_parm = PARM(0x00, 8, 1),
|
||||
static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
|
||||
.hws = {
|
||||
[CLKID_XTAL] = &meson8b_xtal.hw,
|
||||
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
|
||||
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
|
||||
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
|
||||
[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
|
||||
[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
|
||||
[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
|
||||
[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
|
||||
[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
|
||||
[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
|
||||
[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
|
||||
[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
|
||||
[CLKID_CLK81] = &meson8b_clk81.hw,
|
||||
},
|
||||
.num = CLK_NR_CLKS,
|
||||
};
|
||||
|
||||
static const struct clk_conf meson8b_xtal_conf __initconst =
|
||||
FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 0,
|
||||
PARM(0x00, 4, 7));
|
||||
|
||||
static const struct clk_conf meson8b_clk_confs[] __initconst = {
|
||||
FIXED_RATE(CLKID_ZERO, "zero", 0, 0),
|
||||
PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll",
|
||||
p_xtal, 0, &pll_confs),
|
||||
PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
|
||||
p_xtal, 0, &pll_confs),
|
||||
PLL(MESON8B_REG_PLL_SYS, CLKID_PLL_SYS, "sys_pll",
|
||||
p_xtal, 0, &sys_pll_conf),
|
||||
FIXED_FACTOR_DIV(CLKID_FCLK_DIV2, "fclk_div2", p_fclk_div, 0, 2),
|
||||
FIXED_FACTOR_DIV(CLKID_FCLK_DIV3, "fclk_div3", p_fclk_div, 0, 3),
|
||||
FIXED_FACTOR_DIV(CLKID_FCLK_DIV4, "fclk_div4", p_fclk_div, 0, 4),
|
||||
FIXED_FACTOR_DIV(CLKID_FCLK_DIV5, "fclk_div5", p_fclk_div, 0, 5),
|
||||
FIXED_FACTOR_DIV(CLKID_FCLK_DIV7, "fclk_div7", p_fclk_div, 0, 7),
|
||||
CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
|
||||
cpu_div_table),
|
||||
COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
|
||||
CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
|
||||
COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
|
||||
CLK_IGNORE_UNUSED, &mali_conf),
|
||||
static struct meson_clk_pll *const meson8b_clk_plls[] = {
|
||||
&meson8b_fixed_pll,
|
||||
&meson8b_vid_pll,
|
||||
&meson8b_sys_pll,
|
||||
};
|
||||
|
||||
static void __init meson8b_clkc_init(struct device_node *np)
|
||||
static int meson8b_clkc_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *clk_base;
|
||||
|
||||
if (!meson_clk_init(np, CLK_NR_CLKS))
|
||||
return;
|
||||
|
||||
/* XTAL */
|
||||
clk_base = of_iomap(np, 0);
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map xtal base\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base);
|
||||
iounmap(clk_base);
|
||||
int ret, clkid, i;
|
||||
struct clk_hw *parent_hw;
|
||||
struct clk *parent_clk;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
/* Generic clocks and PLLs */
|
||||
clk_base = of_iomap(np, 1);
|
||||
clk_base = of_iomap(dev->of_node, 1);
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map clk base\n", __func__);
|
||||
return;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
meson_clk_register_clks(meson8b_clk_confs,
|
||||
ARRAY_SIZE(meson8b_clk_confs),
|
||||
clk_base);
|
||||
/* Populate base address for PLLs */
|
||||
for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
|
||||
meson8b_clk_plls[i]->base = clk_base;
|
||||
|
||||
/* Populate the base address for CPU clk */
|
||||
meson8b_cpu_clk.base = clk_base;
|
||||
|
||||
/* Populate the base address for the MPEG clks */
|
||||
meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
|
||||
meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
|
||||
meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
|
||||
|
||||
/*
|
||||
* register all clks
|
||||
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
|
||||
*/
|
||||
for (clkid = CLKID_XTAL; clkid < CLK_NR_CLKS; clkid++) {
|
||||
/* array might be sparse */
|
||||
if (!meson8b_hw_onecell_data.hws[clkid])
|
||||
continue;
|
||||
|
||||
/* FIXME convert to devm_clk_register */
|
||||
ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]);
|
||||
if (ret)
|
||||
goto iounmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register CPU clk notifier
|
||||
*
|
||||
* FIXME this is wrong for a lot of reasons. First, the muxes should be
|
||||
* struct clk_hw objects. Second, we shouldn't program the muxes in
|
||||
* notifier handlers. The tricky programming sequence will be handled
|
||||
* by the forthcoming coordinated clock rates mechanism once that
|
||||
* feature is released.
|
||||
*
|
||||
* Furthermore, looking up the parent this way is terrible. At some
|
||||
* point we will stop allocating a default struct clk when registering
|
||||
* a new clk_hw, and this hack will no longer work. Releasing the ccr
|
||||
* feature before that time solves the problem :-)
|
||||
*/
|
||||
parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
|
||||
parent_clk = parent_hw->clk;
|
||||
ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to register clock notifier for cpu_clk\n",
|
||||
__func__);
|
||||
goto iounmap;
|
||||
}
|
||||
|
||||
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
|
||||
&meson8b_hw_onecell_data);
|
||||
|
||||
iounmap:
|
||||
iounmap(clk_base);
|
||||
return ret;
|
||||
}
|
||||
CLK_OF_DECLARE(meson8b_clock, "amlogic,meson8b-clkc", meson8b_clkc_init);
|
||||
|
||||
static const struct of_device_id meson8b_clkc_match_table[] = {
|
||||
{ .compatible = "amlogic,meson8b-clkc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver meson8b_driver = {
|
||||
.probe = meson8b_clkc_probe,
|
||||
.driver = {
|
||||
.name = "meson8b-clkc",
|
||||
.of_match_table = meson8b_clkc_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init meson8b_clkc_init(void)
|
||||
{
|
||||
return platform_driver_register(&meson8b_driver);
|
||||
}
|
||||
device_initcall(meson8b_clkc_init);
|
||||
|
@ -87,7 +87,7 @@ enum {
|
||||
|
||||
enum {
|
||||
/* Start from the last defined clock in dt bindings */
|
||||
LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_HCLK_PLL + 1,
|
||||
LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_PERIPH + 1,
|
||||
LPC32XX_CLK_ADC_RTC,
|
||||
LPC32XX_CLK_TEST1,
|
||||
LPC32XX_CLK_TEST2,
|
||||
@ -99,7 +99,6 @@ enum {
|
||||
LPC32XX_CLK_HCLK_DIV_PERIPH,
|
||||
LPC32XX_CLK_HCLK_DIV,
|
||||
LPC32XX_CLK_HCLK,
|
||||
LPC32XX_CLK_PERIPH,
|
||||
LPC32XX_CLK_ARM,
|
||||
LPC32XX_CLK_ARM_VFP,
|
||||
|
||||
|
@ -2290,6 +2290,32 @@ static struct clk_branch sdc5_h_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch ebi2_2x_clk = {
|
||||
.halt_reg = 0x2fcc,
|
||||
.halt_bit = 18,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2660,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ebi2_2x_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch ebi2_clk = {
|
||||
.halt_reg = 0x2fcc,
|
||||
.halt_bit = 19,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2664,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ebi2_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch adm0_clk = {
|
||||
.halt_reg = 0x2fdc,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
@ -2533,6 +2559,8 @@ static struct clk_regmap *gcc_msm8660_clks[] = {
|
||||
[SDC3_H_CLK] = &sdc3_h_clk.clkr,
|
||||
[SDC4_H_CLK] = &sdc4_h_clk.clkr,
|
||||
[SDC5_H_CLK] = &sdc5_h_clk.clkr,
|
||||
[EBI2_2X_CLK] = &ebi2_2x_clk.clkr,
|
||||
[EBI2_CLK] = &ebi2_clk.clkr,
|
||||
[ADM0_CLK] = &adm0_clk.clkr,
|
||||
[ADM0_PBUS_CLK] = &adm0_pbus_clk.clkr,
|
||||
[ADM1_CLK] = &adm1_clk.clkr,
|
||||
|
@ -2891,21 +2891,6 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_aggre1_pnoc_ahb_clk = {
|
||||
.halt_reg = 0x82014,
|
||||
.clkr = {
|
||||
.enable_reg = 0x82014,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_aggre1_pnoc_ahb_clk",
|
||||
.parent_names = (const char *[]){ "periph_noc_clk_src" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_aggre2_ufs_axi_clk = {
|
||||
.halt_reg = 0x83014,
|
||||
.clkr = {
|
||||
@ -3308,7 +3293,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
|
||||
[GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr,
|
||||
[GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr,
|
||||
[GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr,
|
||||
[GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr,
|
||||
[GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr,
|
||||
[GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr,
|
||||
[GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr,
|
||||
|
@ -1,6 +1,7 @@
|
||||
config CLK_RENESAS_CPG_MSSR
|
||||
bool
|
||||
default y if ARCH_R8A7795
|
||||
default y if ARCH_R8A7796
|
||||
|
||||
config CLK_RENESAS_CPG_MSTP
|
||||
bool
|
||||
@ -11,6 +12,7 @@ config CLK_RENESAS_CPG_MSTP
|
||||
default y if ARCH_R8A7779
|
||||
default y if ARCH_R8A7790
|
||||
default y if ARCH_R8A7791
|
||||
default y if ARCH_R8A7792
|
||||
default y if ARCH_R8A7793
|
||||
default y if ARCH_R8A7794
|
||||
default y if ARCH_SH73A0
|
||||
|
@ -6,9 +6,11 @@ obj-$(CONFIG_ARCH_R8A7778) += clk-r8a7778.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += clk-r8a7779.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7792) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7793) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7794) += clk-rcar-gen2.o clk-div6.o
|
||||
obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o
|
||||
obj-$(CONFIG_ARCH_R8A7795) += r8a7795-cpg-mssr.o rcar-gen3-cpg.o
|
||||
obj-$(CONFIG_ARCH_R8A7796) += r8a7796-cpg-mssr.o rcar-gen3-cpg.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += clk-sh73a0.o clk-div6.o
|
||||
|
||||
obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o clk-div6.o
|
||||
|
@ -12,22 +12,14 @@
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
|
||||
#define CPG_RCKCR 0x240
|
||||
#include "rcar-gen3-cpg.h"
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
@ -58,20 +50,6 @@ enum clk_ids {
|
||||
MOD_CLK_BASE
|
||||
};
|
||||
|
||||
enum r8a7795_clk_types {
|
||||
CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM,
|
||||
CLK_TYPE_GEN3_PLL0,
|
||||
CLK_TYPE_GEN3_PLL1,
|
||||
CLK_TYPE_GEN3_PLL2,
|
||||
CLK_TYPE_GEN3_PLL3,
|
||||
CLK_TYPE_GEN3_PLL4,
|
||||
CLK_TYPE_GEN3_SD,
|
||||
CLK_TYPE_GEN3_R,
|
||||
};
|
||||
|
||||
#define DEF_GEN3_SD(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
|
||||
|
||||
static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
@ -129,6 +107,9 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("fdp1-2", 117, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fdp1-1", 118, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fdp1-0", 119, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("scif5", 202, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scif4", 203, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("scif3", 204, R8A7795_CLK_S3D4),
|
||||
@ -157,11 +138,20 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("drif7", 508, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif6", 509, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif5", 510, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif4", 511, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif3", 512, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif2", 513, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif1", 514, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("drif0", 515, R8A7795_CLK_S3D2),
|
||||
DEF_MOD("hscif4", 516, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif3", 517, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1),
|
||||
DEF_MOD("thermal", 522, R8A7795_CLK_CP),
|
||||
DEF_MOD("pwm", 523, R8A7795_CLK_S3D4),
|
||||
DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1),
|
||||
@ -199,7 +189,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
|
||||
DEF_MOD("du2", 722, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du1", 723, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("du0", 724, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("lvds", 727, R8A7795_CLK_S2D1),
|
||||
DEF_MOD("lvds", 727, R8A7795_CLK_S0D4),
|
||||
DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI),
|
||||
DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI),
|
||||
DEF_MOD("vin7", 804, R8A7795_CLK_S2D1),
|
||||
@ -262,225 +252,6 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = {
|
||||
MOD_CLK_ID(408), /* INTC-AP (GIC) */
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SDn Clock
|
||||
*
|
||||
*/
|
||||
#define CPG_SD_STP_HCK BIT(9)
|
||||
#define CPG_SD_STP_CK BIT(8)
|
||||
|
||||
#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
|
||||
#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
|
||||
|
||||
#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
|
||||
{ \
|
||||
.val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
|
||||
((stp_ck) ? CPG_SD_STP_CK : 0) | \
|
||||
((sd_srcfc) << 2) | \
|
||||
((sd_fc) << 0), \
|
||||
.div = (sd_div), \
|
||||
}
|
||||
|
||||
struct sd_div_table {
|
||||
u32 val;
|
||||
unsigned int div;
|
||||
};
|
||||
|
||||
struct sd_clock {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
const struct sd_div_table *div_table;
|
||||
unsigned int div_num;
|
||||
unsigned int div_min;
|
||||
unsigned int div_max;
|
||||
};
|
||||
|
||||
/* SDn divider
|
||||
* sd_srcfc sd_fc div
|
||||
* stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc
|
||||
*-------------------------------------------------------------------
|
||||
* 0 0 0 (1) 1 (4) 4
|
||||
* 0 0 1 (2) 1 (4) 8
|
||||
* 1 0 2 (4) 1 (4) 16
|
||||
* 1 0 3 (8) 1 (4) 32
|
||||
* 1 0 4 (16) 1 (4) 64
|
||||
* 0 0 0 (1) 0 (2) 2
|
||||
* 0 0 1 (2) 0 (2) 4
|
||||
* 1 0 2 (4) 0 (2) 8
|
||||
* 1 0 3 (8) 0 (2) 16
|
||||
* 1 0 4 (16) 0 (2) 32
|
||||
*/
|
||||
static const struct sd_div_table cpg_sd_div_table[] = {
|
||||
/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32),
|
||||
};
|
||||
|
||||
#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw)
|
||||
|
||||
static int cpg_sd_clock_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
u32 val, sd_fc;
|
||||
unsigned int i;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
|
||||
sd_fc = val & CPG_SD_FC_MASK;
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
val &= ~(CPG_SD_STP_MASK);
|
||||
val |= clock->div_table[i].val & CPG_SD_STP_MASK;
|
||||
|
||||
clk_writel(val, clock->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpg_sd_clock_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
return !(clk_readl(clock->reg) & CPG_SD_STP_MASK);
|
||||
}
|
||||
|
||||
static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned long rate = parent_rate;
|
||||
u32 val, sd_fc;
|
||||
unsigned int i;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
|
||||
sd_fc = val & CPG_SD_FC_MASK;
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div);
|
||||
}
|
||||
|
||||
static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
unsigned int div;
|
||||
|
||||
if (!rate)
|
||||
rate = 1;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
|
||||
return clamp_t(unsigned int, div, clock->div_min, clock->div_max);
|
||||
}
|
||||
|
||||
static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate);
|
||||
|
||||
return DIV_ROUND_CLOSEST(*parent_rate, div);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
|
||||
u32 val;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (div == clock->div_table[i].div)
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
|
||||
val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
|
||||
clk_writel(val, clock->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops cpg_sd_clock_ops = {
|
||||
.enable = cpg_sd_clock_enable,
|
||||
.disable = cpg_sd_clock_disable,
|
||||
.is_enabled = cpg_sd_clock_is_enabled,
|
||||
.recalc_rate = cpg_sd_clock_recalc_rate,
|
||||
.round_rate = cpg_sd_clock_round_rate,
|
||||
.set_rate = cpg_sd_clock_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
|
||||
void __iomem *base,
|
||||
const char *parent_name)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct sd_clock *clock;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = core->name;
|
||||
init.ops = &cpg_sd_clock_ops;
|
||||
init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
clock->reg = base + core->offset;
|
||||
clock->hw.init = &init;
|
||||
clock->div_table = cpg_sd_div_table;
|
||||
clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
|
||||
|
||||
clock->div_max = clock->div_table[0].div;
|
||||
clock->div_min = clock->div_max;
|
||||
for (i = 1; i < clock->div_num; i++) {
|
||||
clock->div_max = max(clock->div_max, clock->div_table[i].div);
|
||||
clock->div_min = min(clock->div_min, clock->div_table[i].div);
|
||||
}
|
||||
|
||||
clk = clk_register(NULL, &clock->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(clock);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
#define CPG_PLL0CR 0x00d8
|
||||
#define CPG_PLL2CR 0x002c
|
||||
#define CPG_PLL4CR 0x01f4
|
||||
|
||||
/*
|
||||
* CPG Clock Data
|
||||
@ -512,13 +283,7 @@ static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
|
||||
(((md) & BIT(19)) >> 18) | \
|
||||
(((md) & BIT(17)) >> 17))
|
||||
|
||||
struct cpg_pll_config {
|
||||
unsigned int extal_div;
|
||||
unsigned int pll1_mult;
|
||||
unsigned int pll3_mult;
|
||||
};
|
||||
|
||||
static const struct cpg_pll_config cpg_pll_configs[16] __initconst = {
|
||||
static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
|
||||
/* EXTAL div PLL1 mult PLL3 mult */
|
||||
{ 1, 192, 192, },
|
||||
{ 1, 192, 128, },
|
||||
@ -538,112 +303,9 @@ static const struct cpg_pll_config cpg_pll_configs[16] __initconst = {
|
||||
{ 2, 192, 192, },
|
||||
};
|
||||
|
||||
static const struct cpg_pll_config *cpg_pll_config __initdata;
|
||||
|
||||
static
|
||||
struct clk * __init r8a7795_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core,
|
||||
const struct cpg_mssr_info *info,
|
||||
struct clk **clks,
|
||||
void __iomem *base)
|
||||
{
|
||||
const struct clk *parent;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
u32 value;
|
||||
|
||||
parent = clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
switch (core->type) {
|
||||
case CLK_TYPE_GEN3_MAIN:
|
||||
div = cpg_pll_config->extal_div;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL0:
|
||||
/*
|
||||
* PLL0 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL0CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL1:
|
||||
mult = cpg_pll_config->pll1_mult;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL2:
|
||||
/*
|
||||
* PLL2 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL2CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL3:
|
||||
mult = cpg_pll_config->pll3_mult;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL4:
|
||||
/*
|
||||
* PLL4 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL4CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_SD:
|
||||
return cpg_sd_clk_register(core, base, __clk_get_name(parent));
|
||||
|
||||
case CLK_TYPE_GEN3_R:
|
||||
/* RINT is default. Only if EXTALR is populated, we switch to it */
|
||||
value = readl(base + CPG_RCKCR) & 0x3f;
|
||||
|
||||
if (clk_get_rate(clks[CLK_EXTALR])) {
|
||||
parent = clks[CLK_EXTALR];
|
||||
value |= BIT(15);
|
||||
}
|
||||
|
||||
writel(value, base + CPG_RCKCR);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return clk_register_fixed_factor(NULL, core->name,
|
||||
__clk_get_name(parent), 0, mult, div);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset register definitions.
|
||||
*/
|
||||
#define MODEMR 0xe6160060
|
||||
|
||||
static u32 rcar_gen3_read_mode_pins(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, 4);
|
||||
u32 mode;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static int __init r8a7795_cpg_mssr_init(struct device *dev)
|
||||
{
|
||||
const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
|
||||
u32 cpg_mode = rcar_gen3_read_mode_pins();
|
||||
|
||||
cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
|
||||
@ -652,7 +314,7 @@ static int __init r8a7795_cpg_mssr_init(struct device *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR);
|
||||
}
|
||||
|
||||
const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = {
|
||||
@ -673,5 +335,5 @@ const struct cpg_mssr_info r8a7795_cpg_mssr_info __initconst = {
|
||||
|
||||
/* Callbacks */
|
||||
.init = r8a7795_cpg_mssr_init,
|
||||
.cpg_clk_register = r8a7795_cpg_clk_register,
|
||||
.cpg_clk_register = rcar_gen3_cpg_clk_register,
|
||||
};
|
||||
|
192
drivers/clk/renesas/r8a7796-cpg-mssr.c
Normal file
192
drivers/clk/renesas/r8a7796-cpg-mssr.c
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* r8a7796 Clock Pulse Generator / Module Standby and Software Reset
|
||||
*
|
||||
* Copyright (C) 2016 Glider bvba
|
||||
*
|
||||
* Based on r8a7795-cpg-mssr.c
|
||||
*
|
||||
* Copyright (C) 2015 Glider bvba
|
||||
* Copyright (C) 2015 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <dt-bindings/clock/r8a7796-cpg-mssr.h>
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
#include "rcar-gen3-cpg.h"
|
||||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R8A7796_CLK_OSC,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_EXTAL,
|
||||
CLK_EXTALR,
|
||||
|
||||
/* Internal Core Clocks */
|
||||
CLK_MAIN,
|
||||
CLK_PLL0,
|
||||
CLK_PLL1,
|
||||
CLK_PLL2,
|
||||
CLK_PLL3,
|
||||
CLK_PLL4,
|
||||
CLK_PLL1_DIV2,
|
||||
CLK_PLL1_DIV4,
|
||||
CLK_S0,
|
||||
CLK_S1,
|
||||
CLK_S2,
|
||||
CLK_S3,
|
||||
CLK_SDSRC,
|
||||
CLK_SSPSRC,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE
|
||||
};
|
||||
|
||||
static const struct cpg_core_clk r8a7796_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
DEF_INPUT("extalr", CLK_EXTALR),
|
||||
|
||||
/* Internal Core Clocks */
|
||||
DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL),
|
||||
DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN),
|
||||
DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN),
|
||||
DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN),
|
||||
DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN),
|
||||
DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN),
|
||||
|
||||
DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
|
||||
DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1),
|
||||
DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
|
||||
DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
|
||||
|
||||
/* Core Clock Outputs */
|
||||
DEF_FIXED("ztr", R8A7796_CLK_ZTR, CLK_PLL1_DIV2, 6, 1),
|
||||
DEF_FIXED("ztrd2", R8A7796_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1),
|
||||
DEF_FIXED("zt", R8A7796_CLK_ZT, CLK_PLL1_DIV2, 4, 1),
|
||||
DEF_FIXED("zx", R8A7796_CLK_ZX, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_FIXED("s0d1", R8A7796_CLK_S0D1, CLK_S0, 1, 1),
|
||||
DEF_FIXED("s0d2", R8A7796_CLK_S0D2, CLK_S0, 2, 1),
|
||||
DEF_FIXED("s0d3", R8A7796_CLK_S0D3, CLK_S0, 3, 1),
|
||||
DEF_FIXED("s0d4", R8A7796_CLK_S0D4, CLK_S0, 4, 1),
|
||||
DEF_FIXED("s0d6", R8A7796_CLK_S0D6, CLK_S0, 6, 1),
|
||||
DEF_FIXED("s0d8", R8A7796_CLK_S0D8, CLK_S0, 8, 1),
|
||||
DEF_FIXED("s0d12", R8A7796_CLK_S0D12, CLK_S0, 12, 1),
|
||||
DEF_FIXED("s1d1", R8A7796_CLK_S1D1, CLK_S1, 1, 1),
|
||||
DEF_FIXED("s1d2", R8A7796_CLK_S1D2, CLK_S1, 2, 1),
|
||||
DEF_FIXED("s1d4", R8A7796_CLK_S1D4, CLK_S1, 4, 1),
|
||||
DEF_FIXED("s2d1", R8A7796_CLK_S2D1, CLK_S2, 1, 1),
|
||||
DEF_FIXED("s2d2", R8A7796_CLK_S2D2, CLK_S2, 2, 1),
|
||||
DEF_FIXED("s2d4", R8A7796_CLK_S2D4, CLK_S2, 4, 1),
|
||||
DEF_FIXED("s3d1", R8A7796_CLK_S3D1, CLK_S3, 1, 1),
|
||||
DEF_FIXED("s3d2", R8A7796_CLK_S3D2, CLK_S3, 2, 1),
|
||||
DEF_FIXED("s3d4", R8A7796_CLK_S3D4, CLK_S3, 4, 1),
|
||||
|
||||
DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1),
|
||||
DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1),
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a7796_mod_clks[] __initconst = {
|
||||
DEF_MOD("scif2", 310, R8A7796_CLK_S3D4),
|
||||
DEF_MOD("intc-ap", 408, R8A7796_CLK_S3D1),
|
||||
};
|
||||
|
||||
static const unsigned int r8a7796_crit_mod_clks[] __initconst = {
|
||||
MOD_CLK_ID(408), /* INTC-AP (GIC) */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* CPG Clock Data
|
||||
*/
|
||||
|
||||
/*
|
||||
* MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4
|
||||
* 14 13 19 17 (MHz)
|
||||
*-------------------------------------------------------------------
|
||||
* 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144
|
||||
* 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144
|
||||
* 0 0 1 0 Prohibited setting
|
||||
* 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144
|
||||
* 0 1 0 0 20 x 1 x150 x160 x120 x160 x120
|
||||
* 0 1 0 1 20 x 1 x150 x160 x120 x106 x120
|
||||
* 0 1 1 0 Prohibited setting
|
||||
* 0 1 1 1 20 x 1 x150 x160 x120 x160 x120
|
||||
* 1 0 0 0 25 x 1 x120 x128 x96 x128 x96
|
||||
* 1 0 0 1 25 x 1 x120 x128 x96 x84 x96
|
||||
* 1 0 1 0 Prohibited setting
|
||||
* 1 0 1 1 25 x 1 x120 x128 x96 x128 x96
|
||||
* 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144
|
||||
* 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144
|
||||
* 1 1 1 0 Prohibited setting
|
||||
* 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144
|
||||
*/
|
||||
#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \
|
||||
(((md) & BIT(13)) >> 11) | \
|
||||
(((md) & BIT(19)) >> 18) | \
|
||||
(((md) & BIT(17)) >> 17))
|
||||
|
||||
static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = {
|
||||
/* EXTAL div PLL1 mult PLL3 mult */
|
||||
{ 1, 192, 192, },
|
||||
{ 1, 192, 128, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 1, 192, 192, },
|
||||
{ 1, 160, 160, },
|
||||
{ 1, 160, 106, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 1, 160, 160, },
|
||||
{ 1, 128, 128, },
|
||||
{ 1, 128, 84, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 1, 128, 128, },
|
||||
{ 2, 192, 192, },
|
||||
{ 2, 192, 128, },
|
||||
{ 0, /* Prohibited setting */ },
|
||||
{ 2, 192, 192, },
|
||||
};
|
||||
|
||||
static int __init r8a7796_cpg_mssr_init(struct device *dev)
|
||||
{
|
||||
const struct rcar_gen3_cpg_pll_config *cpg_pll_config;
|
||||
u32 cpg_mode = rcar_gen3_read_mode_pins();
|
||||
|
||||
cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)];
|
||||
if (!cpg_pll_config->extal_div) {
|
||||
dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR);
|
||||
}
|
||||
|
||||
const struct cpg_mssr_info r8a7796_cpg_mssr_info __initconst = {
|
||||
/* Core Clocks */
|
||||
.core_clks = r8a7796_core_clks,
|
||||
.num_core_clks = ARRAY_SIZE(r8a7796_core_clks),
|
||||
.last_dt_core_clk = LAST_DT_CORE_CLK,
|
||||
.num_total_core_clks = MOD_CLK_BASE,
|
||||
|
||||
/* Module Clocks */
|
||||
.mod_clks = r8a7796_mod_clks,
|
||||
.num_mod_clks = ARRAY_SIZE(r8a7796_mod_clks),
|
||||
.num_hw_mod_clks = 12 * 32,
|
||||
|
||||
/* Critical Module Clocks */
|
||||
.crit_mod_clks = r8a7796_crit_mod_clks,
|
||||
.num_crit_mod_clks = ARRAY_SIZE(r8a7796_crit_mod_clks),
|
||||
|
||||
/* Callbacks */
|
||||
.init = r8a7796_cpg_mssr_init,
|
||||
.cpg_clk_register = rcar_gen3_cpg_clk_register,
|
||||
};
|
359
drivers/clk/renesas/rcar-gen3-cpg.c
Normal file
359
drivers/clk/renesas/rcar-gen3-cpg.c
Normal file
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* R-Car Gen3 Clock Pulse Generator
|
||||
*
|
||||
* Copyright (C) 2015-2016 Glider bvba
|
||||
*
|
||||
* Based on clk-rcar-gen3.c
|
||||
*
|
||||
* Copyright (C) 2015 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
#include "rcar-gen3-cpg.h"
|
||||
|
||||
#define CPG_PLL0CR 0x00d8
|
||||
#define CPG_PLL2CR 0x002c
|
||||
#define CPG_PLL4CR 0x01f4
|
||||
|
||||
|
||||
/*
|
||||
* SDn Clock
|
||||
*/
|
||||
#define CPG_SD_STP_HCK BIT(9)
|
||||
#define CPG_SD_STP_CK BIT(8)
|
||||
|
||||
#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
|
||||
#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
|
||||
|
||||
#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
|
||||
{ \
|
||||
.val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
|
||||
((stp_ck) ? CPG_SD_STP_CK : 0) | \
|
||||
((sd_srcfc) << 2) | \
|
||||
((sd_fc) << 0), \
|
||||
.div = (sd_div), \
|
||||
}
|
||||
|
||||
struct sd_div_table {
|
||||
u32 val;
|
||||
unsigned int div;
|
||||
};
|
||||
|
||||
struct sd_clock {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
const struct sd_div_table *div_table;
|
||||
unsigned int div_num;
|
||||
unsigned int div_min;
|
||||
unsigned int div_max;
|
||||
};
|
||||
|
||||
/* SDn divider
|
||||
* sd_srcfc sd_fc div
|
||||
* stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc
|
||||
*-------------------------------------------------------------------
|
||||
* 0 0 0 (1) 1 (4) 4
|
||||
* 0 0 1 (2) 1 (4) 8
|
||||
* 1 0 2 (4) 1 (4) 16
|
||||
* 1 0 3 (8) 1 (4) 32
|
||||
* 1 0 4 (16) 1 (4) 64
|
||||
* 0 0 0 (1) 0 (2) 2
|
||||
* 0 0 1 (2) 0 (2) 4
|
||||
* 1 0 2 (4) 0 (2) 8
|
||||
* 1 0 3 (8) 0 (2) 16
|
||||
* 1 0 4 (16) 0 (2) 32
|
||||
*/
|
||||
static const struct sd_div_table cpg_sd_div_table[] = {
|
||||
/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32),
|
||||
};
|
||||
|
||||
#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw)
|
||||
|
||||
static int cpg_sd_clock_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
u32 val, sd_fc;
|
||||
unsigned int i;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
|
||||
sd_fc = val & CPG_SD_FC_MASK;
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
val &= ~(CPG_SD_STP_MASK);
|
||||
val |= clock->div_table[i].val & CPG_SD_STP_MASK;
|
||||
|
||||
clk_writel(val, clock->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpg_sd_clock_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
|
||||
return !(clk_readl(clock->reg) & CPG_SD_STP_MASK);
|
||||
}
|
||||
|
||||
static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned long rate = parent_rate;
|
||||
u32 val, sd_fc;
|
||||
unsigned int i;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
|
||||
sd_fc = val & CPG_SD_FC_MASK;
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK))
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div);
|
||||
}
|
||||
|
||||
static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
unsigned int div;
|
||||
|
||||
if (!rate)
|
||||
rate = 1;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
|
||||
return clamp_t(unsigned int, div, clock->div_min, clock->div_max);
|
||||
}
|
||||
|
||||
static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate);
|
||||
|
||||
return DIV_ROUND_CLOSEST(*parent_rate, div);
|
||||
}
|
||||
|
||||
static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct sd_clock *clock = to_sd_clock(hw);
|
||||
unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate);
|
||||
u32 val;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < clock->div_num; i++)
|
||||
if (div == clock->div_table[i].div)
|
||||
break;
|
||||
|
||||
if (i >= clock->div_num)
|
||||
return -EINVAL;
|
||||
|
||||
val = clk_readl(clock->reg);
|
||||
val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK);
|
||||
val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK);
|
||||
clk_writel(val, clock->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops cpg_sd_clock_ops = {
|
||||
.enable = cpg_sd_clock_enable,
|
||||
.disable = cpg_sd_clock_disable,
|
||||
.is_enabled = cpg_sd_clock_is_enabled,
|
||||
.recalc_rate = cpg_sd_clock_recalc_rate,
|
||||
.round_rate = cpg_sd_clock_round_rate,
|
||||
.set_rate = cpg_sd_clock_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core,
|
||||
void __iomem *base,
|
||||
const char *parent_name)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct sd_clock *clock;
|
||||
struct clk *clk;
|
||||
unsigned int i;
|
||||
|
||||
clock = kzalloc(sizeof(*clock), GFP_KERNEL);
|
||||
if (!clock)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = core->name;
|
||||
init.ops = &cpg_sd_clock_ops;
|
||||
init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
clock->reg = base + core->offset;
|
||||
clock->hw.init = &init;
|
||||
clock->div_table = cpg_sd_div_table;
|
||||
clock->div_num = ARRAY_SIZE(cpg_sd_div_table);
|
||||
|
||||
clock->div_max = clock->div_table[0].div;
|
||||
clock->div_min = clock->div_max;
|
||||
for (i = 1; i < clock->div_num; i++) {
|
||||
clock->div_max = max(clock->div_max, clock->div_table[i].div);
|
||||
clock->div_min = min(clock->div_min, clock->div_table[i].div);
|
||||
}
|
||||
|
||||
clk = clk_register(NULL, &clock->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(clock);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
|
||||
static const struct rcar_gen3_cpg_pll_config *cpg_pll_config __initdata;
|
||||
static unsigned int cpg_clk_extalr __initdata;
|
||||
|
||||
struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base)
|
||||
{
|
||||
const struct clk *parent;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
u32 value;
|
||||
|
||||
parent = clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
switch (core->type) {
|
||||
case CLK_TYPE_GEN3_MAIN:
|
||||
div = cpg_pll_config->extal_div;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL0:
|
||||
/*
|
||||
* PLL0 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL0CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL1:
|
||||
mult = cpg_pll_config->pll1_mult;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL2:
|
||||
/*
|
||||
* PLL2 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL2CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL3:
|
||||
mult = cpg_pll_config->pll3_mult;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_PLL4:
|
||||
/*
|
||||
* PLL4 is a configurable multiplier clock. Register it as a
|
||||
* fixed factor clock for now as there's no generic multiplier
|
||||
* clock implementation and we currently have no need to change
|
||||
* the multiplier value.
|
||||
*/
|
||||
value = readl(base + CPG_PLL4CR);
|
||||
mult = (((value >> 24) & 0x7f) + 1) * 2;
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_SD:
|
||||
return cpg_sd_clk_register(core, base, __clk_get_name(parent));
|
||||
|
||||
case CLK_TYPE_GEN3_R:
|
||||
/*
|
||||
* RINT is default.
|
||||
* Only if EXTALR is populated, we switch to it.
|
||||
*/
|
||||
value = readl(base + CPG_RCKCR) & 0x3f;
|
||||
|
||||
if (clk_get_rate(clks[cpg_clk_extalr])) {
|
||||
parent = clks[cpg_clk_extalr];
|
||||
value |= BIT(15);
|
||||
}
|
||||
|
||||
writel(value, base + CPG_RCKCR);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return clk_register_fixed_factor(NULL, core->name,
|
||||
__clk_get_name(parent), 0, mult, div);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset register definitions.
|
||||
*/
|
||||
#define MODEMR 0xe6160060
|
||||
|
||||
u32 __init rcar_gen3_read_mode_pins(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, 4);
|
||||
u32 mode;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
int __init rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
|
||||
unsigned int clk_extalr)
|
||||
{
|
||||
cpg_pll_config = config;
|
||||
cpg_clk_extalr = clk_extalr;
|
||||
return 0;
|
||||
}
|
43
drivers/clk/renesas/rcar-gen3-cpg.h
Normal file
43
drivers/clk/renesas/rcar-gen3-cpg.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* R-Car Gen3 Clock Pulse Generator
|
||||
*
|
||||
* Copyright (C) 2015-2016 Glider bvba
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*/
|
||||
|
||||
#ifndef __CLK_RENESAS_RCAR_GEN3_CPG_H__
|
||||
#define __CLK_RENESAS_RCAR_GEN3_CPG_H__
|
||||
|
||||
enum rcar_gen3_clk_types {
|
||||
CLK_TYPE_GEN3_MAIN = CLK_TYPE_CUSTOM,
|
||||
CLK_TYPE_GEN3_PLL0,
|
||||
CLK_TYPE_GEN3_PLL1,
|
||||
CLK_TYPE_GEN3_PLL2,
|
||||
CLK_TYPE_GEN3_PLL3,
|
||||
CLK_TYPE_GEN3_PLL4,
|
||||
CLK_TYPE_GEN3_SD,
|
||||
CLK_TYPE_GEN3_R,
|
||||
};
|
||||
|
||||
#define DEF_GEN3_SD(_name, _id, _parent, _offset) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset)
|
||||
|
||||
struct rcar_gen3_cpg_pll_config {
|
||||
unsigned int extal_div;
|
||||
unsigned int pll1_mult;
|
||||
unsigned int pll3_mult;
|
||||
};
|
||||
|
||||
#define CPG_RCKCR 0x240
|
||||
|
||||
u32 rcar_gen3_read_mode_pins(void);
|
||||
struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base);
|
||||
int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
|
||||
unsigned int clk_extalr);
|
||||
|
||||
#endif
|
@ -508,6 +508,12 @@ static const struct of_device_id cpg_mssr_match[] = {
|
||||
.compatible = "renesas,r8a7795-cpg-mssr",
|
||||
.data = &r8a7795_cpg_mssr_info,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_R8A7796
|
||||
{
|
||||
.compatible = "renesas,r8a7796-cpg-mssr",
|
||||
.data = &r8a7796_cpg_mssr_info,
|
||||
},
|
||||
#endif
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
@ -131,4 +131,5 @@ struct cpg_mssr_info {
|
||||
};
|
||||
|
||||
extern const struct cpg_mssr_info r8a7795_cpg_mssr_info;
|
||||
extern const struct cpg_mssr_info r8a7796_cpg_mssr_info;
|
||||
#endif
|
||||
|
@ -151,8 +151,8 @@ PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" };
|
||||
PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" };
|
||||
PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" };
|
||||
|
||||
PNAME(mux_sclk_macphy_50m_p) = { "ext_gmac", "phy_50m_out" };
|
||||
PNAME(mux_sclk_gmac_pre_p) = { "sclk_gmac_src", "sclk_macphy_50m" };
|
||||
PNAME(mux_sclk_mac_extclk_p) = { "ext_gmac", "phy_50m_out" };
|
||||
PNAME(mux_sclk_gmac_pre_p) = { "sclk_gmac_src", "sclk_mac_extclk" };
|
||||
PNAME(mux_sclk_macphy_p) = { "sclk_gmac_src", "ext_gmac" };
|
||||
|
||||
static struct rockchip_pll_clock rk3228_pll_clks[] __initdata = {
|
||||
@ -170,6 +170,34 @@ static struct rockchip_pll_clock rk3228_pll_clks[] __initdata = {
|
||||
#define DFLAGS CLK_DIVIDER_HIWORD_MASK
|
||||
#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
|
||||
|
||||
static struct rockchip_clk_branch rk3228_i2s0_fracmux __initdata =
|
||||
MUX(0, "i2s0_pre", mux_i2s0_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(9), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_i2s1_fracmux __initdata =
|
||||
MUX(0, "i2s1_pre", mux_i2s1_pre_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(3), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_i2s2_fracmux __initdata =
|
||||
MUX(0, "i2s2_pre", mux_i2s2_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_spdif_fracmux __initdata =
|
||||
MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(6), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_uart0_fracmux __initdata =
|
||||
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(13), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_uart1_fracmux __initdata =
|
||||
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(14), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_uart2_fracmux __initdata =
|
||||
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(15), 8, 2, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
/*
|
||||
* Clock-Architecture Diagram 1
|
||||
@ -335,7 +363,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
RK2928_CLKGATE_CON(2), 6, GFLAGS),
|
||||
|
||||
GATE(0, "sclk_hsadc", "ext_hsadc", 0,
|
||||
RK3288_CLKGATE_CON(10), 12, GFLAGS),
|
||||
RK2928_CLKGATE_CON(10), 12, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_wifi", mux_pll_src_cpll_gpll_usb480m_p, 0,
|
||||
RK2928_CLKSEL_CON(23), 5, 2, MFLAGS, 0, 6, DFLAGS,
|
||||
@ -379,22 +407,21 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(9), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 3, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(8), 0,
|
||||
RK3288_CLKGATE_CON(0), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S0, "sclk_i2s0", mux_i2s0_p, 0,
|
||||
RK2928_CLKSEL_CON(9), 8, 2, MFLAGS,
|
||||
COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(8), 0,
|
||||
RK2928_CLKGATE_CON(0), 4, GFLAGS,
|
||||
&rk3228_i2s0_fracmux),
|
||||
GATE(SCLK_I2S0, "sclk_i2s0", "i2s0_pre", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKGATE_CON(0), 5, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "i2s1_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 10, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(7), 0,
|
||||
RK3288_CLKGATE_CON(0), 11, GFLAGS),
|
||||
MUX(0, "i2s1_pre", mux_i2s1_pre_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
|
||||
GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", 0,
|
||||
COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(7), 0,
|
||||
RK2928_CLKGATE_CON(0), 11, GFLAGS,
|
||||
&rk3228_i2s1_fracmux),
|
||||
GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKGATE_CON(0), 14, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_out", mux_i2s_out_p, 0,
|
||||
RK2928_CLKSEL_CON(3), 12, 1, MFLAGS,
|
||||
@ -403,21 +430,20 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
COMPOSITE(0, "i2s2_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(16), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(0), 7, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(30), 0,
|
||||
RK3288_CLKGATE_CON(0), 8, GFLAGS),
|
||||
COMPOSITE_NODIV(SCLK_I2S2, "sclk_i2s2", mux_i2s2_p, 0,
|
||||
RK2928_CLKSEL_CON(16), 8, 2, MFLAGS,
|
||||
COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(30), 0,
|
||||
RK2928_CLKGATE_CON(0), 8, GFLAGS,
|
||||
&rk3228_i2s2_fracmux),
|
||||
GATE(SCLK_I2S2, "sclk_i2s2", "i2s2_pre", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKGATE_CON(0), 9, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_spdif_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(6), 15, 1, MFLAGS, 0, 7, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 10, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "spdif_frac", "sclk_spdif_src", CLK_SET_RATE_PARENT,
|
||||
RK3288_CLKSEL_CON(20), 0,
|
||||
RK3288_CLKGATE_CON(2), 12, GFLAGS),
|
||||
MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
|
||||
RK2928_CLKSEL_CON(6), 8, 2, MFLAGS),
|
||||
COMPOSITE_FRACMUX(0, "spdif_frac", "sclk_spdif_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(20), 0,
|
||||
RK2928_CLKGATE_CON(2), 12, GFLAGS,
|
||||
&rk3228_spdif_fracmux),
|
||||
|
||||
GATE(0, "jtag", "ext_jtag", 0,
|
||||
RK2928_CLKGATE_CON(1), 3, GFLAGS),
|
||||
@ -456,45 +482,42 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
COMPOSITE(0, "uart2_src", mux_pll_src_cpll_gpll_usb480m_p,
|
||||
0, RK2928_CLKSEL_CON(15), 12, 2,
|
||||
MFLAGS, 0, 7, DFLAGS, RK2928_CLKGATE_CON(1), 12, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
|
||||
COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(17), 0,
|
||||
RK2928_CLKGATE_CON(1), 9, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKGATE_CON(1), 9, GFLAGS,
|
||||
&rk3228_uart0_fracmux),
|
||||
COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(18), 0,
|
||||
RK2928_CLKGATE_CON(1), 11, GFLAGS),
|
||||
COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKGATE_CON(1), 11, GFLAGS,
|
||||
&rk3228_uart1_fracmux),
|
||||
COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(19), 0,
|
||||
RK2928_CLKGATE_CON(1), 13, GFLAGS),
|
||||
MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
|
||||
MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
|
||||
MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
|
||||
RK2928_CLKGATE_CON(1), 13, GFLAGS,
|
||||
&rk3228_uart2_fracmux),
|
||||
|
||||
COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(2), 14, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 0, GFLAGS),
|
||||
|
||||
COMPOSITE(0, "sclk_gmac_src", mux_pll_src_2plls_p, 0,
|
||||
COMPOSITE(SCLK_MAC_SRC, "sclk_gmac_src", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 7, 1, MFLAGS, 0, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(1), 7, GFLAGS),
|
||||
MUX(0, "sclk_macphy_50m", mux_sclk_macphy_50m_p, 0,
|
||||
MUX(SCLK_MAC_EXTCLK, "sclk_mac_extclk", mux_sclk_mac_extclk_p, 0,
|
||||
RK2928_CLKSEL_CON(29), 10, 1, MFLAGS),
|
||||
MUX(0, "sclk_gmac_pre", mux_sclk_gmac_pre_p, 0,
|
||||
MUX(SCLK_MAC, "sclk_gmac_pre", mux_sclk_gmac_pre_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 5, 1, MFLAGS),
|
||||
GATE(0, "sclk_mac_refout", "sclk_gmac_pre", 0,
|
||||
GATE(SCLK_MAC_REFOUT, "sclk_mac_refout", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 4, GFLAGS),
|
||||
GATE(0, "sclk_mac_ref", "sclk_gmac_pre", 0,
|
||||
GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 3, GFLAGS),
|
||||
GATE(0, "sclk_mac_rx", "sclk_gmac_pre", 0,
|
||||
GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 5, GFLAGS),
|
||||
GATE(0, "sclk_mac_tx", "sclk_gmac_pre", 0,
|
||||
GATE(SCLK_MAC_TX, "sclk_mac_tx", "sclk_gmac_pre", 0,
|
||||
RK2928_CLKGATE_CON(5), 6, GFLAGS),
|
||||
COMPOSITE(0, "sclk_macphy", mux_sclk_macphy_p, 0,
|
||||
COMPOSITE(SCLK_MAC_PHY, "sclk_macphy", mux_sclk_macphy_p, 0,
|
||||
RK2928_CLKSEL_CON(29), 12, 1, MFLAGS, 8, 2, DFLAGS,
|
||||
RK2928_CLKGATE_CON(5), 7, GFLAGS),
|
||||
COMPOSITE(0, "sclk_gmac_out", mux_pll_src_2plls_p, 0,
|
||||
COMPOSITE(SCLK_MAC_OUT, "sclk_gmac_out", mux_pll_src_2plls_p, 0,
|
||||
RK2928_CLKSEL_CON(5), 15, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK2928_CLKGATE_CON(2), 2, GFLAGS),
|
||||
|
||||
@ -528,7 +551,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
|
||||
/* PD_PERI */
|
||||
GATE(0, "aclk_peri_noc", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 0, GFLAGS),
|
||||
GATE(0, "aclk_gmac", "aclk_peri", 0, RK2928_CLKGATE_CON(11), 4, GFLAGS),
|
||||
GATE(ACLK_GMAC, "aclk_gmac", "aclk_peri", 0, RK2928_CLKGATE_CON(11), 4, GFLAGS),
|
||||
|
||||
GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 0, GFLAGS),
|
||||
GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 1, GFLAGS),
|
||||
@ -544,7 +567,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
GATE(0, "hclk_host2_arb", "hclk_peri", 0, RK2928_CLKGATE_CON(11), 14, GFLAGS),
|
||||
GATE(0, "hclk_peri_noc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 1, GFLAGS),
|
||||
|
||||
GATE(0, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(11), 5, GFLAGS),
|
||||
GATE(PCLK_GMAC, "pclk_gmac", "pclk_peri", 0, RK2928_CLKGATE_CON(11), 5, GFLAGS),
|
||||
GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS),
|
||||
|
||||
/* PD_GPU */
|
||||
@ -558,10 +581,10 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
|
||||
GATE(0, "aclk_bus_noc", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS),
|
||||
|
||||
GATE(0, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 3, GFLAGS),
|
||||
GATE(0, "hclk_i2s0_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS),
|
||||
GATE(0, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS),
|
||||
GATE(0, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
|
||||
GATE(0, "hclk_spdif_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
|
||||
GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 7, GFLAGS),
|
||||
GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 8, GFLAGS),
|
||||
GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
|
||||
GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
|
||||
GATE(0, "hclk_tsp", "hclk_cpu", 0, RK2928_CLKGATE_CON(10), 11, GFLAGS),
|
||||
GATE(0, "hclk_crypto_mst", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
|
||||
GATE(0, "hclk_crypto_slv", "hclk_cpu", 0, RK2928_CLKGATE_CON(8), 12, GFLAGS),
|
||||
|
@ -586,7 +586,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
|
||||
RK3399_CLKGATE_CON(8), 15, GFLAGS),
|
||||
|
||||
COMPOSITE(SCLK_SPDIF_REC_DPTX, "clk_spdif_rec_dptx", mux_pll_src_cpll_gpll_p, 0,
|
||||
RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3399_CLKGATE_CON(10), 6, GFLAGS),
|
||||
/* i2s */
|
||||
COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
|
||||
@ -1500,6 +1500,7 @@ static void __init rk3399_clk_init(struct device_node *np)
|
||||
{
|
||||
struct rockchip_clk_provider *ctx;
|
||||
void __iomem *reg_base;
|
||||
struct clk *clk;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
@ -1514,6 +1515,14 @@ static void __init rk3399_clk_init(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Watchdog pclk is controlled by RK3399 SECURE_GRF_SOC_CON3[8]. */
|
||||
clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_alive", 0, 1, 1);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock pclk_wdt: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
else
|
||||
rockchip_clk_add_lookup(ctx, clk, PCLK_WDT);
|
||||
|
||||
rockchip_clk_register_plls(ctx, rk3399_pll_clks,
|
||||
ARRAY_SIZE(rk3399_pll_clks), -1);
|
||||
|
||||
|
@ -9,6 +9,15 @@ config EXYNOS_ARM64_COMMON_CLK
|
||||
bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
|
||||
config EXYNOS_AUDSS_CLK_CON
|
||||
tristate "Samsung Exynos AUDSS clock controller support"
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
default y if ARCH_EXYNOS
|
||||
help
|
||||
Support for the Audio Subsystem CLKCON clock controller present
|
||||
on some Exynos SoC variants. Choose M or Y here if you want to
|
||||
use audio devices such as I2S, PCM, etc.
|
||||
|
||||
# For S3C24XX platforms, select following symbols:
|
||||
config S3C2410_COMMON_CLK
|
||||
bool "Samsung S3C2410 clock controller support" if COMPILE_TEST
|
||||
|
@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
|
||||
obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o
|
||||
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
|
||||
|
@ -45,6 +45,13 @@
|
||||
#define E4210_DIV_STAT_CPU0 0x400
|
||||
#define E4210_DIV_STAT_CPU1 0x404
|
||||
|
||||
#define E5433_MUX_SEL2 0x008
|
||||
#define E5433_MUX_STAT2 0x208
|
||||
#define E5433_DIV_CPU0 0x400
|
||||
#define E5433_DIV_CPU1 0x404
|
||||
#define E5433_DIV_STAT_CPU0 0x500
|
||||
#define E5433_DIV_STAT_CPU1 0x504
|
||||
|
||||
#define E4210_DIV0_RATIO0_MASK 0x7
|
||||
#define E4210_DIV1_HPM_MASK (0x7 << 4)
|
||||
#define E4210_DIV1_COPY_MASK (0x7 << 0)
|
||||
@ -252,6 +259,102 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to set the 'safe' dividers for the CPU clock. The parameters
|
||||
* div and mask contain the divider value and the register bit mask of the
|
||||
* dividers to be programmed.
|
||||
*/
|
||||
static void exynos5433_set_safe_div(void __iomem *base, unsigned long div,
|
||||
unsigned long mask)
|
||||
{
|
||||
unsigned long div0;
|
||||
|
||||
div0 = readl(base + E5433_DIV_CPU0);
|
||||
div0 = (div0 & ~mask) | (div & mask);
|
||||
writel(div0, base + E5433_DIV_CPU0);
|
||||
wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, mask);
|
||||
}
|
||||
|
||||
/* handler for pre-rate change notification from parent clock */
|
||||
static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
|
||||
struct exynos_cpuclk *cpuclk, void __iomem *base)
|
||||
{
|
||||
const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
|
||||
unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
|
||||
unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
|
||||
unsigned long div0, div1 = 0, mux_reg;
|
||||
unsigned long flags;
|
||||
|
||||
/* find out the divider values to use for clock data */
|
||||
while ((cfg_data->prate * 1000) != ndata->new_rate) {
|
||||
if (cfg_data->prate == 0)
|
||||
return -EINVAL;
|
||||
cfg_data++;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(cpuclk->lock, flags);
|
||||
|
||||
/*
|
||||
* For the selected PLL clock frequency, get the pre-defined divider
|
||||
* values.
|
||||
*/
|
||||
div0 = cfg_data->div0;
|
||||
div1 = cfg_data->div1;
|
||||
|
||||
/*
|
||||
* If the old parent clock speed is less than the clock speed of
|
||||
* the alternate parent, then it should be ensured that at no point
|
||||
* the armclk speed is more than the old_prate until the dividers are
|
||||
* set. Also workaround the issue of the dividers being set to lower
|
||||
* values before the parent clock speed is set to new lower speed
|
||||
* (this can result in too high speed of armclk output clocks).
|
||||
*/
|
||||
if (alt_prate > ndata->old_rate || ndata->old_rate > ndata->new_rate) {
|
||||
unsigned long tmp_rate = min(ndata->old_rate, ndata->new_rate);
|
||||
|
||||
alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
|
||||
WARN_ON(alt_div >= MAX_DIV);
|
||||
|
||||
exynos5433_set_safe_div(base, alt_div, alt_div_mask);
|
||||
div0 |= alt_div;
|
||||
}
|
||||
|
||||
/* select the alternate parent */
|
||||
mux_reg = readl(base + E5433_MUX_SEL2);
|
||||
writel(mux_reg | 1, base + E5433_MUX_SEL2);
|
||||
wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 2);
|
||||
|
||||
/* alternate parent is active now. set the dividers */
|
||||
writel(div0, base + E5433_DIV_CPU0);
|
||||
wait_until_divider_stable(base + E5433_DIV_STAT_CPU0, DIV_MASK_ALL);
|
||||
|
||||
writel(div1, base + E5433_DIV_CPU1);
|
||||
wait_until_divider_stable(base + E5433_DIV_STAT_CPU1, DIV_MASK_ALL);
|
||||
|
||||
spin_unlock_irqrestore(cpuclk->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handler for post-rate change notification from parent clock */
|
||||
static int exynos5433_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
|
||||
struct exynos_cpuclk *cpuclk, void __iomem *base)
|
||||
{
|
||||
unsigned long div = 0, div_mask = DIV_MASK;
|
||||
unsigned long mux_reg;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(cpuclk->lock, flags);
|
||||
|
||||
/* select apll as the alternate parent */
|
||||
mux_reg = readl(base + E5433_MUX_SEL2);
|
||||
writel(mux_reg & ~1, base + E5433_MUX_SEL2);
|
||||
wait_until_mux_stable(base + E5433_MUX_STAT2, 0, 1);
|
||||
|
||||
exynos5433_set_safe_div(base, div, div_mask);
|
||||
spin_unlock_irqrestore(cpuclk->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This notifier function is called for the pre-rate and post-rate change
|
||||
* notifications of the parent clock of cpuclk.
|
||||
@ -275,6 +378,29 @@ static int exynos_cpuclk_notifier_cb(struct notifier_block *nb,
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
/*
|
||||
* This notifier function is called for the pre-rate and post-rate change
|
||||
* notifications of the parent clock of cpuclk.
|
||||
*/
|
||||
static int exynos5433_cpuclk_notifier_cb(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
struct clk_notifier_data *ndata = data;
|
||||
struct exynos_cpuclk *cpuclk;
|
||||
void __iomem *base;
|
||||
int err = 0;
|
||||
|
||||
cpuclk = container_of(nb, struct exynos_cpuclk, clk_nb);
|
||||
base = cpuclk->ctrl_base;
|
||||
|
||||
if (event == PRE_RATE_CHANGE)
|
||||
err = exynos5433_cpuclk_pre_rate_change(ndata, cpuclk, base);
|
||||
else if (event == POST_RATE_CHANGE)
|
||||
err = exynos5433_cpuclk_post_rate_change(ndata, cpuclk, base);
|
||||
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
/* helper function to register a CPU clock */
|
||||
int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
|
||||
unsigned int lookup_id, const char *name, const char *parent,
|
||||
@ -301,7 +427,10 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
|
||||
cpuclk->ctrl_base = ctx->reg_base + offset;
|
||||
cpuclk->lock = &ctx->lock;
|
||||
cpuclk->flags = flags;
|
||||
cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
|
||||
if (flags & CLK_CPU_HAS_E5433_REGS_LAYOUT)
|
||||
cpuclk->clk_nb.notifier_call = exynos5433_cpuclk_notifier_cb;
|
||||
else
|
||||
cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
|
||||
|
||||
cpuclk->alt_parent = __clk_lookup(alt_parent);
|
||||
if (!cpuclk->alt_parent) {
|
||||
|
@ -57,10 +57,12 @@ struct exynos_cpuclk {
|
||||
struct notifier_block clk_nb;
|
||||
unsigned long flags;
|
||||
|
||||
/* The CPU clock registers has DIV1 configuration register */
|
||||
/* The CPU clock registers have DIV1 configuration register */
|
||||
#define CLK_CPU_HAS_DIV1 (1 << 0)
|
||||
/* When ALT parent is active, debug clocks need safe divider values */
|
||||
#define CLK_CPU_NEEDS_DEBUG_ALT_DIV (1 << 1)
|
||||
/* The CPU clock registers have Exynos5433-compatible layout */
|
||||
#define CLK_CPU_HAS_E5433_REGS_LAYOUT (1 << 2)
|
||||
};
|
||||
|
||||
extern int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
|
||||
|
@ -273,17 +273,7 @@ static struct platform_driver exynos_audss_clk_driver = {
|
||||
.remove = exynos_audss_clk_remove,
|
||||
};
|
||||
|
||||
static int __init exynos_audss_clk_init(void)
|
||||
{
|
||||
return platform_driver_register(&exynos_audss_clk_driver);
|
||||
}
|
||||
core_initcall(exynos_audss_clk_init);
|
||||
|
||||
static void __exit exynos_audss_clk_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&exynos_audss_clk_driver);
|
||||
}
|
||||
module_exit(exynos_audss_clk_exit);
|
||||
module_platform_driver(exynos_audss_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Padmavathi Venna <padma.v@samsung.com>");
|
||||
MODULE_DESCRIPTION("Exynos Audio Subsystem Clock Controller");
|
||||
|
@ -151,6 +151,8 @@ static void __init exynos5_clkout_init(struct device_node *node)
|
||||
}
|
||||
CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu",
|
||||
exynos5_clkout_init);
|
||||
CLK_OF_DECLARE(exynos5410_clkout, "samsung,exynos5410-pmu",
|
||||
exynos5_clkout_init);
|
||||
CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu",
|
||||
exynos5_clkout_init);
|
||||
CLK_OF_DECLARE(exynos5433_clkout, "samsung,exynos5433-pmu",
|
||||
|
@ -103,7 +103,7 @@
|
||||
#define PWR_CTRL1_USE_CORE1_WFI (1 << 1)
|
||||
#define PWR_CTRL1_USE_CORE0_WFI (1 << 0)
|
||||
|
||||
static unsigned long exynos3250_cmu_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos3250_cmu_clk_regs[] __initconst = {
|
||||
SRC_LEFTBUS,
|
||||
DIV_LEFTBUS,
|
||||
GATE_IP_LEFTBUS,
|
||||
@ -226,7 +226,7 @@ PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti",
|
||||
PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" };
|
||||
PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" };
|
||||
|
||||
static struct samsung_fixed_factor_clock fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "sclk_mpll_1600", "mout_mpll", 1, 1, 0),
|
||||
FFACTOR(0, "sclk_mpll_mif", "mout_mpll", 1, 2, 0),
|
||||
FFACTOR(0, "sclk_bpll", "fout_bpll", 1, 2, 0),
|
||||
@ -237,7 +237,7 @@ static struct samsung_fixed_factor_clock fixed_factor_clks[] __initdata = {
|
||||
FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock mux_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -326,7 +326,7 @@ static struct samsung_mux_clock mux_clks[] __initdata = {
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock div_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -429,7 +429,7 @@ static struct samsung_div_clock div_clks[] __initdata = {
|
||||
DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock gate_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -669,7 +669,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* APLL & MPLL & BPLL & UPLL */
|
||||
static struct samsung_pll_rate_table exynos3250_pll_rates[] = {
|
||||
static const struct samsung_pll_rate_table exynos3250_pll_rates[] __initconst = {
|
||||
PLL_35XX_RATE(1200000000, 400, 4, 1),
|
||||
PLL_35XX_RATE(1100000000, 275, 3, 1),
|
||||
PLL_35XX_RATE(1066000000, 533, 6, 1),
|
||||
@ -691,7 +691,7 @@ static struct samsung_pll_rate_table exynos3250_pll_rates[] = {
|
||||
};
|
||||
|
||||
/* EPLL */
|
||||
static struct samsung_pll_rate_table exynos3250_epll_rates[] = {
|
||||
static const struct samsung_pll_rate_table exynos3250_epll_rates[] __initconst = {
|
||||
PLL_36XX_RATE(800000000, 200, 3, 1, 0),
|
||||
PLL_36XX_RATE(288000000, 96, 2, 2, 0),
|
||||
PLL_36XX_RATE(192000000, 128, 2, 3, 0),
|
||||
@ -710,7 +710,7 @@ static struct samsung_pll_rate_table exynos3250_epll_rates[] = {
|
||||
};
|
||||
|
||||
/* VPLL */
|
||||
static struct samsung_pll_rate_table exynos3250_vpll_rates[] = {
|
||||
static const struct samsung_pll_rate_table exynos3250_vpll_rates[] __initconst = {
|
||||
PLL_36XX_RATE(600000000, 100, 2, 1, 0),
|
||||
PLL_36XX_RATE(533000000, 266, 3, 2, 32768),
|
||||
PLL_36XX_RATE(519230987, 173, 2, 2, 5046),
|
||||
@ -740,7 +740,7 @@ static struct samsung_pll_rate_table exynos3250_vpll_rates[] = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos3250_plls[] __initdata = {
|
||||
static const struct samsung_pll_clock exynos3250_plls[] __initconst = {
|
||||
PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
|
||||
APLL_LOCK, APLL_CON0, exynos3250_pll_rates),
|
||||
PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll",
|
||||
@ -772,7 +772,7 @@ static void __init exynos3_core_down_clock(void __iomem *reg_base)
|
||||
__raw_writel(0x0, reg_base + PWR_CTRL2);
|
||||
}
|
||||
|
||||
static struct samsung_cmu_info cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info cmu_info __initconst = {
|
||||
.pll_clks = exynos3250_plls,
|
||||
.nr_pll_clks = ARRAY_SIZE(exynos3250_plls),
|
||||
.mux_clks = mux_clks,
|
||||
@ -848,7 +848,7 @@ CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init);
|
||||
#define EPLL_CON2 0x111c
|
||||
#define SRC_EPLL 0x1120
|
||||
|
||||
static unsigned long exynos3250_cmu_dmc_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos3250_cmu_dmc_clk_regs[] __initconst = {
|
||||
BPLL_LOCK,
|
||||
BPLL_CON0,
|
||||
BPLL_CON1,
|
||||
@ -874,7 +874,7 @@ PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", };
|
||||
PNAME(mout_mpll_mif_p) = { "fin_pll", "sclk_mpll_mif", };
|
||||
PNAME(mout_dphy_p) = { "mout_mpll_mif", "mout_bpll", };
|
||||
|
||||
static struct samsung_mux_clock dmc_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock dmc_mux_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -893,7 +893,7 @@ static struct samsung_mux_clock dmc_mux_clks[] __initdata = {
|
||||
MUX(CLK_MOUT_EPLL, "mout_epll", mout_epll_p, SRC_EPLL, 4, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock dmc_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock dmc_div_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -910,14 +910,14 @@ static struct samsung_div_clock dmc_div_clks[] __initdata = {
|
||||
DIV(CLK_DIV_DMCD, "div_dmcd", "div_dmc", DIV_DMC1, 11, 3),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos3250_dmc_plls[] __initdata = {
|
||||
static const struct samsung_pll_clock exynos3250_dmc_plls[] __initconst = {
|
||||
PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll",
|
||||
BPLL_LOCK, BPLL_CON0, exynos3250_pll_rates),
|
||||
PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
|
||||
EPLL_LOCK, EPLL_CON0, exynos3250_epll_rates),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info dmc_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info dmc_cmu_info __initconst = {
|
||||
.pll_clks = exynos3250_dmc_plls,
|
||||
.nr_pll_clks = ARRAY_SIZE(exynos3250_dmc_plls),
|
||||
.mux_clks = dmc_mux_clks,
|
||||
@ -947,7 +947,7 @@ CLK_OF_DECLARE(exynos3250_cmu_dmc, "samsung,exynos3250-cmu-dmc",
|
||||
#define GATE_IP_ISP1 0x804
|
||||
#define GATE_SCLK_ISP 0x900
|
||||
|
||||
static struct samsung_div_clock isp_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock isp_div_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -967,7 +967,7 @@ static struct samsung_div_clock isp_div_clks[] __initdata = {
|
||||
DIV(CLK_DIV_MPWM, "div_mpwm", "div_isp1", DIV_ISP1, 0, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock isp_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock isp_gate_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -1063,7 +1063,7 @@ static struct samsung_gate_clock isp_gate_clks[] __initdata = {
|
||||
GATE_SCLK_ISP, 0, CLK_IGNORE_UNUSED, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info isp_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info isp_cmu_info __initconst = {
|
||||
.div_clks = isp_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(isp_div_clks),
|
||||
.gate_clks = isp_gate_clks,
|
||||
@ -1079,14 +1079,15 @@ static int __init exynos3250_cmu_isp_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id exynos3250_cmu_isp_of_match[] = {
|
||||
static const struct of_device_id exynos3250_cmu_isp_of_match[] __initconst = {
|
||||
{ .compatible = "samsung,exynos3250-cmu-isp", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver exynos3250_cmu_isp_driver = {
|
||||
static struct platform_driver exynos3250_cmu_isp_driver __initdata = {
|
||||
.driver = {
|
||||
.name = "exynos3250-cmu-isp",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = exynos3250_cmu_isp_of_match,
|
||||
},
|
||||
};
|
||||
|
@ -169,7 +169,7 @@ static struct samsung_clk_reg_dump *exynos4_save_pll;
|
||||
* list of controller registers to be saved and restored during a
|
||||
* suspend/resume cycle.
|
||||
*/
|
||||
static unsigned long exynos4210_clk_save[] __initdata = {
|
||||
static const unsigned long exynos4210_clk_save[] __initconst = {
|
||||
E4210_SRC_IMAGE,
|
||||
E4210_SRC_LCD1,
|
||||
E4210_SRC_MASK_LCD1,
|
||||
@ -181,7 +181,7 @@ static unsigned long exynos4210_clk_save[] __initdata = {
|
||||
PWR_CTRL1,
|
||||
};
|
||||
|
||||
static unsigned long exynos4x12_clk_save[] __initdata = {
|
||||
static const unsigned long exynos4x12_clk_save[] __initconst = {
|
||||
E4X12_GATE_IP_IMAGE,
|
||||
E4X12_GATE_IP_PERIR,
|
||||
E4X12_SRC_CAM1,
|
||||
@ -192,7 +192,7 @@ static unsigned long exynos4x12_clk_save[] __initdata = {
|
||||
E4X12_PWR_CTRL2,
|
||||
};
|
||||
|
||||
static unsigned long exynos4_clk_pll_regs[] __initdata = {
|
||||
static const unsigned long exynos4_clk_pll_regs[] __initconst = {
|
||||
EPLL_LOCK,
|
||||
VPLL_LOCK,
|
||||
EPLL_CON0,
|
||||
@ -203,7 +203,7 @@ static unsigned long exynos4_clk_pll_regs[] __initdata = {
|
||||
VPLL_CON2,
|
||||
};
|
||||
|
||||
static unsigned long exynos4_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos4_clk_regs[] __initconst = {
|
||||
SRC_LEFTBUS,
|
||||
DIV_LEFTBUS,
|
||||
GATE_IP_LEFTBUS,
|
||||
@ -505,28 +505,28 @@ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initconst = {
|
||||
FRATE(0, "sclk_hdmi24m", NULL, 0, 24000000),
|
||||
FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", "hdmi", 0, 27000000),
|
||||
FRATE(0, "sclk_usbphy0", NULL, 0, 48000000),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initconst = {
|
||||
FRATE(0, "sclk_usbphy1", NULL, 0, 48000000),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "sclk_apll_div_2", "sclk_apll", 1, 2, 0),
|
||||
FFACTOR(0, "fout_mpll_div_2", "fout_mpll", 1, 2, 0),
|
||||
FFACTOR(0, "fout_apll_div_2", "fout_apll", 1, 2, 0),
|
||||
FFACTOR(0, "arm_clk_div_2", "div_core2", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock exynos4210_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock exynos4210_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "sclk_mpll_div_2", "sclk_mpll", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "sclk_mpll_user_l_div_2", "mout_mpll_user_l", 1, 2, 0),
|
||||
FFACTOR(0, "sclk_mpll_user_r_div_2", "mout_mpll_user_r", 1, 2, 0),
|
||||
FFACTOR(0, "sclk_mpll_user_t_div_2", "mout_mpll_user_t", 1, 2, 0),
|
||||
@ -534,7 +534,7 @@ static struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __initda
|
||||
};
|
||||
|
||||
/* list of mux clocks supported in all exynos4 soc's */
|
||||
static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos4_mux_clks[] __initconst = {
|
||||
MUX_FA(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
|
||||
CLK_SET_RATE_PARENT | CLK_RECALC_NEW_RATES, 0,
|
||||
"mout_apll"),
|
||||
@ -555,11 +555,11 @@ static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of mux clocks supported in exynos4210 soc */
|
||||
static struct samsung_mux_clock exynos4210_mux_early[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos4210_mux_early[] __initconst = {
|
||||
MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos4210_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_gdl", sclk_ampll_p4210, SRC_LEFTBUS, 0, 1),
|
||||
MUX(0, "mout_clkout_leftbus", clkout_left_p4210,
|
||||
CLKOUT_CMU_LEFTBUS, 0, 5),
|
||||
@ -622,7 +622,7 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of mux clocks supported in exynos4x12 soc */
|
||||
static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos4x12_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_mpll_user_l", mout_mpll_p, SRC_LEFTBUS, 4, 1),
|
||||
MUX(0, "mout_gdl", mout_gdl_p4x12, SRC_LEFTBUS, 0, 1),
|
||||
MUX(0, "mout_clkout_leftbus", clkout_left_p4x12,
|
||||
@ -705,7 +705,7 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of divider clocks supported in all exynos4 soc's */
|
||||
static struct samsung_div_clock exynos4_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos4_div_clks[] __initconst = {
|
||||
DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
|
||||
DIV(0, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
|
||||
DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
|
||||
@ -795,7 +795,7 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of divider clocks supported in exynos4210 soc */
|
||||
static struct samsung_div_clock exynos4210_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos4210_div_clks[] __initconst = {
|
||||
DIV(CLK_ACLK200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3),
|
||||
DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_IMAGE, 0, 4),
|
||||
DIV(0, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4),
|
||||
@ -806,7 +806,7 @@ static struct samsung_div_clock exynos4210_div_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of divider clocks supported in exynos4x12 soc */
|
||||
static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
|
||||
DIV(0, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4),
|
||||
DIV(0, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4),
|
||||
DIV(0, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4),
|
||||
@ -837,7 +837,7 @@ static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of gate clocks supported in all exynos4 soc's */
|
||||
static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
|
||||
/*
|
||||
* After all Exynos4 based platforms are migrated to use device tree,
|
||||
* the device name and clock alias names specified below for some
|
||||
@ -1043,7 +1043,7 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of gate clocks supported in exynos4210 soc */
|
||||
static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos4210_gate_clks[] __initconst = {
|
||||
GATE(CLK_TVENC, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0),
|
||||
GATE(CLK_G2D, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0),
|
||||
GATE(CLK_ROTATOR, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0),
|
||||
@ -1090,7 +1090,7 @@ static struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
|
||||
};
|
||||
|
||||
/* list of gate clocks supported in exynos4x12 soc */
|
||||
static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
|
||||
GATE(CLK_AUDSS, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0),
|
||||
GATE(CLK_MDNIE0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0),
|
||||
GATE(CLK_ROTATOR, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0),
|
||||
@ -1190,17 +1190,17 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
|
||||
0),
|
||||
};
|
||||
|
||||
static struct samsung_clock_alias exynos4_aliases[] __initdata = {
|
||||
static const struct samsung_clock_alias exynos4_aliases[] __initconst = {
|
||||
ALIAS(CLK_MOUT_CORE, NULL, "moutcore"),
|
||||
ALIAS(CLK_ARM_CLK, NULL, "armclk"),
|
||||
ALIAS(CLK_SCLK_APLL, NULL, "mout_apll"),
|
||||
};
|
||||
|
||||
static struct samsung_clock_alias exynos4210_aliases[] __initdata = {
|
||||
static const struct samsung_clock_alias exynos4210_aliases[] __initconst = {
|
||||
ALIAS(CLK_SCLK_MPLL, NULL, "mout_mpll"),
|
||||
};
|
||||
|
||||
static struct samsung_clock_alias exynos4x12_aliases[] __initdata = {
|
||||
static const struct samsung_clock_alias exynos4x12_aliases[] __initconst = {
|
||||
ALIAS(CLK_MOUT_MPLL_USER_C, NULL, "mout_mpll"),
|
||||
};
|
||||
|
||||
@ -1211,7 +1211,7 @@ static struct samsung_clock_alias exynos4x12_aliases[] __initdata = {
|
||||
* controller is first remapped and the value of XOM[0] bit is read to
|
||||
* determine the parent clock.
|
||||
*/
|
||||
static unsigned long exynos4_get_xom(void)
|
||||
static unsigned long __init exynos4_get_xom(void)
|
||||
{
|
||||
unsigned long xom = 0;
|
||||
void __iomem *chipid_base;
|
||||
@ -1264,7 +1264,7 @@ static const struct of_device_id ext_clk_match[] __initconst = {
|
||||
};
|
||||
|
||||
/* PLLs PMS values */
|
||||
static struct samsung_pll_rate_table exynos4210_apll_rates[] __initdata = {
|
||||
static const struct samsung_pll_rate_table exynos4210_apll_rates[] __initconst = {
|
||||
PLL_45XX_RATE(1200000000, 150, 3, 1, 28),
|
||||
PLL_45XX_RATE(1000000000, 250, 6, 1, 28),
|
||||
PLL_45XX_RATE( 800000000, 200, 6, 1, 28),
|
||||
@ -1277,7 +1277,7 @@ static struct samsung_pll_rate_table exynos4210_apll_rates[] __initdata = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4210_epll_rates[] __initdata = {
|
||||
static const struct samsung_pll_rate_table exynos4210_epll_rates[] __initconst = {
|
||||
PLL_4600_RATE(192000000, 48, 3, 1, 0, 0),
|
||||
PLL_4600_RATE(180633605, 45, 3, 1, 10381, 0),
|
||||
PLL_4600_RATE(180000000, 45, 3, 1, 0, 0),
|
||||
@ -1288,7 +1288,7 @@ static struct samsung_pll_rate_table exynos4210_epll_rates[] __initdata = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4210_vpll_rates[] __initdata = {
|
||||
static const struct samsung_pll_rate_table exynos4210_vpll_rates[] __initconst = {
|
||||
PLL_4650_RATE(360000000, 44, 3, 0, 1024, 0, 14, 0),
|
||||
PLL_4650_RATE(324000000, 53, 2, 1, 1024, 1, 1, 1),
|
||||
PLL_4650_RATE(259617187, 63, 3, 1, 1950, 0, 20, 1),
|
||||
@ -1297,7 +1297,7 @@ static struct samsung_pll_rate_table exynos4210_vpll_rates[] __initdata = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4x12_apll_rates[] __initdata = {
|
||||
static const struct samsung_pll_rate_table exynos4x12_apll_rates[] __initconst = {
|
||||
PLL_35XX_RATE(1500000000, 250, 4, 0),
|
||||
PLL_35XX_RATE(1400000000, 175, 3, 0),
|
||||
PLL_35XX_RATE(1300000000, 325, 6, 0),
|
||||
@ -1315,7 +1315,7 @@ static struct samsung_pll_rate_table exynos4x12_apll_rates[] __initdata = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4x12_epll_rates[] __initdata = {
|
||||
static const struct samsung_pll_rate_table exynos4x12_epll_rates[] __initconst = {
|
||||
PLL_36XX_RATE(192000000, 48, 3, 1, 0),
|
||||
PLL_36XX_RATE(180633605, 45, 3, 1, 10381),
|
||||
PLL_36XX_RATE(180000000, 45, 3, 1, 0),
|
||||
@ -1326,7 +1326,7 @@ static struct samsung_pll_rate_table exynos4x12_epll_rates[] __initdata = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initdata = {
|
||||
static const struct samsung_pll_rate_table exynos4x12_vpll_rates[] __initconst = {
|
||||
PLL_36XX_RATE(533000000, 133, 3, 1, 16384),
|
||||
PLL_36XX_RATE(440000000, 110, 3, 1, 0),
|
||||
PLL_36XX_RATE(350000000, 175, 3, 2, 0),
|
||||
@ -1375,12 +1375,12 @@ static void __init exynos4x12_core_down_clock(void)
|
||||
if (num_possible_cpus() == 4)
|
||||
tmp |= PWR_CTRL1_USE_CORE3_WFE | PWR_CTRL1_USE_CORE2_WFE |
|
||||
PWR_CTRL1_USE_CORE3_WFI | PWR_CTRL1_USE_CORE2_WFI;
|
||||
__raw_writel(tmp, reg_base + PWR_CTRL1);
|
||||
writel_relaxed(tmp, reg_base + PWR_CTRL1);
|
||||
|
||||
/*
|
||||
* Disable the clock up feature in case it was enabled by bootloader.
|
||||
*/
|
||||
__raw_writel(0x0, reg_base + E4X12_PWR_CTRL2);
|
||||
writel_relaxed(0x0, reg_base + E4X12_PWR_CTRL2);
|
||||
}
|
||||
|
||||
#define E4210_CPU_DIV0(apll, pclk_dbg, atb, periph, corem1, corem0) \
|
||||
@ -1450,8 +1450,6 @@ static void __init exynos4_clk_init(struct device_node *np,
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
samsung_clk_of_register_fixed_ext(ctx, exynos4_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
|
||||
|
@ -111,7 +111,7 @@
|
||||
#define DIV_CPU0 0x14500
|
||||
#define DIV_CPU1 0x14504
|
||||
|
||||
static unsigned long exynos4415_cmu_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos4415_cmu_clk_regs[] __initconst = {
|
||||
SRC_LEFTBUS,
|
||||
DIV_LEFTBUS,
|
||||
GATE_IP_LEFTBUS,
|
||||
@ -268,16 +268,16 @@ PNAME(group_aclk_isp0_300_user_p) = { "fin_pll", "mout_aclk_isp0_300" };
|
||||
PNAME(group_aclk_isp1_300_user_p) = { "fin_pll", "mout_aclk_isp1_300" };
|
||||
PNAME(group_mout_mpll_user_t_p) = { "mout_mpll_user_t" };
|
||||
|
||||
static struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initconst = {
|
||||
/* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */
|
||||
FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initconst = {
|
||||
FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos4415_mux_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -427,7 +427,7 @@ static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = {
|
||||
group_aclk_isp1_300_user_p, SRC_TOP_ISP1, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos4415_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos4415_div_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -566,7 +566,7 @@ static struct samsung_div_clock exynos4415_div_clks[] __initdata = {
|
||||
DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock exynos4415_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos4415_gate_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
@ -859,7 +859,7 @@ static struct samsung_gate_clock exynos4415_gate_clks[] __initdata = {
|
||||
/*
|
||||
* APLL & MPLL & BPLL & ISP_PLL & DISP_PLL & G3D_PLL
|
||||
*/
|
||||
static struct samsung_pll_rate_table exynos4415_pll_rates[] = {
|
||||
static const struct samsung_pll_rate_table exynos4415_pll_rates[] __initconst = {
|
||||
PLL_35XX_RATE(1600000000, 400, 3, 1),
|
||||
PLL_35XX_RATE(1500000000, 250, 2, 1),
|
||||
PLL_35XX_RATE(1400000000, 175, 3, 0),
|
||||
@ -891,7 +891,7 @@ static struct samsung_pll_rate_table exynos4415_pll_rates[] = {
|
||||
};
|
||||
|
||||
/* EPLL */
|
||||
static struct samsung_pll_rate_table exynos4415_epll_rates[] = {
|
||||
static const struct samsung_pll_rate_table exynos4415_epll_rates[] __initconst = {
|
||||
PLL_36XX_RATE(800000000, 200, 3, 1, 0),
|
||||
PLL_36XX_RATE(288000000, 96, 2, 2, 0),
|
||||
PLL_36XX_RATE(192000000, 128, 2, 3, 0),
|
||||
@ -909,7 +909,7 @@ static struct samsung_pll_rate_table exynos4415_epll_rates[] = {
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos4415_plls[] __initdata = {
|
||||
static const struct samsung_pll_clock exynos4415_plls[] __initconst = {
|
||||
PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll",
|
||||
APLL_LOCK, APLL_CON0, exynos4415_pll_rates),
|
||||
PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll", "fin_pll",
|
||||
@ -922,7 +922,7 @@ static struct samsung_pll_clock exynos4415_plls[] __initdata = {
|
||||
"fin_pll", DISP_PLL_LOCK, DISP_PLL_CON0, exynos4415_pll_rates),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info cmu_info __initconst = {
|
||||
.pll_clks = exynos4415_plls,
|
||||
.nr_pll_clks = ARRAY_SIZE(exynos4415_plls),
|
||||
.mux_clks = exynos4415_mux_clks,
|
||||
@ -961,7 +961,7 @@ CLK_OF_DECLARE(exynos4415_cmu, "samsung,exynos4415-cmu", exynos4415_cmu_init);
|
||||
#define SRC_DMC 0x300
|
||||
#define DIV_DMC1 0x504
|
||||
|
||||
static unsigned long exynos4415_cmu_dmc_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos4415_cmu_dmc_clk_regs[] __initconst = {
|
||||
MPLL_LOCK,
|
||||
MPLL_CON0,
|
||||
MPLL_CON1,
|
||||
@ -978,14 +978,14 @@ PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", };
|
||||
PNAME(mout_bpll_p) = { "fin_pll", "fout_bpll", };
|
||||
PNAME(mbpll_p) = { "mout_mpll", "mout_bpll", };
|
||||
|
||||
static struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos4415_dmc_mux_clks[] __initconst = {
|
||||
MUX(CLK_DMC_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_DMC, 12, 1),
|
||||
MUX(CLK_DMC_MOUT_BPLL, "mout_bpll", mout_bpll_p, SRC_DMC, 10, 1),
|
||||
MUX(CLK_DMC_MOUT_DPHY, "mout_dphy", mbpll_p, SRC_DMC, 8, 1),
|
||||
MUX(CLK_DMC_MOUT_DMC_BUS, "mout_dmc_bus", mbpll_p, SRC_DMC, 4, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos4415_dmc_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos4415_dmc_div_clks[] __initconst = {
|
||||
DIV(CLK_DMC_DIV_DMC, "div_dmc", "div_dmc_pre", DIV_DMC1, 27, 3),
|
||||
DIV(CLK_DMC_DIV_DPHY, "div_dphy", "mout_dphy", DIV_DMC1, 23, 3),
|
||||
DIV(CLK_DMC_DIV_DMC_PRE, "div_dmc_pre", "mout_dmc_bus",
|
||||
@ -995,14 +995,14 @@ static struct samsung_div_clock exynos4415_dmc_div_clks[] __initdata = {
|
||||
DIV(CLK_DMC_DIV_MPLL_PRE, "div_mpll_pre", "mout_mpll", DIV_DMC1, 8, 2),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos4415_dmc_plls[] __initdata = {
|
||||
static const struct samsung_pll_clock exynos4415_dmc_plls[] __initconst = {
|
||||
PLL(pll_35xx, CLK_DMC_FOUT_MPLL, "fout_mpll", "fin_pll",
|
||||
MPLL_LOCK, MPLL_CON0, exynos4415_pll_rates),
|
||||
PLL(pll_35xx, CLK_DMC_FOUT_BPLL, "fout_bpll", "fin_pll",
|
||||
BPLL_LOCK, BPLL_CON0, exynos4415_pll_rates),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info cmu_dmc_info __initdata = {
|
||||
static const struct samsung_cmu_info cmu_dmc_info __initconst = {
|
||||
.pll_clks = exynos4415_dmc_plls,
|
||||
.nr_pll_clks = ARRAY_SIZE(exynos4415_dmc_plls),
|
||||
.mux_clks = exynos4415_dmc_mux_clks,
|
||||
|
@ -117,7 +117,7 @@ static struct samsung_clk_reg_dump *exynos5250_save;
|
||||
* list of controller registers to be saved and restored during a
|
||||
* suspend/resume cycle.
|
||||
*/
|
||||
static unsigned long exynos5250_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos5250_clk_regs[] __initconst = {
|
||||
SRC_CPU,
|
||||
DIV_CPU0,
|
||||
PWR_CTRL1,
|
||||
@ -190,7 +190,7 @@ static struct syscore_ops exynos5250_clk_syscore_ops = {
|
||||
.resume = exynos5250_clk_resume,
|
||||
};
|
||||
|
||||
static void exynos5250_clk_sleep_init(void)
|
||||
static void __init exynos5250_clk_sleep_init(void)
|
||||
{
|
||||
exynos5250_save = samsung_clk_alloc_reg_dump(exynos5250_clk_regs,
|
||||
ARRAY_SIZE(exynos5250_clk_regs));
|
||||
@ -203,7 +203,7 @@ static void exynos5250_clk_sleep_init(void)
|
||||
register_syscore_ops(&exynos5250_clk_syscore_ops);
|
||||
}
|
||||
#else
|
||||
static void exynos5250_clk_sleep_init(void) {}
|
||||
static void __init exynos5250_clk_sleep_init(void) {}
|
||||
#endif
|
||||
|
||||
/* list of all parent clock list */
|
||||
@ -266,23 +266,23 @@ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initda
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
static struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initconst = {
|
||||
FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 24000000),
|
||||
FRATE(0, "sclk_hdmi27m", NULL, 0, 27000000),
|
||||
FRATE(0, "sclk_dptxphy", NULL, 0, 24000000),
|
||||
FRATE(0, "sclk_uhostphy", NULL, 0, 48000000),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "fout_mplldiv2", "fout_mpll", 1, 2, 0),
|
||||
FFACTOR(0, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initconst = {
|
||||
MUX(0, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by (clock domain, register address,
|
||||
* bitfield shift) triplet in ascending order. When adding new entries,
|
||||
@ -378,7 +378,7 @@ static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos5250_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos5250_div_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by (clock domain, register address,
|
||||
* bitfield shift) triplet in ascending order. When adding new entries,
|
||||
@ -470,7 +470,7 @@ static struct samsung_div_clock exynos5250_div_clks[] __initdata = {
|
||||
DIV(CLK_DIV_I2S2, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by (clock domain, register address,
|
||||
* bitfield shift) triplet in ascending order. When adding new entries,
|
||||
@ -698,7 +698,7 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
|
||||
GATE_IP_ISP1, 7, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = {
|
||||
static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = {
|
||||
/* sorted in descending order */
|
||||
/* PLL_36XX_RATE(rate, m, p, s, k) */
|
||||
PLL_36XX_RATE(266000000, 266, 3, 3, 0),
|
||||
@ -707,7 +707,7 @@ static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = {
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = {
|
||||
static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = {
|
||||
/* sorted in descending order */
|
||||
/* PLL_36XX_RATE(rate, m, p, s, k) */
|
||||
PLL_36XX_RATE(192000000, 64, 2, 2, 0),
|
||||
@ -721,7 +721,7 @@ static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = {
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table apll_24mhz_tbl[] __initdata = {
|
||||
static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = {
|
||||
/* sorted in descending order */
|
||||
/* PLL_35XX_RATE(rate, m, p, s) */
|
||||
PLL_35XX_RATE(1700000000, 425, 6, 0),
|
||||
@ -805,8 +805,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
samsung_clk_of_register_fixed_ext(ctx, exynos5250_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
|
||||
ext_clk_match);
|
||||
|
@ -22,7 +22,7 @@
|
||||
* Applicable for all 2550 Type PLLS for Exynos5260, listed below
|
||||
* DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
|
||||
*/
|
||||
static struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initdata = {
|
||||
static const struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initconst = {
|
||||
PLL_35XX_RATE(1700000000, 425, 6, 0),
|
||||
PLL_35XX_RATE(1600000000, 200, 3, 0),
|
||||
PLL_35XX_RATE(1500000000, 250, 4, 0),
|
||||
@ -55,7 +55,7 @@ static struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initdata = {
|
||||
/*
|
||||
* Applicable for 2650 Type PLL for AUD_PLL.
|
||||
*/
|
||||
static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
|
||||
static const struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initconst = {
|
||||
PLL_36XX_RATE(1600000000, 200, 3, 0, 0),
|
||||
PLL_36XX_RATE(1200000000, 100, 2, 0, 0),
|
||||
PLL_36XX_RATE(1000000000, 250, 3, 1, 0),
|
||||
@ -78,7 +78,7 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
|
||||
|
||||
/* CMU_AUD */
|
||||
|
||||
static unsigned long aud_clk_regs[] __initdata = {
|
||||
static const unsigned long aud_clk_regs[] __initconst = {
|
||||
MUX_SEL_AUD,
|
||||
DIV_AUD0,
|
||||
DIV_AUD1,
|
||||
@ -92,7 +92,7 @@ PNAME(mout_aud_pll_user_p) = {"fin_pll", "fout_aud_pll"};
|
||||
PNAME(mout_sclk_aud_i2s_p) = {"mout_aud_pll_user", "ioclk_i2s_cdclk"};
|
||||
PNAME(mout_sclk_aud_pcm_p) = {"mout_aud_pll_user", "ioclk_pcm_extclk"};
|
||||
|
||||
static struct samsung_mux_clock aud_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock aud_mux_clks[] __initconst = {
|
||||
MUX(AUD_MOUT_AUD_PLL_USER, "mout_aud_pll_user", mout_aud_pll_user_p,
|
||||
MUX_SEL_AUD, 0, 1),
|
||||
MUX(AUD_MOUT_SCLK_AUD_I2S, "mout_sclk_aud_i2s", mout_sclk_aud_i2s_p,
|
||||
@ -101,7 +101,7 @@ static struct samsung_mux_clock aud_mux_clks[] __initdata = {
|
||||
MUX_SEL_AUD, 8, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock aud_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock aud_div_clks[] __initconst = {
|
||||
DIV(AUD_DOUT_ACLK_AUD_131, "dout_aclk_aud_131", "mout_aud_pll_user",
|
||||
DIV_AUD0, 0, 4),
|
||||
|
||||
@ -113,7 +113,7 @@ static struct samsung_div_clock aud_div_clks[] __initdata = {
|
||||
DIV_AUD1, 12, 4),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock aud_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock aud_gate_clks[] __initconst = {
|
||||
GATE(AUD_SCLK_I2S, "sclk_aud_i2s", "dout_sclk_aud_i2s",
|
||||
EN_SCLK_AUD, 0, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(AUD_SCLK_PCM, "sclk_aud_pcm", "dout_sclk_aud_pcm",
|
||||
@ -154,7 +154,7 @@ CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
|
||||
|
||||
/* CMU_DISP */
|
||||
|
||||
static unsigned long disp_clk_regs[] __initdata = {
|
||||
static const unsigned long disp_clk_regs[] __initconst = {
|
||||
MUX_SEL_DISP0,
|
||||
MUX_SEL_DISP1,
|
||||
MUX_SEL_DISP2,
|
||||
@ -201,7 +201,7 @@ PNAME(mout_phyclk_mipi_dphy_4lmrxclk_esc0_user_p) = {"fin_pll",
|
||||
PNAME(mout_sclk_hdmi_spdif_p) = {"fin_pll", "ioclk_spdif_extclk",
|
||||
"dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"};
|
||||
|
||||
static struct samsung_mux_clock disp_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock disp_mux_clks[] __initconst = {
|
||||
MUX(DISP_MOUT_ACLK_DISP_333_USER, "mout_aclk_disp_333_user",
|
||||
mout_aclk_disp_333_user_p,
|
||||
MUX_SEL_DISP0, 0, 1),
|
||||
@ -270,7 +270,7 @@ static struct samsung_mux_clock disp_mux_clks[] __initdata = {
|
||||
MUX_SEL_DISP4, 4, 2),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock disp_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock disp_div_clks[] __initconst = {
|
||||
DIV(DISP_DOUT_PCLK_DISP_111, "dout_pclk_disp_111",
|
||||
"mout_aclk_disp_222_user",
|
||||
DIV_DISP, 8, 4),
|
||||
@ -283,7 +283,7 @@ static struct samsung_div_clock disp_div_clks[] __initdata = {
|
||||
DIV_DISP, 16, 4),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock disp_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock disp_gate_clks[] __initconst = {
|
||||
GATE(DISP_MOUT_HDMI_PHY_PIXEL_USER, "sclk_hdmi_link_i_pixel",
|
||||
"mout_phyclk_hdmi_phy_pixel_clko_user",
|
||||
EN_SCLK_DISP0, 26, CLK_SET_RATE_PARENT, 0),
|
||||
@ -344,7 +344,7 @@ CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
|
||||
|
||||
/* CMU_EGL */
|
||||
|
||||
static unsigned long egl_clk_regs[] __initdata = {
|
||||
static const unsigned long egl_clk_regs[] __initconst = {
|
||||
EGL_PLL_LOCK,
|
||||
EGL_PLL_CON0,
|
||||
EGL_PLL_CON1,
|
||||
@ -361,13 +361,13 @@ static unsigned long egl_clk_regs[] __initdata = {
|
||||
PNAME(mout_egl_b_p) = {"mout_egl_pll", "dout_bus_pll"};
|
||||
PNAME(mout_egl_pll_p) = {"fin_pll", "fout_egl_pll"};
|
||||
|
||||
static struct samsung_mux_clock egl_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock egl_mux_clks[] __initconst = {
|
||||
MUX(EGL_MOUT_EGL_PLL, "mout_egl_pll", mout_egl_pll_p,
|
||||
MUX_SEL_EGL, 4, 1),
|
||||
MUX(EGL_MOUT_EGL_B, "mout_egl_b", mout_egl_b_p, MUX_SEL_EGL, 16, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock egl_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock egl_div_clks[] __initconst = {
|
||||
DIV(EGL_DOUT_EGL1, "dout_egl1", "mout_egl_b", DIV_EGL, 0, 3),
|
||||
DIV(EGL_DOUT_EGL2, "dout_egl2", "dout_egl1", DIV_EGL, 4, 3),
|
||||
DIV(EGL_DOUT_ACLK_EGL, "dout_aclk_egl", "dout_egl2", DIV_EGL, 8, 3),
|
||||
@ -379,7 +379,7 @@ static struct samsung_div_clock egl_div_clks[] __initdata = {
|
||||
DIV(EGL_DOUT_EGL_PLL, "dout_egl_pll", "mout_egl_b", DIV_EGL, 24, 3),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock egl_pll_clks[] __initdata = {
|
||||
static const struct samsung_pll_clock egl_pll_clks[] __initconst = {
|
||||
PLL(pll_2550xx, EGL_FOUT_EGL_PLL, "fout_egl_pll", "fin_pll",
|
||||
EGL_PLL_LOCK, EGL_PLL_CON0,
|
||||
pll2550_24mhz_tbl),
|
||||
@ -408,7 +408,7 @@ CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
|
||||
|
||||
/* CMU_FSYS */
|
||||
|
||||
static unsigned long fsys_clk_regs[] __initdata = {
|
||||
static const unsigned long fsys_clk_regs[] __initconst = {
|
||||
MUX_SEL_FSYS0,
|
||||
MUX_SEL_FSYS1,
|
||||
EN_ACLK_FSYS,
|
||||
@ -431,7 +431,7 @@ PNAME(mout_phyclk_usbdrd30_pipe_pclk_user_p) = {"fin_pll",
|
||||
PNAME(mout_phyclk_usbdrd30_phyclock_user_p) = {"fin_pll",
|
||||
"phyclk_usbdrd30_udrd30_phyclock"};
|
||||
|
||||
static struct samsung_mux_clock fsys_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock fsys_mux_clks[] __initconst = {
|
||||
MUX(FSYS_MOUT_PHYCLK_USBDRD30_PHYCLOCK_USER,
|
||||
"mout_phyclk_usbdrd30_phyclock_user",
|
||||
mout_phyclk_usbdrd30_phyclock_user_p,
|
||||
@ -454,7 +454,7 @@ static struct samsung_mux_clock fsys_mux_clks[] __initdata = {
|
||||
MUX_SEL_FSYS1, 16, 1),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock fsys_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock fsys_gate_clks[] __initconst = {
|
||||
GATE(FSYS_PHYCLK_USBHOST20, "phyclk_usbhost20_phyclock",
|
||||
"mout_phyclk_usbdrd30_phyclock_user",
|
||||
EN_SCLK_FSYS, 1, 0, 0),
|
||||
@ -508,7 +508,7 @@ CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
|
||||
|
||||
/* CMU_G2D */
|
||||
|
||||
static unsigned long g2d_clk_regs[] __initdata = {
|
||||
static const unsigned long g2d_clk_regs[] __initconst = {
|
||||
MUX_SEL_G2D,
|
||||
MUX_STAT_G2D,
|
||||
DIV_G2D,
|
||||
@ -535,18 +535,18 @@ static unsigned long g2d_clk_regs[] __initdata = {
|
||||
|
||||
PNAME(mout_aclk_g2d_333_user_p) = {"fin_pll", "dout_aclk_g2d_333"};
|
||||
|
||||
static struct samsung_mux_clock g2d_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock g2d_mux_clks[] __initconst = {
|
||||
MUX(G2D_MOUT_ACLK_G2D_333_USER, "mout_aclk_g2d_333_user",
|
||||
mout_aclk_g2d_333_user_p,
|
||||
MUX_SEL_G2D, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock g2d_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock g2d_div_clks[] __initconst = {
|
||||
DIV(G2D_DOUT_PCLK_G2D_83, "dout_pclk_g2d_83", "mout_aclk_g2d_333_user",
|
||||
DIV_G2D, 0, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock g2d_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock g2d_gate_clks[] __initconst = {
|
||||
GATE(G2D_CLK_G2D, "clk_g2d", "mout_aclk_g2d_333_user",
|
||||
EN_IP_G2D, 4, 0, 0),
|
||||
GATE(G2D_CLK_JPEG, "clk_jpeg", "mout_aclk_g2d_333_user",
|
||||
@ -599,7 +599,7 @@ CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
|
||||
|
||||
/* CMU_G3D */
|
||||
|
||||
static unsigned long g3d_clk_regs[] __initdata = {
|
||||
static const unsigned long g3d_clk_regs[] __initconst = {
|
||||
G3D_PLL_LOCK,
|
||||
G3D_PLL_CON0,
|
||||
G3D_PLL_CON1,
|
||||
@ -615,23 +615,23 @@ static unsigned long g3d_clk_regs[] __initdata = {
|
||||
|
||||
PNAME(mout_g3d_pll_p) = {"fin_pll", "fout_g3d_pll"};
|
||||
|
||||
static struct samsung_mux_clock g3d_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock g3d_mux_clks[] __initconst = {
|
||||
MUX(G3D_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
|
||||
MUX_SEL_G3D, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock g3d_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock g3d_div_clks[] __initconst = {
|
||||
DIV(G3D_DOUT_PCLK_G3D, "dout_pclk_g3d", "dout_aclk_g3d", DIV_G3D, 0, 3),
|
||||
DIV(G3D_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_g3d_pll", DIV_G3D, 4, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock g3d_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock g3d_gate_clks[] __initconst = {
|
||||
GATE(G3D_CLK_G3D, "clk_g3d", "dout_aclk_g3d", EN_IP_G3D, 2, 0, 0),
|
||||
GATE(G3D_CLK_G3D_HPM, "clk_g3d_hpm", "dout_aclk_g3d",
|
||||
EN_IP_G3D, 3, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
|
||||
static const struct samsung_pll_clock g3d_pll_clks[] __initconst = {
|
||||
PLL(pll_2550, G3D_FOUT_G3D_PLL, "fout_g3d_pll", "fin_pll",
|
||||
G3D_PLL_LOCK, G3D_PLL_CON0,
|
||||
pll2550_24mhz_tbl),
|
||||
@ -662,7 +662,7 @@ CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
|
||||
|
||||
/* CMU_GSCL */
|
||||
|
||||
static unsigned long gscl_clk_regs[] __initdata = {
|
||||
static const unsigned long gscl_clk_regs[] __initconst = {
|
||||
MUX_SEL_GSCL,
|
||||
DIV_GSCL,
|
||||
EN_ACLK_GSCL,
|
||||
@ -692,7 +692,7 @@ PNAME(mout_aclk_m2m_400_user_p) = {"fin_pll", "dout_aclk_gscl_400"};
|
||||
PNAME(mout_aclk_gscl_fimc_user_p) = {"fin_pll", "dout_aclk_gscl_400"};
|
||||
PNAME(mout_aclk_csis_p) = {"dout_aclk_csis_200", "mout_aclk_gscl_fimc_user"};
|
||||
|
||||
static struct samsung_mux_clock gscl_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock gscl_mux_clks[] __initconst = {
|
||||
MUX(GSCL_MOUT_ACLK_GSCL_333_USER, "mout_aclk_gscl_333_user",
|
||||
mout_aclk_gscl_333_user_p,
|
||||
MUX_SEL_GSCL, 0, 1),
|
||||
@ -706,7 +706,7 @@ static struct samsung_mux_clock gscl_mux_clks[] __initdata = {
|
||||
MUX_SEL_GSCL, 24, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock gscl_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock gscl_div_clks[] __initconst = {
|
||||
DIV(GSCL_DOUT_PCLK_M2M_100, "dout_pclk_m2m_100",
|
||||
"mout_aclk_m2m_400_user",
|
||||
DIV_GSCL, 0, 3),
|
||||
@ -715,7 +715,7 @@ static struct samsung_div_clock gscl_div_clks[] __initdata = {
|
||||
DIV_GSCL, 4, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock gscl_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock gscl_gate_clks[] __initconst = {
|
||||
GATE(GSCL_SCLK_CSIS0_WRAP, "sclk_csis0_wrap", "dout_aclk_csis_200",
|
||||
EN_SCLK_GSCL_FIMC, 0, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(GSCL_SCLK_CSIS1_WRAP, "sclk_csis1_wrap", "dout_aclk_csis_200",
|
||||
@ -795,7 +795,7 @@ CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
|
||||
|
||||
/* CMU_ISP */
|
||||
|
||||
static unsigned long isp_clk_regs[] __initdata = {
|
||||
static const unsigned long isp_clk_regs[] __initconst = {
|
||||
MUX_SEL_ISP0,
|
||||
MUX_SEL_ISP1,
|
||||
DIV_ISP,
|
||||
@ -811,14 +811,14 @@ static unsigned long isp_clk_regs[] __initdata = {
|
||||
PNAME(mout_isp_400_user_p) = {"fin_pll", "dout_aclk_isp1_400"};
|
||||
PNAME(mout_isp_266_user_p) = {"fin_pll", "dout_aclk_isp1_266"};
|
||||
|
||||
static struct samsung_mux_clock isp_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock isp_mux_clks[] __initconst = {
|
||||
MUX(ISP_MOUT_ISP_266_USER, "mout_isp_266_user", mout_isp_266_user_p,
|
||||
MUX_SEL_ISP0, 0, 1),
|
||||
MUX(ISP_MOUT_ISP_400_USER, "mout_isp_400_user", mout_isp_400_user_p,
|
||||
MUX_SEL_ISP0, 4, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock isp_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock isp_div_clks[] __initconst = {
|
||||
DIV(ISP_DOUT_PCLK_ISP_66, "dout_pclk_isp_66", "mout_kfc",
|
||||
DIV_ISP, 0, 3),
|
||||
DIV(ISP_DOUT_PCLK_ISP_133, "dout_pclk_isp_133", "mout_kfc",
|
||||
@ -830,7 +830,7 @@ static struct samsung_div_clock isp_div_clks[] __initdata = {
|
||||
DIV(ISP_DOUT_SCLK_MPWM, "dout_sclk_mpwm", "mout_kfc", DIV_ISP, 20, 2),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock isp_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock isp_gate_clks[] __initconst = {
|
||||
GATE(ISP_CLK_GIC, "clk_isp_gic", "mout_aclk_isp1_266",
|
||||
EN_IP_ISP0, 15, 0, 0),
|
||||
|
||||
@ -914,7 +914,7 @@ CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
|
||||
|
||||
/* CMU_KFC */
|
||||
|
||||
static unsigned long kfc_clk_regs[] __initdata = {
|
||||
static const unsigned long kfc_clk_regs[] __initconst = {
|
||||
KFC_PLL_LOCK,
|
||||
KFC_PLL_CON0,
|
||||
KFC_PLL_CON1,
|
||||
@ -932,13 +932,13 @@ static unsigned long kfc_clk_regs[] __initdata = {
|
||||
PNAME(mout_kfc_pll_p) = {"fin_pll", "fout_kfc_pll"};
|
||||
PNAME(mout_kfc_p) = {"mout_kfc_pll", "dout_media_pll"};
|
||||
|
||||
static struct samsung_mux_clock kfc_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock kfc_mux_clks[] __initconst = {
|
||||
MUX(KFC_MOUT_KFC_PLL, "mout_kfc_pll", mout_kfc_pll_p,
|
||||
MUX_SEL_KFC0, 0, 1),
|
||||
MUX(KFC_MOUT_KFC, "mout_kfc", mout_kfc_p, MUX_SEL_KFC2, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock kfc_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock kfc_div_clks[] __initconst = {
|
||||
DIV(KFC_DOUT_KFC1, "dout_kfc1", "mout_kfc", DIV_KFC, 0, 3),
|
||||
DIV(KFC_DOUT_KFC2, "dout_kfc2", "dout_kfc1", DIV_KFC, 4, 3),
|
||||
DIV(KFC_DOUT_KFC_ATCLK, "dout_kfc_atclk", "dout_kfc2", DIV_KFC, 8, 3),
|
||||
@ -949,7 +949,7 @@ static struct samsung_div_clock kfc_div_clks[] __initdata = {
|
||||
DIV(KFC_DOUT_KFC_PLL, "dout_kfc_pll", "mout_kfc", DIV_KFC, 24, 3),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock kfc_pll_clks[] __initdata = {
|
||||
static const struct samsung_pll_clock kfc_pll_clks[] __initconst = {
|
||||
PLL(pll_2550xx, KFC_FOUT_KFC_PLL, "fout_kfc_pll", "fin_pll",
|
||||
KFC_PLL_LOCK, KFC_PLL_CON0,
|
||||
pll2550_24mhz_tbl),
|
||||
@ -978,7 +978,7 @@ CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
|
||||
|
||||
/* CMU_MFC */
|
||||
|
||||
static unsigned long mfc_clk_regs[] __initdata = {
|
||||
static const unsigned long mfc_clk_regs[] __initconst = {
|
||||
MUX_SEL_MFC,
|
||||
DIV_MFC,
|
||||
EN_ACLK_MFC,
|
||||
@ -991,18 +991,18 @@ static unsigned long mfc_clk_regs[] __initdata = {
|
||||
|
||||
PNAME(mout_aclk_mfc_333_user_p) = {"fin_pll", "dout_aclk_mfc_333"};
|
||||
|
||||
static struct samsung_mux_clock mfc_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
|
||||
MUX(MFC_MOUT_ACLK_MFC_333_USER, "mout_aclk_mfc_333_user",
|
||||
mout_aclk_mfc_333_user_p,
|
||||
MUX_SEL_MFC, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock mfc_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock mfc_div_clks[] __initconst = {
|
||||
DIV(MFC_DOUT_PCLK_MFC_83, "dout_pclk_mfc_83", "mout_aclk_mfc_333_user",
|
||||
DIV_MFC, 0, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock mfc_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
|
||||
GATE(MFC_CLK_MFC, "clk_mfc", "mout_aclk_mfc_333_user",
|
||||
EN_IP_MFC, 1, 0, 0),
|
||||
GATE(MFC_CLK_SMMU2_MFCM0, "clk_smmu2_mfcm0", "mout_aclk_mfc_333_user",
|
||||
@ -1034,7 +1034,7 @@ CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
|
||||
|
||||
/* CMU_MIF */
|
||||
|
||||
static unsigned long mif_clk_regs[] __initdata = {
|
||||
static const unsigned long mif_clk_regs[] __initconst = {
|
||||
MEM_PLL_LOCK,
|
||||
BUS_PLL_LOCK,
|
||||
MEDIA_PLL_LOCK,
|
||||
@ -1076,7 +1076,7 @@ PNAME(mout_mif_drex2x_p) = {"dout_mem_pll", "dout_bus_pll"};
|
||||
PNAME(mout_clkm_phy_p) = {"mout_mif_drex", "dout_media_pll"};
|
||||
PNAME(mout_clk2x_phy_p) = {"mout_mif_drex2x", "dout_media_pll"};
|
||||
|
||||
static struct samsung_mux_clock mif_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock mif_mux_clks[] __initconst = {
|
||||
MUX(MIF_MOUT_MEM_PLL, "mout_mem_pll", mout_mem_pll_p,
|
||||
MUX_SEL_MIF, 0, 1),
|
||||
MUX(MIF_MOUT_BUS_PLL, "mout_bus_pll", mout_bus_pll_p,
|
||||
@ -1093,7 +1093,7 @@ static struct samsung_mux_clock mif_mux_clks[] __initdata = {
|
||||
MUX_SEL_MIF, 24, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock mif_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock mif_div_clks[] __initconst = {
|
||||
DIV(MIF_DOUT_MEDIA_PLL, "dout_media_pll", "mout_media_pll",
|
||||
DIV_MIF, 0, 3),
|
||||
DIV(MIF_DOUT_MEM_PLL, "dout_mem_pll", "mout_mem_pll",
|
||||
@ -1112,7 +1112,7 @@ static struct samsung_div_clock mif_div_clks[] __initdata = {
|
||||
DIV_MIF, 28, 4),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock mif_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock mif_gate_clks[] __initconst = {
|
||||
GATE(MIF_CLK_LPDDR3PHY_WRAP0, "clk_lpddr3phy_wrap0", "dout_clk2x_phy",
|
||||
EN_IP_MIF, 12, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(MIF_CLK_LPDDR3PHY_WRAP1, "clk_lpddr3phy_wrap1", "dout_clk2x_phy",
|
||||
@ -1146,7 +1146,7 @@ static struct samsung_gate_clock mif_gate_clks[] __initdata = {
|
||||
CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock mif_pll_clks[] __initdata = {
|
||||
static const struct samsung_pll_clock mif_pll_clks[] __initconst = {
|
||||
PLL(pll_2550xx, MIF_FOUT_MEM_PLL, "fout_mem_pll", "fin_pll",
|
||||
MEM_PLL_LOCK, MEM_PLL_CON0,
|
||||
pll2550_24mhz_tbl),
|
||||
@ -1183,7 +1183,7 @@ CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
|
||||
|
||||
/* CMU_PERI */
|
||||
|
||||
static unsigned long peri_clk_regs[] __initdata = {
|
||||
static const unsigned long peri_clk_regs[] __initconst = {
|
||||
MUX_SEL_PERI,
|
||||
MUX_SEL_PERI1,
|
||||
DIV_PERI,
|
||||
@ -1219,7 +1219,7 @@ PNAME(mout_sclk_i2scod_p) = {"ioclk_i2s_cdclk", "fin_pll", "dout_aclk_peri_aud",
|
||||
PNAME(mout_sclk_spdif_p) = {"ioclk_spdif_extclk", "fin_pll",
|
||||
"dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"};
|
||||
|
||||
static struct samsung_mux_clock peri_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
|
||||
MUX(PERI_MOUT_SCLK_PCM, "mout_sclk_pcm", mout_sclk_pcm_p,
|
||||
MUX_SEL_PERI1, 4, 2),
|
||||
MUX(PERI_MOUT_SCLK_I2SCOD, "mout_sclk_i2scod", mout_sclk_i2scod_p,
|
||||
@ -1228,12 +1228,12 @@ static struct samsung_mux_clock peri_mux_clks[] __initdata = {
|
||||
MUX_SEL_PERI1, 20, 2),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock peri_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock peri_div_clks[] __initconst = {
|
||||
DIV(PERI_DOUT_PCM, "dout_pcm", "mout_sclk_pcm", DIV_PERI, 0, 8),
|
||||
DIV(PERI_DOUT_I2S, "dout_i2s", "mout_sclk_i2scod", DIV_PERI, 8, 6),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock peri_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
|
||||
GATE(PERI_SCLK_PCM1, "sclk_pcm1", "dout_pcm", EN_SCLK_PERI, 0,
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
GATE(PERI_SCLK_I2S, "sclk_i2s", "dout_i2s", EN_SCLK_PERI, 1,
|
||||
@ -1389,7 +1389,7 @@ CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
|
||||
|
||||
/* CMU_TOP */
|
||||
|
||||
static unsigned long top_clk_regs[] __initdata = {
|
||||
static const unsigned long top_clk_regs[] __initconst = {
|
||||
DISP_PLL_LOCK,
|
||||
AUD_PLL_LOCK,
|
||||
DISP_PLL_CON0,
|
||||
@ -1430,7 +1430,7 @@ static unsigned long top_clk_regs[] __initdata = {
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
static struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock fixed_rate_clks[] __initconst = {
|
||||
FRATE(PHYCLK_DPTX_PHY_CH3_TXD_CLK, "phyclk_dptx_phy_ch3_txd_clk", NULL,
|
||||
0, 270000000),
|
||||
FRATE(PHYCLK_DPTX_PHY_CH2_TXD_CLK, "phyclk_dptx_phy_ch2_txd_clk", NULL,
|
||||
@ -1513,7 +1513,7 @@ PNAME(mout_sclk_fsys_mmc1_sdclkin_b_p) = {"mout_sclk_fsys_mmc1_sdclkin_a",
|
||||
PNAME(mout_sclk_fsys_mmc2_sdclkin_b_p) = {"mout_sclk_fsys_mmc2_sdclkin_a",
|
||||
"mout_mediatop_pll_user"};
|
||||
|
||||
static struct samsung_mux_clock top_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock top_mux_clks[] __initconst = {
|
||||
MUX(TOP_MOUT_MEDIATOP_PLL_USER, "mout_mediatop_pll_user",
|
||||
mout_mediatop_pll_user_p,
|
||||
MUX_SEL_TOP_PLL0, 0, 1),
|
||||
@ -1673,7 +1673,7 @@ static struct samsung_mux_clock top_mux_clks[] __initdata = {
|
||||
MUX_SEL_TOP_GSCL, 20, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock top_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock top_div_clks[] __initconst = {
|
||||
DIV(TOP_DOUT_ACLK_G2D_333, "dout_aclk_g2d_333", "mout_aclk_g2d_333",
|
||||
DIV_TOP_G2D_MFC, 0, 3),
|
||||
DIV(TOP_DOUT_ACLK_MFC_333, "dout_aclk_mfc_333", "mout_aclk_mfc_333",
|
||||
@ -1794,7 +1794,7 @@ static struct samsung_div_clock top_div_clks[] __initdata = {
|
||||
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock top_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock top_gate_clks[] __initconst = {
|
||||
GATE(TOP_SCLK_MMC0, "sclk_fsys_mmc0_sdclkin",
|
||||
"dout_sclk_fsys_mmc0_sdclkin_b",
|
||||
EN_SCLK_TOP, 7, CLK_SET_RATE_PARENT, 0),
|
||||
@ -1809,7 +1809,7 @@ static struct samsung_gate_clock top_gate_clks[] __initdata = {
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock top_pll_clks[] __initdata = {
|
||||
static const struct samsung_pll_clock top_pll_clks[] __initconst = {
|
||||
PLL(pll_2550xx, TOP_FOUT_DISP_PLL, "fout_disp_pll", "fin_pll",
|
||||
DISP_PLL_LOCK, DISP_PLL_CON0,
|
||||
pll2550_24mhz_tbl),
|
||||
|
@ -31,11 +31,14 @@
|
||||
#define SRC_CPU 0x200
|
||||
#define DIV_CPU0 0x500
|
||||
#define SRC_CPERI1 0x4204
|
||||
#define GATE_IP_G2D 0x8800
|
||||
#define DIV_TOP0 0x10510
|
||||
#define DIV_TOP1 0x10514
|
||||
#define DIV_FSYS0 0x10548
|
||||
#define DIV_FSYS1 0x1054c
|
||||
#define DIV_FSYS2 0x10550
|
||||
#define DIV_PERIC0 0x10558
|
||||
#define DIV_PERIC3 0x10564
|
||||
#define SRC_TOP0 0x10210
|
||||
#define SRC_TOP1 0x10214
|
||||
#define SRC_TOP2 0x10218
|
||||
@ -44,6 +47,8 @@
|
||||
#define SRC_MASK_FSYS 0x10340
|
||||
#define SRC_MASK_PERIC0 0x10350
|
||||
#define GATE_BUS_FSYS0 0x10740
|
||||
#define GATE_TOP_SCLK_FSYS 0x10840
|
||||
#define GATE_TOP_SCLK_PERIC 0x10850
|
||||
#define GATE_IP_FSYS 0x10944
|
||||
#define GATE_IP_PERIC 0x10950
|
||||
#define GATE_IP_PERIS 0x10960
|
||||
@ -71,12 +76,13 @@ PNAME(mout_kfc_p) = { "mout_kpll", "sclk_mpll", };
|
||||
PNAME(mpll_user_p) = { "fin_pll", "sclk_mpll", };
|
||||
PNAME(bpll_user_p) = { "fin_pll", "sclk_bpll", };
|
||||
PNAME(mpll_bpll_p) = { "sclk_mpll_muxed", "sclk_bpll_muxed", };
|
||||
PNAME(sclk_mpll_bpll_p) = { "sclk_mpll_bpll", "fin_pll", };
|
||||
|
||||
PNAME(group2_p) = { "fin_pll", "fin_pll", "none", "none",
|
||||
"none", "none", "sclk_mpll_bpll",
|
||||
"none", "none", "sclk_cpll" };
|
||||
|
||||
static struct samsung_mux_clock exynos5410_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5410_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_apll", apll_p, SRC_CPU, 0, 1),
|
||||
MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
|
||||
|
||||
@ -96,16 +102,20 @@ static struct samsung_mux_clock exynos5410_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_mmc0", group2_p, SRC_FSYS, 0, 4),
|
||||
MUX(0, "mout_mmc1", group2_p, SRC_FSYS, 4, 4),
|
||||
MUX(0, "mout_mmc2", group2_p, SRC_FSYS, 8, 4),
|
||||
MUX(0, "mout_usbd300", sclk_mpll_bpll_p, SRC_FSYS, 28, 1),
|
||||
MUX(0, "mout_usbd301", sclk_mpll_bpll_p, SRC_FSYS, 29, 1),
|
||||
|
||||
MUX(0, "mout_uart0", group2_p, SRC_PERIC0, 0, 4),
|
||||
MUX(0, "mout_uart1", group2_p, SRC_PERIC0, 4, 4),
|
||||
MUX(0, "mout_uart2", group2_p, SRC_PERIC0, 8, 4),
|
||||
MUX(0, "mout_uart3", group2_p, SRC_PERIC0, 12, 4),
|
||||
MUX(0, "mout_pwm", group2_p, SRC_PERIC0, 24, 4),
|
||||
|
||||
MUX(0, "mout_aclk200", mpll_bpll_p, SRC_TOP0, 12, 1),
|
||||
MUX(0, "mout_aclk400", mpll_bpll_p, SRC_TOP0, 20, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos5410_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos5410_div_clks[] __initconst = {
|
||||
DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
|
||||
DIV(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3),
|
||||
|
||||
@ -121,6 +131,11 @@ static struct samsung_div_clock exynos5410_div_clks[] __initdata = {
|
||||
DIV(0, "aclk66_pre", "sclk_mpll_muxed", DIV_TOP1, 24, 3),
|
||||
DIV(0, "aclk66", "aclk66_pre", DIV_TOP0, 0, 3),
|
||||
|
||||
DIV(0, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4),
|
||||
DIV(0, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 20, 4),
|
||||
DIV(0, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4),
|
||||
DIV(0, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 28, 4),
|
||||
|
||||
DIV(0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
|
||||
DIV(0, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
|
||||
DIV(0, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
|
||||
@ -137,12 +152,19 @@ static struct samsung_div_clock exynos5410_div_clks[] __initdata = {
|
||||
DIV(0, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4),
|
||||
DIV(0, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4),
|
||||
|
||||
DIV(0, "dout_pwm", "mout_pwm", DIV_PERIC3, 0, 4),
|
||||
|
||||
DIV(0, "aclk200", "mout_aclk200", DIV_TOP0, 12, 3),
|
||||
DIV(0, "aclk266", "mpll_user_p", DIV_TOP0, 16, 3),
|
||||
DIV(0, "aclk400", "mout_aclk400", DIV_TOP0, 24, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock exynos5410_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos5410_gate_clks[] __initconst = {
|
||||
GATE(CLK_SSS, "sss", "aclk266", GATE_IP_G2D, 2, 0, 0),
|
||||
GATE(CLK_MCT, "mct", "aclk66", GATE_IP_PERIS, 18, 0, 0),
|
||||
GATE(CLK_WDT, "wdt", "aclk66", GATE_IP_PERIS, 19, 0, 0),
|
||||
GATE(CLK_RTC, "rtc", "aclk66", GATE_IP_PERIS, 20, 0, 0),
|
||||
GATE(CLK_TMU, "tmu", "aclk66", GATE_IP_PERIS, 21, 0, 0),
|
||||
|
||||
GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc_pre0",
|
||||
SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
|
||||
@ -155,9 +177,31 @@ static struct samsung_gate_clock exynos5410_gate_clks[] __initdata = {
|
||||
GATE(CLK_MMC1, "sdmmc1", "aclk200", GATE_BUS_FSYS0, 13, 0, 0),
|
||||
GATE(CLK_MMC2, "sdmmc2", "aclk200", GATE_BUS_FSYS0, 14, 0, 0),
|
||||
|
||||
GATE(CLK_SCLK_USBPHY301, "sclk_usbphy301", "dout_usbphy301",
|
||||
GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_SCLK_USBPHY300, "sclk_usbphy300", "dout_usbphy300",
|
||||
GATE_TOP_SCLK_FSYS, 8, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_SCLK_USBD300, "sclk_usbd300", "dout_usbd300",
|
||||
GATE_TOP_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_SCLK_USBD301, "sclk_usbd301", "dout_usbd301",
|
||||
GATE_TOP_SCLK_FSYS, 10, CLK_SET_RATE_PARENT, 0),
|
||||
|
||||
GATE(CLK_SCLK_PWM, "sclk_pwm", "dout_pwm",
|
||||
GATE_TOP_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0),
|
||||
|
||||
GATE(CLK_UART0, "uart0", "aclk66", GATE_IP_PERIC, 0, 0, 0),
|
||||
GATE(CLK_UART1, "uart1", "aclk66", GATE_IP_PERIC, 1, 0, 0),
|
||||
GATE(CLK_UART2, "uart2", "aclk66", GATE_IP_PERIC, 2, 0, 0),
|
||||
GATE(CLK_UART3, "uart3", "aclk66", GATE_IP_PERIC, 3, 0, 0),
|
||||
GATE(CLK_I2C0, "i2c0", "aclk66", GATE_IP_PERIC, 6, 0, 0),
|
||||
GATE(CLK_I2C1, "i2c1", "aclk66", GATE_IP_PERIC, 7, 0, 0),
|
||||
GATE(CLK_I2C2, "i2c2", "aclk66", GATE_IP_PERIC, 8, 0, 0),
|
||||
GATE(CLK_I2C3, "i2c3", "aclk66", GATE_IP_PERIC, 9, 0, 0),
|
||||
GATE(CLK_USI0, "usi0", "aclk66", GATE_IP_PERIC, 10, 0, 0),
|
||||
GATE(CLK_USI1, "usi1", "aclk66", GATE_IP_PERIC, 11, 0, 0),
|
||||
GATE(CLK_USI2, "usi2", "aclk66", GATE_IP_PERIC, 12, 0, 0),
|
||||
GATE(CLK_USI3, "usi3", "aclk66", GATE_IP_PERIC, 13, 0, 0),
|
||||
GATE(CLK_PWM, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0),
|
||||
|
||||
GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
|
||||
SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0),
|
||||
@ -165,9 +209,15 @@ static struct samsung_gate_clock exynos5410_gate_clks[] __initdata = {
|
||||
SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
|
||||
SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_SCLK_UART3, "sclk_uart3", "div_uart3",
|
||||
SRC_MASK_PERIC0, 12, CLK_SET_RATE_PARENT, 0),
|
||||
|
||||
GATE(CLK_USBH20, "usbh20", "aclk200_fsys", GATE_IP_FSYS, 18, 0, 0),
|
||||
GATE(CLK_USBD300, "usbd300", "aclk200_fsys", GATE_IP_FSYS, 19, 0, 0),
|
||||
GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_IP_FSYS, 20, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = {
|
||||
static const struct samsung_pll_clock exynos5410_plls[nr_plls] __initconst = {
|
||||
[apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
|
||||
APLL_CON0, NULL),
|
||||
[cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK,
|
||||
|
@ -160,7 +160,7 @@ static struct samsung_clk_reg_dump *exynos5800_save;
|
||||
* list of controller registers to be saved and restored during a
|
||||
* suspend/resume cycle.
|
||||
*/
|
||||
static unsigned long exynos5x_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos5x_clk_regs[] __initconst = {
|
||||
SRC_CPU,
|
||||
DIV_CPU0,
|
||||
DIV_CPU1,
|
||||
@ -248,7 +248,7 @@ static unsigned long exynos5x_clk_regs[] __initdata = {
|
||||
DIV_KFC0,
|
||||
};
|
||||
|
||||
static unsigned long exynos5800_clk_regs[] __initdata = {
|
||||
static const unsigned long exynos5800_clk_regs[] __initconst = {
|
||||
SRC_TOP8,
|
||||
SRC_TOP9,
|
||||
SRC_CAM,
|
||||
@ -306,7 +306,7 @@ static struct syscore_ops exynos5420_clk_syscore_ops = {
|
||||
.resume = exynos5420_clk_resume,
|
||||
};
|
||||
|
||||
static void exynos5420_clk_sleep_init(void)
|
||||
static void __init exynos5420_clk_sleep_init(void)
|
||||
{
|
||||
exynos5x_save = samsung_clk_alloc_reg_dump(exynos5x_clk_regs,
|
||||
ARRAY_SIZE(exynos5x_clk_regs));
|
||||
@ -333,7 +333,7 @@ err_soc:
|
||||
return;
|
||||
}
|
||||
#else
|
||||
static void exynos5420_clk_sleep_init(void) {}
|
||||
static void __init exynos5420_clk_sleep_init(void) {}
|
||||
#endif
|
||||
|
||||
/* list of all parent clocks */
|
||||
@ -484,7 +484,7 @@ static struct samsung_fixed_rate_clock
|
||||
};
|
||||
|
||||
/* fixed rate clocks generated inside the soc */
|
||||
static struct samsung_fixed_rate_clock exynos5x_fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock exynos5x_fixed_rate_clks[] __initconst = {
|
||||
FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 24000000),
|
||||
FRATE(0, "sclk_pwi", NULL, 0, 24000000),
|
||||
FRATE(0, "sclk_usbh20", NULL, 0, 48000000),
|
||||
@ -492,19 +492,19 @@ static struct samsung_fixed_rate_clock exynos5x_fixed_rate_clks[] __initdata = {
|
||||
FRATE(0, "sclk_usbh20_scan_clk", NULL, 0, 480000000),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock
|
||||
exynos5x_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock
|
||||
exynos5x_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "ff_hsic_12m", "fin_pll", 1, 2, 0),
|
||||
FFACTOR(0, "ff_sw_aclk66", "mout_sw_aclk66", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock
|
||||
exynos5800_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock
|
||||
exynos5800_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "ff_dout_epll2", "mout_sclk_epll", 1, 2, 0),
|
||||
FFACTOR(0, "ff_dout_spll2", "mout_sclk_spll", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos5800_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5800_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_aclk400_isp", mout_group3_5800_p, SRC_TOP0, 0, 3),
|
||||
MUX(0, "mout_aclk400_mscl", mout_group3_5800_p, SRC_TOP0, 4, 3),
|
||||
MUX(0, "mout_aclk400_wcore", mout_group2_5800_p, SRC_TOP0, 16, 3),
|
||||
@ -553,7 +553,7 @@ static struct samsung_mux_clock exynos5800_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_fimd1", mout_group2_p, SRC_DISP10, 4, 3),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos5800_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos5800_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore",
|
||||
"mout_aclk400_wcore", DIV_TOP0, 16, 3),
|
||||
DIV(0, "dout_aclk550_cam", "mout_aclk550_cam",
|
||||
@ -569,14 +569,14 @@ static struct samsung_div_clock exynos5800_div_clks[] __initdata = {
|
||||
DIV(0, "dout_sclk_sw", "sclk_spll", DIV_TOP9, 24, 6),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock exynos5800_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = {
|
||||
GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam",
|
||||
GATE_BUS_TOP, 24, 0, 0),
|
||||
GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler",
|
||||
GATE_BUS_TOP, 27, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = {
|
||||
MUX(0, "sclk_bpll", mout_bpll_p, TOP_SPARE2, 0, 1),
|
||||
MUX(0, "mout_aclk400_wcore_bpll", mout_aclk400_wcore_bpll_p,
|
||||
TOP_SPARE2, 4, 1),
|
||||
@ -606,12 +606,12 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos5420_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos5420_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore",
|
||||
"mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3),
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p,
|
||||
SRC_TOP7, 4, 1),
|
||||
MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2),
|
||||
@ -778,7 +778,7 @@ static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_isp_sensor", mout_group2_p, SRC_ISP, 28, 3),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock exynos5x_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos5x_div_clks[] __initconst = {
|
||||
DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
|
||||
DIV(0, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
|
||||
DIV(0, "armclk2", "div_arm", DIV_CPU0, 28, 3),
|
||||
@ -911,7 +911,7 @@ static struct samsung_div_clock exynos5x_div_clks[] __initdata = {
|
||||
CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
|
||||
/* G2D */
|
||||
GATE(CLK_MDMA0, "mdma0", "aclk266_g2d", GATE_IP_G2D, 1, 0, 0),
|
||||
GATE(CLK_SSS, "sss", "aclk266_g2d", GATE_IP_G2D, 2, 0, 0),
|
||||
@ -946,7 +946,7 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
|
||||
GATE_BUS_TOP, 13, 0, 0),
|
||||
GATE(0, "aclk166", "mout_user_aclk166",
|
||||
GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(0, "aclk333", "mout_user_aclk333",
|
||||
GATE(CLK_ACLK333, "aclk333", "mout_user_aclk333",
|
||||
GATE_BUS_TOP, 15, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(0, "aclk400_isp", "mout_user_aclk400_isp",
|
||||
GATE_BUS_TOP, 16, 0, 0),
|
||||
@ -1219,7 +1219,7 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
|
||||
GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] = {
|
||||
static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] __initconst = {
|
||||
PLL_35XX_RATE(2000000000, 250, 3, 0),
|
||||
PLL_35XX_RATE(1900000000, 475, 6, 0),
|
||||
PLL_35XX_RATE(1800000000, 225, 3, 0),
|
||||
@ -1356,8 +1356,6 @@ static void __init exynos5x_clk_init(struct device_node *np,
|
||||
exynos5x_soc = soc;
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
samsung_clk_of_register_fixed_ext(ctx, exynos5x_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos5x_fixed_rate_ext_clks),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initda
|
||||
};
|
||||
|
||||
/* fixed rate clocks */
|
||||
static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initconst = {
|
||||
FRATE(0, "ppll", NULL, 0, 1000000000),
|
||||
FRATE(0, "usb_phy0", NULL, 0, 60000000),
|
||||
FRATE(0, "usb_phy1", NULL, 0, 60000000),
|
||||
@ -44,26 +44,26 @@ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata =
|
||||
};
|
||||
|
||||
/* fixed factor clocks */
|
||||
static struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "div250", "ppll", 1, 4, 0),
|
||||
FFACTOR(0, "div200", "ppll", 1, 5, 0),
|
||||
FFACTOR(0, "div125", "div250", 1, 2, 0),
|
||||
};
|
||||
|
||||
/* mux clocks */
|
||||
static struct samsung_mux_clock exynos5440_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock exynos5440_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
|
||||
MUX_A(CLK_ARM_CLK, "arm_clk", mout_armclk_p,
|
||||
CPU_CLK_STATUS, 0, 1, "armclk"),
|
||||
};
|
||||
|
||||
/* divider clocks */
|
||||
static struct samsung_div_clock exynos5440_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock exynos5440_div_clks[] __initconst = {
|
||||
DIV(CLK_SPI_BAUD, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
|
||||
};
|
||||
|
||||
/* gate clocks */
|
||||
static struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock exynos5440_gate_clks[] __initconst = {
|
||||
GATE(CLK_PB0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0),
|
||||
GATE(CLK_PR0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0),
|
||||
GATE(CLK_PR1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0),
|
||||
@ -125,8 +125,6 @@ static void __init exynos5440_clk_init(struct device_node *np)
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
samsung_clk_of_register_fixed_ext(ctx, exynos5440_fixed_rate_ext_clks,
|
||||
ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match);
|
||||
|
@ -36,7 +36,7 @@
|
||||
#define ENABLE_ACLK_TOPC1 0x0804
|
||||
#define ENABLE_SCLK_TOPC1 0x0A04
|
||||
|
||||
static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_topc_bus0_pll", 1, 2, 0),
|
||||
FFACTOR(0, "ffac_topc_bus0_pll_div4",
|
||||
"ffac_topc_bus0_pll_div2", 1, 2, 0),
|
||||
@ -69,7 +69,7 @@ PNAME(mout_topc_mfc_pll_half_p) = { "mout_topc_mfc_pll",
|
||||
PNAME(mout_topc_bus0_pll_out_p) = {"mout_topc_bus0_pll",
|
||||
"ffac_topc_bus0_pll_div2"};
|
||||
|
||||
static unsigned long topc_clk_regs[] __initdata = {
|
||||
static const unsigned long topc_clk_regs[] __initconst = {
|
||||
CC_PLL_LOCK,
|
||||
BUS0_PLL_LOCK,
|
||||
BUS1_DPLL_LOCK,
|
||||
@ -89,7 +89,7 @@ static unsigned long topc_clk_regs[] __initdata = {
|
||||
DIV_TOPC3,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock topc_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock topc_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_topc_bus0_pll", mout_topc_bus0_pll_ctrl_p,
|
||||
MUX_SEL_TOPC0, 0, 1),
|
||||
MUX(0, "mout_topc_bus1_pll", mout_topc_bus1_pll_ctrl_p,
|
||||
@ -118,7 +118,7 @@ static struct samsung_mux_clock topc_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_aclk_peris_66", mout_topc_group2, MUX_SEL_TOPC3, 24, 2),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock topc_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock topc_div_clks[] __initconst = {
|
||||
DIV(DOUT_ACLK_CCORE_133, "dout_aclk_ccore_133", "mout_aclk_ccore_133",
|
||||
DIV_TOPC0, 4, 4),
|
||||
|
||||
@ -139,14 +139,14 @@ static struct samsung_div_clock topc_div_clks[] __initdata = {
|
||||
DIV_TOPC3, 28, 4),
|
||||
};
|
||||
|
||||
static struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initdata = {
|
||||
static const struct samsung_pll_rate_table pll1460x_24mhz_tbl[] __initconst = {
|
||||
PLL_36XX_RATE(491520000, 20, 1, 0, 31457),
|
||||
{},
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock topc_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock topc_gate_clks[] __initconst = {
|
||||
GATE(ACLK_CCORE_133, "aclk_ccore_133", "dout_aclk_ccore_133",
|
||||
ENABLE_ACLK_TOPC0, 4, 0, 0),
|
||||
ENABLE_ACLK_TOPC0, 4, CLK_IS_CRITICAL, 0),
|
||||
|
||||
GATE(ACLK_MSCL_532, "aclk_mscl_532", "dout_aclk_mscl_532",
|
||||
ENABLE_ACLK_TOPC1, 20, 0, 0),
|
||||
@ -174,7 +174,7 @@ static struct samsung_gate_clock topc_gate_clks[] __initdata = {
|
||||
ENABLE_SCLK_TOPC1, 0, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_pll_clock topc_pll_clks[] __initdata = {
|
||||
static const struct samsung_pll_clock topc_pll_clks[] __initconst = {
|
||||
PLL(pll_1451x, 0, "fout_bus0_pll", "fin_pll", BUS0_PLL_LOCK,
|
||||
BUS0_PLL_CON0, NULL),
|
||||
PLL(pll_1452x, 0, "fout_cc_pll", "fin_pll", CC_PLL_LOCK,
|
||||
@ -187,7 +187,7 @@ static struct samsung_pll_clock topc_pll_clks[] __initdata = {
|
||||
AUD_PLL_CON0, pll1460x_24mhz_tbl),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info topc_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info topc_cmu_info __initconst = {
|
||||
.pll_clks = topc_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(topc_pll_clks),
|
||||
.mux_clks = topc_mux_clks,
|
||||
@ -256,7 +256,7 @@ PNAME(mout_top0_group3) = {"ioclk_audiocdclk0",
|
||||
PNAME(mout_top0_group4) = {"ioclk_audiocdclk1", "mout_top0_aud_pll_user",
|
||||
"mout_top0_bus0_pll_half", "mout_top0_bus1_pll_half"};
|
||||
|
||||
static unsigned long top0_clk_regs[] __initdata = {
|
||||
static const unsigned long top0_clk_regs[] __initconst = {
|
||||
MUX_SEL_TOP00,
|
||||
MUX_SEL_TOP01,
|
||||
MUX_SEL_TOP03,
|
||||
@ -275,7 +275,7 @@ static unsigned long top0_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_TOP0_PERIC3,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock top0_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock top0_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_top0_aud_pll_user", mout_top0_aud_pll_user_p,
|
||||
MUX_SEL_TOP00, 0, 1),
|
||||
MUX(0, "mout_top0_mfc_pll_user", mout_top0_mfc_pll_user_p,
|
||||
@ -315,7 +315,7 @@ static struct samsung_mux_clock top0_mux_clks[] __initdata = {
|
||||
MUX(0, "mout_sclk_spi4", mout_top0_group1, MUX_SEL_TOP0_PERIC3, 20, 2),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock top0_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock top0_div_clks[] __initconst = {
|
||||
DIV(DOUT_ACLK_PERIC1, "dout_aclk_peric1_66", "mout_aclk_peric1_66",
|
||||
DIV_TOP03, 12, 6),
|
||||
DIV(DOUT_ACLK_PERIC0, "dout_aclk_peric0_66", "mout_aclk_peric0_66",
|
||||
@ -338,7 +338,7 @@ static struct samsung_div_clock top0_div_clks[] __initdata = {
|
||||
DIV(0, "dout_sclk_spi4", "mout_sclk_spi4", DIV_TOP0_PERIC3, 20, 12),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock top0_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock top0_gate_clks[] __initconst = {
|
||||
GATE(CLK_ACLK_PERIC0_66, "aclk_peric0_66", "dout_aclk_peric0_66",
|
||||
ENABLE_ACLK_TOP03, 20, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_ACLK_PERIC1_66, "aclk_peric1_66", "dout_aclk_peric1_66",
|
||||
@ -372,7 +372,7 @@ static struct samsung_gate_clock top0_gate_clks[] __initdata = {
|
||||
ENABLE_SCLK_TOP0_PERIC3, 20, CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "ffac_top0_bus0_pll_div2", "mout_top0_bus0_pll_user",
|
||||
1, 2, 0),
|
||||
FFACTOR(0, "ffac_top0_bus1_pll_div2", "mout_top0_bus1_pll_user",
|
||||
@ -381,7 +381,7 @@ static struct samsung_fixed_factor_clock top0_fixed_factor_clks[] __initdata = {
|
||||
FFACTOR(0, "ffac_top0_mfc_pll_div2", "mout_top0_mfc_pll_user", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info top0_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info top0_cmu_info __initconst = {
|
||||
.mux_clks = top0_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(top0_mux_clks),
|
||||
.div_clks = top0_div_clks,
|
||||
@ -438,7 +438,7 @@ PNAME(mout_top1_group1) = {"mout_top1_bus0_pll_half",
|
||||
"mout_top1_bus1_pll_half", "mout_top1_cc_pll_half",
|
||||
"mout_top1_mfc_pll_half"};
|
||||
|
||||
static unsigned long top1_clk_regs[] __initdata = {
|
||||
static const unsigned long top1_clk_regs[] __initconst = {
|
||||
MUX_SEL_TOP10,
|
||||
MUX_SEL_TOP11,
|
||||
MUX_SEL_TOP13,
|
||||
@ -455,7 +455,7 @@ static unsigned long top1_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_TOP1_FSYS11,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock top1_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock top1_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_top1_mfc_pll_user", mout_top1_mfc_pll_user_p,
|
||||
MUX_SEL_TOP10, 4, 1),
|
||||
MUX(0, "mout_top1_cc_pll_user", mout_top1_cc_pll_user_p,
|
||||
@ -494,7 +494,7 @@ static struct samsung_mux_clock top1_mux_clks[] __initdata = {
|
||||
MUX_SEL_TOP1_FSYS11, 24, 2),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock top1_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock top1_div_clks[] __initconst = {
|
||||
DIV(DOUT_ACLK_FSYS1_200, "dout_aclk_fsys1_200", "mout_aclk_fsys1_200",
|
||||
DIV_TOP13, 24, 4),
|
||||
DIV(DOUT_ACLK_FSYS0_200, "dout_aclk_fsys0_200", "mout_aclk_fsys0_200",
|
||||
@ -521,7 +521,7 @@ static struct samsung_div_clock top1_div_clks[] __initdata = {
|
||||
"mout_sclk_phy_fsys1_26m", DIV_TOP1_FSYS11, 24, 6),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock top1_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock top1_gate_clks[] __initconst = {
|
||||
GATE(CLK_SCLK_MMC2, "sclk_mmc2", "dout_sclk_mmc2",
|
||||
ENABLE_SCLK_TOP1_FSYS0, 16, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(0, "sclk_usbdrd300", "dout_sclk_usbdrd300",
|
||||
@ -539,7 +539,8 @@ static struct samsung_gate_clock top1_gate_clks[] __initdata = {
|
||||
ENABLE_SCLK_TOP1_FSYS11, 12, CLK_SET_RATE_PARENT, 0),
|
||||
|
||||
GATE(CLK_ACLK_FSYS0_200, "aclk_fsys0_200", "dout_aclk_fsys0_200",
|
||||
ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT, 0),
|
||||
ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT |
|
||||
CLK_IS_CRITICAL, 0),
|
||||
GATE(CLK_ACLK_FSYS1_200, "aclk_fsys1_200", "dout_aclk_fsys1_200",
|
||||
ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT, 0),
|
||||
|
||||
@ -548,7 +549,7 @@ static struct samsung_gate_clock top1_gate_clks[] __initdata = {
|
||||
24, CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = {
|
||||
static const struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initconst = {
|
||||
FFACTOR(0, "ffac_top1_bus0_pll_div2", "mout_top1_bus0_pll_user",
|
||||
1, 2, 0),
|
||||
FFACTOR(0, "ffac_top1_bus1_pll_div2", "mout_top1_bus1_pll_user",
|
||||
@ -557,7 +558,7 @@ static struct samsung_fixed_factor_clock top1_fixed_factor_clks[] __initdata = {
|
||||
FFACTOR(0, "ffac_top1_mfc_pll_div2", "mout_top1_mfc_pll_user", 1, 2, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info top1_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info top1_cmu_info __initconst = {
|
||||
.mux_clks = top1_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(top1_mux_clks),
|
||||
.div_clks = top1_div_clks,
|
||||
@ -591,22 +592,22 @@ CLK_OF_DECLARE(exynos7_clk_top1, "samsung,exynos7-clock-top1",
|
||||
*/
|
||||
PNAME(mout_aclk_ccore_133_user_p) = { "fin_pll", "aclk_ccore_133" };
|
||||
|
||||
static unsigned long ccore_clk_regs[] __initdata = {
|
||||
static const unsigned long ccore_clk_regs[] __initconst = {
|
||||
MUX_SEL_CCORE,
|
||||
ENABLE_PCLK_CCORE,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock ccore_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock ccore_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_aclk_ccore_133_user", mout_aclk_ccore_133_user_p,
|
||||
MUX_SEL_CCORE, 1, 1),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock ccore_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock ccore_gate_clks[] __initconst = {
|
||||
GATE(PCLK_RTC, "pclk_rtc", "mout_aclk_ccore_133_user",
|
||||
ENABLE_PCLK_CCORE, 8, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info ccore_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info ccore_cmu_info __initconst = {
|
||||
.mux_clks = ccore_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(ccore_mux_clks),
|
||||
.gate_clks = ccore_gate_clks,
|
||||
@ -633,20 +634,20 @@ CLK_OF_DECLARE(exynos7_clk_ccore, "samsung,exynos7-clock-ccore",
|
||||
PNAME(mout_aclk_peric0_66_user_p) = { "fin_pll", "aclk_peric0_66" };
|
||||
PNAME(mout_sclk_uart0_user_p) = { "fin_pll", "sclk_uart0" };
|
||||
|
||||
static unsigned long peric0_clk_regs[] __initdata = {
|
||||
static const unsigned long peric0_clk_regs[] __initconst = {
|
||||
MUX_SEL_PERIC0,
|
||||
ENABLE_PCLK_PERIC0,
|
||||
ENABLE_SCLK_PERIC0,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock peric0_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock peric0_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_aclk_peric0_66_user", mout_aclk_peric0_66_user_p,
|
||||
MUX_SEL_PERIC0, 0, 1),
|
||||
MUX(0, "mout_sclk_uart0_user", mout_sclk_uart0_user_p,
|
||||
MUX_SEL_PERIC0, 16, 1),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock peric0_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
|
||||
GATE(PCLK_HSI2C0, "pclk_hsi2c0", "mout_aclk_peric0_66_user",
|
||||
ENABLE_PCLK_PERIC0, 8, 0, 0),
|
||||
GATE(PCLK_HSI2C1, "pclk_hsi2c1", "mout_aclk_peric0_66_user",
|
||||
@ -673,7 +674,7 @@ static struct samsung_gate_clock peric0_gate_clks[] __initdata = {
|
||||
GATE(SCLK_PWM, "sclk_pwm", "fin_pll", ENABLE_SCLK_PERIC0, 21, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info peric0_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info peric0_cmu_info __initconst = {
|
||||
.mux_clks = peric0_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(peric0_mux_clks),
|
||||
.gate_clks = peric0_gate_clks,
|
||||
@ -709,7 +710,7 @@ PNAME(mout_sclk_spi2_user_p) = { "fin_pll", "sclk_spi2" };
|
||||
PNAME(mout_sclk_spi3_user_p) = { "fin_pll", "sclk_spi3" };
|
||||
PNAME(mout_sclk_spi4_user_p) = { "fin_pll", "sclk_spi4" };
|
||||
|
||||
static unsigned long peric1_clk_regs[] __initdata = {
|
||||
static const unsigned long peric1_clk_regs[] __initconst = {
|
||||
MUX_SEL_PERIC10,
|
||||
MUX_SEL_PERIC11,
|
||||
MUX_SEL_PERIC12,
|
||||
@ -717,7 +718,7 @@ static unsigned long peric1_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_PERIC10,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock peric1_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_aclk_peric1_66_user", mout_aclk_peric1_66_user_p,
|
||||
MUX_SEL_PERIC10, 0, 1),
|
||||
|
||||
@ -739,7 +740,7 @@ static struct samsung_mux_clock peric1_mux_clks[] __initdata = {
|
||||
MUX_SEL_PERIC11, 28, 1),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock peric1_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock peric1_gate_clks[] __initconst = {
|
||||
GATE(PCLK_HSI2C2, "pclk_hsi2c2", "mout_aclk_peric1_66_user",
|
||||
ENABLE_PCLK_PERIC1, 4, 0, 0),
|
||||
GATE(PCLK_HSI2C3, "pclk_hsi2c3", "mout_aclk_peric1_66_user",
|
||||
@ -797,7 +798,7 @@ static struct samsung_gate_clock peric1_gate_clks[] __initdata = {
|
||||
ENABLE_SCLK_PERIC10, 19, CLK_SET_RATE_PARENT, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info peric1_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info peric1_cmu_info __initconst = {
|
||||
.mux_clks = peric1_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(peric1_mux_clks),
|
||||
.gate_clks = peric1_gate_clks,
|
||||
@ -825,7 +826,7 @@ CLK_OF_DECLARE(exynos7_clk_peric1, "samsung,exynos7-clock-peric1",
|
||||
/* List of parent clocks for Muxes in CMU_PERIS */
|
||||
PNAME(mout_aclk_peris_66_user_p) = { "fin_pll", "aclk_peris_66" };
|
||||
|
||||
static unsigned long peris_clk_regs[] __initdata = {
|
||||
static const unsigned long peris_clk_regs[] __initconst = {
|
||||
MUX_SEL_PERIS,
|
||||
ENABLE_PCLK_PERIS,
|
||||
ENABLE_PCLK_PERIS_SECURE_CHIPID,
|
||||
@ -833,12 +834,12 @@ static unsigned long peris_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_PERIS_SECURE_CHIPID,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock peris_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock peris_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_aclk_peris_66_user",
|
||||
mout_aclk_peris_66_user_p, MUX_SEL_PERIS, 0, 1),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock peris_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock peris_gate_clks[] __initconst = {
|
||||
GATE(PCLK_WDT, "pclk_wdt", "mout_aclk_peris_66_user",
|
||||
ENABLE_PCLK_PERIS, 6, 0, 0),
|
||||
GATE(PCLK_TMU, "pclk_tmu_apbif", "mout_aclk_peris_66_user",
|
||||
@ -852,7 +853,7 @@ static struct samsung_gate_clock peris_gate_clks[] __initdata = {
|
||||
GATE(SCLK_TMU, "sclk_tmu", "fin_pll", ENABLE_SCLK_PERIS, 10, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info peris_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info peris_cmu_info __initconst = {
|
||||
.mux_clks = peris_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(peris_mux_clks),
|
||||
.gate_clks = peris_gate_clks,
|
||||
@ -893,12 +894,12 @@ PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p) = { "fin_pll",
|
||||
"phyclk_usbdrd300_udrd30_pipe_pclk" };
|
||||
|
||||
/* fixed rate clocks used in the FSYS0 block */
|
||||
static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initconst = {
|
||||
FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, 0, 60000000),
|
||||
FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, 0, 125000000),
|
||||
};
|
||||
|
||||
static unsigned long fsys0_clk_regs[] __initdata = {
|
||||
static const unsigned long fsys0_clk_regs[] __initconst = {
|
||||
MUX_SEL_FSYS00,
|
||||
MUX_SEL_FSYS01,
|
||||
MUX_SEL_FSYS02,
|
||||
@ -909,7 +910,7 @@ static unsigned long fsys0_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_FSYS04,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_aclk_fsys0_200_user", mout_aclk_fsys0_200_user_p,
|
||||
MUX_SEL_FSYS00, 24, 1),
|
||||
|
||||
@ -926,7 +927,7 @@ static struct samsung_mux_clock fsys0_mux_clks[] __initdata = {
|
||||
MUX_SEL_FSYS02, 28, 1),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
|
||||
GATE(ACLK_PDMA1, "aclk_pdma1", "mout_aclk_fsys0_200_user",
|
||||
ENABLE_ACLK_FSYS00, 3, 0, 0),
|
||||
GATE(ACLK_PDMA0, "aclk_pdma0", "mout_aclk_fsys0_200_user",
|
||||
@ -960,7 +961,7 @@ static struct samsung_gate_clock fsys0_gate_clks[] __initdata = {
|
||||
ENABLE_SCLK_FSYS04, 28, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info fsys0_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
|
||||
.fixed_clks = fixed_rate_clks_fsys0,
|
||||
.nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys0),
|
||||
.mux_clks = fsys0_mux_clks,
|
||||
@ -1005,7 +1006,7 @@ PNAME(mout_phyclk_ufs20_rx0_user_p) = { "fin_pll", "phyclk_ufs20_rx0_symbol" };
|
||||
PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" };
|
||||
|
||||
/* fixed rate clocks used in the FSYS1 block */
|
||||
static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = {
|
||||
static const struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initconst = {
|
||||
FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL,
|
||||
0, 300000000),
|
||||
FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL,
|
||||
@ -1014,7 +1015,7 @@ static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = {
|
||||
0, 300000000),
|
||||
};
|
||||
|
||||
static unsigned long fsys1_clk_regs[] __initdata = {
|
||||
static const unsigned long fsys1_clk_regs[] __initconst = {
|
||||
MUX_SEL_FSYS10,
|
||||
MUX_SEL_FSYS11,
|
||||
MUX_SEL_FSYS12,
|
||||
@ -1026,7 +1027,7 @@ static unsigned long fsys1_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_FSYS13,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock fsys1_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
|
||||
MUX(MOUT_FSYS1_PHYCLK_SEL1, "mout_fsys1_phyclk_sel1",
|
||||
mout_fsys1_group_p, MUX_SEL_FSYS10, 16, 2),
|
||||
MUX(0, "mout_fsys1_phyclk_sel0", mout_fsys1_group_p,
|
||||
@ -1049,12 +1050,12 @@ static struct samsung_mux_clock fsys1_mux_clks[] __initdata = {
|
||||
mout_phyclk_ufs20_tx0_user_p, MUX_SEL_FSYS12, 28, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock fsys1_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
|
||||
DIV(DOUT_PCLK_FSYS1, "dout_pclk_fsys1", "mout_aclk_fsys1_200_user",
|
||||
DIV_FSYS1, 0, 2),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock fsys1_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
|
||||
GATE(SCLK_UFSUNIPRO20_USER, "sclk_ufsunipro20_user",
|
||||
"mout_sclk_ufsunipro20_user",
|
||||
ENABLE_SCLK_FSYS11, 20, 0, 0),
|
||||
@ -1089,7 +1090,7 @@ static struct samsung_gate_clock fsys1_gate_clks[] __initdata = {
|
||||
ENABLE_SCLK_FSYS13, 24, CLK_IGNORE_UNUSED, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info fsys1_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
|
||||
.fixed_clks = fixed_rate_clks_fsys1,
|
||||
.nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks_fsys1),
|
||||
.mux_clks = fsys1_mux_clks,
|
||||
@ -1119,22 +1120,22 @@ CLK_OF_DECLARE(exynos7_clk_fsys1, "samsung,exynos7-clock-fsys1",
|
||||
/* List of parent clocks for Muxes in CMU_MSCL */
|
||||
PNAME(mout_aclk_mscl_532_user_p) = { "fin_pll", "aclk_mscl_532" };
|
||||
|
||||
static unsigned long mscl_clk_regs[] __initdata = {
|
||||
static const unsigned long mscl_clk_regs[] __initconst = {
|
||||
MUX_SEL_MSCL,
|
||||
DIV_MSCL,
|
||||
ENABLE_ACLK_MSCL,
|
||||
ENABLE_PCLK_MSCL,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock mscl_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock mscl_mux_clks[] __initconst = {
|
||||
MUX(USERMUX_ACLK_MSCL_532, "usermux_aclk_mscl_532",
|
||||
mout_aclk_mscl_532_user_p, MUX_SEL_MSCL, 0, 1),
|
||||
};
|
||||
static struct samsung_div_clock mscl_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock mscl_div_clks[] __initconst = {
|
||||
DIV(DOUT_PCLK_MSCL, "dout_pclk_mscl", "usermux_aclk_mscl_532",
|
||||
DIV_MSCL, 0, 3),
|
||||
};
|
||||
static struct samsung_gate_clock mscl_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock mscl_gate_clks[] __initconst = {
|
||||
|
||||
GATE(ACLK_MSCL_0, "aclk_mscl_0", "usermux_aclk_mscl_532",
|
||||
ENABLE_ACLK_MSCL, 31, 0, 0),
|
||||
@ -1204,7 +1205,7 @@ static struct samsung_gate_clock mscl_gate_clks[] __initdata = {
|
||||
ENABLE_PCLK_MSCL, 20, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info mscl_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info mscl_cmu_info __initconst = {
|
||||
.mux_clks = mscl_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(mscl_mux_clks),
|
||||
.div_clks = mscl_div_clks,
|
||||
@ -1238,7 +1239,7 @@ CLK_OF_DECLARE(exynos7_clk_mscl, "samsung,exynos7-clock-mscl",
|
||||
PNAME(mout_aud_pll_user_p) = { "fin_pll", "fout_aud_pll" };
|
||||
PNAME(mout_aud_group_p) = { "dout_aud_cdclk", "ioclk_audiocdclk0" };
|
||||
|
||||
static unsigned long aud_clk_regs[] __initdata = {
|
||||
static const unsigned long aud_clk_regs[] __initconst = {
|
||||
MUX_SEL_AUD,
|
||||
DIV_AUD0,
|
||||
DIV_AUD1,
|
||||
@ -1247,13 +1248,13 @@ static unsigned long aud_clk_regs[] __initdata = {
|
||||
ENABLE_SCLK_AUD,
|
||||
};
|
||||
|
||||
static struct samsung_mux_clock aud_mux_clks[] __initdata = {
|
||||
static const struct samsung_mux_clock aud_mux_clks[] __initconst = {
|
||||
MUX(0, "mout_sclk_i2s", mout_aud_group_p, MUX_SEL_AUD, 12, 1),
|
||||
MUX(0, "mout_sclk_pcm", mout_aud_group_p, MUX_SEL_AUD, 16, 1),
|
||||
MUX(0, "mout_aud_pll_user", mout_aud_pll_user_p, MUX_SEL_AUD, 20, 1),
|
||||
};
|
||||
|
||||
static struct samsung_div_clock aud_div_clks[] __initdata = {
|
||||
static const struct samsung_div_clock aud_div_clks[] __initconst = {
|
||||
DIV(0, "dout_aud_ca5", "mout_aud_pll_user", DIV_AUD0, 0, 4),
|
||||
DIV(0, "dout_aclk_aud", "dout_aud_ca5", DIV_AUD0, 4, 4),
|
||||
DIV(0, "dout_aud_pclk_dbg", "dout_aud_ca5", DIV_AUD0, 8, 4),
|
||||
@ -1265,7 +1266,7 @@ static struct samsung_div_clock aud_div_clks[] __initdata = {
|
||||
DIV(0, "dout_aud_cdclk", "mout_aud_pll_user", DIV_AUD1, 24, 4),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock aud_gate_clks[] __initdata = {
|
||||
static const struct samsung_gate_clock aud_gate_clks[] __initconst = {
|
||||
GATE(SCLK_PCM, "sclk_pcm", "dout_sclk_pcm",
|
||||
ENABLE_SCLK_AUD, 27, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(SCLK_I2S, "sclk_i2s", "dout_sclk_i2s",
|
||||
@ -1293,7 +1294,7 @@ static struct samsung_gate_clock aud_gate_clks[] __initdata = {
|
||||
GATE(ACLK_ADMA, "aclk_dmac", "dout_aclk_aud", ENABLE_ACLK_AUD, 31, 0, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info aud_cmu_info __initdata = {
|
||||
static const struct samsung_cmu_info aud_cmu_info __initconst = {
|
||||
.mux_clks = aud_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(aud_mux_clks),
|
||||
.div_clks = aud_div_clks,
|
||||
|
@ -79,7 +79,7 @@ static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
|
||||
u32 pll_con, mdiv, pdiv, sdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
|
||||
@ -112,7 +112,7 @@ static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
|
||||
u32 pll_con, mdiv, pdiv, sdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
|
||||
@ -149,7 +149,7 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
|
||||
@ -186,19 +186,19 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
|
||||
if (!(samsung_pll35xx_mp_change(rate, tmp))) {
|
||||
/* If only s change, change just s value only*/
|
||||
tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
|
||||
tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
|
||||
writel_relaxed(rate->pdiv * PLL35XX_LOCK_FACTOR,
|
||||
pll->lock_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
@ -208,12 +208,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL35XX_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL35XX_SDIV_SHIFT);
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
/* wait_lock_time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
|
||||
<< PLL35XX_LOCK_STAT_SHIFT)));
|
||||
return 0;
|
||||
@ -253,8 +253,8 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
|
||||
s16 kdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con1 = __raw_readl(pll->con_reg + 4);
|
||||
pll_con0 = readl_relaxed(pll->con_reg);
|
||||
pll_con1 = readl_relaxed(pll->con_reg + 4);
|
||||
mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
|
||||
pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
|
||||
sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
|
||||
@ -294,20 +294,20 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con1 = __raw_readl(pll->con_reg + 4);
|
||||
pll_con0 = readl_relaxed(pll->con_reg);
|
||||
pll_con1 = readl_relaxed(pll->con_reg + 4);
|
||||
|
||||
if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
|
||||
/* If only s change, change just s value only*/
|
||||
pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
|
||||
pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
|
||||
__raw_writel(pll_con0, pll->con_reg);
|
||||
writel_relaxed(pll_con0, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
|
||||
writel_relaxed(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
|
||||
@ -316,16 +316,16 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL36XX_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL36XX_SDIV_SHIFT);
|
||||
__raw_writel(pll_con0, pll->con_reg);
|
||||
writel_relaxed(pll_con0, pll->con_reg);
|
||||
|
||||
pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
|
||||
pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
|
||||
__raw_writel(pll_con1, pll->con_reg + 4);
|
||||
writel_relaxed(pll_con1, pll->con_reg + 4);
|
||||
|
||||
/* wait_lock_time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
|
||||
|
||||
return 0;
|
||||
@ -366,7 +366,7 @@ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
|
||||
@ -409,14 +409,14 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
con0 = __raw_readl(pll->con_reg);
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
con0 = readl_relaxed(pll->con_reg);
|
||||
con1 = readl_relaxed(pll->con_reg + 0x4);
|
||||
|
||||
if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
|
||||
/* If only s change, change just s value only*/
|
||||
con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
|
||||
con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
writel_relaxed(con0, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -430,29 +430,29 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
(rate->sdiv << PLL45XX_SDIV_SHIFT);
|
||||
|
||||
/* Set PLL AFC value. */
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
con1 = readl_relaxed(pll->con_reg + 0x4);
|
||||
con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
|
||||
con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
|
||||
|
||||
/* Set PLL lock time. */
|
||||
switch (pll->type) {
|
||||
case pll_4502:
|
||||
__raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
|
||||
writel_relaxed(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
|
||||
break;
|
||||
case pll_4508:
|
||||
__raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
|
||||
writel_relaxed(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set new configuration. */
|
||||
__raw_writel(con1, pll->con_reg + 0x4);
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
writel_relaxed(con1, pll->con_reg + 0x4);
|
||||
writel_relaxed(con0, pll->con_reg);
|
||||
|
||||
/* Wait for locking. */
|
||||
start = ktime_get();
|
||||
while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
|
||||
while (!(readl_relaxed(pll->con_reg) & PLL45XX_LOCKED)) {
|
||||
ktime_t delta = ktime_sub(ktime_get(), start);
|
||||
|
||||
if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
|
||||
@ -513,8 +513,8 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
|
||||
u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con1 = __raw_readl(pll->con_reg + 4);
|
||||
pll_con0 = readl_relaxed(pll->con_reg);
|
||||
pll_con1 = readl_relaxed(pll->con_reg + 4);
|
||||
mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
|
||||
PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
|
||||
pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
|
||||
@ -560,14 +560,14 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
con0 = __raw_readl(pll->con_reg);
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
con0 = readl_relaxed(pll->con_reg);
|
||||
con1 = readl_relaxed(pll->con_reg + 0x4);
|
||||
|
||||
if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
|
||||
/* If only s change, change just s value only*/
|
||||
con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
|
||||
con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
writel_relaxed(con0, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -596,7 +596,7 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
(rate->sdiv << PLL46XX_SDIV_SHIFT);
|
||||
|
||||
/* Set PLL K, MFR and MRR values. */
|
||||
con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
con1 = readl_relaxed(pll->con_reg + 0x4);
|
||||
con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
|
||||
(PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
|
||||
(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
|
||||
@ -605,13 +605,13 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
(rate->mrr << PLL46XX_MRR_SHIFT);
|
||||
|
||||
/* Write configuration to PLL */
|
||||
__raw_writel(lock, pll->lock_reg);
|
||||
__raw_writel(con0, pll->con_reg);
|
||||
__raw_writel(con1, pll->con_reg + 0x4);
|
||||
writel_relaxed(lock, pll->lock_reg);
|
||||
writel_relaxed(con0, pll->con_reg);
|
||||
writel_relaxed(con1, pll->con_reg + 0x4);
|
||||
|
||||
/* Wait for locking. */
|
||||
start = ktime_get();
|
||||
while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
|
||||
while (!(readl_relaxed(pll->con_reg) & PLL46XX_LOCKED)) {
|
||||
ktime_t delta = ktime_sub(ktime_get(), start);
|
||||
|
||||
if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
|
||||
@ -656,7 +656,7 @@ static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
if (pll->type == pll_6552_s3c2416) {
|
||||
mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
|
||||
@ -696,8 +696,8 @@ static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
|
||||
u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con1 = __raw_readl(pll->con_reg + 0x4);
|
||||
pll_con0 = readl_relaxed(pll->con_reg);
|
||||
pll_con1 = readl_relaxed(pll->con_reg + 0x4);
|
||||
mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
|
||||
pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
|
||||
sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
|
||||
@ -734,7 +734,7 @@ static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
|
||||
u32 pll_con, mdiv, pdiv, sdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
|
||||
@ -752,7 +752,7 @@ static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
|
||||
u32 pll_con, mdiv, pdiv, sdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
|
||||
pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
|
||||
sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
|
||||
@ -778,7 +778,7 @@ static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
|
||||
@ -787,7 +787,7 @@ static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLLS3C2410_SDIV_SHIFT);
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
/* Time to settle according to the manual */
|
||||
udelay(300);
|
||||
@ -798,7 +798,7 @@ static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
|
||||
u32 pll_en = readl_relaxed(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
|
||||
u32 pll_en_orig = pll_en;
|
||||
|
||||
if (enable)
|
||||
@ -806,7 +806,7 @@ static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
|
||||
else
|
||||
pll_en |= BIT(bit);
|
||||
|
||||
__raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
|
||||
writel_relaxed(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
|
||||
|
||||
/* if we started the UPLL, then allow to settle */
|
||||
if (enable && (pll_en_orig & BIT(bit)))
|
||||
@ -905,7 +905,7 @@ static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
|
||||
u32 r, p, m, s, pll_stat;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
|
||||
pll_stat = readl_relaxed(pll->reg_base + pll->offset * 3);
|
||||
r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
|
||||
if (!r)
|
||||
return 0;
|
||||
@ -983,7 +983,7 @@ static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
|
||||
u32 mdiv, pdiv, sdiv, pll_con;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con = __raw_readl(pll->con_reg);
|
||||
pll_con = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
|
||||
pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
|
||||
sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
|
||||
@ -1019,19 +1019,19 @@ static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
|
||||
if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
|
||||
/* If only s change, change just s value only*/
|
||||
tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
|
||||
tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set PLL lock time. */
|
||||
__raw_writel(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
|
||||
writel_relaxed(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
|
||||
@ -1040,12 +1040,12 @@ static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
|
||||
(rate->pdiv << PLL2550XX_P_SHIFT) |
|
||||
(rate->sdiv << PLL2550XX_S_SHIFT);
|
||||
__raw_writel(tmp, pll->con_reg);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
/* wait_lock_time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
|
||||
<< PLL2550XX_LOCK_STAT_SHIFT)));
|
||||
|
||||
@ -1089,8 +1089,8 @@ static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
|
||||
s16 kdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con2 = __raw_readl(pll->con_reg + 8);
|
||||
pll_con0 = readl_relaxed(pll->con_reg);
|
||||
pll_con2 = readl_relaxed(pll->con_reg + 8);
|
||||
mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
|
||||
pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
|
||||
sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
|
||||
@ -1117,8 +1117,8 @@ static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_con0 = __raw_readl(pll->con_reg);
|
||||
pll_con2 = __raw_readl(pll->con_reg + 8);
|
||||
pll_con0 = readl_relaxed(pll->con_reg);
|
||||
pll_con2 = readl_relaxed(pll->con_reg + 8);
|
||||
|
||||
/* Change PLL PMS values */
|
||||
pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
|
||||
@ -1135,13 +1135,13 @@ static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
<< PLL2650XX_KDIV_SHIFT;
|
||||
|
||||
/* Set PLL lock time. */
|
||||
__raw_writel(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
|
||||
writel_relaxed(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
|
||||
|
||||
__raw_writel(pll_con0, pll->con_reg);
|
||||
__raw_writel(pll_con2, pll->con_reg + 8);
|
||||
writel_relaxed(pll_con0, pll->con_reg);
|
||||
writel_relaxed(pll_con2, pll->con_reg + 8);
|
||||
|
||||
do {
|
||||
tmp = __raw_readl(pll->con_reg);
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
|
||||
|
||||
return 0;
|
||||
|
@ -428,8 +428,9 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_dclk_driver_ids);
|
||||
|
||||
static struct platform_driver s3c24xx_dclk_driver = {
|
||||
.driver = {
|
||||
.name = "s3c24xx-dclk",
|
||||
.pm = &s3c24xx_dclk_pm_ops,
|
||||
.name = "s3c24xx-dclk",
|
||||
.pm = &s3c24xx_dclk_pm_ops,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = s3c24xx_dclk_probe,
|
||||
.remove = s3c24xx_dclk_remove,
|
||||
|
@ -374,8 +374,6 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
/* Register external clocks only in non-dt cases */
|
||||
if (!np)
|
||||
|
@ -265,8 +265,6 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
/* Register external clocks only in non-dt cases */
|
||||
if (!np)
|
||||
|
@ -400,8 +400,6 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
/* Register external clocks only in non-dt cases */
|
||||
if (!np)
|
||||
|
@ -471,8 +471,6 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
/* Register external clocks. */
|
||||
if (!np)
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <dt-bindings/clock/s5pv210-audss.h>
|
||||
@ -194,20 +194,6 @@ unregister:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s5pv210_audss_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
|
||||
for (i = 0; i < clk_data.clk_num; i++) {
|
||||
if (!IS_ERR(clk_table[i]))
|
||||
clk_unregister(clk_table[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id s5pv210_audss_clk_of_match[] = {
|
||||
{ .compatible = "samsung,s5pv210-audss-clock", },
|
||||
{},
|
||||
@ -216,10 +202,10 @@ static const struct of_device_id s5pv210_audss_clk_of_match[] = {
|
||||
static struct platform_driver s5pv210_audss_clk_driver = {
|
||||
.driver = {
|
||||
.name = "s5pv210-audss-clk",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = s5pv210_audss_clk_of_match,
|
||||
},
|
||||
.probe = s5pv210_audss_clk_probe,
|
||||
.remove = s5pv210_audss_clk_remove,
|
||||
};
|
||||
|
||||
static int __init s5pv210_audss_clk_init(void)
|
||||
@ -227,14 +213,3 @@ static int __init s5pv210_audss_clk_init(void)
|
||||
return platform_driver_register(&s5pv210_audss_clk_driver);
|
||||
}
|
||||
core_initcall(s5pv210_audss_clk_init);
|
||||
|
||||
static void __exit s5pv210_audss_clk_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s5pv210_audss_clk_driver);
|
||||
}
|
||||
module_exit(s5pv210_audss_clk_exit);
|
||||
|
||||
MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
|
||||
MODULE_DESCRIPTION("S5PV210 Audio Subsystem Clock Controller");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:s5pv210-audss-clk");
|
||||
|
@ -784,8 +784,6 @@ static void __init __s5pv210_clk_init(struct device_node *np,
|
||||
struct samsung_clk_provider *ctx;
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
|
||||
if (!ctx)
|
||||
panic("%s: unable to allocate context.\n", __func__);
|
||||
|
||||
samsung_clk_register_mux(ctx, early_mux_clks,
|
||||
ARRAY_SIZE(early_mux_clks));
|
||||
|
@ -346,9 +346,9 @@ static struct syscore_ops samsung_clk_syscore_ops = {
|
||||
.resume = samsung_clk_resume,
|
||||
};
|
||||
|
||||
static void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
const unsigned long *rdump,
|
||||
unsigned long nr_rdump)
|
||||
void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
const unsigned long *rdump,
|
||||
unsigned long nr_rdump)
|
||||
{
|
||||
struct samsung_clock_reg_cache *reg_cache;
|
||||
|
||||
@ -370,9 +370,9 @@ static void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
}
|
||||
|
||||
#else
|
||||
static void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
const unsigned long *rdump,
|
||||
unsigned long nr_rdump) {}
|
||||
void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
const unsigned long *rdump,
|
||||
unsigned long nr_rdump) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -381,7 +381,7 @@ static void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
*/
|
||||
struct samsung_clk_provider * __init samsung_cmu_register_one(
|
||||
struct device_node *np,
|
||||
struct samsung_cmu_info *cmu)
|
||||
const struct samsung_cmu_info *cmu)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct samsung_clk_provider *ctx;
|
||||
|
@ -261,7 +261,7 @@ struct samsung_gate_clock {
|
||||
#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \
|
||||
__GATE(_id, dname, cname, pname, o, b, f, gf, a)
|
||||
|
||||
#define PNAME(x) static const char *x[] __initdata
|
||||
#define PNAME(x) static const char * const x[] __initconst
|
||||
|
||||
/**
|
||||
* struct samsung_clk_reg_dump: register dump of clock controller registers.
|
||||
@ -330,28 +330,28 @@ struct samsung_clock_reg_cache {
|
||||
|
||||
struct samsung_cmu_info {
|
||||
/* list of pll clocks and respective count */
|
||||
struct samsung_pll_clock *pll_clks;
|
||||
const struct samsung_pll_clock *pll_clks;
|
||||
unsigned int nr_pll_clks;
|
||||
/* list of mux clocks and respective count */
|
||||
struct samsung_mux_clock *mux_clks;
|
||||
const struct samsung_mux_clock *mux_clks;
|
||||
unsigned int nr_mux_clks;
|
||||
/* list of div clocks and respective count */
|
||||
struct samsung_div_clock *div_clks;
|
||||
const struct samsung_div_clock *div_clks;
|
||||
unsigned int nr_div_clks;
|
||||
/* list of gate clocks and respective count */
|
||||
struct samsung_gate_clock *gate_clks;
|
||||
const struct samsung_gate_clock *gate_clks;
|
||||
unsigned int nr_gate_clks;
|
||||
/* list of fixed clocks and respective count */
|
||||
struct samsung_fixed_rate_clock *fixed_clks;
|
||||
const struct samsung_fixed_rate_clock *fixed_clks;
|
||||
unsigned int nr_fixed_clks;
|
||||
/* list of fixed factor clocks and respective count */
|
||||
struct samsung_fixed_factor_clock *fixed_factor_clks;
|
||||
const struct samsung_fixed_factor_clock *fixed_factor_clks;
|
||||
unsigned int nr_fixed_factor_clks;
|
||||
/* total number of clocks with IDs assigned*/
|
||||
unsigned int nr_clk_ids;
|
||||
|
||||
/* list and number of clocks registers */
|
||||
unsigned long *clk_regs;
|
||||
const unsigned long *clk_regs;
|
||||
unsigned int nr_clk_regs;
|
||||
};
|
||||
|
||||
@ -395,10 +395,14 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
||||
|
||||
extern struct samsung_clk_provider __init *samsung_cmu_register_one(
|
||||
struct device_node *,
|
||||
struct samsung_cmu_info *);
|
||||
const struct samsung_cmu_info *);
|
||||
|
||||
extern unsigned long _get_rate(const char *clk_name);
|
||||
|
||||
extern void samsung_clk_sleep_init(void __iomem *reg_base,
|
||||
const unsigned long *rdump,
|
||||
unsigned long nr_rdump);
|
||||
|
||||
extern void samsung_clk_save(void __iomem *base,
|
||||
struct samsung_clk_reg_dump *rd,
|
||||
unsigned int num_regs);
|
||||
|
@ -267,7 +267,6 @@ static void __init st_of_flexgen_setup(struct device_node *np)
|
||||
const char **parents;
|
||||
int num_parents, i;
|
||||
spinlock_t *rlock = NULL;
|
||||
unsigned long flex_flags = 0;
|
||||
int ret;
|
||||
|
||||
pnode = of_get_parent(np);
|
||||
@ -308,12 +307,15 @@ static void __init st_of_flexgen_setup(struct device_node *np)
|
||||
for (i = 0; i < clk_data->clk_num; i++) {
|
||||
struct clk *clk;
|
||||
const char *clk_name;
|
||||
unsigned long flex_flags = 0;
|
||||
|
||||
if (of_property_read_string_index(np, "clock-output-names",
|
||||
i, &clk_name)) {
|
||||
break;
|
||||
}
|
||||
|
||||
of_clk_detect_critical(np, i, &flex_flags);
|
||||
|
||||
/*
|
||||
* If we read an empty clock name then the output is unused
|
||||
*/
|
||||
|
@ -1027,7 +1027,7 @@ static const struct clk_ops st_quadfs_ops = {
|
||||
static struct clk * __init st_clk_register_quadfs_fsynth(
|
||||
const char *name, const char *parent_name,
|
||||
struct clkgen_quadfs_data *quadfs, void __iomem *reg, u32 chan,
|
||||
spinlock_t *lock)
|
||||
unsigned long flags, spinlock_t *lock)
|
||||
{
|
||||
struct st_clk_quadfs_fsynth *fs;
|
||||
struct clk *clk;
|
||||
@ -1045,7 +1045,7 @@ static struct clk * __init st_clk_register_quadfs_fsynth(
|
||||
|
||||
init.name = name;
|
||||
init.ops = &st_quadfs_ops;
|
||||
init.flags = CLK_GET_RATE_NOCACHE | CLK_IS_BASIC;
|
||||
init.flags = flags | CLK_GET_RATE_NOCACHE | CLK_IS_BASIC;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
@ -1115,6 +1115,7 @@ static void __init st_of_create_quadfs_fsynths(
|
||||
for (fschan = 0; fschan < QUADFS_MAX_CHAN; fschan++) {
|
||||
struct clk *clk;
|
||||
const char *clk_name;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (of_property_read_string_index(np, "clock-output-names",
|
||||
fschan, &clk_name)) {
|
||||
@ -1127,8 +1128,11 @@ static void __init st_of_create_quadfs_fsynths(
|
||||
if (*clk_name == '\0')
|
||||
continue;
|
||||
|
||||
of_clk_detect_critical(np, fschan, &flags);
|
||||
|
||||
clk = st_clk_register_quadfs_fsynth(clk_name, pll_name,
|
||||
quadfs, reg, fschan, lock);
|
||||
quadfs, reg, fschan,
|
||||
flags, lock);
|
||||
|
||||
/*
|
||||
* If there was an error registering this clock output, clean
|
||||
|
@ -840,7 +840,7 @@ static const struct clk_ops stm_pll4600c28_ops = {
|
||||
|
||||
static struct clk * __init clkgen_pll_register(const char *parent_name,
|
||||
struct clkgen_pll_data *pll_data,
|
||||
void __iomem *reg,
|
||||
void __iomem *reg, unsigned long pll_flags,
|
||||
const char *clk_name, spinlock_t *lock)
|
||||
{
|
||||
struct clkgen_pll *pll;
|
||||
@ -854,7 +854,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name,
|
||||
init.name = clk_name;
|
||||
init.ops = pll_data->ops;
|
||||
|
||||
init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE;
|
||||
init.flags = pll_flags | CLK_IS_BASIC | CLK_GET_RATE_NOCACHE;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
@ -948,7 +948,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
|
||||
*/
|
||||
clk_data->clks[0] = clkgen_pll_register(parent_name,
|
||||
(struct clkgen_pll_data *) &st_pll1600c65_ax,
|
||||
reg + CLKGENAx_PLL0_OFFSET, clk_name, NULL);
|
||||
reg + CLKGENAx_PLL0_OFFSET, 0, clk_name, NULL);
|
||||
|
||||
if (IS_ERR(clk_data->clks[0]))
|
||||
goto err;
|
||||
@ -977,7 +977,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
|
||||
*/
|
||||
clk_data->clks[2] = clkgen_pll_register(parent_name,
|
||||
(struct clkgen_pll_data *) &st_pll800c65_ax,
|
||||
reg + CLKGENAx_PLL1_OFFSET, clk_name, NULL);
|
||||
reg + CLKGENAx_PLL1_OFFSET, 0, clk_name, NULL);
|
||||
|
||||
if (IS_ERR(clk_data->clks[2]))
|
||||
goto err;
|
||||
@ -995,7 +995,7 @@ CLK_OF_DECLARE(clkgena_c65_plls,
|
||||
static struct clk * __init clkgen_odf_register(const char *parent_name,
|
||||
void __iomem *reg,
|
||||
struct clkgen_pll_data *pll_data,
|
||||
int odf,
|
||||
unsigned long pll_flags, int odf,
|
||||
spinlock_t *odf_lock,
|
||||
const char *odf_name)
|
||||
{
|
||||
@ -1004,7 +1004,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
|
||||
struct clk_gate *gate;
|
||||
struct clk_divider *div;
|
||||
|
||||
flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
|
||||
flags = pll_flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
|
||||
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
@ -1099,6 +1099,7 @@ static void __init clkgen_c32_pll_setup(struct device_node *np)
|
||||
int num_odfs, odf;
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct clkgen_pll_data *data;
|
||||
unsigned long pll_flags = 0;
|
||||
|
||||
match = of_match_node(c32_pll_of_match, np);
|
||||
if (!match) {
|
||||
@ -1116,8 +1117,10 @@ static void __init clkgen_c32_pll_setup(struct device_node *np)
|
||||
if (!pll_base)
|
||||
return;
|
||||
|
||||
clk = clkgen_pll_register(parent_name, data, pll_base, np->name,
|
||||
data->lock);
|
||||
of_clk_detect_critical(np, 0, &pll_flags);
|
||||
|
||||
clk = clkgen_pll_register(parent_name, data, pll_base, pll_flags,
|
||||
np->name, data->lock);
|
||||
if (IS_ERR(clk))
|
||||
return;
|
||||
|
||||
@ -1139,12 +1142,15 @@ static void __init clkgen_c32_pll_setup(struct device_node *np)
|
||||
for (odf = 0; odf < num_odfs; odf++) {
|
||||
struct clk *clk;
|
||||
const char *clk_name;
|
||||
unsigned long odf_flags = 0;
|
||||
|
||||
if (of_property_read_string_index(np, "clock-output-names",
|
||||
odf, &clk_name))
|
||||
return;
|
||||
|
||||
clk = clkgen_odf_register(pll_name, pll_base, data,
|
||||
of_clk_detect_critical(np, odf, &odf_flags);
|
||||
|
||||
clk = clkgen_odf_register(pll_name, pll_base, data, odf_flags,
|
||||
odf, &clkgena_c32_odf_lock, clk_name);
|
||||
if (IS_ERR(clk))
|
||||
goto err;
|
||||
@ -1206,7 +1212,8 @@ static void __init clkgengpu_c32_pll_setup(struct device_node *np)
|
||||
/*
|
||||
* PLL 1200MHz output
|
||||
*/
|
||||
clk = clkgen_pll_register(parent_name, data, reg, clk_name, data->lock);
|
||||
clk = clkgen_pll_register(parent_name, data, reg,
|
||||
0, clk_name, data->lock);
|
||||
|
||||
if (!IS_ERR(clk))
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
|
65
drivers/clk/sunxi-ng/Kconfig
Normal file
65
drivers/clk/sunxi-ng/Kconfig
Normal file
@ -0,0 +1,65 @@
|
||||
config SUNXI_CCU
|
||||
bool "Clock support for Allwinner SoCs"
|
||||
default ARCH_SUNXI
|
||||
|
||||
if SUNXI_CCU
|
||||
|
||||
# Base clock types
|
||||
|
||||
config SUNXI_CCU_DIV
|
||||
bool
|
||||
select SUNXI_CCU_MUX
|
||||
|
||||
config SUNXI_CCU_FRAC
|
||||
bool
|
||||
|
||||
config SUNXI_CCU_GATE
|
||||
bool
|
||||
|
||||
config SUNXI_CCU_MUX
|
||||
bool
|
||||
|
||||
config SUNXI_CCU_PHASE
|
||||
bool
|
||||
|
||||
# Multi-factor clocks
|
||||
|
||||
config SUNXI_CCU_NK
|
||||
bool
|
||||
select SUNXI_CCU_GATE
|
||||
|
||||
config SUNXI_CCU_NKM
|
||||
bool
|
||||
select RATIONAL
|
||||
select SUNXI_CCU_GATE
|
||||
|
||||
config SUNXI_CCU_NKMP
|
||||
bool
|
||||
select RATIONAL
|
||||
select SUNXI_CCU_GATE
|
||||
|
||||
config SUNXI_CCU_NM
|
||||
bool
|
||||
select RATIONAL
|
||||
select SUNXI_CCU_FRAC
|
||||
select SUNXI_CCU_GATE
|
||||
|
||||
config SUNXI_CCU_MP
|
||||
bool
|
||||
select SUNXI_CCU_GATE
|
||||
select SUNXI_CCU_MUX
|
||||
|
||||
# SoC Drivers
|
||||
|
||||
config SUN8I_H3_CCU
|
||||
bool "Support for the Allwinner H3 CCU"
|
||||
select SUNXI_CCU_DIV
|
||||
select SUNXI_CCU_NK
|
||||
select SUNXI_CCU_NKM
|
||||
select SUNXI_CCU_NKMP
|
||||
select SUNXI_CCU_NM
|
||||
select SUNXI_CCU_MP
|
||||
select SUNXI_CCU_PHASE
|
||||
default MACH_SUN8I
|
||||
|
||||
endif
|
20
drivers/clk/sunxi-ng/Makefile
Normal file
20
drivers/clk/sunxi-ng/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# Common objects
|
||||
obj-$(CONFIG_SUNXI_CCU) += ccu_common.o
|
||||
obj-$(CONFIG_SUNXI_CCU) += ccu_reset.o
|
||||
|
||||
# Base clock types
|
||||
obj-$(CONFIG_SUNXI_CCU_DIV) += ccu_div.o
|
||||
obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o
|
||||
obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o
|
||||
obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o
|
||||
obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o
|
||||
|
||||
# Multi-factor clocks
|
||||
obj-$(CONFIG_SUNXI_CCU_NK) += ccu_nk.o
|
||||
obj-$(CONFIG_SUNXI_CCU_NKM) += ccu_nkm.o
|
||||
obj-$(CONFIG_SUNXI_CCU_NKMP) += ccu_nkmp.o
|
||||
obj-$(CONFIG_SUNXI_CCU_NM) += ccu_nm.o
|
||||
obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o
|
||||
|
||||
# SoC support
|
||||
obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
|
826
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
Normal file
826
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
Normal file
@ -0,0 +1,826 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Maxime Ripard. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
|
||||
#include "ccu_div.h"
|
||||
#include "ccu_gate.h"
|
||||
#include "ccu_mp.h"
|
||||
#include "ccu_mult.h"
|
||||
#include "ccu_nk.h"
|
||||
#include "ccu_nkm.h"
|
||||
#include "ccu_nkmp.h"
|
||||
#include "ccu_nm.h"
|
||||
#include "ccu_phase.h"
|
||||
|
||||
#include "ccu-sun8i-h3.h"
|
||||
|
||||
static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux",
|
||||
"osc24M", 0x000,
|
||||
8, 5, /* N */
|
||||
4, 2, /* K */
|
||||
0, 2, /* M */
|
||||
16, 2, /* P */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
/*
|
||||
* The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
|
||||
* the base (2x, 4x and 8x), and one variable divider (the one true
|
||||
* pll audio).
|
||||
*
|
||||
* We don't have any need for the variable divider for now, so we just
|
||||
* hardcode it to match with the clock names
|
||||
*/
|
||||
#define SUN8I_H3_PLL_AUDIO_REG 0x008
|
||||
|
||||
static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
|
||||
"osc24M", 0x0010,
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
|
||||
"osc24M", 0x0018,
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
|
||||
"osc24M", 0x020,
|
||||
8, 5, /* N */
|
||||
4, 2, /* K */
|
||||
0, 2, /* M */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
|
||||
"osc24M", 0x028,
|
||||
8, 5, /* N */
|
||||
4, 2, /* K */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
2, /* post-div */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
|
||||
"osc24M", 0x0038,
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
|
||||
"osc24M", 0x044,
|
||||
8, 5, /* N */
|
||||
4, 2, /* K */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
2, /* post-div */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
|
||||
"osc24M", 0x0048,
|
||||
8, 7, /* N */
|
||||
0, 4, /* M */
|
||||
BIT(24), /* frac enable */
|
||||
BIT(25), /* frac select */
|
||||
270000000, /* frac rate 0 */
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
|
||||
static const char * const cpux_parents[] = { "osc32k", "osc24M",
|
||||
"pll-cpux" , "pll-cpux" };
|
||||
static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
|
||||
0x050, 16, 2, CLK_IS_CRITICAL);
|
||||
|
||||
static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
|
||||
|
||||
static const char * const ahb1_parents[] = { "osc32k", "osc24M",
|
||||
"axi" , "pll-periph0" };
|
||||
static struct ccu_div ahb1_clk = {
|
||||
.div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
|
||||
|
||||
.mux = {
|
||||
.shift = 12,
|
||||
.width = 2,
|
||||
|
||||
.variable_prediv = {
|
||||
.index = 3,
|
||||
.shift = 6,
|
||||
.width = 2,
|
||||
},
|
||||
},
|
||||
|
||||
.common = {
|
||||
.reg = 0x054,
|
||||
.features = CCU_FEATURE_VARIABLE_PREDIV,
|
||||
.hw.init = CLK_HW_INIT_PARENTS("ahb1",
|
||||
ahb1_parents,
|
||||
&ccu_div_ops,
|
||||
0),
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_div_table apb1_div_table[] = {
|
||||
{ .val = 0, .div = 2 },
|
||||
{ .val = 1, .div = 2 },
|
||||
{ .val = 2, .div = 4 },
|
||||
{ .val = 3, .div = 8 },
|
||||
{ /* Sentinel */ },
|
||||
};
|
||||
static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
|
||||
0x054, 8, 2, apb1_div_table, 0);
|
||||
|
||||
static const char * const apb2_parents[] = { "osc32k", "osc24M",
|
||||
"pll-periph0" , "pll-periph0" };
|
||||
static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
|
||||
0, 5, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
0);
|
||||
|
||||
static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" };
|
||||
static struct ccu_mux ahb2_clk = {
|
||||
.mux = {
|
||||
.shift = 0,
|
||||
.width = 1,
|
||||
|
||||
.fixed_prediv = {
|
||||
.index = 1,
|
||||
.div = 2,
|
||||
},
|
||||
},
|
||||
|
||||
.common = {
|
||||
.reg = 0x05c,
|
||||
.features = CCU_FEATURE_FIXED_PREDIV,
|
||||
.hw.init = CLK_HW_INIT_PARENTS("ahb2",
|
||||
ahb2_parents,
|
||||
&ccu_mux_ops,
|
||||
0),
|
||||
},
|
||||
};
|
||||
|
||||
static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb1",
|
||||
0x060, BIT(5), 0);
|
||||
static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
|
||||
0x060, BIT(6), 0);
|
||||
static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
|
||||
0x060, BIT(8), 0);
|
||||
static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
|
||||
0x060, BIT(9), 0);
|
||||
static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
|
||||
0x060, BIT(10), 0);
|
||||
static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
|
||||
0x060, BIT(13), 0);
|
||||
static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
|
||||
0x060, BIT(14), 0);
|
||||
static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb2",
|
||||
0x060, BIT(17), 0);
|
||||
static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb1",
|
||||
0x060, BIT(18), 0);
|
||||
static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
|
||||
0x060, BIT(19), 0);
|
||||
static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
|
||||
0x060, BIT(20), 0);
|
||||
static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
|
||||
0x060, BIT(21), 0);
|
||||
static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
|
||||
0x060, BIT(23), 0);
|
||||
static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1",
|
||||
0x060, BIT(24), 0);
|
||||
static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb2",
|
||||
0x060, BIT(25), 0);
|
||||
static SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb2",
|
||||
0x060, BIT(26), 0);
|
||||
static SUNXI_CCU_GATE(bus_ehci3_clk, "bus-ehci3", "ahb2",
|
||||
0x060, BIT(27), 0);
|
||||
static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1",
|
||||
0x060, BIT(28), 0);
|
||||
static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb2",
|
||||
0x060, BIT(29), 0);
|
||||
static SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "ahb2",
|
||||
0x060, BIT(30), 0);
|
||||
static SUNXI_CCU_GATE(bus_ohci3_clk, "bus-ohci3", "ahb2",
|
||||
0x060, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
|
||||
0x064, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(bus_tcon0_clk, "bus-tcon0", "ahb1",
|
||||
0x064, BIT(3), 0);
|
||||
static SUNXI_CCU_GATE(bus_tcon1_clk, "bus-tcon1", "ahb1",
|
||||
0x064, BIT(4), 0);
|
||||
static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "ahb1",
|
||||
0x064, BIT(5), 0);
|
||||
static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
|
||||
0x064, BIT(8), 0);
|
||||
static SUNXI_CCU_GATE(bus_tve_clk, "bus-tve", "ahb1",
|
||||
0x064, BIT(9), 0);
|
||||
static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb1",
|
||||
0x064, BIT(11), 0);
|
||||
static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1",
|
||||
0x064, BIT(12), 0);
|
||||
static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
|
||||
0x064, BIT(20), 0);
|
||||
static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
|
||||
0x064, BIT(21), 0);
|
||||
static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
|
||||
0x064, BIT(22), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
|
||||
0x068, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1",
|
||||
0x068, BIT(1), 0);
|
||||
static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
|
||||
0x068, BIT(5), 0);
|
||||
static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1",
|
||||
0x068, BIT(8), 0);
|
||||
static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
|
||||
0x068, BIT(12), 0);
|
||||
static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
|
||||
0x068, BIT(13), 0);
|
||||
static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1",
|
||||
0x068, BIT(14), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
|
||||
0x06c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
|
||||
0x06c, BIT(1), 0);
|
||||
static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
|
||||
0x06c, BIT(2), 0);
|
||||
static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
|
||||
0x06c, BIT(16), 0);
|
||||
static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
|
||||
0x06c, BIT(17), 0);
|
||||
static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
|
||||
0x06c, BIT(18), 0);
|
||||
static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
|
||||
0x06c, BIT(19), 0);
|
||||
static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2",
|
||||
0x06c, BIT(20), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(bus_ephy_clk, "bus-ephy", "ahb1",
|
||||
0x070, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1",
|
||||
0x070, BIT(7), 0);
|
||||
|
||||
static struct clk_div_table ths_div_table[] = {
|
||||
{ .val = 0, .div = 1 },
|
||||
{ .val = 1, .div = 2 },
|
||||
{ .val = 2, .div = 4 },
|
||||
{ .val = 3, .div = 6 },
|
||||
};
|
||||
static SUNXI_CCU_DIV_TABLE_WITH_GATE(ths_clk, "ths", "osc24M",
|
||||
0x074, 0, 2, ths_div_table, BIT(31), 0);
|
||||
|
||||
static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
|
||||
"pll-periph1" };
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
|
||||
0x088, 20, 3, 0);
|
||||
static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
|
||||
0x088, 8, 3, 0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
|
||||
0x08c, 20, 3, 0);
|
||||
static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
|
||||
0x08c, 8, 3, 0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
|
||||
0x090, 20, 3, 0);
|
||||
static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
|
||||
0x090, 8, 3, 0);
|
||||
|
||||
static const char * const ts_parents[] = { "osc24M", "pll-periph0", };
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x098,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", mod0_default_parents, 0x09c,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
|
||||
0, 4, /* M */
|
||||
16, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
|
||||
"pll-audio-2x", "pll-audio" };
|
||||
static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
|
||||
0x0b0, 16, 2, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
|
||||
0x0b4, 16, 2, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", i2s_parents,
|
||||
0x0b8, 16, 2, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
|
||||
0x0c0, 0, 4, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
|
||||
0x0cc, BIT(8), 0);
|
||||
static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
|
||||
0x0cc, BIT(9), 0);
|
||||
static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
|
||||
0x0cc, BIT(10), 0);
|
||||
static SUNXI_CCU_GATE(usb_phy3_clk, "usb-phy3", "osc24M",
|
||||
0x0cc, BIT(11), 0);
|
||||
static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M",
|
||||
0x0cc, BIT(16), 0);
|
||||
static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc24M",
|
||||
0x0cc, BIT(17), 0);
|
||||
static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M",
|
||||
0x0cc, BIT(18), 0);
|
||||
static SUNXI_CCU_GATE(usb_ohci3_clk, "usb-ohci3", "osc24M",
|
||||
0x0cc, BIT(19), 0);
|
||||
|
||||
static const char * const dram_parents[] = { "pll-ddr", "pll-periph0-2x" };
|
||||
static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents,
|
||||
0x0f4, 0, 4, 20, 2, CLK_IS_CRITICAL);
|
||||
|
||||
static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram",
|
||||
0x100, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram",
|
||||
0x100, BIT(1), 0);
|
||||
static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram",
|
||||
0x100, BIT(2), 0);
|
||||
static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram",
|
||||
0x100, BIT(3), 0);
|
||||
|
||||
static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
|
||||
0x104, 0, 4, 24, 3, BIT(31), 0);
|
||||
|
||||
static const char * const tcon_parents[] = { "pll-video" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(tcon_clk, "tcon", tcon_parents,
|
||||
0x118, 0, 4, 24, 3, BIT(31), 0);
|
||||
|
||||
static const char * const tve_parents[] = { "pll-de", "pll-periph1" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(tve_clk, "tve", tve_parents,
|
||||
0x120, 0, 4, 24, 3, BIT(31), 0);
|
||||
|
||||
static const char * const deinterlace_parents[] = { "pll-periph0", "pll-periph1" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", deinterlace_parents,
|
||||
0x124, 0, 4, 24, 3, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M",
|
||||
0x130, BIT(31), 0);
|
||||
|
||||
static const char * const csi_sclk_parents[] = { "pll-periph0", "pll-periph1" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents,
|
||||
0x134, 16, 4, 24, 3, BIT(31), 0);
|
||||
|
||||
static const char * const csi_mclk_parents[] = { "osc24M", "pll-video", "pll-periph0" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(csi_mclk_clk, "csi-mclk", csi_mclk_parents,
|
||||
0x134, 0, 5, 8, 3, BIT(15), 0);
|
||||
|
||||
static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
|
||||
0x13c, 16, 3, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
|
||||
0x140, BIT(31), 0);
|
||||
static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
|
||||
0x144, BIT(31), 0);
|
||||
|
||||
static const char * const hdmi_parents[] = { "pll-video" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents,
|
||||
0x150, 0, 4, 24, 2, BIT(31), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M",
|
||||
0x154, BIT(31), 0);
|
||||
|
||||
static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x", "pll-ddr" };
|
||||
static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
|
||||
0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
|
||||
|
||||
static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
|
||||
0x1a0, 0, 3, BIT(31), 0);
|
||||
|
||||
static struct ccu_common *sun8i_h3_ccu_clks[] = {
|
||||
&pll_cpux_clk.common,
|
||||
&pll_audio_base_clk.common,
|
||||
&pll_video_clk.common,
|
||||
&pll_ve_clk.common,
|
||||
&pll_ddr_clk.common,
|
||||
&pll_periph0_clk.common,
|
||||
&pll_gpu_clk.common,
|
||||
&pll_periph1_clk.common,
|
||||
&pll_de_clk.common,
|
||||
&cpux_clk.common,
|
||||
&axi_clk.common,
|
||||
&ahb1_clk.common,
|
||||
&apb1_clk.common,
|
||||
&apb2_clk.common,
|
||||
&ahb2_clk.common,
|
||||
&bus_ce_clk.common,
|
||||
&bus_dma_clk.common,
|
||||
&bus_mmc0_clk.common,
|
||||
&bus_mmc1_clk.common,
|
||||
&bus_mmc2_clk.common,
|
||||
&bus_nand_clk.common,
|
||||
&bus_dram_clk.common,
|
||||
&bus_emac_clk.common,
|
||||
&bus_ts_clk.common,
|
||||
&bus_hstimer_clk.common,
|
||||
&bus_spi0_clk.common,
|
||||
&bus_spi1_clk.common,
|
||||
&bus_otg_clk.common,
|
||||
&bus_ehci0_clk.common,
|
||||
&bus_ehci1_clk.common,
|
||||
&bus_ehci2_clk.common,
|
||||
&bus_ehci3_clk.common,
|
||||
&bus_ohci0_clk.common,
|
||||
&bus_ohci1_clk.common,
|
||||
&bus_ohci2_clk.common,
|
||||
&bus_ohci3_clk.common,
|
||||
&bus_ve_clk.common,
|
||||
&bus_tcon0_clk.common,
|
||||
&bus_tcon1_clk.common,
|
||||
&bus_deinterlace_clk.common,
|
||||
&bus_csi_clk.common,
|
||||
&bus_tve_clk.common,
|
||||
&bus_hdmi_clk.common,
|
||||
&bus_de_clk.common,
|
||||
&bus_gpu_clk.common,
|
||||
&bus_msgbox_clk.common,
|
||||
&bus_spinlock_clk.common,
|
||||
&bus_codec_clk.common,
|
||||
&bus_spdif_clk.common,
|
||||
&bus_pio_clk.common,
|
||||
&bus_ths_clk.common,
|
||||
&bus_i2s0_clk.common,
|
||||
&bus_i2s1_clk.common,
|
||||
&bus_i2s2_clk.common,
|
||||
&bus_i2c0_clk.common,
|
||||
&bus_i2c1_clk.common,
|
||||
&bus_i2c2_clk.common,
|
||||
&bus_uart0_clk.common,
|
||||
&bus_uart1_clk.common,
|
||||
&bus_uart2_clk.common,
|
||||
&bus_uart3_clk.common,
|
||||
&bus_scr_clk.common,
|
||||
&bus_ephy_clk.common,
|
||||
&bus_dbg_clk.common,
|
||||
&ths_clk.common,
|
||||
&nand_clk.common,
|
||||
&mmc0_clk.common,
|
||||
&mmc0_sample_clk.common,
|
||||
&mmc0_output_clk.common,
|
||||
&mmc1_clk.common,
|
||||
&mmc1_sample_clk.common,
|
||||
&mmc1_output_clk.common,
|
||||
&mmc2_clk.common,
|
||||
&mmc2_sample_clk.common,
|
||||
&mmc2_output_clk.common,
|
||||
&ts_clk.common,
|
||||
&ce_clk.common,
|
||||
&spi0_clk.common,
|
||||
&spi1_clk.common,
|
||||
&i2s0_clk.common,
|
||||
&i2s1_clk.common,
|
||||
&i2s2_clk.common,
|
||||
&spdif_clk.common,
|
||||
&usb_phy0_clk.common,
|
||||
&usb_phy1_clk.common,
|
||||
&usb_phy2_clk.common,
|
||||
&usb_phy3_clk.common,
|
||||
&usb_ohci0_clk.common,
|
||||
&usb_ohci1_clk.common,
|
||||
&usb_ohci2_clk.common,
|
||||
&usb_ohci3_clk.common,
|
||||
&dram_clk.common,
|
||||
&dram_ve_clk.common,
|
||||
&dram_csi_clk.common,
|
||||
&dram_deinterlace_clk.common,
|
||||
&dram_ts_clk.common,
|
||||
&de_clk.common,
|
||||
&tcon_clk.common,
|
||||
&tve_clk.common,
|
||||
&deinterlace_clk.common,
|
||||
&csi_misc_clk.common,
|
||||
&csi_sclk_clk.common,
|
||||
&csi_mclk_clk.common,
|
||||
&ve_clk.common,
|
||||
&ac_dig_clk.common,
|
||||
&avs_clk.common,
|
||||
&hdmi_clk.common,
|
||||
&hdmi_ddc_clk.common,
|
||||
&mbus_clk.common,
|
||||
&gpu_clk.common,
|
||||
};
|
||||
|
||||
/* We hardcode the divider to 4 for now */
|
||||
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
|
||||
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
|
||||
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
|
||||
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
|
||||
"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
|
||||
"pll-periph0", 1, 2, 0);
|
||||
|
||||
static struct clk_hw_onecell_data sun8i_h3_hw_clks = {
|
||||
.hws = {
|
||||
[CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
|
||||
[CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
|
||||
[CLK_PLL_AUDIO] = &pll_audio_clk.hw,
|
||||
[CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
|
||||
[CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
|
||||
[CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
|
||||
[CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
|
||||
[CLK_PLL_VE] = &pll_ve_clk.common.hw,
|
||||
[CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
|
||||
[CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
|
||||
[CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw,
|
||||
[CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
|
||||
[CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
|
||||
[CLK_PLL_DE] = &pll_de_clk.common.hw,
|
||||
[CLK_CPUX] = &cpux_clk.common.hw,
|
||||
[CLK_AXI] = &axi_clk.common.hw,
|
||||
[CLK_AHB1] = &ahb1_clk.common.hw,
|
||||
[CLK_APB1] = &apb1_clk.common.hw,
|
||||
[CLK_APB2] = &apb2_clk.common.hw,
|
||||
[CLK_AHB2] = &ahb2_clk.common.hw,
|
||||
[CLK_BUS_CE] = &bus_ce_clk.common.hw,
|
||||
[CLK_BUS_DMA] = &bus_dma_clk.common.hw,
|
||||
[CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
|
||||
[CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
|
||||
[CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
|
||||
[CLK_BUS_NAND] = &bus_nand_clk.common.hw,
|
||||
[CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
|
||||
[CLK_BUS_EMAC] = &bus_emac_clk.common.hw,
|
||||
[CLK_BUS_TS] = &bus_ts_clk.common.hw,
|
||||
[CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
|
||||
[CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
|
||||
[CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
|
||||
[CLK_BUS_OTG] = &bus_otg_clk.common.hw,
|
||||
[CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
|
||||
[CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw,
|
||||
[CLK_BUS_EHCI2] = &bus_ehci2_clk.common.hw,
|
||||
[CLK_BUS_EHCI3] = &bus_ehci3_clk.common.hw,
|
||||
[CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
|
||||
[CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw,
|
||||
[CLK_BUS_OHCI2] = &bus_ohci2_clk.common.hw,
|
||||
[CLK_BUS_OHCI3] = &bus_ohci3_clk.common.hw,
|
||||
[CLK_BUS_VE] = &bus_ve_clk.common.hw,
|
||||
[CLK_BUS_TCON0] = &bus_tcon0_clk.common.hw,
|
||||
[CLK_BUS_TCON1] = &bus_tcon1_clk.common.hw,
|
||||
[CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw,
|
||||
[CLK_BUS_CSI] = &bus_csi_clk.common.hw,
|
||||
[CLK_BUS_TVE] = &bus_tve_clk.common.hw,
|
||||
[CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw,
|
||||
[CLK_BUS_DE] = &bus_de_clk.common.hw,
|
||||
[CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
|
||||
[CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
|
||||
[CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
|
||||
[CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
|
||||
[CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
|
||||
[CLK_BUS_PIO] = &bus_pio_clk.common.hw,
|
||||
[CLK_BUS_THS] = &bus_ths_clk.common.hw,
|
||||
[CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
|
||||
[CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
|
||||
[CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw,
|
||||
[CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
|
||||
[CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
|
||||
[CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
|
||||
[CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
|
||||
[CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
|
||||
[CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
|
||||
[CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
|
||||
[CLK_BUS_SCR] = &bus_scr_clk.common.hw,
|
||||
[CLK_BUS_EPHY] = &bus_ephy_clk.common.hw,
|
||||
[CLK_BUS_DBG] = &bus_dbg_clk.common.hw,
|
||||
[CLK_THS] = &ths_clk.common.hw,
|
||||
[CLK_NAND] = &nand_clk.common.hw,
|
||||
[CLK_MMC0] = &mmc0_clk.common.hw,
|
||||
[CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
|
||||
[CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
|
||||
[CLK_MMC1] = &mmc1_clk.common.hw,
|
||||
[CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
|
||||
[CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
|
||||
[CLK_MMC2] = &mmc2_clk.common.hw,
|
||||
[CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
|
||||
[CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
|
||||
[CLK_TS] = &ts_clk.common.hw,
|
||||
[CLK_CE] = &ce_clk.common.hw,
|
||||
[CLK_SPI0] = &spi0_clk.common.hw,
|
||||
[CLK_SPI1] = &spi1_clk.common.hw,
|
||||
[CLK_I2S0] = &i2s0_clk.common.hw,
|
||||
[CLK_I2S1] = &i2s1_clk.common.hw,
|
||||
[CLK_I2S2] = &i2s2_clk.common.hw,
|
||||
[CLK_SPDIF] = &spdif_clk.common.hw,
|
||||
[CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
|
||||
[CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
|
||||
[CLK_USB_PHY2] = &usb_phy2_clk.common.hw,
|
||||
[CLK_USB_PHY3] = &usb_phy3_clk.common.hw,
|
||||
[CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
|
||||
[CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
|
||||
[CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
|
||||
[CLK_USB_OHCI3] = &usb_ohci3_clk.common.hw,
|
||||
[CLK_DRAM] = &dram_clk.common.hw,
|
||||
[CLK_DRAM_VE] = &dram_ve_clk.common.hw,
|
||||
[CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
|
||||
[CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw,
|
||||
[CLK_DRAM_TS] = &dram_ts_clk.common.hw,
|
||||
[CLK_DE] = &de_clk.common.hw,
|
||||
[CLK_TCON0] = &tcon_clk.common.hw,
|
||||
[CLK_TVE] = &tve_clk.common.hw,
|
||||
[CLK_DEINTERLACE] = &deinterlace_clk.common.hw,
|
||||
[CLK_CSI_MISC] = &csi_misc_clk.common.hw,
|
||||
[CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
|
||||
[CLK_CSI_MCLK] = &csi_mclk_clk.common.hw,
|
||||
[CLK_VE] = &ve_clk.common.hw,
|
||||
[CLK_AC_DIG] = &ac_dig_clk.common.hw,
|
||||
[CLK_AVS] = &avs_clk.common.hw,
|
||||
[CLK_HDMI] = &hdmi_clk.common.hw,
|
||||
[CLK_HDMI_DDC] = &hdmi_ddc_clk.common.hw,
|
||||
[CLK_MBUS] = &mbus_clk.common.hw,
|
||||
[CLK_GPU] = &gpu_clk.common.hw,
|
||||
},
|
||||
.num = CLK_NUMBER,
|
||||
};
|
||||
|
||||
static struct ccu_reset_map sun8i_h3_ccu_resets[] = {
|
||||
[RST_USB_PHY0] = { 0x0cc, BIT(0) },
|
||||
[RST_USB_PHY1] = { 0x0cc, BIT(1) },
|
||||
[RST_USB_PHY2] = { 0x0cc, BIT(2) },
|
||||
[RST_USB_PHY3] = { 0x0cc, BIT(3) },
|
||||
|
||||
[RST_MBUS] = { 0x0fc, BIT(31) },
|
||||
|
||||
[RST_BUS_CE] = { 0x2c0, BIT(5) },
|
||||
[RST_BUS_DMA] = { 0x2c0, BIT(6) },
|
||||
[RST_BUS_MMC0] = { 0x2c0, BIT(8) },
|
||||
[RST_BUS_MMC1] = { 0x2c0, BIT(9) },
|
||||
[RST_BUS_MMC2] = { 0x2c0, BIT(10) },
|
||||
[RST_BUS_NAND] = { 0x2c0, BIT(13) },
|
||||
[RST_BUS_DRAM] = { 0x2c0, BIT(14) },
|
||||
[RST_BUS_EMAC] = { 0x2c0, BIT(17) },
|
||||
[RST_BUS_TS] = { 0x2c0, BIT(18) },
|
||||
[RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
|
||||
[RST_BUS_SPI0] = { 0x2c0, BIT(20) },
|
||||
[RST_BUS_SPI1] = { 0x2c0, BIT(21) },
|
||||
[RST_BUS_OTG] = { 0x2c0, BIT(23) },
|
||||
[RST_BUS_EHCI0] = { 0x2c0, BIT(24) },
|
||||
[RST_BUS_EHCI1] = { 0x2c0, BIT(25) },
|
||||
[RST_BUS_EHCI2] = { 0x2c0, BIT(26) },
|
||||
[RST_BUS_EHCI3] = { 0x2c0, BIT(27) },
|
||||
[RST_BUS_OHCI0] = { 0x2c0, BIT(28) },
|
||||
[RST_BUS_OHCI1] = { 0x2c0, BIT(29) },
|
||||
[RST_BUS_OHCI2] = { 0x2c0, BIT(30) },
|
||||
[RST_BUS_OHCI3] = { 0x2c0, BIT(31) },
|
||||
|
||||
[RST_BUS_VE] = { 0x2c4, BIT(0) },
|
||||
[RST_BUS_TCON0] = { 0x2c4, BIT(3) },
|
||||
[RST_BUS_TCON1] = { 0x2c4, BIT(4) },
|
||||
[RST_BUS_DEINTERLACE] = { 0x2c4, BIT(5) },
|
||||
[RST_BUS_CSI] = { 0x2c4, BIT(8) },
|
||||
[RST_BUS_TVE] = { 0x2c4, BIT(9) },
|
||||
[RST_BUS_HDMI0] = { 0x2c4, BIT(10) },
|
||||
[RST_BUS_HDMI1] = { 0x2c4, BIT(11) },
|
||||
[RST_BUS_DE] = { 0x2c4, BIT(12) },
|
||||
[RST_BUS_GPU] = { 0x2c4, BIT(20) },
|
||||
[RST_BUS_MSGBOX] = { 0x2c4, BIT(21) },
|
||||
[RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) },
|
||||
[RST_BUS_DBG] = { 0x2c4, BIT(31) },
|
||||
|
||||
[RST_BUS_EPHY] = { 0x2c8, BIT(2) },
|
||||
|
||||
[RST_BUS_CODEC] = { 0x2d0, BIT(0) },
|
||||
[RST_BUS_SPDIF] = { 0x2d0, BIT(1) },
|
||||
[RST_BUS_THS] = { 0x2d0, BIT(8) },
|
||||
[RST_BUS_I2S0] = { 0x2d0, BIT(12) },
|
||||
[RST_BUS_I2S1] = { 0x2d0, BIT(13) },
|
||||
[RST_BUS_I2S2] = { 0x2d0, BIT(14) },
|
||||
|
||||
[RST_BUS_I2C0] = { 0x2d4, BIT(0) },
|
||||
[RST_BUS_I2C1] = { 0x2d4, BIT(1) },
|
||||
[RST_BUS_I2C2] = { 0x2d4, BIT(2) },
|
||||
[RST_BUS_UART0] = { 0x2d4, BIT(16) },
|
||||
[RST_BUS_UART1] = { 0x2d4, BIT(17) },
|
||||
[RST_BUS_UART2] = { 0x2d4, BIT(18) },
|
||||
[RST_BUS_UART3] = { 0x2d4, BIT(19) },
|
||||
[RST_BUS_SCR] = { 0x2d4, BIT(20) },
|
||||
};
|
||||
|
||||
static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = {
|
||||
.ccu_clks = sun8i_h3_ccu_clks,
|
||||
.num_ccu_clks = ARRAY_SIZE(sun8i_h3_ccu_clks),
|
||||
|
||||
.hw_clks = &sun8i_h3_hw_clks,
|
||||
|
||||
.resets = sun8i_h3_ccu_resets,
|
||||
.num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets),
|
||||
};
|
||||
|
||||
static void __init sun8i_h3_ccu_setup(struct device_node *node)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%s: Could not map the clock registers\n",
|
||||
of_node_full_name(node));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, &sun8i_h3_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu",
|
||||
sun8i_h3_ccu_setup);
|
62
drivers/clk/sunxi-ng/ccu-sun8i-h3.h
Normal file
62
drivers/clk/sunxi-ng/ccu-sun8i-h3.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2016 Maxime Ripard
|
||||
*
|
||||
* Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CCU_SUN8I_H3_H_
|
||||
#define _CCU_SUN8I_H3_H_
|
||||
|
||||
#include <dt-bindings/clock/sun8i-h3-ccu.h>
|
||||
#include <dt-bindings/reset/sun8i-h3-ccu.h>
|
||||
|
||||
#define CLK_PLL_CPUX 0
|
||||
#define CLK_PLL_AUDIO_BASE 1
|
||||
#define CLK_PLL_AUDIO 2
|
||||
#define CLK_PLL_AUDIO_2X 3
|
||||
#define CLK_PLL_AUDIO_4X 4
|
||||
#define CLK_PLL_AUDIO_8X 5
|
||||
#define CLK_PLL_VIDEO 6
|
||||
#define CLK_PLL_VE 7
|
||||
#define CLK_PLL_DDR 8
|
||||
#define CLK_PLL_PERIPH0 9
|
||||
#define CLK_PLL_PERIPH0_2X 10
|
||||
#define CLK_PLL_GPU 11
|
||||
#define CLK_PLL_PERIPH1 12
|
||||
#define CLK_PLL_DE 13
|
||||
|
||||
/* The CPUX clock is exported */
|
||||
|
||||
#define CLK_AXI 15
|
||||
#define CLK_AHB1 16
|
||||
#define CLK_APB1 17
|
||||
#define CLK_APB2 18
|
||||
#define CLK_AHB2 19
|
||||
|
||||
/* All the bus gates are exported */
|
||||
|
||||
/* The first bunch of module clocks are exported */
|
||||
|
||||
#define CLK_DRAM 96
|
||||
|
||||
/* All the DRAM gates are exported */
|
||||
|
||||
/* Some more module clocks are exported */
|
||||
|
||||
#define CLK_MBUS 113
|
||||
|
||||
/* And the GPU module clock is exported */
|
||||
|
||||
#define CLK_NUMBER (CLK_GPU + 1)
|
||||
|
||||
#endif /* _CCU_SUN8I_H3_H_ */
|
90
drivers/clk/sunxi-ng/ccu_common.c
Normal file
90
drivers/clk/sunxi-ng/ccu_common.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2016 Maxime Ripard
|
||||
*
|
||||
* Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
|
||||
static DEFINE_SPINLOCK(ccu_lock);
|
||||
|
||||
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (!lock)
|
||||
return;
|
||||
|
||||
WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg,
|
||||
!(reg & lock), 100, 70000));
|
||||
}
|
||||
|
||||
int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
{
|
||||
struct ccu_reset *reset;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < desc->num_ccu_clks; i++) {
|
||||
struct ccu_common *cclk = desc->ccu_clks[i];
|
||||
|
||||
if (!cclk)
|
||||
continue;
|
||||
|
||||
cclk->base = reg;
|
||||
cclk->lock = &ccu_lock;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->hw_clks->num ; i++) {
|
||||
struct clk_hw *hw = desc->hw_clks->hws[i];
|
||||
|
||||
if (!hw)
|
||||
continue;
|
||||
|
||||
ret = clk_hw_register(NULL, hw);
|
||||
if (ret) {
|
||||
pr_err("Couldn't register clock %s\n",
|
||||
clk_hw_get_name(hw));
|
||||
goto err_clk_unreg;
|
||||
}
|
||||
}
|
||||
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
|
||||
desc->hw_clks);
|
||||
if (ret)
|
||||
goto err_clk_unreg;
|
||||
|
||||
reset = kzalloc(sizeof(*reset), GFP_KERNEL);
|
||||
reset->rcdev.of_node = node;
|
||||
reset->rcdev.ops = &ccu_reset_ops;
|
||||
reset->rcdev.owner = THIS_MODULE;
|
||||
reset->rcdev.nr_resets = desc->num_resets;
|
||||
reset->base = reg;
|
||||
reset->lock = &ccu_lock;
|
||||
reset->reset_map = desc->resets;
|
||||
|
||||
ret = reset_controller_register(&reset->rcdev);
|
||||
if (ret)
|
||||
goto err_of_clk_unreg;
|
||||
|
||||
return 0;
|
||||
|
||||
err_of_clk_unreg:
|
||||
err_clk_unreg:
|
||||
return ret;
|
||||
}
|
85
drivers/clk/sunxi-ng/ccu_common.h
Normal file
85
drivers/clk/sunxi-ng/ccu_common.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Maxime Ripard. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _COMMON_H_
|
||||
#define _COMMON_H_
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#define CCU_FEATURE_FRACTIONAL BIT(0)
|
||||
#define CCU_FEATURE_VARIABLE_PREDIV BIT(1)
|
||||
#define CCU_FEATURE_FIXED_PREDIV BIT(2)
|
||||
#define CCU_FEATURE_FIXED_POSTDIV BIT(3)
|
||||
|
||||
struct device_node;
|
||||
|
||||
#define CLK_HW_INIT(_name, _parent, _ops, _flags) \
|
||||
&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = (const char *[]) { _parent }, \
|
||||
.num_parents = 1, \
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
|
||||
&(struct clk_init_data) { \
|
||||
.flags = _flags, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.ops = _ops, \
|
||||
}
|
||||
|
||||
#define CLK_FIXED_FACTOR(_struct, _name, _parent, \
|
||||
_div, _mult, _flags) \
|
||||
struct clk_fixed_factor _struct = { \
|
||||
.div = _div, \
|
||||
.mult = _mult, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&clk_fixed_factor_ops, \
|
||||
_flags), \
|
||||
}
|
||||
|
||||
struct ccu_common {
|
||||
void __iomem *base;
|
||||
u16 reg;
|
||||
|
||||
unsigned long features;
|
||||
spinlock_t *lock;
|
||||
struct clk_hw hw;
|
||||
};
|
||||
|
||||
static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct ccu_common, hw);
|
||||
}
|
||||
|
||||
struct sunxi_ccu_desc {
|
||||
struct ccu_common **ccu_clks;
|
||||
unsigned long num_ccu_clks;
|
||||
|
||||
struct clk_hw_onecell_data *hw_clks;
|
||||
|
||||
struct ccu_reset_map *resets;
|
||||
unsigned long num_resets;
|
||||
};
|
||||
|
||||
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock);
|
||||
|
||||
int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc);
|
||||
|
||||
#endif /* _COMMON_H_ */
|
136
drivers/clk/sunxi-ng/ccu_div.c
Normal file
136
drivers/clk/sunxi-ng/ccu_div.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Maxime Ripard
|
||||
* Maxime Ripard <maxime.ripard@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "ccu_gate.h"
|
||||
#include "ccu_div.h"
|
||||
|
||||
static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
|
||||
unsigned long parent_rate,
|
||||
unsigned long rate,
|
||||
void *data)
|
||||
{
|
||||
struct ccu_div *cd = data;
|
||||
unsigned long val;
|
||||
|
||||
/*
|
||||
* We can't use divider_round_rate that assumes that there's
|
||||
* several parents, while we might be called to evaluate
|
||||
* several different parents.
|
||||
*/
|
||||
val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
|
||||
cd->div.flags);
|
||||
|
||||
return divider_recalc_rate(&cd->common.hw, parent_rate, val,
|
||||
cd->div.table, cd->div.flags);
|
||||
}
|
||||
|
||||
static void ccu_div_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_gate_helper_disable(&cd->common, cd->enable);
|
||||
}
|
||||
|
||||
static int ccu_div_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_gate_helper_enable(&cd->common, cd->enable);
|
||||
}
|
||||
|
||||
static int ccu_div_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_gate_helper_is_enabled(&cd->common, cd->enable);
|
||||
}
|
||||
|
||||
static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
unsigned long val;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(cd->common.base + cd->common.reg);
|
||||
val = reg >> cd->div.shift;
|
||||
val &= (1 << cd->div.width) - 1;
|
||||
|
||||
ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1,
|
||||
&parent_rate);
|
||||
|
||||
return divider_recalc_rate(hw, parent_rate, val, cd->div.table,
|
||||
cd->div.flags);
|
||||
}
|
||||
|
||||
static int ccu_div_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
|
||||
req, ccu_div_round_rate, cd);
|
||||
}
|
||||
|
||||
static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
unsigned long flags;
|
||||
unsigned long val;
|
||||
u32 reg;
|
||||
|
||||
ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1,
|
||||
&parent_rate);
|
||||
|
||||
val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
|
||||
cd->div.flags);
|
||||
|
||||
spin_lock_irqsave(cd->common.lock, flags);
|
||||
|
||||
reg = readl(cd->common.base + cd->common.reg);
|
||||
reg &= ~GENMASK(cd->div.width + cd->div.shift - 1, cd->div.shift);
|
||||
|
||||
writel(reg | (val << cd->div.shift),
|
||||
cd->common.base + cd->common.reg);
|
||||
|
||||
spin_unlock_irqrestore(cd->common.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 ccu_div_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_mux_helper_get_parent(&cd->common, &cd->mux);
|
||||
}
|
||||
|
||||
static int ccu_div_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_mux_helper_set_parent(&cd->common, &cd->mux, index);
|
||||
}
|
||||
|
||||
const struct clk_ops ccu_div_ops = {
|
||||
.disable = ccu_div_disable,
|
||||
.enable = ccu_div_enable,
|
||||
.is_enabled = ccu_div_is_enabled,
|
||||
|
||||
.get_parent = ccu_div_get_parent,
|
||||
.set_parent = ccu_div_set_parent,
|
||||
|
||||
.determine_rate = ccu_div_determine_rate,
|
||||
.recalc_rate = ccu_div_recalc_rate,
|
||||
.set_rate = ccu_div_set_rate,
|
||||
};
|
133
drivers/clk/sunxi-ng/ccu_div.h
Normal file
133
drivers/clk/sunxi-ng/ccu_div.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Maxime Ripard. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CCU_DIV_H_
|
||||
#define _CCU_DIV_H_
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_mux.h"
|
||||
|
||||
struct _ccu_div {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
|
||||
u32 flags;
|
||||
|
||||
struct clk_div_table *table;
|
||||
};
|
||||
|
||||
#define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags) \
|
||||
{ \
|
||||
.shift = _shift, \
|
||||
.width = _width, \
|
||||
.flags = _flags, \
|
||||
.table = _table, \
|
||||
}
|
||||
|
||||
#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
|
||||
_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, _flags)
|
||||
|
||||
#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
|
||||
_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
|
||||
|
||||
#define _SUNXI_CCU_DIV(_shift, _width) \
|
||||
_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, 0)
|
||||
|
||||
struct ccu_div {
|
||||
u32 enable;
|
||||
|
||||
struct _ccu_div div;
|
||||
struct ccu_mux_internal mux;
|
||||
struct ccu_common common;
|
||||
};
|
||||
|
||||
#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_shift, _width, \
|
||||
_table, _gate, _flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \
|
||||
_table), \
|
||||
.enable = _gate, \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg, \
|
||||
_shift, _width, \
|
||||
_table, _flags) \
|
||||
SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_shift, _width, _table, 0, \
|
||||
_flags)
|
||||
|
||||
#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, _muxshift, _muxwidth, \
|
||||
_gate, _flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.enable = _gate, \
|
||||
.div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS(_name, \
|
||||
_parents, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, _muxshift, _muxwidth, \
|
||||
_flags) \
|
||||
SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, _muxshift, _muxwidth, \
|
||||
0, _flags)
|
||||
|
||||
|
||||
#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_mshift, _mwidth, _gate, \
|
||||
_flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.enable = _gate, \
|
||||
.div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth, \
|
||||
_flags) \
|
||||
SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_mshift, _mwidth, 0, _flags)
|
||||
|
||||
static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_common *common = hw_to_ccu_common(hw);
|
||||
|
||||
return container_of(common, struct ccu_div, common);
|
||||
}
|
||||
|
||||
extern const struct clk_ops ccu_div_ops;
|
||||
|
||||
#endif /* _CCU_DIV_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user