diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2017-04-19 12:02:00 -0400 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2017-04-19 12:02:00 -0400 |
commit | 8062b4aafc67376fb55c0438f26410d0563459ec (patch) | |
tree | bceac42287e7cd3c26bef2e16abfc184d5ac45a2 /drivers/clk | |
parent | e609f9f23e57f6af1c8f0b5759a87f9db3521eb1 (diff) | |
parent | cb545960dea2749771c88b0cb26e5adfd12a0315 (diff) |
Merge tag 'sunxi-clk-for-4.12' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-next
Pull Allwinner clock patches for 4.12 from Maxime Ripard:
Support for the new H5 SoC and the PRCM block found in a number of SoCs as
well, plus the usual chunk of fixes and minor enhancements.
* tag 'sunxi-clk-for-4.12' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux:
clk: sunxi-ng: Display index when clock registration fails
clk: sunxi-ng: a33: Add offset and minimum value for DDR1 PLL N factor
clk: sunxi-ng: a80: Remodel CPU cluster PLLs as N-type multiplier clocks
clk: sunxi-ng: mult: Support PLL lock detection
clk: sunxi-ng: add support for PRCM CCUs
dt-bindings: update device tree binding for Allwinner PRCM CCUs
clk: sunxi-ng: sun5i: Fix mux width for csi clock
clk: sunxi-ng: tighten SoC deps on explicit AllWinner SoCs
clk: sunxi-ng: add Allwinner H5 CCU support for H3 CCU driver
clk: sunxi-ng: gate: Support common pre-dividers
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/sunxi-ng/Kconfig | 16 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun5i.c | 2 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 18 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 327 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-h3.h | 3 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-r.c | 213 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-r.h | 27 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 70 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu_common.c | 4 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu_gate.c | 47 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu_mult.c | 2 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu_mult.h | 2 |
13 files changed, 695 insertions, 37 deletions
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 1c2357301017..64088e599404 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig | |||
@@ -64,6 +64,7 @@ config SUN50I_A64_CCU | |||
64 | select SUNXI_CCU_MP | 64 | select SUNXI_CCU_MP |
65 | select SUNXI_CCU_PHASE | 65 | select SUNXI_CCU_PHASE |
66 | default ARM64 && ARCH_SUNXI | 66 | default ARM64 && ARCH_SUNXI |
67 | depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST | ||
67 | 68 | ||
68 | config SUN5I_CCU | 69 | config SUN5I_CCU |
69 | bool "Support for the Allwinner sun5i family CCM" | 70 | bool "Support for the Allwinner sun5i family CCM" |
@@ -75,6 +76,7 @@ config SUN5I_CCU | |||
75 | select SUNXI_CCU_MP | 76 | select SUNXI_CCU_MP |
76 | select SUNXI_CCU_PHASE | 77 | select SUNXI_CCU_PHASE |
77 | default MACH_SUN5I | 78 | default MACH_SUN5I |
79 | depends on MACH_SUN5I || COMPILE_TEST | ||
78 | 80 | ||
79 | config SUN6I_A31_CCU | 81 | config SUN6I_A31_CCU |
80 | bool "Support for the Allwinner A31/A31s CCU" | 82 | bool "Support for the Allwinner A31/A31s CCU" |
@@ -86,6 +88,7 @@ config SUN6I_A31_CCU | |||
86 | select SUNXI_CCU_MP | 88 | select SUNXI_CCU_MP |
87 | select SUNXI_CCU_PHASE | 89 | select SUNXI_CCU_PHASE |
88 | default MACH_SUN6I | 90 | default MACH_SUN6I |
91 | depends on MACH_SUN6I || COMPILE_TEST | ||
89 | 92 | ||
90 | config SUN8I_A23_CCU | 93 | config SUN8I_A23_CCU |
91 | bool "Support for the Allwinner A23 CCU" | 94 | bool "Support for the Allwinner A23 CCU" |
@@ -98,6 +101,7 @@ config SUN8I_A23_CCU | |||
98 | select SUNXI_CCU_MP | 101 | select SUNXI_CCU_MP |
99 | select SUNXI_CCU_PHASE | 102 | select SUNXI_CCU_PHASE |
100 | default MACH_SUN8I | 103 | default MACH_SUN8I |
104 | depends on MACH_SUN8I || COMPILE_TEST | ||
101 | 105 | ||
102 | config SUN8I_A33_CCU | 106 | config SUN8I_A33_CCU |
103 | bool "Support for the Allwinner A33 CCU" | 107 | bool "Support for the Allwinner A33 CCU" |
@@ -110,6 +114,7 @@ config SUN8I_A33_CCU | |||
110 | select SUNXI_CCU_MP | 114 | select SUNXI_CCU_MP |
111 | select SUNXI_CCU_PHASE | 115 | select SUNXI_CCU_PHASE |
112 | default MACH_SUN8I | 116 | default MACH_SUN8I |
117 | depends on MACH_SUN8I || COMPILE_TEST | ||
113 | 118 | ||
114 | config SUN8I_H3_CCU | 119 | config SUN8I_H3_CCU |
115 | bool "Support for the Allwinner H3 CCU" | 120 | bool "Support for the Allwinner H3 CCU" |
@@ -120,7 +125,8 @@ config SUN8I_H3_CCU | |||
120 | select SUNXI_CCU_NM | 125 | select SUNXI_CCU_NM |
121 | select SUNXI_CCU_MP | 126 | select SUNXI_CCU_MP |
122 | select SUNXI_CCU_PHASE | 127 | select SUNXI_CCU_PHASE |
123 | default MACH_SUN8I | 128 | default MACH_SUN8I || (ARM64 && ARCH_SUNXI) |
129 | depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST | ||
124 | 130 | ||
125 | config SUN8I_V3S_CCU | 131 | config SUN8I_V3S_CCU |
126 | bool "Support for the Allwinner V3s CCU" | 132 | bool "Support for the Allwinner V3s CCU" |
@@ -132,6 +138,7 @@ config SUN8I_V3S_CCU | |||
132 | select SUNXI_CCU_MP | 138 | select SUNXI_CCU_MP |
133 | select SUNXI_CCU_PHASE | 139 | select SUNXI_CCU_PHASE |
134 | default MACH_SUN8I | 140 | default MACH_SUN8I |
141 | depends on MACH_SUN8I || COMPILE_TEST | ||
135 | 142 | ||
136 | config SUN9I_A80_CCU | 143 | config SUN9I_A80_CCU |
137 | bool "Support for the Allwinner A80 CCU" | 144 | bool "Support for the Allwinner A80 CCU" |
@@ -143,5 +150,12 @@ config SUN9I_A80_CCU | |||
143 | select SUNXI_CCU_MP | 150 | select SUNXI_CCU_MP |
144 | select SUNXI_CCU_PHASE | 151 | select SUNXI_CCU_PHASE |
145 | default MACH_SUN9I | 152 | default MACH_SUN9I |
153 | depends on MACH_SUN9I || COMPILE_TEST | ||
154 | |||
155 | config SUN8I_R_CCU | ||
156 | bool "Support for Allwinner SoCs' PRCM CCUs" | ||
157 | select SUNXI_CCU_DIV | ||
158 | select SUNXI_CCU_GATE | ||
159 | default MACH_SUN8I || (ARCH_SUNXI && ARM64) | ||
146 | 160 | ||
147 | endif | 161 | endif |
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 6feaac0c5600..0ec02fe14c50 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o | |||
25 | obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o | 25 | obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o |
26 | obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o | 26 | obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o |
27 | obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o | 27 | obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o |
28 | obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o | ||
28 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o | 29 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o |
29 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o | 30 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o |
30 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o | 31 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o |
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index 06edaa523479..5c476f966a72 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c | |||
@@ -469,7 +469,7 @@ static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1", | |||
469 | static const u8 csi_table[] = { 0, 1, 2, 5, 6 }; | 469 | static const u8 csi_table[] = { 0, 1, 2, 5, 6 }; |
470 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi", | 470 | static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi", |
471 | csi_parents, csi_table, | 471 | csi_parents, csi_table, |
472 | 0x134, 0, 5, 24, 2, BIT(31), 0); | 472 | 0x134, 0, 5, 24, 3, BIT(31), 0); |
473 | 473 | ||
474 | static SUNXI_CCU_GATE(ve_clk, "ve", "pll-ve", | 474 | static SUNXI_CCU_GATE(ve_clk, "ve", "pll-ve", |
475 | 0x13c, BIT(31), CLK_SET_RATE_PARENT); | 475 | 0x13c, BIT(31), CLK_SET_RATE_PARENT); |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 2c69b631967a..8d38e6510e29 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c | |||
@@ -159,13 +159,17 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", | |||
159 | BIT(28), /* lock */ | 159 | BIT(28), /* lock */ |
160 | CLK_SET_RATE_UNGATE); | 160 | CLK_SET_RATE_UNGATE); |
161 | 161 | ||
162 | /* TODO: Fix N */ | 162 | static struct ccu_mult pll_ddr1_clk = { |
163 | static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1", | 163 | .enable = BIT(31), |
164 | "osc24M", 0x04c, | 164 | .lock = BIT(28), |
165 | 8, 6, /* N */ | 165 | .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 6, 0, 12, 0), |
166 | BIT(31), /* gate */ | 166 | .common = { |
167 | BIT(28), /* lock */ | 167 | .reg = 0x04c, |
168 | CLK_SET_RATE_UNGATE); | 168 | .hw.init = CLK_HW_INIT("pll-ddr1", "osc24M", |
169 | &ccu_mult_ops, | ||
170 | CLK_SET_RATE_UNGATE), | ||
171 | }, | ||
172 | }; | ||
169 | 173 | ||
170 | static const char * const cpux_parents[] = { "osc32k", "osc24M", | 174 | static const char * const cpux_parents[] = { "osc32k", "osc24M", |
171 | "pll-cpux" , "pll-cpux" }; | 175 | "pll-cpux" , "pll-cpux" }; |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index a26c8a19fe93..4cbc1b701b7c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c | |||
@@ -300,8 +300,10 @@ static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", | |||
300 | 0x06c, BIT(18), 0); | 300 | 0x06c, BIT(18), 0); |
301 | static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", | 301 | static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", |
302 | 0x06c, BIT(19), 0); | 302 | 0x06c, BIT(19), 0); |
303 | static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", | 303 | static SUNXI_CCU_GATE(bus_scr0_clk, "bus-scr0", "apb2", |
304 | 0x06c, BIT(20), 0); | 304 | 0x06c, BIT(20), 0); |
305 | static SUNXI_CCU_GATE(bus_scr1_clk, "bus-scr1", "apb2", | ||
306 | 0x06c, BIT(21), 0); | ||
305 | 307 | ||
306 | static SUNXI_CCU_GATE(bus_ephy_clk, "bus-ephy", "ahb1", | 308 | static SUNXI_CCU_GATE(bus_ephy_clk, "bus-ephy", "ahb1", |
307 | 0x070, BIT(0), 0); | 309 | 0x070, BIT(0), 0); |
@@ -546,7 +548,7 @@ static struct ccu_common *sun8i_h3_ccu_clks[] = { | |||
546 | &bus_uart1_clk.common, | 548 | &bus_uart1_clk.common, |
547 | &bus_uart2_clk.common, | 549 | &bus_uart2_clk.common, |
548 | &bus_uart3_clk.common, | 550 | &bus_uart3_clk.common, |
549 | &bus_scr_clk.common, | 551 | &bus_scr0_clk.common, |
550 | &bus_ephy_clk.common, | 552 | &bus_ephy_clk.common, |
551 | &bus_dbg_clk.common, | 553 | &bus_dbg_clk.common, |
552 | &ths_clk.common, | 554 | &ths_clk.common, |
@@ -597,6 +599,114 @@ static struct ccu_common *sun8i_h3_ccu_clks[] = { | |||
597 | &gpu_clk.common, | 599 | &gpu_clk.common, |
598 | }; | 600 | }; |
599 | 601 | ||
602 | static struct ccu_common *sun50i_h5_ccu_clks[] = { | ||
603 | &pll_cpux_clk.common, | ||
604 | &pll_audio_base_clk.common, | ||
605 | &pll_video_clk.common, | ||
606 | &pll_ve_clk.common, | ||
607 | &pll_ddr_clk.common, | ||
608 | &pll_periph0_clk.common, | ||
609 | &pll_gpu_clk.common, | ||
610 | &pll_periph1_clk.common, | ||
611 | &pll_de_clk.common, | ||
612 | &cpux_clk.common, | ||
613 | &axi_clk.common, | ||
614 | &ahb1_clk.common, | ||
615 | &apb1_clk.common, | ||
616 | &apb2_clk.common, | ||
617 | &ahb2_clk.common, | ||
618 | &bus_ce_clk.common, | ||
619 | &bus_dma_clk.common, | ||
620 | &bus_mmc0_clk.common, | ||
621 | &bus_mmc1_clk.common, | ||
622 | &bus_mmc2_clk.common, | ||
623 | &bus_nand_clk.common, | ||
624 | &bus_dram_clk.common, | ||
625 | &bus_emac_clk.common, | ||
626 | &bus_ts_clk.common, | ||
627 | &bus_hstimer_clk.common, | ||
628 | &bus_spi0_clk.common, | ||
629 | &bus_spi1_clk.common, | ||
630 | &bus_otg_clk.common, | ||
631 | &bus_ehci0_clk.common, | ||
632 | &bus_ehci1_clk.common, | ||
633 | &bus_ehci2_clk.common, | ||
634 | &bus_ehci3_clk.common, | ||
635 | &bus_ohci0_clk.common, | ||
636 | &bus_ohci1_clk.common, | ||
637 | &bus_ohci2_clk.common, | ||
638 | &bus_ohci3_clk.common, | ||
639 | &bus_ve_clk.common, | ||
640 | &bus_tcon0_clk.common, | ||
641 | &bus_tcon1_clk.common, | ||
642 | &bus_deinterlace_clk.common, | ||
643 | &bus_csi_clk.common, | ||
644 | &bus_tve_clk.common, | ||
645 | &bus_hdmi_clk.common, | ||
646 | &bus_de_clk.common, | ||
647 | &bus_gpu_clk.common, | ||
648 | &bus_msgbox_clk.common, | ||
649 | &bus_spinlock_clk.common, | ||
650 | &bus_codec_clk.common, | ||
651 | &bus_spdif_clk.common, | ||
652 | &bus_pio_clk.common, | ||
653 | &bus_ths_clk.common, | ||
654 | &bus_i2s0_clk.common, | ||
655 | &bus_i2s1_clk.common, | ||
656 | &bus_i2s2_clk.common, | ||
657 | &bus_i2c0_clk.common, | ||
658 | &bus_i2c1_clk.common, | ||
659 | &bus_i2c2_clk.common, | ||
660 | &bus_uart0_clk.common, | ||
661 | &bus_uart1_clk.common, | ||
662 | &bus_uart2_clk.common, | ||
663 | &bus_uart3_clk.common, | ||
664 | &bus_scr0_clk.common, | ||
665 | &bus_scr1_clk.common, | ||
666 | &bus_ephy_clk.common, | ||
667 | &bus_dbg_clk.common, | ||
668 | &ths_clk.common, | ||
669 | &nand_clk.common, | ||
670 | &mmc0_clk.common, | ||
671 | &mmc1_clk.common, | ||
672 | &mmc2_clk.common, | ||
673 | &ts_clk.common, | ||
674 | &ce_clk.common, | ||
675 | &spi0_clk.common, | ||
676 | &spi1_clk.common, | ||
677 | &i2s0_clk.common, | ||
678 | &i2s1_clk.common, | ||
679 | &i2s2_clk.common, | ||
680 | &spdif_clk.common, | ||
681 | &usb_phy0_clk.common, | ||
682 | &usb_phy1_clk.common, | ||
683 | &usb_phy2_clk.common, | ||
684 | &usb_phy3_clk.common, | ||
685 | &usb_ohci0_clk.common, | ||
686 | &usb_ohci1_clk.common, | ||
687 | &usb_ohci2_clk.common, | ||
688 | &usb_ohci3_clk.common, | ||
689 | &dram_clk.common, | ||
690 | &dram_ve_clk.common, | ||
691 | &dram_csi_clk.common, | ||
692 | &dram_deinterlace_clk.common, | ||
693 | &dram_ts_clk.common, | ||
694 | &de_clk.common, | ||
695 | &tcon_clk.common, | ||
696 | &tve_clk.common, | ||
697 | &deinterlace_clk.common, | ||
698 | &csi_misc_clk.common, | ||
699 | &csi_sclk_clk.common, | ||
700 | &csi_mclk_clk.common, | ||
701 | &ve_clk.common, | ||
702 | &ac_dig_clk.common, | ||
703 | &avs_clk.common, | ||
704 | &hdmi_clk.common, | ||
705 | &hdmi_ddc_clk.common, | ||
706 | &mbus_clk.common, | ||
707 | &gpu_clk.common, | ||
708 | }; | ||
709 | |||
600 | /* We hardcode the divider to 4 for now */ | 710 | /* We hardcode the divider to 4 for now */ |
601 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 711 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", |
602 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); | 712 | "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); |
@@ -677,7 +787,7 @@ static struct clk_hw_onecell_data sun8i_h3_hw_clks = { | |||
677 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, | 787 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, |
678 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, | 788 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, |
679 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, | 789 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, |
680 | [CLK_BUS_SCR] = &bus_scr_clk.common.hw, | 790 | [CLK_BUS_SCR0] = &bus_scr0_clk.common.hw, |
681 | [CLK_BUS_EPHY] = &bus_ephy_clk.common.hw, | 791 | [CLK_BUS_EPHY] = &bus_ephy_clk.common.hw, |
682 | [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, | 792 | [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, |
683 | [CLK_THS] = &ths_clk.common.hw, | 793 | [CLK_THS] = &ths_clk.common.hw, |
@@ -727,7 +837,123 @@ static struct clk_hw_onecell_data sun8i_h3_hw_clks = { | |||
727 | [CLK_MBUS] = &mbus_clk.common.hw, | 837 | [CLK_MBUS] = &mbus_clk.common.hw, |
728 | [CLK_GPU] = &gpu_clk.common.hw, | 838 | [CLK_GPU] = &gpu_clk.common.hw, |
729 | }, | 839 | }, |
730 | .num = CLK_NUMBER, | 840 | .num = CLK_NUMBER_H3, |
841 | }; | ||
842 | |||
843 | static struct clk_hw_onecell_data sun50i_h5_hw_clks = { | ||
844 | .hws = { | ||
845 | [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, | ||
846 | [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, | ||
847 | [CLK_PLL_AUDIO] = &pll_audio_clk.hw, | ||
848 | [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, | ||
849 | [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, | ||
850 | [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, | ||
851 | [CLK_PLL_VIDEO] = &pll_video_clk.common.hw, | ||
852 | [CLK_PLL_VE] = &pll_ve_clk.common.hw, | ||
853 | [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, | ||
854 | [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw, | ||
855 | [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw, | ||
856 | [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, | ||
857 | [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw, | ||
858 | [CLK_PLL_DE] = &pll_de_clk.common.hw, | ||
859 | [CLK_CPUX] = &cpux_clk.common.hw, | ||
860 | [CLK_AXI] = &axi_clk.common.hw, | ||
861 | [CLK_AHB1] = &ahb1_clk.common.hw, | ||
862 | [CLK_APB1] = &apb1_clk.common.hw, | ||
863 | [CLK_APB2] = &apb2_clk.common.hw, | ||
864 | [CLK_AHB2] = &ahb2_clk.common.hw, | ||
865 | [CLK_BUS_CE] = &bus_ce_clk.common.hw, | ||
866 | [CLK_BUS_DMA] = &bus_dma_clk.common.hw, | ||
867 | [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, | ||
868 | [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, | ||
869 | [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, | ||
870 | [CLK_BUS_NAND] = &bus_nand_clk.common.hw, | ||
871 | [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, | ||
872 | [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, | ||
873 | [CLK_BUS_TS] = &bus_ts_clk.common.hw, | ||
874 | [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, | ||
875 | [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, | ||
876 | [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, | ||
877 | [CLK_BUS_OTG] = &bus_otg_clk.common.hw, | ||
878 | [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, | ||
879 | [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw, | ||
880 | [CLK_BUS_EHCI2] = &bus_ehci2_clk.common.hw, | ||
881 | [CLK_BUS_EHCI3] = &bus_ehci3_clk.common.hw, | ||
882 | [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, | ||
883 | [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw, | ||
884 | [CLK_BUS_OHCI2] = &bus_ohci2_clk.common.hw, | ||
885 | [CLK_BUS_OHCI3] = &bus_ohci3_clk.common.hw, | ||
886 | [CLK_BUS_VE] = &bus_ve_clk.common.hw, | ||
887 | [CLK_BUS_TCON0] = &bus_tcon0_clk.common.hw, | ||
888 | [CLK_BUS_TCON1] = &bus_tcon1_clk.common.hw, | ||
889 | [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw, | ||
890 | [CLK_BUS_CSI] = &bus_csi_clk.common.hw, | ||
891 | [CLK_BUS_TVE] = &bus_tve_clk.common.hw, | ||
892 | [CLK_BUS_HDMI] = &bus_hdmi_clk.common.hw, | ||
893 | [CLK_BUS_DE] = &bus_de_clk.common.hw, | ||
894 | [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, | ||
895 | [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, | ||
896 | [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, | ||
897 | [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, | ||
898 | [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, | ||
899 | [CLK_BUS_PIO] = &bus_pio_clk.common.hw, | ||
900 | [CLK_BUS_THS] = &bus_ths_clk.common.hw, | ||
901 | [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, | ||
902 | [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, | ||
903 | [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, | ||
904 | [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, | ||
905 | [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, | ||
906 | [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, | ||
907 | [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, | ||
908 | [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, | ||
909 | [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, | ||
910 | [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, | ||
911 | [CLK_BUS_SCR0] = &bus_scr0_clk.common.hw, | ||
912 | [CLK_BUS_SCR1] = &bus_scr1_clk.common.hw, | ||
913 | [CLK_BUS_EPHY] = &bus_ephy_clk.common.hw, | ||
914 | [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, | ||
915 | [CLK_THS] = &ths_clk.common.hw, | ||
916 | [CLK_NAND] = &nand_clk.common.hw, | ||
917 | [CLK_MMC0] = &mmc0_clk.common.hw, | ||
918 | [CLK_MMC1] = &mmc1_clk.common.hw, | ||
919 | [CLK_MMC2] = &mmc2_clk.common.hw, | ||
920 | [CLK_TS] = &ts_clk.common.hw, | ||
921 | [CLK_CE] = &ce_clk.common.hw, | ||
922 | [CLK_SPI0] = &spi0_clk.common.hw, | ||
923 | [CLK_SPI1] = &spi1_clk.common.hw, | ||
924 | [CLK_I2S0] = &i2s0_clk.common.hw, | ||
925 | [CLK_I2S1] = &i2s1_clk.common.hw, | ||
926 | [CLK_I2S2] = &i2s2_clk.common.hw, | ||
927 | [CLK_SPDIF] = &spdif_clk.common.hw, | ||
928 | [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, | ||
929 | [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, | ||
930 | [CLK_USB_PHY2] = &usb_phy2_clk.common.hw, | ||
931 | [CLK_USB_PHY3] = &usb_phy3_clk.common.hw, | ||
932 | [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, | ||
933 | [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, | ||
934 | [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, | ||
935 | [CLK_USB_OHCI3] = &usb_ohci3_clk.common.hw, | ||
936 | [CLK_DRAM] = &dram_clk.common.hw, | ||
937 | [CLK_DRAM_VE] = &dram_ve_clk.common.hw, | ||
938 | [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, | ||
939 | [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw, | ||
940 | [CLK_DRAM_TS] = &dram_ts_clk.common.hw, | ||
941 | [CLK_DE] = &de_clk.common.hw, | ||
942 | [CLK_TCON0] = &tcon_clk.common.hw, | ||
943 | [CLK_TVE] = &tve_clk.common.hw, | ||
944 | [CLK_DEINTERLACE] = &deinterlace_clk.common.hw, | ||
945 | [CLK_CSI_MISC] = &csi_misc_clk.common.hw, | ||
946 | [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, | ||
947 | [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, | ||
948 | [CLK_VE] = &ve_clk.common.hw, | ||
949 | [CLK_AC_DIG] = &ac_dig_clk.common.hw, | ||
950 | [CLK_AVS] = &avs_clk.common.hw, | ||
951 | [CLK_HDMI] = &hdmi_clk.common.hw, | ||
952 | [CLK_HDMI_DDC] = &hdmi_ddc_clk.common.hw, | ||
953 | [CLK_MBUS] = &mbus_clk.common.hw, | ||
954 | [CLK_GPU] = &gpu_clk.common.hw, | ||
955 | }, | ||
956 | .num = CLK_NUMBER_H5, | ||
731 | }; | 957 | }; |
732 | 958 | ||
733 | static struct ccu_reset_map sun8i_h3_ccu_resets[] = { | 959 | static struct ccu_reset_map sun8i_h3_ccu_resets[] = { |
@@ -790,7 +1016,71 @@ static struct ccu_reset_map sun8i_h3_ccu_resets[] = { | |||
790 | [RST_BUS_UART1] = { 0x2d8, BIT(17) }, | 1016 | [RST_BUS_UART1] = { 0x2d8, BIT(17) }, |
791 | [RST_BUS_UART2] = { 0x2d8, BIT(18) }, | 1017 | [RST_BUS_UART2] = { 0x2d8, BIT(18) }, |
792 | [RST_BUS_UART3] = { 0x2d8, BIT(19) }, | 1018 | [RST_BUS_UART3] = { 0x2d8, BIT(19) }, |
793 | [RST_BUS_SCR] = { 0x2d8, BIT(20) }, | 1019 | [RST_BUS_SCR0] = { 0x2d8, BIT(20) }, |
1020 | }; | ||
1021 | |||
1022 | static struct ccu_reset_map sun50i_h5_ccu_resets[] = { | ||
1023 | [RST_USB_PHY0] = { 0x0cc, BIT(0) }, | ||
1024 | [RST_USB_PHY1] = { 0x0cc, BIT(1) }, | ||
1025 | [RST_USB_PHY2] = { 0x0cc, BIT(2) }, | ||
1026 | [RST_USB_PHY3] = { 0x0cc, BIT(3) }, | ||
1027 | |||
1028 | [RST_MBUS] = { 0x0fc, BIT(31) }, | ||
1029 | |||
1030 | [RST_BUS_CE] = { 0x2c0, BIT(5) }, | ||
1031 | [RST_BUS_DMA] = { 0x2c0, BIT(6) }, | ||
1032 | [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, | ||
1033 | [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, | ||
1034 | [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, | ||
1035 | [RST_BUS_NAND] = { 0x2c0, BIT(13) }, | ||
1036 | [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, | ||
1037 | [RST_BUS_EMAC] = { 0x2c0, BIT(17) }, | ||
1038 | [RST_BUS_TS] = { 0x2c0, BIT(18) }, | ||
1039 | [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, | ||
1040 | [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, | ||
1041 | [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, | ||
1042 | [RST_BUS_OTG] = { 0x2c0, BIT(23) }, | ||
1043 | [RST_BUS_EHCI0] = { 0x2c0, BIT(24) }, | ||
1044 | [RST_BUS_EHCI1] = { 0x2c0, BIT(25) }, | ||
1045 | [RST_BUS_EHCI2] = { 0x2c0, BIT(26) }, | ||
1046 | [RST_BUS_EHCI3] = { 0x2c0, BIT(27) }, | ||
1047 | [RST_BUS_OHCI0] = { 0x2c0, BIT(28) }, | ||
1048 | [RST_BUS_OHCI1] = { 0x2c0, BIT(29) }, | ||
1049 | [RST_BUS_OHCI2] = { 0x2c0, BIT(30) }, | ||
1050 | [RST_BUS_OHCI3] = { 0x2c0, BIT(31) }, | ||
1051 | |||
1052 | [RST_BUS_VE] = { 0x2c4, BIT(0) }, | ||
1053 | [RST_BUS_TCON0] = { 0x2c4, BIT(3) }, | ||
1054 | [RST_BUS_TCON1] = { 0x2c4, BIT(4) }, | ||
1055 | [RST_BUS_DEINTERLACE] = { 0x2c4, BIT(5) }, | ||
1056 | [RST_BUS_CSI] = { 0x2c4, BIT(8) }, | ||
1057 | [RST_BUS_TVE] = { 0x2c4, BIT(9) }, | ||
1058 | [RST_BUS_HDMI0] = { 0x2c4, BIT(10) }, | ||
1059 | [RST_BUS_HDMI1] = { 0x2c4, BIT(11) }, | ||
1060 | [RST_BUS_DE] = { 0x2c4, BIT(12) }, | ||
1061 | [RST_BUS_GPU] = { 0x2c4, BIT(20) }, | ||
1062 | [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) }, | ||
1063 | [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) }, | ||
1064 | [RST_BUS_DBG] = { 0x2c4, BIT(31) }, | ||
1065 | |||
1066 | [RST_BUS_EPHY] = { 0x2c8, BIT(2) }, | ||
1067 | |||
1068 | [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, | ||
1069 | [RST_BUS_SPDIF] = { 0x2d0, BIT(1) }, | ||
1070 | [RST_BUS_THS] = { 0x2d0, BIT(8) }, | ||
1071 | [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, | ||
1072 | [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, | ||
1073 | [RST_BUS_I2S2] = { 0x2d0, BIT(14) }, | ||
1074 | |||
1075 | [RST_BUS_I2C0] = { 0x2d8, BIT(0) }, | ||
1076 | [RST_BUS_I2C1] = { 0x2d8, BIT(1) }, | ||
1077 | [RST_BUS_I2C2] = { 0x2d8, BIT(2) }, | ||
1078 | [RST_BUS_UART0] = { 0x2d8, BIT(16) }, | ||
1079 | [RST_BUS_UART1] = { 0x2d8, BIT(17) }, | ||
1080 | [RST_BUS_UART2] = { 0x2d8, BIT(18) }, | ||
1081 | [RST_BUS_UART3] = { 0x2d8, BIT(19) }, | ||
1082 | [RST_BUS_SCR0] = { 0x2d8, BIT(20) }, | ||
1083 | [RST_BUS_SCR1] = { 0x2d8, BIT(20) }, | ||
794 | }; | 1084 | }; |
795 | 1085 | ||
796 | static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = { | 1086 | static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = { |
@@ -803,6 +1093,16 @@ static const struct sunxi_ccu_desc sun8i_h3_ccu_desc = { | |||
803 | .num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets), | 1093 | .num_resets = ARRAY_SIZE(sun8i_h3_ccu_resets), |
804 | }; | 1094 | }; |
805 | 1095 | ||
1096 | static const struct sunxi_ccu_desc sun50i_h5_ccu_desc = { | ||
1097 | .ccu_clks = sun50i_h5_ccu_clks, | ||
1098 | .num_ccu_clks = ARRAY_SIZE(sun50i_h5_ccu_clks), | ||
1099 | |||
1100 | .hw_clks = &sun50i_h5_hw_clks, | ||
1101 | |||
1102 | .resets = sun50i_h5_ccu_resets, | ||
1103 | .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets), | ||
1104 | }; | ||
1105 | |||
806 | static struct ccu_mux_nb sun8i_h3_cpu_nb = { | 1106 | static struct ccu_mux_nb sun8i_h3_cpu_nb = { |
807 | .common = &cpux_clk.common, | 1107 | .common = &cpux_clk.common, |
808 | .cm = &cpux_clk.mux, | 1108 | .cm = &cpux_clk.mux, |
@@ -810,7 +1110,8 @@ static struct ccu_mux_nb sun8i_h3_cpu_nb = { | |||
810 | .bypass_index = 1, /* index of 24 MHz oscillator */ | 1110 | .bypass_index = 1, /* index of 24 MHz oscillator */ |
811 | }; | 1111 | }; |
812 | 1112 | ||
813 | static void __init sun8i_h3_ccu_setup(struct device_node *node) | 1113 | static void __init sunxi_h3_h5_ccu_init(struct device_node *node, |
1114 | const struct sunxi_ccu_desc *desc) | ||
814 | { | 1115 | { |
815 | void __iomem *reg; | 1116 | void __iomem *reg; |
816 | u32 val; | 1117 | u32 val; |
@@ -827,10 +1128,22 @@ static void __init sun8i_h3_ccu_setup(struct device_node *node) | |||
827 | val &= ~GENMASK(19, 16); | 1128 | val &= ~GENMASK(19, 16); |
828 | writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG); | 1129 | writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG); |
829 | 1130 | ||
830 | sunxi_ccu_probe(node, reg, &sun8i_h3_ccu_desc); | 1131 | sunxi_ccu_probe(node, reg, desc); |
831 | 1132 | ||
832 | ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, | 1133 | ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, |
833 | &sun8i_h3_cpu_nb); | 1134 | &sun8i_h3_cpu_nb); |
834 | } | 1135 | } |
1136 | |||
1137 | static void __init sun8i_h3_ccu_setup(struct device_node *node) | ||
1138 | { | ||
1139 | sunxi_h3_h5_ccu_init(node, &sun8i_h3_ccu_desc); | ||
1140 | } | ||
835 | CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu", | 1141 | CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu", |
836 | sun8i_h3_ccu_setup); | 1142 | sun8i_h3_ccu_setup); |
1143 | |||
1144 | static void __init sun50i_h5_ccu_setup(struct device_node *node) | ||
1145 | { | ||
1146 | sunxi_h3_h5_ccu_init(node, &sun50i_h5_ccu_desc); | ||
1147 | } | ||
1148 | CLK_OF_DECLARE(sun50i_h5_ccu, "allwinner,sun50i-h5-ccu", | ||
1149 | sun50i_h5_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h index 78be712c7487..85973d1e8165 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.h +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.h | |||
@@ -57,6 +57,7 @@ | |||
57 | 57 | ||
58 | /* And the GPU module clock is exported */ | 58 | /* And the GPU module clock is exported */ |
59 | 59 | ||
60 | #define CLK_NUMBER (CLK_GPU + 1) | 60 | #define CLK_NUMBER_H3 (CLK_GPU + 1) |
61 | #define CLK_NUMBER_H5 (CLK_BUS_SCR1 + 1) | ||
61 | 62 | ||
62 | #endif /* _CCU_SUN8I_H3_H_ */ | 63 | #endif /* _CCU_SUN8I_H3_H_ */ |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c new file mode 100644 index 000000000000..0d027d53dbdf --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c | |||
@@ -0,0 +1,213 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz> | ||
3 | * | ||
4 | * This software is licensed under the terms of the GNU General Public | ||
5 | * License version 2, as published by the Free Software Foundation, and | ||
6 | * may be copied, distributed, and modified under those terms. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include "ccu_common.h" | ||
19 | #include "ccu_reset.h" | ||
20 | |||
21 | #include "ccu_div.h" | ||
22 | #include "ccu_gate.h" | ||
23 | #include "ccu_mp.h" | ||
24 | #include "ccu_nm.h" | ||
25 | |||
26 | #include "ccu-sun8i-r.h" | ||
27 | |||
28 | static const char * const ar100_parents[] = { "osc32k", "osc24M", | ||
29 | "pll-periph0", "iosc" }; | ||
30 | |||
31 | static struct ccu_div ar100_clk = { | ||
32 | .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
33 | |||
34 | .mux = { | ||
35 | .shift = 16, | ||
36 | .width = 2, | ||
37 | |||
38 | .variable_prediv = { | ||
39 | .index = 2, | ||
40 | .shift = 8, | ||
41 | .width = 5, | ||
42 | }, | ||
43 | }, | ||
44 | |||
45 | .common = { | ||
46 | .reg = 0x00, | ||
47 | .features = CCU_FEATURE_VARIABLE_PREDIV, | ||
48 | .hw.init = CLK_HW_INIT_PARENTS("ar100", | ||
49 | ar100_parents, | ||
50 | &ccu_div_ops, | ||
51 | 0), | ||
52 | }, | ||
53 | }; | ||
54 | |||
55 | static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0); | ||
56 | |||
57 | static struct ccu_div apb0_clk = { | ||
58 | .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), | ||
59 | |||
60 | .common = { | ||
61 | .reg = 0x0c, | ||
62 | .hw.init = CLK_HW_INIT("apb0", | ||
63 | "ahb0", | ||
64 | &ccu_div_ops, | ||
65 | 0), | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", | ||
70 | 0x28, BIT(0), 0); | ||
71 | static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", | ||
72 | 0x28, BIT(1), 0); | ||
73 | static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0", | ||
74 | 0x28, BIT(2), 0); | ||
75 | static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0", | ||
76 | 0x28, BIT(3), 0); | ||
77 | static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0", | ||
78 | 0x28, BIT(4), 0); | ||
79 | static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0", | ||
80 | 0x28, BIT(6), 0); | ||
81 | static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0", | ||
82 | 0x28, BIT(7), 0); | ||
83 | |||
84 | static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" }; | ||
85 | static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", | ||
86 | r_mod0_default_parents, 0x54, | ||
87 | 0, 4, /* M */ | ||
88 | 16, 2, /* P */ | ||
89 | 24, 2, /* mux */ | ||
90 | BIT(31), /* gate */ | ||
91 | 0); | ||
92 | |||
93 | static struct ccu_common *sun8i_h3_r_ccu_clks[] = { | ||
94 | &ar100_clk.common, | ||
95 | &apb0_clk.common, | ||
96 | &apb0_pio_clk.common, | ||
97 | &apb0_ir_clk.common, | ||
98 | &apb0_timer_clk.common, | ||
99 | &apb0_uart_clk.common, | ||
100 | &apb0_i2c_clk.common, | ||
101 | &apb0_twd_clk.common, | ||
102 | &ir_clk.common, | ||
103 | }; | ||
104 | |||
105 | static struct ccu_common *sun50i_a64_r_ccu_clks[] = { | ||
106 | &ar100_clk.common, | ||
107 | &apb0_clk.common, | ||
108 | &apb0_pio_clk.common, | ||
109 | &apb0_ir_clk.common, | ||
110 | &apb0_timer_clk.common, | ||
111 | &apb0_rsb_clk.common, | ||
112 | &apb0_uart_clk.common, | ||
113 | &apb0_i2c_clk.common, | ||
114 | &apb0_twd_clk.common, | ||
115 | &ir_clk.common, | ||
116 | }; | ||
117 | |||
118 | static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = { | ||
119 | .hws = { | ||
120 | [CLK_AR100] = &ar100_clk.common.hw, | ||
121 | [CLK_AHB0] = &ahb0_clk.hw, | ||
122 | [CLK_APB0] = &apb0_clk.common.hw, | ||
123 | [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, | ||
124 | [CLK_APB0_IR] = &apb0_ir_clk.common.hw, | ||
125 | [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, | ||
126 | [CLK_APB0_UART] = &apb0_uart_clk.common.hw, | ||
127 | [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, | ||
128 | [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, | ||
129 | [CLK_IR] = &ir_clk.common.hw, | ||
130 | }, | ||
131 | .num = CLK_NUMBER, | ||
132 | }; | ||
133 | |||
134 | static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = { | ||
135 | .hws = { | ||
136 | [CLK_AR100] = &ar100_clk.common.hw, | ||
137 | [CLK_AHB0] = &ahb0_clk.hw, | ||
138 | [CLK_APB0] = &apb0_clk.common.hw, | ||
139 | [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, | ||
140 | [CLK_APB0_IR] = &apb0_ir_clk.common.hw, | ||
141 | [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, | ||
142 | [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw, | ||
143 | [CLK_APB0_UART] = &apb0_uart_clk.common.hw, | ||
144 | [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, | ||
145 | [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, | ||
146 | [CLK_IR] = &ir_clk.common.hw, | ||
147 | }, | ||
148 | .num = CLK_NUMBER, | ||
149 | }; | ||
150 | |||
151 | static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = { | ||
152 | [RST_APB0_IR] = { 0xb0, BIT(1) }, | ||
153 | [RST_APB0_TIMER] = { 0xb0, BIT(2) }, | ||
154 | [RST_APB0_UART] = { 0xb0, BIT(4) }, | ||
155 | [RST_APB0_I2C] = { 0xb0, BIT(6) }, | ||
156 | }; | ||
157 | |||
158 | static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = { | ||
159 | [RST_APB0_IR] = { 0xb0, BIT(1) }, | ||
160 | [RST_APB0_TIMER] = { 0xb0, BIT(2) }, | ||
161 | [RST_APB0_RSB] = { 0xb0, BIT(3) }, | ||
162 | [RST_APB0_UART] = { 0xb0, BIT(4) }, | ||
163 | [RST_APB0_I2C] = { 0xb0, BIT(6) }, | ||
164 | }; | ||
165 | |||
166 | static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = { | ||
167 | .ccu_clks = sun8i_h3_r_ccu_clks, | ||
168 | .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks), | ||
169 | |||
170 | .hw_clks = &sun8i_h3_r_hw_clks, | ||
171 | |||
172 | .resets = sun8i_h3_r_ccu_resets, | ||
173 | .num_resets = ARRAY_SIZE(sun8i_h3_r_ccu_resets), | ||
174 | }; | ||
175 | |||
176 | static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = { | ||
177 | .ccu_clks = sun50i_a64_r_ccu_clks, | ||
178 | .num_ccu_clks = ARRAY_SIZE(sun50i_a64_r_ccu_clks), | ||
179 | |||
180 | .hw_clks = &sun50i_a64_r_hw_clks, | ||
181 | |||
182 | .resets = sun50i_a64_r_ccu_resets, | ||
183 | .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets), | ||
184 | }; | ||
185 | |||
186 | static void __init sunxi_r_ccu_init(struct device_node *node, | ||
187 | const struct sunxi_ccu_desc *desc) | ||
188 | { | ||
189 | void __iomem *reg; | ||
190 | |||
191 | reg = of_io_request_and_map(node, 0, of_node_full_name(node)); | ||
192 | if (IS_ERR(reg)) { | ||
193 | pr_err("%s: Could not map the clock registers\n", | ||
194 | of_node_full_name(node)); | ||
195 | return; | ||
196 | } | ||
197 | |||
198 | sunxi_ccu_probe(node, reg, desc); | ||
199 | } | ||
200 | |||
201 | static void __init sun8i_h3_r_ccu_setup(struct device_node *node) | ||
202 | { | ||
203 | sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc); | ||
204 | } | ||
205 | CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu", | ||
206 | sun8i_h3_r_ccu_setup); | ||
207 | |||
208 | static void __init sun50i_a64_r_ccu_setup(struct device_node *node) | ||
209 | { | ||
210 | sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc); | ||
211 | } | ||
212 | CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu", | ||
213 | sun50i_a64_r_ccu_setup); | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h new file mode 100644 index 000000000000..eaa431fd1d8f --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Copyright 2016 Icenowy <icenowy@aosc.xyz> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef _CCU_SUN8I_R_H | ||
16 | #define _CCU_SUN8I_R_H_ | ||
17 | |||
18 | #include <dt-bindings/clock/sun8i-r-ccu.h> | ||
19 | #include <dt-bindings/reset/sun8i-r-ccu.h> | ||
20 | |||
21 | /* AHB/APB bus clocks are not exported */ | ||
22 | #define CLK_AHB0 1 | ||
23 | #define CLK_APB0 2 | ||
24 | |||
25 | #define CLK_NUMBER (CLK_APB0_TWD + 1) | ||
26 | |||
27 | #endif /* _CCU_SUN8I_R_H */ | ||
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c index e13e313ce4f5..51f6d495de5b 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c | |||
@@ -29,41 +29,41 @@ | |||
29 | 29 | ||
30 | #define CCU_SUN9I_LOCK_REG 0x09c | 30 | #define CCU_SUN9I_LOCK_REG 0x09c |
31 | 31 | ||
32 | static struct clk_div_table pll_cpux_p_div_table[] = { | ||
33 | { .val = 0, .div = 1 }, | ||
34 | { .val = 1, .div = 4 }, | ||
35 | { /* Sentinel */ }, | ||
36 | }; | ||
37 | |||
38 | /* | 32 | /* |
39 | * The CPU PLLs are actually NP clocks, but P is /1 or /4, so here we | 33 | * The CPU PLLs are actually NP clocks, with P being /1 or /4. However |
40 | * use the NM clocks with a divider table for M. | 34 | * P should only be used for output frequencies lower than 228 MHz. |
35 | * Neither mainline Linux, U-boot, nor the vendor BSPs use these. | ||
36 | * | ||
37 | * For now we can just model it as a multiplier clock, and force P to /1. | ||
41 | */ | 38 | */ |
42 | static struct ccu_nm pll_c0cpux_clk = { | 39 | #define SUN9I_A80_PLL_C0CPUX_REG 0x000 |
40 | #define SUN9I_A80_PLL_C1CPUX_REG 0x004 | ||
41 | |||
42 | static struct ccu_mult pll_c0cpux_clk = { | ||
43 | .enable = BIT(31), | 43 | .enable = BIT(31), |
44 | .lock = BIT(0), | 44 | .lock = BIT(0), |
45 | .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), | 45 | .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), |
46 | .m = _SUNXI_CCU_DIV_TABLE(16, 1, pll_cpux_p_div_table), | ||
47 | .common = { | 46 | .common = { |
48 | .reg = 0x000, | 47 | .reg = SUN9I_A80_PLL_C0CPUX_REG, |
49 | .lock_reg = CCU_SUN9I_LOCK_REG, | 48 | .lock_reg = CCU_SUN9I_LOCK_REG, |
50 | .features = CCU_FEATURE_LOCK_REG, | 49 | .features = CCU_FEATURE_LOCK_REG, |
51 | .hw.init = CLK_HW_INIT("pll-c0cpux", "osc24M", | 50 | .hw.init = CLK_HW_INIT("pll-c0cpux", "osc24M", |
52 | &ccu_nm_ops, CLK_SET_RATE_UNGATE), | 51 | &ccu_mult_ops, |
52 | CLK_SET_RATE_UNGATE), | ||
53 | }, | 53 | }, |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static struct ccu_nm pll_c1cpux_clk = { | 56 | static struct ccu_mult pll_c1cpux_clk = { |
57 | .enable = BIT(31), | 57 | .enable = BIT(31), |
58 | .lock = BIT(1), | 58 | .lock = BIT(1), |
59 | .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), | 59 | .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), |
60 | .m = _SUNXI_CCU_DIV_TABLE(16, 1, pll_cpux_p_div_table), | ||
61 | .common = { | 60 | .common = { |
62 | .reg = 0x004, | 61 | .reg = SUN9I_A80_PLL_C1CPUX_REG, |
63 | .lock_reg = CCU_SUN9I_LOCK_REG, | 62 | .lock_reg = CCU_SUN9I_LOCK_REG, |
64 | .features = CCU_FEATURE_LOCK_REG, | 63 | .features = CCU_FEATURE_LOCK_REG, |
65 | .hw.init = CLK_HW_INIT("pll-c1cpux", "osc24M", | 64 | .hw.init = CLK_HW_INIT("pll-c1cpux", "osc24M", |
66 | &ccu_nm_ops, CLK_SET_RATE_UNGATE), | 65 | &ccu_mult_ops, |
66 | CLK_SET_RATE_UNGATE), | ||
67 | }, | 67 | }, |
68 | }; | 68 | }; |
69 | 69 | ||
@@ -1189,6 +1189,36 @@ static const struct sunxi_ccu_desc sun9i_a80_ccu_desc = { | |||
1189 | .num_resets = ARRAY_SIZE(sun9i_a80_ccu_resets), | 1189 | .num_resets = ARRAY_SIZE(sun9i_a80_ccu_resets), |
1190 | }; | 1190 | }; |
1191 | 1191 | ||
1192 | #define SUN9I_A80_PLL_P_SHIFT 16 | ||
1193 | #define SUN9I_A80_PLL_N_SHIFT 8 | ||
1194 | #define SUN9I_A80_PLL_N_WIDTH 8 | ||
1195 | |||
1196 | static void sun9i_a80_cpu_pll_fixup(void __iomem *reg) | ||
1197 | { | ||
1198 | u32 val = readl(reg); | ||
1199 | |||
1200 | /* bail out if P divider is not used */ | ||
1201 | if (!(val & BIT(SUN9I_A80_PLL_P_SHIFT))) | ||
1202 | return; | ||
1203 | |||
1204 | /* | ||
1205 | * If P is used, output should be less than 288 MHz. When we | ||
1206 | * set P to 1, we should also decrease the multiplier so the | ||
1207 | * output doesn't go out of range, but not too much such that | ||
1208 | * the multiplier stays above 12, the minimal operation value. | ||
1209 | * | ||
1210 | * To keep it simple, set the multiplier to 17, the reset value. | ||
1211 | */ | ||
1212 | val &= ~GENMASK(SUN9I_A80_PLL_N_SHIFT + SUN9I_A80_PLL_N_WIDTH - 1, | ||
1213 | SUN9I_A80_PLL_N_SHIFT); | ||
1214 | val |= 17 << SUN9I_A80_PLL_N_SHIFT; | ||
1215 | |||
1216 | /* And clear P */ | ||
1217 | val &= ~BIT(SUN9I_A80_PLL_P_SHIFT); | ||
1218 | |||
1219 | writel(val, reg); | ||
1220 | } | ||
1221 | |||
1192 | static int sun9i_a80_ccu_probe(struct platform_device *pdev) | 1222 | static int sun9i_a80_ccu_probe(struct platform_device *pdev) |
1193 | { | 1223 | { |
1194 | struct resource *res; | 1224 | struct resource *res; |
@@ -1205,6 +1235,10 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev) | |||
1205 | val &= (BIT(16) & BIT(18)); | 1235 | val &= (BIT(16) & BIT(18)); |
1206 | writel(val, reg + SUN9I_A80_PLL_AUDIO_REG); | 1236 | writel(val, reg + SUN9I_A80_PLL_AUDIO_REG); |
1207 | 1237 | ||
1238 | /* Enforce P = 1 for both CPU cluster PLLs */ | ||
1239 | sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C0CPUX_REG); | ||
1240 | sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C1CPUX_REG); | ||
1241 | |||
1208 | return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc); | 1242 | return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc); |
1209 | } | 1243 | } |
1210 | 1244 | ||
diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 9d8724715a43..40aac316128f 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c | |||
@@ -112,8 +112,8 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, | |||
112 | 112 | ||
113 | ret = clk_hw_register(NULL, hw); | 113 | ret = clk_hw_register(NULL, hw); |
114 | if (ret) { | 114 | if (ret) { |
115 | pr_err("Couldn't register clock %s\n", | 115 | pr_err("Couldn't register clock %d - %s\n", |
116 | clk_hw_get_name(hw)); | 116 | i, clk_hw_get_name(hw)); |
117 | goto err_clk_unreg; | 117 | goto err_clk_unreg; |
118 | } | 118 | } |
119 | } | 119 | } |
diff --git a/drivers/clk/sunxi-ng/ccu_gate.c b/drivers/clk/sunxi-ng/ccu_gate.c index 8a81f9d4a89f..cd069d5da215 100644 --- a/drivers/clk/sunxi-ng/ccu_gate.c +++ b/drivers/clk/sunxi-ng/ccu_gate.c | |||
@@ -75,8 +75,55 @@ static int ccu_gate_is_enabled(struct clk_hw *hw) | |||
75 | return ccu_gate_helper_is_enabled(&cg->common, cg->enable); | 75 | return ccu_gate_helper_is_enabled(&cg->common, cg->enable); |
76 | } | 76 | } |
77 | 77 | ||
78 | static unsigned long ccu_gate_recalc_rate(struct clk_hw *hw, | ||
79 | unsigned long parent_rate) | ||
80 | { | ||
81 | struct ccu_gate *cg = hw_to_ccu_gate(hw); | ||
82 | unsigned long rate = parent_rate; | ||
83 | |||
84 | if (cg->common.features & CCU_FEATURE_ALL_PREDIV) | ||
85 | rate /= cg->common.prediv; | ||
86 | |||
87 | return rate; | ||
88 | } | ||
89 | |||
90 | static long ccu_gate_round_rate(struct clk_hw *hw, unsigned long rate, | ||
91 | unsigned long *prate) | ||
92 | { | ||
93 | struct ccu_gate *cg = hw_to_ccu_gate(hw); | ||
94 | int div = 1; | ||
95 | |||
96 | if (cg->common.features & CCU_FEATURE_ALL_PREDIV) | ||
97 | div = cg->common.prediv; | ||
98 | |||
99 | if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { | ||
100 | unsigned long best_parent = rate; | ||
101 | |||
102 | if (cg->common.features & CCU_FEATURE_ALL_PREDIV) | ||
103 | best_parent *= div; | ||
104 | *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); | ||
105 | } | ||
106 | |||
107 | return *prate / div; | ||
108 | } | ||
109 | |||
110 | static int ccu_gate_set_rate(struct clk_hw *hw, unsigned long rate, | ||
111 | unsigned long parent_rate) | ||
112 | { | ||
113 | /* | ||
114 | * We must report success but we can do so unconditionally because | ||
115 | * clk_factor_round_rate returns values that ensure this call is a | ||
116 | * nop. | ||
117 | */ | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
78 | const struct clk_ops ccu_gate_ops = { | 122 | const struct clk_ops ccu_gate_ops = { |
79 | .disable = ccu_gate_disable, | 123 | .disable = ccu_gate_disable, |
80 | .enable = ccu_gate_enable, | 124 | .enable = ccu_gate_enable, |
81 | .is_enabled = ccu_gate_is_enabled, | 125 | .is_enabled = ccu_gate_is_enabled, |
126 | .round_rate = ccu_gate_round_rate, | ||
127 | .set_rate = ccu_gate_set_rate, | ||
128 | .recalc_rate = ccu_gate_recalc_rate, | ||
82 | }; | 129 | }; |
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 8724c01171b1..671141359895 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c | |||
@@ -137,6 +137,8 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, | |||
137 | 137 | ||
138 | spin_unlock_irqrestore(cm->common.lock, flags); | 138 | spin_unlock_irqrestore(cm->common.lock, flags); |
139 | 139 | ||
140 | ccu_helper_wait_for_lock(&cm->common, cm->lock); | ||
141 | |||
140 | return 0; | 142 | return 0; |
141 | } | 143 | } |
142 | 144 | ||
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h index 524acddfcb2e..f9c37b987d72 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.h +++ b/drivers/clk/sunxi-ng/ccu_mult.h | |||
@@ -33,6 +33,7 @@ struct ccu_mult_internal { | |||
33 | 33 | ||
34 | struct ccu_mult { | 34 | struct ccu_mult { |
35 | u32 enable; | 35 | u32 enable; |
36 | u32 lock; | ||
36 | 37 | ||
37 | struct ccu_frac_internal frac; | 38 | struct ccu_frac_internal frac; |
38 | struct ccu_mult_internal mult; | 39 | struct ccu_mult_internal mult; |
@@ -45,6 +46,7 @@ struct ccu_mult { | |||
45 | _flags) \ | 46 | _flags) \ |
46 | struct ccu_mult _struct = { \ | 47 | struct ccu_mult _struct = { \ |
47 | .enable = _gate, \ | 48 | .enable = _gate, \ |
49 | .lock = _lock, \ | ||
48 | .mult = _SUNXI_CCU_MULT(_mshift, _mwidth), \ | 50 | .mult = _SUNXI_CCU_MULT(_mshift, _mwidth), \ |
49 | .common = { \ | 51 | .common = { \ |
50 | .reg = _reg, \ | 52 | .reg = _reg, \ |