Commit 2fbae64a authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'sunxi-clk-for-4.11' of...

Merge tag 'sunxi-clk-for-4.11' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next

Pull Allwinner clock updates from Maxime Ripard:

  - Support for one new SoC, the V3s
  - Conversion of two old SoCs to the new framework, the old sun5i family
    and the A80
  - A bunch of fixes

* tag 'sunxi-clk-for-4.11' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux: (25 commits)
  ARM: dts: sun9i: Switch to new clock bindings
  clk: sunxi-ng: Add A80 Display Engine CCU
  clk: sunxi-ng: Add A80 USB CCU
  clk: sunxi-ng: Add A80 CCU
  clk: sunxi-ng: Support separately grouped PLL lock status register
  clk: sunxi-ng: mux: Get closest parent rate possible with CLK_SET_RATE_PARENT
  clk: sunxi-ng: mux: honor CLK_SET_RATE_NO_REPARENT flag
  clk: sunxi-ng: mux: Fix determine_rate for mux clocks with pre-dividers
  clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for the GPU
  clk: sunxi-ng: Call divider_round_rate if we only have a single parent
  ARM: gr8: Convert to CCU
  ARM: sun5i: Convert to CCU
  clk: sunxi-ng: Add sun5i CCU driver
  clk: sunxi-ng: Implement global pre-divider
  clk: sunxi-ng: Implement multiplier maximum
  clk: sunxi-ng: mult: Fix minimum in round rate
  clk: sunxi-ng: Implement factors offsets
  clk: sunxi-ng: multiplier: Add fractional support
  clk: sunxi-ng: add support for V3s CCU
  dt-bindings: add device binding for the CCU of Allwinner V3s
  ...
parents eaff16bc 64507fe3
Allwinner A80 Display Engine Clock Control Binding
--------------------------------------------------
Required properties :
- compatible: must contain one of the following compatibles:
- "allwinner,sun9i-a80-de-clks"
- reg: Must contain the registers base address and length
- clocks: phandle to the clocks feeding the display engine subsystem.
Three are needed:
- "mod": the display engine module clock
- "dram": the DRAM bus clock for the system
- "bus": the bus clock for the whole display engine subsystem
- clock-names: Must contain the clock names described just above
- resets: phandle to the reset control for the display engine subsystem.
- #clock-cells : must contain 1
- #reset-cells : must contain 1
Example:
de_clocks: clock@3000000 {
compatible = "allwinner,sun9i-a80-de-clks";
reg = <0x03000000 0x30>;
clocks = <&ccu CLK_DE>, <&ccu CLK_SDRAM>, <&ccu CLK_BUS_DE>;
clock-names = "mod", "dram", "bus";
resets = <&ccu RST_BUS_DE>;
#clock-cells = <1>;
#reset-cells = <1>;
};
Allwinner A80 USB Clock Control Binding
---------------------------------------
Required properties :
- compatible: must contain one of the following compatibles:
- "allwinner,sun9i-a80-usb-clocks"
- reg: Must contain the registers base address and length
- clocks: phandle to the clocks feeding the USB subsystem. Two are needed:
- "bus": the bus clock for the whole USB subsystem
- "hosc": the high frequency oscillator (usually at 24MHz)
- clock-names: Must contain the clock names described just above
- #clock-cells : must contain 1
- #reset-cells : must contain 1
Example:
usb_clocks: clock@a08000 {
compatible = "allwinner,sun9i-a80-usb-clks";
reg = <0x00a08000 0x8>;
clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
clock-names = "bus", "hosc";
#clock-cells = <1>;
#reset-cells = <1>;
};
......@@ -7,6 +7,8 @@ Required properties :
- "allwinner,sun8i-a23-ccu"
- "allwinner,sun8i-a33-ccu"
- "allwinner,sun8i-h3-ccu"
- "allwinner,sun8i-v3s-ccu"
- "allwinner,sun9i-a80-ccu"
- "allwinner,sun50i-a64-ccu"
- reg: Must contain the registers base address and length
......
......@@ -65,8 +65,9 @@ framebuffer@0 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 43>, <&ahb_gates 44>;
clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_HDMI>,
<&ccu CLK_AHB_DE_BE>, <&ccu CLK_DRAM_DE_BE>,
<&ccu CLK_DE_BE>, <&ccu CLK_HDMI>;
status = "disabled";
};
......@@ -74,8 +75,8 @@ framebuffer@1 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 44>;
clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
status = "disabled";
};
......@@ -83,77 +84,19 @@ framebuffer@2 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-tve0";
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 34>,
<&ahb_gates 36>, <&ahb_gates 44>;
clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
<&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
status = "disabled";
};
};
clocks {
ahb_gates: clk@01c20060 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a10s-ahb-gates-clk";
reg = <0x01c20060 0x8>;
clocks = <&ahb>;
clock-indices = <0>, <1>,
<2>, <5>, <6>,
<7>, <8>, <9>,
<10>, <13>,
<14>, <17>, <18>,
<20>, <21>, <22>,
<26>, <28>, <32>,
<34>, <36>, <40>,
<43>, <44>,
<46>, <51>,
<52>;
clock-output-names = "ahb_usbotg", "ahb_ehci",
"ahb_ohci", "ahb_ss", "ahb_dma",
"ahb_bist", "ahb_mmc0", "ahb_mmc1",
"ahb_mmc2", "ahb_nand",
"ahb_sdram", "ahb_emac", "ahb_ts",
"ahb_spi0", "ahb_spi1", "ahb_spi2",
"ahb_gps", "ahb_stimer", "ahb_ve",
"ahb_tve", "ahb_lcd", "ahb_csi",
"ahb_hdmi", "ahb_de_be",
"ahb_de_fe", "ahb_iep",
"ahb_mali400";
};
apb0_gates: clk@01c20068 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a10s-apb0-gates-clk";
reg = <0x01c20068 0x4>;
clocks = <&apb0>;
clock-indices = <0>, <3>,
<5>, <6>,
<10>;
clock-output-names = "apb0_codec", "apb0_iis",
"apb0_pio", "apb0_ir",
"apb0_keypad";
};
apb1_gates: clk@01c2006c {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a10s-apb1-gates-clk";
reg = <0x01c2006c 0x4>;
clocks = <&apb1>;
clock-indices = <0>, <1>,
<2>, <16>,
<17>, <18>,
<19>;
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_uart0",
"apb1_uart1", "apb1_uart2",
"apb1_uart3";
};
};
soc@01c00000 {
emac: ethernet@01c0b000 {
compatible = "allwinner,sun4i-a10-emac";
reg = <0x01c0b000 0x1000>;
interrupts = <55>;
clocks = <&ahb_gates 17>;
clocks = <&ccu CLK_AHB_EMAC>;
allwinner,sram = <&emac_sram 1>;
status = "disabled";
};
......@@ -169,7 +112,7 @@ mdio: mdio@01c0b080 {
pwm: pwm@01c20e00 {
compatible = "allwinner,sun5i-a10s-pwm";
reg = <0x01c20e00 0xc>;
clocks = <&osc24M>;
clocks = <&ccu CLK_HOSC>;
#pwm-cells = <3>;
status = "disabled";
};
......@@ -180,7 +123,7 @@ uart0: serial@01c28000 {
interrupts = <1>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 16>;
clocks = <&ccu CLK_APB1_UART0>;
status = "disabled";
};
......@@ -190,12 +133,16 @@ uart2: serial@01c28800 {
interrupts = <3>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
clocks = <&ccu CLK_APB1_UART2>;
status = "disabled";
};
};
};
&ccu {
compatible = "allwinner,sun5i-a10s-ccu";
};
&pio {
compatible = "allwinner,sun5i-a10s-pinctrl";
......
......@@ -61,8 +61,8 @@ framebuffer@0 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
clocks = <&ahb_gates 36>, <&ahb_gates 44>, <&de_be_clk>,
<&tcon_ch0_clk>, <&dram_gates 26>;
clocks = <&ccu CLK_AHB_LCD>, <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_TCON_CH0>, <&ccu CLK_DRAM_DE_BE>;
status = "disabled";
};
};
......@@ -99,114 +99,6 @@ cpu_crit: cpu_crit {
};
};
clocks {
ahb_gates: clk@01c20060 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-ahb-gates-clk";
reg = <0x01c20060 0x8>;
clocks = <&ahb>;
clock-indices = <0>, <1>,
<2>, <5>, <6>,
<7>, <8>, <9>,
<10>, <13>,
<14>, <20>,
<21>, <22>,
<28>, <32>, <34>,
<36>, <40>, <44>,
<46>, <51>,
<52>;
clock-output-names = "ahb_usbotg", "ahb_ehci",
"ahb_ohci", "ahb_ss", "ahb_dma",
"ahb_bist", "ahb_mmc0", "ahb_mmc1",
"ahb_mmc2", "ahb_nand",
"ahb_sdram", "ahb_spi0",
"ahb_spi1", "ahb_spi2",
"ahb_stimer", "ahb_ve", "ahb_tve",
"ahb_lcd", "ahb_csi", "ahb_de_be",
"ahb_de_fe", "ahb_iep",
"ahb_mali400";
};
apb0_gates: clk@01c20068 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-apb0-gates-clk";
reg = <0x01c20068 0x4>;
clocks = <&apb0>;
clock-indices = <0>, <5>,
<6>;
clock-output-names = "apb0_codec", "apb0_pio",
"apb0_ir";
};
apb1_gates: clk@01c2006c {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-apb1-gates-clk";
reg = <0x01c2006c 0x4>;
clocks = <&apb1>;
clock-indices = <0>, <1>,
<2>, <17>,
<19>;
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_uart1",
"apb1_uart3";
};
dram_gates: clk@01c20100 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-dram-gates-clk",
"allwinner,sun4i-a10-gates-clk";
reg = <0x01c20100 0x4>;
clocks = <&pll5 0>;
clock-indices = <0>,
<1>,
<25>,
<26>,
<29>,
<31>;
clock-output-names = "dram_ve",
"dram_csi",
"dram_de_fe",
"dram_de_be",
"dram_ace",
"dram_iep";
};
de_be_clk: clk@01c20104 {
#clock-cells = <0>;
#reset-cells = <0>;
compatible = "allwinner,sun4i-a10-display-clk";
reg = <0x01c20104 0x4>;
clocks = <&pll3>, <&pll7>, <&pll5 1>;
clock-output-names = "de-be";
};
de_fe_clk: clk@01c2010c {
#clock-cells = <0>;
#reset-cells = <0>;
compatible = "allwinner,sun4i-a10-display-clk";
reg = <0x01c2010c 0x4>;
clocks = <&pll3>, <&pll7>, <&pll5 1>;
clock-output-names = "de-fe";
};
tcon_ch0_clk: clk@01c20118 {
#clock-cells = <0>;
#reset-cells = <1>;
compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
reg = <0x01c20118 0x4>;
clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
clock-output-names = "tcon-ch0-sclk";
};
tcon_ch1_clk: clk@01c2012c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
reg = <0x01c2012c 0x4>;
clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
clock-output-names = "tcon-ch1-sclk";
};
};
display-engine {
compatible = "allwinner,sun5i-a13-display-engine";
allwinner,pipelines = <&fe0>;
......@@ -217,11 +109,11 @@ tcon0: lcd-controller@01c0c000 {
compatible = "allwinner,sun5i-a13-tcon";
reg = <0x01c0c000 0x1000>;
interrupts = <44>;
resets = <&tcon_ch0_clk 1>;
resets = <&ccu RST_LCD>;
reset-names = "lcd";
clocks = <&ahb_gates 36>,
<&tcon_ch0_clk>,
<&tcon_ch1_clk>;
clocks = <&ccu CLK_AHB_LCD>,
<&ccu CLK_TCON_CH0>,
<&ccu CLK_TCON_CH1>;
clock-names = "ahb",
"tcon-ch0",
"tcon-ch1";
......@@ -254,7 +146,7 @@ tcon0_out: port@1 {
pwm: pwm@01c20e00 {
compatible = "allwinner,sun5i-a13-pwm";
reg = <0x01c20e00 0xc>;
clocks = <&osc24M>;
clocks = <&ccu CLK_HOSC>;
#pwm-cells = <3>;
status = "disabled";
};
......@@ -263,11 +155,11 @@ fe0: display-frontend@01e00000 {
compatible = "allwinner,sun5i-a13-display-frontend";
reg = <0x01e00000 0x20000>;
interrupts = <47>;
clocks = <&ahb_gates 46>, <&de_fe_clk>,
<&dram_gates 25>;
clocks = <&ccu CLK_DE_FE>, <&ccu CLK_DE_FE>,
<&ccu CLK_DRAM_DE_FE>;
clock-names = "ahb", "mod",
"ram";
resets = <&de_fe_clk>;
resets = <&ccu RST_DE_FE>;
status = "disabled";
ports {
......@@ -290,14 +182,14 @@ fe0_out_be0: endpoint@0 {
be0: display-backend@01e60000 {
compatible = "allwinner,sun5i-a13-display-backend";
reg = <0x01e60000 0x10000>;
clocks = <&ahb_gates 44>, <&de_be_clk>,
<&dram_gates 26>;
clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_DRAM_DE_BE>;
clock-names = "ahb", "mod",
"ram";
resets = <&de_be_clk>;
resets = <&ccu RST_DE_BE>;
status = "disabled";
assigned-clocks = <&de_be_clk>;
assigned-clocks = <&ccu CLK_DE_BE>;
assigned-clock-rates = <300000000>;
ports {
......@@ -330,6 +222,10 @@ be0_out_tcon0: endpoint@0 {
};
};
&ccu {
compatible = "allwinner,sun5i-a13-ccu";
};
&cpu0 {
clock-latency = <244144>; /* 8 32k periods */
operating-points = <
......
......@@ -42,9 +42,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <dt-bindings/clock/sun4i-a10-pll2.h>
#include <dt-bindings/clock/sun5i-ccu.h>
#include <dt-bindings/dma/sun4i-a10.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
#include <dt-bindings/reset/sun5i-ccu.h>
/ {
interrupt-parent = <&intc>;
......@@ -59,7 +60,7 @@ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a8";
reg = <0x0>;
clocks = <&cpu>;
clocks = <&ccu CLK_CPU>;
};
};
......@@ -68,419 +69,19 @@ clocks {
#size-cells = <1>;
ranges;
/*
* This is a dummy clock, to be used as placeholder on
* other mux clocks when a specific parent clock is not
* yet implemented. It should be dropped when the driver
* is complete.
*/
dummy: dummy {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
};
osc24M: clk@01c20050 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-osc-clk";
reg = <0x01c20050 0x4>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc24M";
};
osc3M: osc3M-clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <8>;
clock-mult = <1>;
clocks = <&osc24M>;
clock-output-names = "osc3M";
};
osc32k: clk@0 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc32k";
};
pll1: clk@01c20000 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20000 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll1";
};
pll2: clk@01c20008 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-pll2-clk";
reg = <0x01c20008 0x8>;
clocks = <&osc24M>;
clock-output-names = "pll2-1x", "pll2-2x",
"pll2-4x", "pll2-8x";
};
pll3: clk@01c20010 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll3-clk";
reg = <0x01c20010 0x4>;
clocks = <&osc3M>;
clock-output-names = "pll3";
};
pll3x2: pll3x2-clk {
compatible = "allwinner,sun4i-a10-pll3-2x-clk";
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <2>;
clocks = <&pll3>;
clock-output-names = "pll3-2x";
};
pll4: clk@01c20018 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20018 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll4";
};
pll5: clk@01c20020 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-pll5-clk";
reg = <0x01c20020 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll5_ddr", "pll5_other";
};
pll6: clk@01c20028 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-pll6-clk";
reg = <0x01c20028 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
pll7: clk@01c20030 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll3-clk";
reg = <0x01c20030 0x4>;
clocks = <&osc3M>;
clock-output-names = "pll7";
};
pll7x2: pll7x2-clk {
compatible = "allwinner,sun4i-a10-pll3-2x-clk";
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <2>;
clocks = <&pll7>;
clock-output-names = "pll7-2x";
};
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-cpu-clk";
reg = <0x01c20054 0x4>;
clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
clock-output-names = "cpu";
};
axi: axi@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-axi-clk";
reg = <0x01c20054 0x4>;
clocks = <&cpu>;
clock-output-names = "axi";
};
ahb: ahb@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-ahb-clk";
reg = <0x01c20054 0x4>;
clocks = <&axi>, <&cpu>, <&pll6 1>;
clock-output-names = "ahb";
/*
* Use PLL6 as parent, instead of CPU/AXI
* which has rate changes due to cpufreq
*/
assigned-clocks = <&ahb>;
assigned-clock-parents = <&pll6 1>;
};
apb0: apb0@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb0-clk";
reg = <0x01c20054 0x4>;
clocks = <&ahb>;
clock-output-names = "apb0";
};
apb1: clk@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb1-clk";
reg = <0x01c20058 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
clock-output-names = "apb1";
};
axi_gates: clk@01c2005c {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-gates-clk";
reg = <0x01c2005c 0x4>;
clocks = <&axi>;
clock-indices = <0>;
clock-output-names = "axi_dram";
};
ahb_gates: clk@01c20060 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-ahb-gates-clk";
reg = <0x01c20060 0x8>;
clocks = <&ahb>;
clock-indices = <0>, <1>,
<2>, <5>, <6>,
<7>, <8>, <9>,
<10>, <13>,
<14>, <17>, <20>,
<21>, <22>,
<28>, <32>, <34>,
<36>, <40>, <44>,
<46>, <51>,
<52>;
clock-output-names = "ahb_usbotg", "ahb_ehci",
"ahb_ohci", "ahb_ss", "ahb_dma",
"ahb_bist", "ahb_mmc0", "ahb_mmc1",
"ahb_mmc2", "ahb_nand",
"ahb_sdram", "ahb_emac", "ahb_spi0",
"ahb_spi1", "ahb_spi2",
"ahb_hstimer", "ahb_ve", "ahb_tve",
"ahb_lcd", "ahb_csi", "ahb_de_be",
"ahb_de_fe", "ahb_iep",
"ahb_mali400";
};
apb0_gates: clk@01c20068 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-gates-clk";
reg = <0x01c20068 0x4>;
clocks = <&apb0>;
clock-indices = <0>, <3>,
<5>, <6>;
clock-output-names = "apb0_codec", "apb0_i2s0",
"apb0_pio", "apb0_ir";
};
apb1_gates: clk@01c2006c {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-gates-clk";
reg = <0x01c2006c 0x4>;
clocks = <&apb1>;
clock-indices = <0>, <1>,
<2>, <17>,
<18>, <19>;
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_uart1",
"apb1_uart2", "apb1_uart3";
};
nand_clk: clk@01c20080 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20080 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "nand";
};
ms_clk: clk@01c20084 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20084 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ms";
};
mmc0_clk: clk@01c20088 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
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 1>, <&pll5 1>;
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 1>, <&pll5 1>;
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
ts_clk: clk@01c20098 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20098 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ts";
};
ss_clk: clk@01c2009c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c2009c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ss";
};
spi0_clk: clk@01c200a0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a0 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi0";
};
spi1_clk: clk@01c200a4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a4 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi1";
};
spi2_clk: clk@01c200a8 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a8 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi2";
};
ir0_clk: clk@01c200b0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200b0 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ir0";
};
i2s0_clk: clk@01c200b8 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod1-clk";
reg = <0x01c200b8 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_8X>,
<&pll2 SUN4I_A10_PLL2_4X>,
<&pll2 SUN4I_A10_PLL2_2X>,
<&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "i2s0";
};
spdif_clk: clk@01c200c0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod1-clk";
reg = <0x01c200c0 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_8X>,
<&pll2 SUN4I_A10_PLL2_4X>,
<&pll2 SUN4I_A10_PLL2_2X>,
<&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "spdif";
};
usb_clk: clk@01c200cc {
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun5i-a13-usb-clk";
reg = <0x01c200cc 0x4>;
clocks = <&pll6 1>;
clock-output-names = "usb_ohci0", "usb_phy";
};
dram_gates: clk@01c20100 {
#clock-cells = <1>;
compatible = "nextthing,gr8-dram-gates-clk",
"allwinner,sun4i-a10-gates-clk";
reg = <0x01c20100 0x4>;
clocks = <&pll5 0>;
clock-indices = <0>,
<1>,
<25>,
<26>,
<29>,
<31>;
clock-output-names = "dram_ve",
"dram_csi",
"dram_de_fe",
"dram_de_be",
"dram_ace",
"dram_iep";
};
de_be_clk: clk@01c20104 {
#clock-cells = <0>;
#reset-cells = <0>;
compatible = "allwinner,sun4i-a10-display-clk";
reg = <0x01c20104 0x4>;
clocks = <&pll3>, <&pll7>, <&pll5 1>;
clock-output-names = "de-be";
};
de_fe_clk: clk@01c2010c {
#clock-cells = <0>;
#reset-cells = <0>;
compatible = "allwinner,sun4i-a10-display-clk";
reg = <0x01c2010c 0x4>;
clocks = <&pll3>, <&pll7>, <&pll5 1>;
clock-output-names = "de-fe";
};
tcon_ch0_clk: clk@01c20118 {
#clock-cells = <0>;
#reset-cells = <1>;
compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
reg = <0x01c20118 0x4>;
clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
clock-output-names = "tcon-ch0-sclk";
};
tcon_ch1_clk: clk@01c2012c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
reg = <0x01c2012c 0x4>;
clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
clock-output-names = "tcon-ch1-sclk";
};
codec_clk: clk@01c20140 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-codec-clk";
reg = <0x01c20140 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "codec";
};
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-mbus-clk";
reg = <0x01c2015c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mbus";
};
};
display-engine {
......@@ -528,7 +129,7 @@ dma: dma-controller@01c02000 {
compatible = "allwinner,sun4i-a10-dma";
reg = <0x01c02000 0x1000>;
interrupts = <27>;
clocks = <&ahb_gates 6>;
clocks = <&ccu CLK_AHB_DMA>;
#dma-cells = <2>;
};
......@@ -536,7 +137,7 @@ nfc: nand@01c03000 {
compatible = "allwinner,sun4i-a10-nand";
reg = <0x01c03000 0x1000>;
interrupts = <37>;
clocks = <&ahb_gates 13>, <&nand_clk>;
clocks = <&ccu CLK_AHB_NAND>, <&ccu CLK_NAND>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 3>;
dma-names = "rxtx";
......@@ -549,7 +150,7 @@ spi0: spi@01c05000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c05000 0x1000>;
interrupts = <10>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 27>,
<&dma SUN4I_DMA_DEDICATED 26>;
......@@ -563,7 +164,7 @@ spi1: spi@01c06000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c06000 0x1000>;
interrupts = <11>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 9>,
<&dma SUN4I_DMA_DEDICATED 8>;
......@@ -576,8 +177,8 @@ spi1: spi@01c06000 {
tve0: tv-encoder@01c0a000 {
compatible = "allwinner,sun4i-a10-tv-encoder";
reg = <0x01c0a000 0x1000>;
clocks = <&ahb_gates 34>;
resets = <&tcon_ch0_clk 0>;
clocks = <&ccu CLK_AHB_TVE>;
resets = <&ccu RST_TVE>;
status = "disabled";
port {
......@@ -595,11 +196,11 @@ tcon0: lcd-controller@01c0c000 {
compatible = "allwinner,sun5i-a13-tcon";
reg = <0x01c0c000 0x1000>;
interrupts = <44>;
resets = <&tcon_ch0_clk 1>;
resets = <&ccu RST_LCD>;
reset-names = "lcd";
clocks = <&ahb_gates 36>,
<&tcon_ch0_clk>,
<&tcon_ch1_clk>;
clocks = <&ccu CLK_AHB_LCD>,
<&ccu CLK_TCON_CH0>,
<&ccu CLK_TCON_CH1>;
clock-names = "ahb",
"tcon-ch0",
"tcon-ch1";
......@@ -637,14 +238,8 @@ tcon0_out_tve0: endpoint@1 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
clock-names = "ahb", "mmc";
interrupts = <32>;
status = "disabled";
#address-cells = <1>;
......@@ -654,14 +249,8 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
clock-names = "ahb", "mmc";
interrupts = <33>;
status = "disabled";
#address-cells = <1>;
......@@ -671,14 +260,8 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
clock-names = "ahb", "mmc";
interrupts = <34>;
status = "disabled";
#address-cells = <1>;
......@@ -688,7 +271,7 @@ mmc2: mmc@01c11000 {
usb_otg: usb@01c13000 {
compatible = "allwinner,sun4i-a10-musb";
reg = <0x01c13000 0x0400>;
clocks = <&ahb_gates 0>;
clocks = <&ccu CLK_AHB_OTG>;
interrupts = <38>;
interrupt-names = "mc";
phys = <&usbphy 0>;
......@@ -705,9 +288,9 @@ usbphy: phy@01c13400 {
compatible = "allwinner,sun5i-a13-usb-phy";
reg = <0x01c13400 0x10 0x01c14800 0x4>;
reg-names = "phy_ctrl", "pmu1";
clocks = <&usb_clk 8>;
clocks = <&ccu CLK_USB_PHY0>;
clock-names = "usb_phy";
resets = <&usb_clk 0>, <&usb_clk 1>;
resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
reset-names = "usb0_reset", "usb1_reset";
status = "disabled";
};
......@@ -716,7 +299,7 @@ ehci0: usb@01c14000 {
compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
reg = <0x01c14000 0x100>;
interrupts = <39>;
clocks = <&ahb_gates 1>;
clocks = <&ccu CLK_AHB_EHCI>;
phys = <&usbphy 1>;
phy-names = "usb";
status = "disabled";
......@@ -726,7 +309,7 @@ ohci0: usb@01c14400 {
compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
reg = <0x01c14400 0x100>;
interrupts = <40>;
clocks = <&usb_clk 6>, <&ahb_gates 2>;
clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
phys = <&usbphy 1>;
phy-names = "usb";
status = "disabled";
......@@ -736,7 +319,7 @@ spi2: spi@01c17000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c17000 0x1000>;
interrupts = <12>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 29>,
<&dma SUN4I_DMA_DEDICATED 28>;
......@@ -746,6 +329,15 @@ spi2: spi@01c17000 {
#size-cells = <0>;
};
ccu: clock@01c20000 {
compatible = "nextthing,gr8-ccu";
reg = <0x01c20000 0x400>;
clocks = <&osc24M>, <&osc32k>;
clock-names = "hosc", "losc";
#clock-cells = <1>;
#reset-cells = <1>;
};
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-a10-ic";
reg = <0x01c20400 0x400>;
......@@ -757,7 +349,7 @@ pio: pinctrl@01c20800 {
compatible = "nextthing,gr8-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <28>;
clocks = <&apb0_gates 5>;
clocks = <&ccu CLK_APB0_PIO>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
......@@ -914,7 +506,7 @@ uart3_cts_rts_pins_a: uart3-cts-rts@0 {
pwm: pwm@01c20e00 {
compatible = "allwinner,sun5i-a10s-pwm";
reg = <0x01c20e00 0xc>;
clocks = <&osc24M>;
clocks = <&ccu CLK_HOSC>;
#pwm-cells = <3>;
status = "disabled";
};
......@@ -923,7 +515,7 @@ timer@01c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0x90>;
interrupts = <22>;
clocks = <&osc24M>;
clocks = <&ccu CLK_HOSC>;
};
wdt: watchdog@01c20c90 {
......@@ -936,7 +528,7 @@ spdif: spdif@01c21000 {
compatible = "allwinner,sun4i-a10-spdif";
reg = <0x01c21000 0x400>;
interrupts = <13>;
clocks = <&apb0_gates 1>, <&spdif_clk>;
clocks = <&ccu CLK_APB0_SPDIF>, <&ccu CLK_SPDIF>;
clock-names = "apb", "spdif";
dmas = <&dma SUN4I_DMA_NORMAL 2>,
<&dma SUN4I_DMA_NORMAL 2>;
......@@ -946,7 +538,7 @@ spdif: spdif@01c21000 {
ir0: ir@01c21800 {
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 6>, <&ir0_clk>;
clocks = <&ccu CLK_APB0_IR>, <&ccu CLK_IR>;
clock-names = "apb", "ir";
interrupts = <5>;
reg = <0x01c21800 0x40>;
......@@ -958,7 +550,7 @@ i2s0: i2s@01c22400 {
compatible = "allwinner,sun4i-a10-i2s";
reg = <0x01c22400 0x400>;
interrupts = <16>;
clocks = <&apb0_gates 3>, <&i2s0_clk>;
clocks = <&ccu CLK_APB0_I2S>, <&ccu CLK_I2S>;
clock-names = "apb", "mod";
dmas = <&dma SUN4I_DMA_NORMAL 3>,
<&dma SUN4I_DMA_NORMAL 3>;
......@@ -978,7 +570,7 @@ codec: codec@01c22c00 {
compatible = "allwinner,sun4i-a10-codec";
reg = <0x01c22c00 0x40>;
interrupts = <30>;
clocks = <&apb0_gates 0>, <&codec_clk>;
clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
clock-names = "apb", "codec";
dmas = <&dma SUN4I_DMA_NORMAL 19>,
<&dma SUN4I_DMA_NORMAL 19>;
......@@ -999,7 +591,7 @@ uart1: serial@01c28400 {
interrupts = <2>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
clocks = <&ccu CLK_APB1_UART1>;
status = "disabled";
};
......@@ -1009,7 +601,7 @@ uart2: serial@01c28800 {
interrupts = <3>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
clocks = <&ccu CLK_APB1_UART2>;
status = "disabled";
};
......@@ -1019,7 +611,7 @@ uart3: serial@01c28c00 {
interrupts = <4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
clocks = <&ccu CLK_APB1_UART3>;
status = "disabled";
};
......@@ -1027,7 +619,7 @@ i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2ac00 0x400>;
interrupts = <7>;
clocks = <&apb1_gates 0>;
clocks = <&ccu CLK_APB1_I2C0>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -1037,7 +629,7 @@ i2c1: i2c@01c2b000 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2b000 0x400>;
interrupts = <8>;
clocks = <&apb1_gates 1>;
clocks = <&ccu CLK_APB1_I2C1>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -1047,7 +639,7 @@ i2c2: i2c@01c2b400 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2b400 0x400>;
interrupts = <9>;
clocks = <&apb1_gates 2>;
clocks = <&ccu CLK_APB1_I2C2>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -1057,18 +649,18 @@ timer@01c60000 {
compatible = "allwinner,sun5i-a13-hstimer";
reg = <0x01c60000 0x1000>;
interrupts = <82>, <83>;
clocks = <&ahb_gates 28>;
clocks = <&ccu CLK_AHB_HSTIMER>;
};
fe0: display-frontend@01e00000 {
compatible = "allwinner,sun5i-a13-display-frontend";
reg = <0x01e00000 0x20000>;
interrupts = <47>;
clocks = <&ahb_gates 46>, <&de_fe_clk>,
<&dram_gates 25>;
clocks = <&ccu CLK_AHB_DE_FE>, <&ccu CLK_DE_FE>,
<&ccu CLK_DRAM_DE_FE>;
clock-names = "ahb", "mod",
"ram";
resets = <&de_fe_clk>;
resets = <&ccu RST_DE_FE>;
status = "disabled";
ports {
......@@ -1091,14 +683,14 @@ fe0_out_be0: endpoint@0 {
be0: display-backend@01e60000 {
compatible = "allwinner,sun5i-a13-display-backend";
reg = <0x01e60000 0x10000>;
clocks = <&ahb_gates 44>, <&de_be_clk>,
<&dram_gates 26>;
clocks = <&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_DRAM_DE_BE>;
clock-names = "ahb", "mod",
"ram";
resets = <&de_be_clk>;
resets = <&ccu RST_DE_BE>;
status = "disabled";
assigned-clocks = <&de_be_clk>;
assigned-clocks = <&ccu CLK_DE_BE>;
assigned-clock-rates = <300000000>;
ports {
......
......@@ -51,9 +51,9 @@ framebuffer@1 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-tve0";
clocks = <&ahb_gates 34>, <&ahb_gates 36>,
<&ahb_gates 44>, <&de_be_clk>,
<&tcon_ch1_clk>, <&dram_gates 26>;
clocks = <&ccu CLK_AHB_TVE>, <&ccu CLK_AHB_LCD>,
<&ccu CLK_AHB_DE_BE>, <&ccu CLK_DE_BE>,
<&ccu CLK_TCON_CH1>, <&ccu CLK_DRAM_DE_BE>;
status = "disabled";
};
};
......@@ -62,8 +62,8 @@ soc@01c00000 {
tve0: tv-encoder@01c0a000 {
compatible = "allwinner,sun4i-a10-tv-encoder";
reg = <0x01c0a000 0x1000>;
clocks = <&ahb_gates 34>;
resets = <&tcon_ch0_clk 0>;
clocks = <&ccu CLK_AHB_TVE>;
resets = <&ccu RST_TVE>;
status = "disabled";
port {
......
......@@ -44,9 +44,10 @@
#include "skeleton.dtsi"
#include <dt-bindings/clock/sun4i-a10-pll2.h>
#include <dt-bindings/clock/sun5i-ccu.h>
#include <dt-bindings/dma/sun4i-a10.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
#include <dt-bindings/reset/sun5i-ccu.h>
/ {
interrupt-parent = <&intc>;
......@@ -59,7 +60,7 @@ cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a8";
reg = <0x0>;
clocks = <&cpu>;
clocks = <&ccu CLK_CPU>;
};
};
......@@ -68,291 +69,19 @@ clocks {
#size-cells = <1>;
ranges;
/*
* This is a dummy clock, to be used as placeholder on
* other mux clocks when a specific parent clock is not
* yet implemented. It should be dropped when the driver
* is complete.
*/
dummy: dummy {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
};
osc24M: clk@01c20050 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-osc-clk";
reg = <0x01c20050 0x4>;
compatible = "fixed-clock";
clock-frequency = <24000000>;
clock-output-names = "osc24M";
};
osc3M: osc3M_clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <8>;
clock-mult = <1>;
clocks = <&osc24M>;
clock-output-names = "osc3M";
};
osc32k: clk@0 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc32k";
};
pll1: clk@01c20000 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20000 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll1";
};
pll2: clk@01c20008 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-pll2-clk";
reg = <0x01c20008 0x8>;
clocks = <&osc24M>;
clock-output-names = "pll2-1x", "pll2-2x",
"pll2-4x", "pll2-8x";
};
pll3: clk@01c20010 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll3-clk";
reg = <0x01c20010 0x4>;
clocks = <&osc3M>;
clock-output-names = "pll3";
};
pll3x2: pll3x2_clk {
compatible = "allwinner,sun4i-a10-pll3-2x-clk", "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <2>;
clocks = <&pll3>;
clock-output-names = "pll3-2x";
};
pll4: clk@01c20018 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20018 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll4";
};
pll5: clk@01c20020 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-pll5-clk";
reg = <0x01c20020 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll5_ddr", "pll5_other";
};
pll6: clk@01c20028 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-pll6-clk";
reg = <0x01c20028 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
pll7: clk@01c20030 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll3-clk";
reg = <0x01c20030 0x4>;
clocks = <&osc3M>;
clock-output-names = "pll7";
};
pll7x2: pll7x2_clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <2>;
clocks = <&pll7>;
clock-output-names = "pll7-2x";
};
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-cpu-clk";
reg = <0x01c20054 0x4>;
clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
clock-output-names = "cpu";
};
axi: axi@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-axi-clk";
reg = <0x01c20054 0x4>;
clocks = <&cpu>;
clock-output-names = "axi";
};
ahb: ahb@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-ahb-clk";
reg = <0x01c20054 0x4>;
clocks = <&axi>, <&cpu>, <&pll6 1>;
clock-output-names = "ahb";
/*
* Use PLL6 as parent, instead of CPU/AXI
* which has rate changes due to cpufreq
*/
assigned-clocks = <&ahb>;
assigned-clock-parents = <&pll6 1>;
};
apb0: apb0@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb0-clk";
reg = <0x01c20054 0x4>;
clocks = <&ahb>;
clock-output-names = "apb0";
};
apb1: clk@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb1-clk";
reg = <0x01c20058 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
clock-output-names = "apb1";
};
axi_gates: clk@01c2005c {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-axi-gates-clk";
reg = <0x01c2005c 0x4>;
clocks = <&axi>;
clock-indices = <0>;
clock-output-names = "axi_dram";
};
nand_clk: clk@01c20080 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20080 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "nand";
};
ms_clk: clk@01c20084 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20084 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ms";
};
mmc0_clk: clk@01c20088 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
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 1>, <&pll5 1>;
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 1>, <&pll5 1>;
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
ts_clk: clk@01c20098 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20098 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ts";
};
ss_clk: clk@01c2009c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c2009c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ss";
};
spi0_clk: clk@01c200a0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a0 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi0";
};
spi1_clk: clk@01c200a4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a4 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi1";
};
spi2_clk: clk@01c200a8 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a8 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi2";
};
ir0_clk: clk@01c200b0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200b0 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ir0";
};
usb_clk: clk@01c200cc {
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun5i-a13-usb-clk";
reg = <0x01c200cc 0x4>;
clocks = <&pll6 1>;
clock-output-names = "usb_ohci0", "usb_phy";
};
codec_clk: clk@01c20140 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-codec-clk";
reg = <0x01c20140 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "codec";
};
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-mbus-clk";
reg = <0x01c2015c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mbus";
};
};
soc@01c00000 {
......@@ -395,7 +124,7 @@ dma: dma-controller@01c02000 {
compatible = "allwinner,sun4i-a10-dma";
reg = <0x01c02000 0x1000>;
interrupts = <27>;
clocks = <&ahb_gates 6>;
clocks = <&ccu CLK_AHB_DMA>;
#dma-cells = <2>;
};
......@@ -403,7 +132,7 @@ spi0: spi@01c05000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c05000 0x1000>;
interrupts = <10>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clocks = <&ccu CLK_AHB_SPI0>, <&ccu CLK_SPI0>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 27>,
<&dma SUN4I_DMA_DEDICATED 26>;
......@@ -417,7 +146,7 @@ spi1: spi@01c06000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c06000 0x1000>;
interrupts = <11>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clocks = <&ccu CLK_AHB_SPI1>, <&ccu CLK_SPI1>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 9>,
<&dma SUN4I_DMA_DEDICATED 8>;
......@@ -430,14 +159,8 @@ spi1: spi@01c06000 {
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
clocks = <&ccu CLK_AHB_MMC0>, <&ccu CLK_MMC0>;
clock-names = "ahb", "mmc";
interrupts = <32>;
status = "disabled";
#address-cells = <1>;
......@@ -447,14 +170,8 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
clocks = <&ccu CLK_AHB_MMC1>, <&ccu CLK_MMC1>;
clock-names = "ahb", "mmc";
interrupts = <33>;
status = "disabled";
#address-cells = <1>;
......@@ -464,14 +181,8 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
clocks = <&ccu CLK_AHB_MMC2>, <&ccu CLK_MMC2>;
clock-names = "ahb", "mmc";
interrupts = <34>;
status = "disabled";
#address-cells = <1>;
......@@ -481,7 +192,7 @@ mmc2: mmc@01c11000 {
usb_otg: usb@01c13000 {
compatible = "allwinner,sun4i-a10-musb";
reg = <0x01c13000 0x0400>;
clocks = <&ahb_gates 0>;
clocks = <&ccu CLK_AHB_OTG>;
interrupts = <38>;
interrupt-names = "mc";
phys = <&usbphy 0>;
......@@ -496,9 +207,9 @@ usbphy: phy@01c13400 {
compatible = "allwinner,sun5i-a13-usb-phy";
reg = <0x01c13400 0x10 0x01c14800 0x4>;
reg-names = "phy_ctrl", "pmu1";
clocks = <&usb_clk 8>;
clocks = <&ccu CLK_USB_PHY0>;
clock-names = "usb_phy";
resets = <&usb_clk 0>, <&usb_clk 1>;
resets = <&ccu RST_USB_PHY0>, <&ccu RST_USB_PHY1>;
reset-names = "usb0_reset", "usb1_reset";
status = "disabled";
};
......@@ -507,7 +218,7 @@ ehci0: usb@01c14000 {
compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
reg = <0x01c14000 0x100>;
interrupts = <39>;
clocks = <&ahb_gates 1>;
clocks = <&ccu CLK_AHB_EHCI>;
phys = <&usbphy 1>;
phy-names = "usb";
status = "disabled";
......@@ -517,7 +228,7 @@ ohci0: usb@01c14400 {
compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
reg = <0x01c14400 0x100>;
interrupts = <40>;
clocks = <&usb_clk 6>, <&ahb_gates 2>;
clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>;
phys = <&usbphy 1>;
phy-names = "usb";
status = "disabled";
......@@ -527,7 +238,7 @@ spi2: spi@01c17000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c17000 0x1000>;
interrupts = <12>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clocks = <&ccu CLK_AHB_SPI2>, <&ccu CLK_SPI2>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 29>,
<&dma SUN4I_DMA_DEDICATED 28>;
......@@ -537,6 +248,14 @@ spi2: spi@01c17000 {
#size-cells = <0>;
};
ccu: clock@01c20000 {
reg = <0x01c20000 0x400>;
clocks = <&osc24M>, <&osc32k>;
clock-names = "hosc", "losc";
#clock-cells = <1>;
#reset-cells = <1>;
};
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-a10-ic";
reg = <0x01c20400 0x400>;
......@@ -547,7 +266,7 @@ intc: interrupt-controller@01c20400 {
pio: pinctrl@01c20800 {
reg = <0x01c20800 0x400>;
interrupts = <28>;
clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>;
clocks = <&ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
......@@ -642,7 +361,7 @@ timer@01c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0x90>;
interrupts = <22>;
clocks = <&osc24M>;
clocks = <&ccu CLK_HOSC>;
};
wdt: watchdog@01c20c90 {
......@@ -662,7 +381,7 @@ codec: codec@01c22c00 {
compatible = "allwinner,sun4i-a10-codec";
reg = <0x01c22c00 0x40>;
interrupts = <30>;
clocks = <&apb0_gates 0>, <&codec_clk>;
clocks = <&ccu CLK_APB0_CODEC>, <&ccu CLK_CODEC>;
clock-names = "apb", "codec";
dmas = <&dma SUN4I_DMA_NORMAL 19>,
<&dma SUN4I_DMA_NORMAL 19>;
......@@ -688,7 +407,7 @@ uart1: serial@01c28400 {
interrupts = <2>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
clocks = <&ccu CLK_APB1_UART1>;
status = "disabled";
};
......@@ -698,7 +417,7 @@ uart3: serial@01c28c00 {
interrupts = <4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
clocks = <&ccu CLK_APB1_UART3>;
status = "disabled";
};
......@@ -706,7 +425,7 @@ i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2ac00 0x400>;
interrupts = <7>;
clocks = <&apb1_gates 0>;
clocks = <&ccu CLK_APB1_I2C0>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -716,7 +435,7 @@ i2c1: i2c@01c2b000 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2b000 0x400>;
interrupts = <8>;
clocks = <&apb1_gates 1>;
clocks = <&ccu CLK_APB1_I2C1>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -726,7 +445,7 @@ i2c2: i2c@01c2b400 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2b400 0x400>;
interrupts = <9>;
clocks = <&apb1_gates 2>;
clocks = <&ccu CLK_APB1_I2C2>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -736,7 +455,7 @@ timer@01c60000 {
compatible = "allwinner,sun5i-a13-hstimer";
reg = <0x01c60000 0x1000>;
interrupts = <82>, <83>;
clocks = <&ahb_gates 28>;
clocks = <&ccu CLK_AHB_HSTIMER>;
};
};
};
......@@ -48,6 +48,13 @@
#include <dt-bindings/pinctrl/sun4i-a10.h>
#include <dt-bindings/clock/sun9i-a80-ccu.h>
#include <dt-bindings/clock/sun9i-a80-de.h>
#include <dt-bindings/clock/sun9i-a80-usb.h>
#include <dt-bindings/reset/sun9i-a80-ccu.h>
#include <dt-bindings/reset/sun9i-a80-de.h>
#include <dt-bindings/reset/sun9i-a80-usb.h>
/ {
interrupt-parent = <&gic>;
......@@ -159,228 +166,13 @@ osc32k: osc32k_clk {
clock-output-names = "osc32k";
};
usb_mod_clk: clk@00a08000 {
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun9i-a80-usb-mod-clk";
reg = <0x00a08000 0x4>;
clocks = <&ahb1_gates 1>;
clock-output-names = "usb0_ahb", "usb_ohci0",
"usb1_ahb", "usb_ohci1",
"usb2_ahb", "usb_ohci2";
};
usb_phy_clk: clk@00a08004 {
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun9i-a80-usb-phy-clk";
reg = <0x00a08004 0x4>;
clocks = <&ahb1_gates 1>;
clock-output-names = "usb_phy0", "usb_hsic1_480M",
"usb_phy1", "usb_hsic2_480M",
"usb_phy2", "usb_hsic_12M";
};
pll3: clk@06000008 {
/* placeholder until implemented */
#clock-cells = <0>;
compatible = "fixed-clock";
clock-rate = <0>;
clock-output-names = "pll3";
};
pll4: clk@0600000c {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-pll4-clk";
reg = <0x0600000c 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll4";
};
pll12: clk@0600002c {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-pll4-clk";
reg = <0x0600002c 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll12";
};
gt_clk: clk@0600005c {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-gt-clk";
reg = <0x0600005c 0x4>;
clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
clock-output-names = "gt";
};
ahb0: clk@06000060 {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-ahb-clk";
reg = <0x06000060 0x4>;
clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
clock-output-names = "ahb0";
};
ahb1: clk@06000064 {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-ahb-clk";
reg = <0x06000064 0x4>;
clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
clock-output-names = "ahb1";
};
ahb2: clk@06000068 {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-ahb-clk";
reg = <0x06000068 0x4>;
clocks = <&gt_clk>, <&pll4>, <&pll12>, <&pll12>;
clock-output-names = "ahb2";
};
apb0: clk@06000070 {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-apb0-clk";
reg = <0x06000070 0x4>;
clocks = <&osc24M>, <&pll4>;
clock-output-names = "apb0";
};
apb1: clk@06000074 {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-apb1-clk";
reg = <0x06000074 0x4>;
clocks = <&osc24M>, <&pll4>;
clock-output-names = "apb1";
};
cci400_clk: clk@06000078 {
#clock-cells = <0>;
compatible = "allwinner,sun9i-a80-gt-clk";
reg = <0x06000078 0x4>;
clocks = <&osc24M>, <&pll4>, <&pll12>, <&pll12>;
clock-output-names = "cci400";
};
mmc0_clk: clk@06000410 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-mmc-clk";
reg = <0x06000410 0x4>;
clocks = <&osc24M>, <&pll4>;
clock-output-names = "mmc0", "mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@06000414 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-mmc-clk";
reg = <0x06000414 0x4>;
clocks = <&osc24M>, <&pll4>;
clock-output-names = "mmc1", "mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@06000418 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-mmc-clk";
reg = <0x06000418 0x4>;
clocks = <&osc24M>, <&pll4>;
clock-output-names = "mmc2", "mmc2_output",
"mmc2_sample";
};
mmc3_clk: clk@0600041c {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-mmc-clk";
reg = <0x0600041c 0x4>;
clocks = <&osc24M>, <&pll4>;
clock-output-names = "mmc3", "mmc3_output",
"mmc3_sample";
};
ahb0_gates: clk@06000580 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-ahb0-gates-clk";
reg = <0x06000580 0x4>;
clocks = <&ahb0>;
clock-indices = <0>, <1>, <3>,
<5>, <8>, <12>,
<13>, <14>,
<15>, <16>, <18>,
<20>, <21>, <22>,
<23>;
clock-output-names = "ahb0_fd", "ahb0_ve", "ahb0_gpu",
"ahb0_ss", "ahb0_sd", "ahb0_nand1",
"ahb0_nand0", "ahb0_sdram",
"ahb0_mipi_hsi", "ahb0_sata", "ahb0_ts",
"ahb0_spi0", "ahb0_spi1", "ahb0_spi2",
"ahb0_spi3";
};
ahb1_gates: clk@06000584 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-ahb1-gates-clk";
reg = <0x06000584 0x4>;
clocks = <&ahb1>;
clock-indices = <0>, <1>,
<17>, <21>,
<22>, <23>,
<24>;
clock-output-names = "ahb1_usbotg", "ahb1_usbhci",
"ahb1_gmac", "ahb1_msgbox",
"ahb1_spinlock", "ahb1_hstimer",
"ahb1_dma";
};
ahb2_gates: clk@06000588 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-ahb2-gates-clk";
reg = <0x06000588 0x4>;
clocks = <&ahb2>;
clock-indices = <0>, <1>,
<2>, <4>, <5>,
<7>, <8>, <11>;
clock-output-names = "ahb2_lcd0", "ahb2_lcd1",
"ahb2_edp", "ahb2_csi", "ahb2_hdmi",
"ahb2_de", "ahb2_mp", "ahb2_mipi_dsi";
};
apb0_gates: clk@06000590 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-apb0-gates-clk";
reg = <0x06000590 0x4>;
clocks = <&apb0>;
clock-indices = <1>, <5>,
<11>, <12>, <13>,
<15>, <17>, <18>,
<19>;
clock-output-names = "apb0_spdif", "apb0_pio",
"apb0_ac97", "apb0_i2s0", "apb0_i2s1",
"apb0_lradc", "apb0_gpadc", "apb0_twd",
"apb0_cirtx";
};
apb1_gates: clk@06000594 {
#clock-cells = <1>;
compatible = "allwinner,sun9i-a80-apb1-gates-clk";
reg = <0x06000594 0x4>;
clocks = <&apb1>;
clock-indices = <0>, <1>,
<2>, <3>, <4>,
<16>, <17>,
<18>, <19>,
<20>, <21>;
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_i2c3", "apb1_i2c4",
"apb1_uart0", "apb1_uart1",
"apb1_uart2", "apb1_uart3",
"apb1_uart4", "apb1_uart5";
};
cpus_clk: clk@08001410 {
compatible = "allwinner,sun9i-a80-cpus-clk";
reg = <0x08001410 0x4>;
#clock-cells = <0>;
clocks = <&osc32k>, <&osc24M>, <&pll4>, <&pll3>;
clocks = <&osc32k>, <&osc24M>,
<&ccu CLK_PLL_PERIPH0>,
<&ccu CLK_PLL_AUDIO>;
clock-output-names = "cpus";
};
......@@ -453,8 +245,8 @@ ehci0: usb@00a00000 {
compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
reg = <0x00a00000 0x100>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_mod_clk 1>;
resets = <&usb_mod_clk 17>;
clocks = <&usb_clocks CLK_BUS_HCI0>;
resets = <&usb_clocks RST_USB0_HCI>;
phys = <&usbphy1>;
phy-names = "usb";
status = "disabled";
......@@ -464,8 +256,9 @@ ohci0: usb@00a00400 {
compatible = "allwinner,sun9i-a80-ohci", "generic-ohci";
reg = <0x00a00400 0x100>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_mod_clk 1>, <&usb_mod_clk 2>;
resets = <&usb_mod_clk 17>;
clocks = <&usb_clocks CLK_BUS_HCI0>,
<&usb_clocks CLK_USB_OHCI0>;
resets = <&usb_clocks RST_USB0_HCI>;
phys = <&usbphy1>;
phy-names = "usb";
status = "disabled";
......@@ -474,9 +267,9 @@ ohci0: usb@00a00400 {
usbphy1: phy@00a00800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a00800 0x4>;
clocks = <&usb_phy_clk 1>;
clocks = <&usb_clocks CLK_USB0_PHY>;
clock-names = "phy";
resets = <&usb_phy_clk 17>;
resets = <&usb_clocks RST_USB0_PHY>;
reset-names = "phy";
status = "disabled";
#phy-cells = <0>;
......@@ -486,8 +279,8 @@ ehci1: usb@00a01000 {
compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
reg = <0x00a01000 0x100>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_mod_clk 3>;
resets = <&usb_mod_clk 18>;
clocks = <&usb_clocks CLK_BUS_HCI1>;
resets = <&usb_clocks RST_USB1_HCI>;
phys = <&usbphy2>;
phy-names = "usb";
status = "disabled";
......@@ -496,11 +289,16 @@ ehci1: usb@00a01000 {
usbphy2: phy@00a01800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a01800 0x4>;
clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>,
<&usb_phy_clk 3>;
clock-names = "hsic_480M", "hsic_12M", "phy";
resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>;
reset-names = "hsic", "phy";
clocks = <&usb_clocks CLK_USB1_HSIC>,
<&usb_clocks CLK_USB_HSIC>,
<&usb_clocks CLK_USB1_PHY>;
clock-names = "hsic_480M",
"hsic_12M",
"phy";
resets = <&usb_clocks RST_USB1_HSIC>,
<&usb_clocks RST_USB1_PHY>;
reset-names = "hsic",
"phy";
status = "disabled";
#phy-cells = <0>;
/* usb1 is always used with HSIC */
......@@ -511,8 +309,8 @@ ehci2: usb@00a02000 {
compatible = "allwinner,sun9i-a80-ehci", "generic-ehci";
reg = <0x00a02000 0x100>;
interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_mod_clk 5>;
resets = <&usb_mod_clk 19>;
clocks = <&usb_clocks CLK_BUS_HCI2>;
resets = <&usb_clocks RST_USB2_HCI>;
phys = <&usbphy3>;
phy-names = "usb";
status = "disabled";
......@@ -522,8 +320,9 @@ ohci2: usb@00a02400 {
compatible = "allwinner,sun9i-a80-ohci", "generic-ohci";
reg = <0x00a02400 0x100>;
interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&usb_mod_clk 5>, <&usb_mod_clk 6>;
resets = <&usb_mod_clk 19>;
clocks = <&usb_clocks CLK_BUS_HCI2>,
<&usb_clocks CLK_USB_OHCI2>;
resets = <&usb_clocks RST_USB2_HCI>;
phys = <&usbphy3>;
phy-names = "usb";
status = "disabled";
......@@ -532,20 +331,35 @@ ohci2: usb@00a02400 {
usbphy3: phy@00a02800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a02800 0x4>;
clocks = <&usb_phy_clk 4>, <&usb_phy_clk 10>,
<&usb_phy_clk 5>;
clock-names = "hsic_480M", "hsic_12M", "phy";
resets = <&usb_phy_clk 20>, <&usb_phy_clk 21>;
reset-names = "hsic", "phy";
clocks = <&usb_clocks CLK_USB2_HSIC>,
<&usb_clocks CLK_USB_HSIC>,
<&usb_clocks CLK_USB2_PHY>;
clock-names = "hsic_480M",
"hsic_12M",
"phy";
resets = <&usb_clocks RST_USB2_HSIC>,
<&usb_clocks RST_USB2_PHY>;
reset-names = "hsic",
"phy";
status = "disabled";
#phy-cells = <0>;
};
usb_clocks: clock@00a08000 {
compatible = "allwinner,sun9i-a80-usb-clks";
reg = <0x00a08000 0x8>;
clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
clock-names = "bus", "hosc";
#clock-cells = <1>;
#reset-cells = <1>;
};
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun9i-a80-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>,
<&mmc0_clk 1>, <&mmc0_clk 2>;
clocks = <&mmc_config_clk 0>, <&ccu CLK_MMC0>,
<&ccu CLK_MMC0_OUTPUT>,
<&ccu CLK_MMC0_SAMPLE>;
clock-names = "ahb", "mmc", "output", "sample";
resets = <&mmc_config_clk 0>;
reset-names = "ahb";
......@@ -558,8 +372,9 @@ mmc0: mmc@01c0f000 {
mmc1: mmc@01c10000 {
compatible = "allwinner,sun9i-a80-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>,
<&mmc1_clk 1>, <&mmc1_clk 2>;
clocks = <&mmc_config_clk 1>, <&ccu CLK_MMC1>,
<&ccu CLK_MMC1_OUTPUT>,
<&ccu CLK_MMC1_SAMPLE>;
clock-names = "ahb", "mmc", "output", "sample";
resets = <&mmc_config_clk 1>;
reset-names = "ahb";
......@@ -572,8 +387,9 @@ mmc1: mmc@01c10000 {
mmc2: mmc@01c11000 {
compatible = "allwinner,sun9i-a80-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>,
<&mmc2_clk 1>, <&mmc2_clk 2>;
clocks = <&mmc_config_clk 2>, <&ccu CLK_MMC2>,
<&ccu CLK_MMC2_OUTPUT>,
<&ccu CLK_MMC2_SAMPLE>;
clock-names = "ahb", "mmc", "output", "sample";
resets = <&mmc_config_clk 2>;
reset-names = "ahb";
......@@ -586,8 +402,9 @@ mmc2: mmc@01c11000 {
mmc3: mmc@01c12000 {
compatible = "allwinner,sun9i-a80-mmc";
reg = <0x01c12000 0x1000>;
clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>,
<&mmc3_clk 1>, <&mmc3_clk 2>;
clocks = <&mmc_config_clk 3>, <&ccu CLK_MMC3>,
<&ccu CLK_MMC3_OUTPUT>,
<&ccu CLK_MMC3_SAMPLE>;
clock-names = "ahb", "mmc", "output", "sample";
resets = <&mmc_config_clk 3>;
reset-names = "ahb";
......@@ -600,9 +417,9 @@ mmc3: mmc@01c12000 {
mmc_config_clk: clk@01c13000 {
compatible = "allwinner,sun9i-a80-mmc-config-clk";
reg = <0x01c13000 0x10>;
clocks = <&ahb0_gates 8>;
clocks = <&ccu CLK_BUS_MMC>;
clock-names = "ahb";
resets = <&ahb0_resets 8>;
resets = <&ccu RST_BUS_MMC>;
reset-names = "ahb";
#clock-cells = <1>;
#reset-cells = <1>;
......@@ -621,34 +438,27 @@ gic: interrupt-controller@01c41000 {
interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};
ahb0_resets: reset@060005a0 {
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x060005a0 0x4>;
};
ahb1_resets: reset@060005a4 {
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x060005a4 0x4>;
};
ahb2_resets: reset@060005a8 {
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x060005a8 0x4>;
};
apb0_resets: reset@060005b0 {
de_clocks: clock@03000000 {
compatible = "allwinner,sun9i-a80-de-clks";
reg = <0x03000000 0x30>;
clocks = <&ccu CLK_DE>,
<&ccu CLK_SDRAM>,
<&ccu CLK_BUS_DE>;
clock-names = "mod",
"dram",
"bus";
resets = <&ccu RST_BUS_DE>;
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x060005b0 0x4>;
};
apb1_resets: reset@060005b4 {
ccu: clock@06000000 {
compatible = "allwinner,sun9i-a80-ccu";
reg = <0x06000000 0x800>;
clocks = <&osc24M>, <&osc32k>;
clock-names = "hosc", "losc";
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun6i-a31-clock-reset";
reg = <0x060005b4 0x4>;
};
timer@06000c00 {
......@@ -678,7 +488,7 @@ pio: pinctrl@06000800 {
<GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 5>, <&osc24M>, <&osc32k>;
clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
clock-names = "apb", "hosc", "losc";
gpio-controller;
interrupt-controller;
......@@ -740,8 +550,8 @@ uart0: serial@07000000 {
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 16>;
resets = <&apb1_resets 16>;
clocks = <&ccu CLK_BUS_UART0>;
resets = <&ccu RST_BUS_UART0>;
status = "disabled";
};
......@@ -751,8 +561,8 @@ uart1: serial@07000400 {
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
resets = <&apb1_resets 17>;
clocks = <&ccu CLK_BUS_UART1>;
resets = <&ccu RST_BUS_UART1>;
status = "disabled";
};
......@@ -762,8 +572,8 @@ uart2: serial@07000800 {
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
resets = <&apb1_resets 18>;
clocks = <&ccu CLK_BUS_UART2>;
resets = <&ccu RST_BUS_UART2>;
status = "disabled";
};
......@@ -773,8 +583,8 @@ uart3: serial@07000c00 {
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
resets = <&apb1_resets 19>;
clocks = <&ccu CLK_BUS_UART3>;
resets = <&ccu RST_BUS_UART3>;
status = "disabled";
};
......@@ -784,8 +594,8 @@ uart4: serial@07001000 {
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 20>;
resets = <&apb1_resets 20>;
clocks = <&ccu CLK_BUS_UART4>;
resets = <&ccu RST_BUS_UART4>;
status = "disabled";
};
......@@ -795,8 +605,8 @@ uart5: serial@07001400 {
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 21>;
resets = <&apb1_resets 21>;
clocks = <&ccu CLK_BUS_UART5>;
resets = <&ccu RST_BUS_UART5>;
status = "disabled";
};
......@@ -804,8 +614,8 @@ i2c0: i2c@07002800 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07002800 0x400>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 0>;
resets = <&apb1_resets 0>;
clocks = <&ccu CLK_BUS_I2C0>;
resets = <&ccu RST_BUS_I2C0>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -815,8 +625,8 @@ i2c1: i2c@07002c00 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07002c00 0x400>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 1>;
resets = <&apb1_resets 1>;
clocks = <&ccu CLK_BUS_I2C1>;
resets = <&ccu RST_BUS_I2C1>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -826,8 +636,8 @@ i2c2: i2c@07003000 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07003000 0x400>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 2>;
resets = <&apb1_resets 2>;
clocks = <&ccu CLK_BUS_I2C2>;
resets = <&ccu RST_BUS_I2C2>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -837,8 +647,8 @@ i2c3: i2c@07003400 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07003400 0x400>;
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 3>;
resets = <&apb1_resets 3>;
clocks = <&ccu CLK_BUS_I2C3>;
resets = <&ccu RST_BUS_I2C3>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......@@ -848,8 +658,8 @@ i2c4: i2c@07003800 {
compatible = "allwinner,sun6i-a31-i2c";
reg = <0x07003800 0x400>;
interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb1_gates 4>;
resets = <&apb1_resets 4>;
clocks = <&ccu CLK_BUS_I2C4>;
resets = <&ccu RST_BUS_I2C4>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
......
......@@ -64,6 +64,16 @@ config SUN50I_A64_CCU
select SUNXI_CCU_PHASE
default ARM64 && ARCH_SUNXI
config SUN5I_CCU
bool "Support for the Allwinner sun5i family CCM"
select SUNXI_CCU_DIV
select SUNXI_CCU_NK
select SUNXI_CCU_NKM
select SUNXI_CCU_NM
select SUNXI_CCU_MP
select SUNXI_CCU_PHASE
default MACH_SUN5I
config SUN6I_A31_CCU
bool "Support for the Allwinner A31/A31s CCU"
select SUNXI_CCU_DIV
......@@ -109,4 +119,25 @@ config SUN8I_H3_CCU
select SUNXI_CCU_PHASE
default MACH_SUN8I
config SUN8I_V3S_CCU
bool "Support for the Allwinner V3s 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
config SUN9I_A80_CCU
bool "Support for the Allwinner A80 CCU"
select SUNXI_CCU_DIV
select SUNXI_CCU_GATE
select SUNXI_CCU_NKMP
select SUNXI_CCU_NM
select SUNXI_CCU_MP
select SUNXI_CCU_PHASE
default MACH_SUN9I
endif
......@@ -19,7 +19,12 @@ obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o
# SoC support
obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o
obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o
obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o
obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
/*
* 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-sun5i.h"
static struct ccu_nkmp pll_core_clk = {
.enable = BIT(31),
.n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
.k = _SUNXI_CCU_MULT(4, 2),
.m = _SUNXI_CCU_DIV(0, 2),
.p = _SUNXI_CCU_DIV(16, 2),
.common = {
.reg = 0x000,
.hw.init = CLK_HW_INIT("pll-core",
"hosc",
&ccu_nkmp_ops,
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 SUN5I_PLL_AUDIO_REG 0x008
static struct ccu_nm pll_audio_base_clk = {
.enable = BIT(31),
.n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
/*
* The datasheet is wrong here, this doesn't have any
* offset
*/
.m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
.common = {
.reg = 0x008,
.hw.init = CLK_HW_INIT("pll-audio-base",
"hosc",
&ccu_nm_ops,
0),
},
};
static struct ccu_mult pll_video0_clk = {
.enable = BIT(31),
.mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
.frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
270000000, 297000000),
.common = {
.reg = 0x010,
.features = (CCU_FEATURE_FRACTIONAL |
CCU_FEATURE_ALL_PREDIV),
.prediv = 8,
.hw.init = CLK_HW_INIT("pll-video0",
"hosc",
&ccu_mult_ops,
0),
},
};
static struct ccu_nkmp pll_ve_clk = {
.enable = BIT(31),
.n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
.k = _SUNXI_CCU_MULT(4, 2),
.m = _SUNXI_CCU_DIV(0, 2),
.p = _SUNXI_CCU_DIV(16, 2),
.common = {
.reg = 0x018,
.hw.init = CLK_HW_INIT("pll-ve",
"hosc",
&ccu_nkmp_ops,
0),
},
};
static struct ccu_nk pll_ddr_base_clk = {
.enable = BIT(31),
.n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
.k = _SUNXI_CCU_MULT(4, 2),
.common = {
.reg = 0x020,
.hw.init = CLK_HW_INIT("pll-ddr-base",
"hosc",
&ccu_nk_ops,
0),
},
};
static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2,
CLK_IS_CRITICAL);
static struct ccu_div pll_ddr_other_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
.common = {
.reg = 0x020,
.hw.init = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
&ccu_div_ops,
0),
},
};
static struct ccu_nk pll_periph_clk = {
.enable = BIT(31),
.n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
.k = _SUNXI_CCU_MULT(4, 2),
.fixed_post_div = 2,
.common = {
.reg = 0x028,
.features = CCU_FEATURE_FIXED_POSTDIV,
.hw.init = CLK_HW_INIT("pll-periph",
"hosc",
&ccu_nk_ops,
0),
},
};
static struct ccu_mult pll_video1_clk = {
.enable = BIT(31),
.mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
.frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
270000000, 297000000),
.common = {
.reg = 0x030,
.features = (CCU_FEATURE_FRACTIONAL |
CCU_FEATURE_ALL_PREDIV),
.prediv = 8,
.hw.init = CLK_HW_INIT("pll-video1",
"hosc",
&ccu_mult_ops,
0),
},
};
static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0);
#define SUN5I_AHB_REG 0x054
static const char * const cpu_parents[] = { "osc32k", "hosc",
"pll-core" , "pll-periph" };
static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
{ .index = 3, .div = 3, },
};
static struct ccu_mux cpu_clk = {
.mux = {
.shift = 16,
.width = 2,
.fixed_predivs = cpu_predivs,
.n_predivs = ARRAY_SIZE(cpu_predivs),
},
.common = {
.reg = 0x054,
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("cpu",
cpu_parents,
&ccu_mux_ops,
CLK_IS_CRITICAL),
}
};
static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
static const struct ccu_mux_fixed_prediv ahb_predivs[] = {
{ .index = 2, .div = 2, },
};
static struct ccu_div ahb_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = {
.shift = 6,
.width = 2,
.fixed_predivs = ahb_predivs,
.n_predivs = ARRAY_SIZE(ahb_predivs),
},
.common = {
.reg = 0x054,
.hw.init = CLK_HW_INIT_PARENTS("ahb",
ahb_parents,
&ccu_div_ops,
0),
},
};
static struct clk_div_table apb0_div_table[] = {
{ .val = 0, .div = 2 },
{ .val = 1, .div = 2 },
{ .val = 2, .div = 4 },
{ .val = 3, .div = 8 },
{ /* Sentinel */ },
};
static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
0x054, 8, 2, apb0_div_table, 0);
static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
0, 5, /* M */
16, 2, /* P */
24, 2, /* mux */
0);
static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "axi",
0x05c, BIT(0), 0);
static SUNXI_CCU_GATE(ahb_otg_clk, "ahb-otg", "ahb",
0x060, BIT(0), 0);
static SUNXI_CCU_GATE(ahb_ehci_clk, "ahb-ehci", "ahb",
0x060, BIT(1), 0);
static SUNXI_CCU_GATE(ahb_ohci_clk, "ahb-ohci", "ahb",
0x060, BIT(2), 0);
static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb",
0x060, BIT(5), 0);
static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb",
0x060, BIT(6), 0);
static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb",
0x060, BIT(6), 0);
static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb",
0x060, BIT(8), 0);
static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb",
0x060, BIT(9), 0);
static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb",
0x060, BIT(10), 0);
static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb",
0x060, BIT(13), 0);
static SUNXI_CCU_GATE(ahb_sdram_clk, "ahb-sdram", "ahb",
0x060, BIT(14), CLK_IS_CRITICAL);
static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb",
0x060, BIT(17), 0);
static SUNXI_CCU_GATE(ahb_ts_clk, "ahb-ts", "ahb",
0x060, BIT(18), 0);
static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb",
0x060, BIT(20), 0);
static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb",
0x060, BIT(21), 0);
static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb",
0x060, BIT(22), 0);
static SUNXI_CCU_GATE(ahb_gps_clk, "ahb-gps", "ahb",
0x060, BIT(26), 0);
static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer", "ahb",
0x060, BIT(28), 0);
static SUNXI_CCU_GATE(ahb_ve_clk, "ahb-ve", "ahb",
0x064, BIT(0), 0);
static SUNXI_CCU_GATE(ahb_tve_clk, "ahb-tve", "ahb",
0x064, BIT(2), 0);
static SUNXI_CCU_GATE(ahb_lcd_clk, "ahb-lcd", "ahb",
0x064, BIT(4), 0);
static SUNXI_CCU_GATE(ahb_csi_clk, "ahb-csi", "ahb",
0x064, BIT(8), 0);
static SUNXI_CCU_GATE(ahb_hdmi_clk, "ahb-hdmi", "ahb",
0x064, BIT(11), 0);
static SUNXI_CCU_GATE(ahb_de_be_clk, "ahb-de-be", "ahb",
0x064, BIT(12), 0);
static SUNXI_CCU_GATE(ahb_de_fe_clk, "ahb-de-fe", "ahb",
0x064, BIT(14), 0);
static SUNXI_CCU_GATE(ahb_iep_clk, "ahb-iep", "ahb",
0x064, BIT(19), 0);
static SUNXI_CCU_GATE(ahb_gpu_clk, "ahb-gpu", "ahb",
0x064, BIT(20), 0);
static SUNXI_CCU_GATE(apb0_codec_clk, "apb0-codec", "apb0",
0x068, BIT(0), 0);
static SUNXI_CCU_GATE(apb0_spdif_clk, "apb0-spdif", "apb0",
0x068, BIT(1), 0);
static SUNXI_CCU_GATE(apb0_i2s_clk, "apb0-i2s", "apb0",
0x068, BIT(3), 0);
static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0",
0x068, BIT(5), 0);
static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0",
0x068, BIT(6), 0);
static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad", "apb0",
0x068, BIT(10), 0);
static SUNXI_CCU_GATE(apb1_i2c0_clk, "apb1-i2c0", "apb1",
0x06c, BIT(0), 0);
static SUNXI_CCU_GATE(apb1_i2c1_clk, "apb1-i2c1", "apb1",
0x06c, BIT(1), 0);
static SUNXI_CCU_GATE(apb1_i2c2_clk, "apb1-i2c2", "apb1",
0x06c, BIT(2), 0);
static SUNXI_CCU_GATE(apb1_uart0_clk, "apb1-uart0", "apb1",
0x06c, BIT(16), 0);
static SUNXI_CCU_GATE(apb1_uart1_clk, "apb1-uart1", "apb1",
0x06c, BIT(17), 0);
static SUNXI_CCU_GATE(apb1_uart2_clk, "apb1-uart2", "apb1",
0x06c, BIT(18), 0);
static SUNXI_CCU_GATE(apb1_uart3_clk, "apb1-uart3", "apb1",
0x06c, BIT(19), 0);
static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
"pll-ddr-other" };
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_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_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_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", 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 SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
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(i2s_clk, "i2s", i2s_parents,
0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
static const char * const spdif_parents[] = { "pll-audio-8x", "pll-audio-4x",
"pll-audio-2x", "pll-audio" };
static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", spdif_parents,
0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
static const char * const keypad_parents[] = { "hosc", "losc"};
static const u8 keypad_table[] = { 0, 2 };
static struct ccu_mp keypad_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(8, 5),
.p = _SUNXI_CCU_DIV(20, 2),
.mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
.common = {
.reg = 0x0c4,
.hw.init = CLK_HW_INIT_PARENTS("keypad",
keypad_parents,
&ccu_mp_ops,
0),
},
};
static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "pll-periph",
0x0cc, BIT(6), 0);
static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "pll-periph",
0x0cc, BIT(8), 0);
static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "pll-periph",
0x0cc, BIT(9), 0);
static const char * const gps_parents[] = { "hosc", "pll-periph",
"pll-video1", "pll-ve" };
static SUNXI_CCU_M_WITH_MUX_GATE(gps_clk, "gps", gps_parents,
0x0d0, 0, 3, 24, 2, BIT(31), 0);
static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
0x100, BIT(0), 0);
static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr",
0x100, BIT(1), 0);
static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "pll-ddr",
0x100, BIT(3), 0);
static SUNXI_CCU_GATE(dram_tve_clk, "dram-tve", "pll-ddr",
0x100, BIT(5), 0);
static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr",
0x100, BIT(25), 0);
static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr",
0x100, BIT(26), 0);
static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr",
0x100, BIT(29), 0);
static SUNXI_CCU_GATE(dram_iep_clk, "dram-iep", "pll-ddr",
0x100, BIT(31), 0);
static const char * const de_parents[] = { "pll-video0", "pll-video1",
"pll-ddr-other" };
static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
0x104, 0, 4, 24, 2, BIT(31), 0);
static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
0x10c, 0, 4, 24, 2, BIT(31), 0);
static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
"pll-video0-2x", "pll-video1-2x" };
static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
tcon_parents,
0x12c, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
0x12c, 11, 1, BIT(15), CLK_SET_RATE_PARENT);
static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
"pll-video0-2x", "pll-video1-2x" };
static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
csi_parents, csi_table,
0x134, 0, 5, 24, 2, BIT(31), 0);
static SUNXI_CCU_GATE(ve_clk, "ve", "pll-ve",
0x13c, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
0x140, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(avs_clk, "avs", "hosc",
0x144, BIT(31), 0);
static const char * const hdmi_parents[] = { "pll-video0", "pll-video0-2x" };
static const u8 hdmi_table[] = { 0, 2 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
hdmi_parents, hdmi_table,
0x150, 0, 4, 24, 2, BIT(31),
CLK_SET_RATE_PARENT);
static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
"pll-ddr-other", "pll-video1",
"pll-video1-2x" };
static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
0x154, 0, 4, 24, 3, BIT(31), 0);
static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
static SUNXI_CCU_GATE(iep_clk, "iep", "de-be",
0x160, BIT(31), 0);
static struct ccu_common *sun5i_a10s_ccu_clks[] = {
&hosc_clk.common,
&pll_core_clk.common,
&pll_audio_base_clk.common,
&pll_video0_clk.common,
&pll_ve_clk.common,
&pll_ddr_base_clk.common,
&pll_ddr_clk.common,
&pll_ddr_other_clk.common,
&pll_periph_clk.common,
&pll_video1_clk.common,
&cpu_clk.common,
&axi_clk.common,
&ahb_clk.common,
&apb0_clk.common,
&apb1_clk.common,
&axi_dram_clk.common,
&ahb_otg_clk.common,
&ahb_ehci_clk.common,
&ahb_ohci_clk.common,
&ahb_ss_clk.common,
&ahb_dma_clk.common,
&ahb_bist_clk.common,
&ahb_mmc0_clk.common,
&ahb_mmc1_clk.common,
&ahb_mmc2_clk.common,
&ahb_nand_clk.common,
&ahb_sdram_clk.common,
&ahb_emac_clk.common,
&ahb_ts_clk.common,
&ahb_spi0_clk.common,
&ahb_spi1_clk.common,
&ahb_spi2_clk.common,
&ahb_gps_clk.common,
&ahb_hstimer_clk.common,
&ahb_ve_clk.common,
&ahb_tve_clk.common,
&ahb_lcd_clk.common,
&ahb_csi_clk.common,
&ahb_hdmi_clk.common,
&ahb_de_be_clk.common,
&ahb_de_fe_clk.common,
&ahb_iep_clk.common,
&ahb_gpu_clk.common,
&apb0_codec_clk.common,
&apb0_spdif_clk.common,
&apb0_i2s_clk.common,
&apb0_pio_clk.common,
&apb0_ir_clk.common,
&apb0_keypad_clk.common,
&apb1_i2c0_clk.common,
&apb1_i2c1_clk.common,
&apb1_i2c2_clk.common,
&apb1_uart0_clk.common,
&apb1_uart1_clk.common,
&apb1_uart2_clk.common,
&apb1_uart3_clk.common,
&nand_clk.common,
&mmc0_clk.common,
&mmc1_clk.common,
&mmc2_clk.common,
&ts_clk.common,
&ss_clk.common,
&spi0_clk.common,
&spi1_clk.common,
&spi2_clk.common,
&ir_clk.common,
&i2s_clk.common,
&spdif_clk.common,
&keypad_clk.common,
&usb_ohci_clk.common,
&usb_phy0_clk.common,
&usb_phy1_clk.common,
&gps_clk.common,
&dram_ve_clk.common,
&dram_csi_clk.common,
&dram_ts_clk.common,
&dram_tve_clk.common,
&dram_de_fe_clk.common,
&dram_de_be_clk.common,
&dram_ace_clk.common,
&dram_iep_clk.common,
&de_be_clk.common,
&de_fe_clk.common,
&tcon_ch0_clk.common,
&tcon_ch1_sclk2_clk.common,
&tcon_ch1_sclk1_clk.common,
&csi_clk.common,
&ve_clk.common,
&codec_clk.common,
&avs_clk.common,
&hdmi_clk.common,
&gpu_clk.common,
&mbus_clk.common,
&iep_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_video0_2x_clk, "pll-video0-2x",
"pll-video0", 1, 2, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
"pll-video1", 1, 2, CLK_SET_RATE_PARENT);
static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
.hws = {
[CLK_HOSC] = &hosc_clk.common.hw,
[CLK_PLL_CORE] = &pll_core_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_VIDEO0] = &pll_video0_clk.common.hw,
[CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
[CLK_PLL_VE] = &pll_ve_clk.common.hw,
[CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
[CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
[CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
[CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
[CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
[CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
[CLK_CPU] = &cpu_clk.common.hw,
[CLK_AXI] = &axi_clk.common.hw,
[CLK_AHB] = &ahb_clk.common.hw,
[CLK_APB0] = &apb0_clk.common.hw,
[CLK_APB1] = &apb1_clk.common.hw,
[CLK_DRAM_AXI] = &axi_dram_clk.common.hw,
[CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
[CLK_AHB_EHCI] = &ahb_ehci_clk.common.hw,
[CLK_AHB_OHCI] = &ahb_ohci_clk.common.hw,
[CLK_AHB_SS] = &ahb_ss_clk.common.hw,
[CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
[CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
[CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
[CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
[CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
[CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
[CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
[CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
[CLK_AHB_TS] = &ahb_ts_clk.common.hw,
[CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
[CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
[CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
[CLK_AHB_GPS] = &ahb_gps_clk.common.hw,
[CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
[CLK_AHB_VE] = &ahb_ve_clk.common.hw,
[CLK_AHB_TVE] = &ahb_tve_clk.common.hw,
[CLK_AHB_LCD] = &ahb_lcd_clk.common.hw,
[CLK_AHB_CSI] = &ahb_csi_clk.common.hw,
[CLK_AHB_HDMI] = &ahb_hdmi_clk.common.hw,
[CLK_AHB_DE_BE] = &ahb_de_be_clk.common.hw,
[CLK_AHB_DE_FE] = &ahb_de_fe_clk.common.hw,
[CLK_AHB_IEP] = &ahb_iep_clk.common.hw,
[CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
[CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
[CLK_APB0_I2S] = &apb0_i2s_clk.common.hw,
[CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
[CLK_APB0_IR] = &apb0_ir_clk.common.hw,
[CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw,
[CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
[CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
[CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
[CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
[CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
[CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
[CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
[CLK_NAND] = &nand_clk.common.hw,
[CLK_MMC0] = &mmc0_clk.common.hw,
[CLK_MMC1] = &mmc1_clk.common.hw,
[CLK_MMC2] = &mmc2_clk.common.hw,
[CLK_TS] = &ts_clk.common.hw,
[CLK_SS] = &ss_clk.common.hw,
[CLK_SPI0] = &spi0_clk.common.hw,
[CLK_SPI1] = &spi1_clk.common.hw,
[CLK_SPI2] = &spi2_clk.common.hw,
[CLK_IR] = &ir_clk.common.hw,
[CLK_I2S] = &i2s_clk.common.hw,
[CLK_KEYPAD] = &keypad_clk.common.hw,
[CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
[CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
[CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
[CLK_GPS] = &gps_clk.common.hw,
[CLK_DRAM_VE] = &dram_ve_clk.common.hw,
[CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
[CLK_DRAM_TS] = &dram_ts_clk.common.hw,
[CLK_DRAM_TVE] = &dram_tve_clk.common.hw,
[CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
[CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
[CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
[CLK_DRAM_IEP] = &dram_iep_clk.common.hw,
[CLK_DE_BE] = &de_be_clk.common.hw,
[CLK_DE_FE] = &de_fe_clk.common.hw,
[CLK_TCON_CH0] = &tcon_ch0_clk.common.hw,
[CLK_TCON_CH1_SCLK] = &tcon_ch1_sclk2_clk.common.hw,
[CLK_TCON_CH1] = &tcon_ch1_sclk1_clk.common.hw,
[CLK_CSI] = &csi_clk.common.hw,
[CLK_VE] = &ve_clk.common.hw,
[CLK_CODEC] = &codec_clk.common.hw,
[CLK_AVS] = &avs_clk.common.hw,
[CLK_HDMI] = &hdmi_clk.common.hw,
[CLK_GPU] = &gpu_clk.common.hw,
[CLK_MBUS] = &mbus_clk.common.hw,
[CLK_IEP] = &iep_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct ccu_reset_map sun5i_a10s_ccu_resets[] = {
[RST_USB_PHY0] = { 0x0cc, BIT(0) },
[RST_USB_PHY1] = { 0x0cc, BIT(1) },
[RST_GPS] = { 0x0d0, BIT(30) },
[RST_DE_BE] = { 0x104, BIT(30) },
[RST_DE_FE] = { 0x10c, BIT(30) },
[RST_TVE] = { 0x118, BIT(29) },
[RST_LCD] = { 0x118, BIT(30) },
[RST_CSI] = { 0x134, BIT(30) },
[RST_VE] = { 0x13c, BIT(0) },
[RST_GPU] = { 0x154, BIT(30) },
[RST_IEP] = { 0x160, BIT(30) },
};
static const struct sunxi_ccu_desc sun5i_a10s_ccu_desc = {
.ccu_clks = sun5i_a10s_ccu_clks,
.num_ccu_clks = ARRAY_SIZE(sun5i_a10s_ccu_clks),
.hw_clks = &sun5i_a10s_hw_clks,
.resets = sun5i_a10s_ccu_resets,
.num_resets = ARRAY_SIZE(sun5i_a10s_ccu_resets),
};
/*
* The A13 is the A10s minus the TS, GPS, HDMI, I2S and the keypad
*/
static struct clk_hw_onecell_data sun5i_a13_hw_clks = {
.hws = {
[CLK_HOSC] = &hosc_clk.common.hw,
[CLK_PLL_CORE] = &pll_core_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_VIDEO0] = &pll_video0_clk.common.hw,
[CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
[CLK_PLL_VE] = &pll_ve_clk.common.hw,
[CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
[CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
[CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
[CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
[CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
[CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
[CLK_CPU] = &cpu_clk.common.hw,
[CLK_AXI] = &axi_clk.common.hw,
[CLK_AHB] = &ahb_clk.common.hw,
[CLK_APB0] = &apb0_clk.common.hw,
[CLK_APB1] = &apb1_clk.common.hw,
[CLK_DRAM_AXI] = &axi_dram_clk.common.hw,
[CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
[CLK_AHB_EHCI] = &ahb_ehci_clk.common.hw,
[CLK_AHB_OHCI] = &ahb_ohci_clk.common.hw,
[CLK_AHB_SS] = &ahb_ss_clk.common.hw,
[CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
[CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
[CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
[CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
[CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
[CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
[CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
[CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
[CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
[CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
[CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
[CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
[CLK_AHB_VE] = &ahb_ve_clk.common.hw,
[CLK_AHB_TVE] = &ahb_tve_clk.common.hw,
[CLK_AHB_LCD] = &ahb_lcd_clk.common.hw,
[CLK_AHB_CSI] = &ahb_csi_clk.common.hw,
[CLK_AHB_DE_BE] = &ahb_de_be_clk.common.hw,
[CLK_AHB_DE_FE] = &ahb_de_fe_clk.common.hw,
[CLK_AHB_IEP] = &ahb_iep_clk.common.hw,
[CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
[CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
[CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
[CLK_APB0_IR] = &apb0_ir_clk.common.hw,
[CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
[CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
[CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
[CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
[CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
[CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
[CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
[CLK_NAND] = &nand_clk.common.hw,
[CLK_MMC0] = &mmc0_clk.common.hw,
[CLK_MMC1] = &mmc1_clk.common.hw,
[CLK_MMC2] = &mmc2_clk.common.hw,
[CLK_SS] = &ss_clk.common.hw,
[CLK_SPI0] = &spi0_clk.common.hw,
[CLK_SPI1] = &spi1_clk.common.hw,
[CLK_SPI2] = &spi2_clk.common.hw,
[CLK_IR] = &ir_clk.common.hw,
[CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
[CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
[CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
[CLK_DRAM_VE] = &dram_ve_clk.common.hw,
[CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
[CLK_DRAM_TVE] = &dram_tve_clk.common.hw,
[CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
[CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
[CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
[CLK_DRAM_IEP] = &dram_iep_clk.common.hw,
[CLK_DE_BE] = &de_be_clk.common.hw,
[CLK_DE_FE] = &de_fe_clk.common.hw,
[CLK_TCON_CH0] = &tcon_ch0_clk.common.hw,
[CLK_TCON_CH1_SCLK] = &tcon_ch1_sclk2_clk.common.hw,
[CLK_TCON_CH1] = &tcon_ch1_sclk1_clk.common.hw,
[CLK_CSI] = &csi_clk.common.hw,
[CLK_VE] = &ve_clk.common.hw,
[CLK_CODEC] = &codec_clk.common.hw,
[CLK_AVS] = &avs_clk.common.hw,
[CLK_GPU] = &gpu_clk.common.hw,
[CLK_MBUS] = &mbus_clk.common.hw,
[CLK_IEP] = &iep_clk.common.hw,
},
.num = CLK_NUMBER,
};
static const struct sunxi_ccu_desc sun5i_a13_ccu_desc = {
.ccu_clks = sun5i_a10s_ccu_clks,
.num_ccu_clks = ARRAY_SIZE(sun5i_a10s_ccu_clks),
.hw_clks = &sun5i_a13_hw_clks,
.resets = sun5i_a10s_ccu_resets,
.num_resets = ARRAY_SIZE(sun5i_a10s_ccu_resets),
};
/*
* The GR8 is the A10s CCU minus the HDMI and keypad, plus SPDIF
*/
static struct clk_hw_onecell_data sun5i_gr8_hw_clks = {
.hws = {
[CLK_HOSC] = &hosc_clk.common.hw,
[CLK_PLL_CORE] = &pll_core_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_VIDEO0] = &pll_video0_clk.common.hw,
[CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
[CLK_PLL_VE] = &pll_ve_clk.common.hw,
[CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw,
[CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
[CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw,
[CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
[CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
[CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
[CLK_CPU] = &cpu_clk.common.hw,
[CLK_AXI] = &axi_clk.common.hw,
[CLK_AHB] = &ahb_clk.common.hw,
[CLK_APB0] = &apb0_clk.common.hw,
[CLK_APB1] = &apb1_clk.common.hw,
[CLK_DRAM_AXI] = &axi_dram_clk.common.hw,
[CLK_AHB_OTG] = &ahb_otg_clk.common.hw,
[CLK_AHB_EHCI] = &ahb_ehci_clk.common.hw,
[CLK_AHB_OHCI] = &ahb_ohci_clk.common.hw,
[CLK_AHB_SS] = &ahb_ss_clk.common.hw,
[CLK_AHB_DMA] = &ahb_dma_clk.common.hw,
[CLK_AHB_BIST] = &ahb_bist_clk.common.hw,
[CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw,
[CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw,
[CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw,
[CLK_AHB_NAND] = &ahb_nand_clk.common.hw,
[CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw,
[CLK_AHB_EMAC] = &ahb_emac_clk.common.hw,
[CLK_AHB_TS] = &ahb_ts_clk.common.hw,
[CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw,
[CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw,
[CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw,
[CLK_AHB_GPS] = &ahb_gps_clk.common.hw,
[CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw,
[CLK_AHB_VE] = &ahb_ve_clk.common.hw,
[CLK_AHB_TVE] = &ahb_tve_clk.common.hw,
[CLK_AHB_LCD] = &ahb_lcd_clk.common.hw,
[CLK_AHB_CSI] = &ahb_csi_clk.common.hw,
[CLK_AHB_DE_BE] = &ahb_de_be_clk.common.hw,
[CLK_AHB_DE_FE] = &ahb_de_fe_clk.common.hw,
[CLK_AHB_IEP] = &ahb_iep_clk.common.hw,
[CLK_AHB_GPU] = &ahb_gpu_clk.common.hw,
[CLK_APB0_CODEC] = &apb0_codec_clk.common.hw,
[CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw,
[CLK_APB0_I2S] = &apb0_i2s_clk.common.hw,
[CLK_APB0_PIO] = &apb0_pio_clk.common.hw,
[CLK_APB0_IR] = &apb0_ir_clk.common.hw,
[CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw,
[CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw,
[CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw,
[CLK_APB1_UART0] = &apb1_uart0_clk.common.hw,
[CLK_APB1_UART1] = &apb1_uart1_clk.common.hw,
[CLK_APB1_UART2] = &apb1_uart2_clk.common.hw,
[CLK_APB1_UART3] = &apb1_uart3_clk.common.hw,
[CLK_NAND] = &nand_clk.common.hw,
[CLK_MMC0] = &mmc0_clk.common.hw,
[CLK_MMC1] = &mmc1_clk.common.hw,
[CLK_MMC2] = &mmc2_clk.common.hw,
[CLK_TS] = &ts_clk.common.hw,
[CLK_SS] = &ss_clk.common.hw,
[CLK_SPI0] = &spi0_clk.common.hw,
[CLK_SPI1] = &spi1_clk.common.hw,
[CLK_SPI2] = &spi2_clk.common.hw,
[CLK_IR] = &ir_clk.common.hw,
[CLK_I2S] = &i2s_clk.common.hw,
[CLK_SPDIF] = &spdif_clk.common.hw,
[CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
[CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
[CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
[CLK_GPS] = &gps_clk.common.hw,
[CLK_DRAM_VE] = &dram_ve_clk.common.hw,
[CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
[CLK_DRAM_TS] = &dram_ts_clk.common.hw,
[CLK_DRAM_TVE] = &dram_tve_clk.common.hw,
[CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
[CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
[CLK_DRAM_ACE] = &dram_ace_clk.common.hw,
[CLK_DRAM_IEP] = &dram_iep_clk.common.hw,
[CLK_DE_BE] = &de_be_clk.common.hw,
[CLK_DE_FE] = &de_fe_clk.common.hw,
[CLK_TCON_CH0] = &tcon_ch0_clk.common.hw,
[CLK_TCON_CH1_SCLK] = &tcon_ch1_sclk2_clk.common.hw,
[CLK_TCON_CH1] = &tcon_ch1_sclk1_clk.common.hw,
[CLK_CSI] = &csi_clk.common.hw,
[CLK_VE] = &ve_clk.common.hw,
[CLK_CODEC] = &codec_clk.common.hw,
[CLK_AVS] = &avs_clk.common.hw,
[CLK_GPU] = &gpu_clk.common.hw,
[CLK_MBUS] = &mbus_clk.common.hw,
[CLK_IEP] = &iep_clk.common.hw,
},
.num = CLK_NUMBER,
};
static const struct sunxi_ccu_desc sun5i_gr8_ccu_desc = {
.ccu_clks = sun5i_a10s_ccu_clks,
.num_ccu_clks = ARRAY_SIZE(sun5i_a10s_ccu_clks),
.hw_clks = &sun5i_gr8_hw_clks,
.resets = sun5i_a10s_ccu_resets,
.num_resets = ARRAY_SIZE(sun5i_a10s_ccu_resets),
};
static void __init sun5i_ccu_init(struct device_node *node,
const struct sunxi_ccu_desc *desc)
{
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 + SUN5I_PLL_AUDIO_REG);
val &= ~GENMASK(19, 16);
writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
/*
* Use the peripheral PLL as the AHB parent, instead of CPU /
* AXI which have rate changes due to cpufreq.
*
* This is especially a big deal for the HS timer whose parent
* clock is AHB.
*/
val = readl(reg + SUN5I_AHB_REG);
val &= ~GENMASK(7, 6);
writel(val | (2 << 6), reg + SUN5I_AHB_REG);
sunxi_ccu_probe(node, reg, desc);
}
static void __init sun5i_a10s_ccu_setup(struct device_node *node)
{
sun5i_ccu_init(node, &sun5i_a10s_ccu_desc);
}
CLK_OF_DECLARE(sun5i_a10s_ccu, "allwinner,sun5i-a10s-ccu",
sun5i_a10s_ccu_setup);
static void __init sun5i_a13_ccu_setup(struct device_node *node)
{
sun5i_ccu_init(node, &sun5i_a13_ccu_desc);
}
CLK_OF_DECLARE(sun5i_a13_ccu, "allwinner,sun5i-a13-ccu",
sun5i_a13_ccu_setup);
static void __init sun5i_gr8_ccu_setup(struct device_node *node)
{
sun5i_ccu_init(node, &sun5i_gr8_ccu_desc);
}
CLK_OF_DECLARE(sun5i_gr8_ccu, "nextthing,gr8-ccu",
sun5i_gr8_ccu_setup);
/*
* 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_SUN5I_H_
#define _CCU_SUN5I_H_
#include <dt-bindings/clock/sun5i-ccu.h>
#include <dt-bindings/reset/sun5i-ccu.h>
/* The HOSC is exported */
#define CLK_PLL_CORE 2
#define CLK_PLL_AUDIO_BASE 3
#define CLK_PLL_AUDIO 4
#define CLK_PLL_AUDIO_2X 5
#define CLK_PLL_AUDIO_4X 6
#define CLK_PLL_AUDIO_8X 7
#define CLK_PLL_VIDEO0 8
#define CLK_PLL_VIDEO0_2X 9
#define CLK_PLL_VE 10
#define CLK_PLL_DDR_BASE 11
#define CLK_PLL_DDR 12
#define CLK_PLL_DDR_OTHER 13
#define CLK_PLL_PERIPH 14
#define CLK_PLL_VIDEO1 15
#define CLK_PLL_VIDEO1_2X 16
/* The CPU clock is exported */
#define CLK_AXI 18
#define CLK_AHB 19
#define CLK_APB0 20
#define CLK_APB1 21
#define CLK_DRAM_AXI 22
/* AHB gates are exported */
/* APB0 gates are exported */
/* APB1 gates are exported */
/* Modules clocks are exported */
/* USB clocks are exported */
/* GPS clock is exported */
/* DRAM gates are exported */
/* More display modules clocks are exported */
#define CLK_TCON_CH1_SCLK 91
/* The rest of the module clocks are exported */
#define CLK_MBUS 99
/* And finally the IEP clock */
#define CLK_NUMBER (CLK_IEP + 1)
#endif /* _CCU_SUN5I_H_ */
......@@ -468,8 +468,8 @@ static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", daudio_parents,
0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
0x0cc, BIT(8), 0);
......
......@@ -170,7 +170,7 @@ static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
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);
0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
......@@ -440,7 +440,7 @@ static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
0x140, BIT(31), 0);
0x140, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x",
0x140, BIT(30), 0);
static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
......@@ -468,7 +468,7 @@ static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc",
0x180, 0, 4, 24, 3, BIT(31), 0);
static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
0x1a0, 0, 3, BIT(31), 0);
0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
static const char * const ats_parents[] = { "osc24M", "pll-periph" };
static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents,
......@@ -752,6 +752,13 @@ static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = {
.num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets),
};
static struct ccu_mux_nb sun8i_a33_cpu_nb = {
.common = &cpux_clk.common,
.cm = &cpux_clk.mux,
.delay_us = 1, /* > 8 clock cycles at 24 MHz */
.bypass_index = 1, /* index of 24 MHz oscillator */
};
static void __init sun8i_a33_ccu_setup(struct device_node *node)
{
void __iomem *reg;
......@@ -775,6 +782,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
&sun8i_a33_cpu_nb);
}
CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
sun8i_a33_ccu_setup);
......@@ -803,6 +803,13 @@ static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = {
.num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets),
};
static struct ccu_mux_nb sun8i_h3_cpu_nb = {
.common = &cpux_clk.common,
.cm = &cpux_clk.mux,
.delay_us = 1, /* > 8 clock cycles at 24 MHz */
.bypass_index = 1, /* index of 24 MHz oscillator */
};
static void __init sun8i_h3_ccu_setup(struct device_node *node)
{
void __iomem *reg;
......@@ -821,6 +828,9 @@ static void __init sun8i_h3_ccu_setup(struct device_node *node)
writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
sunxi_ccu_probe(node, reg, &sun8i_h3_ccu_desc);
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
&sun8i_h3_cpu_nb);
}
CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu",
sun8i_h3_ccu_setup);
/*
* Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
*
* Based on ccu-sun8i-h3.c, which is:
* 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-v3s.h"
static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
"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_V3S_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_isp_clk, "pll-isp",
"osc24M", 0x002c,
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 const char * const cpu_parents[] = { "osc32k", "osc24M",
"pll-cpu", "pll-cpu" };
static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
0x050, 16, 2, CLK_IS_CRITICAL);
static SUNXI_CCU_M(axi_clk, "axi", "cpu", 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 const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
{ .index = 1, .div = 2 },
};
static struct ccu_mux ahb2_clk = {
.mux = {
.shift = 0,
.width = 1,
.fixed_predivs = ahb2_fixed_predivs,
.n_predivs = ARRAY_SIZE(ahb2_fixed_predivs),
},
.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_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_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_otg_clk, "bus-otg", "ahb1",
0x060, BIT(24), 0);
static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1",
0x060, BIT(26), 0);
static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1",
0x060, BIT(29), 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(4), 0);
static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
0x064, BIT(8), 0);
static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1",
0x064, BIT(12), 0);
static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
0x068, BIT(0), 0);
static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
0x068, BIT(5), 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_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_ephy_clk, "bus-ephy", "ahb1",
0x070, BIT(0), 0);
static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1",
0x070, BIT(7), 0);
static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0",
"pll-periph1" };
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 ce_parents[] = { "osc24M", "pll-periph0", };
static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_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_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
0x0cc, BIT(8), 0);
static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M",
0x0cc, BIT(16), 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_ehci_clk, "dram-ehci", "dram",
0x100, BIT(17), 0);
static SUNXI_CCU_GATE(dram_ohci_clk, "dram-ohci", "dram",
0x100, BIT(18), 0);
static const char * const de_parents[] = { "pll-video", "pll-periph0" };
static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
0x104, 0, 4, 24, 2, 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 SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M",
0x130, BIT(31), 0);
static const char * const csi_mclk_parents[] = { "osc24M", "pll-video",
"pll-periph0", "pll-periph1" };
static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents,
0x130, 0, 5, 8, 3, BIT(15), 0);
static const char * const csi1_sclk_parents[] = { "pll-video", "pll-isp" };
static SUNXI_CCU_M_WITH_MUX_GATE(csi1_sclk_clk, "csi-sclk", csi1_sclk_parents,
0x134, 16, 4, 24, 3, BIT(31), 0);
static SUNXI_CCU_M_WITH_MUX_GATE(csi1_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), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
0x144, 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 const char * const mipi_csi_parents[] = { "pll-video", "pll-periph0",
"pll-isp" };
static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_clk, "mipi-csi", mipi_csi_parents,
0x16c, 0, 3, 24, 2, BIT(31), 0);
static struct ccu_common *sun8i_v3s_ccu_clks[] = {
&pll_cpu_clk.common,
&pll_audio_base_clk.common,
&pll_video_clk.common,
&pll_ve_clk.common,
&pll_ddr_clk.common,
&pll_periph0_clk.common,
&pll_isp_clk.common,
&pll_periph1_clk.common,
&cpu_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_dram_clk.common,
&bus_emac_clk.common,
&bus_hstimer_clk.common,
&bus_spi0_clk.common,
&bus_otg_clk.common,
&bus_ehci0_clk.common,
&bus_ohci0_clk.common,
&bus_ve_clk.common,
&bus_tcon0_clk.common,
&bus_csi_clk.common,
&bus_de_clk.common,
&bus_codec_clk.common,
&bus_pio_clk.common,
&bus_i2c0_clk.common,
&bus_i2c1_clk.common,
&bus_uart0_clk.common,
&bus_uart1_clk.common,
&bus_uart2_clk.common,
&bus_ephy_clk.common,
&bus_dbg_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,
&ce_clk.common,
&spi0_clk.common,
&usb_phy0_clk.common,
&usb_ohci0_clk.common,
&dram_clk.common,
&dram_ve_clk.common,
&dram_csi_clk.common,
&dram_ohci_clk.common,
&dram_ehci_clk.common,
&de_clk.common,
&tcon_clk.common,
&csi_misc_clk.common,
&csi0_mclk_clk.common,
&csi1_sclk_clk.common,
&csi1_mclk_clk.common,
&ve_clk.common,
&ac_dig_clk.common,
&avs_clk.common,
&mbus_clk.common,
&mipi_csi_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_v3s_hw_clks = {
.hws = {
[CLK_PLL_CPU] = &pll_cpu_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_ISP] = &pll_isp_clk.common.hw,
[CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
[CLK_CPU] = &cpu_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_DRAM] = &bus_dram_clk.common.hw,
[CLK_BUS_EMAC] = &bus_emac_clk.common.hw,
[CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
[CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
[CLK_BUS_OTG] = &bus_otg_clk.common.hw,
[CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw,
[CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw,
[CLK_BUS_VE] = &bus_ve_clk.common.hw,
[CLK_BUS_TCON0] = &bus_tcon0_clk.common.hw,
[CLK_BUS_CSI] = &bus_csi_clk.common.hw,
[CLK_BUS_DE] = &bus_de_clk.common.hw,
[CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
[CLK_BUS_PIO] = &bus_pio_clk.common.hw,
[CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
[CLK_BUS_I2C1] = &bus_i2c1_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_EPHY] = &bus_ephy_clk.common.hw,
[CLK_BUS_DBG] = &bus_dbg_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_CE] = &ce_clk.common.hw,
[CLK_SPI0] = &spi0_clk.common.hw,
[CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
[CLK_USB_OHCI0] = &usb_ohci0_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_EHCI] = &dram_ehci_clk.common.hw,
[CLK_DRAM_OHCI] = &dram_ohci_clk.common.hw,
[CLK_DE] = &de_clk.common.hw,
[CLK_TCON0] = &tcon_clk.common.hw,
[CLK_CSI_MISC] = &csi_misc_clk.common.hw,
[CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
[CLK_CSI1_SCLK] = &csi1_sclk_clk.common.hw,
[CLK_CSI1_MCLK] = &csi1_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_MBUS] = &mbus_clk.common.hw,
[CLK_MIPI_CSI] = &mipi_csi_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct ccu_reset_map sun8i_v3s_ccu_resets[] = {
[RST_USB_PHY0] = { 0x0cc, BIT(0) },
[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_DRAM] = { 0x2c0, BIT(14) },
[RST_BUS_EMAC] = { 0x2c0, BIT(17) },
[RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
[RST_BUS_SPI0] = { 0x2c0, BIT(20) },
[RST_BUS_OTG] = { 0x2c0, BIT(23) },
[RST_BUS_EHCI0] = { 0x2c0, BIT(26) },
[RST_BUS_OHCI0] = { 0x2c0, BIT(29) },
[RST_BUS_VE] = { 0x2c4, BIT(0) },
[RST_BUS_TCON0] = { 0x2c4, BIT(3) },
[RST_BUS_CSI] = { 0x2c4, BIT(8) },
[RST_BUS_DE] = { 0x2c4, BIT(12) },
[RST_BUS_DBG] = { 0x2c4, BIT(31) },
[RST_BUS_EPHY] = { 0x2c8, BIT(2) },
[RST_BUS_CODEC] = { 0x2d0, BIT(0) },
[RST_BUS_I2C0] = { 0x2d8, BIT(0) },
[RST_BUS_I2C1] = { 0x2d8, BIT(1) },
[RST_BUS_UART0] = { 0x2d8, BIT(16) },
[RST_BUS_UART1] = { 0x2d8, BIT(17) },
[RST_BUS_UART2] = { 0x2d8, BIT(18) },
};
static const struct sunxi_ccu_desc sun8i_v3s_ccu_desc = {
.ccu_clks = sun8i_v3s_ccu_clks,
.num_ccu_clks = ARRAY_SIZE(sun8i_v3s_ccu_clks),
.hw_clks = &sun8i_v3s_hw_clks,
.resets = sun8i_v3s_ccu_resets,
.num_resets = ARRAY_SIZE(sun8i_v3s_ccu_resets),
};
static void __init sun8i_v3s_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_V3S_PLL_AUDIO_REG);
val &= ~GENMASK(19, 16);
writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG);
sunxi_ccu_probe(node, reg, &sun8i_v3s_ccu_desc);
}
CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
sun8i_v3s_ccu_setup);
/*
* Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
*
* Based on ccu-sun8i-h3.h, which is:
* Copyright (c) 2016 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-v3s-ccu.h>
#include <dt-bindings/reset/sun8i-v3s-ccu.h>
#define CLK_PLL_CPU 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_ISP 11
#define CLK_PLL_PERIPH1 12
/* Reserve one number for not implemented and not used PLL_DDR1 */
/* The CPU 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 58
/* All the DRAM gates are exported */
/* Some more module clocks are exported */
#define CLK_MBUS 72
/* And the GPU module clock is exported */
#define CLK_NUMBER (CLK_MIPI_CSI + 1)
#endif /* _CCU_SUN8I_H3_H_ */
/*
* Copyright (c) 2016 Chen-Yu Tsai. 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.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include "ccu_common.h"
#include "ccu_div.h"
#include "ccu_gate.h"
#include "ccu_reset.h"
#include "ccu-sun9i-a80-de.h"
static SUNXI_CCU_GATE(fe0_clk, "fe0", "fe0-div",
0x00, BIT(0), 0);
static SUNXI_CCU_GATE(fe1_clk, "fe1", "fe1-div",
0x00, BIT(1), 0);
static SUNXI_CCU_GATE(fe2_clk, "fe2", "fe2-div",
0x00, BIT(2), 0);
static SUNXI_CCU_GATE(iep_deu0_clk, "iep-deu0", "de",
0x00, BIT(4), 0);
static SUNXI_CCU_GATE(iep_deu1_clk, "iep-deu1", "de",
0x00, BIT(5), 0);
static SUNXI_CCU_GATE(be0_clk, "be0", "be0-div",
0x00, BIT(8), 0);
static SUNXI_CCU_GATE(be1_clk, "be1", "be1-div",
0x00, BIT(9), 0);
static SUNXI_CCU_GATE(be2_clk, "be2", "be2-div",
0x00, BIT(10), 0);
static SUNXI_CCU_GATE(iep_drc0_clk, "iep-drc0", "de",
0x00, BIT(12), 0);
static SUNXI_CCU_GATE(iep_drc1_clk, "iep-drc1", "de",
0x00, BIT(13), 0);
static SUNXI_CCU_GATE(merge_clk, "merge", "de",
0x00, BIT(20), 0);
static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "sdram",
0x04, BIT(0), 0);
static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "sdram",
0x04, BIT(1), 0);
static SUNXI_CCU_GATE(dram_fe2_clk, "dram-fe2", "sdram",
0x04, BIT(2), 0);
static SUNXI_CCU_GATE(dram_deu0_clk, "dram-deu0", "sdram",
0x04, BIT(4), 0);
static SUNXI_CCU_GATE(dram_deu1_clk, "dram-deu1", "sdram",
0x04, BIT(5), 0);
static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "sdram",
0x04, BIT(8), 0);
static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "sdram",
0x04, BIT(9), 0);
static SUNXI_CCU_GATE(dram_be2_clk, "dram-be2", "sdram",
0x04, BIT(10), 0);
static SUNXI_CCU_GATE(dram_drc0_clk, "dram-drc0", "sdram",
0x04, BIT(12), 0);
static SUNXI_CCU_GATE(dram_drc1_clk, "dram-drc1", "sdram",
0x04, BIT(13), 0);
static SUNXI_CCU_GATE(bus_fe0_clk, "bus-fe0", "bus-de",
0x08, BIT(0), 0);
static SUNXI_CCU_GATE(bus_fe1_clk, "bus-fe1", "bus-de",
0x08, BIT(1), 0);
static SUNXI_CCU_GATE(bus_fe2_clk, "bus-fe2", "bus-de",
0x08, BIT(2), 0);
static SUNXI_CCU_GATE(bus_deu0_clk, "bus-deu0", "bus-de",
0x08, BIT(4), 0);
static SUNXI_CCU_GATE(bus_deu1_clk, "bus-deu1", "bus-de",
0x08, BIT(5), 0);
static SUNXI_CCU_GATE(bus_be0_clk, "bus-be0", "bus-de",
0x08, BIT(8), 0);
static SUNXI_CCU_GATE(bus_be1_clk, "bus-be1", "bus-de",
0x08, BIT(9), 0);
static SUNXI_CCU_GATE(bus_be2_clk, "bus-be2", "bus-de",
0x08, BIT(10), 0);
static SUNXI_CCU_GATE(bus_drc0_clk, "bus-drc0", "bus-de",
0x08, BIT(12), 0);
static SUNXI_CCU_GATE(bus_drc1_clk, "bus-drc1", "bus-de",
0x08, BIT(13), 0);
static SUNXI_CCU_M(fe0_div_clk, "fe0-div", "de", 0x20, 0, 4, 0);
static SUNXI_CCU_M(fe1_div_clk, "fe1-div", "de", 0x20, 4, 4, 0);
static SUNXI_CCU_M(fe2_div_clk, "fe2-div", "de", 0x20, 8, 4, 0);
static SUNXI_CCU_M(be0_div_clk, "be0-div", "de", 0x20, 16, 4, 0);
static SUNXI_CCU_M(be1_div_clk, "be1-div", "de", 0x20, 20, 4, 0);
static SUNXI_CCU_M(be2_div_clk, "be2-div", "de", 0x20, 24, 4, 0);
static struct ccu_common *sun9i_a80_de_clks[] = {
&fe0_clk.common,
&fe1_clk.common,
&fe2_clk.common,
&iep_deu0_clk.common,
&iep_deu1_clk.common,
&be0_clk.common,
&be1_clk.common,
&be2_clk.common,
&iep_drc0_clk.common,
&iep_drc1_clk.common,
&merge_clk.common,
&dram_fe0_clk.common,
&dram_fe1_clk.common,
&dram_fe2_clk.common,
&dram_deu0_clk.common,
&dram_deu1_clk.common,
&dram_be0_clk.common,
&dram_be1_clk.common,
&dram_be2_clk.common,
&dram_drc0_clk.common,
&dram_drc1_clk.common,
&bus_fe0_clk.common,
&bus_fe1_clk.common,
&bus_fe2_clk.common,
&bus_deu0_clk.common,
&bus_deu1_clk.common,
&bus_be0_clk.common,
&bus_be1_clk.common,
&bus_be2_clk.common,
&bus_drc0_clk.common,
&bus_drc1_clk.common,
&fe0_div_clk.common,
&fe1_div_clk.common,
&fe2_div_clk.common,
&be0_div_clk.common,
&be1_div_clk.common,
&be2_div_clk.common,
};
static struct clk_hw_onecell_data sun9i_a80_de_hw_clks = {
.hws = {
[CLK_FE0] = &fe0_clk.common.hw,
[CLK_FE1] = &fe1_clk.common.hw,
[CLK_FE2] = &fe2_clk.common.hw,
[CLK_IEP_DEU0] = &iep_deu0_clk.common.hw,
[CLK_IEP_DEU1] = &iep_deu1_clk.common.hw,
[CLK_BE0] = &be0_clk.common.hw,
[CLK_BE1] = &be1_clk.common.hw,
[CLK_BE2] = &be2_clk.common.hw,
[CLK_IEP_DRC0] = &iep_drc0_clk.common.hw,
[CLK_IEP_DRC1] = &iep_drc1_clk.common.hw,
[CLK_MERGE] = &merge_clk.common.hw,
[CLK_DRAM_FE0] = &dram_fe0_clk.common.hw,
[CLK_DRAM_FE1] = &dram_fe1_clk.common.hw,
[CLK_DRAM_FE2] = &dram_fe2_clk.common.hw,
[CLK_DRAM_DEU0] = &dram_deu0_clk.common.hw,
[CLK_DRAM_DEU1] = &dram_deu1_clk.common.hw,
[CLK_DRAM_BE0] = &dram_be0_clk.common.hw,
[CLK_DRAM_BE1] = &dram_be1_clk.common.hw,
[CLK_DRAM_BE2] = &dram_be2_clk.common.hw,
[CLK_DRAM_DRC0] = &dram_drc0_clk.common.hw,
[CLK_DRAM_DRC1] = &dram_drc1_clk.common.hw,
[CLK_BUS_FE0] = &bus_fe0_clk.common.hw,
[CLK_BUS_FE1] = &bus_fe1_clk.common.hw,
[CLK_BUS_FE2] = &bus_fe2_clk.common.hw,
[CLK_BUS_DEU0] = &bus_deu0_clk.common.hw,
[CLK_BUS_DEU1] = &bus_deu1_clk.common.hw,
[CLK_BUS_BE0] = &bus_be0_clk.common.hw,
[CLK_BUS_BE1] = &bus_be1_clk.common.hw,
[CLK_BUS_BE2] = &bus_be2_clk.common.hw,
[CLK_BUS_DRC0] = &bus_drc0_clk.common.hw,
[CLK_BUS_DRC1] = &bus_drc1_clk.common.hw,
[CLK_FE0_DIV] = &fe0_div_clk.common.hw,
[CLK_FE1_DIV] = &fe1_div_clk.common.hw,
[CLK_FE2_DIV] = &fe2_div_clk.common.hw,
[CLK_BE0_DIV] = &be0_div_clk.common.hw,
[CLK_BE1_DIV] = &be1_div_clk.common.hw,
[CLK_BE2_DIV] = &be2_div_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct ccu_reset_map sun9i_a80_de_resets[] = {
[RST_FE0] = { 0x0c, BIT(0) },
[RST_FE1] = { 0x0c, BIT(1) },
[RST_FE2] = { 0x0c, BIT(2) },
[RST_DEU0] = { 0x0c, BIT(4) },
[RST_DEU1] = { 0x0c, BIT(5) },
[RST_BE0] = { 0x0c, BIT(8) },
[RST_BE1] = { 0x0c, BIT(9) },
[RST_BE2] = { 0x0c, BIT(10) },
[RST_DRC0] = { 0x0c, BIT(12) },
[RST_DRC1] = { 0x0c, BIT(13) },
[RST_MERGE] = { 0x0c, BIT(20) },
};
static const struct sunxi_ccu_desc sun9i_a80_de_clk_desc = {
.ccu_clks = sun9i_a80_de_clks,
.num_ccu_clks = ARRAY_SIZE(sun9i_a80_de_clks),
.hw_clks = &sun9i_a80_de_hw_clks,
.resets = sun9i_a80_de_resets,
.num_resets = ARRAY_SIZE(sun9i_a80_de_resets),
};
static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
{
struct resource *res;
struct clk *bus_clk;
struct reset_control *rstc;
void __iomem *reg;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(reg))
return PTR_ERR(reg);
bus_clk = devm_clk_get(&pdev->dev, "bus");
if (IS_ERR(bus_clk)) {
ret = PTR_ERR(bus_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
return ret;
}
rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(rstc)) {
ret = PTR_ERR(bus_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"Couldn't get reset control: %d\n", ret);
return ret;
}
/* The bus clock needs to be enabled for us to access the registers */
ret = clk_prepare_enable(bus_clk);
if (ret) {
dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret);
return ret;
}
/* The reset control needs to be asserted for the controls to work */
ret = reset_control_deassert(rstc);
if (ret) {
dev_err(&pdev->dev,
"Couldn't deassert reset control: %d\n", ret);
goto err_disable_clk;
}
ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
&sun9i_a80_de_clk_desc);
if (ret)
goto err_assert_reset;
return 0;
err_assert_reset:
reset_control_assert(rstc);
err_disable_clk:
clk_disable_unprepare(bus_clk);
return ret;
}
static const struct of_device_id sun9i_a80_de_clk_ids[] = {
{ .compatible = "allwinner,sun9i-a80-de-clks" },
{ }
};
static struct platform_driver sun9i_a80_de_clk_driver = {
.probe = sun9i_a80_de_clk_probe,
.driver = {
.name = "sun9i-a80-de-clks",
.of_match_table = sun9i_a80_de_clk_ids,
},
};
builtin_platform_driver(sun9i_a80_de_clk_driver);
/*
* Copyright 2016 Chen-Yu Tsai
*
* Chen-Yu Tsai <wens@csie.org>
*
* 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_SUN9I_A80_DE_H_
#define _CCU_SUN9I_A80_DE_H_
#include <dt-bindings/clock/sun9i-a80-de.h>
#include <dt-bindings/reset/sun9i-a80-de.h>
/* Intermediary clock dividers are not exported */
#define CLK_FE0_DIV 31
#define CLK_FE1_DIV 32
#define CLK_FE2_DIV 33
#define CLK_BE0_DIV 34
#define CLK_BE1_DIV 35
#define CLK_BE2_DIV 36
#define CLK_NUMBER (CLK_BE2_DIV + 1)
#endif /* _CCU_SUN9I_A80_DE_H_ */
/*
* Copyright (c) 2016 Chen-Yu Tsai. 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.h>
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include "ccu_common.h"
#include "ccu_gate.h"
#include "ccu_reset.h"
#include "ccu-sun9i-a80-usb.h"
static SUNXI_CCU_GATE(bus_hci0_clk, "bus-hci0", "bus-usb", 0x0, BIT(1), 0);
static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", 0x0, BIT(2), 0);
static SUNXI_CCU_GATE(bus_hci1_clk, "bus-hci1", "bus-usb", 0x0, BIT(3), 0);
static SUNXI_CCU_GATE(bus_hci2_clk, "bus-hci2", "bus-usb", 0x0, BIT(5), 0);
static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", 0x0, BIT(6), 0);
static SUNXI_CCU_GATE(usb0_phy_clk, "usb0-phy", "osc24M", 0x4, BIT(1), 0);
static SUNXI_CCU_GATE(usb1_hsic_clk, "usb1-hsic", "osc24M", 0x4, BIT(2), 0);
static SUNXI_CCU_GATE(usb1_phy_clk, "usb1-phy", "osc24M", 0x4, BIT(3), 0);
static SUNXI_CCU_GATE(usb2_hsic_clk, "usb2-hsic", "osc24M", 0x4, BIT(4), 0);
static SUNXI_CCU_GATE(usb2_phy_clk, "usb2-phy", "osc24M", 0x4, BIT(5), 0);
static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "osc24M", 0x4, BIT(10), 0);
static struct ccu_common *sun9i_a80_usb_clks[] = {
&bus_hci0_clk.common,
&usb_ohci0_clk.common,
&bus_hci1_clk.common,
&bus_hci2_clk.common,
&usb_ohci2_clk.common,
&usb0_phy_clk.common,
&usb1_hsic_clk.common,
&usb1_phy_clk.common,
&usb2_hsic_clk.common,
&usb2_phy_clk.common,
&usb_hsic_clk.common,
};
static struct clk_hw_onecell_data sun9i_a80_usb_hw_clks = {
.hws = {
[CLK_BUS_HCI0] = &bus_hci0_clk.common.hw,
[CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
[CLK_BUS_HCI1] = &bus_hci1_clk.common.hw,
[CLK_BUS_HCI2] = &bus_hci2_clk.common.hw,
[CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
[CLK_USB0_PHY] = &usb0_phy_clk.common.hw,
[CLK_USB1_HSIC] = &usb1_hsic_clk.common.hw,
[CLK_USB1_PHY] = &usb1_phy_clk.common.hw,
[CLK_USB2_HSIC] = &usb2_hsic_clk.common.hw,
[CLK_USB2_PHY] = &usb2_phy_clk.common.hw,
[CLK_USB_HSIC] = &usb_hsic_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct ccu_reset_map sun9i_a80_usb_resets[] = {
[RST_USB0_HCI] = { 0x0, BIT(17) },
[RST_USB1_HCI] = { 0x0, BIT(18) },
[RST_USB2_HCI] = { 0x0, BIT(19) },
[RST_USB0_PHY] = { 0x4, BIT(17) },
[RST_USB1_HSIC] = { 0x4, BIT(18) },
[RST_USB1_PHY] = { 0x4, BIT(19) },
[RST_USB2_HSIC] = { 0x4, BIT(20) },
[RST_USB2_PHY] = { 0x4, BIT(21) },
};
static const struct sunxi_ccu_desc sun9i_a80_usb_clk_desc = {
.ccu_clks = sun9i_a80_usb_clks,
.num_ccu_clks = ARRAY_SIZE(sun9i_a80_usb_clks),
.hw_clks = &sun9i_a80_usb_hw_clks,
.resets = sun9i_a80_usb_resets,
.num_resets = ARRAY_SIZE(sun9i_a80_usb_resets),
};
static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
{
struct resource *res;
struct clk *bus_clk;
void __iomem *reg;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(reg))
return PTR_ERR(reg);
bus_clk = devm_clk_get(&pdev->dev, "bus");
if (IS_ERR(bus_clk)) {
ret = PTR_ERR(bus_clk);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret);
return ret;
}
/* The bus clock needs to be enabled for us to access the registers */
ret = clk_prepare_enable(bus_clk);
if (ret) {
dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret);
return ret;
}
ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
&sun9i_a80_usb_clk_desc);
if (ret)
goto err_disable_clk;
return 0;
err_disable_clk:
clk_disable_unprepare(bus_clk);
return ret;
}
static const struct of_device_id sun9i_a80_usb_clk_ids[] = {
{ .compatible = "allwinner,sun9i-a80-usb-clks" },
{ }
};
static struct platform_driver sun9i_a80_usb_clk_driver = {
.probe = sun9i_a80_usb_clk_probe,
.driver = {
.name = "sun9i-a80-usb-clks",
.of_match_table = sun9i_a80_usb_clk_ids,
},
};
builtin_platform_driver(sun9i_a80_usb_clk_driver);
/*
* Copyright 2016 Chen-Yu Tsai
*
* Chen-Yu Tsai <wens@csie.org>
*
* 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_SUN9I_A80_USB_H_
#define _CCU_SUN9I_A80_USB_H_
#include <dt-bindings/clock/sun9i-a80-usb.h>
#include <dt-bindings/reset/sun9i-a80-usb.h>
#define CLK_NUMBER (CLK_USB_HSIC + 1)
#endif /* _CCU_SUN9I_A80_USB_H_ */
/*
* Copyright (c) 2016 Chen-Yu Tsai. 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 <linux/platform_device.h>
#include "ccu_common.h"
#include "ccu_reset.h"
#include "ccu_div.h"
#include "ccu_gate.h"
#include "ccu_mp.h"
#include "ccu_nkmp.h"
#include "ccu_nm.h"
#include "ccu_phase.h"
#include "ccu-sun9i-a80.h"
#define CCU_SUN9I_LOCK_REG 0x09c
static struct clk_div_table pll_cpux_p_div_table[] = {
{ .val = 0, .div = 1 },
{ .val = 1, .div = 4 },
{ /* Sentinel */ },
};
/*
* The CPU PLLs are actually NP clocks, but P is /1 or /4, so here we
* use the NM clocks with a divider table for M.
*/
static struct ccu_nm pll_c0cpux_clk = {
.enable = BIT(31),
.lock = BIT(0),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV_TABLE(16, 1, pll_cpux_p_div_table),
.common = {
.reg = 0x000,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-c0cpux", "osc24M",
&ccu_nm_ops, CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nm pll_c1cpux_clk = {
.enable = BIT(31),
.lock = BIT(1),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV_TABLE(16, 1, pll_cpux_p_div_table),
.common = {
.reg = 0x004,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-c1cpux", "osc24M",
&ccu_nm_ops, CLK_SET_RATE_UNGATE),
},
};
/*
* The Audio PLL has d1, d2 dividers in addition to the usual N, M
* factors. Since we only need 2 frequencies from this PLL: 22.5792 MHz
* and 24.576 MHz, ignore them for now. Enforce the default for them,
* which is d1 = 0, d2 = 1.
*/
#define SUN9I_A80_PLL_AUDIO_REG 0x008
static struct ccu_nm pll_audio_clk = {
.enable = BIT(31),
.lock = BIT(2),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV_OFFSET(0, 6, 0),
.common = {
.reg = 0x008,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-audio", "osc24M",
&ccu_nm_ops, CLK_SET_RATE_UNGATE),
},
};
/* Some PLLs are input * N / div1 / div2. Model them as NKMP with no K */
static struct ccu_nkmp pll_periph0_clk = {
.enable = BIT(31),
.lock = BIT(3),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x00c,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-periph0", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_ve_clk = {
.enable = BIT(31),
.lock = BIT(4),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x010,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-ve", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_ddr_clk = {
.enable = BIT(31),
.lock = BIT(5),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x014,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-ddr", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nm pll_video0_clk = {
.enable = BIT(31),
.lock = BIT(6),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.common = {
.reg = 0x018,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-video0", "osc24M",
&ccu_nm_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_video1_clk = {
.enable = BIT(31),
.lock = BIT(7),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(0, 2), /* external divider p */
.common = {
.reg = 0x01c,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-video1", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_gpu_clk = {
.enable = BIT(31),
.lock = BIT(8),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x020,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-gpu", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_de_clk = {
.enable = BIT(31),
.lock = BIT(9),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x024,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-de", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_isp_clk = {
.enable = BIT(31),
.lock = BIT(10),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x028,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-isp", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static struct ccu_nkmp pll_periph1_clk = {
.enable = BIT(31),
.lock = BIT(11),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(16, 1), /* input divider */
.p = _SUNXI_CCU_DIV(18, 1), /* output divider */
.common = {
.reg = 0x028,
.lock_reg = CCU_SUN9I_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.hw.init = CLK_HW_INIT("pll-periph1", "osc24M",
&ccu_nkmp_ops,
CLK_SET_RATE_UNGATE),
},
};
static const char * const c0cpux_parents[] = { "osc24M", "pll-c0cpux" };
static SUNXI_CCU_MUX(c0cpux_clk, "c0cpux", c0cpux_parents,
0x50, 0, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
static const char * const c1cpux_parents[] = { "osc24M", "pll-c1cpux" };
static SUNXI_CCU_MUX(c1cpux_clk, "c1cpux", c1cpux_parents,
0x50, 8, 1, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
static struct clk_div_table axi_div_table[] = {
{ .val = 0, .div = 1 },
{ .val = 1, .div = 2 },
{ .val = 2, .div = 3 },
{ .val = 3, .div = 4 },
{ .val = 4, .div = 4 },
{ .val = 5, .div = 4 },
{ .val = 6, .div = 4 },
{ .val = 7, .div = 4 },
{ /* Sentinel */ },
};
static SUNXI_CCU_M(atb0_clk, "atb0", "c0cpux", 0x054, 8, 2, 0);
static SUNXI_CCU_DIV_TABLE(axi0_clk, "axi0", "c0cpux",
0x054, 0, 3, axi_div_table, 0);
static SUNXI_CCU_M(atb1_clk, "atb1", "c1cpux", 0x058, 8, 2, 0);
static SUNXI_CCU_DIV_TABLE(axi1_clk, "axi1", "c1cpux",
0x058, 0, 3, axi_div_table, 0);
static const char * const gtbus_parents[] = { "osc24M", "pll-periph0",
"pll-periph1", "pll-periph1" };
static SUNXI_CCU_M_WITH_MUX(gtbus_clk, "gtbus", gtbus_parents,
0x05c, 0, 2, 24, 2, CLK_IS_CRITICAL);
static const char * const ahb_parents[] = { "gtbus", "pll-periph0",
"pll-periph1", "pll-periph1" };
static struct ccu_div ahb0_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = _SUNXI_CCU_MUX(24, 2),
.common = {
.reg = 0x060,
.hw.init = CLK_HW_INIT_PARENTS("ahb0",
ahb_parents,
&ccu_div_ops,
0),
},
};
static struct ccu_div ahb1_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = _SUNXI_CCU_MUX(24, 2),
.common = {
.reg = 0x064,
.hw.init = CLK_HW_INIT_PARENTS("ahb1",
ahb_parents,
&ccu_div_ops,
0),
},
};
static struct ccu_div ahb2_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = _SUNXI_CCU_MUX(24, 2),
.common = {
.reg = 0x068,
.hw.init = CLK_HW_INIT_PARENTS("ahb2",
ahb_parents,
&ccu_div_ops,
0),
},
};
static const char * const apb_parents[] = { "osc24M", "pll-periph0" };
static struct ccu_div apb0_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = _SUNXI_CCU_MUX(24, 1),
.common = {
.reg = 0x070,
.hw.init = CLK_HW_INIT_PARENTS("apb0",
apb_parents,
&ccu_div_ops,
0),
},
};
static struct ccu_div apb1_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = _SUNXI_CCU_MUX(24, 1),
.common = {
.reg = 0x074,
.hw.init = CLK_HW_INIT_PARENTS("apb1",
apb_parents,
&ccu_div_ops,
0),
},
};
static struct ccu_div cci400_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = _SUNXI_CCU_MUX(24, 2),
.common = {
.reg = 0x078,
.hw.init = CLK_HW_INIT_PARENTS("cci400",
ahb_parents,
&ccu_div_ops,
CLK_IS_CRITICAL),
},
};
static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", apb_parents,
0x080, 0, 3, 24, 2, BIT(31), 0);
static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", apb_parents,
0x084, 0, 3, 24, 2, BIT(31), 0);
static const char * const out_parents[] = { "osc24M", "osc32k", "osc24M" };
static const struct ccu_mux_fixed_prediv out_prediv = {
.index = 0, .div = 750
};
static struct ccu_mp out_a_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(8, 5),
.p = _SUNXI_CCU_DIV(20, 2),
.mux = {
.shift = 24,
.width = 4,
.fixed_predivs = &out_prediv,
.n_predivs = 1,
},
.common = {
.reg = 0x180,
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("out-a",
out_parents,
&ccu_mp_ops,
0),
},
};
static struct ccu_mp out_b_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(8, 5),
.p = _SUNXI_CCU_DIV(20, 2),
.mux = {
.shift = 24,
.width = 4,
.fixed_predivs = &out_prediv,
.n_predivs = 1,
},
.common = {
.reg = 0x184,
.features = CCU_FEATURE_FIXED_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("out-b",
out_parents,
&ccu_mp_ops,
0),
},
};
static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0" };
static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_0_clk, "nand0-0", mod0_default_parents,
0x400,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_1_clk, "nand0-1", mod0_default_parents,
0x404,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_0_clk, "nand1-0", mod0_default_parents,
0x408,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_1_clk, "nand1-1", mod0_default_parents,
0x40c,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
0x410,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0-sample", "mmc0",
0x410, 20, 3, 0);
static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0-output", "mmc0",
0x410, 8, 3, 0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
0x414,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1-sample", "mmc1",
0x414, 20, 3, 0);
static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1-output", "mmc1",
0x414, 8, 3, 0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
0x418,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2-sample", "mmc2",
0x418, 20, 3, 0);
static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2-output", "mmc2",
0x418, 8, 3, 0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents,
0x41c,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3-sample", "mmc3",
0x41c, 20, 3, 0);
static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3-output", "mmc3",
0x41c, 8, 3, 0);
static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents,
0x428,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static const char * const ss_parents[] = { "osc24M", "pll-periph",
"pll-periph1" };
static const u8 ss_table[] = { 0, 1, 13 };
static struct ccu_mp ss_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(0, 4),
.p = _SUNXI_CCU_DIV(16, 2),
.mux = _SUNXI_CCU_MUX_TABLE(24, 4, ss_table),
.common = {
.reg = 0x42c,
.hw.init = CLK_HW_INIT_PARENTS("ss",
ss_parents,
&ccu_mp_ops,
0),
},
};
static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents,
0x430,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents,
0x434,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents,
0x438,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents,
0x43c,
0, 4, /* M */
16, 2, /* P */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_M_WITH_GATE(i2s0_clk, "i2s0", "pll-audio",
0x440, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_GATE(i2s1_clk, "i2s1", "pll-audio",
0x444, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
0x44c, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
static const char * const sdram_parents[] = { "pll-periph0", "pll-ddr" };
static const u8 sdram_table[] = { 0, 3 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(sdram_clk, "sdram",
sdram_parents, sdram_table,
0x484,
8, 4, /* M */
12, 4, /* mux */
0, /* no gate */
CLK_IS_CRITICAL);
static SUNXI_CCU_M_WITH_GATE(de_clk, "de", "pll-de", 0x490,
0, 4, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(edp_clk, "edp", "osc24M", 0x494, BIT(31), 0);
static const char * const mp_parents[] = { "pll-video1", "pll-gpu", "pll-de" };
static const u8 mp_table[] = { 9, 10, 11 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mp_clk, "mp", mp_parents, mp_table,
0x498,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
0);
static const char * const display_parents[] = { "pll-video0", "pll-video1" };
static const u8 display_table[] = { 8, 9 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd0_clk, "lcd0",
display_parents, display_table,
0x49c,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_NO_REPARENT |
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd1_clk, "lcd1",
display_parents, display_table,
0x4a0,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_NO_REPARENT |
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi0_clk, "mipi-dsi0",
display_parents, display_table,
0x4a8,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_PARENT);
static const char * const mipi_dsi1_parents[] = { "osc24M", "pll-video1" };
static const u8 mipi_dsi1_table[] = { 0, 9 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(mipi_dsi1_clk, "mipi-dsi1",
mipi_dsi1_parents, mipi_dsi1_table,
0x4ac,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
display_parents, display_table,
0x4b0,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_NO_REPARENT |
CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 0x4b4, BIT(31), 0);
static SUNXI_CCU_M_WITH_GATE(mipi_csi_clk, "mipi-csi", "osc24M", 0x4bc,
0, 4, BIT(31), 0);
static SUNXI_CCU_M_WITH_GATE(csi_isp_clk, "csi-isp", "pll-isp", 0x4c0,
0, 4, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x4c0, BIT(16), 0);
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_mclk_clk, "csi0-mclk",
mipi_dsi1_parents, mipi_dsi1_table,
0x4c4,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_mclk_clk, "csi1-mclk",
mipi_dsi1_parents, mipi_dsi1_table,
0x4c8,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_PARENT);
static const char * const fd_parents[] = { "pll-periph0", "pll-isp" };
static const u8 fd_table[] = { 1, 12 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(fd_clk, "fd", fd_parents, fd_table,
0x4cc,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x4d0,
16, 3, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x4d4, BIT(31), 0);
static SUNXI_CCU_M_WITH_GATE(gpu_core_clk, "gpu-core", "pll-gpu", 0x4f0,
0, 3, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_GATE(gpu_memory_clk, "gpu-memory", "pll-gpu", 0x4f4,
0, 3, BIT(31), CLK_SET_RATE_PARENT);
static const char * const gpu_axi_parents[] = { "pll-periph0", "pll-gpu" };
static const u8 gpu_axi_table[] = { 1, 10 };
static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_axi_clk, "gpu-axi",
gpu_axi_parents, gpu_axi_table,
0x4f8,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_GATE(sata_clk, "sata", "pll-periph0", 0x500,
0, 4, BIT(31), 0);
static SUNXI_CCU_M_WITH_GATE(ac97_clk, "ac97", "pll-audio",
0x504, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_GATE(mipi_hsi_clk, "mipi-hsi",
mod0_default_parents, 0x508,
0, 4, /* M */
24, 4, /* mux */
BIT(31), /* gate */
0);
static const char * const gpadc_parents[] = { "osc24M", "pll-audio", "osc32k" };
static const u8 gpadc_table[] = { 0, 4, 7 };
static struct ccu_mp gpadc_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(0, 4),
.p = _SUNXI_CCU_DIV(16, 2),
.mux = _SUNXI_CCU_MUX_TABLE(24, 4, gpadc_table),
.common = {
.reg = 0x50c,
.hw.init = CLK_HW_INIT_PARENTS("gpadc",
gpadc_parents,
&ccu_mp_ops,
0),
},
};
static const char * const cir_tx_parents[] = { "osc24M", "osc32k" };
static const u8 cir_tx_table[] = { 0, 7 };
static struct ccu_mp cir_tx_clk = {
.enable = BIT(31),
.m = _SUNXI_CCU_DIV(0, 4),
.p = _SUNXI_CCU_DIV(16, 2),
.mux = _SUNXI_CCU_MUX_TABLE(24, 4, cir_tx_table),
.common = {
.reg = 0x510,
.hw.init = CLK_HW_INIT_PARENTS("cir-tx",
cir_tx_parents,
&ccu_mp_ops,
0),
},
};
/* AHB0 bus gates */
static SUNXI_CCU_GATE(bus_fd_clk, "bus-fd", "ahb0",
0x580, BIT(0), 0);
static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb0",
0x580, BIT(1), 0);
static SUNXI_CCU_GATE(bus_gpu_ctrl_clk, "bus-gpu-ctrl", "ahb0",
0x580, BIT(3), 0);
static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb0",
0x580, BIT(5), 0);
static SUNXI_CCU_GATE(bus_mmc_clk, "bus-mmc", "ahb0",
0x580, BIT(8), 0);
static SUNXI_CCU_GATE(bus_nand0_clk, "bus-nand0", "ahb0",
0x580, BIT(12), 0);
static SUNXI_CCU_GATE(bus_nand1_clk, "bus-nand1", "ahb0",
0x580, BIT(13), 0);
static SUNXI_CCU_GATE(bus_sdram_clk, "bus-sdram", "ahb0",
0x580, BIT(14), 0);
static SUNXI_CCU_GATE(bus_mipi_hsi_clk, "bus-mipi-hsi", "ahb0",
0x580, BIT(15), 0);
static SUNXI_CCU_GATE(bus_sata_clk, "bus-sata", "ahb0",
0x580, BIT(16), 0);
static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb0",
0x580, BIT(18), 0);
static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb0",
0x580, BIT(20), 0);
static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb0",
0x580, BIT(21), 0);
static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb0",
0x580, BIT(22), 0);
static SUNXI_CCU_GATE(bus_spi3_clk, "bus-spi3", "ahb0",
0x580, BIT(23), 0);
/* AHB1 bus gates */
static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
0x584, BIT(0), 0);
static SUNXI_CCU_GATE(bus_usb_clk, "bus-usb", "ahb1",
0x584, BIT(1), 0);
static SUNXI_CCU_GATE(bus_gmac_clk, "bus-gmac", "ahb1",
0x584, BIT(17), 0);
static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
0x584, BIT(21), 0);
static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
0x584, BIT(22), 0);
static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
0x584, BIT(23), 0);
static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
0x584, BIT(24), 0);
/* AHB2 bus gates */
static SUNXI_CCU_GATE(bus_lcd0_clk, "bus-lcd0", "ahb2",
0x588, BIT(0), 0);
static SUNXI_CCU_GATE(bus_lcd1_clk, "bus-lcd1", "ahb2",
0x588, BIT(1), 0);
static SUNXI_CCU_GATE(bus_edp_clk, "bus-edp", "ahb2",
0x588, BIT(2), 0);
static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb2",
0x588, BIT(4), 0);
static SUNXI_CCU_GATE(bus_hdmi_clk, "bus-hdmi", "ahb2",
0x588, BIT(5), 0);
static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb2",
0x588, BIT(7), 0);
static SUNXI_CCU_GATE(bus_mp_clk, "bus-mp", "ahb2",
0x588, BIT(8), 0);
static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb2",
0x588, BIT(11), 0);
/* APB0 bus gates */
static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb0",
0x590, BIT(1), 0);
static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb0",
0x590, BIT(5), 0);
static SUNXI_CCU_GATE(bus_ac97_clk, "bus-ac97", "apb0",
0x590, BIT(11), 0);
static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb0",
0x590, BIT(12), 0);
static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb0",
0x590, BIT(13), 0);
static SUNXI_CCU_GATE(bus_lradc_clk, "bus-lradc", "apb0",
0x590, BIT(15), 0);
static SUNXI_CCU_GATE(bus_gpadc_clk, "bus-gpadc", "apb0",
0x590, BIT(17), 0);
static SUNXI_CCU_GATE(bus_twd_clk, "bus-twd", "apb0",
0x590, BIT(18), 0);
static SUNXI_CCU_GATE(bus_cir_tx_clk, "bus-cir-tx", "apb0",
0x590, BIT(19), 0);
/* APB1 bus gates */
static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb1",
0x594, BIT(0), 0);
static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb1",
0x594, BIT(1), 0);
static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb1",
0x594, BIT(2), 0);
static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb1",
0x594, BIT(3), 0);
static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb1",
0x594, BIT(4), 0);
static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb1",
0x594, BIT(16), 0);
static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb1",
0x594, BIT(17), 0);
static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb1",
0x594, BIT(18), 0);
static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb1",
0x594, BIT(19), 0);
static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb1",
0x594, BIT(20), 0);
static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb1",
0x594, BIT(21), 0);
static struct ccu_common *sun9i_a80_ccu_clks[] = {
&pll_c0cpux_clk.common,
&pll_c1cpux_clk.common,
&pll_audio_clk.common,
&pll_periph0_clk.common,
&pll_ve_clk.common,
&pll_ddr_clk.common,
&pll_video0_clk.common,
&pll_video1_clk.common,
&pll_gpu_clk.common,
&pll_de_clk.common,
&pll_isp_clk.common,
&pll_periph1_clk.common,
&c0cpux_clk.common,
&c1cpux_clk.common,
&atb0_clk.common,
&axi0_clk.common,
&atb1_clk.common,
&axi1_clk.common,
&gtbus_clk.common,
&ahb0_clk.common,
&ahb1_clk.common,
&ahb2_clk.common,
&apb0_clk.common,
&apb1_clk.common,
&cci400_clk.common,
&ats_clk.common,
&trace_clk.common,
&out_a_clk.common,
&out_b_clk.common,
/* module clocks */
&nand0_0_clk.common,
&nand0_1_clk.common,
&nand1_0_clk.common,
&nand1_1_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,
&mmc3_clk.common,
&mmc3_sample_clk.common,
&mmc3_output_clk.common,
&ts_clk.common,
&ss_clk.common,
&spi0_clk.common,
&spi1_clk.common,
&spi2_clk.common,
&spi3_clk.common,
&i2s0_clk.common,
&i2s1_clk.common,
&spdif_clk.common,
&sdram_clk.common,
&de_clk.common,
&edp_clk.common,
&mp_clk.common,
&lcd0_clk.common,
&lcd1_clk.common,
&mipi_dsi0_clk.common,
&mipi_dsi1_clk.common,
&hdmi_clk.common,
&hdmi_slow_clk.common,
&mipi_csi_clk.common,
&csi_isp_clk.common,
&csi_misc_clk.common,
&csi0_mclk_clk.common,
&csi1_mclk_clk.common,
&fd_clk.common,
&ve_clk.common,
&avs_clk.common,
&gpu_core_clk.common,
&gpu_memory_clk.common,
&gpu_axi_clk.common,
&sata_clk.common,
&ac97_clk.common,
&mipi_hsi_clk.common,
&gpadc_clk.common,
&cir_tx_clk.common,
/* AHB0 bus gates */
&bus_fd_clk.common,
&bus_ve_clk.common,
&bus_gpu_ctrl_clk.common,
&bus_ss_clk.common,
&bus_mmc_clk.common,
&bus_nand0_clk.common,
&bus_nand1_clk.common,
&bus_sdram_clk.common,
&bus_mipi_hsi_clk.common,
&bus_sata_clk.common,
&bus_ts_clk.common,
&bus_spi0_clk.common,
&bus_spi1_clk.common,
&bus_spi2_clk.common,
&bus_spi3_clk.common,
/* AHB1 bus gates */
&bus_otg_clk.common,
&bus_usb_clk.common,
&bus_gmac_clk.common,
&bus_msgbox_clk.common,
&bus_spinlock_clk.common,
&bus_hstimer_clk.common,
&bus_dma_clk.common,
/* AHB2 bus gates */
&bus_lcd0_clk.common,
&bus_lcd1_clk.common,
&bus_edp_clk.common,
&bus_csi_clk.common,
&bus_hdmi_clk.common,
&bus_de_clk.common,
&bus_mp_clk.common,
&bus_mipi_dsi_clk.common,
/* APB0 bus gates */
&bus_spdif_clk.common,
&bus_pio_clk.common,
&bus_ac97_clk.common,
&bus_i2s0_clk.common,
&bus_i2s1_clk.common,
&bus_lradc_clk.common,
&bus_gpadc_clk.common,
&bus_twd_clk.common,
&bus_cir_tx_clk.common,
/* APB1 bus gates */
&bus_i2c0_clk.common,
&bus_i2c1_clk.common,
&bus_i2c2_clk.common,
&bus_i2c3_clk.common,
&bus_i2c4_clk.common,
&bus_uart0_clk.common,
&bus_uart1_clk.common,
&bus_uart2_clk.common,
&bus_uart3_clk.common,
&bus_uart4_clk.common,
&bus_uart5_clk.common,
};
static struct clk_hw_onecell_data sun9i_a80_hw_clks = {
.hws = {
[CLK_PLL_C0CPUX] = &pll_c0cpux_clk.common.hw,
[CLK_PLL_C1CPUX] = &pll_c1cpux_clk.common.hw,
[CLK_PLL_AUDIO] = &pll_audio_clk.common.hw,
[CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw,
[CLK_PLL_VE] = &pll_ve_clk.common.hw,
[CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
[CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
[CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
[CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
[CLK_PLL_DE] = &pll_de_clk.common.hw,
[CLK_PLL_ISP] = &pll_isp_clk.common.hw,
[CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw,
[CLK_C0CPUX] = &c0cpux_clk.common.hw,
[CLK_C1CPUX] = &c1cpux_clk.common.hw,
[CLK_ATB0] = &atb0_clk.common.hw,
[CLK_AXI0] = &axi0_clk.common.hw,
[CLK_ATB1] = &atb1_clk.common.hw,
[CLK_AXI1] = &axi1_clk.common.hw,
[CLK_GTBUS] = &gtbus_clk.common.hw,
[CLK_AHB0] = &ahb0_clk.common.hw,
[CLK_AHB1] = &ahb1_clk.common.hw,
[CLK_AHB2] = &ahb2_clk.common.hw,
[CLK_APB0] = &apb0_clk.common.hw,
[CLK_APB1] = &apb1_clk.common.hw,
[CLK_CCI400] = &cci400_clk.common.hw,
[CLK_ATS] = &ats_clk.common.hw,
[CLK_TRACE] = &trace_clk.common.hw,
[CLK_OUT_A] = &out_a_clk.common.hw,
[CLK_OUT_B] = &out_b_clk.common.hw,
[CLK_NAND0_0] = &nand0_0_clk.common.hw,
[CLK_NAND0_1] = &nand0_1_clk.common.hw,
[CLK_NAND1_0] = &nand1_0_clk.common.hw,
[CLK_NAND1_1] = &nand1_1_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_MMC3] = &mmc3_clk.common.hw,
[CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw,
[CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw,
[CLK_TS] = &ts_clk.common.hw,
[CLK_SS] = &ss_clk.common.hw,
[CLK_SPI0] = &spi0_clk.common.hw,
[CLK_SPI1] = &spi1_clk.common.hw,
[CLK_SPI2] = &spi2_clk.common.hw,
[CLK_SPI3] = &spi3_clk.common.hw,
[CLK_I2S0] = &i2s0_clk.common.hw,
[CLK_I2S1] = &i2s1_clk.common.hw,
[CLK_SPDIF] = &spdif_clk.common.hw,
[CLK_SDRAM] = &sdram_clk.common.hw,
[CLK_DE] = &de_clk.common.hw,
[CLK_EDP] = &edp_clk.common.hw,
[CLK_MP] = &mp_clk.common.hw,
[CLK_LCD0] = &lcd0_clk.common.hw,
[CLK_LCD1] = &lcd1_clk.common.hw,
[CLK_MIPI_DSI0] = &mipi_dsi0_clk.common.hw,
[CLK_MIPI_DSI1] = &mipi_dsi1_clk.common.hw,
[CLK_HDMI] = &hdmi_clk.common.hw,
[CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw,
[CLK_MIPI_CSI] = &mipi_csi_clk.common.hw,
[CLK_CSI_ISP] = &csi_isp_clk.common.hw,
[CLK_CSI_MISC] = &csi_misc_clk.common.hw,
[CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
[CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
[CLK_FD] = &fd_clk.common.hw,
[CLK_VE] = &ve_clk.common.hw,
[CLK_AVS] = &avs_clk.common.hw,
[CLK_GPU_CORE] = &gpu_core_clk.common.hw,
[CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw,
[CLK_GPU_AXI] = &gpu_axi_clk.common.hw,
[CLK_SATA] = &sata_clk.common.hw,
[CLK_AC97] = &ac97_clk.common.hw,
[CLK_MIPI_HSI] = &mipi_hsi_clk.common.hw,
[CLK_GPADC] = &gpadc_clk.common.hw,
[CLK_CIR_TX] = &cir_tx_clk.common.hw,
[CLK_BUS_FD] = &bus_fd_clk.common.hw,
[CLK_BUS_VE] = &bus_ve_clk.common.hw,
[CLK_BUS_GPU_CTRL] = &bus_gpu_ctrl_clk.common.hw,
[CLK_BUS_SS] = &bus_ss_clk.common.hw,
[CLK_BUS_MMC] = &bus_mmc_clk.common.hw,
[CLK_BUS_NAND0] = &bus_nand0_clk.common.hw,
[CLK_BUS_NAND1] = &bus_nand1_clk.common.hw,
[CLK_BUS_SDRAM] = &bus_sdram_clk.common.hw,
[CLK_BUS_MIPI_HSI] = &bus_mipi_hsi_clk.common.hw,
[CLK_BUS_SATA] = &bus_sata_clk.common.hw,
[CLK_BUS_TS] = &bus_ts_clk.common.hw,
[CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
[CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
[CLK_BUS_SPI2] = &bus_spi2_clk.common.hw,
[CLK_BUS_SPI3] = &bus_spi3_clk.common.hw,
[CLK_BUS_OTG] = &bus_otg_clk.common.hw,
[CLK_BUS_USB] = &bus_usb_clk.common.hw,
[CLK_BUS_GMAC] = &bus_gmac_clk.common.hw,
[CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
[CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
[CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
[CLK_BUS_DMA] = &bus_dma_clk.common.hw,
[CLK_BUS_LCD0] = &bus_lcd0_clk.common.hw,
[CLK_BUS_LCD1] = &bus_lcd1_clk.common.hw,
[CLK_BUS_EDP] = &bus_edp_clk.common.hw,
[CLK_BUS_CSI] = &bus_csi_clk.common.hw,
[CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw,
[CLK_BUS_DE] = &bus_de_clk.common.hw,
[CLK_BUS_MP] = &bus_mp_clk.common.hw,
[CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
[CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
[CLK_BUS_PIO] = &bus_pio_clk.common.hw,
[CLK_BUS_AC97] = &bus_ac97_clk.common.hw,
[CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
[CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
[CLK_BUS_LRADC] = &bus_lradc_clk.common.hw,
[CLK_BUS_GPADC] = &bus_gpadc_clk.common.hw,
[CLK_BUS_TWD] = &bus_twd_clk.common.hw,
[CLK_BUS_CIR_TX] = &bus_cir_tx_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_I2C3] = &bus_i2c3_clk.common.hw,
[CLK_BUS_I2C4] = &bus_i2c4_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_UART4] = &bus_uart4_clk.common.hw,
[CLK_BUS_UART5] = &bus_uart5_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct ccu_reset_map sun9i_a80_ccu_resets[] = {
/* AHB0 reset controls */
[RST_BUS_FD] = { 0x5a0, BIT(0) },
[RST_BUS_VE] = { 0x5a0, BIT(1) },
[RST_BUS_GPU_CTRL] = { 0x5a0, BIT(3) },
[RST_BUS_SS] = { 0x5a0, BIT(5) },
[RST_BUS_MMC] = { 0x5a0, BIT(8) },
[RST_BUS_NAND0] = { 0x5a0, BIT(12) },
[RST_BUS_NAND1] = { 0x5a0, BIT(13) },
[RST_BUS_SDRAM] = { 0x5a0, BIT(14) },
[RST_BUS_SATA] = { 0x5a0, BIT(16) },
[RST_BUS_TS] = { 0x5a0, BIT(18) },
[RST_BUS_SPI0] = { 0x5a0, BIT(20) },
[RST_BUS_SPI1] = { 0x5a0, BIT(21) },
[RST_BUS_SPI2] = { 0x5a0, BIT(22) },
[RST_BUS_SPI3] = { 0x5a0, BIT(23) },
/* AHB1 reset controls */
[RST_BUS_OTG] = { 0x5a4, BIT(0) },
[RST_BUS_OTG_PHY] = { 0x5a4, BIT(1) },
[RST_BUS_MIPI_HSI] = { 0x5a4, BIT(9) },
[RST_BUS_GMAC] = { 0x5a4, BIT(17) },
[RST_BUS_MSGBOX] = { 0x5a4, BIT(21) },
[RST_BUS_SPINLOCK] = { 0x5a4, BIT(22) },
[RST_BUS_HSTIMER] = { 0x5a4, BIT(23) },
[RST_BUS_DMA] = { 0x5a4, BIT(24) },
/* AHB2 reset controls */
[RST_BUS_LCD0] = { 0x5a8, BIT(0) },
[RST_BUS_LCD1] = { 0x5a8, BIT(1) },
[RST_BUS_EDP] = { 0x5a8, BIT(2) },
[RST_BUS_LVDS] = { 0x5a8, BIT(3) },
[RST_BUS_CSI] = { 0x5a8, BIT(4) },
[RST_BUS_HDMI0] = { 0x5a8, BIT(5) },
[RST_BUS_HDMI1] = { 0x5a8, BIT(6) },
[RST_BUS_DE] = { 0x5a8, BIT(7) },
[RST_BUS_MP] = { 0x5a8, BIT(8) },
[RST_BUS_GPU] = { 0x5a8, BIT(9) },
[RST_BUS_MIPI_DSI] = { 0x5a8, BIT(11) },
/* APB0 reset controls */
[RST_BUS_SPDIF] = { 0x5b0, BIT(1) },
[RST_BUS_AC97] = { 0x5b0, BIT(11) },
[RST_BUS_I2S0] = { 0x5b0, BIT(12) },
[RST_BUS_I2S1] = { 0x5b0, BIT(13) },
[RST_BUS_LRADC] = { 0x5b0, BIT(15) },
[RST_BUS_GPADC] = { 0x5b0, BIT(17) },
[RST_BUS_CIR_TX] = { 0x5b0, BIT(19) },
/* APB1 reset controls */
[RST_BUS_I2C0] = { 0x5b4, BIT(0) },
[RST_BUS_I2C1] = { 0x5b4, BIT(1) },
[RST_BUS_I2C2] = { 0x5b4, BIT(2) },
[RST_BUS_I2C3] = { 0x5b4, BIT(3) },
[RST_BUS_I2C4] = { 0x5b4, BIT(4) },
[RST_BUS_UART0] = { 0x5b4, BIT(16) },
[RST_BUS_UART1] = { 0x5b4, BIT(17) },
[RST_BUS_UART2] = { 0x5b4, BIT(18) },
[RST_BUS_UART3] = { 0x5b4, BIT(19) },
[RST_BUS_UART4] = { 0x5b4, BIT(20) },
[RST_BUS_UART5] = { 0x5b4, BIT(21) },
};
static const struct sunxi_ccu_desc sun9i_a80_ccu_desc = {
.ccu_clks = sun9i_a80_ccu_clks,
.num_ccu_clks = ARRAY_SIZE(sun9i_a80_ccu_clks),
.hw_clks = &sun9i_a80_hw_clks,
.resets = sun9i_a80_ccu_resets,
.num_resets = ARRAY_SIZE(sun9i_a80_ccu_resets),
};
static int sun9i_a80_ccu_probe(struct platform_device *pdev)
{
struct resource *res;
void __iomem *reg;
u32 val;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(reg))
return PTR_ERR(reg);
/* Enforce d1 = 0, d2 = 0 for Audio PLL */
val = readl(reg + SUN9I_A80_PLL_AUDIO_REG);
val &= (BIT(16) & BIT(18));
writel(val, reg + SUN9I_A80_PLL_AUDIO_REG);
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc);
}
static const struct of_device_id sun9i_a80_ccu_ids[] = {
{ .compatible = "allwinner,sun9i-a80-ccu" },
{ }
};
static struct platform_driver sun9i_a80_ccu_driver = {
.probe = sun9i_a80_ccu_probe,
.driver = {
.name = "sun9i-a80-ccu",
.of_match_table = sun9i_a80_ccu_ids,
},
};
builtin_platform_driver(sun9i_a80_ccu_driver);
/*
* Copyright 2016 Chen-Yu Tsai
*
* Chen-Yu Tsai <wens@csie.org>
*
* 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_SUN9I_A80_H_
#define _CCU_SUN9I_A80_H_
#include <dt-bindings/clock/sun9i-a80-ccu.h>
#include <dt-bindings/reset/sun9i-a80-ccu.h>
#define CLK_PLL_C0CPUX 0
#define CLK_PLL_C1CPUX 1
/* pll-audio and pll-periph0 are exported to the PRCM block */
#define CLK_PLL_VE 4
#define CLK_PLL_DDR 5
#define CLK_PLL_VIDEO0 6
#define CLK_PLL_VIDEO1 7
#define CLK_PLL_GPU 8
#define CLK_PLL_DE 9
#define CLK_PLL_ISP 10
#define CLK_PLL_PERIPH1 11
/* The CPUX clocks are exported */
#define CLK_ATB0 14
#define CLK_AXI0 15
#define CLK_ATB1 16
#define CLK_AXI1 17
#define CLK_GTBUS 18
#define CLK_AHB0 19
#define CLK_AHB1 20
#define CLK_AHB2 21
#define CLK_APB0 22
#define CLK_APB1 23
#define CLK_CCI400 24
#define CLK_ATS 25
#define CLK_TRACE 26
/* module clocks and bus gates exported */
#define CLK_NUMBER (CLK_BUS_UART5 + 1)
#endif /* _CCU_SUN9I_A80_H_ */
......@@ -25,13 +25,18 @@ static DEFINE_SPINLOCK(ccu_lock);
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
{
void __iomem *addr;
u32 reg;
if (!lock)
return;
WARN_ON(readl_relaxed_poll_timeout(common->base + common->reg, reg,
reg & lock, 100, 70000));
if (common->features & CCU_FEATURE_LOCK_REG)
addr = common->base + common->lock_reg;
else
addr = common->base + common->reg;
WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000));
}
int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
......
......@@ -21,6 +21,8 @@
#define CCU_FEATURE_VARIABLE_PREDIV BIT(1)
#define CCU_FEATURE_FIXED_PREDIV BIT(2)
#define CCU_FEATURE_FIXED_POSTDIV BIT(3)
#define CCU_FEATURE_ALL_PREDIV BIT(4)
#define CCU_FEATURE_LOCK_REG BIT(5)
struct device_node;
......@@ -56,6 +58,8 @@ struct device_node;
struct ccu_common {
void __iomem *base;
u16 reg;
u16 lock_reg;
u32 prediv;
unsigned long features;
spinlock_t *lock;
......
......@@ -77,6 +77,18 @@ static int ccu_div_determine_rate(struct clk_hw *hw,
{
struct ccu_div *cd = hw_to_ccu_div(hw);
if (clk_hw_get_num_parents(hw) == 1) {
req->rate = divider_round_rate(hw, req->rate,
&req->best_parent_rate,
cd->div.table,
cd->div.width,
cd->div.flags);
req->best_parent_hw = clk_hw_get_parent(hw);
return 0;
}
return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
req, ccu_div_round_rate, cd);
}
......
......@@ -41,6 +41,7 @@ struct ccu_div_internal {
u8 width;
u32 max;
u32 offset;
u32 flags;
......@@ -58,20 +59,27 @@ struct ccu_div_internal {
#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
_SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
#define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
{ \
.shift = _shift, \
.width = _width, \
.flags = _flags, \
.max = _max, \
.offset = _off, \
}
#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
_SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
#define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset) \
_SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
#define _SUNXI_CCU_DIV(_shift, _width) \
_SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
......
......@@ -89,11 +89,14 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
m = reg >> cmp->m.shift;
m &= (1 << cmp->m.width) - 1;
m += cmp->m.offset;
if (!m)
m++;
p = reg >> cmp->p.shift;
p &= (1 << cmp->p.width) - 1;
return (parent_rate >> p) / (m + 1);
return (parent_rate >> p) / m;
}
static int ccu_mp_determine_rate(struct clk_hw *hw,
......@@ -124,9 +127,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
reg = readl(cmp->common.base + cmp->common.reg);
reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
reg |= (m - cmp->m.offset) << cmp->m.shift;
reg |= ilog2(p) << cmp->p.shift;
writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift),
cmp->common.base + cmp->common.reg);
writel(reg, cmp->common.base + cmp->common.reg);
spin_unlock_irqrestore(cmp->common.lock, flags);
......
......@@ -40,8 +40,13 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
struct ccu_mult *cm = data;
struct _ccu_mult _cm;
_cm.min = 1;
_cm.max = 1 << cm->mult.width;
_cm.min = cm->mult.min;
if (cm->mult.max)
_cm.max = cm->mult.max;
else
_cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
ccu_mult_find_best(parent_rate, rate, &_cm);
return parent_rate * _cm.mult;
......@@ -75,6 +80,9 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
unsigned long val;
u32 reg;
if (ccu_frac_helper_is_enabled(&cm->common, &cm->frac))
return ccu_frac_helper_read_rate(&cm->common, &cm->frac);
reg = readl(cm->common.base + cm->common.reg);
val = reg >> cm->mult.shift;
val &= (1 << cm->mult.width) - 1;
......@@ -82,7 +90,7 @@ static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
&parent_rate);
return parent_rate * (val + 1);
return parent_rate * (val + cm->mult.offset);
}
static int ccu_mult_determine_rate(struct clk_hw *hw,
......@@ -102,20 +110,30 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long flags;
u32 reg;
if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate))
return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate);
else
ccu_frac_helper_disable(&cm->common, &cm->frac);
ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
&parent_rate);
_cm.min = cm->mult.min;
_cm.max = 1 << cm->mult.width;
if (cm->mult.max)
_cm.max = cm->mult.max;
else
_cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
ccu_mult_find_best(parent_rate, rate, &_cm);
spin_lock_irqsave(cm->common.lock, flags);
reg = readl(cm->common.base + cm->common.reg);
reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
reg |= ((_cm.mult - cm->mult.offset) << cm->mult.shift);
writel(reg | ((_cm.mult - 1) << cm->mult.shift),
cm->common.base + cm->common.reg);
writel(reg, cm->common.base + cm->common.reg);
spin_unlock_irqrestore(cm->common.lock, flags);
......
......@@ -2,27 +2,39 @@
#define _CCU_MULT_H_
#include "ccu_common.h"
#include "ccu_frac.h"
#include "ccu_mux.h"
struct ccu_mult_internal {
u8 offset;
u8 shift;
u8 width;
u8 min;
u8 max;
};
#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \
{ \
.shift = _shift, \
.width = _width, \
.min = _min, \
#define _SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, _min, _max) \
{ \
.min = _min, \
.max = _max, \
.offset = _offset, \
.shift = _shift, \
.width = _width, \
}
#define _SUNXI_CCU_MULT_MIN(_shift, _width, _min) \
_SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, _min, 0)
#define _SUNXI_CCU_MULT_OFFSET(_shift, _width, _offset) \
_SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, _offset, 1, 0)
#define _SUNXI_CCU_MULT(_shift, _width) \
_SUNXI_CCU_MULT_MIN(_shift, _width, 1)
_SUNXI_CCU_MULT_OFFSET_MIN_MAX(_shift, _width, 1, 1, 0)
struct ccu_mult {
u32 enable;
struct ccu_frac_internal frac;
struct ccu_mult_internal mult;
struct ccu_mux_internal mux;
struct ccu_common common;
......
......@@ -25,9 +25,15 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
int i;
if (!((common->features & CCU_FEATURE_FIXED_PREDIV) ||
(common->features & CCU_FEATURE_VARIABLE_PREDIV)))
(common->features & CCU_FEATURE_VARIABLE_PREDIV) ||
(common->features & CCU_FEATURE_ALL_PREDIV)))
return;
if (common->features & CCU_FEATURE_ALL_PREDIV) {
*parent_rate = *parent_rate / common->prediv;
return;
}
reg = readl(common->base + common->reg);
if (parent_index < 0) {
parent_index = reg >> cm->shift;
......@@ -64,19 +70,46 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
struct clk_hw *best_parent, *hw = &common->hw;
unsigned int i;
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
unsigned long adj_parent_rate;
best_parent = clk_hw_get_parent(hw);
best_parent_rate = clk_hw_get_rate(best_parent);
adj_parent_rate = best_parent_rate;
ccu_mux_helper_adjust_parent_for_prediv(common, cm, -1,
&adj_parent_rate);
best_rate = round(cm, adj_parent_rate, req->rate, data);
goto out;
}
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
unsigned long tmp_rate, parent_rate;
unsigned long tmp_rate, parent_rate, adj_parent_rate;
struct clk_hw *parent;
parent = clk_hw_get_parent_by_index(hw, i);
if (!parent)
continue;
parent_rate = clk_hw_get_rate(parent);
if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
struct clk_rate_request parent_req = *req;
int ret = __clk_determine_rate(parent, &parent_req);
if (ret)
continue;
parent_rate = parent_req.rate;
} else {
parent_rate = clk_hw_get_rate(parent);
}
adj_parent_rate = parent_rate;
ccu_mux_helper_adjust_parent_for_prediv(common, cm, i,
&parent_rate);
&adj_parent_rate);
tmp_rate = round(cm, clk_hw_get_rate(parent), req->rate, data);
tmp_rate = round(cm, adj_parent_rate, req->rate, data);
if (tmp_rate == req->rate) {
best_parent = parent;
best_parent_rate = parent_rate;
......
......@@ -76,12 +76,17 @@ static unsigned long ccu_nk_recalc_rate(struct clk_hw *hw,
n = reg >> nk->n.shift;
n &= (1 << nk->n.width) - 1;
n += nk->n.offset;
if (!n)
n++;
k = reg >> nk->k.shift;
k &= (1 << nk->k.width) - 1;
k += nk->k.offset;
if (!k)
k++;
rate = parent_rate * (n + 1) * (k + 1);
rate = parent_rate * n * k;
if (nk->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nk->fixed_post_div;
......@@ -98,9 +103,9 @@ static long ccu_nk_round_rate(struct clk_hw *hw, unsigned long rate,
rate *= nk->fixed_post_div;
_nk.min_n = nk->n.min;
_nk.max_n = 1 << nk->n.width;
_nk.max_n = nk->n.max ?: 1 << nk->n.width;
_nk.min_k = nk->k.min;
_nk.max_k = 1 << nk->k.width;
_nk.max_k = nk->k.max ?: 1 << nk->k.width;
ccu_nk_find_best(*parent_rate, rate, &_nk);
rate = *parent_rate * _nk.n * _nk.k;
......@@ -123,9 +128,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
rate = rate * nk->fixed_post_div;
_nk.min_n = nk->n.min;
_nk.max_n = 1 << nk->n.width;
_nk.max_n = nk->n.max ?: 1 << nk->n.width;
_nk.min_k = nk->k.min;
_nk.max_k = 1 << nk->k.width;
_nk.max_k = nk->k.max ?: 1 << nk->k.width;
ccu_nk_find_best(parent_rate, rate, &_nk);
......@@ -135,8 +140,9 @@ static int ccu_nk_set_rate(struct clk_hw *hw, unsigned long rate,
reg &= ~GENMASK(nk->n.width + nk->n.shift - 1, nk->n.shift);
reg &= ~GENMASK(nk->k.width + nk->k.shift - 1, nk->k.shift);
writel(reg | ((_nk.k - 1) << nk->k.shift) | ((_nk.n - 1) << nk->n.shift),
nk->common.base + nk->common.reg);
reg |= (_nk.k - nk->k.offset) << nk->k.shift;
reg |= (_nk.n - nk->n.offset) << nk->n.shift;
writel(reg, nk->common.base + nk->common.reg);
spin_unlock_irqrestore(nk->common.lock, flags);
......
......@@ -82,14 +82,23 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
n = reg >> nkm->n.shift;
n &= (1 << nkm->n.width) - 1;
n += nkm->n.offset;
if (!n)
n++;
k = reg >> nkm->k.shift;
k &= (1 << nkm->k.width) - 1;
k += nkm->k.offset;
if (!k)
k++;
m = reg >> nkm->m.shift;
m &= (1 << nkm->m.width) - 1;
m += nkm->m.offset;
if (!m)
m++;
return parent_rate * (n + 1) * (k + 1) / (m + 1);
return parent_rate * n * k / m;
}
static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
......@@ -101,9 +110,9 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
struct _ccu_nkm _nkm;
_nkm.min_n = nkm->n.min;
_nkm.max_n = 1 << nkm->n.width;
_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
_nkm.min_k = nkm->k.min;
_nkm.max_k = 1 << nkm->k.width;
_nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
_nkm.min_m = 1;
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
......@@ -130,9 +139,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
u32 reg;
_nkm.min_n = nkm->n.min;
_nkm.max_n = 1 << nkm->n.width;
_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
_nkm.min_k = nkm->k.min;
_nkm.max_k = 1 << nkm->k.width;
_nkm.max_k = nkm->k.max ?: 1 << nkm->k.width;
_nkm.min_m = 1;
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
......@@ -145,10 +154,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
reg &= ~GENMASK(nkm->k.width + nkm->k.shift - 1, nkm->k.shift);
reg &= ~GENMASK(nkm->m.width + nkm->m.shift - 1, nkm->m.shift);
reg |= (_nkm.n - 1) << nkm->n.shift;
reg |= (_nkm.k - 1) << nkm->k.shift;
reg |= (_nkm.m - 1) << nkm->m.shift;
reg |= (_nkm.n - nkm->n.offset) << nkm->n.shift;
reg |= (_nkm.k - nkm->k.offset) << nkm->k.shift;
reg |= (_nkm.m - nkm->m.offset) << nkm->m.shift;
writel(reg, nkm->common.base + nkm->common.reg);
spin_unlock_irqrestore(nkm->common.lock, flags);
......
......@@ -88,17 +88,26 @@ static unsigned long ccu_nkmp_recalc_rate(struct clk_hw *hw,
n = reg >> nkmp->n.shift;
n &= (1 << nkmp->n.width) - 1;
n += nkmp->n.offset;
if (!n)
n++;
k = reg >> nkmp->k.shift;
k &= (1 << nkmp->k.width) - 1;
k += nkmp->k.offset;
if (!k)
k++;
m = reg >> nkmp->m.shift;
m &= (1 << nkmp->m.width) - 1;
m += nkmp->m.offset;
if (!m)
m++;
p = reg >> nkmp->p.shift;
p &= (1 << nkmp->p.width) - 1;
return (parent_rate * (n + 1) * (k + 1) >> p) / (m + 1);
return parent_rate * n * k >> p / m;
}
static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
......@@ -108,9 +117,9 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
struct _ccu_nkmp _nkmp;
_nkmp.min_n = nkmp->n.min;
_nkmp.max_n = 1 << nkmp->n.width;
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
_nkmp.min_k = nkmp->k.min;
_nkmp.max_k = 1 << nkmp->k.width;
_nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
_nkmp.min_m = 1;
_nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
_nkmp.min_p = 1;
......@@ -130,9 +139,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
u32 reg;
_nkmp.min_n = 1;
_nkmp.max_n = 1 << nkmp->n.width;
_nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width;
_nkmp.min_k = 1;
_nkmp.max_k = 1 << nkmp->k.width;
_nkmp.max_k = nkmp->k.max ?: 1 << nkmp->k.width;
_nkmp.min_m = 1;
_nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
_nkmp.min_p = 1;
......@@ -148,9 +157,9 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
reg &= ~GENMASK(nkmp->m.width + nkmp->m.shift - 1, nkmp->m.shift);
reg &= ~GENMASK(nkmp->p.width + nkmp->p.shift - 1, nkmp->p.shift);
reg |= (_nkmp.n - 1) << nkmp->n.shift;
reg |= (_nkmp.k - 1) << nkmp->k.shift;
reg |= (_nkmp.m - 1) << nkmp->m.shift;
reg |= (_nkmp.n - nkmp->n.offset) << nkmp->n.shift;
reg |= (_nkmp.k - nkmp->k.offset) << nkmp->k.shift;
reg |= (_nkmp.m - nkmp->m.offset) << nkmp->m.shift;
reg |= ilog2(_nkmp.p) << nkmp->p.shift;
writel(reg, nkmp->common.base + nkmp->common.reg);
......
......@@ -80,11 +80,17 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
n = reg >> nm->n.shift;
n &= (1 << nm->n.width) - 1;
n += nm->n.offset;
if (!n)
n++;
m = reg >> nm->m.shift;
m &= (1 << nm->m.width) - 1;
m += nm->m.offset;
if (!m)
m++;
return parent_rate * (n + 1) / (m + 1);
return parent_rate * n / m;
}
static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
......@@ -94,7 +100,7 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
struct _ccu_nm _nm;
_nm.min_n = nm->n.min;
_nm.max_n = 1 << nm->n.width;
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
_nm.min_m = 1;
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
......@@ -117,7 +123,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
ccu_frac_helper_disable(&nm->common, &nm->frac);
_nm.min_n = 1;
_nm.max_n = 1 << nm->n.width;
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
_nm.min_m = 1;
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
......@@ -129,8 +135,9 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
reg &= ~GENMASK(nm->n.width + nm->n.shift - 1, nm->n.shift);
reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
writel(reg | ((_nm.m - 1) << nm->m.shift) | ((_nm.n - 1) << nm->n.shift),
nm->common.base + nm->common.reg);
reg |= (_nm.n - nm->n.offset) << nm->n.shift;
reg |= (_nm.m - nm->m.offset) << nm->m.shift;
writel(reg, nm->common.base + nm->common.reg);
spin_unlock_irqrestore(nm->common.lock, flags);
......
/*
* 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 _DT_BINDINGS_CLK_SUN5I_H_
#define _DT_BINDINGS_CLK_SUN5I_H_
#define CLK_HOSC 1
#define CLK_CPU 17
#define CLK_AHB_OTG 23
#define CLK_AHB_EHCI 24
#define CLK_AHB_OHCI 25
#define CLK_AHB_SS 26
#define CLK_AHB_DMA 27
#define CLK_AHB_BIST 28
#define CLK_AHB_MMC0 29
#define CLK_AHB_MMC1 30
#define CLK_AHB_MMC2 31
#define CLK_AHB_NAND 32
#define CLK_AHB_SDRAM 33
#define CLK_AHB_EMAC 34
#define CLK_AHB_TS 35
#define CLK_AHB_SPI0 36
#define CLK_AHB_SPI1 37
#define CLK_AHB_SPI2 38
#define CLK_AHB_GPS 39
#define CLK_AHB_HSTIMER 40
#define CLK_AHB_VE 41
#define CLK_AHB_TVE 42
#define CLK_AHB_LCD 43
#define CLK_AHB_CSI 44
#define CLK_AHB_HDMI 45
#define CLK_AHB_DE_BE 46
#define CLK_AHB_DE_FE 47
#define CLK_AHB_IEP 48
#define CLK_AHB_GPU 49
#define CLK_APB0_CODEC 50
#define CLK_APB0_SPDIF 51
#define CLK_APB0_I2S 52
#define CLK_APB0_PIO 53
#define CLK_APB0_IR 54
#define CLK_APB0_KEYPAD 55
#define CLK_APB1_I2C0 56
#define CLK_APB1_I2C1 57
#define CLK_APB1_I2C2 58
#define CLK_APB1_UART0 59
#define CLK_APB1_UART1 60
#define CLK_APB1_UART2 61
#define CLK_APB1_UART3 62
#define CLK_NAND 63
#define CLK_MMC0 64
#define CLK_MMC1 65
#define CLK_MMC2 66
#define CLK_TS 67
#define CLK_SS 68
#define CLK_SPI0 69
#define CLK_SPI1 70
#define CLK_SPI2 71
#define CLK_IR 72
#define CLK_I2S 73
#define CLK_SPDIF 74
#define CLK_KEYPAD 75
#define CLK_USB_OHCI 76
#define CLK_USB_PHY0 77
#define CLK_USB_PHY1 78
#define CLK_GPS 79
#define CLK_DRAM_VE 80
#define CLK_DRAM_CSI 81
#define CLK_DRAM_TS 82
#define CLK_DRAM_TVE 83
#define CLK_DRAM_DE_FE 84
#define CLK_DRAM_DE_BE 85
#define CLK_DRAM_ACE 86
#define CLK_DRAM_IEP 87
#define CLK_DE_BE 88
#define CLK_DE_FE 89
#define CLK_TCON_CH0 90
#define CLK_TCON_CH1 92
#define CLK_CSI 93
#define CLK_VE 94
#define CLK_CODEC 95
#define CLK_AVS 96
#define CLK_HDMI 97
#define CLK_GPU 98
#define CLK_IEP 100
#endif /* _DT_BINDINGS_CLK_SUN5I_H_ */
/*
* Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz>
*
* Based on sun8i-h3-ccu.h, which is:
* Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_CLK_SUN8I_V3S_H_
#define _DT_BINDINGS_CLK_SUN8I_V3S_H_
#define CLK_CPU 14
#define CLK_BUS_CE 20
#define CLK_BUS_DMA 21
#define CLK_BUS_MMC0 22
#define CLK_BUS_MMC1 23
#define CLK_BUS_MMC2 24
#define CLK_BUS_DRAM 25
#define CLK_BUS_EMAC 26
#define CLK_BUS_HSTIMER 27
#define CLK_BUS_SPI0 28
#define CLK_BUS_OTG 29
#define CLK_BUS_EHCI0 30
#define CLK_BUS_OHCI0 31
#define CLK_BUS_VE 32
#define CLK_BUS_TCON0 33
#define CLK_BUS_CSI 34
#define CLK_BUS_DE 35
#define CLK_BUS_CODEC 36
#define CLK_BUS_PIO 37
#define CLK_BUS_I2C0 38
#define CLK_BUS_I2C1 39
#define CLK_BUS_UART0 40
#define CLK_BUS_UART1 41
#define CLK_BUS_UART2 42
#define CLK_BUS_EPHY 43
#define CLK_BUS_DBG 44
#define CLK_MMC0 45
#define CLK_MMC0_SAMPLE 46
#define CLK_MMC0_OUTPUT 47
#define CLK_MMC1 48
#define CLK_MMC1_SAMPLE 49
#define CLK_MMC1_OUTPUT 50
#define CLK_MMC2 51
#define CLK_MMC2_SAMPLE 52
#define CLK_MMC2_OUTPUT 53
#define CLK_CE 54
#define CLK_SPI0 55
#define CLK_USB_PHY0 56
#define CLK_USB_OHCI0 57
#define CLK_DRAM_VE 59
#define CLK_DRAM_CSI 60
#define CLK_DRAM_EHCI 61
#define CLK_DRAM_OHCI 62
#define CLK_DE 63
#define CLK_TCON0 64
#define CLK_CSI_MISC 65
#define CLK_CSI0_MCLK 66
#define CLK_CSI1_SCLK 67
#define CLK_CSI1_MCLK 68
#define CLK_VE 69
#define CLK_AC_DIG 70
#define CLK_AVS 71
#define CLK_MIPI_CSI 73
#endif /* _DT_BINDINGS_CLK_SUN8I_V3S_H_ */
/*
* Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_
#define _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_
#define CLK_PLL_AUDIO 2
#define CLK_PLL_PERIPH0 3
#define CLK_C0CPUX 12
#define CLK_C1CPUX 13
#define CLK_OUT_A 27
#define CLK_OUT_B 28
#define CLK_NAND0_0 29
#define CLK_NAND0_1 30
#define CLK_NAND1_0 31
#define CLK_NAND1_1 32
#define CLK_MMC0 33
#define CLK_MMC0_SAMPLE 34
#define CLK_MMC0_OUTPUT 35
#define CLK_MMC1 36
#define CLK_MMC1_SAMPLE 37
#define CLK_MMC1_OUTPUT 38
#define CLK_MMC2 39
#define CLK_MMC2_SAMPLE 40
#define CLK_MMC2_OUTPUT 41
#define CLK_MMC3 42
#define CLK_MMC3_SAMPLE 43
#define CLK_MMC3_OUTPUT 44
#define CLK_TS 45
#define CLK_SS 46
#define CLK_SPI0 47
#define CLK_SPI1 48
#define CLK_SPI2 49
#define CLK_SPI3 50
#define CLK_I2S0 51
#define CLK_I2S1 52
#define CLK_SPDIF 53
#define CLK_SDRAM 54
#define CLK_DE 55
#define CLK_EDP 56
#define CLK_MP 57
#define CLK_LCD0 58
#define CLK_LCD1 59
#define CLK_MIPI_DSI0 60
#define CLK_MIPI_DSI1 61
#define CLK_HDMI 62
#define CLK_HDMI_SLOW 63
#define CLK_MIPI_CSI 64
#define CLK_CSI_ISP 65
#define CLK_CSI_MISC 66
#define CLK_CSI0_MCLK 67
#define CLK_CSI1_MCLK 68
#define CLK_FD 69
#define CLK_VE 70
#define CLK_AVS 71
#define CLK_GPU_CORE 72
#define CLK_GPU_MEMORY 73
#define CLK_GPU_AXI 74
#define CLK_SATA 75
#define CLK_AC97 76
#define CLK_MIPI_HSI 77
#define CLK_GPADC 78
#define CLK_CIR_TX 79
#define CLK_BUS_FD 80
#define CLK_BUS_VE 81
#define CLK_BUS_GPU_CTRL 82
#define CLK_BUS_SS 83
#define CLK_BUS_MMC 84
#define CLK_BUS_NAND0 85
#define CLK_BUS_NAND1 86
#define CLK_BUS_SDRAM 87
#define CLK_BUS_MIPI_HSI 88
#define CLK_BUS_SATA 89
#define CLK_BUS_TS 90
#define CLK_BUS_SPI0 91
#define CLK_BUS_SPI1 92
#define CLK_BUS_SPI2 93
#define CLK_BUS_SPI3 94
#define CLK_BUS_OTG 95
#define CLK_BUS_USB 96
#define CLK_BUS_GMAC 97
#define CLK_BUS_MSGBOX 98
#define CLK_BUS_SPINLOCK 99
#define CLK_BUS_HSTIMER 100
#define CLK_BUS_DMA 101
#define CLK_BUS_LCD0 102
#define CLK_BUS_LCD1 103
#define CLK_BUS_EDP 104
#define CLK_BUS_CSI 105
#define CLK_BUS_HDMI 106
#define CLK_BUS_DE 107
#define CLK_BUS_MP 108
#define CLK_BUS_MIPI_DSI 109
#define CLK_BUS_SPDIF 110
#define CLK_BUS_PIO 111
#define CLK_BUS_AC97 112
#define CLK_BUS_I2S0 113
#define CLK_BUS_I2S1 114
#define CLK_BUS_LRADC 115
#define CLK_BUS_GPADC 116
#define CLK_BUS_TWD 117
#define CLK_BUS_CIR_TX 118
#define CLK_BUS_I2C0 119
#define CLK_BUS_I2C1 120
#define CLK_BUS_I2C2 121
#define CLK_BUS_I2C3 122
#define CLK_BUS_I2C4 123
#define CLK_BUS_UART0 124
#define CLK_BUS_UART1 125
#define CLK_BUS_UART2 126
#define CLK_BUS_UART3 127
#define CLK_BUS_UART4 128
#define CLK_BUS_UART5 129
#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_CCU_H_ */
/*
* Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_
#define _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_
#define CLK_FE0 0
#define CLK_FE1 1
#define CLK_FE2 2
#define CLK_IEP_DEU0 3
#define CLK_IEP_DEU1 4
#define CLK_BE0 5
#define CLK_BE1 6
#define CLK_BE2 7
#define CLK_IEP_DRC0 8
#define CLK_IEP_DRC1 9
#define CLK_MERGE 10
#define CLK_DRAM_FE0 11
#define CLK_DRAM_FE1 12
#define CLK_DRAM_FE2 13
#define CLK_DRAM_DEU0 14
#define CLK_DRAM_DEU1 15
#define CLK_DRAM_BE0 16
#define CLK_DRAM_BE1 17
#define CLK_DRAM_BE2 18
#define CLK_DRAM_DRC0 19
#define CLK_DRAM_DRC1 20
#define CLK_BUS_FE0 21
#define CLK_BUS_FE1 22
#define CLK_BUS_FE2 23
#define CLK_BUS_DEU0 24
#define CLK_BUS_DEU1 25
#define CLK_BUS_BE0 26
#define CLK_BUS_BE1 27
#define CLK_BUS_BE2 28
#define CLK_BUS_DRC0 29
#define CLK_BUS_DRC1 30
#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_DE_H_ */
/*
* Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_
#define _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_
#define CLK_BUS_HCI0 0
#define CLK_USB_OHCI0 1
#define CLK_BUS_HCI1 2
#define CLK_BUS_HCI2 3
#define CLK_USB_OHCI2 4
#define CLK_USB0_PHY 5
#define CLK_USB1_HSIC 6
#define CLK_USB1_PHY 7
#define CLK_USB2_HSIC 8
#define CLK_USB2_PHY 9
#define CLK_USB_HSIC 10
#endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_ */
/*
* 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 _RST_SUN5I_H_
#define _RST_SUN5I_H_
#define RST_USB_PHY0 0
#define RST_USB_PHY1 1
#define RST_GPS 2
#define RST_DE_BE 3
#define RST_DE_FE 4
#define RST_TVE 5
#define RST_LCD 6
#define RST_CSI 7
#define RST_VE 8
#define RST_GPU 9
#define RST_IEP 10
#endif /* _RST_SUN5I_H_ */
/*
* Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
*
* Based on sun8i-v3s-ccu.h, which is
* Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_RST_SUN8I_V3S_H_
#define _DT_BINDINGS_RST_SUN8I_V3S_H_
#define RST_USB_PHY0 0
#define RST_MBUS 1
#define RST_BUS_CE 5
#define RST_BUS_DMA 6
#define RST_BUS_MMC0 7
#define RST_BUS_MMC1 8
#define RST_BUS_MMC2 9
#define RST_BUS_DRAM 11
#define RST_BUS_EMAC 12
#define RST_BUS_HSTIMER 14
#define RST_BUS_SPI0 15
#define RST_BUS_OTG 17
#define RST_BUS_EHCI0 18
#define RST_BUS_OHCI0 22
#define RST_BUS_VE 26
#define RST_BUS_TCON0 27
#define RST_BUS_CSI 30
#define RST_BUS_DE 34
#define RST_BUS_DBG 38
#define RST_BUS_EPHY 39
#define RST_BUS_CODEC 40
#define RST_BUS_I2C0 46
#define RST_BUS_I2C1 47
#define RST_BUS_UART0 49
#define RST_BUS_UART1 50
#define RST_BUS_UART2 51
#endif /* _DT_BINDINGS_RST_SUN8I_H3_H_ */
/*
* Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_
#define _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_
#define RST_BUS_FD 0
#define RST_BUS_VE 1
#define RST_BUS_GPU_CTRL 2
#define RST_BUS_SS 3
#define RST_BUS_MMC 4
#define RST_BUS_NAND0 5
#define RST_BUS_NAND1 6
#define RST_BUS_SDRAM 7
#define RST_BUS_SATA 8
#define RST_BUS_TS 9
#define RST_BUS_SPI0 10
#define RST_BUS_SPI1 11
#define RST_BUS_SPI2 12
#define RST_BUS_SPI3 13
#define RST_BUS_OTG 14
#define RST_BUS_OTG_PHY 15
#define RST_BUS_MIPI_HSI 16
#define RST_BUS_GMAC 17
#define RST_BUS_MSGBOX 18
#define RST_BUS_SPINLOCK 19
#define RST_BUS_HSTIMER 20
#define RST_BUS_DMA 21
#define RST_BUS_LCD0 22
#define RST_BUS_LCD1 23
#define RST_BUS_EDP 24
#define RST_BUS_LVDS 25
#define RST_BUS_CSI 26
#define RST_BUS_HDMI0 27
#define RST_BUS_HDMI1 28
#define RST_BUS_DE 29
#define RST_BUS_MP 30
#define RST_BUS_GPU 31
#define RST_BUS_MIPI_DSI 32
#define RST_BUS_SPDIF 33
#define RST_BUS_AC97 34
#define RST_BUS_I2S0 35
#define RST_BUS_I2S1 36
#define RST_BUS_LRADC 37
#define RST_BUS_GPADC 38
#define RST_BUS_CIR_TX 39
#define RST_BUS_I2C0 40
#define RST_BUS_I2C1 41
#define RST_BUS_I2C2 42
#define RST_BUS_I2C3 43
#define RST_BUS_I2C4 44
#define RST_BUS_UART0 45
#define RST_BUS_UART1 46
#define RST_BUS_UART2 47
#define RST_BUS_UART3 48
#define RST_BUS_UART4 49
#define RST_BUS_UART5 50
#endif /* _DT_BINDINGS_RESET_SUN9I_A80_CCU_H_ */
/*
* Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_RESET_SUN9I_A80_DE_H_
#define _DT_BINDINGS_RESET_SUN9I_A80_DE_H_
#define RST_FE0 0
#define RST_FE1 1
#define RST_FE2 2
#define RST_DEU0 3
#define RST_DEU1 4
#define RST_BE0 5
#define RST_BE1 6
#define RST_BE2 7
#define RST_DRC0 8
#define RST_DRC1 9
#define RST_MERGE 10
#endif /* _DT_BINDINGS_RESET_SUN9I_A80_DE_H_ */
/*
* Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DT_BINDINGS_RESET_SUN9I_A80_USB_H_
#define _DT_BINDINGS_RESET_SUN9I_A80_USB_H_
#define RST_USB0_HCI 0
#define RST_USB1_HCI 1
#define RST_USB2_HCI 2
#define RST_USB0_PHY 3
#define RST_USB1_HSIC 4
#define RST_USB1_PHY 5
#define RST_USB2_HSIC 6
#define RST_USB2_PHY 7
#endif /* _DT_BINDINGS_RESET_SUN9I_A80_USB_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment