0001
0002
0003
0004
0005
0006
0007 #include <linux/clk-provider.h>
0008 #include <linux/io.h>
0009 #include <linux/module.h>
0010 #include <linux/platform_device.h>
0011
0012 #include "ccu_common.h"
0013 #include "ccu_reset.h"
0014
0015 #include "ccu_div.h"
0016 #include "ccu_gate.h"
0017 #include "ccu_mp.h"
0018 #include "ccu_mult.h"
0019 #include "ccu_nk.h"
0020 #include "ccu_nkm.h"
0021 #include "ccu_nkmp.h"
0022 #include "ccu_nm.h"
0023 #include "ccu_phase.h"
0024
0025 #include "ccu-suniv-f1c100s.h"
0026
0027 static struct ccu_nkmp pll_cpu_clk = {
0028 .enable = BIT(31),
0029 .lock = BIT(28),
0030
0031 .n = _SUNXI_CCU_MULT(8, 5),
0032 .k = _SUNXI_CCU_MULT(4, 2),
0033 .m = _SUNXI_CCU_DIV(0, 2),
0034
0035 .p = _SUNXI_CCU_DIV_MAX(16, 2, 4),
0036
0037 .common = {
0038 .reg = 0x000,
0039 .hw.init = CLK_HW_INIT("pll-cpu", "osc24M",
0040 &ccu_nkmp_ops,
0041 CLK_SET_RATE_UNGATE),
0042 },
0043 };
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #define SUNIV_PLL_AUDIO_REG 0x008
0054
0055 static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
0056 "osc24M", 0x008,
0057 8, 7,
0058 0, 5,
0059 BIT(31),
0060 BIT(28),
0061 CLK_SET_RATE_UNGATE);
0062
0063 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
0064 "osc24M", 0x010,
0065 8, 7,
0066 0, 4,
0067 BIT(24),
0068 BIT(25),
0069 270000000,
0070 297000000,
0071 BIT(31),
0072 BIT(28),
0073 CLK_SET_RATE_UNGATE);
0074
0075 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
0076 "osc24M", 0x018,
0077 8, 7,
0078 0, 4,
0079 BIT(24),
0080 BIT(25),
0081 270000000,
0082 297000000,
0083 BIT(31),
0084 BIT(28),
0085 CLK_SET_RATE_UNGATE);
0086
0087 static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr",
0088 "osc24M", 0x020,
0089 8, 5,
0090 4, 2,
0091 0, 2,
0092 BIT(31),
0093 BIT(28),
0094 CLK_IS_CRITICAL);
0095
0096 static struct ccu_nk pll_periph_clk = {
0097 .enable = BIT(31),
0098 .lock = BIT(28),
0099 .k = _SUNXI_CCU_MULT(4, 2),
0100 .n = _SUNXI_CCU_MULT(8, 5),
0101 .common = {
0102 .reg = 0x028,
0103 .hw.init = CLK_HW_INIT("pll-periph", "osc24M",
0104 &ccu_nk_ops, 0),
0105 },
0106 };
0107
0108 static const char * const cpu_parents[] = { "osc32k", "osc24M",
0109 "pll-cpu", "pll-cpu" };
0110 static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents,
0111 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
0112
0113 static const char * const ahb_parents[] = { "osc32k", "osc24M",
0114 "cpu", "pll-periph" };
0115 static const struct ccu_mux_var_prediv ahb_predivs[] = {
0116 { .index = 3, .shift = 6, .width = 2 },
0117 };
0118 static struct ccu_div ahb_clk = {
0119 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
0120
0121 .mux = {
0122 .shift = 12,
0123 .width = 2,
0124
0125 .var_predivs = ahb_predivs,
0126 .n_var_predivs = ARRAY_SIZE(ahb_predivs),
0127 },
0128
0129 .common = {
0130 .reg = 0x054,
0131 .features = CCU_FEATURE_VARIABLE_PREDIV,
0132 .hw.init = CLK_HW_INIT_PARENTS("ahb",
0133 ahb_parents,
0134 &ccu_div_ops,
0135 0),
0136 },
0137 };
0138
0139 static struct clk_div_table apb_div_table[] = {
0140 { .val = 0, .div = 2 },
0141 { .val = 1, .div = 2 },
0142 { .val = 2, .div = 4 },
0143 { .val = 3, .div = 8 },
0144 { },
0145 };
0146 static SUNXI_CCU_DIV_TABLE(apb_clk, "apb", "ahb",
0147 0x054, 8, 2, apb_div_table, 0);
0148
0149 static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb",
0150 0x060, BIT(6), 0);
0151 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb",
0152 0x060, BIT(8), 0);
0153 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb",
0154 0x060, BIT(9), 0);
0155 static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb",
0156 0x060, BIT(14), 0);
0157 static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb",
0158 0x060, BIT(20), 0);
0159 static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb",
0160 0x060, BIT(21), 0);
0161 static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb",
0162 0x060, BIT(24), 0);
0163
0164 static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb",
0165 0x064, BIT(0), 0);
0166 static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb",
0167 0x064, BIT(4), 0);
0168 static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "ahb",
0169 0x064, BIT(5), 0);
0170 static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb",
0171 0x064, BIT(8), 0);
0172 static SUNXI_CCU_GATE(bus_tvd_clk, "bus-tvd", "ahb",
0173 0x064, BIT(9), 0);
0174 static SUNXI_CCU_GATE(bus_tve_clk, "bus-tve", "ahb",
0175 0x064, BIT(10), 0);
0176 static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb",
0177 0x064, BIT(12), 0);
0178 static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb",
0179 0x064, BIT(14), 0);
0180
0181 static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb",
0182 0x068, BIT(0), 0);
0183 static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb",
0184 0x068, BIT(1), 0);
0185 static SUNXI_CCU_GATE(bus_ir_clk, "bus-ir", "apb",
0186 0x068, BIT(2), 0);
0187 static SUNXI_CCU_GATE(bus_rsb_clk, "bus-rsb", "apb",
0188 0x068, BIT(3), 0);
0189 static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb",
0190 0x068, BIT(12), 0);
0191 static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb",
0192 0x068, BIT(16), 0);
0193 static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb",
0194 0x068, BIT(17), 0);
0195 static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb",
0196 0x068, BIT(18), 0);
0197 static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb",
0198 0x068, BIT(19), 0);
0199 static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb",
0200 0x068, BIT(20), 0);
0201 static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb",
0202 0x068, BIT(21), 0);
0203 static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb",
0204 0x068, BIT(22), 0);
0205
0206 static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
0207 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
0208 0, 4,
0209 16, 2,
0210 24, 2,
0211 BIT(31),
0212 0);
0213
0214 static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
0215 0x088, 20, 3, 0);
0216 static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
0217 0x088, 8, 3, 0);
0218
0219 static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
0220 0, 4,
0221 16, 2,
0222 24, 2,
0223 BIT(31),
0224 0);
0225
0226 static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
0227 0x08c, 20, 3, 0);
0228 static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
0229 0x08c, 8, 3, 0);
0230
0231 static const char * const i2s_spdif_parents[] = { "pll-audio-8x",
0232 "pll-audio-4x",
0233 "pll-audio-2x",
0234 "pll-audio" };
0235
0236 static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_spdif_parents,
0237 0x0b0, 16, 2, BIT(31), 0);
0238
0239 static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_spdif_parents,
0240 0x0b4, 16, 2, BIT(31), 0);
0241
0242
0243
0244 static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
0245 0x0cc, BIT(1), 0);
0246
0247 static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
0248 0x100, BIT(0), 0);
0249 static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr",
0250 0x100, BIT(1), 0);
0251 static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace",
0252 "pll-ddr", 0x100, BIT(2), 0);
0253 static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "pll-ddr",
0254 0x100, BIT(3), 0);
0255 static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr",
0256 0x100, BIT(24), 0);
0257 static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr",
0258 0x100, BIT(26), 0);
0259
0260 static const char * const de_parents[] = { "pll-video", "pll-periph" };
0261 static const u8 de_table[] = { 0, 2, };
0262 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be",
0263 de_parents, de_table,
0264 0x104, 0, 4, 24, 3, BIT(31), 0);
0265
0266 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe",
0267 de_parents, de_table,
0268 0x10c, 0, 4, 24, 3, BIT(31), 0);
0269
0270 static const char * const tcon_parents[] = { "pll-video", "pll-video-2x" };
0271 static const u8 tcon_table[] = { 0, 2, };
0272 static SUNXI_CCU_MUX_TABLE_WITH_GATE(tcon_clk, "tcon",
0273 tcon_parents, tcon_table,
0274 0x118, 24, 3, BIT(31),
0275 CLK_SET_RATE_PARENT);
0276
0277 static const char * const deinterlace_parents[] = { "pll-video",
0278 "pll-video-2x" };
0279 static const u8 deinterlace_table[] = { 0, 2, };
0280 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(deinterlace_clk, "deinterlace",
0281 deinterlace_parents, deinterlace_table,
0282 0x11c, 0, 4, 24, 3, BIT(31), 0);
0283
0284 static const char * const tve_clk2_parents[] = { "pll-video",
0285 "pll-video-2x" };
0286 static const u8 tve_clk2_table[] = { 0, 2, };
0287 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(tve_clk2_clk, "tve-clk2",
0288 tve_clk2_parents, tve_clk2_table,
0289 0x120, 0, 4, 24, 3, BIT(31), 0);
0290 static SUNXI_CCU_M_WITH_GATE(tve_clk1_clk, "tve-clk1", "tve-clk2",
0291 0x120, 8, 1, BIT(15), 0);
0292
0293 static const char * const tvd_parents[] = { "pll-video", "osc24M",
0294 "pll-video-2x" };
0295 static SUNXI_CCU_M_WITH_MUX_GATE(tvd_clk, "tvd", tvd_parents,
0296 0x124, 0, 4, 24, 3, BIT(31), 0);
0297
0298 static const char * const csi_parents[] = { "pll-video", "osc24M" };
0299 static const u8 csi_table[] = { 0, 5, };
0300 static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi", csi_parents, csi_table,
0301 0x120, 0, 4, 8, 3, BIT(15), 0);
0302
0303
0304
0305
0306
0307 static SUNXI_CCU_GATE(ve_clk, "ve", "pll-audio", 0x13c, BIT(31), 0);
0308
0309 static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", 0x140, BIT(31), 0);
0310
0311 static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 0x144, BIT(31), 0);
0312
0313 static struct ccu_common *suniv_ccu_clks[] = {
0314 &pll_cpu_clk.common,
0315 &pll_audio_base_clk.common,
0316 &pll_video_clk.common,
0317 &pll_ve_clk.common,
0318 &pll_ddr0_clk.common,
0319 &pll_periph_clk.common,
0320 &cpu_clk.common,
0321 &ahb_clk.common,
0322 &apb_clk.common,
0323 &bus_dma_clk.common,
0324 &bus_mmc0_clk.common,
0325 &bus_mmc1_clk.common,
0326 &bus_dram_clk.common,
0327 &bus_spi0_clk.common,
0328 &bus_spi1_clk.common,
0329 &bus_otg_clk.common,
0330 &bus_ve_clk.common,
0331 &bus_lcd_clk.common,
0332 &bus_deinterlace_clk.common,
0333 &bus_csi_clk.common,
0334 &bus_tve_clk.common,
0335 &bus_tvd_clk.common,
0336 &bus_de_be_clk.common,
0337 &bus_de_fe_clk.common,
0338 &bus_codec_clk.common,
0339 &bus_spdif_clk.common,
0340 &bus_ir_clk.common,
0341 &bus_rsb_clk.common,
0342 &bus_i2s0_clk.common,
0343 &bus_i2c0_clk.common,
0344 &bus_i2c1_clk.common,
0345 &bus_i2c2_clk.common,
0346 &bus_pio_clk.common,
0347 &bus_uart0_clk.common,
0348 &bus_uart1_clk.common,
0349 &bus_uart2_clk.common,
0350 &mmc0_clk.common,
0351 &mmc0_sample_clk.common,
0352 &mmc0_output_clk.common,
0353 &mmc1_clk.common,
0354 &mmc1_sample_clk.common,
0355 &mmc1_output_clk.common,
0356 &i2s_clk.common,
0357 &spdif_clk.common,
0358 &usb_phy0_clk.common,
0359 &dram_ve_clk.common,
0360 &dram_csi_clk.common,
0361 &dram_deinterlace_clk.common,
0362 &dram_tvd_clk.common,
0363 &dram_de_fe_clk.common,
0364 &dram_de_be_clk.common,
0365 &de_be_clk.common,
0366 &de_fe_clk.common,
0367 &tcon_clk.common,
0368 &deinterlace_clk.common,
0369 &tve_clk2_clk.common,
0370 &tve_clk1_clk.common,
0371 &tvd_clk.common,
0372 &csi_clk.common,
0373 &ve_clk.common,
0374 &codec_clk.common,
0375 &avs_clk.common,
0376 };
0377
0378 static const struct clk_hw *clk_parent_pll_audio[] = {
0379 &pll_audio_base_clk.common.hw
0380 };
0381
0382 static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
0383 clk_parent_pll_audio,
0384 4, 1, CLK_SET_RATE_PARENT);
0385 static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
0386 clk_parent_pll_audio,
0387 2, 1, CLK_SET_RATE_PARENT);
0388 static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
0389 clk_parent_pll_audio,
0390 1, 1, CLK_SET_RATE_PARENT);
0391 static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
0392 clk_parent_pll_audio,
0393 1, 2, CLK_SET_RATE_PARENT);
0394 static CLK_FIXED_FACTOR_HW(pll_video_2x_clk, "pll-video-2x",
0395 &pll_video_clk.common.hw,
0396 1, 2, 0);
0397
0398 static struct clk_hw_onecell_data suniv_hw_clks = {
0399 .hws = {
0400 [CLK_PLL_CPU] = &pll_cpu_clk.common.hw,
0401 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
0402 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
0403 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
0404 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
0405 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
0406 [CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
0407 [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw,
0408 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
0409 [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw,
0410 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
0411 [CLK_CPU] = &cpu_clk.common.hw,
0412 [CLK_AHB] = &ahb_clk.common.hw,
0413 [CLK_APB] = &apb_clk.common.hw,
0414 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
0415 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
0416 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
0417 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
0418 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
0419 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
0420 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
0421 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
0422 [CLK_BUS_LCD] = &bus_lcd_clk.common.hw,
0423 [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw,
0424 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
0425 [CLK_BUS_TVD] = &bus_tvd_clk.common.hw,
0426 [CLK_BUS_TVE] = &bus_tve_clk.common.hw,
0427 [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw,
0428 [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw,
0429 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
0430 [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw,
0431 [CLK_BUS_IR] = &bus_ir_clk.common.hw,
0432 [CLK_BUS_RSB] = &bus_rsb_clk.common.hw,
0433 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
0434 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
0435 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
0436 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
0437 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
0438 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
0439 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
0440 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
0441 [CLK_MMC0] = &mmc0_clk.common.hw,
0442 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
0443 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
0444 [CLK_MMC1] = &mmc1_clk.common.hw,
0445 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
0446 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
0447 [CLK_I2S] = &i2s_clk.common.hw,
0448 [CLK_SPDIF] = &spdif_clk.common.hw,
0449 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
0450 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
0451 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
0452 [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw,
0453 [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw,
0454 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
0455 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
0456 [CLK_DE_BE] = &de_be_clk.common.hw,
0457 [CLK_DE_FE] = &de_fe_clk.common.hw,
0458 [CLK_TCON] = &tcon_clk.common.hw,
0459 [CLK_DEINTERLACE] = &deinterlace_clk.common.hw,
0460 [CLK_TVE2_CLK] = &tve_clk2_clk.common.hw,
0461 [CLK_TVE1_CLK] = &tve_clk1_clk.common.hw,
0462 [CLK_TVD] = &tvd_clk.common.hw,
0463 [CLK_CSI] = &csi_clk.common.hw,
0464 [CLK_VE] = &ve_clk.common.hw,
0465 [CLK_CODEC] = &codec_clk.common.hw,
0466 [CLK_AVS] = &avs_clk.common.hw,
0467 },
0468 .num = CLK_NUMBER,
0469 };
0470
0471 static struct ccu_reset_map suniv_ccu_resets[] = {
0472 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
0473
0474 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
0475 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
0476 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
0477 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
0478 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
0479 [RST_BUS_SPI1] = { 0x2c0, BIT(21) },
0480 [RST_BUS_OTG] = { 0x2c0, BIT(24) },
0481 [RST_BUS_VE] = { 0x2c4, BIT(0) },
0482 [RST_BUS_LCD] = { 0x2c4, BIT(4) },
0483 [RST_BUS_DEINTERLACE] = { 0x2c4, BIT(5) },
0484 [RST_BUS_CSI] = { 0x2c4, BIT(8) },
0485 [RST_BUS_TVD] = { 0x2c4, BIT(9) },
0486 [RST_BUS_TVE] = { 0x2c4, BIT(10) },
0487 [RST_BUS_DE_BE] = { 0x2c4, BIT(12) },
0488 [RST_BUS_DE_FE] = { 0x2c4, BIT(14) },
0489 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
0490 [RST_BUS_SPDIF] = { 0x2d0, BIT(1) },
0491 [RST_BUS_IR] = { 0x2d0, BIT(2) },
0492 [RST_BUS_RSB] = { 0x2d0, BIT(3) },
0493 [RST_BUS_I2S0] = { 0x2d0, BIT(12) },
0494 [RST_BUS_I2C0] = { 0x2d0, BIT(16) },
0495 [RST_BUS_I2C1] = { 0x2d0, BIT(17) },
0496 [RST_BUS_I2C2] = { 0x2d0, BIT(18) },
0497 [RST_BUS_UART0] = { 0x2d0, BIT(20) },
0498 [RST_BUS_UART1] = { 0x2d0, BIT(21) },
0499 [RST_BUS_UART2] = { 0x2d0, BIT(22) },
0500 };
0501
0502 static const struct sunxi_ccu_desc suniv_ccu_desc = {
0503 .ccu_clks = suniv_ccu_clks,
0504 .num_ccu_clks = ARRAY_SIZE(suniv_ccu_clks),
0505
0506 .hw_clks = &suniv_hw_clks,
0507
0508 .resets = suniv_ccu_resets,
0509 .num_resets = ARRAY_SIZE(suniv_ccu_resets),
0510 };
0511
0512 static struct ccu_pll_nb suniv_pll_cpu_nb = {
0513 .common = &pll_cpu_clk.common,
0514
0515 .enable = BIT(31),
0516 .lock = BIT(28),
0517 };
0518
0519 static struct ccu_mux_nb suniv_cpu_nb = {
0520 .common = &cpu_clk.common,
0521 .cm = &cpu_clk.mux,
0522 .delay_us = 1,
0523 .bypass_index = 1,
0524 };
0525
0526 static int suniv_f1c100s_ccu_probe(struct platform_device *pdev)
0527 {
0528 void __iomem *reg;
0529 int ret;
0530 u32 val;
0531
0532 reg = devm_platform_ioremap_resource(pdev, 0);
0533 if (IS_ERR(reg))
0534 return PTR_ERR(reg);
0535
0536
0537 val = readl(reg + SUNIV_PLL_AUDIO_REG);
0538 val &= ~GENMASK(19, 16);
0539 writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
0540
0541 ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &suniv_ccu_desc);
0542 if (ret)
0543 return ret;
0544
0545
0546 ccu_pll_notifier_register(&suniv_pll_cpu_nb);
0547
0548
0549 ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
0550 &suniv_cpu_nb);
0551
0552 return 0;
0553 }
0554
0555 static const struct of_device_id suniv_f1c100s_ccu_ids[] = {
0556 { .compatible = "allwinner,suniv-f1c100s-ccu" },
0557 { }
0558 };
0559
0560 static struct platform_driver suniv_f1c100s_ccu_driver = {
0561 .probe = suniv_f1c100s_ccu_probe,
0562 .driver = {
0563 .name = "suniv-f1c100s-ccu",
0564 .suppress_bind_attrs = true,
0565 .of_match_table = suniv_f1c100s_ccu_ids,
0566 },
0567 };
0568 module_platform_driver(suniv_f1c100s_ccu_driver);
0569
0570 MODULE_IMPORT_NS(SUNXI_CCU);
0571 MODULE_LICENSE("GPL");