Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull Allwinner clock driver changes from Maxime Ripard:

Four more SoCs converted to the new clock framework (A31, A31s, A23 and
A33).

* tag 'sunxi-clk-for-4.9' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux:
clk: sunxi-ng: Add hardware dependency
clk: sunxi-ng: Add A23 CCU
clk: sunxi-ng: Add A33 CCU support
clk: sunxi-ng: Add N-class clocks support
clk: sunxi-ng: mux: Add mux table macro
clk: sunxi-ng: div: Allow to set a maximum
clk: sunxi-ng: div: Add kerneldoc for the _ccu_div structure
clk: sunxi-ng: div: Add mux table macros
clk: sunxi-ng: Add A31/A31s clocks
clk: sunxi-ng: mux: Add clk notifier functions
clk: sunxi-ng: mux: support fixed pre-dividers on multiple parents
clk: sunxi-ng: mux: Add support for mux tables
clk: sunxi-ng: mux: Rename mux macro to be consistent
clk: sunxi-ng: nkm: Add mux to support multiple parents
clk: sunxi-ng: mux: Increase fixed pre-divider div size

+3861 -80
+4 -1
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
··· 2 2 ------------------------------------ 3 3 4 4 Required properties : 5 - - compatible: must contain one of the following compatible: 5 + - compatible: must contain one of the following compatibles: 6 + - "allwinner,sun6i-a31-ccu" 7 + - "allwinner,sun8i-a23-ccu" 8 + - "allwinner,sun8i-a33-ccu" 6 9 - "allwinner,sun8i-h3-ccu" 7 10 8 11 - reg: Must contain the registers base address and length
+39
drivers/clk/sunxi-ng/Kconfig
··· 1 1 config SUNXI_CCU 2 2 bool "Clock support for Allwinner SoCs" 3 + depends on ARCH_SUNXI || COMPILE_TEST 3 4 default ARCH_SUNXI 4 5 5 6 if SUNXI_CCU ··· 19 18 20 19 config SUNXI_CCU_MUX 21 20 bool 21 + 22 + config SUNXI_CCU_MULT 23 + bool 24 + select SUNXI_CCU_MUX 22 25 23 26 config SUNXI_CCU_PHASE 24 27 bool ··· 55 50 select SUNXI_CCU_MUX 56 51 57 52 # SoC Drivers 53 + 54 + config SUN6I_A31_CCU 55 + bool "Support for the Allwinner A31/A31s CCU" 56 + select SUNXI_CCU_DIV 57 + select SUNXI_CCU_NK 58 + select SUNXI_CCU_NKM 59 + select SUNXI_CCU_NM 60 + select SUNXI_CCU_MP 61 + select SUNXI_CCU_PHASE 62 + default MACH_SUN6I 63 + 64 + config SUN8I_A23_CCU 65 + bool "Support for the Allwinner A23 CCU" 66 + select SUNXI_CCU_DIV 67 + select SUNXI_CCU_MULT 68 + select SUNXI_CCU_NK 69 + select SUNXI_CCU_NKM 70 + select SUNXI_CCU_NKMP 71 + select SUNXI_CCU_NM 72 + select SUNXI_CCU_MP 73 + select SUNXI_CCU_PHASE 74 + default MACH_SUN8I 75 + 76 + config SUN8I_A33_CCU 77 + bool "Support for the Allwinner A33 CCU" 78 + select SUNXI_CCU_DIV 79 + select SUNXI_CCU_MULT 80 + select SUNXI_CCU_NK 81 + select SUNXI_CCU_NKM 82 + select SUNXI_CCU_NKMP 83 + select SUNXI_CCU_NM 84 + select SUNXI_CCU_MP 85 + select SUNXI_CCU_PHASE 86 + default MACH_SUN8I 58 87 59 88 config SUN8I_H3_CCU 60 89 bool "Support for the Allwinner H3 CCU"
+4
drivers/clk/sunxi-ng/Makefile
··· 7 7 obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o 8 8 obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o 9 9 obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o 10 + obj-$(CONFIG_SUNXI_CCU_MULT) += ccu_mult.o 10 11 obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o 11 12 12 13 # Multi-factor clocks ··· 18 17 obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o 19 18 20 19 # SoC support 20 + obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o 21 + obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o 22 + obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o 21 23 obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
+1235
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
··· 1 + /* 2 + * Copyright (c) 2016 Chen-Yu Tsai 3 + * 4 + * Chen-Yu Tsai <wens@csie.org> 5 + * 6 + * Based on ccu-sun8i-h3.c by Maxime Ripard. 7 + * 8 + * This software is licensed under the terms of the GNU General Public 9 + * License version 2, as published by the Free Software Foundation, and 10 + * may be copied, distributed, and modified under those terms. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/clk-provider.h> 19 + #include <linux/of_address.h> 20 + 21 + #include "ccu_common.h" 22 + #include "ccu_reset.h" 23 + 24 + #include "ccu_div.h" 25 + #include "ccu_gate.h" 26 + #include "ccu_mp.h" 27 + #include "ccu_mult.h" 28 + #include "ccu_mux.h" 29 + #include "ccu_nk.h" 30 + #include "ccu_nkm.h" 31 + #include "ccu_nkmp.h" 32 + #include "ccu_nm.h" 33 + #include "ccu_phase.h" 34 + 35 + #include "ccu-sun6i-a31.h" 36 + 37 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu", 38 + "osc24M", 0x000, 39 + 8, 5, /* N */ 40 + 4, 2, /* K */ 41 + 0, 2, /* M */ 42 + BIT(31), /* gate */ 43 + BIT(28), /* lock */ 44 + 0); 45 + 46 + /* 47 + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from 48 + * the base (2x, 4x and 8x), and one variable divider (the one true 49 + * pll audio). 50 + * 51 + * We don't have any need for the variable divider for now, so we just 52 + * hardcode it to match with the clock names 53 + */ 54 + #define SUN6I_A31_PLL_AUDIO_REG 0x008 55 + 56 + static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", 57 + "osc24M", 0x008, 58 + 8, 7, /* N */ 59 + 0, 5, /* M */ 60 + BIT(31), /* gate */ 61 + BIT(28), /* lock */ 62 + 0); 63 + 64 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", 65 + "osc24M", 0x010, 66 + 8, 7, /* N */ 67 + 0, 4, /* M */ 68 + BIT(24), /* frac enable */ 69 + BIT(25), /* frac select */ 70 + 270000000, /* frac rate 0 */ 71 + 297000000, /* frac rate 1 */ 72 + BIT(31), /* gate */ 73 + BIT(28), /* lock */ 74 + 0); 75 + 76 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", 77 + "osc24M", 0x018, 78 + 8, 7, /* N */ 79 + 0, 4, /* M */ 80 + BIT(24), /* frac enable */ 81 + BIT(25), /* frac select */ 82 + 270000000, /* frac rate 0 */ 83 + 297000000, /* frac rate 1 */ 84 + BIT(31), /* gate */ 85 + BIT(28), /* lock */ 86 + 0); 87 + 88 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr", 89 + "osc24M", 0x020, 90 + 8, 5, /* N */ 91 + 4, 2, /* K */ 92 + 0, 2, /* M */ 93 + BIT(31), /* gate */ 94 + BIT(28), /* lock */ 95 + 0); 96 + 97 + static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph", 98 + "osc24M", 0x028, 99 + 8, 5, /* N */ 100 + 4, 2, /* K */ 101 + BIT(31), /* gate */ 102 + BIT(28), /* lock */ 103 + 2, /* post-div */ 104 + 0); 105 + 106 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", 107 + "osc24M", 0x030, 108 + 8, 7, /* N */ 109 + 0, 4, /* M */ 110 + BIT(24), /* frac enable */ 111 + BIT(25), /* frac select */ 112 + 270000000, /* frac rate 0 */ 113 + 297000000, /* frac rate 1 */ 114 + BIT(31), /* gate */ 115 + BIT(28), /* lock */ 116 + 0); 117 + 118 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", 119 + "osc24M", 0x038, 120 + 8, 7, /* N */ 121 + 0, 4, /* M */ 122 + BIT(24), /* frac enable */ 123 + BIT(25), /* frac select */ 124 + 270000000, /* frac rate 0 */ 125 + 297000000, /* frac rate 1 */ 126 + BIT(31), /* gate */ 127 + BIT(28), /* lock */ 128 + 0); 129 + 130 + /* 131 + * The MIPI PLL has 2 modes: "MIPI" and "HDMI". 132 + * 133 + * The MIPI mode is a standard NKM-style clock. The HDMI mode is an 134 + * integer / fractional clock with switchable multipliers and dividers. 135 + * This is not supported here. We hardcode the PLL to MIPI mode. 136 + */ 137 + #define SUN6I_A31_PLL_MIPI_REG 0x040 138 + 139 + static const char * const pll_mipi_parents[] = { "pll-video0", "pll-video1" }; 140 + static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(pll_mipi_clk, "pll-mipi", 141 + pll_mipi_parents, 0x040, 142 + 8, 4, /* N */ 143 + 4, 2, /* K */ 144 + 0, 4, /* M */ 145 + 21, 0, /* mux */ 146 + BIT(31), /* gate */ 147 + BIT(28), /* lock */ 148 + 0); 149 + 150 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll9_clk, "pll9", 151 + "osc24M", 0x044, 152 + 8, 7, /* N */ 153 + 0, 4, /* M */ 154 + BIT(24), /* frac enable */ 155 + BIT(25), /* frac select */ 156 + 270000000, /* frac rate 0 */ 157 + 297000000, /* frac rate 1 */ 158 + BIT(31), /* gate */ 159 + BIT(28), /* lock */ 160 + 0); 161 + 162 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll10_clk, "pll10", 163 + "osc24M", 0x048, 164 + 8, 7, /* N */ 165 + 0, 4, /* M */ 166 + BIT(24), /* frac enable */ 167 + BIT(25), /* frac select */ 168 + 270000000, /* frac rate 0 */ 169 + 297000000, /* frac rate 1 */ 170 + BIT(31), /* gate */ 171 + BIT(28), /* lock */ 172 + 0); 173 + 174 + static const char * const cpux_parents[] = { "osc32k", "osc24M", 175 + "pll-cpu", "pll-cpu" }; 176 + static SUNXI_CCU_MUX(cpu_clk, "cpu", cpux_parents, 177 + 0x050, 16, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL); 178 + 179 + static struct clk_div_table axi_div_table[] = { 180 + { .val = 0, .div = 1 }, 181 + { .val = 1, .div = 2 }, 182 + { .val = 2, .div = 3 }, 183 + { .val = 3, .div = 4 }, 184 + { .val = 4, .div = 4 }, 185 + { .val = 5, .div = 4 }, 186 + { .val = 6, .div = 4 }, 187 + { .val = 7, .div = 4 }, 188 + { /* Sentinel */ }, 189 + }; 190 + 191 + static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu", 192 + 0x050, 0, 3, axi_div_table, 0); 193 + 194 + static const char * const ahb1_parents[] = { "osc32k", "osc24M", 195 + "axi", "pll-periph" }; 196 + 197 + static struct ccu_div ahb1_clk = { 198 + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), 199 + 200 + .mux = { 201 + .shift = 12, 202 + .width = 2, 203 + 204 + .variable_prediv = { 205 + .index = 3, 206 + .shift = 6, 207 + .width = 2, 208 + }, 209 + }, 210 + 211 + .common = { 212 + .reg = 0x054, 213 + .features = CCU_FEATURE_VARIABLE_PREDIV, 214 + .hw.init = CLK_HW_INIT_PARENTS("ahb1", 215 + ahb1_parents, 216 + &ccu_div_ops, 217 + 0), 218 + }, 219 + }; 220 + 221 + static struct clk_div_table apb1_div_table[] = { 222 + { .val = 0, .div = 2 }, 223 + { .val = 1, .div = 2 }, 224 + { .val = 2, .div = 4 }, 225 + { .val = 3, .div = 8 }, 226 + { /* Sentinel */ }, 227 + }; 228 + 229 + static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", 230 + 0x054, 8, 2, apb1_div_table, 0); 231 + 232 + static const char * const apb2_parents[] = { "osc32k", "osc24M", 233 + "pll-periph", "pll-periph" }; 234 + static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, 235 + 0, 5, /* M */ 236 + 16, 2, /* P */ 237 + 24, 2, /* mux */ 238 + 0); 239 + 240 + static SUNXI_CCU_GATE(ahb1_mipidsi_clk, "ahb1-mipidsi", "ahb1", 241 + 0x060, BIT(1), 0); 242 + static SUNXI_CCU_GATE(ahb1_ss_clk, "ahb1-ss", "ahb1", 243 + 0x060, BIT(5), 0); 244 + static SUNXI_CCU_GATE(ahb1_dma_clk, "ahb1-dma", "ahb1", 245 + 0x060, BIT(6), 0); 246 + static SUNXI_CCU_GATE(ahb1_mmc0_clk, "ahb1-mmc0", "ahb1", 247 + 0x060, BIT(8), 0); 248 + static SUNXI_CCU_GATE(ahb1_mmc1_clk, "ahb1-mmc1", "ahb1", 249 + 0x060, BIT(9), 0); 250 + static SUNXI_CCU_GATE(ahb1_mmc2_clk, "ahb1-mmc2", "ahb1", 251 + 0x060, BIT(10), 0); 252 + static SUNXI_CCU_GATE(ahb1_mmc3_clk, "ahb1-mmc3", "ahb1", 253 + 0x060, BIT(12), 0); 254 + static SUNXI_CCU_GATE(ahb1_nand1_clk, "ahb1-nand1", "ahb1", 255 + 0x060, BIT(13), 0); 256 + static SUNXI_CCU_GATE(ahb1_nand0_clk, "ahb1-nand0", "ahb1", 257 + 0x060, BIT(13), 0); 258 + static SUNXI_CCU_GATE(ahb1_sdram_clk, "ahb1-sdram", "ahb1", 259 + 0x060, BIT(14), 0); 260 + static SUNXI_CCU_GATE(ahb1_emac_clk, "ahb1-emac", "ahb1", 261 + 0x060, BIT(17), 0); 262 + static SUNXI_CCU_GATE(ahb1_ts_clk, "ahb1-ts", "ahb1", 263 + 0x060, BIT(18), 0); 264 + static SUNXI_CCU_GATE(ahb1_hstimer_clk, "ahb1-hstimer", "ahb1", 265 + 0x060, BIT(19), 0); 266 + static SUNXI_CCU_GATE(ahb1_spi0_clk, "ahb1-spi0", "ahb1", 267 + 0x060, BIT(20), 0); 268 + static SUNXI_CCU_GATE(ahb1_spi1_clk, "ahb1-spi1", "ahb1", 269 + 0x060, BIT(21), 0); 270 + static SUNXI_CCU_GATE(ahb1_spi2_clk, "ahb1-spi2", "ahb1", 271 + 0x060, BIT(22), 0); 272 + static SUNXI_CCU_GATE(ahb1_spi3_clk, "ahb1-spi3", "ahb1", 273 + 0x060, BIT(23), 0); 274 + static SUNXI_CCU_GATE(ahb1_otg_clk, "ahb1-otg", "ahb1", 275 + 0x060, BIT(24), 0); 276 + static SUNXI_CCU_GATE(ahb1_ehci0_clk, "ahb1-ehci0", "ahb1", 277 + 0x060, BIT(26), 0); 278 + static SUNXI_CCU_GATE(ahb1_ehci1_clk, "ahb1-ehci1", "ahb1", 279 + 0x060, BIT(27), 0); 280 + static SUNXI_CCU_GATE(ahb1_ohci0_clk, "ahb1-ohci0", "ahb1", 281 + 0x060, BIT(29), 0); 282 + static SUNXI_CCU_GATE(ahb1_ohci1_clk, "ahb1-ohci1", "ahb1", 283 + 0x060, BIT(30), 0); 284 + static SUNXI_CCU_GATE(ahb1_ohci2_clk, "ahb1-ohci2", "ahb1", 285 + 0x060, BIT(31), 0); 286 + 287 + static SUNXI_CCU_GATE(ahb1_ve_clk, "ahb1-ve", "ahb1", 288 + 0x064, BIT(0), 0); 289 + static SUNXI_CCU_GATE(ahb1_lcd0_clk, "ahb1-lcd0", "ahb1", 290 + 0x064, BIT(4), 0); 291 + static SUNXI_CCU_GATE(ahb1_lcd1_clk, "ahb1-lcd1", "ahb1", 292 + 0x064, BIT(5), 0); 293 + static SUNXI_CCU_GATE(ahb1_csi_clk, "ahb1-csi", "ahb1", 294 + 0x064, BIT(8), 0); 295 + static SUNXI_CCU_GATE(ahb1_hdmi_clk, "ahb1-hdmi", "ahb1", 296 + 0x064, BIT(11), 0); 297 + static SUNXI_CCU_GATE(ahb1_be0_clk, "ahb1-be0", "ahb1", 298 + 0x064, BIT(12), 0); 299 + static SUNXI_CCU_GATE(ahb1_be1_clk, "ahb1-be1", "ahb1", 300 + 0x064, BIT(13), 0); 301 + static SUNXI_CCU_GATE(ahb1_fe0_clk, "ahb1-fe0", "ahb1", 302 + 0x064, BIT(14), 0); 303 + static SUNXI_CCU_GATE(ahb1_fe1_clk, "ahb1-fe1", "ahb1", 304 + 0x064, BIT(15), 0); 305 + static SUNXI_CCU_GATE(ahb1_mp_clk, "ahb1-mp", "ahb1", 306 + 0x064, BIT(18), 0); 307 + static SUNXI_CCU_GATE(ahb1_gpu_clk, "ahb1-gpu", "ahb1", 308 + 0x064, BIT(20), 0); 309 + static SUNXI_CCU_GATE(ahb1_deu0_clk, "ahb1-deu0", "ahb1", 310 + 0x064, BIT(23), 0); 311 + static SUNXI_CCU_GATE(ahb1_deu1_clk, "ahb1-deu1", "ahb1", 312 + 0x064, BIT(24), 0); 313 + static SUNXI_CCU_GATE(ahb1_drc0_clk, "ahb1-drc0", "ahb1", 314 + 0x064, BIT(25), 0); 315 + static SUNXI_CCU_GATE(ahb1_drc1_clk, "ahb1-drc1", "ahb1", 316 + 0x064, BIT(26), 0); 317 + 318 + static SUNXI_CCU_GATE(apb1_codec_clk, "apb1-codec", "apb1", 319 + 0x068, BIT(0), 0); 320 + static SUNXI_CCU_GATE(apb1_spdif_clk, "apb1-spdif", "apb1", 321 + 0x068, BIT(1), 0); 322 + static SUNXI_CCU_GATE(apb1_digital_mic_clk, "apb1-digital-mic", "apb1", 323 + 0x068, BIT(4), 0); 324 + static SUNXI_CCU_GATE(apb1_pio_clk, "apb1-pio", "apb1", 325 + 0x068, BIT(5), 0); 326 + static SUNXI_CCU_GATE(apb1_daudio0_clk, "apb1-daudio0", "apb1", 327 + 0x068, BIT(12), 0); 328 + static SUNXI_CCU_GATE(apb1_daudio1_clk, "apb1-daudio1", "apb1", 329 + 0x068, BIT(13), 0); 330 + 331 + static SUNXI_CCU_GATE(apb2_i2c0_clk, "apb2-i2c0", "apb2", 332 + 0x06c, BIT(0), 0); 333 + static SUNXI_CCU_GATE(apb2_i2c1_clk, "apb2-i2c1", "apb2", 334 + 0x06c, BIT(1), 0); 335 + static SUNXI_CCU_GATE(apb2_i2c2_clk, "apb2-i2c2", "apb2", 336 + 0x06c, BIT(2), 0); 337 + static SUNXI_CCU_GATE(apb2_i2c3_clk, "apb2-i2c3", "apb2", 338 + 0x06c, BIT(3), 0); 339 + static SUNXI_CCU_GATE(apb2_uart0_clk, "apb2-uart0", "apb2", 340 + 0x06c, BIT(16), 0); 341 + static SUNXI_CCU_GATE(apb2_uart1_clk, "apb2-uart1", "apb2", 342 + 0x06c, BIT(17), 0); 343 + static SUNXI_CCU_GATE(apb2_uart2_clk, "apb2-uart2", "apb2", 344 + 0x06c, BIT(18), 0); 345 + static SUNXI_CCU_GATE(apb2_uart3_clk, "apb2-uart3", "apb2", 346 + 0x06c, BIT(19), 0); 347 + static SUNXI_CCU_GATE(apb2_uart4_clk, "apb2-uart4", "apb2", 348 + 0x06c, BIT(20), 0); 349 + static SUNXI_CCU_GATE(apb2_uart5_clk, "apb2-uart5", "apb2", 350 + 0x06c, BIT(21), 0); 351 + 352 + static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; 353 + static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", mod0_default_parents, 354 + 0x080, 355 + 0, 4, /* M */ 356 + 16, 2, /* P */ 357 + 24, 2, /* mux */ 358 + BIT(31), /* gate */ 359 + 0); 360 + 361 + static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", mod0_default_parents, 362 + 0x084, 363 + 0, 4, /* M */ 364 + 16, 2, /* P */ 365 + 24, 2, /* mux */ 366 + BIT(31), /* gate */ 367 + 0); 368 + 369 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 370 + 0x088, 371 + 0, 4, /* M */ 372 + 16, 2, /* P */ 373 + 24, 2, /* mux */ 374 + BIT(31), /* gate */ 375 + 0); 376 + 377 + static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", 378 + 0x088, 20, 3, 0); 379 + static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", 380 + 0x088, 8, 3, 0); 381 + 382 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 383 + 0x08c, 384 + 0, 4, /* M */ 385 + 16, 2, /* P */ 386 + 24, 2, /* mux */ 387 + BIT(31), /* gate */ 388 + 0); 389 + 390 + static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", 391 + 0x08c, 20, 3, 0); 392 + static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", 393 + 0x08c, 8, 3, 0); 394 + 395 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 396 + 0x090, 397 + 0, 4, /* M */ 398 + 16, 2, /* P */ 399 + 24, 2, /* mux */ 400 + BIT(31), /* gate */ 401 + 0); 402 + 403 + static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", 404 + 0x090, 20, 3, 0); 405 + static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", 406 + 0x090, 8, 3, 0); 407 + 408 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 409 + 0x094, 410 + 0, 4, /* M */ 411 + 16, 2, /* P */ 412 + 24, 2, /* mux */ 413 + BIT(31), /* gate */ 414 + 0); 415 + 416 + static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3", 417 + 0x094, 20, 3, 0); 418 + static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3", 419 + 0x094, 8, 3, 0); 420 + 421 + static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098, 422 + 0, 4, /* M */ 423 + 16, 2, /* P */ 424 + 24, 2, /* mux */ 425 + BIT(31), /* gate */ 426 + 0); 427 + 428 + static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c, 429 + 0, 4, /* M */ 430 + 16, 2, /* P */ 431 + 24, 2, /* mux */ 432 + BIT(31), /* gate */ 433 + 0); 434 + 435 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, 436 + 0, 4, /* M */ 437 + 16, 2, /* P */ 438 + 24, 2, /* mux */ 439 + BIT(31), /* gate */ 440 + 0); 441 + 442 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, 443 + 0, 4, /* M */ 444 + 16, 2, /* P */ 445 + 24, 2, /* mux */ 446 + BIT(31), /* gate */ 447 + 0); 448 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8, 449 + 0, 4, /* M */ 450 + 16, 2, /* P */ 451 + 24, 2, /* mux */ 452 + BIT(31), /* gate */ 453 + 0); 454 + 455 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac, 456 + 0, 4, /* M */ 457 + 16, 2, /* P */ 458 + 24, 2, /* mux */ 459 + BIT(31), /* gate */ 460 + 0); 461 + 462 + static const char * const daudio_parents[] = { "pll-audio-8x", "pll-audio-4x", 463 + "pll-audio-2x", "pll-audio" }; 464 + static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents, 465 + 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 466 + static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents, 467 + 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 468 + 469 + static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio", 470 + 0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT); 471 + 472 + static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 473 + 0x0cc, BIT(8), 0); 474 + static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 475 + 0x0cc, BIT(9), 0); 476 + static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M", 477 + 0x0cc, BIT(10), 0); 478 + static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", 479 + 0x0cc, BIT(16), 0); 480 + static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc24M", 481 + 0x0cc, BIT(17), 0); 482 + static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", 483 + 0x0cc, BIT(18), 0); 484 + 485 + /* TODO emac clk not supported yet */ 486 + 487 + static const char * const dram_parents[] = { "pll-ddr", "pll-periph" }; 488 + static SUNXI_CCU_MP_WITH_MUX_GATE(mdfs_clk, "mdfs", dram_parents, 0x0f0, 489 + 0, 4, /* M */ 490 + 16, 2, /* P */ 491 + 24, 2, /* mux */ 492 + BIT(31), /* gate */ 493 + CLK_IS_CRITICAL); 494 + 495 + static SUNXI_CCU_M_WITH_MUX(sdram0_clk, "sdram0", dram_parents, 496 + 0x0f4, 0, 4, 4, 1, CLK_IS_CRITICAL); 497 + static SUNXI_CCU_M_WITH_MUX(sdram1_clk, "sdram1", dram_parents, 498 + 0x0f4, 8, 4, 12, 1, CLK_IS_CRITICAL); 499 + 500 + static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "mdfs", 501 + 0x100, BIT(0), 0); 502 + static SUNXI_CCU_GATE(dram_csi_isp_clk, "dram-csi-isp", "mdfs", 503 + 0x100, BIT(1), 0); 504 + static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "mdfs", 505 + 0x100, BIT(3), 0); 506 + static SUNXI_CCU_GATE(dram_drc0_clk, "dram-drc0", "mdfs", 507 + 0x100, BIT(16), 0); 508 + static SUNXI_CCU_GATE(dram_drc1_clk, "dram-drc1", "mdfs", 509 + 0x100, BIT(17), 0); 510 + static SUNXI_CCU_GATE(dram_deu0_clk, "dram-deu0", "mdfs", 511 + 0x100, BIT(18), 0); 512 + static SUNXI_CCU_GATE(dram_deu1_clk, "dram-deu1", "mdfs", 513 + 0x100, BIT(19), 0); 514 + static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "mdfs", 515 + 0x100, BIT(24), 0); 516 + static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "mdfs", 517 + 0x100, BIT(25), 0); 518 + static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "mdfs", 519 + 0x100, BIT(26), 0); 520 + static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "mdfs", 521 + 0x100, BIT(27), 0); 522 + static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "mdfs", 523 + 0x100, BIT(28), 0); 524 + 525 + static const char * const de_parents[] = { "pll-video0", "pll-video1", 526 + "pll-periph-2x", "pll-gpu", 527 + "pll9", "pll10" }; 528 + static SUNXI_CCU_M_WITH_MUX_GATE(be0_clk, "be0", de_parents, 529 + 0x104, 0, 4, 24, 3, BIT(31), 0); 530 + static SUNXI_CCU_M_WITH_MUX_GATE(be1_clk, "be1", de_parents, 531 + 0x108, 0, 4, 24, 3, BIT(31), 0); 532 + static SUNXI_CCU_M_WITH_MUX_GATE(fe0_clk, "fe0", de_parents, 533 + 0x10c, 0, 4, 24, 3, BIT(31), 0); 534 + static SUNXI_CCU_M_WITH_MUX_GATE(fe1_clk, "fe1", de_parents, 535 + 0x110, 0, 4, 24, 3, BIT(31), 0); 536 + 537 + static const char * const mp_parents[] = { "pll-video0", "pll-video1", 538 + "pll9", "pll10" }; 539 + static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", mp_parents, 540 + 0x114, 0, 4, 24, 3, BIT(31), 0); 541 + 542 + static const char * const lcd_ch0_parents[] = { "pll-video0", "pll-video1", 543 + "pll-video0-2x", 544 + "pll-video1-2x", "pll-mipi" }; 545 + static SUNXI_CCU_MUX_WITH_GATE(lcd0_ch0_clk, "lcd0-ch0", lcd_ch0_parents, 546 + 0x118, 24, 2, BIT(31), 0); 547 + static SUNXI_CCU_MUX_WITH_GATE(lcd1_ch0_clk, "lcd1-ch0", lcd_ch0_parents, 548 + 0x11c, 24, 2, BIT(31), 0); 549 + 550 + static const char * const lcd_ch1_parents[] = { "pll-video0", "pll-video1", 551 + "pll-video0-2x", 552 + "pll-video1-2x" }; 553 + static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents, 554 + 0x12c, 0, 4, 24, 3, BIT(31), 0); 555 + static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents, 556 + 0x12c, 0, 4, 24, 3, BIT(31), 0); 557 + 558 + static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1", 559 + "pll9", "pll10", "pll-mipi", 560 + "pll-ve" }; 561 + static SUNXI_CCU_M_WITH_MUX_GATE(csi0_sclk_clk, "csi0-sclk", csi_sclk_parents, 562 + 0x134, 16, 4, 24, 3, BIT(31), 0); 563 + 564 + static const char * const csi_mclk_parents[] = { "pll-video0", "pll-video1", 565 + "osc24M" }; 566 + static const u8 csi_mclk_table[] = { 0, 1, 5 }; 567 + static struct ccu_div csi0_mclk_clk = { 568 + .enable = BIT(15), 569 + .div = _SUNXI_CCU_DIV(0, 4), 570 + .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table), 571 + .common = { 572 + .reg = 0x134, 573 + .hw.init = CLK_HW_INIT_PARENTS("csi0-mclk", 574 + csi_mclk_parents, 575 + &ccu_div_ops, 576 + 0), 577 + }, 578 + }; 579 + 580 + static struct ccu_div csi1_mclk_clk = { 581 + .enable = BIT(15), 582 + .div = _SUNXI_CCU_DIV(0, 4), 583 + .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table), 584 + .common = { 585 + .reg = 0x138, 586 + .hw.init = CLK_HW_INIT_PARENTS("csi1-mclk", 587 + csi_mclk_parents, 588 + &ccu_div_ops, 589 + 0), 590 + }, 591 + }; 592 + 593 + static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 594 + 0x13c, 16, 3, BIT(31), 0); 595 + 596 + static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", 597 + 0x140, BIT(31), CLK_SET_RATE_PARENT); 598 + static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 599 + 0x144, BIT(31), 0); 600 + static SUNXI_CCU_GATE(digital_mic_clk, "digital-mic", "pll-audio", 601 + 0x148, BIT(31), CLK_SET_RATE_PARENT); 602 + 603 + static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents, 604 + 0x150, 0, 4, 24, 2, BIT(31), 0); 605 + 606 + static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(31), 0); 607 + 608 + static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0); 609 + 610 + static const char * const mbus_parents[] = { "osc24M", "pll-periph", 611 + "pll-ddr" }; 612 + static SUNXI_CCU_MP_WITH_MUX_GATE(mbus0_clk, "mbus0", mbus_parents, 0x15c, 613 + 0, 3, /* M */ 614 + 16, 2, /* P */ 615 + 24, 2, /* mux */ 616 + BIT(31), /* gate */ 617 + CLK_IS_CRITICAL); 618 + 619 + static SUNXI_CCU_MP_WITH_MUX_GATE(mbus1_clk, "mbus1", mbus_parents, 0x160, 620 + 0, 3, /* M */ 621 + 16, 2, /* P */ 622 + 24, 2, /* mux */ 623 + BIT(31), /* gate */ 624 + CLK_IS_CRITICAL); 625 + 626 + static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", lcd_ch1_parents, 627 + 0x168, 16, 3, 24, 2, BIT(31), 0); 628 + static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_dphy_clk, "mipi-dsi-dphy", 629 + lcd_ch1_parents, 0x168, 0, 3, 8, 2, 630 + BIT(15), 0); 631 + static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_dphy_clk, "mipi-csi-dphy", 632 + lcd_ch1_parents, 0x168, 0, 3, 8, 2, 633 + BIT(15), 0); 634 + 635 + static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc0_clk, "iep-drc0", de_parents, 636 + 0x180, 0, 3, 24, 2, BIT(31), 0); 637 + static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc1_clk, "iep-drc1", de_parents, 638 + 0x184, 0, 3, 24, 2, BIT(31), 0); 639 + static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu0_clk, "iep-deu0", de_parents, 640 + 0x188, 0, 3, 24, 2, BIT(31), 0); 641 + static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu1_clk, "iep-deu1", de_parents, 642 + 0x18c, 0, 3, 24, 2, BIT(31), 0); 643 + 644 + static const char * const gpu_parents[] = { "pll-gpu", "pll-periph-2x", 645 + "pll-video0", "pll-video1", 646 + "pll9", "pll10" }; 647 + static const struct ccu_mux_fixed_prediv gpu_predivs[] = { 648 + { .index = 1, .div = 3, }, 649 + }; 650 + 651 + static struct ccu_div gpu_core_clk = { 652 + .enable = BIT(31), 653 + .div = _SUNXI_CCU_DIV(0, 3), 654 + .mux = { 655 + .shift = 24, 656 + .width = 3, 657 + .fixed_predivs = gpu_predivs, 658 + .n_predivs = ARRAY_SIZE(gpu_predivs), 659 + }, 660 + .common = { 661 + .reg = 0x1a0, 662 + .features = CCU_FEATURE_FIXED_PREDIV, 663 + .hw.init = CLK_HW_INIT_PARENTS("gpu-core", 664 + gpu_parents, 665 + &ccu_div_ops, 666 + 0), 667 + }, 668 + }; 669 + 670 + static struct ccu_div gpu_memory_clk = { 671 + .enable = BIT(31), 672 + .div = _SUNXI_CCU_DIV(0, 3), 673 + .mux = { 674 + .shift = 24, 675 + .width = 3, 676 + .fixed_predivs = gpu_predivs, 677 + .n_predivs = ARRAY_SIZE(gpu_predivs), 678 + }, 679 + .common = { 680 + .reg = 0x1a4, 681 + .features = CCU_FEATURE_FIXED_PREDIV, 682 + .hw.init = CLK_HW_INIT_PARENTS("gpu-memory", 683 + gpu_parents, 684 + &ccu_div_ops, 685 + 0), 686 + }, 687 + }; 688 + 689 + static struct ccu_div gpu_hyd_clk = { 690 + .enable = BIT(31), 691 + .div = _SUNXI_CCU_DIV(0, 3), 692 + .mux = { 693 + .shift = 24, 694 + .width = 3, 695 + .fixed_predivs = gpu_predivs, 696 + .n_predivs = ARRAY_SIZE(gpu_predivs), 697 + }, 698 + .common = { 699 + .reg = 0x1a8, 700 + .features = CCU_FEATURE_FIXED_PREDIV, 701 + .hw.init = CLK_HW_INIT_PARENTS("gpu-hyd", 702 + gpu_parents, 703 + &ccu_div_ops, 704 + 0), 705 + }, 706 + }; 707 + 708 + static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", mod0_default_parents, 0x1b0, 709 + 0, 3, /* M */ 710 + 24, 2, /* mux */ 711 + BIT(31), /* gate */ 712 + 0); 713 + 714 + static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", mod0_default_parents, 715 + 0x1b0, 716 + 0, 3, /* M */ 717 + 24, 2, /* mux */ 718 + BIT(31), /* gate */ 719 + 0); 720 + 721 + static const char * const clk_out_parents[] = { "osc24M", "osc32k", "osc24M", 722 + "axi", "ahb1" }; 723 + static const u8 clk_out_table[] = { 0, 1, 2, 11, 13 }; 724 + 725 + static const struct ccu_mux_fixed_prediv clk_out_predivs[] = { 726 + { .index = 0, .div = 750, }, 727 + { .index = 3, .div = 4, }, 728 + { .index = 4, .div = 4, }, 729 + }; 730 + 731 + static struct ccu_mp out_a_clk = { 732 + .enable = BIT(31), 733 + .m = _SUNXI_CCU_DIV(8, 5), 734 + .p = _SUNXI_CCU_DIV(20, 2), 735 + .mux = { 736 + .shift = 24, 737 + .width = 4, 738 + .table = clk_out_table, 739 + .fixed_predivs = clk_out_predivs, 740 + .n_predivs = ARRAY_SIZE(clk_out_predivs), 741 + }, 742 + .common = { 743 + .reg = 0x300, 744 + .features = CCU_FEATURE_FIXED_PREDIV, 745 + .hw.init = CLK_HW_INIT_PARENTS("out-a", 746 + clk_out_parents, 747 + &ccu_div_ops, 748 + 0), 749 + }, 750 + }; 751 + 752 + static struct ccu_mp out_b_clk = { 753 + .enable = BIT(31), 754 + .m = _SUNXI_CCU_DIV(8, 5), 755 + .p = _SUNXI_CCU_DIV(20, 2), 756 + .mux = { 757 + .shift = 24, 758 + .width = 4, 759 + .table = clk_out_table, 760 + .fixed_predivs = clk_out_predivs, 761 + .n_predivs = ARRAY_SIZE(clk_out_predivs), 762 + }, 763 + .common = { 764 + .reg = 0x304, 765 + .features = CCU_FEATURE_FIXED_PREDIV, 766 + .hw.init = CLK_HW_INIT_PARENTS("out-b", 767 + clk_out_parents, 768 + &ccu_div_ops, 769 + 0), 770 + }, 771 + }; 772 + 773 + static struct ccu_mp out_c_clk = { 774 + .enable = BIT(31), 775 + .m = _SUNXI_CCU_DIV(8, 5), 776 + .p = _SUNXI_CCU_DIV(20, 2), 777 + .mux = { 778 + .shift = 24, 779 + .width = 4, 780 + .table = clk_out_table, 781 + .fixed_predivs = clk_out_predivs, 782 + .n_predivs = ARRAY_SIZE(clk_out_predivs), 783 + }, 784 + .common = { 785 + .reg = 0x308, 786 + .features = CCU_FEATURE_FIXED_PREDIV, 787 + .hw.init = CLK_HW_INIT_PARENTS("out-c", 788 + clk_out_parents, 789 + &ccu_div_ops, 790 + 0), 791 + }, 792 + }; 793 + 794 + static struct ccu_common *sun6i_a31_ccu_clks[] = { 795 + &pll_cpu_clk.common, 796 + &pll_audio_base_clk.common, 797 + &pll_video0_clk.common, 798 + &pll_ve_clk.common, 799 + &pll_ddr_clk.common, 800 + &pll_periph_clk.common, 801 + &pll_video1_clk.common, 802 + &pll_gpu_clk.common, 803 + &pll_mipi_clk.common, 804 + &pll9_clk.common, 805 + &pll10_clk.common, 806 + &cpu_clk.common, 807 + &axi_clk.common, 808 + &ahb1_clk.common, 809 + &apb1_clk.common, 810 + &apb2_clk.common, 811 + &ahb1_mipidsi_clk.common, 812 + &ahb1_ss_clk.common, 813 + &ahb1_dma_clk.common, 814 + &ahb1_mmc0_clk.common, 815 + &ahb1_mmc1_clk.common, 816 + &ahb1_mmc2_clk.common, 817 + &ahb1_mmc3_clk.common, 818 + &ahb1_nand1_clk.common, 819 + &ahb1_nand0_clk.common, 820 + &ahb1_sdram_clk.common, 821 + &ahb1_emac_clk.common, 822 + &ahb1_ts_clk.common, 823 + &ahb1_hstimer_clk.common, 824 + &ahb1_spi0_clk.common, 825 + &ahb1_spi1_clk.common, 826 + &ahb1_spi2_clk.common, 827 + &ahb1_spi3_clk.common, 828 + &ahb1_otg_clk.common, 829 + &ahb1_ehci0_clk.common, 830 + &ahb1_ehci1_clk.common, 831 + &ahb1_ohci0_clk.common, 832 + &ahb1_ohci1_clk.common, 833 + &ahb1_ohci2_clk.common, 834 + &ahb1_ve_clk.common, 835 + &ahb1_lcd0_clk.common, 836 + &ahb1_lcd1_clk.common, 837 + &ahb1_csi_clk.common, 838 + &ahb1_hdmi_clk.common, 839 + &ahb1_be0_clk.common, 840 + &ahb1_be1_clk.common, 841 + &ahb1_fe0_clk.common, 842 + &ahb1_fe1_clk.common, 843 + &ahb1_mp_clk.common, 844 + &ahb1_gpu_clk.common, 845 + &ahb1_deu0_clk.common, 846 + &ahb1_deu1_clk.common, 847 + &ahb1_drc0_clk.common, 848 + &ahb1_drc1_clk.common, 849 + &apb1_codec_clk.common, 850 + &apb1_spdif_clk.common, 851 + &apb1_digital_mic_clk.common, 852 + &apb1_pio_clk.common, 853 + &apb1_daudio0_clk.common, 854 + &apb1_daudio1_clk.common, 855 + &apb2_i2c0_clk.common, 856 + &apb2_i2c1_clk.common, 857 + &apb2_i2c2_clk.common, 858 + &apb2_i2c3_clk.common, 859 + &apb2_uart0_clk.common, 860 + &apb2_uart1_clk.common, 861 + &apb2_uart2_clk.common, 862 + &apb2_uart3_clk.common, 863 + &apb2_uart4_clk.common, 864 + &apb2_uart5_clk.common, 865 + &nand0_clk.common, 866 + &nand1_clk.common, 867 + &mmc0_clk.common, 868 + &mmc0_sample_clk.common, 869 + &mmc0_output_clk.common, 870 + &mmc1_clk.common, 871 + &mmc1_sample_clk.common, 872 + &mmc1_output_clk.common, 873 + &mmc2_clk.common, 874 + &mmc2_sample_clk.common, 875 + &mmc2_output_clk.common, 876 + &mmc3_clk.common, 877 + &mmc3_sample_clk.common, 878 + &mmc3_output_clk.common, 879 + &ts_clk.common, 880 + &ss_clk.common, 881 + &spi0_clk.common, 882 + &spi1_clk.common, 883 + &spi2_clk.common, 884 + &spi3_clk.common, 885 + &daudio0_clk.common, 886 + &daudio1_clk.common, 887 + &spdif_clk.common, 888 + &usb_phy0_clk.common, 889 + &usb_phy1_clk.common, 890 + &usb_phy2_clk.common, 891 + &usb_ohci0_clk.common, 892 + &usb_ohci1_clk.common, 893 + &usb_ohci2_clk.common, 894 + &mdfs_clk.common, 895 + &sdram0_clk.common, 896 + &sdram1_clk.common, 897 + &dram_ve_clk.common, 898 + &dram_csi_isp_clk.common, 899 + &dram_ts_clk.common, 900 + &dram_drc0_clk.common, 901 + &dram_drc1_clk.common, 902 + &dram_deu0_clk.common, 903 + &dram_deu1_clk.common, 904 + &dram_fe0_clk.common, 905 + &dram_fe1_clk.common, 906 + &dram_be0_clk.common, 907 + &dram_be1_clk.common, 908 + &dram_mp_clk.common, 909 + &be0_clk.common, 910 + &be1_clk.common, 911 + &fe0_clk.common, 912 + &fe1_clk.common, 913 + &mp_clk.common, 914 + &lcd0_ch0_clk.common, 915 + &lcd1_ch0_clk.common, 916 + &lcd0_ch1_clk.common, 917 + &lcd1_ch1_clk.common, 918 + &csi0_sclk_clk.common, 919 + &csi0_mclk_clk.common, 920 + &csi1_mclk_clk.common, 921 + &ve_clk.common, 922 + &codec_clk.common, 923 + &avs_clk.common, 924 + &digital_mic_clk.common, 925 + &hdmi_clk.common, 926 + &hdmi_ddc_clk.common, 927 + &ps_clk.common, 928 + &mbus0_clk.common, 929 + &mbus1_clk.common, 930 + &mipi_dsi_clk.common, 931 + &mipi_dsi_dphy_clk.common, 932 + &mipi_csi_dphy_clk.common, 933 + &iep_drc0_clk.common, 934 + &iep_drc1_clk.common, 935 + &iep_deu0_clk.common, 936 + &iep_deu1_clk.common, 937 + &gpu_core_clk.common, 938 + &gpu_memory_clk.common, 939 + &gpu_hyd_clk.common, 940 + &ats_clk.common, 941 + &trace_clk.common, 942 + &out_a_clk.common, 943 + &out_b_clk.common, 944 + &out_c_clk.common, 945 + }; 946 + 947 + /* We hardcode the divider to 4 for now */ 948 + static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", 949 + "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); 950 + static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 951 + "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 952 + static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", 953 + "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 954 + static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", 955 + "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); 956 + static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", 957 + "pll-periph", 1, 2, 0); 958 + static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", 959 + "pll-video0", 1, 2, 0); 960 + static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", 961 + "pll-video1", 1, 2, 0); 962 + 963 + static struct clk_hw_onecell_data sun6i_a31_hw_clks = { 964 + .hws = { 965 + [CLK_PLL_CPU] = &pll_cpu_clk.common.hw, 966 + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, 967 + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, 968 + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, 969 + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, 970 + [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, 971 + [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, 972 + [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, 973 + [CLK_PLL_VE] = &pll_ve_clk.common.hw, 974 + [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, 975 + [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, 976 + [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw, 977 + [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, 978 + [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, 979 + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, 980 + [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, 981 + [CLK_PLL9] = &pll9_clk.common.hw, 982 + [CLK_PLL10] = &pll10_clk.common.hw, 983 + [CLK_CPU] = &cpu_clk.common.hw, 984 + [CLK_AXI] = &axi_clk.common.hw, 985 + [CLK_AHB1] = &ahb1_clk.common.hw, 986 + [CLK_APB1] = &apb1_clk.common.hw, 987 + [CLK_APB2] = &apb2_clk.common.hw, 988 + [CLK_AHB1_MIPIDSI] = &ahb1_mipidsi_clk.common.hw, 989 + [CLK_AHB1_SS] = &ahb1_ss_clk.common.hw, 990 + [CLK_AHB1_DMA] = &ahb1_dma_clk.common.hw, 991 + [CLK_AHB1_MMC0] = &ahb1_mmc0_clk.common.hw, 992 + [CLK_AHB1_MMC1] = &ahb1_mmc1_clk.common.hw, 993 + [CLK_AHB1_MMC2] = &ahb1_mmc2_clk.common.hw, 994 + [CLK_AHB1_MMC3] = &ahb1_mmc3_clk.common.hw, 995 + [CLK_AHB1_NAND1] = &ahb1_nand1_clk.common.hw, 996 + [CLK_AHB1_NAND0] = &ahb1_nand0_clk.common.hw, 997 + [CLK_AHB1_SDRAM] = &ahb1_sdram_clk.common.hw, 998 + [CLK_AHB1_EMAC] = &ahb1_emac_clk.common.hw, 999 + [CLK_AHB1_TS] = &ahb1_ts_clk.common.hw, 1000 + [CLK_AHB1_HSTIMER] = &ahb1_hstimer_clk.common.hw, 1001 + [CLK_AHB1_SPI0] = &ahb1_spi0_clk.common.hw, 1002 + [CLK_AHB1_SPI1] = &ahb1_spi1_clk.common.hw, 1003 + [CLK_AHB1_SPI2] = &ahb1_spi2_clk.common.hw, 1004 + [CLK_AHB1_SPI3] = &ahb1_spi3_clk.common.hw, 1005 + [CLK_AHB1_OTG] = &ahb1_otg_clk.common.hw, 1006 + [CLK_AHB1_EHCI0] = &ahb1_ehci0_clk.common.hw, 1007 + [CLK_AHB1_EHCI1] = &ahb1_ehci1_clk.common.hw, 1008 + [CLK_AHB1_OHCI0] = &ahb1_ohci0_clk.common.hw, 1009 + [CLK_AHB1_OHCI1] = &ahb1_ohci1_clk.common.hw, 1010 + [CLK_AHB1_OHCI2] = &ahb1_ohci2_clk.common.hw, 1011 + [CLK_AHB1_VE] = &ahb1_ve_clk.common.hw, 1012 + [CLK_AHB1_LCD0] = &ahb1_lcd0_clk.common.hw, 1013 + [CLK_AHB1_LCD1] = &ahb1_lcd1_clk.common.hw, 1014 + [CLK_AHB1_CSI] = &ahb1_csi_clk.common.hw, 1015 + [CLK_AHB1_HDMI] = &ahb1_hdmi_clk.common.hw, 1016 + [CLK_AHB1_BE0] = &ahb1_be0_clk.common.hw, 1017 + [CLK_AHB1_BE1] = &ahb1_be1_clk.common.hw, 1018 + [CLK_AHB1_FE0] = &ahb1_fe0_clk.common.hw, 1019 + [CLK_AHB1_FE1] = &ahb1_fe1_clk.common.hw, 1020 + [CLK_AHB1_MP] = &ahb1_mp_clk.common.hw, 1021 + [CLK_AHB1_GPU] = &ahb1_gpu_clk.common.hw, 1022 + [CLK_AHB1_DEU0] = &ahb1_deu0_clk.common.hw, 1023 + [CLK_AHB1_DEU1] = &ahb1_deu1_clk.common.hw, 1024 + [CLK_AHB1_DRC0] = &ahb1_drc0_clk.common.hw, 1025 + [CLK_AHB1_DRC1] = &ahb1_drc1_clk.common.hw, 1026 + [CLK_APB1_CODEC] = &apb1_codec_clk.common.hw, 1027 + [CLK_APB1_SPDIF] = &apb1_spdif_clk.common.hw, 1028 + [CLK_APB1_DIGITAL_MIC] = &apb1_digital_mic_clk.common.hw, 1029 + [CLK_APB1_PIO] = &apb1_pio_clk.common.hw, 1030 + [CLK_APB1_DAUDIO0] = &apb1_daudio0_clk.common.hw, 1031 + [CLK_APB1_DAUDIO1] = &apb1_daudio1_clk.common.hw, 1032 + [CLK_APB2_I2C0] = &apb2_i2c0_clk.common.hw, 1033 + [CLK_APB2_I2C1] = &apb2_i2c1_clk.common.hw, 1034 + [CLK_APB2_I2C2] = &apb2_i2c2_clk.common.hw, 1035 + [CLK_APB2_I2C3] = &apb2_i2c3_clk.common.hw, 1036 + [CLK_APB2_UART0] = &apb2_uart0_clk.common.hw, 1037 + [CLK_APB2_UART1] = &apb2_uart1_clk.common.hw, 1038 + [CLK_APB2_UART2] = &apb2_uart2_clk.common.hw, 1039 + [CLK_APB2_UART3] = &apb2_uart3_clk.common.hw, 1040 + [CLK_APB2_UART4] = &apb2_uart4_clk.common.hw, 1041 + [CLK_APB2_UART5] = &apb2_uart5_clk.common.hw, 1042 + [CLK_NAND0] = &nand0_clk.common.hw, 1043 + [CLK_NAND1] = &nand1_clk.common.hw, 1044 + [CLK_MMC0] = &mmc0_clk.common.hw, 1045 + [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, 1046 + [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, 1047 + [CLK_MMC1] = &mmc1_clk.common.hw, 1048 + [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, 1049 + [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, 1050 + [CLK_MMC2] = &mmc2_clk.common.hw, 1051 + [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, 1052 + [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, 1053 + [CLK_MMC3] = &mmc3_clk.common.hw, 1054 + [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw, 1055 + [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw, 1056 + [CLK_TS] = &ts_clk.common.hw, 1057 + [CLK_SS] = &ss_clk.common.hw, 1058 + [CLK_SPI0] = &spi0_clk.common.hw, 1059 + [CLK_SPI1] = &spi1_clk.common.hw, 1060 + [CLK_SPI2] = &spi2_clk.common.hw, 1061 + [CLK_SPI3] = &spi3_clk.common.hw, 1062 + [CLK_DAUDIO0] = &daudio0_clk.common.hw, 1063 + [CLK_DAUDIO1] = &daudio1_clk.common.hw, 1064 + [CLK_SPDIF] = &spdif_clk.common.hw, 1065 + [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, 1066 + [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, 1067 + [CLK_USB_PHY2] = &usb_phy2_clk.common.hw, 1068 + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, 1069 + [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, 1070 + [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, 1071 + [CLK_MDFS] = &mdfs_clk.common.hw, 1072 + [CLK_SDRAM0] = &sdram0_clk.common.hw, 1073 + [CLK_SDRAM1] = &sdram1_clk.common.hw, 1074 + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, 1075 + [CLK_DRAM_CSI_ISP] = &dram_csi_isp_clk.common.hw, 1076 + [CLK_DRAM_TS] = &dram_ts_clk.common.hw, 1077 + [CLK_DRAM_DRC0] = &dram_drc0_clk.common.hw, 1078 + [CLK_DRAM_DRC1] = &dram_drc1_clk.common.hw, 1079 + [CLK_DRAM_DEU0] = &dram_deu0_clk.common.hw, 1080 + [CLK_DRAM_DEU1] = &dram_deu1_clk.common.hw, 1081 + [CLK_DRAM_FE0] = &dram_fe0_clk.common.hw, 1082 + [CLK_DRAM_FE1] = &dram_fe1_clk.common.hw, 1083 + [CLK_DRAM_BE0] = &dram_be0_clk.common.hw, 1084 + [CLK_DRAM_BE1] = &dram_be1_clk.common.hw, 1085 + [CLK_DRAM_MP] = &dram_mp_clk.common.hw, 1086 + [CLK_BE0] = &be0_clk.common.hw, 1087 + [CLK_BE1] = &be1_clk.common.hw, 1088 + [CLK_FE0] = &fe0_clk.common.hw, 1089 + [CLK_FE1] = &fe1_clk.common.hw, 1090 + [CLK_MP] = &mp_clk.common.hw, 1091 + [CLK_LCD0_CH0] = &lcd0_ch0_clk.common.hw, 1092 + [CLK_LCD1_CH0] = &lcd1_ch0_clk.common.hw, 1093 + [CLK_LCD0_CH1] = &lcd0_ch1_clk.common.hw, 1094 + [CLK_LCD1_CH1] = &lcd1_ch1_clk.common.hw, 1095 + [CLK_CSI0_SCLK] = &csi0_sclk_clk.common.hw, 1096 + [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw, 1097 + [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw, 1098 + [CLK_VE] = &ve_clk.common.hw, 1099 + [CLK_CODEC] = &codec_clk.common.hw, 1100 + [CLK_AVS] = &avs_clk.common.hw, 1101 + [CLK_DIGITAL_MIC] = &digital_mic_clk.common.hw, 1102 + [CLK_HDMI] = &hdmi_clk.common.hw, 1103 + [CLK_HDMI_DDC] = &hdmi_ddc_clk.common.hw, 1104 + [CLK_PS] = &ps_clk.common.hw, 1105 + [CLK_MBUS0] = &mbus0_clk.common.hw, 1106 + [CLK_MBUS1] = &mbus1_clk.common.hw, 1107 + [CLK_MIPI_DSI] = &mipi_dsi_clk.common.hw, 1108 + [CLK_MIPI_DSI_DPHY] = &mipi_dsi_dphy_clk.common.hw, 1109 + [CLK_MIPI_CSI_DPHY] = &mipi_csi_dphy_clk.common.hw, 1110 + [CLK_IEP_DRC0] = &iep_drc0_clk.common.hw, 1111 + [CLK_IEP_DRC1] = &iep_drc1_clk.common.hw, 1112 + [CLK_IEP_DEU0] = &iep_deu0_clk.common.hw, 1113 + [CLK_IEP_DEU1] = &iep_deu1_clk.common.hw, 1114 + [CLK_GPU_CORE] = &gpu_core_clk.common.hw, 1115 + [CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw, 1116 + [CLK_GPU_HYD] = &gpu_hyd_clk.common.hw, 1117 + [CLK_ATS] = &ats_clk.common.hw, 1118 + [CLK_TRACE] = &trace_clk.common.hw, 1119 + [CLK_OUT_A] = &out_a_clk.common.hw, 1120 + [CLK_OUT_B] = &out_b_clk.common.hw, 1121 + [CLK_OUT_C] = &out_c_clk.common.hw, 1122 + }, 1123 + .num = CLK_NUMBER, 1124 + }; 1125 + 1126 + static struct ccu_reset_map sun6i_a31_ccu_resets[] = { 1127 + [RST_USB_PHY0] = { 0x0cc, BIT(0) }, 1128 + [RST_USB_PHY1] = { 0x0cc, BIT(1) }, 1129 + [RST_USB_PHY2] = { 0x0cc, BIT(2) }, 1130 + 1131 + [RST_AHB1_MIPI_DSI] = { 0x2c0, BIT(1) }, 1132 + [RST_AHB1_SS] = { 0x2c0, BIT(5) }, 1133 + [RST_AHB1_DMA] = { 0x2c0, BIT(6) }, 1134 + [RST_AHB1_MMC0] = { 0x2c0, BIT(8) }, 1135 + [RST_AHB1_MMC1] = { 0x2c0, BIT(9) }, 1136 + [RST_AHB1_MMC2] = { 0x2c0, BIT(10) }, 1137 + [RST_AHB1_MMC3] = { 0x2c0, BIT(11) }, 1138 + [RST_AHB1_NAND1] = { 0x2c0, BIT(12) }, 1139 + [RST_AHB1_NAND0] = { 0x2c0, BIT(13) }, 1140 + [RST_AHB1_SDRAM] = { 0x2c0, BIT(14) }, 1141 + [RST_AHB1_EMAC] = { 0x2c0, BIT(17) }, 1142 + [RST_AHB1_TS] = { 0x2c0, BIT(18) }, 1143 + [RST_AHB1_HSTIMER] = { 0x2c0, BIT(19) }, 1144 + [RST_AHB1_SPI0] = { 0x2c0, BIT(20) }, 1145 + [RST_AHB1_SPI1] = { 0x2c0, BIT(21) }, 1146 + [RST_AHB1_SPI2] = { 0x2c0, BIT(22) }, 1147 + [RST_AHB1_SPI3] = { 0x2c0, BIT(23) }, 1148 + [RST_AHB1_OTG] = { 0x2c0, BIT(24) }, 1149 + [RST_AHB1_EHCI0] = { 0x2c0, BIT(26) }, 1150 + [RST_AHB1_EHCI1] = { 0x2c0, BIT(27) }, 1151 + [RST_AHB1_OHCI0] = { 0x2c0, BIT(29) }, 1152 + [RST_AHB1_OHCI1] = { 0x2c0, BIT(30) }, 1153 + [RST_AHB1_OHCI2] = { 0x2c0, BIT(31) }, 1154 + 1155 + [RST_AHB1_VE] = { 0x2c4, BIT(0) }, 1156 + [RST_AHB1_LCD0] = { 0x2c4, BIT(4) }, 1157 + [RST_AHB1_LCD1] = { 0x2c4, BIT(5) }, 1158 + [RST_AHB1_CSI] = { 0x2c4, BIT(8) }, 1159 + [RST_AHB1_HDMI] = { 0x2c4, BIT(11) }, 1160 + [RST_AHB1_BE0] = { 0x2c4, BIT(12) }, 1161 + [RST_AHB1_BE1] = { 0x2c4, BIT(13) }, 1162 + [RST_AHB1_FE0] = { 0x2c4, BIT(14) }, 1163 + [RST_AHB1_FE1] = { 0x2c4, BIT(15) }, 1164 + [RST_AHB1_MP] = { 0x2c4, BIT(18) }, 1165 + [RST_AHB1_GPU] = { 0x2c4, BIT(20) }, 1166 + [RST_AHB1_DEU0] = { 0x2c4, BIT(23) }, 1167 + [RST_AHB1_DEU1] = { 0x2c4, BIT(24) }, 1168 + [RST_AHB1_DRC0] = { 0x2c4, BIT(25) }, 1169 + [RST_AHB1_DRC1] = { 0x2c4, BIT(26) }, 1170 + [RST_AHB1_LVDS] = { 0x2c8, BIT(0) }, 1171 + 1172 + [RST_APB1_CODEC] = { 0x2d0, BIT(0) }, 1173 + [RST_APB1_SPDIF] = { 0x2d0, BIT(1) }, 1174 + [RST_APB1_DIGITAL_MIC] = { 0x2d0, BIT(4) }, 1175 + [RST_APB1_DAUDIO0] = { 0x2d0, BIT(12) }, 1176 + [RST_APB1_DAUDIO1] = { 0x2d0, BIT(13) }, 1177 + 1178 + [RST_APB2_I2C0] = { 0x2d8, BIT(0) }, 1179 + [RST_APB2_I2C1] = { 0x2d8, BIT(1) }, 1180 + [RST_APB2_I2C2] = { 0x2d8, BIT(2) }, 1181 + [RST_APB2_I2C3] = { 0x2d8, BIT(3) }, 1182 + [RST_APB2_UART0] = { 0x2d8, BIT(16) }, 1183 + [RST_APB2_UART1] = { 0x2d8, BIT(17) }, 1184 + [RST_APB2_UART2] = { 0x2d8, BIT(18) }, 1185 + [RST_APB2_UART3] = { 0x2d8, BIT(19) }, 1186 + [RST_APB2_UART4] = { 0x2d8, BIT(20) }, 1187 + [RST_APB2_UART5] = { 0x2d8, BIT(21) }, 1188 + }; 1189 + 1190 + static const struct sunxi_ccu_desc sun6i_a31_ccu_desc = { 1191 + .ccu_clks = sun6i_a31_ccu_clks, 1192 + .num_ccu_clks = ARRAY_SIZE(sun6i_a31_ccu_clks), 1193 + 1194 + .hw_clks = &sun6i_a31_hw_clks, 1195 + 1196 + .resets = sun6i_a31_ccu_resets, 1197 + .num_resets = ARRAY_SIZE(sun6i_a31_ccu_resets), 1198 + }; 1199 + 1200 + static struct ccu_mux_nb sun6i_a31_cpu_nb = { 1201 + .common = &cpu_clk.common, 1202 + .cm = &cpu_clk.mux, 1203 + .delay_us = 1, /* > 8 clock cycles at 24 MHz */ 1204 + .bypass_index = 1, /* index of 24 MHz oscillator */ 1205 + }; 1206 + 1207 + static void __init sun6i_a31_ccu_setup(struct device_node *node) 1208 + { 1209 + void __iomem *reg; 1210 + u32 val; 1211 + 1212 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1213 + if (IS_ERR(reg)) { 1214 + pr_err("%s: Could not map the clock registers\n", 1215 + of_node_full_name(node)); 1216 + return; 1217 + } 1218 + 1219 + /* Force the PLL-Audio-1x divider to 4 */ 1220 + val = readl(reg + SUN6I_A31_PLL_AUDIO_REG); 1221 + val &= ~GENMASK(19, 16); 1222 + writel(val | (3 << 16), reg + SUN6I_A31_PLL_AUDIO_REG); 1223 + 1224 + /* Force PLL-MIPI to MIPI mode */ 1225 + val = readl(reg + SUN6I_A31_PLL_MIPI_REG); 1226 + val &= BIT(16); 1227 + writel(val, reg + SUN6I_A31_PLL_MIPI_REG); 1228 + 1229 + sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); 1230 + 1231 + ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, 1232 + &sun6i_a31_cpu_nb); 1233 + } 1234 + CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu", 1235 + sun6i_a31_ccu_setup);
+72
drivers/clk/sunxi-ng/ccu-sun6i-a31.h
··· 1 + /* 2 + * Copyright 2016 Chen-Yu Tsai 3 + * 4 + * Chen-Yu Tsai <wens@csie.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #ifndef _CCU_SUN6I_A31_H_ 18 + #define _CCU_SUN6I_A31_H_ 19 + 20 + #include <dt-bindings/clock/sun6i-a31-ccu.h> 21 + #include <dt-bindings/reset/sun6i-a31-ccu.h> 22 + 23 + #define CLK_PLL_CPU 0 24 + #define CLK_PLL_AUDIO_BASE 1 25 + #define CLK_PLL_AUDIO 2 26 + #define CLK_PLL_AUDIO_2X 3 27 + #define CLK_PLL_AUDIO_4X 4 28 + #define CLK_PLL_AUDIO_8X 5 29 + #define CLK_PLL_VIDEO0 6 30 + #define CLK_PLL_VIDEO0_2X 7 31 + #define CLK_PLL_VE 8 32 + #define CLK_PLL_DDR 9 33 + 34 + /* The PLL_PERIPH clock is exported */ 35 + 36 + #define CLK_PLL_PERIPH_2X 11 37 + #define CLK_PLL_VIDEO1 12 38 + #define CLK_PLL_VIDEO1_2X 13 39 + #define CLK_PLL_GPU 14 40 + #define CLK_PLL_MIPI 15 41 + #define CLK_PLL9 16 42 + #define CLK_PLL10 17 43 + 44 + /* The CPUX clock is exported */ 45 + 46 + #define CLK_AXI 19 47 + #define CLK_AHB1 20 48 + #define CLK_APB1 21 49 + #define CLK_APB2 22 50 + 51 + /* All the bus gates are exported */ 52 + 53 + /* The first bunch of module clocks are exported */ 54 + 55 + /* EMAC clock is not implemented */ 56 + 57 + #define CLK_MDFS 107 58 + #define CLK_SDRAM0 108 59 + #define CLK_SDRAM1 109 60 + 61 + /* All the DRAM gates are exported */ 62 + 63 + /* Some more module clocks are exported */ 64 + 65 + #define CLK_MBUS0 141 66 + #define CLK_MBUS1 142 67 + 68 + /* Some more module clocks and external clock outputs are exported */ 69 + 70 + #define CLK_NUMBER (CLK_OUT_C + 1) 71 + 72 + #endif /* _CCU_SUN6I_A31_H_ */
+63
drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
··· 1 + /* 2 + * Copyright 2016 Maxime Ripard 3 + * 4 + * Maxime Ripard <maxime.ripard@free-electrons.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #ifndef _CCU_SUN8I_A23_A33_H_ 18 + #define _CCU_SUN8I_A23_A33_H_ 19 + 20 + #include <dt-bindings/clock/sun8i-a23-a33-ccu.h> 21 + #include <dt-bindings/reset/sun8i-a23-a33-ccu.h> 22 + 23 + #define CLK_PLL_CPUX 0 24 + #define CLK_PLL_AUDIO_BASE 1 25 + #define CLK_PLL_AUDIO 2 26 + #define CLK_PLL_AUDIO_2X 3 27 + #define CLK_PLL_AUDIO_4X 4 28 + #define CLK_PLL_AUDIO_8X 5 29 + #define CLK_PLL_VIDEO 6 30 + #define CLK_PLL_VIDEO_2X 7 31 + #define CLK_PLL_VE 8 32 + #define CLK_PLL_DDR0 9 33 + #define CLK_PLL_PERIPH 10 34 + #define CLK_PLL_PERIPH_2X 11 35 + #define CLK_PLL_GPU 12 36 + #define CLK_PLL_MIPI 13 37 + #define CLK_PLL_HSIC 14 38 + #define CLK_PLL_DE 15 39 + #define CLK_PLL_DDR1 16 40 + #define CLK_PLL_DDR 17 41 + 42 + /* The CPUX clock is exported */ 43 + 44 + #define CLK_AXI 19 45 + #define CLK_AHB1 20 46 + #define CLK_APB1 21 47 + #define CLK_APB2 22 48 + 49 + /* All the bus gates are exported */ 50 + 51 + /* The first part of the mod clocks is exported */ 52 + 53 + #define CLK_DRAM 79 54 + 55 + /* Some more module clocks are exported */ 56 + 57 + #define CLK_MBUS 95 58 + 59 + /* And the last module clocks are exported */ 60 + 61 + #define CLK_NUMBER (CLK_ATS + 1) 62 + 63 + #endif /* _CCU_SUN8I_A23_A33_H_ */
+737
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
··· 1 + /* 2 + * Copyright (c) 2016 Maxime Ripard. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/clk-provider.h> 15 + #include <linux/of_address.h> 16 + 17 + #include "ccu_common.h" 18 + #include "ccu_reset.h" 19 + 20 + #include "ccu_div.h" 21 + #include "ccu_gate.h" 22 + #include "ccu_mp.h" 23 + #include "ccu_mult.h" 24 + #include "ccu_nk.h" 25 + #include "ccu_nkm.h" 26 + #include "ccu_nkmp.h" 27 + #include "ccu_nm.h" 28 + #include "ccu_phase.h" 29 + 30 + #include "ccu-sun8i-a23-a33.h" 31 + 32 + 33 + static struct ccu_nkmp pll_cpux_clk = { 34 + .enable = BIT(31), 35 + .lock = BIT(28), 36 + 37 + .n = _SUNXI_CCU_MULT(8, 5), 38 + .k = _SUNXI_CCU_MULT(4, 2), 39 + .m = _SUNXI_CCU_DIV(0, 2), 40 + .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), 41 + 42 + .common = { 43 + .reg = 0x000, 44 + .hw.init = CLK_HW_INIT("pll-cpux", "osc24M", 45 + &ccu_nkmp_ops, 46 + 0), 47 + }, 48 + }; 49 + 50 + /* 51 + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from 52 + * the base (2x, 4x and 8x), and one variable divider (the one true 53 + * pll audio). 54 + * 55 + * We don't have any need for the variable divider for now, so we just 56 + * hardcode it to match with the clock names 57 + */ 58 + #define SUN8I_A23_PLL_AUDIO_REG 0x008 59 + 60 + static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", 61 + "osc24M", 0x008, 62 + 8, 7, /* N */ 63 + 0, 5, /* M */ 64 + BIT(31), /* gate */ 65 + BIT(28), /* lock */ 66 + CLK_SET_RATE_UNGATE); 67 + 68 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video", 69 + "osc24M", 0x010, 70 + 8, 7, /* N */ 71 + 0, 4, /* M */ 72 + BIT(24), /* frac enable */ 73 + BIT(25), /* frac select */ 74 + 270000000, /* frac rate 0 */ 75 + 297000000, /* frac rate 1 */ 76 + BIT(31), /* gate */ 77 + BIT(28), /* lock */ 78 + CLK_SET_RATE_UNGATE); 79 + 80 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", 81 + "osc24M", 0x018, 82 + 8, 7, /* N */ 83 + 0, 4, /* M */ 84 + BIT(24), /* frac enable */ 85 + BIT(25), /* frac select */ 86 + 270000000, /* frac rate 0 */ 87 + 297000000, /* frac rate 1 */ 88 + BIT(31), /* gate */ 89 + BIT(28), /* lock */ 90 + CLK_SET_RATE_UNGATE); 91 + 92 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr", 93 + "osc24M", 0x020, 94 + 8, 5, /* N */ 95 + 4, 2, /* K */ 96 + 0, 2, /* M */ 97 + BIT(31), /* gate */ 98 + BIT(28), /* lock */ 99 + 0); 100 + 101 + static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph", 102 + "osc24M", 0x028, 103 + 8, 5, /* N */ 104 + 4, 2, /* K */ 105 + BIT(31), /* gate */ 106 + BIT(28), /* lock */ 107 + 2, /* post-div */ 108 + CLK_SET_RATE_UNGATE); 109 + 110 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", 111 + "osc24M", 0x038, 112 + 8, 7, /* N */ 113 + 0, 4, /* M */ 114 + BIT(24), /* frac enable */ 115 + BIT(25), /* frac select */ 116 + 270000000, /* frac rate 0 */ 117 + 297000000, /* frac rate 1 */ 118 + BIT(31), /* gate */ 119 + BIT(28), /* lock */ 120 + CLK_SET_RATE_UNGATE); 121 + 122 + /* 123 + * The MIPI PLL has 2 modes: "MIPI" and "HDMI". 124 + * 125 + * The MIPI mode is a standard NKM-style clock. The HDMI mode is an 126 + * integer / fractional clock with switchable multipliers and dividers. 127 + * This is not supported here. We hardcode the PLL to MIPI mode. 128 + */ 129 + #define SUN8I_A23_PLL_MIPI_REG 0x040 130 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi", 131 + "pll-video", 0x040, 132 + 8, 4, /* N */ 133 + 4, 2, /* K */ 134 + 0, 4, /* M */ 135 + BIT(31), /* gate */ 136 + BIT(28), /* lock */ 137 + CLK_SET_RATE_UNGATE); 138 + 139 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic", 140 + "osc24M", 0x044, 141 + 8, 7, /* N */ 142 + 0, 4, /* M */ 143 + BIT(24), /* frac enable */ 144 + BIT(25), /* frac select */ 145 + 270000000, /* frac rate 0 */ 146 + 297000000, /* frac rate 1 */ 147 + BIT(31), /* gate */ 148 + BIT(28), /* lock */ 149 + CLK_SET_RATE_UNGATE); 150 + 151 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", 152 + "osc24M", 0x048, 153 + 8, 7, /* N */ 154 + 0, 4, /* M */ 155 + BIT(24), /* frac enable */ 156 + BIT(25), /* frac select */ 157 + 270000000, /* frac rate 0 */ 158 + 297000000, /* frac rate 1 */ 159 + BIT(31), /* gate */ 160 + BIT(28), /* lock */ 161 + CLK_SET_RATE_UNGATE); 162 + 163 + static const char * const cpux_parents[] = { "osc32k", "osc24M", 164 + "pll-cpux" , "pll-cpux" }; 165 + static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, 166 + 0x050, 16, 2, CLK_IS_CRITICAL); 167 + 168 + static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); 169 + 170 + static const char * const ahb1_parents[] = { "osc32k", "osc24M", 171 + "axi" , "pll-periph" }; 172 + static struct ccu_div ahb1_clk = { 173 + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), 174 + 175 + .mux = { 176 + .shift = 12, 177 + .width = 2, 178 + 179 + .variable_prediv = { 180 + .index = 3, 181 + .shift = 6, 182 + .width = 2, 183 + }, 184 + }, 185 + 186 + .common = { 187 + .reg = 0x054, 188 + .features = CCU_FEATURE_VARIABLE_PREDIV, 189 + .hw.init = CLK_HW_INIT_PARENTS("ahb1", 190 + ahb1_parents, 191 + &ccu_div_ops, 192 + 0), 193 + }, 194 + }; 195 + 196 + static struct clk_div_table apb1_div_table[] = { 197 + { .val = 0, .div = 2 }, 198 + { .val = 1, .div = 2 }, 199 + { .val = 2, .div = 4 }, 200 + { .val = 3, .div = 8 }, 201 + { /* Sentinel */ }, 202 + }; 203 + static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", 204 + 0x054, 8, 2, apb1_div_table, 0); 205 + 206 + static const char * const apb2_parents[] = { "osc32k", "osc24M", 207 + "pll-periph" , "pll-periph" }; 208 + static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, 209 + 0, 5, /* M */ 210 + 16, 2, /* P */ 211 + 24, 2, /* mux */ 212 + 0); 213 + 214 + static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", 215 + 0x060, BIT(1), 0); 216 + static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", 217 + 0x060, BIT(6), 0); 218 + static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", 219 + 0x060, BIT(8), 0); 220 + static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", 221 + 0x060, BIT(9), 0); 222 + static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", 223 + 0x060, BIT(10), 0); 224 + static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", 225 + 0x060, BIT(13), 0); 226 + static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", 227 + 0x060, BIT(14), 0); 228 + static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", 229 + 0x060, BIT(19), 0); 230 + static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", 231 + 0x060, BIT(20), 0); 232 + static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", 233 + 0x060, BIT(21), 0); 234 + static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", 235 + 0x060, BIT(24), 0); 236 + static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1", 237 + 0x060, BIT(26), 0); 238 + static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1", 239 + 0x060, BIT(29), 0); 240 + 241 + static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", 242 + 0x064, BIT(0), 0); 243 + static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1", 244 + 0x064, BIT(4), 0); 245 + static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1", 246 + 0x064, BIT(8), 0); 247 + static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1", 248 + 0x064, BIT(12), 0); 249 + static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1", 250 + 0x064, BIT(14), 0); 251 + static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", 252 + 0x064, BIT(20), 0); 253 + static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1", 254 + 0x064, BIT(21), 0); 255 + static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1", 256 + 0x064, BIT(22), 0); 257 + static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1", 258 + 0x064, BIT(25), 0); 259 + 260 + static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1", 261 + 0x068, BIT(0), 0); 262 + static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", 263 + 0x068, BIT(5), 0); 264 + static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 265 + 0x068, BIT(12), 0); 266 + static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 267 + 0x068, BIT(13), 0); 268 + 269 + static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 270 + 0x06c, BIT(0), 0); 271 + static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 272 + 0x06c, BIT(1), 0); 273 + static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 274 + 0x06c, BIT(2), 0); 275 + static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 276 + 0x06c, BIT(16), 0); 277 + static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 278 + 0x06c, BIT(17), 0); 279 + static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 280 + 0x06c, BIT(18), 0); 281 + static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 282 + 0x06c, BIT(19), 0); 283 + static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 284 + 0x06c, BIT(20), 0); 285 + 286 + static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; 287 + static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, 288 + 0, 4, /* M */ 289 + 16, 2, /* P */ 290 + 24, 2, /* mux */ 291 + BIT(31), /* gate */ 292 + 0); 293 + 294 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, 295 + 0, 4, /* M */ 296 + 16, 2, /* P */ 297 + 24, 2, /* mux */ 298 + BIT(31), /* gate */ 299 + 0); 300 + 301 + static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", 302 + 0x088, 20, 3, 0); 303 + static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", 304 + 0x088, 8, 3, 0); 305 + 306 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, 307 + 0, 4, /* M */ 308 + 16, 2, /* P */ 309 + 24, 2, /* mux */ 310 + BIT(31), /* gate */ 311 + 0); 312 + 313 + static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", 314 + 0x08c, 20, 3, 0); 315 + static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", 316 + 0x08c, 8, 3, 0); 317 + 318 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, 319 + 0, 4, /* M */ 320 + 16, 2, /* P */ 321 + 24, 2, /* mux */ 322 + BIT(31), /* gate */ 323 + 0); 324 + 325 + static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", 326 + 0x090, 20, 3, 0); 327 + static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", 328 + 0x090, 8, 3, 0); 329 + 330 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, 331 + 0, 4, /* M */ 332 + 16, 2, /* P */ 333 + 24, 2, /* mux */ 334 + BIT(31), /* gate */ 335 + 0); 336 + 337 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, 338 + 0, 4, /* M */ 339 + 16, 2, /* P */ 340 + 24, 2, /* mux */ 341 + BIT(31), /* gate */ 342 + 0); 343 + 344 + static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x", 345 + "pll-audio-2x", "pll-audio" }; 346 + static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents, 347 + 0x0b0, 16, 2, BIT(31), 0); 348 + 349 + static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents, 350 + 0x0b4, 16, 2, BIT(31), 0); 351 + 352 + /* TODO: the parent for most of the USB clocks is not known */ 353 + static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 354 + 0x0cc, BIT(8), 0); 355 + static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 356 + 0x0cc, BIT(9), 0); 357 + static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", 358 + 0x0cc, BIT(10), 0); 359 + static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M", 360 + 0x0cc, BIT(11), 0); 361 + static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M", 362 + 0x0cc, BIT(16), 0); 363 + 364 + static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr", 365 + 0x100, BIT(0), 0); 366 + static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr", 367 + 0x100, BIT(1), 0); 368 + static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "pll-ddr", 369 + 0x100, BIT(16), 0); 370 + static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr", 371 + 0x100, BIT(24), 0); 372 + static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr", 373 + 0x100, BIT(26), 0); 374 + 375 + static const char * const de_parents[] = { "pll-video", "pll-periph-2x", 376 + "pll-gpu", "pll-de" }; 377 + static const u8 de_table[] = { 0, 2, 3, 5 }; 378 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be", 379 + de_parents, de_table, 380 + 0x104, 0, 4, 24, 3, BIT(31), 0); 381 + 382 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe", 383 + de_parents, de_table, 384 + 0x10c, 0, 4, 24, 3, BIT(31), 0); 385 + 386 + static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x", 387 + "pll-mipi" }; 388 + static const u8 lcd_ch0_table[] = { 0, 2, 4 }; 389 + static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0", 390 + lcd_ch0_parents, lcd_ch0_table, 391 + 0x118, 24, 3, BIT(31), 392 + CLK_SET_RATE_PARENT); 393 + 394 + static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" }; 395 + static const u8 lcd_ch1_table[] = { 0, 2 }; 396 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1", 397 + lcd_ch1_parents, lcd_ch1_table, 398 + 0x12c, 0, 4, 24, 2, BIT(31), 0); 399 + 400 + static const char * const csi_sclk_parents[] = { "pll-video", "pll-de", 401 + "pll-mipi", "pll-ve" }; 402 + static const u8 csi_sclk_table[] = { 0, 3, 4, 5 }; 403 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk", 404 + csi_sclk_parents, csi_sclk_table, 405 + 0x134, 16, 4, 24, 3, BIT(31), 0); 406 + 407 + static const char * const csi_mclk_parents[] = { "pll-video", "pll-de", 408 + "osc24M" }; 409 + static const u8 csi_mclk_table[] = { 0, 3, 5 }; 410 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", 411 + csi_mclk_parents, csi_mclk_table, 412 + 0x134, 0, 5, 8, 3, BIT(15), 0); 413 + 414 + static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 415 + 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); 416 + 417 + static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio", 418 + 0x140, BIT(31), 0); 419 + static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 420 + 0x144, BIT(31), 0); 421 + 422 + static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x", 423 + "pll-ddr" }; 424 + static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 425 + 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL); 426 + 427 + static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" }; 428 + static const u8 dsi_sclk_table[] = { 0, 2 }; 429 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk", 430 + dsi_sclk_parents, dsi_sclk_table, 431 + 0x168, 16, 4, 24, 2, BIT(31), 0); 432 + 433 + static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" }; 434 + static const u8 dsi_dphy_table[] = { 0, 2 }; 435 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy", 436 + dsi_dphy_parents, dsi_dphy_table, 437 + 0x168, 0, 4, 8, 2, BIT(15), 0); 438 + 439 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc", 440 + de_parents, de_table, 441 + 0x180, 0, 4, 24, 3, BIT(31), 0); 442 + 443 + static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", 444 + 0x1a0, 0, 3, BIT(31), 0); 445 + 446 + static const char * const ats_parents[] = { "osc24M", "pll-periph" }; 447 + static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents, 448 + 0x1b0, 0, 3, 24, 2, BIT(31), 0); 449 + 450 + static struct ccu_common *sun8i_a23_ccu_clks[] = { 451 + &pll_cpux_clk.common, 452 + &pll_audio_base_clk.common, 453 + &pll_video_clk.common, 454 + &pll_ve_clk.common, 455 + &pll_ddr_clk.common, 456 + &pll_periph_clk.common, 457 + &pll_gpu_clk.common, 458 + &pll_mipi_clk.common, 459 + &pll_hsic_clk.common, 460 + &pll_de_clk.common, 461 + &cpux_clk.common, 462 + &axi_clk.common, 463 + &ahb1_clk.common, 464 + &apb1_clk.common, 465 + &apb2_clk.common, 466 + &bus_mipi_dsi_clk.common, 467 + &bus_dma_clk.common, 468 + &bus_mmc0_clk.common, 469 + &bus_mmc1_clk.common, 470 + &bus_mmc2_clk.common, 471 + &bus_nand_clk.common, 472 + &bus_dram_clk.common, 473 + &bus_hstimer_clk.common, 474 + &bus_spi0_clk.common, 475 + &bus_spi1_clk.common, 476 + &bus_otg_clk.common, 477 + &bus_ehci_clk.common, 478 + &bus_ohci_clk.common, 479 + &bus_ve_clk.common, 480 + &bus_lcd_clk.common, 481 + &bus_csi_clk.common, 482 + &bus_de_fe_clk.common, 483 + &bus_de_be_clk.common, 484 + &bus_gpu_clk.common, 485 + &bus_msgbox_clk.common, 486 + &bus_spinlock_clk.common, 487 + &bus_drc_clk.common, 488 + &bus_codec_clk.common, 489 + &bus_pio_clk.common, 490 + &bus_i2s0_clk.common, 491 + &bus_i2s1_clk.common, 492 + &bus_i2c0_clk.common, 493 + &bus_i2c1_clk.common, 494 + &bus_i2c2_clk.common, 495 + &bus_uart0_clk.common, 496 + &bus_uart1_clk.common, 497 + &bus_uart2_clk.common, 498 + &bus_uart3_clk.common, 499 + &bus_uart4_clk.common, 500 + &nand_clk.common, 501 + &mmc0_clk.common, 502 + &mmc0_sample_clk.common, 503 + &mmc0_output_clk.common, 504 + &mmc1_clk.common, 505 + &mmc1_sample_clk.common, 506 + &mmc1_output_clk.common, 507 + &mmc2_clk.common, 508 + &mmc2_sample_clk.common, 509 + &mmc2_output_clk.common, 510 + &spi0_clk.common, 511 + &spi1_clk.common, 512 + &i2s0_clk.common, 513 + &i2s1_clk.common, 514 + &usb_phy0_clk.common, 515 + &usb_phy1_clk.common, 516 + &usb_hsic_clk.common, 517 + &usb_hsic_12M_clk.common, 518 + &usb_ohci_clk.common, 519 + &dram_ve_clk.common, 520 + &dram_csi_clk.common, 521 + &dram_drc_clk.common, 522 + &dram_de_fe_clk.common, 523 + &dram_de_be_clk.common, 524 + &de_be_clk.common, 525 + &de_fe_clk.common, 526 + &lcd_ch0_clk.common, 527 + &lcd_ch1_clk.common, 528 + &csi_sclk_clk.common, 529 + &csi_mclk_clk.common, 530 + &ve_clk.common, 531 + &ac_dig_clk.common, 532 + &avs_clk.common, 533 + &mbus_clk.common, 534 + &dsi_sclk_clk.common, 535 + &dsi_dphy_clk.common, 536 + &drc_clk.common, 537 + &gpu_clk.common, 538 + &ats_clk.common, 539 + }; 540 + 541 + /* We hardcode the divider to 4 for now */ 542 + static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", 543 + "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); 544 + static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 545 + "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 546 + static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", 547 + "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 548 + static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", 549 + "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); 550 + static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", 551 + "pll-periph", 1, 2, 0); 552 + static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", 553 + "pll-video", 1, 2, 0); 554 + 555 + static struct clk_hw_onecell_data sun8i_a23_hw_clks = { 556 + .hws = { 557 + [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, 558 + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, 559 + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, 560 + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, 561 + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, 562 + [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, 563 + [CLK_PLL_VIDEO] = &pll_video_clk.common.hw, 564 + [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw, 565 + [CLK_PLL_VE] = &pll_ve_clk.common.hw, 566 + [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw, 567 + [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, 568 + [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw, 569 + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, 570 + [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, 571 + [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, 572 + [CLK_PLL_DE] = &pll_de_clk.common.hw, 573 + [CLK_CPUX] = &cpux_clk.common.hw, 574 + [CLK_AXI] = &axi_clk.common.hw, 575 + [CLK_AHB1] = &ahb1_clk.common.hw, 576 + [CLK_APB1] = &apb1_clk.common.hw, 577 + [CLK_APB2] = &apb2_clk.common.hw, 578 + [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, 579 + [CLK_BUS_DMA] = &bus_dma_clk.common.hw, 580 + [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, 581 + [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, 582 + [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, 583 + [CLK_BUS_NAND] = &bus_nand_clk.common.hw, 584 + [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, 585 + [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, 586 + [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, 587 + [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, 588 + [CLK_BUS_OTG] = &bus_otg_clk.common.hw, 589 + [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw, 590 + [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw, 591 + [CLK_BUS_VE] = &bus_ve_clk.common.hw, 592 + [CLK_BUS_LCD] = &bus_lcd_clk.common.hw, 593 + [CLK_BUS_CSI] = &bus_csi_clk.common.hw, 594 + [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw, 595 + [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw, 596 + [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, 597 + [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, 598 + [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, 599 + [CLK_BUS_DRC] = &bus_drc_clk.common.hw, 600 + [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, 601 + [CLK_BUS_PIO] = &bus_pio_clk.common.hw, 602 + [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, 603 + [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, 604 + [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, 605 + [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, 606 + [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, 607 + [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, 608 + [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, 609 + [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, 610 + [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, 611 + [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, 612 + [CLK_NAND] = &nand_clk.common.hw, 613 + [CLK_MMC0] = &mmc0_clk.common.hw, 614 + [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, 615 + [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, 616 + [CLK_MMC1] = &mmc1_clk.common.hw, 617 + [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, 618 + [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, 619 + [CLK_MMC2] = &mmc2_clk.common.hw, 620 + [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, 621 + [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, 622 + [CLK_SPI0] = &spi0_clk.common.hw, 623 + [CLK_SPI1] = &spi1_clk.common.hw, 624 + [CLK_I2S0] = &i2s0_clk.common.hw, 625 + [CLK_I2S1] = &i2s1_clk.common.hw, 626 + [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, 627 + [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, 628 + [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, 629 + [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw, 630 + [CLK_USB_OHCI] = &usb_ohci_clk.common.hw, 631 + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, 632 + [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, 633 + [CLK_DRAM_DRC] = &dram_drc_clk.common.hw, 634 + [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw, 635 + [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw, 636 + [CLK_DE_BE] = &de_be_clk.common.hw, 637 + [CLK_DE_FE] = &de_fe_clk.common.hw, 638 + [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw, 639 + [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw, 640 + [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, 641 + [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, 642 + [CLK_VE] = &ve_clk.common.hw, 643 + [CLK_AC_DIG] = &ac_dig_clk.common.hw, 644 + [CLK_AVS] = &avs_clk.common.hw, 645 + [CLK_MBUS] = &mbus_clk.common.hw, 646 + [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw, 647 + [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw, 648 + [CLK_DRC] = &drc_clk.common.hw, 649 + [CLK_GPU] = &gpu_clk.common.hw, 650 + [CLK_ATS] = &ats_clk.common.hw, 651 + }, 652 + .num = CLK_NUMBER, 653 + }; 654 + 655 + static struct ccu_reset_map sun8i_a23_ccu_resets[] = { 656 + [RST_USB_PHY0] = { 0x0cc, BIT(0) }, 657 + [RST_USB_PHY1] = { 0x0cc, BIT(1) }, 658 + [RST_USB_HSIC] = { 0x0cc, BIT(2) }, 659 + 660 + [RST_MBUS] = { 0x0fc, BIT(31) }, 661 + 662 + [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, 663 + [RST_BUS_DMA] = { 0x2c0, BIT(6) }, 664 + [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, 665 + [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, 666 + [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, 667 + [RST_BUS_NAND] = { 0x2c0, BIT(13) }, 668 + [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, 669 + [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, 670 + [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, 671 + [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, 672 + [RST_BUS_OTG] = { 0x2c0, BIT(24) }, 673 + [RST_BUS_EHCI] = { 0x2c0, BIT(26) }, 674 + [RST_BUS_OHCI] = { 0x2c0, BIT(29) }, 675 + 676 + [RST_BUS_VE] = { 0x2c4, BIT(0) }, 677 + [RST_BUS_LCD] = { 0x2c4, BIT(4) }, 678 + [RST_BUS_CSI] = { 0x2c4, BIT(8) }, 679 + [RST_BUS_DE_BE] = { 0x2c4, BIT(12) }, 680 + [RST_BUS_DE_FE] = { 0x2c4, BIT(14) }, 681 + [RST_BUS_GPU] = { 0x2c4, BIT(20) }, 682 + [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) }, 683 + [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) }, 684 + [RST_BUS_DRC] = { 0x2c4, BIT(25) }, 685 + 686 + [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, 687 + 688 + [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, 689 + [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, 690 + [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, 691 + 692 + [RST_BUS_I2C0] = { 0x2d4, BIT(0) }, 693 + [RST_BUS_I2C1] = { 0x2d4, BIT(1) }, 694 + [RST_BUS_I2C2] = { 0x2d4, BIT(2) }, 695 + [RST_BUS_UART0] = { 0x2d4, BIT(16) }, 696 + [RST_BUS_UART1] = { 0x2d4, BIT(17) }, 697 + [RST_BUS_UART2] = { 0x2d4, BIT(18) }, 698 + [RST_BUS_UART3] = { 0x2d4, BIT(19) }, 699 + [RST_BUS_UART4] = { 0x2d4, BIT(20) }, 700 + }; 701 + 702 + static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = { 703 + .ccu_clks = sun8i_a23_ccu_clks, 704 + .num_ccu_clks = ARRAY_SIZE(sun8i_a23_ccu_clks), 705 + 706 + .hw_clks = &sun8i_a23_hw_clks, 707 + 708 + .resets = sun8i_a23_ccu_resets, 709 + .num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets), 710 + }; 711 + 712 + static void __init sun8i_a23_ccu_setup(struct device_node *node) 713 + { 714 + void __iomem *reg; 715 + u32 val; 716 + 717 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 718 + if (IS_ERR(reg)) { 719 + pr_err("%s: Could not map the clock registers\n", 720 + of_node_full_name(node)); 721 + return; 722 + } 723 + 724 + /* Force the PLL-Audio-1x divider to 4 */ 725 + val = readl(reg + SUN8I_A23_PLL_AUDIO_REG); 726 + val &= ~GENMASK(19, 16); 727 + writel(val | (3 << 16), reg + SUN8I_A23_PLL_AUDIO_REG); 728 + 729 + /* Force PLL-MIPI to MIPI mode */ 730 + val = readl(reg + SUN8I_A23_PLL_MIPI_REG); 731 + val &= ~BIT(16); 732 + writel(val, reg + SUN8I_A23_PLL_MIPI_REG); 733 + 734 + sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); 735 + } 736 + CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu", 737 + sun8i_a23_ccu_setup);
+780
drivers/clk/sunxi-ng/ccu-sun8i-a33.c
··· 1 + /* 2 + * Copyright (c) 2016 Maxime Ripard. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/clk-provider.h> 15 + #include <linux/of_address.h> 16 + 17 + #include "ccu_common.h" 18 + #include "ccu_reset.h" 19 + 20 + #include "ccu_div.h" 21 + #include "ccu_gate.h" 22 + #include "ccu_mp.h" 23 + #include "ccu_mult.h" 24 + #include "ccu_nk.h" 25 + #include "ccu_nkm.h" 26 + #include "ccu_nkmp.h" 27 + #include "ccu_nm.h" 28 + #include "ccu_phase.h" 29 + 30 + #include "ccu-sun8i-a23-a33.h" 31 + 32 + static struct ccu_nkmp pll_cpux_clk = { 33 + .enable = BIT(31), 34 + .lock = BIT(28), 35 + 36 + .n = _SUNXI_CCU_MULT(8, 5), 37 + .k = _SUNXI_CCU_MULT(4, 2), 38 + .m = _SUNXI_CCU_DIV(0, 2), 39 + .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), 40 + 41 + .common = { 42 + .reg = 0x000, 43 + .hw.init = CLK_HW_INIT("pll-cpux", "osc24M", 44 + &ccu_nkmp_ops, 45 + 0), 46 + }, 47 + }; 48 + 49 + /* 50 + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from 51 + * the base (2x, 4x and 8x), and one variable divider (the one true 52 + * pll audio). 53 + * 54 + * We don't have any need for the variable divider for now, so we just 55 + * hardcode it to match with the clock names 56 + */ 57 + #define SUN8I_A33_PLL_AUDIO_REG 0x008 58 + 59 + static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", 60 + "osc24M", 0x008, 61 + 8, 7, /* N */ 62 + 0, 5, /* M */ 63 + BIT(31), /* gate */ 64 + BIT(28), /* lock */ 65 + CLK_SET_RATE_UNGATE); 66 + 67 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video", 68 + "osc24M", 0x010, 69 + 8, 7, /* N */ 70 + 0, 4, /* M */ 71 + BIT(24), /* frac enable */ 72 + BIT(25), /* frac select */ 73 + 270000000, /* frac rate 0 */ 74 + 297000000, /* frac rate 1 */ 75 + BIT(31), /* gate */ 76 + BIT(28), /* lock */ 77 + CLK_SET_RATE_UNGATE); 78 + 79 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", 80 + "osc24M", 0x018, 81 + 8, 7, /* N */ 82 + 0, 4, /* M */ 83 + BIT(24), /* frac enable */ 84 + BIT(25), /* frac select */ 85 + 270000000, /* frac rate 0 */ 86 + 297000000, /* frac rate 1 */ 87 + BIT(31), /* gate */ 88 + BIT(28), /* lock */ 89 + CLK_SET_RATE_UNGATE); 90 + 91 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0", 92 + "osc24M", 0x020, 93 + 8, 5, /* N */ 94 + 4, 2, /* K */ 95 + 0, 2, /* M */ 96 + BIT(31), /* gate */ 97 + BIT(28), /* lock */ 98 + 0); 99 + 100 + static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph", 101 + "osc24M", 0x028, 102 + 8, 5, /* N */ 103 + 4, 2, /* K */ 104 + BIT(31), /* gate */ 105 + BIT(28), /* lock */ 106 + 2, /* post-div */ 107 + CLK_SET_RATE_UNGATE); 108 + 109 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", 110 + "osc24M", 0x038, 111 + 8, 7, /* N */ 112 + 0, 4, /* M */ 113 + BIT(24), /* frac enable */ 114 + BIT(25), /* frac select */ 115 + 270000000, /* frac rate 0 */ 116 + 297000000, /* frac rate 1 */ 117 + BIT(31), /* gate */ 118 + BIT(28), /* lock */ 119 + CLK_SET_RATE_UNGATE); 120 + 121 + /* 122 + * The MIPI PLL has 2 modes: "MIPI" and "HDMI". 123 + * 124 + * The MIPI mode is a standard NKM-style clock. The HDMI mode is an 125 + * integer / fractional clock with switchable multipliers and dividers. 126 + * This is not supported here. We hardcode the PLL to MIPI mode. 127 + */ 128 + #define SUN8I_A33_PLL_MIPI_REG 0x040 129 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi", 130 + "pll-video", 0x040, 131 + 8, 4, /* N */ 132 + 4, 2, /* K */ 133 + 0, 4, /* M */ 134 + BIT(31), /* gate */ 135 + BIT(28), /* lock */ 136 + CLK_SET_RATE_UNGATE); 137 + 138 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic", 139 + "osc24M", 0x044, 140 + 8, 7, /* N */ 141 + 0, 4, /* M */ 142 + BIT(24), /* frac enable */ 143 + BIT(25), /* frac select */ 144 + 270000000, /* frac rate 0 */ 145 + 297000000, /* frac rate 1 */ 146 + BIT(31), /* gate */ 147 + BIT(28), /* lock */ 148 + CLK_SET_RATE_UNGATE); 149 + 150 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", 151 + "osc24M", 0x048, 152 + 8, 7, /* N */ 153 + 0, 4, /* M */ 154 + BIT(24), /* frac enable */ 155 + BIT(25), /* frac select */ 156 + 270000000, /* frac rate 0 */ 157 + 297000000, /* frac rate 1 */ 158 + BIT(31), /* gate */ 159 + BIT(28), /* lock */ 160 + CLK_SET_RATE_UNGATE); 161 + 162 + /* TODO: Fix N */ 163 + static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1", 164 + "osc24M", 0x04c, 165 + 8, 6, /* N */ 166 + BIT(31), /* gate */ 167 + BIT(28), /* lock */ 168 + CLK_SET_RATE_UNGATE); 169 + 170 + static const char * const cpux_parents[] = { "osc32k", "osc24M", 171 + "pll-cpux" , "pll-cpux" }; 172 + static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, 173 + 0x050, 16, 2, CLK_IS_CRITICAL); 174 + 175 + static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); 176 + 177 + static const char * const ahb1_parents[] = { "osc32k", "osc24M", 178 + "axi" , "pll-periph" }; 179 + static struct ccu_div ahb1_clk = { 180 + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), 181 + 182 + .mux = { 183 + .shift = 12, 184 + .width = 2, 185 + 186 + .variable_prediv = { 187 + .index = 3, 188 + .shift = 6, 189 + .width = 2, 190 + }, 191 + }, 192 + 193 + .common = { 194 + .reg = 0x054, 195 + .features = CCU_FEATURE_VARIABLE_PREDIV, 196 + .hw.init = CLK_HW_INIT_PARENTS("ahb1", 197 + ahb1_parents, 198 + &ccu_div_ops, 199 + 0), 200 + }, 201 + }; 202 + 203 + static struct clk_div_table apb1_div_table[] = { 204 + { .val = 0, .div = 2 }, 205 + { .val = 1, .div = 2 }, 206 + { .val = 2, .div = 4 }, 207 + { .val = 3, .div = 8 }, 208 + { /* Sentinel */ }, 209 + }; 210 + static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", 211 + 0x054, 8, 2, apb1_div_table, 0); 212 + 213 + static const char * const apb2_parents[] = { "osc32k", "osc24M", 214 + "pll-periph" , "pll-periph" }; 215 + static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, 216 + 0, 5, /* M */ 217 + 16, 2, /* P */ 218 + 24, 2, /* mux */ 219 + 0); 220 + 221 + static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", 222 + 0x060, BIT(1), 0); 223 + static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb1", 224 + 0x060, BIT(5), 0); 225 + static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", 226 + 0x060, BIT(6), 0); 227 + static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", 228 + 0x060, BIT(8), 0); 229 + static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", 230 + 0x060, BIT(9), 0); 231 + static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", 232 + 0x060, BIT(10), 0); 233 + static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", 234 + 0x060, BIT(13), 0); 235 + static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", 236 + 0x060, BIT(14), 0); 237 + static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", 238 + 0x060, BIT(19), 0); 239 + static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", 240 + 0x060, BIT(20), 0); 241 + static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", 242 + 0x060, BIT(21), 0); 243 + static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", 244 + 0x060, BIT(24), 0); 245 + static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1", 246 + 0x060, BIT(26), 0); 247 + static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1", 248 + 0x060, BIT(29), 0); 249 + 250 + static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", 251 + 0x064, BIT(0), 0); 252 + static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1", 253 + 0x064, BIT(4), 0); 254 + static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1", 255 + 0x064, BIT(8), 0); 256 + static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1", 257 + 0x064, BIT(12), 0); 258 + static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1", 259 + 0x064, BIT(14), 0); 260 + static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", 261 + 0x064, BIT(20), 0); 262 + static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1", 263 + 0x064, BIT(21), 0); 264 + static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1", 265 + 0x064, BIT(22), 0); 266 + static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1", 267 + 0x064, BIT(25), 0); 268 + static SUNXI_CCU_GATE(bus_sat_clk, "bus-sat", "ahb1", 269 + 0x064, BIT(26), 0); 270 + 271 + static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1", 272 + 0x068, BIT(0), 0); 273 + static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", 274 + 0x068, BIT(5), 0); 275 + static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 276 + 0x068, BIT(12), 0); 277 + static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 278 + 0x068, BIT(13), 0); 279 + 280 + static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 281 + 0x06c, BIT(0), 0); 282 + static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 283 + 0x06c, BIT(1), 0); 284 + static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 285 + 0x06c, BIT(2), 0); 286 + static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 287 + 0x06c, BIT(16), 0); 288 + static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 289 + 0x06c, BIT(17), 0); 290 + static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 291 + 0x06c, BIT(18), 0); 292 + static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 293 + 0x06c, BIT(19), 0); 294 + static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 295 + 0x06c, BIT(20), 0); 296 + 297 + static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" }; 298 + static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, 299 + 0, 4, /* M */ 300 + 16, 2, /* P */ 301 + 24, 2, /* mux */ 302 + BIT(31), /* gate */ 303 + 0); 304 + 305 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, 306 + 0, 4, /* M */ 307 + 16, 2, /* P */ 308 + 24, 2, /* mux */ 309 + BIT(31), /* gate */ 310 + 0); 311 + 312 + static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", 313 + 0x088, 20, 3, 0); 314 + static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", 315 + 0x088, 8, 3, 0); 316 + 317 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, 318 + 0, 4, /* M */ 319 + 16, 2, /* P */ 320 + 24, 2, /* mux */ 321 + BIT(31), /* gate */ 322 + 0); 323 + 324 + static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", 325 + 0x08c, 20, 3, 0); 326 + static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", 327 + 0x08c, 8, 3, 0); 328 + 329 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, 330 + 0, 4, /* M */ 331 + 16, 2, /* P */ 332 + 24, 2, /* mux */ 333 + BIT(31), /* gate */ 334 + 0); 335 + 336 + static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", 337 + 0x090, 20, 3, 0); 338 + static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", 339 + 0x090, 8, 3, 0); 340 + 341 + static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c, 342 + 0, 4, /* M */ 343 + 16, 2, /* P */ 344 + 24, 2, /* mux */ 345 + BIT(31), /* gate */ 346 + 0); 347 + 348 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, 349 + 0, 4, /* M */ 350 + 16, 2, /* P */ 351 + 24, 2, /* mux */ 352 + BIT(31), /* gate */ 353 + 0); 354 + 355 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, 356 + 0, 4, /* M */ 357 + 16, 2, /* P */ 358 + 24, 2, /* mux */ 359 + BIT(31), /* gate */ 360 + 0); 361 + 362 + static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x", 363 + "pll-audio-2x", "pll-audio" }; 364 + static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents, 365 + 0x0b0, 16, 2, BIT(31), 0); 366 + 367 + static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents, 368 + 0x0b4, 16, 2, BIT(31), 0); 369 + 370 + /* TODO: the parent for most of the USB clocks is not known */ 371 + static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 372 + 0x0cc, BIT(8), 0); 373 + static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 374 + 0x0cc, BIT(9), 0); 375 + static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic", 376 + 0x0cc, BIT(10), 0); 377 + static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M", 378 + 0x0cc, BIT(11), 0); 379 + static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M", 380 + 0x0cc, BIT(16), 0); 381 + 382 + static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr", 383 + 0x0f4, 0, 4, CLK_IS_CRITICAL); 384 + 385 + static const char * const pll_ddr_parents[] = { "pll-ddr0", "pll-ddr1" }; 386 + static SUNXI_CCU_MUX(pll_ddr_clk, "pll-ddr", pll_ddr_parents, 387 + 0x0f8, 16, 1, 0); 388 + 389 + static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", 390 + 0x100, BIT(0), 0); 391 + static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram", 392 + 0x100, BIT(1), 0); 393 + static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "dram", 394 + 0x100, BIT(16), 0); 395 + static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "dram", 396 + 0x100, BIT(24), 0); 397 + static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "dram", 398 + 0x100, BIT(26), 0); 399 + 400 + static const char * const de_parents[] = { "pll-video", "pll-periph-2x", 401 + "pll-gpu", "pll-de" }; 402 + static const u8 de_table[] = { 0, 2, 3, 5 }; 403 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be", 404 + de_parents, de_table, 405 + 0x104, 0, 4, 24, 3, BIT(31), 0); 406 + 407 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe", 408 + de_parents, de_table, 409 + 0x10c, 0, 4, 24, 3, BIT(31), 0); 410 + 411 + static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x", 412 + "pll-mipi" }; 413 + static const u8 lcd_ch0_table[] = { 0, 2, 4 }; 414 + static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0", 415 + lcd_ch0_parents, lcd_ch0_table, 416 + 0x118, 24, 3, BIT(31), 417 + CLK_SET_RATE_PARENT); 418 + 419 + static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" }; 420 + static const u8 lcd_ch1_table[] = { 0, 2 }; 421 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1", 422 + lcd_ch1_parents, lcd_ch1_table, 423 + 0x12c, 0, 4, 24, 2, BIT(31), 0); 424 + 425 + static const char * const csi_sclk_parents[] = { "pll-video", "pll-de", 426 + "pll-mipi", "pll-ve" }; 427 + static const u8 csi_sclk_table[] = { 0, 3, 4, 5 }; 428 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk", 429 + csi_sclk_parents, csi_sclk_table, 430 + 0x134, 16, 4, 24, 3, BIT(31), 0); 431 + 432 + static const char * const csi_mclk_parents[] = { "pll-video", "pll-de", 433 + "osc24M" }; 434 + static const u8 csi_mclk_table[] = { 0, 3, 5 }; 435 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk", 436 + csi_mclk_parents, csi_mclk_table, 437 + 0x134, 0, 5, 8, 3, BIT(15), 0); 438 + 439 + static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 440 + 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); 441 + 442 + static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio", 443 + 0x140, BIT(31), 0); 444 + static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x", 445 + 0x140, BIT(30), 0); 446 + static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 447 + 0x144, BIT(31), 0); 448 + 449 + static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x", 450 + "pll-ddr0", "pll-ddr1" }; 451 + static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 452 + 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL); 453 + 454 + static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" }; 455 + static const u8 dsi_sclk_table[] = { 0, 2 }; 456 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk", 457 + dsi_sclk_parents, dsi_sclk_table, 458 + 0x168, 16, 4, 24, 2, BIT(31), 0); 459 + 460 + static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" }; 461 + static const u8 dsi_dphy_table[] = { 0, 2 }; 462 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy", 463 + dsi_dphy_parents, dsi_dphy_table, 464 + 0x168, 0, 4, 8, 2, BIT(15), 0); 465 + 466 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc", 467 + de_parents, de_table, 468 + 0x180, 0, 4, 24, 3, BIT(31), 0); 469 + 470 + static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", 471 + 0x1a0, 0, 3, BIT(31), 0); 472 + 473 + static const char * const ats_parents[] = { "osc24M", "pll-periph" }; 474 + static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents, 475 + 0x1b0, 0, 3, 24, 2, BIT(31), 0); 476 + 477 + static struct ccu_common *sun8i_a33_ccu_clks[] = { 478 + &pll_cpux_clk.common, 479 + &pll_audio_base_clk.common, 480 + &pll_video_clk.common, 481 + &pll_ve_clk.common, 482 + &pll_ddr0_clk.common, 483 + &pll_periph_clk.common, 484 + &pll_gpu_clk.common, 485 + &pll_mipi_clk.common, 486 + &pll_hsic_clk.common, 487 + &pll_de_clk.common, 488 + &pll_ddr1_clk.common, 489 + &pll_ddr_clk.common, 490 + &cpux_clk.common, 491 + &axi_clk.common, 492 + &ahb1_clk.common, 493 + &apb1_clk.common, 494 + &apb2_clk.common, 495 + &bus_mipi_dsi_clk.common, 496 + &bus_ss_clk.common, 497 + &bus_dma_clk.common, 498 + &bus_mmc0_clk.common, 499 + &bus_mmc1_clk.common, 500 + &bus_mmc2_clk.common, 501 + &bus_nand_clk.common, 502 + &bus_dram_clk.common, 503 + &bus_hstimer_clk.common, 504 + &bus_spi0_clk.common, 505 + &bus_spi1_clk.common, 506 + &bus_otg_clk.common, 507 + &bus_ehci_clk.common, 508 + &bus_ohci_clk.common, 509 + &bus_ve_clk.common, 510 + &bus_lcd_clk.common, 511 + &bus_csi_clk.common, 512 + &bus_de_fe_clk.common, 513 + &bus_de_be_clk.common, 514 + &bus_gpu_clk.common, 515 + &bus_msgbox_clk.common, 516 + &bus_spinlock_clk.common, 517 + &bus_drc_clk.common, 518 + &bus_sat_clk.common, 519 + &bus_codec_clk.common, 520 + &bus_pio_clk.common, 521 + &bus_i2s0_clk.common, 522 + &bus_i2s1_clk.common, 523 + &bus_i2c0_clk.common, 524 + &bus_i2c1_clk.common, 525 + &bus_i2c2_clk.common, 526 + &bus_uart0_clk.common, 527 + &bus_uart1_clk.common, 528 + &bus_uart2_clk.common, 529 + &bus_uart3_clk.common, 530 + &bus_uart4_clk.common, 531 + &nand_clk.common, 532 + &mmc0_clk.common, 533 + &mmc0_sample_clk.common, 534 + &mmc0_output_clk.common, 535 + &mmc1_clk.common, 536 + &mmc1_sample_clk.common, 537 + &mmc1_output_clk.common, 538 + &mmc2_clk.common, 539 + &mmc2_sample_clk.common, 540 + &mmc2_output_clk.common, 541 + &ss_clk.common, 542 + &spi0_clk.common, 543 + &spi1_clk.common, 544 + &i2s0_clk.common, 545 + &i2s1_clk.common, 546 + &usb_phy0_clk.common, 547 + &usb_phy1_clk.common, 548 + &usb_hsic_clk.common, 549 + &usb_hsic_12M_clk.common, 550 + &usb_ohci_clk.common, 551 + &dram_clk.common, 552 + &dram_ve_clk.common, 553 + &dram_csi_clk.common, 554 + &dram_drc_clk.common, 555 + &dram_de_fe_clk.common, 556 + &dram_de_be_clk.common, 557 + &de_be_clk.common, 558 + &de_fe_clk.common, 559 + &lcd_ch0_clk.common, 560 + &lcd_ch1_clk.common, 561 + &csi_sclk_clk.common, 562 + &csi_mclk_clk.common, 563 + &ve_clk.common, 564 + &ac_dig_clk.common, 565 + &ac_dig_4x_clk.common, 566 + &avs_clk.common, 567 + &mbus_clk.common, 568 + &dsi_sclk_clk.common, 569 + &dsi_dphy_clk.common, 570 + &drc_clk.common, 571 + &gpu_clk.common, 572 + &ats_clk.common, 573 + }; 574 + 575 + /* We hardcode the divider to 4 for now */ 576 + static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", 577 + "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); 578 + static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 579 + "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 580 + static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", 581 + "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 582 + static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", 583 + "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); 584 + static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x", 585 + "pll-periph", 1, 2, 0); 586 + static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x", 587 + "pll-video", 1, 2, 0); 588 + 589 + static struct clk_hw_onecell_data sun8i_a33_hw_clks = { 590 + .hws = { 591 + [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw, 592 + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, 593 + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, 594 + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, 595 + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, 596 + [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, 597 + [CLK_PLL_VIDEO] = &pll_video_clk.common.hw, 598 + [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw, 599 + [CLK_PLL_VE] = &pll_ve_clk.common.hw, 600 + [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, 601 + [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw, 602 + [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw, 603 + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, 604 + [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, 605 + [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw, 606 + [CLK_PLL_DE] = &pll_de_clk.common.hw, 607 + [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw, 608 + [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, 609 + [CLK_CPUX] = &cpux_clk.common.hw, 610 + [CLK_AXI] = &axi_clk.common.hw, 611 + [CLK_AHB1] = &ahb1_clk.common.hw, 612 + [CLK_APB1] = &apb1_clk.common.hw, 613 + [CLK_APB2] = &apb2_clk.common.hw, 614 + [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, 615 + [CLK_BUS_SS] = &bus_ss_clk.common.hw, 616 + [CLK_BUS_DMA] = &bus_dma_clk.common.hw, 617 + [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, 618 + [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, 619 + [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, 620 + [CLK_BUS_NAND] = &bus_nand_clk.common.hw, 621 + [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, 622 + [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, 623 + [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, 624 + [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, 625 + [CLK_BUS_OTG] = &bus_otg_clk.common.hw, 626 + [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw, 627 + [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw, 628 + [CLK_BUS_VE] = &bus_ve_clk.common.hw, 629 + [CLK_BUS_LCD] = &bus_lcd_clk.common.hw, 630 + [CLK_BUS_CSI] = &bus_csi_clk.common.hw, 631 + [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw, 632 + [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw, 633 + [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, 634 + [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw, 635 + [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw, 636 + [CLK_BUS_DRC] = &bus_drc_clk.common.hw, 637 + [CLK_BUS_SAT] = &bus_sat_clk.common.hw, 638 + [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, 639 + [CLK_BUS_PIO] = &bus_pio_clk.common.hw, 640 + [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, 641 + [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, 642 + [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, 643 + [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, 644 + [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, 645 + [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, 646 + [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, 647 + [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, 648 + [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, 649 + [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, 650 + [CLK_NAND] = &nand_clk.common.hw, 651 + [CLK_MMC0] = &mmc0_clk.common.hw, 652 + [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, 653 + [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, 654 + [CLK_MMC1] = &mmc1_clk.common.hw, 655 + [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, 656 + [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, 657 + [CLK_MMC2] = &mmc2_clk.common.hw, 658 + [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, 659 + [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, 660 + [CLK_SS] = &ss_clk.common.hw, 661 + [CLK_SPI0] = &spi0_clk.common.hw, 662 + [CLK_SPI1] = &spi1_clk.common.hw, 663 + [CLK_I2S0] = &i2s0_clk.common.hw, 664 + [CLK_I2S1] = &i2s1_clk.common.hw, 665 + [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, 666 + [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, 667 + [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, 668 + [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw, 669 + [CLK_USB_OHCI] = &usb_ohci_clk.common.hw, 670 + [CLK_DRAM] = &dram_clk.common.hw, 671 + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, 672 + [CLK_DRAM_CSI] = &dram_csi_clk.common.hw, 673 + [CLK_DRAM_DRC] = &dram_drc_clk.common.hw, 674 + [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw, 675 + [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw, 676 + [CLK_DE_BE] = &de_be_clk.common.hw, 677 + [CLK_DE_FE] = &de_fe_clk.common.hw, 678 + [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw, 679 + [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw, 680 + [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, 681 + [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw, 682 + [CLK_VE] = &ve_clk.common.hw, 683 + [CLK_AC_DIG] = &ac_dig_clk.common.hw, 684 + [CLK_AC_DIG_4X] = &ac_dig_4x_clk.common.hw, 685 + [CLK_AVS] = &avs_clk.common.hw, 686 + [CLK_MBUS] = &mbus_clk.common.hw, 687 + [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw, 688 + [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw, 689 + [CLK_DRC] = &drc_clk.common.hw, 690 + [CLK_GPU] = &gpu_clk.common.hw, 691 + [CLK_ATS] = &ats_clk.common.hw, 692 + }, 693 + .num = CLK_NUMBER, 694 + }; 695 + 696 + static struct ccu_reset_map sun8i_a33_ccu_resets[] = { 697 + [RST_USB_PHY0] = { 0x0cc, BIT(0) }, 698 + [RST_USB_PHY1] = { 0x0cc, BIT(1) }, 699 + [RST_USB_HSIC] = { 0x0cc, BIT(2) }, 700 + 701 + [RST_MBUS] = { 0x0fc, BIT(31) }, 702 + 703 + [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, 704 + [RST_BUS_SS] = { 0x2c0, BIT(5) }, 705 + [RST_BUS_DMA] = { 0x2c0, BIT(6) }, 706 + [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, 707 + [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, 708 + [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, 709 + [RST_BUS_NAND] = { 0x2c0, BIT(13) }, 710 + [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, 711 + [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, 712 + [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, 713 + [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, 714 + [RST_BUS_OTG] = { 0x2c0, BIT(24) }, 715 + [RST_BUS_EHCI] = { 0x2c0, BIT(26) }, 716 + [RST_BUS_OHCI] = { 0x2c0, BIT(29) }, 717 + 718 + [RST_BUS_VE] = { 0x2c4, BIT(0) }, 719 + [RST_BUS_LCD] = { 0x2c4, BIT(4) }, 720 + [RST_BUS_CSI] = { 0x2c4, BIT(8) }, 721 + [RST_BUS_DE_BE] = { 0x2c4, BIT(12) }, 722 + [RST_BUS_DE_FE] = { 0x2c4, BIT(14) }, 723 + [RST_BUS_GPU] = { 0x2c4, BIT(20) }, 724 + [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) }, 725 + [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) }, 726 + [RST_BUS_DRC] = { 0x2c4, BIT(25) }, 727 + [RST_BUS_SAT] = { 0x2c4, BIT(26) }, 728 + 729 + [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, 730 + 731 + [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, 732 + [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, 733 + [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, 734 + 735 + [RST_BUS_I2C0] = { 0x2d4, BIT(0) }, 736 + [RST_BUS_I2C1] = { 0x2d4, BIT(1) }, 737 + [RST_BUS_I2C2] = { 0x2d4, BIT(2) }, 738 + [RST_BUS_UART0] = { 0x2d4, BIT(16) }, 739 + [RST_BUS_UART1] = { 0x2d4, BIT(17) }, 740 + [RST_BUS_UART2] = { 0x2d4, BIT(18) }, 741 + [RST_BUS_UART3] = { 0x2d4, BIT(19) }, 742 + [RST_BUS_UART4] = { 0x2d4, BIT(20) }, 743 + }; 744 + 745 + static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = { 746 + .ccu_clks = sun8i_a33_ccu_clks, 747 + .num_ccu_clks = ARRAY_SIZE(sun8i_a33_ccu_clks), 748 + 749 + .hw_clks = &sun8i_a33_hw_clks, 750 + 751 + .resets = sun8i_a33_ccu_resets, 752 + .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets), 753 + }; 754 + 755 + static void __init sun8i_a33_ccu_setup(struct device_node *node) 756 + { 757 + void __iomem *reg; 758 + u32 val; 759 + 760 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 761 + if (IS_ERR(reg)) { 762 + pr_err("%s: Could not map the clock registers\n", 763 + of_node_full_name(node)); 764 + return; 765 + } 766 + 767 + /* Force the PLL-Audio-1x divider to 4 */ 768 + val = readl(reg + SUN8I_A33_PLL_AUDIO_REG); 769 + val &= ~GENMASK(19, 16); 770 + writel(val | (3 << 16), reg + SUN8I_A33_PLL_AUDIO_REG); 771 + 772 + /* Force PLL-MIPI to MIPI mode */ 773 + val = readl(reg + SUN8I_A33_PLL_MIPI_REG); 774 + val &= ~BIT(16); 775 + writel(val, reg + SUN8I_A33_PLL_MIPI_REG); 776 + 777 + sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); 778 + } 779 + CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu", 780 + sun8i_a33_ccu_setup);
+5 -5
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
··· 184 184 0); 185 185 186 186 static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" }; 187 + static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = { 188 + { .index = 1, .div = 2 }, 189 + }; 187 190 static struct ccu_mux ahb2_clk = { 188 191 .mux = { 189 192 .shift = 0, 190 193 .width = 1, 191 - 192 - .fixed_prediv = { 193 - .index = 1, 194 - .div = 2, 195 - }, 194 + .fixed_predivs = ahb2_fixed_predivs, 195 + .n_predivs = ARRAY_SIZE(ahb2_fixed_predivs), 196 196 }, 197 197 198 198 .common = {
+55 -11
drivers/clk/sunxi-ng/ccu_div.h
··· 19 19 #include "ccu_common.h" 20 20 #include "ccu_mux.h" 21 21 22 + /** 23 + * struct _ccu_div - Internal divider description 24 + * @shift: Bit offset of the divider in its register 25 + * @width: Width of the divider field in its register 26 + * @max: Maximum value allowed for that divider. This is the 27 + * arithmetic value, not the maximum value to be set in the 28 + * register. 29 + * @flags: clk_divider flags to apply on this divider 30 + * @table: Divider table pointer (if applicable) 31 + * 32 + * That structure represents a single divider, and is meant to be 33 + * embedded in other structures representing the various clock 34 + * classes. 35 + * 36 + * It is basically a wrapper around the clk_divider functions 37 + * arguments. 38 + */ 22 39 struct _ccu_div { 23 40 u8 shift; 24 41 u8 width; 42 + 43 + u32 max; 25 44 26 45 u32 flags; 27 46 ··· 55 36 .table = _table, \ 56 37 } 57 38 58 - #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \ 59 - _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, _flags) 60 - 61 39 #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \ 62 40 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0) 63 41 42 + #define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \ 43 + { \ 44 + .shift = _shift, \ 45 + .width = _width, \ 46 + .flags = _flags, \ 47 + .max = _max, \ 48 + } 49 + 50 + #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \ 51 + _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags) 52 + 53 + #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \ 54 + _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0) 55 + 64 56 #define _SUNXI_CCU_DIV(_shift, _width) \ 65 - _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, 0) 57 + _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0) 66 58 67 59 struct ccu_div { 68 60 u32 enable; ··· 107 77 _shift, _width, _table, 0, \ 108 78 _flags) 109 79 110 - #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 111 - _mshift, _mwidth, _muxshift, _muxwidth, \ 112 - _gate, _flags) \ 80 + #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ 81 + _parents, _table, \ 82 + _reg, \ 83 + _mshift, _mwidth, \ 84 + _muxshift, _muxwidth, \ 85 + _gate, _flags) \ 113 86 struct ccu_div _struct = { \ 114 87 .enable = _gate, \ 115 88 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 116 - .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ 89 + .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \ 117 90 .common = { \ 118 91 .reg = _reg, \ 119 92 .hw.init = CLK_HW_INIT_PARENTS(_name, \ ··· 126 93 }, \ 127 94 } 128 95 96 + #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 97 + _mshift, _mwidth, _muxshift, _muxwidth, \ 98 + _gate, _flags) \ 99 + SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ 100 + _parents, NULL, \ 101 + _reg, _mshift, _mwidth, \ 102 + _muxshift, _muxwidth, \ 103 + _gate, _flags) 104 + 129 105 #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \ 130 106 _mshift, _mwidth, _muxshift, _muxwidth, \ 131 107 _flags) \ 132 - SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 133 - _mshift, _mwidth, _muxshift, _muxwidth, \ 134 - 0, _flags) 108 + SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \ 109 + _parents, NULL, \ 110 + _reg, _mshift, _mwidth, \ 111 + _muxshift, _muxwidth, \ 112 + 0, _flags) 135 113 136 114 137 115 #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
+13 -10
drivers/clk/sunxi-ng/ccu_mp.c
··· 21 21 unsigned int best_m = 0, best_p = 0; 22 22 unsigned int _m, _p; 23 23 24 - for (_p = 0; _p <= max_p; _p++) { 24 + for (_p = 1; _p <= max_p; _p <<= 1) { 25 25 for (_m = 1; _m <= max_m; _m++) { 26 - unsigned long tmp_rate = (parent >> _p) / _m; 26 + unsigned long tmp_rate = parent / _p / _m; 27 27 28 28 if (tmp_rate > rate) 29 29 continue; ··· 46 46 void *data) 47 47 { 48 48 struct ccu_mp *cmp = data; 49 + unsigned int max_m, max_p; 49 50 unsigned int m, p; 50 51 51 - ccu_mp_find_best(parent_rate, rate, 52 - 1 << cmp->m.width, (1 << cmp->p.width) - 1, 53 - &m, &p); 52 + max_m = cmp->m.max ?: 1 << cmp->m.width; 53 + max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); 54 54 55 - return (parent_rate >> p) / m; 55 + ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p); 56 + 57 + return parent_rate / p / m; 56 58 } 57 59 58 60 static void ccu_mp_disable(struct clk_hw *hw) ··· 110 108 { 111 109 struct ccu_mp *cmp = hw_to_ccu_mp(hw); 112 110 unsigned long flags; 111 + unsigned int max_m, max_p; 113 112 unsigned int m, p; 114 113 u32 reg; 115 114 116 - ccu_mp_find_best(parent_rate, rate, 117 - 1 << cmp->m.width, (1 << cmp->p.width) - 1, 118 - &m, &p); 115 + max_m = cmp->m.max ?: 1 << cmp->m.width; 116 + max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); 119 117 118 + ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p); 120 119 121 120 spin_lock_irqsave(cmp->common.lock, flags); 122 121 ··· 125 122 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); 126 123 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); 127 124 128 - writel(reg | (p << cmp->p.shift) | ((m - 1) << cmp->m.shift), 125 + writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift), 129 126 cmp->common.base + cmp->common.reg); 130 127 131 128 spin_unlock_irqrestore(cmp->common.lock, flags);
+1 -1
drivers/clk/sunxi-ng/ccu_mp.h
··· 44 44 .enable = _gate, \ 45 45 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 46 46 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ 47 - .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ 47 + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ 48 48 .common = { \ 49 49 .reg = _reg, \ 50 50 .hw.init = CLK_HW_INIT_PARENTS(_name, \
+133
drivers/clk/sunxi-ng/ccu_mult.c
··· 1 + /* 2 + * Copyright (C) 2016 Maxime Ripard 3 + * Maxime Ripard <maxime.ripard@free-electrons.com> 4 + * 5 + * This program is free software; you can redistribute it and/or 6 + * modify it under the terms of the GNU General Public License as 7 + * published by the Free Software Foundation; either version 2 of 8 + * the License, or (at your option) any later version. 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + 13 + #include "ccu_gate.h" 14 + #include "ccu_mult.h" 15 + 16 + static void ccu_mult_find_best(unsigned long parent, unsigned long rate, 17 + unsigned int max_n, unsigned int *n) 18 + { 19 + *n = rate / parent; 20 + } 21 + 22 + static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, 23 + unsigned long parent_rate, 24 + unsigned long rate, 25 + void *data) 26 + { 27 + struct ccu_mult *cm = data; 28 + unsigned int n; 29 + 30 + ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n); 31 + 32 + return parent_rate * n; 33 + } 34 + 35 + static void ccu_mult_disable(struct clk_hw *hw) 36 + { 37 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 38 + 39 + return ccu_gate_helper_disable(&cm->common, cm->enable); 40 + } 41 + 42 + static int ccu_mult_enable(struct clk_hw *hw) 43 + { 44 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 45 + 46 + return ccu_gate_helper_enable(&cm->common, cm->enable); 47 + } 48 + 49 + static int ccu_mult_is_enabled(struct clk_hw *hw) 50 + { 51 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 52 + 53 + return ccu_gate_helper_is_enabled(&cm->common, cm->enable); 54 + } 55 + 56 + static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw, 57 + unsigned long parent_rate) 58 + { 59 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 60 + unsigned long val; 61 + u32 reg; 62 + 63 + reg = readl(cm->common.base + cm->common.reg); 64 + val = reg >> cm->mult.shift; 65 + val &= (1 << cm->mult.width) - 1; 66 + 67 + ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, 68 + &parent_rate); 69 + 70 + return parent_rate * (val + 1); 71 + } 72 + 73 + static int ccu_mult_determine_rate(struct clk_hw *hw, 74 + struct clk_rate_request *req) 75 + { 76 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 77 + 78 + return ccu_mux_helper_determine_rate(&cm->common, &cm->mux, 79 + req, ccu_mult_round_rate, cm); 80 + } 81 + 82 + static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, 83 + unsigned long parent_rate) 84 + { 85 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 86 + unsigned long flags; 87 + unsigned int n; 88 + u32 reg; 89 + 90 + ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1, 91 + &parent_rate); 92 + 93 + ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n); 94 + 95 + spin_lock_irqsave(cm->common.lock, flags); 96 + 97 + reg = readl(cm->common.base + cm->common.reg); 98 + reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift); 99 + 100 + writel(reg | ((n - 1) << cm->mult.shift), 101 + cm->common.base + cm->common.reg); 102 + 103 + spin_unlock_irqrestore(cm->common.lock, flags); 104 + 105 + return 0; 106 + } 107 + 108 + static u8 ccu_mult_get_parent(struct clk_hw *hw) 109 + { 110 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 111 + 112 + return ccu_mux_helper_get_parent(&cm->common, &cm->mux); 113 + } 114 + 115 + static int ccu_mult_set_parent(struct clk_hw *hw, u8 index) 116 + { 117 + struct ccu_mult *cm = hw_to_ccu_mult(hw); 118 + 119 + return ccu_mux_helper_set_parent(&cm->common, &cm->mux, index); 120 + } 121 + 122 + const struct clk_ops ccu_mult_ops = { 123 + .disable = ccu_mult_disable, 124 + .enable = ccu_mult_enable, 125 + .is_enabled = ccu_mult_is_enabled, 126 + 127 + .get_parent = ccu_mult_get_parent, 128 + .set_parent = ccu_mult_set_parent, 129 + 130 + .determine_rate = ccu_mult_determine_rate, 131 + .recalc_rate = ccu_mult_recalc_rate, 132 + .set_rate = ccu_mult_set_rate, 133 + };
+35
drivers/clk/sunxi-ng/ccu_mult.h
··· 1 1 #ifndef _CCU_MULT_H_ 2 2 #define _CCU_MULT_H_ 3 3 4 + #include "ccu_common.h" 5 + #include "ccu_mux.h" 6 + 4 7 struct _ccu_mult { 5 8 u8 shift; 6 9 u8 width; ··· 14 11 .shift = _shift, \ 15 12 .width = _width, \ 16 13 } 14 + 15 + struct ccu_mult { 16 + u32 enable; 17 + 18 + struct _ccu_mult mult; 19 + struct ccu_mux_internal mux; 20 + struct ccu_common common; 21 + }; 22 + 23 + #define SUNXI_CCU_N_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ 24 + _mshift, _mwidth, _gate, _lock, \ 25 + _flags) \ 26 + struct ccu_mult _struct = { \ 27 + .enable = _gate, \ 28 + .mult = _SUNXI_CCU_MULT(_mshift, _mwidth), \ 29 + .common = { \ 30 + .reg = _reg, \ 31 + .hw.init = CLK_HW_INIT(_name, \ 32 + _parent, \ 33 + &ccu_mult_ops, \ 34 + _flags), \ 35 + }, \ 36 + } 37 + 38 + static inline struct ccu_mult *hw_to_ccu_mult(struct clk_hw *hw) 39 + { 40 + struct ccu_common *common = hw_to_ccu_common(hw); 41 + 42 + return container_of(common, struct ccu_mult, common); 43 + } 44 + 45 + extern const struct clk_ops ccu_mult_ops; 17 46 18 47 #endif /* _CCU_MULT_H_ */
+53 -3
drivers/clk/sunxi-ng/ccu_mux.c
··· 8 8 * the License, or (at your option) any later version. 9 9 */ 10 10 11 + #include <linux/clk.h> 11 12 #include <linux/clk-provider.h> 13 + #include <linux/delay.h> 12 14 13 15 #include "ccu_gate.h" 14 16 #include "ccu_mux.h" ··· 20 18 int parent_index, 21 19 unsigned long *parent_rate) 22 20 { 23 - u8 prediv = 1; 21 + u16 prediv = 1; 24 22 u32 reg; 23 + int i; 25 24 26 25 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || 27 26 (common->features & CCU_FEATURE_VARIABLE_PREDIV))) ··· 35 32 } 36 33 37 34 if (common->features & CCU_FEATURE_FIXED_PREDIV) 38 - if (parent_index == cm->fixed_prediv.index) 39 - prediv = cm->fixed_prediv.div; 35 + for (i = 0; i < cm->n_predivs; i++) 36 + if (parent_index == cm->fixed_predivs[i].index) 37 + prediv = cm->fixed_predivs[i].div; 40 38 41 39 if (common->features & CCU_FEATURE_VARIABLE_PREDIV) 42 40 if (parent_index == cm->variable_prediv.index) { ··· 111 107 parent = reg >> cm->shift; 112 108 parent &= (1 << cm->width) - 1; 113 109 110 + if (cm->table) { 111 + int num_parents = clk_hw_get_num_parents(&common->hw); 112 + int i; 113 + 114 + for (i = 0; i < num_parents; i++) 115 + if (cm->table[i] == parent) 116 + return i; 117 + } 118 + 114 119 return parent; 115 120 } 116 121 ··· 129 116 { 130 117 unsigned long flags; 131 118 u32 reg; 119 + 120 + if (cm->table) 121 + index = cm->table[index]; 132 122 133 123 spin_lock_irqsave(common->lock, flags); 134 124 ··· 201 185 .determine_rate = __clk_mux_determine_rate, 202 186 .recalc_rate = ccu_mux_recalc_rate, 203 187 }; 188 + 189 + /* 190 + * This clock notifier is called when the frequency of the of the parent 191 + * PLL clock is to be changed. The idea is to switch the parent to a 192 + * stable clock, such as the main oscillator, while the PLL frequency 193 + * stabilizes. 194 + */ 195 + static int ccu_mux_notifier_cb(struct notifier_block *nb, 196 + unsigned long event, void *data) 197 + { 198 + struct ccu_mux_nb *mux = to_ccu_mux_nb(nb); 199 + int ret = 0; 200 + 201 + if (event == PRE_RATE_CHANGE) { 202 + mux->original_index = ccu_mux_helper_get_parent(mux->common, 203 + mux->cm); 204 + ret = ccu_mux_helper_set_parent(mux->common, mux->cm, 205 + mux->bypass_index); 206 + } else if (event == POST_RATE_CHANGE) { 207 + ret = ccu_mux_helper_set_parent(mux->common, mux->cm, 208 + mux->original_index); 209 + } 210 + 211 + udelay(mux->delay_us); 212 + 213 + return notifier_from_errno(ret); 214 + } 215 + 216 + int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb) 217 + { 218 + mux_nb->clk_nb.notifier_call = ccu_mux_notifier_cb; 219 + 220 + return clk_notifier_register(clk, &mux_nb->clk_nb); 221 + }
+46 -24
drivers/clk/sunxi-ng/ccu_mux.h
··· 5 5 6 6 #include "ccu_common.h" 7 7 8 - struct ccu_mux_internal { 9 - u8 shift; 10 - u8 width; 8 + struct ccu_mux_fixed_prediv { 9 + u8 index; 10 + u16 div; 11 + }; 11 12 12 - struct { 13 - u8 index; 14 - u8 div; 15 - } fixed_prediv; 13 + struct ccu_mux_internal { 14 + u8 shift; 15 + u8 width; 16 + const u8 *table; 17 + 18 + const struct ccu_mux_fixed_prediv *fixed_predivs; 19 + u8 n_predivs; 16 20 17 21 struct { 18 22 u8 index; ··· 25 21 } variable_prediv; 26 22 }; 27 23 28 - #define SUNXI_CLK_MUX(_shift, _width) \ 29 - { \ 30 - .shift = _shift, \ 31 - .width = _width, \ 24 + #define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \ 25 + { \ 26 + .shift = _shift, \ 27 + .width = _width, \ 28 + .table = _table, \ 32 29 } 30 + 31 + #define _SUNXI_CCU_MUX(_shift, _width) \ 32 + _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL) 33 33 34 34 struct ccu_mux { 35 35 u16 reg; ··· 43 35 struct ccu_common common; 44 36 }; 45 37 46 - #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, _flags) \ 38 + #define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \ 39 + _reg, _shift, _width, _gate, \ 40 + _flags) \ 47 41 struct ccu_mux _struct = { \ 48 - .mux = SUNXI_CLK_MUX(_shift, _width), \ 42 + .enable = _gate, \ 43 + .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \ 49 44 .common = { \ 50 45 .reg = _reg, \ 51 46 .hw.init = CLK_HW_INIT_PARENTS(_name, \ ··· 60 49 61 50 #define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \ 62 51 _shift, _width, _gate, _flags) \ 63 - struct ccu_mux _struct = { \ 64 - .enable = _gate, \ 65 - .mux = SUNXI_CLK_MUX(_shift, _width), \ 66 - .common = { \ 67 - .reg = _reg, \ 68 - .hw.init = CLK_HW_INIT_PARENTS(_name, \ 69 - _parents, \ 70 - &ccu_mux_ops, \ 71 - _flags), \ 72 - } \ 73 - } 52 + SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ 53 + _reg, _shift, _width, _gate, \ 54 + _flags) 55 + 56 + #define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \ 57 + _flags) \ 58 + SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \ 59 + _reg, _shift, _width, 0, _flags) 74 60 75 61 static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) 76 62 { ··· 95 87 int ccu_mux_helper_set_parent(struct ccu_common *common, 96 88 struct ccu_mux_internal *cm, 97 89 u8 index); 90 + 91 + struct ccu_mux_nb { 92 + struct notifier_block clk_nb; 93 + struct ccu_common *common; 94 + struct ccu_mux_internal *cm; 95 + 96 + u32 delay_us; /* How many us to wait after reparenting */ 97 + u8 bypass_index; /* Which parent to temporarily use */ 98 + u8 original_index; /* This is set by the notifier callback */ 99 + }; 100 + 101 + #define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb) 102 + 103 + int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb); 98 104 99 105 #endif /* _CCU_MUX_H_ */
+36 -8
drivers/clk/sunxi-ng/ccu_nkm.c
··· 93 93 return parent_rate * (n + 1) * (k + 1) / (m + 1); 94 94 } 95 95 96 - static long ccu_nkm_round_rate(struct clk_hw *hw, unsigned long rate, 97 - unsigned long *parent_rate) 96 + static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, 97 + unsigned long parent_rate, 98 + unsigned long rate, 99 + void *data) 98 100 { 99 - struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 101 + struct ccu_nkm *nkm = data; 100 102 struct _ccu_nkm _nkm; 101 103 102 104 _nkm.max_n = 1 << nkm->n.width; 103 105 _nkm.max_k = 1 << nkm->k.width; 104 - _nkm.max_m = 1 << nkm->m.width; 106 + _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; 105 107 106 - ccu_nkm_find_best(*parent_rate, rate, &_nkm); 108 + ccu_nkm_find_best(parent_rate, rate, &_nkm); 107 109 108 - return *parent_rate * _nkm.n * _nkm.k / _nkm.m; 110 + return parent_rate * _nkm.n * _nkm.k / _nkm.m; 111 + } 112 + 113 + static int ccu_nkm_determine_rate(struct clk_hw *hw, 114 + struct clk_rate_request *req) 115 + { 116 + struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 117 + 118 + return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux, 119 + req, ccu_nkm_round_rate, nkm); 109 120 } 110 121 111 122 static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, ··· 129 118 130 119 _nkm.max_n = 1 << nkm->n.width; 131 120 _nkm.max_k = 1 << nkm->k.width; 132 - _nkm.max_m = 1 << nkm->m.width; 121 + _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; 133 122 134 123 ccu_nkm_find_best(parent_rate, rate, &_nkm); 135 124 ··· 153 142 return 0; 154 143 } 155 144 145 + static u8 ccu_nkm_get_parent(struct clk_hw *hw) 146 + { 147 + struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 148 + 149 + return ccu_mux_helper_get_parent(&nkm->common, &nkm->mux); 150 + } 151 + 152 + static int ccu_nkm_set_parent(struct clk_hw *hw, u8 index) 153 + { 154 + struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 155 + 156 + return ccu_mux_helper_set_parent(&nkm->common, &nkm->mux, index); 157 + } 158 + 156 159 const struct clk_ops ccu_nkm_ops = { 157 160 .disable = ccu_nkm_disable, 158 161 .enable = ccu_nkm_enable, 159 162 .is_enabled = ccu_nkm_is_enabled, 160 163 164 + .get_parent = ccu_nkm_get_parent, 165 + .set_parent = ccu_nkm_set_parent, 166 + 167 + .determine_rate = ccu_nkm_determine_rate, 161 168 .recalc_rate = ccu_nkm_recalc_rate, 162 - .round_rate = ccu_nkm_round_rate, 163 169 .set_rate = ccu_nkm_set_rate, 164 170 };
+23
drivers/clk/sunxi-ng/ccu_nkm.h
··· 32 32 struct _ccu_mult n; 33 33 struct _ccu_mult k; 34 34 struct _ccu_div m; 35 + struct ccu_mux_internal mux; 35 36 36 37 struct ccu_common common; 37 38 }; 39 + 40 + #define SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(_struct, _name, _parents, _reg, \ 41 + _nshift, _nwidth, \ 42 + _kshift, _kwidth, \ 43 + _mshift, _mwidth, \ 44 + _muxshift, _muxwidth, \ 45 + _gate, _lock, _flags) \ 46 + struct ccu_nkm _struct = { \ 47 + .enable = _gate, \ 48 + .lock = _lock, \ 49 + .k = _SUNXI_CCU_MULT(_kshift, _kwidth), \ 50 + .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ 51 + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 52 + .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \ 53 + .common = { \ 54 + .reg = _reg, \ 55 + .hw.init = CLK_HW_INIT_PARENTS(_name, \ 56 + _parents, \ 57 + &ccu_nkm_ops, \ 58 + _flags), \ 59 + }, \ 60 + } 38 61 39 62 #define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ 40 63 _nshift, _nwidth, \
+10 -11
drivers/clk/sunxi-ng/ccu_nkmp.c
··· 29 29 unsigned long _n, _k, _m, _p; 30 30 31 31 for (_k = 1; _k <= nkmp->max_k; _k++) { 32 - for (_p = 0; _p <= nkmp->max_p; _p++) { 32 + for (_p = 1; _p <= nkmp->max_p; _p <<= 1) { 33 33 unsigned long tmp_rate; 34 34 35 - rational_best_approximation(rate / _k, parent >> _p, 35 + rational_best_approximation(rate / _k, parent / _p, 36 36 nkmp->max_n, nkmp->max_m, 37 37 &_n, &_m); 38 38 39 - tmp_rate = (parent * _n * _k >> _p) / _m; 39 + tmp_rate = parent * _n * _k / (_m * _p); 40 40 41 41 if (tmp_rate > rate) 42 42 continue; ··· 110 110 111 111 _nkmp.max_n = 1 << nkmp->n.width; 112 112 _nkmp.max_k = 1 << nkmp->k.width; 113 - _nkmp.max_m = 1 << nkmp->m.width; 114 - _nkmp.max_p = (1 << nkmp->p.width) - 1; 113 + _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width; 114 + _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); 115 115 116 - ccu_nkmp_find_best(*parent_rate, rate, 117 - &_nkmp); 116 + ccu_nkmp_find_best(*parent_rate, rate, &_nkmp); 118 117 119 - return (*parent_rate * _nkmp.n * _nkmp.k >> _nkmp.p) / _nkmp.m; 118 + return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p); 120 119 } 121 120 122 121 static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, ··· 128 129 129 130 _nkmp.max_n = 1 << nkmp->n.width; 130 131 _nkmp.max_k = 1 << nkmp->k.width; 131 - _nkmp.max_m = 1 << nkmp->m.width; 132 - _nkmp.max_p = (1 << nkmp->p.width) - 1; 132 + _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width; 133 + _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1); 133 134 134 135 ccu_nkmp_find_best(parent_rate, rate, &_nkmp); 135 136 ··· 144 145 reg |= (_nkmp.n - 1) << nkmp->n.shift; 145 146 reg |= (_nkmp.k - 1) << nkmp->k.shift; 146 147 reg |= (_nkmp.m - 1) << nkmp->m.shift; 147 - reg |= _nkmp.p << nkmp->p.shift; 148 + reg |= ilog2(_nkmp.p) << nkmp->p.shift; 148 149 149 150 writel(reg, nkmp->common.base + nkmp->common.reg); 150 151
+10 -6
drivers/clk/sunxi-ng/ccu_nm.c
··· 61 61 unsigned long *parent_rate) 62 62 { 63 63 struct ccu_nm *nm = hw_to_ccu_nm(hw); 64 + unsigned long max_n, max_m; 64 65 unsigned long n, m; 65 66 66 - rational_best_approximation(rate, *parent_rate, 67 - 1 << nm->n.width, 1 << nm->m.width, 68 - &n, &m); 67 + max_n = 1 << nm->n.width; 68 + max_m = nm->m.max ?: 1 << nm->m.width; 69 + 70 + rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m); 69 71 70 72 return *parent_rate * n / m; 71 73 } ··· 77 75 { 78 76 struct ccu_nm *nm = hw_to_ccu_nm(hw); 79 77 unsigned long flags; 78 + unsigned long max_n, max_m; 80 79 unsigned long n, m; 81 80 u32 reg; 82 81 ··· 86 83 else 87 84 ccu_frac_helper_disable(&nm->common, &nm->frac); 88 85 89 - rational_best_approximation(rate, parent_rate, 90 - 1 << nm->n.width, 1 << nm->m.width, 91 - &n, &m); 86 + max_n = 1 << nm->n.width; 87 + max_m = nm->m.max ?: 1 << nm->m.width; 88 + 89 + rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m); 92 90 93 91 spin_lock_irqsave(nm->common.lock, flags); 94 92
+187
include/dt-bindings/clock/sun6i-a31-ccu.h
··· 1 + /* 2 + * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_ 44 + #define _DT_BINDINGS_CLK_SUN6I_A31_H_ 45 + 46 + #define CLK_PLL_PERIPH 10 47 + 48 + #define CLK_CPU 18 49 + 50 + #define CLK_AHB1_MIPIDSI 23 51 + #define CLK_AHB1_SS 24 52 + #define CLK_AHB1_DMA 25 53 + #define CLK_AHB1_MMC0 26 54 + #define CLK_AHB1_MMC1 27 55 + #define CLK_AHB1_MMC2 28 56 + #define CLK_AHB1_MMC3 29 57 + #define CLK_AHB1_NAND1 30 58 + #define CLK_AHB1_NAND0 31 59 + #define CLK_AHB1_SDRAM 32 60 + #define CLK_AHB1_EMAC 33 61 + #define CLK_AHB1_TS 34 62 + #define CLK_AHB1_HSTIMER 35 63 + #define CLK_AHB1_SPI0 36 64 + #define CLK_AHB1_SPI1 37 65 + #define CLK_AHB1_SPI2 38 66 + #define CLK_AHB1_SPI3 39 67 + #define CLK_AHB1_OTG 40 68 + #define CLK_AHB1_EHCI0 41 69 + #define CLK_AHB1_EHCI1 42 70 + #define CLK_AHB1_OHCI0 43 71 + #define CLK_AHB1_OHCI1 44 72 + #define CLK_AHB1_OHCI2 45 73 + #define CLK_AHB1_VE 46 74 + #define CLK_AHB1_LCD0 47 75 + #define CLK_AHB1_LCD1 48 76 + #define CLK_AHB1_CSI 49 77 + #define CLK_AHB1_HDMI 50 78 + #define CLK_AHB1_BE0 51 79 + #define CLK_AHB1_BE1 52 80 + #define CLK_AHB1_FE0 53 81 + #define CLK_AHB1_FE1 54 82 + #define CLK_AHB1_MP 55 83 + #define CLK_AHB1_GPU 56 84 + #define CLK_AHB1_DEU0 57 85 + #define CLK_AHB1_DEU1 58 86 + #define CLK_AHB1_DRC0 59 87 + #define CLK_AHB1_DRC1 60 88 + 89 + #define CLK_APB1_CODEC 61 90 + #define CLK_APB1_SPDIF 62 91 + #define CLK_APB1_DIGITAL_MIC 63 92 + #define CLK_APB1_PIO 64 93 + #define CLK_APB1_DAUDIO0 65 94 + #define CLK_APB1_DAUDIO1 66 95 + 96 + #define CLK_APB2_I2C0 67 97 + #define CLK_APB2_I2C1 68 98 + #define CLK_APB2_I2C2 69 99 + #define CLK_APB2_I2C3 70 100 + #define CLK_APB2_UART0 71 101 + #define CLK_APB2_UART1 72 102 + #define CLK_APB2_UART2 73 103 + #define CLK_APB2_UART3 74 104 + #define CLK_APB2_UART4 75 105 + #define CLK_APB2_UART5 76 106 + 107 + #define CLK_NAND0 77 108 + #define CLK_NAND1 78 109 + #define CLK_MMC0 79 110 + #define CLK_MMC0_SAMPLE 80 111 + #define CLK_MMC0_OUTPUT 81 112 + #define CLK_MMC1 82 113 + #define CLK_MMC1_SAMPLE 83 114 + #define CLK_MMC1_OUTPUT 84 115 + #define CLK_MMC2 85 116 + #define CLK_MMC2_SAMPLE 86 117 + #define CLK_MMC2_OUTPUT 87 118 + #define CLK_MMC3 88 119 + #define CLK_MMC3_SAMPLE 89 120 + #define CLK_MMC3_OUTPUT 90 121 + #define CLK_TS 91 122 + #define CLK_SS 92 123 + #define CLK_SPI0 93 124 + #define CLK_SPI1 94 125 + #define CLK_SPI2 95 126 + #define CLK_SPI3 96 127 + #define CLK_DAUDIO0 97 128 + #define CLK_DAUDIO1 98 129 + #define CLK_SPDIF 99 130 + #define CLK_USB_PHY0 100 131 + #define CLK_USB_PHY1 101 132 + #define CLK_USB_PHY2 102 133 + #define CLK_USB_OHCI0 103 134 + #define CLK_USB_OHCI1 104 135 + #define CLK_USB_OHCI2 105 136 + 137 + #define CLK_DRAM_VE 110 138 + #define CLK_DRAM_CSI_ISP 111 139 + #define CLK_DRAM_TS 112 140 + #define CLK_DRAM_DRC0 113 141 + #define CLK_DRAM_DRC1 114 142 + #define CLK_DRAM_DEU0 115 143 + #define CLK_DRAM_DEU1 116 144 + #define CLK_DRAM_FE0 117 145 + #define CLK_DRAM_FE1 118 146 + #define CLK_DRAM_BE0 119 147 + #define CLK_DRAM_BE1 120 148 + #define CLK_DRAM_MP 121 149 + 150 + #define CLK_BE0 122 151 + #define CLK_BE1 123 152 + #define CLK_FE0 124 153 + #define CLK_FE1 125 154 + #define CLK_MP 126 155 + #define CLK_LCD0_CH0 127 156 + #define CLK_LCD1_CH0 128 157 + #define CLK_LCD0_CH1 129 158 + #define CLK_LCD1_CH1 130 159 + #define CLK_CSI0_SCLK 131 160 + #define CLK_CSI0_MCLK 132 161 + #define CLK_CSI1_MCLK 133 162 + #define CLK_VE 134 163 + #define CLK_CODEC 135 164 + #define CLK_AVS 136 165 + #define CLK_DIGITAL_MIC 137 166 + #define CLK_HDMI 138 167 + #define CLK_HDMI_DDC 139 168 + #define CLK_PS 140 169 + 170 + #define CLK_MIPI_DSI 143 171 + #define CLK_MIPI_DSI_DPHY 144 172 + #define CLK_MIPI_CSI_DPHY 145 173 + #define CLK_IEP_DRC0 146 174 + #define CLK_IEP_DRC1 147 175 + #define CLK_IEP_DEU0 148 176 + #define CLK_IEP_DEU1 149 177 + #define CLK_GPU_CORE 150 178 + #define CLK_GPU_MEMORY 151 179 + #define CLK_GPU_HYD 152 180 + #define CLK_ATS 153 181 + #define CLK_TRACE 154 182 + 183 + #define CLK_OUT_A 155 184 + #define CLK_OUT_B 156 185 + #define CLK_OUT_C 157 186 + 187 + #endif /* _DT_BINDINGS_CLK_SUN6I_A31_H_ */
+127
include/dt-bindings/clock/sun8i-a23-a33-ccu.h
··· 1 + /* 2 + * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ 44 + #define _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ 45 + 46 + #define CLK_CPUX 18 47 + 48 + #define CLK_BUS_MIPI_DSI 23 49 + #define CLK_BUS_SS 24 50 + #define CLK_BUS_DMA 25 51 + #define CLK_BUS_MMC0 26 52 + #define CLK_BUS_MMC1 27 53 + #define CLK_BUS_MMC2 28 54 + #define CLK_BUS_NAND 29 55 + #define CLK_BUS_DRAM 30 56 + #define CLK_BUS_HSTIMER 31 57 + #define CLK_BUS_SPI0 32 58 + #define CLK_BUS_SPI1 33 59 + #define CLK_BUS_OTG 34 60 + #define CLK_BUS_EHCI 35 61 + #define CLK_BUS_OHCI 36 62 + #define CLK_BUS_VE 37 63 + #define CLK_BUS_LCD 38 64 + #define CLK_BUS_CSI 39 65 + #define CLK_BUS_DE_BE 40 66 + #define CLK_BUS_DE_FE 41 67 + #define CLK_BUS_GPU 42 68 + #define CLK_BUS_MSGBOX 43 69 + #define CLK_BUS_SPINLOCK 44 70 + #define CLK_BUS_DRC 45 71 + #define CLK_BUS_SAT 46 72 + #define CLK_BUS_CODEC 47 73 + #define CLK_BUS_PIO 48 74 + #define CLK_BUS_I2S0 49 75 + #define CLK_BUS_I2S1 50 76 + #define CLK_BUS_I2C0 51 77 + #define CLK_BUS_I2C1 52 78 + #define CLK_BUS_I2C2 53 79 + #define CLK_BUS_UART0 54 80 + #define CLK_BUS_UART1 55 81 + #define CLK_BUS_UART2 56 82 + #define CLK_BUS_UART3 57 83 + #define CLK_BUS_UART4 58 84 + #define CLK_NAND 59 85 + #define CLK_MMC0 60 86 + #define CLK_MMC0_SAMPLE 61 87 + #define CLK_MMC0_OUTPUT 62 88 + #define CLK_MMC1 63 89 + #define CLK_MMC1_SAMPLE 64 90 + #define CLK_MMC1_OUTPUT 65 91 + #define CLK_MMC2 66 92 + #define CLK_MMC2_SAMPLE 67 93 + #define CLK_MMC2_OUTPUT 68 94 + #define CLK_SS 69 95 + #define CLK_SPI0 70 96 + #define CLK_SPI1 71 97 + #define CLK_I2S0 72 98 + #define CLK_I2S1 73 99 + #define CLK_USB_PHY0 74 100 + #define CLK_USB_PHY1 75 101 + #define CLK_USB_HSIC 76 102 + #define CLK_USB_HSIC_12M 77 103 + #define CLK_USB_OHCI 78 104 + 105 + #define CLK_DRAM_VE 80 106 + #define CLK_DRAM_CSI 81 107 + #define CLK_DRAM_DRC 82 108 + #define CLK_DRAM_DE_FE 83 109 + #define CLK_DRAM_DE_BE 84 110 + #define CLK_DE_BE 85 111 + #define CLK_DE_FE 86 112 + #define CLK_LCD_CH0 87 113 + #define CLK_LCD_CH1 88 114 + #define CLK_CSI_SCLK 89 115 + #define CLK_CSI_MCLK 90 116 + #define CLK_VE 91 117 + #define CLK_AC_DIG 92 118 + #define CLK_AC_DIG_4X 93 119 + #define CLK_AVS 94 120 + 121 + #define CLK_DSI_SCLK 96 122 + #define CLK_DSI_DPHY 97 123 + #define CLK_DRC 98 124 + #define CLK_GPU 99 125 + #define CLK_ATS 100 126 + 127 + #endif /* _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ */
+106
include/dt-bindings/reset/sun6i-a31-ccu.h
··· 1 + /* 2 + * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_RST_SUN6I_A31_H_ 44 + #define _DT_BINDINGS_RST_SUN6I_A31_H_ 45 + 46 + #define RST_USB_PHY0 0 47 + #define RST_USB_PHY1 1 48 + #define RST_USB_PHY2 2 49 + 50 + #define RST_AHB1_MIPI_DSI 3 51 + #define RST_AHB1_SS 4 52 + #define RST_AHB1_DMA 5 53 + #define RST_AHB1_MMC0 6 54 + #define RST_AHB1_MMC1 7 55 + #define RST_AHB1_MMC2 8 56 + #define RST_AHB1_MMC3 9 57 + #define RST_AHB1_NAND1 10 58 + #define RST_AHB1_NAND0 11 59 + #define RST_AHB1_SDRAM 12 60 + #define RST_AHB1_EMAC 13 61 + #define RST_AHB1_TS 14 62 + #define RST_AHB1_HSTIMER 15 63 + #define RST_AHB1_SPI0 16 64 + #define RST_AHB1_SPI1 17 65 + #define RST_AHB1_SPI2 18 66 + #define RST_AHB1_SPI3 19 67 + #define RST_AHB1_OTG 20 68 + #define RST_AHB1_EHCI0 21 69 + #define RST_AHB1_EHCI1 22 70 + #define RST_AHB1_OHCI0 23 71 + #define RST_AHB1_OHCI1 24 72 + #define RST_AHB1_OHCI2 25 73 + #define RST_AHB1_VE 26 74 + #define RST_AHB1_LCD0 27 75 + #define RST_AHB1_LCD1 28 76 + #define RST_AHB1_CSI 29 77 + #define RST_AHB1_HDMI 30 78 + #define RST_AHB1_BE0 31 79 + #define RST_AHB1_BE1 32 80 + #define RST_AHB1_FE0 33 81 + #define RST_AHB1_FE1 34 82 + #define RST_AHB1_MP 35 83 + #define RST_AHB1_GPU 36 84 + #define RST_AHB1_DEU0 37 85 + #define RST_AHB1_DEU1 38 86 + #define RST_AHB1_DRC0 39 87 + #define RST_AHB1_DRC1 40 88 + #define RST_AHB1_LVDS 41 89 + 90 + #define RST_APB1_CODEC 42 91 + #define RST_APB1_SPDIF 43 92 + #define RST_APB1_DIGITAL_MIC 44 93 + #define RST_APB1_DAUDIO0 45 94 + #define RST_APB1_DAUDIO1 46 95 + #define RST_APB2_I2C0 47 96 + #define RST_APB2_I2C1 48 97 + #define RST_APB2_I2C2 49 98 + #define RST_APB2_I2C3 50 99 + #define RST_APB2_UART0 51 100 + #define RST_APB2_UART1 52 101 + #define RST_APB2_UART2 53 102 + #define RST_APB2_UART3 54 103 + #define RST_APB2_UART4 55 104 + #define RST_APB2_UART5 56 105 + 106 + #endif /* _DT_BINDINGS_RST_SUN6I_A31_H_ */
+87
include/dt-bindings/reset/sun8i-a23-a33-ccu.h
··· 1 + /* 2 + * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_RST_SUN8I_A23_A33_H_ 44 + #define _DT_BINDINGS_RST_SUN8I_A23_A33_H_ 45 + 46 + #define RST_USB_PHY0 0 47 + #define RST_USB_PHY1 1 48 + #define RST_USB_HSIC 2 49 + #define RST_MBUS 3 50 + #define RST_BUS_MIPI_DSI 4 51 + #define RST_BUS_SS 5 52 + #define RST_BUS_DMA 6 53 + #define RST_BUS_MMC0 7 54 + #define RST_BUS_MMC1 8 55 + #define RST_BUS_MMC2 9 56 + #define RST_BUS_NAND 10 57 + #define RST_BUS_DRAM 11 58 + #define RST_BUS_HSTIMER 12 59 + #define RST_BUS_SPI0 13 60 + #define RST_BUS_SPI1 14 61 + #define RST_BUS_OTG 15 62 + #define RST_BUS_EHCI 16 63 + #define RST_BUS_OHCI 17 64 + #define RST_BUS_VE 18 65 + #define RST_BUS_LCD 19 66 + #define RST_BUS_CSI 20 67 + #define RST_BUS_DE_BE 21 68 + #define RST_BUS_DE_FE 22 69 + #define RST_BUS_GPU 23 70 + #define RST_BUS_MSGBOX 24 71 + #define RST_BUS_SPINLOCK 25 72 + #define RST_BUS_DRC 26 73 + #define RST_BUS_SAT 27 74 + #define RST_BUS_LVDS 28 75 + #define RST_BUS_CODEC 29 76 + #define RST_BUS_I2S0 30 77 + #define RST_BUS_I2S1 31 78 + #define RST_BUS_I2C0 32 79 + #define RST_BUS_I2C1 33 80 + #define RST_BUS_I2C2 34 81 + #define RST_BUS_UART0 35 82 + #define RST_BUS_UART1 36 83 + #define RST_BUS_UART2 37 84 + #define RST_BUS_UART3 38 85 + #define RST_BUS_UART4 39 86 + 87 + #endif /* _DT_BINDINGS_RST_SUN8I_A23_A33_H_ */