diff mbox

[6/10] clk: sunxi-ng: Add A10s CCU driver

Message ID 2110deed00d33bdb557efebe8f988976fbf5a440.1478625788.git-series.maxime.ripard@free-electrons.com (mailing list archive)
State Not Applicable, archived
Delegated to: Stephen Boyd
Headers show

Commit Message

Maxime Ripard Nov. 8, 2016, 5:23 p.m. UTC
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/clk/sunxi-ng/Kconfig          |  10 +-
 drivers/clk/sunxi-ng/Makefile         |   1 +-
 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c | 755 +++++++++++++++++++++++++++-
 drivers/clk/sunxi-ng/ccu-sun5i.h      | 129 +++++-
 4 files changed, 895 insertions(+), 0 deletions(-)
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
 create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i.h

Comments

Chen-Yu Tsai Nov. 13, 2016, 9:34 a.m. UTC | #1
On Wed, Nov 9, 2016 at 1:23 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/sunxi-ng/Kconfig          |  10 +-
>  drivers/clk/sunxi-ng/Makefile         |   1 +-
>  drivers/clk/sunxi-ng/ccu-sun5i-a10s.c | 755 +++++++++++++++++++++++++++-
>  drivers/clk/sunxi-ng/ccu-sun5i.h      | 129 +++++-
>  4 files changed, 895 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
>  create mode 100644 drivers/clk/sunxi-ng/ccu-sun5i.h
>
> diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
> index 8454c6e3dd65..e2becd36a1f9 100644
> --- a/drivers/clk/sunxi-ng/Kconfig
> +++ b/drivers/clk/sunxi-ng/Kconfig
> @@ -64,6 +64,16 @@ config SUN50I_A64_CCU
>         select SUNXI_CCU_PHASE
>         default ARM64 && ARCH_SUNXI
>
> +config SUN5I_A10S_CCU
> +       bool "Support for the Allwinner A10s CCM"
> +       select SUNXI_CCU_DIV
> +       select SUNXI_CCU_NK
> +       select SUNXI_CCU_NKM
> +       select SUNXI_CCU_NM
> +       select SUNXI_CCU_MP
> +       select SUNXI_CCU_PHASE
> +       default MACH_SUN5I
> +
>  config SUN6I_A31_CCU
>         bool "Support for the Allwinner A31/A31s CCU"
>         select SUNXI_CCU_DIV
> diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
> index 24fbc6e5deb8..79e9a166dc83 100644
> --- a/drivers/clk/sunxi-ng/Makefile
> +++ b/drivers/clk/sunxi-ng/Makefile
> @@ -19,6 +19,7 @@ obj-$(CONFIG_SUNXI_CCU_MP)    += ccu_mp.o
>
>  # SoC support
>  obj-$(CONFIG_SUN50I_A64_CCU)   += ccu-sun50i-a64.o
> +obj-$(CONFIG_SUN5I_A10S_CCU)   += ccu-sun5i-a10s.o
>  obj-$(CONFIG_SUN6I_A31_CCU)    += ccu-sun6i-a31.o
>  obj-$(CONFIG_SUN8I_A23_CCU)    += ccu-sun8i-a23.o
>  obj-$(CONFIG_SUN8I_A33_CCU)    += ccu-sun8i-a33.o
> diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
> new file mode 100644
> index 000000000000..94d9a5cbf60b
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
> @@ -0,0 +1,755 @@
> +/*
> + * Copyright (c) 2016 Maxime Ripard. All rights reserved.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +
> +#include "ccu_common.h"
> +#include "ccu_reset.h"
> +
> +#include "ccu_div.h"
> +#include "ccu_gate.h"
> +#include "ccu_mp.h"
> +#include "ccu_mult.h"
> +#include "ccu_nk.h"
> +#include "ccu_nkm.h"
> +#include "ccu_nkmp.h"
> +#include "ccu_nm.h"
> +#include "ccu_phase.h"
> +
> +#include "ccu-sun5i.h"
> +
> +static struct ccu_nkmp pll_core_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .m              = _SUNXI_CCU_DIV(0, 2),
> +       .p              = _SUNXI_CCU_DIV(16, 2),
> +       .common         = {
> +               .reg            = 0x000,
> +               .hw.init        = CLK_HW_INIT("pll-core",
> +                                             "hosc",
> +                                             &ccu_nkmp_ops,
> +                                             0),
> +       },
> +};
> +
> +/*
> + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
> + * the base (2x, 4x and 8x), and one variable divider (the one true
> + * pll audio).
> + *
> + * We don't have any need for the variable divider for now, so we just
> + * hardcode it to match with the clock names
> + */
> +#define SUN5I_PLL_AUDIO_REG    0x008
> +
> +static struct ccu_nm pll_audio_base_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
> +       .m              = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),

Nit: a note explaining that the datasheet is wrong would be nice.

> +       .common         = {
> +               .reg            = 0x008,
> +               .hw.init        = CLK_HW_INIT("pll-audio-base",
> +                                             "hosc",
> +                                             &ccu_nm_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_mult pll_video0_clk = {
> +       .enable         = BIT(31),
> +       .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
> +       .frac           = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
> +                                         270000000, 297000000),
> +       .common         = {
> +               .reg            = 0x010,
> +               .features       = CCU_FEATURE_FRACTIONAL,
> +               .hw.init        = CLK_HW_INIT("pll-video0",
> +                                             "osc3M",
> +                                             &ccu_mult_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_nkmp pll_ve_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .m              = _SUNXI_CCU_DIV(0, 2),
> +       .p              = _SUNXI_CCU_DIV(16, 2),

Any chance we'll support the bypass switch on this one?

> +       .common         = {
> +               .reg            = 0x018,
> +               .hw.init        = CLK_HW_INIT("pll-ve",
> +                                             "hosc",
> +                                             &ccu_nkmp_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_nk pll_ddr_base_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .common         = {
> +               .reg            = 0x020,
> +               .hw.init        = CLK_HW_INIT("pll-ddr-base",
> +                                             "hosc",
> +                                             &ccu_nk_ops,
> +                                             0),
> +       },
> +};
> +
> +static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);

Maybe we should set CLK_IS_CRITICAL on this one as well... in case the
bootloader uses pll-periph for mbus, and none of the dram gates are enabled.

> +
> +static struct ccu_div pll_ddr_other_clk = {
> +       .div            = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
> +
> +       .common         = {
> +               .reg            = 0x020,
> +               .hw.init        = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
> +                                             &ccu_div_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_nk pll_periph_clk = {
> +       .enable         = BIT(31),
> +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> +       .k              = _SUNXI_CCU_MULT(4, 2),
> +       .fixed_post_div = 2,
> +       .common         = {
> +               .reg            = 0x028,
> +               .features       = CCU_FEATURE_FIXED_POSTDIV,
> +               .hw.init        = CLK_HW_INIT("pll-periph",
> +                                             "hosc",
> +                                             &ccu_nk_ops,
> +                                             0),
> +       },
> +};
> +
> +static struct ccu_mult pll_video1_clk = {
> +       .enable         = BIT(31),
> +       .mult           = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
> +       .frac           = _SUNXI_CCU_FRAC(BIT(15), BIT(14),
> +                                 270000000, 297000000),
> +       .common         = {
> +               .reg            = 0x030,
> +               .features       = CCU_FEATURE_FRACTIONAL,
> +               .hw.init        = CLK_HW_INIT("pll-video1",
> +                                             "osc3M",
> +                                             &ccu_mult_ops,
> +                                             0),
> +       },
> +};
> +
> +static SUNXI_CCU_GATE(hosc_clk,        "hosc", "osc24M", 0x050, BIT(0), 0);

Why the extra "hosc" clock here? You should probably just internalize "osc24M".

> +
> +#define SUN5I_AHB_REG  0x054
> +static const char * const cpu_parents[] = { "osc32k", "hosc",
> +                                           "pll-core" , "pll-periph" };
> +static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
> +       { .index = 3, .div = 3, },
> +};
> +static struct ccu_mux cpu_clk = {
> +       .mux            = {
> +               .shift          = 16,
> +               .width          = 2,
> +               .fixed_predivs  = cpu_predivs,
> +               .n_predivs      = ARRAY_SIZE(cpu_predivs),
> +       },
> +       .common         = {
> +               .reg            = 0x054,
> +               .features       = CCU_FEATURE_FIXED_PREDIV,
> +               .hw.init        = CLK_HW_INIT_PARENTS("cpu",
> +                                                     cpu_parents,
> +                                                     &ccu_mux_ops,
> +                                                     CLK_IS_CRITICAL),
> +       }
> +};
> +
> +static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
> +
> +static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
> +static struct ccu_div ahb_clk = {
> +       .div            = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
> +       .mux            = _SUNXI_CCU_MUX(6, 2),

There's a fixed /2 pre-divider on pll-periph.

> +
> +       .common         = {
> +               .reg            = 0x054,
> +               .hw.init        = CLK_HW_INIT_PARENTS("ahb",
> +                                                     ahb_parents,
> +                                                     &ccu_div_ops,
> +                                                     0),
> +       },
> +};
> +
> +static struct clk_div_table apb0_div_table[] = {
> +       { .val = 0, .div = 2 },
> +       { .val = 1, .div = 2 },
> +       { .val = 2, .div = 4 },
> +       { .val = 3, .div = 8 },
> +       { /* Sentinel */ },
> +};
> +static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
> +                          0x054, 8, 2, apb0_div_table, 0);
> +
> +static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
> +static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
> +                            0, 5,      /* M */
> +                            16, 2,     /* P */
> +                            24, 2,     /* mux */
> +                            0);
> +
> +static SUNXI_CCU_GATE(axi_dram_clk,    "axi-dram",     "axi",
> +                     0x05c, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE(ahb_otg_clk,     "ahb-otg",      "ahb",
> +                     0x060, BIT(0), 0);
> +static SUNXI_CCU_GATE(ahb_ehci_clk,    "ahb-ehci",     "ahb",
> +                     0x060, BIT(1), 0);
> +static SUNXI_CCU_GATE(ahb_ohci_clk,    "ahb-ohci",     "ahb",
> +                     0x060, BIT(2), 0);
> +static SUNXI_CCU_GATE(ahb_ss_clk,      "ahb-ss",       "ahb",
> +                     0x060, BIT(5), 0);
> +static SUNXI_CCU_GATE(ahb_dma_clk,     "ahb-dma",      "ahb",
> +                     0x060, BIT(6), 0);
> +static SUNXI_CCU_GATE(ahb_bist_clk,    "ahb-bist",     "ahb",
> +                     0x060, BIT(6), 0);
> +static SUNXI_CCU_GATE(ahb_mmc0_clk,    "ahb-mmc0",     "ahb",
> +                     0x060, BIT(8), 0);
> +static SUNXI_CCU_GATE(ahb_mmc1_clk,    "ahb-mmc1",     "ahb",
> +                     0x060, BIT(9), 0);
> +static SUNXI_CCU_GATE(ahb_mmc2_clk,    "ahb-mmc2",     "ahb",
> +                     0x060, BIT(10), 0);
> +static SUNXI_CCU_GATE(ahb_nand_clk,    "ahb-nand",     "ahb",
> +                     0x060, BIT(13), 0);
> +static SUNXI_CCU_GATE(ahb_sdram_clk,   "ahb-sdram",    "ahb",
> +                     0x060, BIT(14), CLK_IS_CRITICAL);
> +static SUNXI_CCU_GATE(ahb_emac_clk,    "ahb-emac",     "ahb",
> +                     0x060, BIT(17), 0);
> +static SUNXI_CCU_GATE(ahb_ts_clk,      "ahb-ts",       "ahb",
> +                     0x060, BIT(18), 0);
> +static SUNXI_CCU_GATE(ahb_spi0_clk,    "ahb-spi0",     "ahb",
> +                     0x060, BIT(20), 0);
> +static SUNXI_CCU_GATE(ahb_spi1_clk,    "ahb-spi1",     "ahb",
> +                     0x060, BIT(21), 0);
> +static SUNXI_CCU_GATE(ahb_spi2_clk,    "ahb-spi2",     "ahb",
> +                     0x060, BIT(22), 0);
> +static SUNXI_CCU_GATE(ahb_gps_clk,     "ahb-gps",      "ahb",
> +                     0x060, BIT(26), 0);
> +static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer",  "ahb",
> +                     0x060, BIT(28), 0);
> +
> +static SUNXI_CCU_GATE(ahb_ve_clk,      "ahb-ve",       "ahb",
> +                     0x064, BIT(0), 0);
> +static SUNXI_CCU_GATE(ahb_tve_clk,     "ahb-tve",      "ahb",
> +                     0x064, BIT(2), 0);
> +static SUNXI_CCU_GATE(ahb_lcd_clk,     "ahb-lcd",      "ahb",
> +                     0x064, BIT(4), 0);
> +static SUNXI_CCU_GATE(ahb_csi_clk,     "ahb-csi",      "ahb",
> +                     0x064, BIT(8), 0);
> +static SUNXI_CCU_GATE(ahb_hdmi_clk,    "ahb-hdmi",     "ahb",
> +                     0x064, BIT(11), 0);
> +static SUNXI_CCU_GATE(ahb_de_be_clk,   "ahb-de-be",    "ahb",
> +                     0x064, BIT(12), 0);
> +static SUNXI_CCU_GATE(ahb_de_fe_clk,   "ahb-de-fe",    "ahb",
> +                     0x064, BIT(14), 0);
> +static SUNXI_CCU_GATE(ahb_iep_clk,     "ahb-iep",      "ahb",
> +                     0x064, BIT(19), 0);
> +static SUNXI_CCU_GATE(ahb_gpu_clk,     "ahb-gpu",      "ahb",
> +                     0x064, BIT(20), 0);
> +
> +static SUNXI_CCU_GATE(apb0_codec_clk,  "apb0-codec",   "apb0",
> +                     0x068, BIT(0), 0);
> +static SUNXI_CCU_GATE(apb0_i2s_clk,    "apb0-i2s",     "apb0",
> +                     0x068, BIT(3), 0);
> +static SUNXI_CCU_GATE(apb0_pio_clk,    "apb0-pio",     "apb0",
> +                     0x068, BIT(5), 0);
> +static SUNXI_CCU_GATE(apb0_ir_clk,     "apb0-ir",      "apb0",
> +                     0x068, BIT(6), 0);
> +static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad",  "apb0",
> +                     0x068, BIT(10), 0);
> +
> +static SUNXI_CCU_GATE(apb1_i2c0_clk,   "apb1-i2c0",    "apb1",
> +                     0x06c, BIT(0), 0);
> +static SUNXI_CCU_GATE(apb1_i2c1_clk,   "apb1-i2c1",    "apb1",
> +                     0x06c, BIT(1), 0);
> +static SUNXI_CCU_GATE(apb1_i2c2_clk,   "apb1-i2c2",    "apb1",
> +                     0x06c, BIT(2), 0);
> +static SUNXI_CCU_GATE(apb1_uart0_clk,  "apb1-uart0",   "apb1",
> +                     0x06c, BIT(16), 0);
> +static SUNXI_CCU_GATE(apb1_uart1_clk,  "apb1-uart1",   "apb1",
> +                     0x06c, BIT(17), 0);
> +static SUNXI_CCU_GATE(apb1_uart2_clk,  "apb1-uart2",   "apb1",
> +                     0x06c, BIT(18), 0);
> +static SUNXI_CCU_GATE(apb1_uart3_clk,  "apb1-uart3",   "apb1",
> +                     0x06c, BIT(19), 0);
> +
> +static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
> +                                                    "pll-ddr-other" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
> +                                 0, 4,         /* M */
> +                                 16, 2,        /* P */
> +                                 24, 2,        /* mux */
> +                                 BIT(31),      /* gate */
> +                                 0);
> +
> +static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
> +                                           "pll-audio-2x", "pll-audio" };
> +static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_parents,
> +                              0x0b8, 16, 2, BIT(31), 0);

CLK_SET_RATE_PARENT please.

> +
> +static const char * const keypad_parents[] = { "hosc", "losc"};
> +static const u8 keypad_table[] = { 0, 2 };
> +static struct ccu_mp keypad_clk = {
> +       .enable         = BIT(31),
> +       .m              = _SUNXI_CCU_DIV(8, 5),
> +       .p              = _SUNXI_CCU_DIV(20, 2),
> +       .mux            = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
> +
> +       .common         = {
> +               .reg            = 0x0c4,
> +               .hw.init        = CLK_HW_INIT_PARENTS("keypad",
> +                                                     keypad_parents,
> +                                                     &ccu_mp_ops,
> +                                                     0),
> +       },
> +};
> +
> +static SUNXI_CCU_GATE(usb_ohci_clk,    "usb-ohci",     "pll-periph",
> +                     0x0cc, BIT(6), 0);
> +static SUNXI_CCU_GATE(usb_phy0_clk,    "usb-phy0",     "pll-periph",
> +                     0x0cc, BIT(8), 0);
> +static SUNXI_CCU_GATE(usb_phy1_clk,    "usb-phy1",     "pll-periph",
> +                     0x0cc, BIT(9), 0);
> +
> +static const char * const gps_parents[] = { "hosc", "pll-periph",
> +                                           "pll-video1", "pll-ve" };
> +static SUNXI_CCU_M_WITH_MUX_GATE(gps_clk, "gps", gps_parents,
> +                                0x0d0, 0, 3, 24, 2, BIT(31), 0);
> +
> +static SUNXI_CCU_GATE(dram_ve_clk,     "dram-ve",      "pll-ddr",
> +                     0x100, BIT(0), 0);
> +static SUNXI_CCU_GATE(dram_csi_clk,    "dram-csi",     "pll-ddr",
> +                     0x100, BIT(1), 0);
> +static SUNXI_CCU_GATE(dram_ts_clk,     "dram-ts",      "pll-ddr",
> +                     0x100, BIT(3), 0);
> +static SUNXI_CCU_GATE(dram_tve_clk,    "dram-tve",     "pll-ddr",
> +                     0x100, BIT(5), 0);
> +static SUNXI_CCU_GATE(dram_de_fe_clk,  "dram-de-fe",   "pll-ddr",
> +                     0x100, BIT(25), 0);
> +static SUNXI_CCU_GATE(dram_de_be_clk,  "dram-de-be",   "pll-ddr",
> +                     0x100, BIT(26), 0);
> +static SUNXI_CCU_GATE(dram_ace_clk,    "dram-ace",     "pll-ddr",
> +                     0x100, BIT(29), 0);
> +static SUNXI_CCU_GATE(dram_iep_clk,    "dram-iep",     "pll-ddr",
> +                     0x100, BIT(31), 0);
> +
> +static const char * const de_parents[] = { "pll-video0", "pll-video1",
> +                                          "pll-ddr-other" };
> +static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
> +                                0x104, 0, 4, 24, 2, BIT(31), 0);
> +
> +static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
> +                                0x10c, 0, 4, 24, 2, BIT(31), 0);
> +
> +static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
> +                                            "pll-video0-2x", "pll-video1-2x" };
> +static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
> +                              0x118, 24, 2, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
> +                                tcon_parents,
> +                                0x12c, 0, 4, 24, 2, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
> +                            0x12c, 11, 1, BIT(15), 0);

CLK_SET_RATE_PARENT?

> +
> +static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
> +                                           "pll-video0-2x", "pll-video1-2x" };
> +static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
> +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
> +                                      csi_parents, csi_table,
> +                                      0x134, 0, 5, 24, 2, BIT(31), 0);

Do you know if CSI needs to change the module clock?

> +
> +static SUNXI_CCU_GATE(ve_clk,          "ve",           "pll-ve",
> +                     0x13c, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_GATE(codec_clk,       "codec",        "pll-audio",
> +                     0x140, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static SUNXI_CCU_GATE(avs_clk,         "avs",          "hosc",
> +                     0x144, BIT(31), 0);
> +
> +static const char * const hdmi_parents[] = { "pll-video0", "pll-video0-2x" };
> +static const u8 hdmi_table[] = { 0, 2 };
> +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
> +                                      hdmi_parents, hdmi_table,
> +                                      0x150, 0, 4, 24, 2, BIT(31), 0);

CLK_SET_RATE_PARENT?

> +
> +static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
> +                                           "pll-ddr-other", "pll-video1",
> +                                           "pll-video1-2x" };
> +static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
> +                                0x154, 0, 4, 24, 3, BIT(31), 0);
> +
> +static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
> +static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
> +                                 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
> +
> +static SUNXI_CCU_GATE(iep_clk,         "iep",          "de-be",
> +                     0x160, BIT(31), 0);
> +
> +static struct ccu_common *sun5i_a10s_ccu_clks[] = {
> +       &hosc_clk.common,
> +       &pll_core_clk.common,
> +       &pll_audio_base_clk.common,
> +       &pll_video0_clk.common,
> +       &pll_ve_clk.common,
> +       &pll_ddr_base_clk.common,
> +       &pll_ddr_clk.common,
> +       &pll_ddr_other_clk.common,
> +       &pll_periph_clk.common,
> +       &pll_video1_clk.common,
> +       &cpu_clk.common,
> +       &axi_clk.common,
> +       &ahb_clk.common,
> +       &apb0_clk.common,
> +       &apb1_clk.common,
> +       &axi_dram_clk.common,
> +       &ahb_otg_clk.common,
> +       &ahb_ehci_clk.common,
> +       &ahb_ohci_clk.common,
> +       &ahb_ss_clk.common,
> +       &ahb_dma_clk.common,
> +       &ahb_bist_clk.common,
> +       &ahb_mmc0_clk.common,
> +       &ahb_mmc1_clk.common,
> +       &ahb_mmc2_clk.common,
> +       &ahb_nand_clk.common,
> +       &ahb_sdram_clk.common,
> +       &ahb_emac_clk.common,
> +       &ahb_ts_clk.common,
> +       &ahb_spi0_clk.common,
> +       &ahb_spi1_clk.common,
> +       &ahb_spi2_clk.common,
> +       &ahb_gps_clk.common,
> +       &ahb_hstimer_clk.common,
> +       &ahb_ve_clk.common,
> +       &ahb_tve_clk.common,
> +       &ahb_lcd_clk.common,
> +       &ahb_csi_clk.common,
> +       &ahb_hdmi_clk.common,
> +       &ahb_de_be_clk.common,
> +       &ahb_de_fe_clk.common,
> +       &ahb_iep_clk.common,
> +       &ahb_gpu_clk.common,
> +       &apb0_codec_clk.common,
> +       &apb0_i2s_clk.common,
> +       &apb0_pio_clk.common,
> +       &apb0_ir_clk.common,
> +       &apb0_keypad_clk.common,
> +       &apb1_i2c0_clk.common,
> +       &apb1_i2c1_clk.common,
> +       &apb1_i2c2_clk.common,
> +       &apb1_uart0_clk.common,
> +       &apb1_uart1_clk.common,
> +       &apb1_uart2_clk.common,
> +       &apb1_uart3_clk.common,
> +       &nand_clk.common,
> +       &mmc0_clk.common,
> +       &mmc1_clk.common,
> +       &mmc2_clk.common,
> +       &ts_clk.common,
> +       &ss_clk.common,
> +       &spi0_clk.common,
> +       &spi1_clk.common,
> +       &spi2_clk.common,
> +       &ir_clk.common,
> +       &i2s_clk.common,
> +       &keypad_clk.common,
> +       &usb_ohci_clk.common,
> +       &usb_phy0_clk.common,
> +       &usb_phy1_clk.common,
> +       &gps_clk.common,
> +       &dram_ve_clk.common,
> +       &dram_csi_clk.common,
> +       &dram_ts_clk.common,
> +       &dram_tve_clk.common,
> +       &dram_de_fe_clk.common,
> +       &dram_de_be_clk.common,
> +       &dram_ace_clk.common,
> +       &dram_iep_clk.common,
> +       &de_be_clk.common,
> +       &de_fe_clk.common,
> +       &tcon_ch0_clk.common,
> +       &tcon_ch1_sclk2_clk.common,
> +       &tcon_ch1_sclk1_clk.common,
> +       &csi_clk.common,
> +       &ve_clk.common,
> +       &codec_clk.common,
> +       &avs_clk.common,
> +       &hdmi_clk.common,
> +       &gpu_clk.common,
> +       &mbus_clk.common,
> +       &iep_clk.common,
> +};
> +
> +static CLK_FIXED_FACTOR(osc3M_clk, "osc3M", "hosc", 8, 1, 0);
> +/* We hardcode the divider to 4 for now */
> +static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
> +                       "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
> +                       "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
> +                       "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
> +                       "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
> +                       "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
> +static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
> +                       "pll-video1", 1, 2, CLK_SET_RATE_PARENT);
> +
> +static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
> +       .hws    = {
> +               [CLK_HOSC]              = &hosc_clk.common.hw,
> +               [CLK_OSC3M]             = &osc3M_clk.hw,
> +               [CLK_PLL_CORE]          = &pll_core_clk.common.hw,
> +               [CLK_PLL_AUDIO_BASE]    = &pll_audio_base_clk.common.hw,
> +               [CLK_PLL_AUDIO]         = &pll_audio_clk.hw,
> +               [CLK_PLL_AUDIO_2X]      = &pll_audio_2x_clk.hw,
> +               [CLK_PLL_AUDIO_4X]      = &pll_audio_4x_clk.hw,
> +               [CLK_PLL_AUDIO_8X]      = &pll_audio_8x_clk.hw,
> +               [CLK_PLL_VIDEO0]        = &pll_video0_clk.common.hw,
> +               [CLK_PLL_VIDEO0_2X]     = &pll_video0_2x_clk.hw,
> +               [CLK_PLL_VE]            = &pll_ve_clk.common.hw,
> +               [CLK_PLL_DDR_BASE]      = &pll_ddr_base_clk.common.hw,
> +               [CLK_PLL_DDR]           = &pll_ddr_clk.common.hw,
> +               [CLK_PLL_DDR_OTHER]     = &pll_ddr_other_clk.common.hw,
> +               [CLK_PLL_PERIPH]        = &pll_periph_clk.common.hw,
> +               [CLK_PLL_VIDEO1]        = &pll_video1_clk.common.hw,
> +               [CLK_PLL_VIDEO1_2X]     = &pll_video1_2x_clk.hw,
> +               [CLK_CPU]               = &cpu_clk.common.hw,
> +               [CLK_AXI]               = &axi_clk.common.hw,
> +               [CLK_AHB]               = &ahb_clk.common.hw,
> +               [CLK_APB0]              = &apb0_clk.common.hw,
> +               [CLK_APB1]              = &apb1_clk.common.hw,
> +               [CLK_DRAM_AXI]          = &axi_dram_clk.common.hw,
> +               [CLK_AHB_OTG]           = &ahb_otg_clk.common.hw,
> +               [CLK_AHB_EHCI]          = &ahb_ehci_clk.common.hw,
> +               [CLK_AHB_OHCI]          = &ahb_ohci_clk.common.hw,
> +               [CLK_AHB_SS]            = &ahb_ss_clk.common.hw,
> +               [CLK_AHB_DMA]           = &ahb_dma_clk.common.hw,
> +               [CLK_AHB_BIST]          = &ahb_bist_clk.common.hw,
> +               [CLK_AHB_MMC0]          = &ahb_mmc0_clk.common.hw,
> +               [CLK_AHB_MMC1]          = &ahb_mmc1_clk.common.hw,
> +               [CLK_AHB_MMC2]          = &ahb_mmc2_clk.common.hw,
> +               [CLK_AHB_NAND]          = &ahb_nand_clk.common.hw,
> +               [CLK_AHB_SDRAM]         = &ahb_sdram_clk.common.hw,
> +               [CLK_AHB_EMAC]          = &ahb_emac_clk.common.hw,
> +               [CLK_AHB_TS]            = &ahb_ts_clk.common.hw,
> +               [CLK_AHB_SPI0]          = &ahb_spi0_clk.common.hw,
> +               [CLK_AHB_SPI1]          = &ahb_spi1_clk.common.hw,
> +               [CLK_AHB_SPI2]          = &ahb_spi2_clk.common.hw,
> +               [CLK_AHB_GPS]           = &ahb_gps_clk.common.hw,
> +               [CLK_AHB_HSTIMER]       = &ahb_hstimer_clk.common.hw,
> +               [CLK_AHB_VE]            = &ahb_ve_clk.common.hw,
> +               [CLK_AHB_TVE]           = &ahb_tve_clk.common.hw,
> +               [CLK_AHB_LCD]           = &ahb_lcd_clk.common.hw,
> +               [CLK_AHB_CSI]           = &ahb_csi_clk.common.hw,
> +               [CLK_AHB_HDMI]          = &ahb_hdmi_clk.common.hw,
> +               [CLK_AHB_DE_BE]         = &ahb_de_be_clk.common.hw,
> +               [CLK_AHB_DE_FE]         = &ahb_de_fe_clk.common.hw,
> +               [CLK_AHB_IEP]           = &ahb_iep_clk.common.hw,
> +               [CLK_AHB_GPU]           = &ahb_gpu_clk.common.hw,
> +               [CLK_APB0_CODEC]        = &apb0_codec_clk.common.hw,
> +               [CLK_APB0_I2S]          = &apb0_i2s_clk.common.hw,
> +               [CLK_APB0_PIO]          = &apb0_pio_clk.common.hw,
> +               [CLK_APB0_IR]           = &apb0_ir_clk.common.hw,
> +               [CLK_APB0_KEYPAD]       = &apb0_keypad_clk.common.hw,
> +               [CLK_APB1_I2C0]         = &apb1_i2c0_clk.common.hw,
> +               [CLK_APB1_I2C1]         = &apb1_i2c1_clk.common.hw,
> +               [CLK_APB1_I2C2]         = &apb1_i2c2_clk.common.hw,
> +               [CLK_APB1_UART0]        = &apb1_uart0_clk.common.hw,
> +               [CLK_APB1_UART1]        = &apb1_uart1_clk.common.hw,
> +               [CLK_APB1_UART2]        = &apb1_uart2_clk.common.hw,
> +               [CLK_APB1_UART3]        = &apb1_uart3_clk.common.hw,
> +               [CLK_NAND]              = &nand_clk.common.hw,
> +               [CLK_MMC0]              = &mmc0_clk.common.hw,
> +               [CLK_MMC1]              = &mmc1_clk.common.hw,
> +               [CLK_MMC2]              = &mmc2_clk.common.hw,
> +               [CLK_TS]                = &ts_clk.common.hw,
> +               [CLK_SS]                = &ss_clk.common.hw,
> +               [CLK_SPI0]              = &spi0_clk.common.hw,
> +               [CLK_SPI1]              = &spi1_clk.common.hw,
> +               [CLK_SPI2]              = &spi2_clk.common.hw,
> +               [CLK_IR]                = &ir_clk.common.hw,
> +               [CLK_I2S]               = &i2s_clk.common.hw,
> +               [CLK_KEYPAD]            = &keypad_clk.common.hw,
> +               [CLK_USB_OHCI]          = &usb_ohci_clk.common.hw,
> +               [CLK_USB_PHY0]          = &usb_phy0_clk.common.hw,
> +               [CLK_USB_PHY1]          = &usb_phy1_clk.common.hw,
> +               [CLK_GPS]               = &gps_clk.common.hw,
> +               [CLK_DRAM_VE]           = &dram_ve_clk.common.hw,
> +               [CLK_DRAM_CSI]          = &dram_csi_clk.common.hw,
> +               [CLK_DRAM_TS]           = &dram_ts_clk.common.hw,
> +               [CLK_DRAM_TVE]          = &dram_tve_clk.common.hw,
> +               [CLK_DRAM_DE_FE]        = &dram_de_fe_clk.common.hw,
> +               [CLK_DRAM_DE_BE]        = &dram_de_be_clk.common.hw,
> +               [CLK_DRAM_ACE]          = &dram_ace_clk.common.hw,
> +               [CLK_DRAM_IEP]          = &dram_iep_clk.common.hw,
> +               [CLK_DE_BE]             = &de_be_clk.common.hw,
> +               [CLK_DE_FE]             = &de_fe_clk.common.hw,
> +               [CLK_TCON_CH0]          = &tcon_ch0_clk.common.hw,
> +               [CLK_TCON_CH1_SCLK]     = &tcon_ch1_sclk2_clk.common.hw,
> +               [CLK_TCON_CH1]          = &tcon_ch1_sclk1_clk.common.hw,
> +               [CLK_CSI]               = &csi_clk.common.hw,
> +               [CLK_VE]                = &ve_clk.common.hw,
> +               [CLK_CODEC]             = &codec_clk.common.hw,
> +               [CLK_AVS]               = &avs_clk.common.hw,
> +               [CLK_HDMI]              = &hdmi_clk.common.hw,
> +               [CLK_GPU]               = &gpu_clk.common.hw,
> +               [CLK_MBUS]              = &mbus_clk.common.hw,
> +               [CLK_IEP]               = &iep_clk.common.hw,
> +       },
> +       .num    = CLK_NUMBER,
> +};
> +
> +static struct ccu_reset_map sun5i_a10s_ccu_resets[] = {
> +       [RST_USB_PHY0]          =  { 0x0cc, BIT(0) },
> +       [RST_USB_PHY1]          =  { 0x0cc, BIT(1) },
> +
> +       [RST_GPS]               =  { 0x0d0, BIT(30) },
> +
> +       [RST_DE_BE]             =  { 0x104, BIT(30) },
> +
> +       [RST_DE_FE]             =  { 0x10c, BIT(30) },
> +
> +       [RST_TVE]               =  { 0x118, BIT(29) },
> +       [RST_LCD]               =  { 0x118, BIT(30) },
> +
> +       [RST_CSI]               =  { 0x134, BIT(30) },
> +
> +       [RST_VE]                =  { 0x13c, BIT(0) },
> +
> +       [RST_GPU]               =  { 0x154, BIT(30) },
> +
> +       [RST_IEP]               =  { 0x160, BIT(30) },
> +};
> +
> +static const struct sunxi_ccu_desc sun5i_a10s_ccu_desc = {
> +       .ccu_clks       = sun5i_a10s_ccu_clks,
> +       .num_ccu_clks   = ARRAY_SIZE(sun5i_a10s_ccu_clks),
> +
> +       .hw_clks        = &sun5i_a10s_hw_clks,
> +
> +       .resets         = sun5i_a10s_ccu_resets,
> +       .num_resets     = ARRAY_SIZE(sun5i_a10s_ccu_resets),
> +};
> +
> +static void __init sun5i_a10s_ccu_setup(struct device_node *node)
> +{
> +       void __iomem *reg;
> +       u32 val;
> +
> +       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> +       if (IS_ERR(reg)) {
> +               pr_err("%s: Could not map the clock registers\n",
> +                      of_node_full_name(node));
> +               return;
> +       }
> +
> +       /* Force the PLL-Audio-1x divider to 4 */
> +       val = readl(reg + SUN5I_PLL_AUDIO_REG);
> +       val &= ~GENMASK(19, 16);
> +       writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
> +
> +       /*
> +        * Use the peripheral PLL as the AHB parent, instead of CPU /
> +        * AXI which have rate changes due to cpufreq.
> +        *
> +        * This is especially a big deal for the HS timer whose parent
> +        * clock is AHB.
> +        */
> +       val = readl(reg + SUN5I_AHB_REG);
> +       val &= ~GENMASK(7, 6);
> +       writel(val | (2 << 6), reg + SUN5I_AHB_REG);
> +
> +       sunxi_ccu_probe(node, reg, &sun5i_a10s_ccu_desc);
> +}
> +CLK_OF_DECLARE(sun5i_a10s_ccu, "allwinner,sun5i-a10s-ccu",
> +              sun5i_a10s_ccu_setup);
> diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
> new file mode 100644
> index 000000000000..43f2ce3e9e6e
> --- /dev/null
> +++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
> @@ -0,0 +1,129 @@
> +/*
> + * Copyright 2016 Maxime Ripard
> + *
> + * Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#ifndef _CCU_SUN5I_H_
> +#define _CCU_SUN5I_H_
> +
> +#include <dt-bindings/clock/sun5i-ccu.h>
> +#include <dt-bindings/reset/sun5i-ccu.h>
> +
> +#define CLK_HOSC               1
> +#define CLK_OSC3M              2
> +#define CLK_PLL_CORE           3
> +#define CLK_PLL_AUDIO_BASE     4
> +#define CLK_PLL_AUDIO          5
> +#define CLK_PLL_AUDIO_2X       6
> +#define CLK_PLL_AUDIO_4X       7
> +#define CLK_PLL_AUDIO_8X       8
> +#define CLK_PLL_VIDEO0         9
> +#define CLK_PLL_VIDEO0_2X      10
> +#define CLK_PLL_VE             11
> +#define CLK_PLL_DDR_BASE       12
> +#define CLK_PLL_DDR            13
> +#define CLK_PLL_DDR_OTHER      14
> +#define CLK_PLL_PERIPH         15
> +#define CLK_PLL_VIDEO1         16
> +#define CLK_PLL_VIDEO1_2X      17
> +#define CLK_OSC24M             18
> +#define CLK_CPU                        19
> +#define CLK_AXI                        20
> +#define CLK_AHB                        21
> +#define CLK_APB0               22
> +#define CLK_APB1               23
> +#define CLK_DRAM_AXI           24
> +#define CLK_AHB_OTG            25
> +#define CLK_AHB_EHCI           26
> +#define CLK_AHB_OHCI           27
> +#define CLK_AHB_SS             28
> +#define CLK_AHB_DMA            29
> +#define CLK_AHB_BIST           30
> +#define CLK_AHB_MMC0           31
> +#define CLK_AHB_MMC1           32
> +#define CLK_AHB_MMC2           33
> +#define CLK_AHB_NAND           34
> +#define CLK_AHB_SDRAM          35
> +#define CLK_AHB_EMAC           36
> +#define CLK_AHB_TS             37
> +#define CLK_AHB_SPI0           38
> +#define CLK_AHB_SPI1           39
> +#define CLK_AHB_SPI2           40
> +#define CLK_AHB_GPS            41
> +#define CLK_AHB_HSTIMER                42
> +#define CLK_AHB_VE             43
> +#define CLK_AHB_TVE            44
> +#define CLK_AHB_LCD            45
> +#define CLK_AHB_CSI            46
> +#define CLK_AHB_HDMI           47
> +#define CLK_AHB_DE_BE          48
> +#define CLK_AHB_DE_FE          49
> +#define CLK_AHB_IEP            50
> +#define CLK_AHB_GPU            51
> +#define CLK_APB0_CODEC         52
> +#define CLK_APB0_SPDIF         53
> +#define CLK_APB0_I2S           54
> +#define CLK_APB0_PIO           55
> +#define CLK_APB0_IR            56
> +#define CLK_APB0_KEYPAD                57
> +#define CLK_APB1_I2C0          58
> +#define CLK_APB1_I2C1          59
> +#define CLK_APB1_I2C2          60
> +#define CLK_APB1_UART0         61
> +#define CLK_APB1_UART1         62
> +#define CLK_APB1_UART2         63
> +#define CLK_APB1_UART3         64
> +#define CLK_NAND               65
> +#define CLK_MMC0               66
> +#define CLK_MMC1               67
> +#define CLK_MMC2               68
> +#define CLK_TS                 69
> +#define CLK_SS                 70
> +#define CLK_CE                 71
> +#define CLK_SPI0               72
> +#define CLK_SPI1               73
> +#define CLK_SPI2               74
> +#define CLK_IR                 75
> +#define CLK_I2S                        76
> +#define CLK_SPDIF              77
> +#define CLK_KEYPAD             78
> +#define CLK_USB_OHCI           79
> +#define CLK_USB_PHY0           80
> +#define CLK_USB_PHY1           81
> +#define CLK_GPS                        82
> +#define CLK_DRAM_VE            83
> +#define CLK_DRAM_CSI           84
> +#define CLK_DRAM_TS            85
> +#define CLK_DRAM_TVE           86
> +#define CLK_DRAM_DE_FE         87
> +#define CLK_DRAM_DE_BE         88
> +#define CLK_DRAM_ACE           89
> +#define CLK_DRAM_IEP           90
> +#define CLK_DE_BE              91
> +#define CLK_DE_FE              92
> +#define CLK_TCON_CH0           93
> +#define CLK_TCON_CH1_SCLK      94
> +#define CLK_TCON_CH1           95
> +#define CLK_CSI                        96
> +#define CLK_VE                 97
> +#define CLK_CODEC              98
> +#define CLK_AVS                        99
> +#define CLK_HDMI               100
> +#define CLK_GPU                        101
> +#define CLK_MBUS               102
> +#define CLK_IEP                        103
> +
> +#define CLK_NUMBER             (CLK_IEP + 1)
> +
> +#endif /* _CCU_SUN5I_H_ */

Didn't you already list all the clocks in the device tree bindings header
patch 5?


Regards
ChenYu
--
To unsubscribe from this list: send the line "unsubscribe linux-clk" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Nov. 21, 2016, 9:45 p.m. UTC | #2
On Sun, Nov 13, 2016 at 05:34:44PM +0800, Chen-Yu Tsai wrote:
> > +static struct ccu_nkmp pll_ve_clk = {
> > +       .enable         = BIT(31),
> > +       .n              = _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
> > +       .k              = _SUNXI_CCU_MULT(4, 2),
> > +       .m              = _SUNXI_CCU_DIV(0, 2),
> > +       .p              = _SUNXI_CCU_DIV(16, 2),
> 
> Any chance we'll support the bypass switch on this one?

I'm not sure this will be useful to have it running at 24MHz.

> > +static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);
> 
> Maybe we should set CLK_IS_CRITICAL on this one as well... in case the
> bootloader uses pll-periph for mbus, and none of the dram gates are enabled.

Ack.

> > +static SUNXI_CCU_GATE(hosc_clk,        "hosc", "osc24M", 0x050, BIT(0), 0);
> 
> Why the extra "hosc" clock here? You should probably just internalize "osc24M".

I'd prefer to model it as it is modelled in hardware: you have two
crystals, and then a gate within the CCU.

> > +static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
> > +                                           "pll-video0-2x", "pll-video1-2x" };
> > +static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
> > +static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
> > +                                      csi_parents, csi_table,
> > +                                      0x134, 0, 5, 24, 2, BIT(31), 0);
> 
> Do you know if CSI needs to change the module clock?

Apparently not.

Thanks!
Maxime
diff mbox

Patch

diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 8454c6e3dd65..e2becd36a1f9 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -64,6 +64,16 @@  config SUN50I_A64_CCU
 	select SUNXI_CCU_PHASE
 	default ARM64 && ARCH_SUNXI
 
+config SUN5I_A10S_CCU
+	bool "Support for the Allwinner A10s CCM"
+	select SUNXI_CCU_DIV
+	select SUNXI_CCU_NK
+	select SUNXI_CCU_NKM
+	select SUNXI_CCU_NM
+	select SUNXI_CCU_MP
+	select SUNXI_CCU_PHASE
+	default MACH_SUN5I
+
 config SUN6I_A31_CCU
 	bool "Support for the Allwinner A31/A31s CCU"
 	select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 24fbc6e5deb8..79e9a166dc83 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -19,6 +19,7 @@  obj-$(CONFIG_SUNXI_CCU_MP)	+= ccu_mp.o
 
 # SoC support
 obj-$(CONFIG_SUN50I_A64_CCU)	+= ccu-sun50i-a64.o
+obj-$(CONFIG_SUN5I_A10S_CCU)	+= ccu-sun5i-a10s.o
 obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
 obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
 obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
new file mode 100644
index 000000000000..94d9a5cbf60b
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i-a10s.c
@@ -0,0 +1,755 @@ 
+/*
+ * Copyright (c) 2016 Maxime Ripard. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+
+#include "ccu_common.h"
+#include "ccu_reset.h"
+
+#include "ccu_div.h"
+#include "ccu_gate.h"
+#include "ccu_mp.h"
+#include "ccu_mult.h"
+#include "ccu_nk.h"
+#include "ccu_nkm.h"
+#include "ccu_nkmp.h"
+#include "ccu_nm.h"
+#include "ccu_phase.h"
+
+#include "ccu-sun5i.h"
+
+static struct ccu_nkmp pll_core_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x000,
+		.hw.init	= CLK_HW_INIT("pll-core",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+/*
+ * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
+ * the base (2x, 4x and 8x), and one variable divider (the one true
+ * pll audio).
+ *
+ * We don't have any need for the variable divider for now, so we just
+ * hardcode it to match with the clock names
+ */
+#define SUN5I_PLL_AUDIO_REG	0x008
+
+static struct ccu_nm pll_audio_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
+	.m		= _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
+	.common		= {
+		.reg		= 0x008,
+		.hw.init	= CLK_HW_INIT("pll-audio-base",
+					      "hosc",
+					      &ccu_nm_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video0_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+					  270000000, 297000000),
+	.common		= {
+		.reg		= 0x010,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video0",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static struct ccu_nkmp pll_ve_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.m		= _SUNXI_CCU_DIV(0, 2),
+	.p		= _SUNXI_CCU_DIV(16, 2),
+	.common		= {
+		.reg		= 0x018,
+		.hw.init	= CLK_HW_INIT("pll-ve",
+					      "hosc",
+					      &ccu_nkmp_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_ddr_base_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-base",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 0);
+
+static struct ccu_div pll_ddr_other_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO),
+
+	.common		= {
+		.reg		= 0x020,
+		.hw.init	= CLK_HW_INIT("pll-ddr-other", "pll-ddr-base",
+					      &ccu_div_ops,
+					      0),
+	},
+};
+
+static struct ccu_nk pll_periph_clk = {
+	.enable		= BIT(31),
+	.n		= _SUNXI_CCU_MULT_OFFSET(8, 5, 0),
+	.k		= _SUNXI_CCU_MULT(4, 2),
+	.fixed_post_div	= 2,
+	.common		= {
+		.reg		= 0x028,
+		.features	= CCU_FEATURE_FIXED_POSTDIV,
+		.hw.init	= CLK_HW_INIT("pll-periph",
+					      "hosc",
+					      &ccu_nk_ops,
+					      0),
+	},
+};
+
+static struct ccu_mult pll_video1_clk = {
+	.enable		= BIT(31),
+	.mult		= _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127),
+	.frac		= _SUNXI_CCU_FRAC(BIT(15), BIT(14),
+				  270000000, 297000000),
+	.common		= {
+		.reg		= 0x030,
+		.features	= CCU_FEATURE_FRACTIONAL,
+		.hw.init	= CLK_HW_INIT("pll-video1",
+					      "osc3M",
+					      &ccu_mult_ops,
+					      0),
+	},
+};
+
+static SUNXI_CCU_GATE(hosc_clk,	"hosc",	"osc24M", 0x050, BIT(0), 0);
+
+#define SUN5I_AHB_REG	0x054
+static const char * const cpu_parents[] = { "osc32k", "hosc",
+					    "pll-core" , "pll-periph" };
+static const struct ccu_mux_fixed_prediv cpu_predivs[] = {
+	{ .index = 3, .div = 3, },
+};
+static struct ccu_mux cpu_clk = {
+	.mux		= {
+		.shift		= 16,
+		.width		= 2,
+		.fixed_predivs	= cpu_predivs,
+		.n_predivs	= ARRAY_SIZE(cpu_predivs),
+	},
+	.common		= {
+		.reg		= 0x054,
+		.features	= CCU_FEATURE_FIXED_PREDIV,
+		.hw.init	= CLK_HW_INIT_PARENTS("cpu",
+						      cpu_parents,
+						      &ccu_mux_ops,
+						      CLK_IS_CRITICAL),
+	}
+};
+
+static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0);
+
+static const char * const ahb_parents[] = { "axi" , "cpu", "pll-periph" };
+static struct ccu_div ahb_clk = {
+	.div		= _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
+	.mux		= _SUNXI_CCU_MUX(6, 2),
+
+	.common		= {
+		.reg		= 0x054,
+		.hw.init	= CLK_HW_INIT_PARENTS("ahb",
+						      ahb_parents,
+						      &ccu_div_ops,
+						      0),
+	},
+};
+
+static struct clk_div_table apb0_div_table[] = {
+	{ .val = 0, .div = 2 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 8 },
+	{ /* Sentinel */ },
+};
+static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb",
+			   0x054, 8, 2, apb0_div_table, 0);
+
+static const char * const apb1_parents[] = { "hosc", "pll-periph", "osc32k" };
+static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058,
+			     0, 5,	/* M */
+			     16, 2,	/* P */
+			     24, 2,	/* mux */
+			     0);
+
+static SUNXI_CCU_GATE(axi_dram_clk,	"axi-dram",	"axi",
+		      0x05c, BIT(0), 0);
+
+static SUNXI_CCU_GATE(ahb_otg_clk,	"ahb-otg",	"ahb",
+		      0x060, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_ehci_clk,	"ahb-ehci",	"ahb",
+		      0x060, BIT(1), 0);
+static SUNXI_CCU_GATE(ahb_ohci_clk,	"ahb-ohci",	"ahb",
+		      0x060, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_ss_clk,	"ahb-ss",	"ahb",
+		      0x060, BIT(5), 0);
+static SUNXI_CCU_GATE(ahb_dma_clk,	"ahb-dma",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_bist_clk,	"ahb-bist",	"ahb",
+		      0x060, BIT(6), 0);
+static SUNXI_CCU_GATE(ahb_mmc0_clk,	"ahb-mmc0",	"ahb",
+		      0x060, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_mmc1_clk,	"ahb-mmc1",	"ahb",
+		      0x060, BIT(9), 0);
+static SUNXI_CCU_GATE(ahb_mmc2_clk,	"ahb-mmc2",	"ahb",
+		      0x060, BIT(10), 0);
+static SUNXI_CCU_GATE(ahb_nand_clk,	"ahb-nand",	"ahb",
+		      0x060, BIT(13), 0);
+static SUNXI_CCU_GATE(ahb_sdram_clk,	"ahb-sdram",	"ahb",
+		      0x060, BIT(14), CLK_IS_CRITICAL);
+static SUNXI_CCU_GATE(ahb_emac_clk,	"ahb-emac",	"ahb",
+		      0x060, BIT(17), 0);
+static SUNXI_CCU_GATE(ahb_ts_clk,	"ahb-ts",	"ahb",
+		      0x060, BIT(18), 0);
+static SUNXI_CCU_GATE(ahb_spi0_clk,	"ahb-spi0",	"ahb",
+		      0x060, BIT(20), 0);
+static SUNXI_CCU_GATE(ahb_spi1_clk,	"ahb-spi1",	"ahb",
+		      0x060, BIT(21), 0);
+static SUNXI_CCU_GATE(ahb_spi2_clk,	"ahb-spi2",	"ahb",
+		      0x060, BIT(22), 0);
+static SUNXI_CCU_GATE(ahb_gps_clk,	"ahb-gps",	"ahb",
+		      0x060, BIT(26), 0);
+static SUNXI_CCU_GATE(ahb_hstimer_clk,	"ahb-hstimer",	"ahb",
+		      0x060, BIT(28), 0);
+
+static SUNXI_CCU_GATE(ahb_ve_clk,	"ahb-ve",	"ahb",
+		      0x064, BIT(0), 0);
+static SUNXI_CCU_GATE(ahb_tve_clk,	"ahb-tve",	"ahb",
+		      0x064, BIT(2), 0);
+static SUNXI_CCU_GATE(ahb_lcd_clk,	"ahb-lcd",	"ahb",
+		      0x064, BIT(4), 0);
+static SUNXI_CCU_GATE(ahb_csi_clk,	"ahb-csi",	"ahb",
+		      0x064, BIT(8), 0);
+static SUNXI_CCU_GATE(ahb_hdmi_clk,	"ahb-hdmi",	"ahb",
+		      0x064, BIT(11), 0);
+static SUNXI_CCU_GATE(ahb_de_be_clk,	"ahb-de-be",	"ahb",
+		      0x064, BIT(12), 0);
+static SUNXI_CCU_GATE(ahb_de_fe_clk,	"ahb-de-fe",	"ahb",
+		      0x064, BIT(14), 0);
+static SUNXI_CCU_GATE(ahb_iep_clk,	"ahb-iep",	"ahb",
+		      0x064, BIT(19), 0);
+static SUNXI_CCU_GATE(ahb_gpu_clk,	"ahb-gpu",	"ahb",
+		      0x064, BIT(20), 0);
+
+static SUNXI_CCU_GATE(apb0_codec_clk,	"apb0-codec",	"apb0",
+		      0x068, BIT(0), 0);
+static SUNXI_CCU_GATE(apb0_i2s_clk,	"apb0-i2s",	"apb0",
+		      0x068, BIT(3), 0);
+static SUNXI_CCU_GATE(apb0_pio_clk,	"apb0-pio",	"apb0",
+		      0x068, BIT(5), 0);
+static SUNXI_CCU_GATE(apb0_ir_clk,	"apb0-ir",	"apb0",
+		      0x068, BIT(6), 0);
+static SUNXI_CCU_GATE(apb0_keypad_clk,	"apb0-keypad",	"apb0",
+		      0x068, BIT(10), 0);
+
+static SUNXI_CCU_GATE(apb1_i2c0_clk,	"apb1-i2c0",	"apb1",
+		      0x06c, BIT(0), 0);
+static SUNXI_CCU_GATE(apb1_i2c1_clk,	"apb1-i2c1",	"apb1",
+		      0x06c, BIT(1), 0);
+static SUNXI_CCU_GATE(apb1_i2c2_clk,	"apb1-i2c2",	"apb1",
+		      0x06c, BIT(2), 0);
+static SUNXI_CCU_GATE(apb1_uart0_clk,	"apb1-uart0",	"apb1",
+		      0x06c, BIT(16), 0);
+static SUNXI_CCU_GATE(apb1_uart1_clk,	"apb1-uart1",	"apb1",
+		      0x06c, BIT(17), 0);
+static SUNXI_CCU_GATE(apb1_uart2_clk,	"apb1-uart2",	"apb1",
+		      0x06c, BIT(18), 0);
+static SUNXI_CCU_GATE(apb1_uart3_clk,	"apb1-uart3",	"apb1",
+		      0x06c, BIT(19), 0);
+
+static const char * const mod0_default_parents[] = { "hosc", "pll-periph",
+						     "pll-ddr-other" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", mod0_default_parents, 0x0b0,
+				  0, 4,		/* M */
+				  16, 2,	/* P */
+				  24, 2,	/* mux */
+				  BIT(31),	/* gate */
+				  0);
+
+static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
+					    "pll-audio-2x", "pll-audio" };
+static SUNXI_CCU_MUX_WITH_GATE(i2s_clk, "i2s", i2s_parents,
+			       0x0b8, 16, 2, BIT(31), 0);
+
+static const char * const keypad_parents[] = { "hosc", "losc"};
+static const u8 keypad_table[] = { 0, 2 };
+static struct ccu_mp keypad_clk = {
+	.enable		= BIT(31),
+	.m		= _SUNXI_CCU_DIV(8, 5),
+	.p		= _SUNXI_CCU_DIV(20, 2),
+	.mux		= _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table),
+
+	.common		= {
+		.reg		= 0x0c4,
+		.hw.init	= CLK_HW_INIT_PARENTS("keypad",
+						      keypad_parents,
+						      &ccu_mp_ops,
+						      0),
+	},
+};
+
+static SUNXI_CCU_GATE(usb_ohci_clk,	"usb-ohci",	"pll-periph",
+		      0x0cc, BIT(6), 0);
+static SUNXI_CCU_GATE(usb_phy0_clk,	"usb-phy0",	"pll-periph",
+		      0x0cc, BIT(8), 0);
+static SUNXI_CCU_GATE(usb_phy1_clk,	"usb-phy1",	"pll-periph",
+		      0x0cc, BIT(9), 0);
+
+static const char * const gps_parents[] = { "hosc", "pll-periph",
+					    "pll-video1", "pll-ve" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gps_clk, "gps", gps_parents,
+				 0x0d0, 0, 3, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(dram_ve_clk,	"dram-ve",	"pll-ddr",
+		      0x100, BIT(0), 0);
+static SUNXI_CCU_GATE(dram_csi_clk,	"dram-csi",	"pll-ddr",
+		      0x100, BIT(1), 0);
+static SUNXI_CCU_GATE(dram_ts_clk,	"dram-ts",	"pll-ddr",
+		      0x100, BIT(3), 0);
+static SUNXI_CCU_GATE(dram_tve_clk,	"dram-tve",	"pll-ddr",
+		      0x100, BIT(5), 0);
+static SUNXI_CCU_GATE(dram_de_fe_clk,	"dram-de-fe",	"pll-ddr",
+		      0x100, BIT(25), 0);
+static SUNXI_CCU_GATE(dram_de_be_clk,	"dram-de-be",	"pll-ddr",
+		      0x100, BIT(26), 0);
+static SUNXI_CCU_GATE(dram_ace_clk,	"dram-ace",	"pll-ddr",
+		      0x100, BIT(29), 0);
+static SUNXI_CCU_GATE(dram_iep_clk,	"dram-iep",	"pll-ddr",
+		      0x100, BIT(31), 0);
+
+static const char * const de_parents[] = { "pll-video0", "pll-video1",
+					   "pll-ddr-other" };
+static SUNXI_CCU_M_WITH_MUX_GATE(de_be_clk, "de-be", de_parents,
+				 0x104, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(de_fe_clk, "de-fe", de_parents,
+				 0x10c, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const tcon_parents[] = { "pll-video0", "pll-video1",
+					     "pll-video0-2x", "pll-video1-2x" };
+static SUNXI_CCU_MUX_WITH_GATE(tcon_ch0_clk, "tcon-ch0-sclk", tcon_parents,
+			       0x118, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_MUX_GATE(tcon_ch1_sclk2_clk, "tcon-ch1-sclk2",
+				 tcon_parents,
+				 0x12c, 0, 4, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_M_WITH_GATE(tcon_ch1_sclk1_clk, "tcon-ch1-sclk1", "tcon-ch1-sclk2",
+			     0x12c, 11, 1, BIT(15), 0);
+
+static const char * const csi_parents[] = { "hosc", "pll-video0", "pll-video1",
+					    "pll-video0-2x", "pll-video1-2x" };
+static const u8 csi_table[] = { 0, 1, 2, 5, 6 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_clk, "csi",
+				       csi_parents, csi_table,
+				       0x134, 0, 5, 24, 2, BIT(31), 0);
+
+static SUNXI_CCU_GATE(ve_clk,		"ve",		"pll-ve",
+		      0x13c, BIT(31), 0);
+
+static SUNXI_CCU_GATE(codec_clk,	"codec",	"pll-audio",
+		      0x140, BIT(31), 0);
+
+static SUNXI_CCU_GATE(avs_clk,		"avs",		"hosc",
+		      0x144, BIT(31), 0);
+
+static const char * const hdmi_parents[] = { "pll-video0", "pll-video0-2x" };
+static const u8 hdmi_table[] = { 0, 2 };
+static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi_clk, "hdmi",
+				       hdmi_parents, hdmi_table,
+				       0x150, 0, 4, 24, 2, BIT(31), 0);
+
+static const char * const gpu_parents[] = { "pll-video0", "pll-ve",
+					    "pll-ddr-other", "pll-video1",
+					    "pll-video1-2x" };
+static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents,
+				 0x154, 0, 4, 24, 3, BIT(31), 0);
+
+static const char * const mbus_parents[] = { "hosc", "pll-periph", "pll-ddr" };
+static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
+				  0x15c, 0, 4, 16, 2, 24, 2, BIT(31), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE(iep_clk,		"iep",		"de-be",
+		      0x160, BIT(31), 0);
+
+static struct ccu_common *sun5i_a10s_ccu_clks[] = {
+	&hosc_clk.common,
+	&pll_core_clk.common,
+	&pll_audio_base_clk.common,
+	&pll_video0_clk.common,
+	&pll_ve_clk.common,
+	&pll_ddr_base_clk.common,
+	&pll_ddr_clk.common,
+	&pll_ddr_other_clk.common,
+	&pll_periph_clk.common,
+	&pll_video1_clk.common,
+	&cpu_clk.common,
+	&axi_clk.common,
+	&ahb_clk.common,
+	&apb0_clk.common,
+	&apb1_clk.common,
+	&axi_dram_clk.common,
+	&ahb_otg_clk.common,
+	&ahb_ehci_clk.common,
+	&ahb_ohci_clk.common,
+	&ahb_ss_clk.common,
+	&ahb_dma_clk.common,
+	&ahb_bist_clk.common,
+	&ahb_mmc0_clk.common,
+	&ahb_mmc1_clk.common,
+	&ahb_mmc2_clk.common,
+	&ahb_nand_clk.common,
+	&ahb_sdram_clk.common,
+	&ahb_emac_clk.common,
+	&ahb_ts_clk.common,
+	&ahb_spi0_clk.common,
+	&ahb_spi1_clk.common,
+	&ahb_spi2_clk.common,
+	&ahb_gps_clk.common,
+	&ahb_hstimer_clk.common,
+	&ahb_ve_clk.common,
+	&ahb_tve_clk.common,
+	&ahb_lcd_clk.common,
+	&ahb_csi_clk.common,
+	&ahb_hdmi_clk.common,
+	&ahb_de_be_clk.common,
+	&ahb_de_fe_clk.common,
+	&ahb_iep_clk.common,
+	&ahb_gpu_clk.common,
+	&apb0_codec_clk.common,
+	&apb0_i2s_clk.common,
+	&apb0_pio_clk.common,
+	&apb0_ir_clk.common,
+	&apb0_keypad_clk.common,
+	&apb1_i2c0_clk.common,
+	&apb1_i2c1_clk.common,
+	&apb1_i2c2_clk.common,
+	&apb1_uart0_clk.common,
+	&apb1_uart1_clk.common,
+	&apb1_uart2_clk.common,
+	&apb1_uart3_clk.common,
+	&nand_clk.common,
+	&mmc0_clk.common,
+	&mmc1_clk.common,
+	&mmc2_clk.common,
+	&ts_clk.common,
+	&ss_clk.common,
+	&spi0_clk.common,
+	&spi1_clk.common,
+	&spi2_clk.common,
+	&ir_clk.common,
+	&i2s_clk.common,
+	&keypad_clk.common,
+	&usb_ohci_clk.common,
+	&usb_phy0_clk.common,
+	&usb_phy1_clk.common,
+	&gps_clk.common,
+	&dram_ve_clk.common,
+	&dram_csi_clk.common,
+	&dram_ts_clk.common,
+	&dram_tve_clk.common,
+	&dram_de_fe_clk.common,
+	&dram_de_be_clk.common,
+	&dram_ace_clk.common,
+	&dram_iep_clk.common,
+	&de_be_clk.common,
+	&de_fe_clk.common,
+	&tcon_ch0_clk.common,
+	&tcon_ch1_sclk2_clk.common,
+	&tcon_ch1_sclk1_clk.common,
+	&csi_clk.common,
+	&ve_clk.common,
+	&codec_clk.common,
+	&avs_clk.common,
+	&hdmi_clk.common,
+	&gpu_clk.common,
+	&mbus_clk.common,
+	&iep_clk.common,
+};
+
+static CLK_FIXED_FACTOR(osc3M_clk, "osc3M", "hosc", 8, 1, 0);
+/* We hardcode the divider to 4 for now */
+static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
+			"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
+			"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
+			"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
+			"pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
+			"pll-video0", 1, 2, CLK_SET_RATE_PARENT);
+static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
+			"pll-video1", 1, 2, CLK_SET_RATE_PARENT);
+
+static struct clk_hw_onecell_data sun5i_a10s_hw_clks = {
+	.hws	= {
+		[CLK_HOSC]		= &hosc_clk.common.hw,
+		[CLK_OSC3M]		= &osc3M_clk.hw,
+		[CLK_PLL_CORE]		= &pll_core_clk.common.hw,
+		[CLK_PLL_AUDIO_BASE]	= &pll_audio_base_clk.common.hw,
+		[CLK_PLL_AUDIO]		= &pll_audio_clk.hw,
+		[CLK_PLL_AUDIO_2X]	= &pll_audio_2x_clk.hw,
+		[CLK_PLL_AUDIO_4X]	= &pll_audio_4x_clk.hw,
+		[CLK_PLL_AUDIO_8X]	= &pll_audio_8x_clk.hw,
+		[CLK_PLL_VIDEO0]	= &pll_video0_clk.common.hw,
+		[CLK_PLL_VIDEO0_2X]	= &pll_video0_2x_clk.hw,
+		[CLK_PLL_VE]		= &pll_ve_clk.common.hw,
+		[CLK_PLL_DDR_BASE]	= &pll_ddr_base_clk.common.hw,
+		[CLK_PLL_DDR]		= &pll_ddr_clk.common.hw,
+		[CLK_PLL_DDR_OTHER]	= &pll_ddr_other_clk.common.hw,
+		[CLK_PLL_PERIPH]	= &pll_periph_clk.common.hw,
+		[CLK_PLL_VIDEO1]	= &pll_video1_clk.common.hw,
+		[CLK_PLL_VIDEO1_2X]	= &pll_video1_2x_clk.hw,
+		[CLK_CPU]		= &cpu_clk.common.hw,
+		[CLK_AXI]		= &axi_clk.common.hw,
+		[CLK_AHB]		= &ahb_clk.common.hw,
+		[CLK_APB0]		= &apb0_clk.common.hw,
+		[CLK_APB1]		= &apb1_clk.common.hw,
+		[CLK_DRAM_AXI]		= &axi_dram_clk.common.hw,
+		[CLK_AHB_OTG]		= &ahb_otg_clk.common.hw,
+		[CLK_AHB_EHCI]		= &ahb_ehci_clk.common.hw,
+		[CLK_AHB_OHCI]		= &ahb_ohci_clk.common.hw,
+		[CLK_AHB_SS]		= &ahb_ss_clk.common.hw,
+		[CLK_AHB_DMA]		= &ahb_dma_clk.common.hw,
+		[CLK_AHB_BIST]		= &ahb_bist_clk.common.hw,
+		[CLK_AHB_MMC0]		= &ahb_mmc0_clk.common.hw,
+		[CLK_AHB_MMC1]		= &ahb_mmc1_clk.common.hw,
+		[CLK_AHB_MMC2]		= &ahb_mmc2_clk.common.hw,
+		[CLK_AHB_NAND]		= &ahb_nand_clk.common.hw,
+		[CLK_AHB_SDRAM]		= &ahb_sdram_clk.common.hw,
+		[CLK_AHB_EMAC]		= &ahb_emac_clk.common.hw,
+		[CLK_AHB_TS]		= &ahb_ts_clk.common.hw,
+		[CLK_AHB_SPI0]		= &ahb_spi0_clk.common.hw,
+		[CLK_AHB_SPI1]		= &ahb_spi1_clk.common.hw,
+		[CLK_AHB_SPI2]		= &ahb_spi2_clk.common.hw,
+		[CLK_AHB_GPS]		= &ahb_gps_clk.common.hw,
+		[CLK_AHB_HSTIMER]	= &ahb_hstimer_clk.common.hw,
+		[CLK_AHB_VE]		= &ahb_ve_clk.common.hw,
+		[CLK_AHB_TVE]		= &ahb_tve_clk.common.hw,
+		[CLK_AHB_LCD]		= &ahb_lcd_clk.common.hw,
+		[CLK_AHB_CSI]		= &ahb_csi_clk.common.hw,
+		[CLK_AHB_HDMI]		= &ahb_hdmi_clk.common.hw,
+		[CLK_AHB_DE_BE]		= &ahb_de_be_clk.common.hw,
+		[CLK_AHB_DE_FE]		= &ahb_de_fe_clk.common.hw,
+		[CLK_AHB_IEP]		= &ahb_iep_clk.common.hw,
+		[CLK_AHB_GPU]		= &ahb_gpu_clk.common.hw,
+		[CLK_APB0_CODEC]	= &apb0_codec_clk.common.hw,
+		[CLK_APB0_I2S]		= &apb0_i2s_clk.common.hw,
+		[CLK_APB0_PIO]		= &apb0_pio_clk.common.hw,
+		[CLK_APB0_IR]		= &apb0_ir_clk.common.hw,
+		[CLK_APB0_KEYPAD]	= &apb0_keypad_clk.common.hw,
+		[CLK_APB1_I2C0]		= &apb1_i2c0_clk.common.hw,
+		[CLK_APB1_I2C1]		= &apb1_i2c1_clk.common.hw,
+		[CLK_APB1_I2C2]		= &apb1_i2c2_clk.common.hw,
+		[CLK_APB1_UART0]	= &apb1_uart0_clk.common.hw,
+		[CLK_APB1_UART1]	= &apb1_uart1_clk.common.hw,
+		[CLK_APB1_UART2]	= &apb1_uart2_clk.common.hw,
+		[CLK_APB1_UART3]	= &apb1_uart3_clk.common.hw,
+		[CLK_NAND]		= &nand_clk.common.hw,
+		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_MMC2]		= &mmc2_clk.common.hw,
+		[CLK_TS]		= &ts_clk.common.hw,
+		[CLK_SS]		= &ss_clk.common.hw,
+		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_IR]		= &ir_clk.common.hw,
+		[CLK_I2S]		= &i2s_clk.common.hw,
+		[CLK_KEYPAD]		= &keypad_clk.common.hw,
+		[CLK_USB_OHCI]		= &usb_ohci_clk.common.hw,
+		[CLK_USB_PHY0]		= &usb_phy0_clk.common.hw,
+		[CLK_USB_PHY1]		= &usb_phy1_clk.common.hw,
+		[CLK_GPS]		= &gps_clk.common.hw,
+		[CLK_DRAM_VE]		= &dram_ve_clk.common.hw,
+		[CLK_DRAM_CSI]		= &dram_csi_clk.common.hw,
+		[CLK_DRAM_TS]		= &dram_ts_clk.common.hw,
+		[CLK_DRAM_TVE]		= &dram_tve_clk.common.hw,
+		[CLK_DRAM_DE_FE]	= &dram_de_fe_clk.common.hw,
+		[CLK_DRAM_DE_BE]	= &dram_de_be_clk.common.hw,
+		[CLK_DRAM_ACE]		= &dram_ace_clk.common.hw,
+		[CLK_DRAM_IEP]		= &dram_iep_clk.common.hw,
+		[CLK_DE_BE]		= &de_be_clk.common.hw,
+		[CLK_DE_FE]		= &de_fe_clk.common.hw,
+		[CLK_TCON_CH0]		= &tcon_ch0_clk.common.hw,
+		[CLK_TCON_CH1_SCLK]	= &tcon_ch1_sclk2_clk.common.hw,
+		[CLK_TCON_CH1]		= &tcon_ch1_sclk1_clk.common.hw,
+		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_VE]		= &ve_clk.common.hw,
+		[CLK_CODEC]		= &codec_clk.common.hw,
+		[CLK_AVS]		= &avs_clk.common.hw,
+		[CLK_HDMI]		= &hdmi_clk.common.hw,
+		[CLK_GPU]		= &gpu_clk.common.hw,
+		[CLK_MBUS]		= &mbus_clk.common.hw,
+		[CLK_IEP]		= &iep_clk.common.hw,
+	},
+	.num	= CLK_NUMBER,
+};
+
+static struct ccu_reset_map sun5i_a10s_ccu_resets[] = {
+	[RST_USB_PHY0]		=  { 0x0cc, BIT(0) },
+	[RST_USB_PHY1]		=  { 0x0cc, BIT(1) },
+
+	[RST_GPS]		=  { 0x0d0, BIT(30) },
+
+	[RST_DE_BE]		=  { 0x104, BIT(30) },
+
+	[RST_DE_FE]		=  { 0x10c, BIT(30) },
+
+	[RST_TVE]		=  { 0x118, BIT(29) },
+	[RST_LCD]		=  { 0x118, BIT(30) },
+
+	[RST_CSI]		=  { 0x134, BIT(30) },
+
+	[RST_VE]		=  { 0x13c, BIT(0) },
+
+	[RST_GPU]		=  { 0x154, BIT(30) },
+
+	[RST_IEP]		=  { 0x160, BIT(30) },
+};
+
+static const struct sunxi_ccu_desc sun5i_a10s_ccu_desc = {
+	.ccu_clks	= sun5i_a10s_ccu_clks,
+	.num_ccu_clks	= ARRAY_SIZE(sun5i_a10s_ccu_clks),
+
+	.hw_clks	= &sun5i_a10s_hw_clks,
+
+	.resets		= sun5i_a10s_ccu_resets,
+	.num_resets	= ARRAY_SIZE(sun5i_a10s_ccu_resets),
+};
+
+static void __init sun5i_a10s_ccu_setup(struct device_node *node)
+{
+	void __iomem *reg;
+	u32 val;
+
+	reg = of_io_request_and_map(node, 0, of_node_full_name(node));
+	if (IS_ERR(reg)) {
+		pr_err("%s: Could not map the clock registers\n",
+		       of_node_full_name(node));
+		return;
+	}
+
+	/* Force the PLL-Audio-1x divider to 4 */
+	val = readl(reg + SUN5I_PLL_AUDIO_REG);
+	val &= ~GENMASK(19, 16);
+	writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
+
+	/*
+	 * Use the peripheral PLL as the AHB parent, instead of CPU /
+	 * AXI which have rate changes due to cpufreq.
+	 *
+	 * This is especially a big deal for the HS timer whose parent
+	 * clock is AHB.
+	 */
+	val = readl(reg + SUN5I_AHB_REG);
+	val &= ~GENMASK(7, 6);
+	writel(val | (2 << 6), reg + SUN5I_AHB_REG);
+
+	sunxi_ccu_probe(node, reg, &sun5i_a10s_ccu_desc);
+}
+CLK_OF_DECLARE(sun5i_a10s_ccu, "allwinner,sun5i-a10s-ccu",
+	       sun5i_a10s_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.h b/drivers/clk/sunxi-ng/ccu-sun5i.h
new file mode 100644
index 000000000000..43f2ce3e9e6e
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.h
@@ -0,0 +1,129 @@ 
+/*
+ * Copyright 2016 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CCU_SUN5I_H_
+#define _CCU_SUN5I_H_
+
+#include <dt-bindings/clock/sun5i-ccu.h>
+#include <dt-bindings/reset/sun5i-ccu.h>
+
+#define CLK_HOSC		1
+#define CLK_OSC3M		2
+#define CLK_PLL_CORE		3
+#define CLK_PLL_AUDIO_BASE	4
+#define CLK_PLL_AUDIO		5
+#define CLK_PLL_AUDIO_2X	6
+#define CLK_PLL_AUDIO_4X	7
+#define CLK_PLL_AUDIO_8X	8
+#define CLK_PLL_VIDEO0		9
+#define CLK_PLL_VIDEO0_2X	10
+#define CLK_PLL_VE		11
+#define CLK_PLL_DDR_BASE	12
+#define CLK_PLL_DDR		13
+#define CLK_PLL_DDR_OTHER	14
+#define CLK_PLL_PERIPH		15
+#define CLK_PLL_VIDEO1		16
+#define CLK_PLL_VIDEO1_2X	17
+#define CLK_OSC24M		18
+#define CLK_CPU			19
+#define CLK_AXI			20
+#define CLK_AHB			21
+#define CLK_APB0		22
+#define CLK_APB1		23
+#define CLK_DRAM_AXI		24
+#define CLK_AHB_OTG		25
+#define CLK_AHB_EHCI		26
+#define CLK_AHB_OHCI		27
+#define CLK_AHB_SS		28
+#define CLK_AHB_DMA		29
+#define CLK_AHB_BIST		30
+#define CLK_AHB_MMC0		31
+#define CLK_AHB_MMC1		32
+#define CLK_AHB_MMC2		33
+#define CLK_AHB_NAND		34
+#define CLK_AHB_SDRAM		35
+#define CLK_AHB_EMAC		36
+#define CLK_AHB_TS		37
+#define CLK_AHB_SPI0		38
+#define CLK_AHB_SPI1		39
+#define CLK_AHB_SPI2		40
+#define CLK_AHB_GPS		41
+#define CLK_AHB_HSTIMER		42
+#define CLK_AHB_VE		43
+#define CLK_AHB_TVE		44
+#define CLK_AHB_LCD		45
+#define CLK_AHB_CSI		46
+#define CLK_AHB_HDMI		47
+#define CLK_AHB_DE_BE		48
+#define CLK_AHB_DE_FE		49
+#define CLK_AHB_IEP		50
+#define CLK_AHB_GPU		51
+#define CLK_APB0_CODEC		52
+#define CLK_APB0_SPDIF		53
+#define CLK_APB0_I2S		54
+#define CLK_APB0_PIO		55
+#define CLK_APB0_IR		56
+#define CLK_APB0_KEYPAD		57
+#define CLK_APB1_I2C0		58
+#define CLK_APB1_I2C1		59
+#define CLK_APB1_I2C2		60
+#define CLK_APB1_UART0		61
+#define CLK_APB1_UART1		62
+#define CLK_APB1_UART2		63
+#define CLK_APB1_UART3		64
+#define CLK_NAND		65
+#define CLK_MMC0		66
+#define CLK_MMC1		67
+#define CLK_MMC2		68
+#define CLK_TS			69
+#define CLK_SS			70
+#define CLK_CE			71
+#define CLK_SPI0		72
+#define CLK_SPI1		73
+#define CLK_SPI2		74
+#define CLK_IR			75
+#define CLK_I2S			76
+#define CLK_SPDIF		77
+#define CLK_KEYPAD		78
+#define CLK_USB_OHCI		79
+#define CLK_USB_PHY0		80
+#define CLK_USB_PHY1		81
+#define CLK_GPS			82
+#define CLK_DRAM_VE		83
+#define CLK_DRAM_CSI		84
+#define CLK_DRAM_TS		85
+#define CLK_DRAM_TVE		86
+#define CLK_DRAM_DE_FE		87
+#define CLK_DRAM_DE_BE		88
+#define CLK_DRAM_ACE		89
+#define CLK_DRAM_IEP		90
+#define CLK_DE_BE		91
+#define CLK_DE_FE		92
+#define CLK_TCON_CH0		93
+#define CLK_TCON_CH1_SCLK	94
+#define CLK_TCON_CH1		95
+#define CLK_CSI			96
+#define CLK_VE			97
+#define CLK_CODEC		98
+#define CLK_AVS			99
+#define CLK_HDMI		100
+#define CLK_GPU			101
+#define CLK_MBUS		102
+#define CLK_IEP			103
+
+#define CLK_NUMBER		(CLK_IEP + 1)
+
+#endif /* _CCU_SUN5I_H_ */