[PATCH v2] clk: uniphier: add clock drivers for UniPhier SoCs
Masahiro Yamada
yamada.masahiro at socionext.com
Mon Dec 28 02:20:03 PST 2015
This is the initial commit for the UniPhier clock drivers, including
support for PH1-sLD3, PH1-LD4, PH1-Pro4, PH1-sLD8, PH1-Pro5, and
ProXstream2/PH1-LD6b.
To improve the code maintainability, the driver consists of common
functions (clk-uniphier-core.c) and clock data arrays needed to
support each SoC.
Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
Changes in v2:
- split emmc_hw_reset
- make SD clock rate-controllable
- add CLK_SET_RATE_PARENT flag to mux, gate, fixed-factor clocks
MAINTAINERS | 1 +
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/uniphier/Kconfig | 35 ++++
drivers/clk/uniphier/Makefile | 10 +
drivers/clk/uniphier/clk-ph1-ld4.c | 117 ++++++++++++
drivers/clk/uniphier/clk-ph1-pro4.c | 117 ++++++++++++
drivers/clk/uniphier/clk-ph1-pro5.c | 107 +++++++++++
drivers/clk/uniphier/clk-ph1-sld3.c | 117 ++++++++++++
drivers/clk/uniphier/clk-ph1-sld8.c | 107 +++++++++++
drivers/clk/uniphier/clk-proxstream2.c | 88 +++++++++
drivers/clk/uniphier/clk-uniphier-core.c | 151 +++++++++++++++
drivers/clk/uniphier/clk-uniphier-mio.c | 315 +++++++++++++++++++++++++++++++
drivers/clk/uniphier/clk-uniphier-peri.c | 175 +++++++++++++++++
drivers/clk/uniphier/clk-uniphier.h | 68 +++++++
15 files changed, 1410 insertions(+)
create mode 100644 drivers/clk/uniphier/Kconfig
create mode 100644 drivers/clk/uniphier/Makefile
create mode 100644 drivers/clk/uniphier/clk-ph1-ld4.c
create mode 100644 drivers/clk/uniphier/clk-ph1-pro4.c
create mode 100644 drivers/clk/uniphier/clk-ph1-pro5.c
create mode 100644 drivers/clk/uniphier/clk-ph1-sld3.c
create mode 100644 drivers/clk/uniphier/clk-ph1-sld8.c
create mode 100644 drivers/clk/uniphier/clk-proxstream2.c
create mode 100644 drivers/clk/uniphier/clk-uniphier-core.c
create mode 100644 drivers/clk/uniphier/clk-uniphier-mio.c
create mode 100644 drivers/clk/uniphier/clk-uniphier-peri.c
create mode 100644 drivers/clk/uniphier/clk-uniphier.h
diff --git a/MAINTAINERS b/MAINTAINERS
index fc08493..6c10e9b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1644,6 +1644,7 @@ F: arch/arm/mach-uniphier/
F: arch/arm/mm/cache-uniphier.c
F: arch/arm64/boot/dts/socionext/
F: drivers/bus/uniphier-system-bus.c
+F: drivers/clk/uniphier/
F: drivers/i2c/busses/i2c-uniphier*
F: drivers/pinctrl/uniphier/
F: drivers/tty/serial/8250/8250_uniphier.c
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c3e3a02..7580323 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -191,6 +191,7 @@ config COMMON_CLK_CDCE706
source "drivers/clk/bcm/Kconfig"
source "drivers/clk/hisilicon/Kconfig"
source "drivers/clk/qcom/Kconfig"
+source "drivers/clk/uniphier/Kconfig"
endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 820714c..ab9d1bd 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_ARCH_STI) += st/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/
+obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
obj-$(CONFIG_ARCH_U8500) += ux500/
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_X86) += x86/
diff --git a/drivers/clk/uniphier/Kconfig b/drivers/clk/uniphier/Kconfig
new file mode 100644
index 0000000..7606f27
--- /dev/null
+++ b/drivers/clk/uniphier/Kconfig
@@ -0,0 +1,35 @@
+menuconfig CLK_UNIPHIER
+ bool "Clock drivers for UniPhier SoCs"
+ depends on ARCH_UNIPHIER
+ depends on OF
+ default y
+ help
+ Supports clock drivers for UniPhier SoCs.
+
+if CLK_UNIPHIER
+
+config CLK_UNIPHIER_PH1_SLD3
+ bool "Clock driver for UniPhier PH1-sLD3 SoC"
+ default y
+
+config CLK_UNIPHIER_PH1_LD4
+ bool "Clock driver for UniPhier PH1-LD4 SoC"
+ default y
+
+config CLK_UNIPHIER_PH1_PRO4
+ bool "Clock driver for UniPhier PH1-Pro4 SoC"
+ default y
+
+config CLK_UNIPHIER_PH1_SLD8
+ bool "Clock driver for UniPhier PH1-sLD8 SoC"
+ default y
+
+config CLK_UNIPHIER_PH1_PRO5
+ bool "Clock driver for UniPhier PH1-Pro5 SoC"
+ default y
+
+config CLK_UNIPHIER_PROXSTREAM2
+ bool "Clock driver for UniPhier ProXstream2/PH1-LD6b SoC"
+ default y
+
+endif
diff --git a/drivers/clk/uniphier/Makefile b/drivers/clk/uniphier/Makefile
new file mode 100644
index 0000000..3be1a17
--- /dev/null
+++ b/drivers/clk/uniphier/Makefile
@@ -0,0 +1,10 @@
+obj-y += clk-uniphier-core.o
+obj-y += clk-uniphier-peri.o
+obj-y += clk-uniphier-mio.o
+
+obj-$(CONFIG_CLK_UNIPHIER_PH1_SLD3) += clk-ph1-sld3.o
+obj-$(CONFIG_CLK_UNIPHIER_PH1_LD4) += clk-ph1-ld4.o
+obj-$(CONFIG_CLK_UNIPHIER_PH1_PRO4) += clk-ph1-pro4.o
+obj-$(CONFIG_CLK_UNIPHIER_PH1_SLD8) += clk-ph1-sld8.o
+obj-$(CONFIG_CLK_UNIPHIER_PH1_PRO5) += clk-ph1-pro5.o
+obj-$(CONFIG_CLK_UNIPHIER_PROXSTREAM2) += clk-proxstream2.o
diff --git a/drivers/clk/uniphier/clk-ph1-ld4.c b/drivers/clk/uniphier/clk-ph1-ld4.c
new file mode 100644
index 0000000..48d342f
--- /dev/null
+++ b/drivers/clk/uniphier/clk-ph1-ld4.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+static struct uniphier_clk_init_data ph1_ld4_clk_idata[] __initdata = {
+ {
+ .name = "spll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 65,
+ .div = 1,
+ },
+ },
+ {
+ .name = "upll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 288000,
+ .div = 24576,
+ },
+ },
+ {
+ .name = "a2pll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 24,
+ .div = 1,
+ },
+ },
+ {
+ .name = "uart",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 3,
+ .data.factor = {
+ .parent_name = "a2pll",
+ .mult = 1,
+ .div = 16,
+ },
+ },
+ {
+ .name = "i2c",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 4,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 16,
+ },
+ },
+ {
+ .name = "arm-scu",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 7,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 32,
+ },
+ },
+ {
+ .name = "stdmac-clken",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = -1,
+ .data.gate = {
+ .parent_name = NULL,
+ .reg = 0x2104,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "stdmac",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = 10,
+ .data.gate = {
+ .parent_name = "stdmac-clken",
+ .reg = 0x2000,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "ehci",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 18,
+ .data.factor = {
+ .parent_name = "upll",
+ .mult = 1,
+ .div = 12,
+ },
+ },
+ { /* sentinel */ }
+};
+
+static void __init ph1_ld4_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_ld4_clk_idata);
+}
+CLK_OF_DECLARE(ph1_ld4_clk, "socionext,ph1-ld4-sysctrl", ph1_ld4_clk_init);
diff --git a/drivers/clk/uniphier/clk-ph1-pro4.c b/drivers/clk/uniphier/clk-ph1-pro4.c
new file mode 100644
index 0000000..052813a
--- /dev/null
+++ b/drivers/clk/uniphier/clk-ph1-pro4.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+static struct uniphier_clk_init_data ph1_pro4_clk_idata[] __initdata = {
+ {
+ .name = "spll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 64,
+ .div = 1,
+ },
+ },
+ {
+ .name = "upll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 288,
+ .div = 25,
+ },
+ },
+ {
+ .name = "a2pll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = "upll",
+ .mult = 256,
+ .div = 125,
+ },
+ },
+ {
+ .name = "uart",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 3,
+ .data.factor = {
+ .parent_name = "a2pll",
+ .mult = 1,
+ .div = 8,
+ },
+ },
+ {
+ .name = "fi2c",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 4,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 32,
+ },
+ },
+ {
+ .name = "arm-scu",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 7,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 32,
+ },
+ },
+ {
+ .name = "stdmac-clken",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = -1,
+ .data.gate = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .reg = 0x2104,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "stdmac",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = 10,
+ .data.gate = {
+ .parent_name = "stdmac-clken",
+ .reg = 0x2000,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "ehci",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 18,
+ .data.factor = {
+ .parent_name = "upll",
+ .mult = 1,
+ .div = 12,
+ },
+ },
+ { /* sentinel */ }
+};
+
+static void __init ph1_pro4_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_pro4_clk_idata);
+}
+CLK_OF_DECLARE(ph1_pro4_clk, "socionext,ph1-pro4-sysctrl", ph1_pro4_clk_init);
diff --git a/drivers/clk/uniphier/clk-ph1-pro5.c b/drivers/clk/uniphier/clk-ph1-pro5.c
new file mode 100644
index 0000000..9f782d9
--- /dev/null
+++ b/drivers/clk/uniphier/clk-ph1-pro5.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+static struct uniphier_clk_init_data ph1_pro5_clk_idata[] __initdata = {
+ {
+ .name = "spll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 120,
+ .div = 1,
+ },
+ },
+ {
+ .name = "dapll1",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 128,
+ .div = 125,
+ },
+ },
+ {
+ .name = "dapll2",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = "upll",
+ .mult = 144,
+ .div = 5,
+ },
+ },
+ {
+ .name = "uart",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 3,
+ .data.factor = {
+ .parent_name = "dapll2",
+ .mult = 1,
+ .div = 8,
+ },
+ },
+ {
+ .name = "fi2c",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 4,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 48,
+ },
+ },
+ {
+ .name = "arm-scu",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 7,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 48,
+ },
+ },
+ {
+ .name = "stdmac-clken",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = -1,
+ .data.gate = {
+ .parent_name = NULL,
+ .reg = 0x2104,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "stdmac",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = 10,
+ .data.gate = {
+ .parent_name = "stdmac-clken",
+ .reg = 0x2000,
+ .bit_idx = 10,
+ },
+ },
+ { /* sentinel */ }
+};
+
+static void __init ph1_pro5_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_pro5_clk_idata);
+}
+CLK_OF_DECLARE(ph1_pro5_clk, "socionext,ph1-pro5-sysctrl", ph1_pro5_clk_init);
diff --git a/drivers/clk/uniphier/clk-ph1-sld3.c b/drivers/clk/uniphier/clk-ph1-sld3.c
new file mode 100644
index 0000000..7249a81
--- /dev/null
+++ b/drivers/clk/uniphier/clk-ph1-sld3.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+static struct uniphier_clk_init_data ph1_sld3_clk_idata[] __initdata = {
+ {
+ .name = "spll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 65,
+ .div = 1,
+ },
+ },
+ {
+ .name = "upll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 288000,
+ .div = 24576,
+ },
+ },
+ {
+ .name = "a2pll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 24,
+ .div = 1,
+ },
+ },
+ {
+ .name = "uart",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 3,
+ .data.factor = {
+ .parent_name = "a2pll",
+ .mult = 1,
+ .div = 16,
+ },
+ },
+ {
+ .name = "i2c",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 4,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 16,
+ },
+ },
+ {
+ .name = "arm-scu",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 7,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 32,
+ },
+ },
+ {
+ .name = "stdmac-clken",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = -1,
+ .data.gate = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .reg = 0x2104,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "stdmac",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = 10,
+ .data.gate = {
+ .parent_name = "stdmac-clken",
+ .reg = 0x2000,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "ehci",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 18,
+ .data.factor = {
+ .parent_name = "upll",
+ .mult = 1,
+ .div = 12,
+ },
+ },
+ { /* sentinel */ }
+};
+
+static void __init ph1_sld3_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_sld3_clk_idata);
+}
+CLK_OF_DECLARE(ph1_sld3_clk, "socionext,ph1-sld3-sysctrl", ph1_sld3_clk_init);
diff --git a/drivers/clk/uniphier/clk-ph1-sld8.c b/drivers/clk/uniphier/clk-ph1-sld8.c
new file mode 100644
index 0000000..bfebd38
--- /dev/null
+++ b/drivers/clk/uniphier/clk-ph1-sld8.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+static struct uniphier_clk_init_data ph1_sld8_clk_idata[] __initdata = {
+ {
+ .name = "spll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 64,
+ .div = 1,
+ },
+ },
+ {
+ .name = "upll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 288,
+ .div = 25,
+ },
+ },
+ {
+ .name = "uart",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 3,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 20,
+ },
+ },
+ {
+ .name = "i2c",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 4,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 16,
+ },
+ },
+ {
+ .name = "arm-scu",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 7,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 32,
+ },
+ },
+ {
+ .name = "stdmac-clken",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = -1,
+ .data.gate = {
+ .parent_name = NULL,
+ .reg = 0x2104,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "stdmac",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = 10,
+ .data.gate = {
+ .parent_name = "stdmac-clken",
+ .reg = 0x2000,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "ehci",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 18,
+ .data.factor = {
+ .parent_name = "upll",
+ .mult = 1,
+ .div = 12,
+ },
+ },
+ { /* sentinel */ }
+};
+
+static void __init ph1_sld8_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_sld8_clk_idata);
+}
+CLK_OF_DECLARE(ph1_sld8_clk, "socionext,ph1-sld8-sysctrl", ph1_sld8_clk_init);
diff --git a/drivers/clk/uniphier/clk-proxstream2.c b/drivers/clk/uniphier/clk-proxstream2.c
new file mode 100644
index 0000000..b3ffedc
--- /dev/null
+++ b/drivers/clk/uniphier/clk-proxstream2.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+static struct uniphier_clk_init_data proxstream2_clk_idata[] __initdata = {
+ {
+ .name = "spll",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = -1,
+ .data.factor = {
+ .parent_name = UNIPHIER_CLK_EXT "ref",
+ .mult = 96,
+ .div = 1,
+ },
+ },
+ {
+ .name = "uart",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 3,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 27,
+ },
+ },
+ {
+ .name = "fi2c",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 4,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 48,
+ },
+ },
+ {
+ .name = "arm-scu",
+ .type = UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ .output_index = 7,
+ .data.factor = {
+ .parent_name = "spll",
+ .mult = 1,
+ .div = 48,
+ },
+ },
+ {
+ .name = "stdmac-clken",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = -1,
+ .data.gate = {
+ .parent_name = NULL,
+ .reg = 0x2104,
+ .bit_idx = 10,
+ },
+ },
+ {
+ .name = "stdmac",
+ .type = UNIPHIER_CLK_TYPE_GATE,
+ .output_index = 10,
+ .data.gate = {
+ .parent_name = "stdmac-clken",
+ .reg = 0x2000,
+ .bit_idx = 10,
+ },
+ },
+ { /* sentinel */ }
+};
+
+static void __init proxstream2_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, proxstream2_clk_idata);
+}
+CLK_OF_DECLARE(proxstream2_clk, "socionext,proxstream2-sysctrl",
+ proxstream2_clk_init);
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c
new file mode 100644
index 0000000..8680101
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-core.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#define pr_fmt(fmt) "uniphier-clk: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/log2.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk-uniphier.h"
+
+static void __init uniphier_clk_update_parent_name(struct device_node *np,
+ const char **parent_name)
+{
+ const char *new_name;
+ int index;
+
+ if (!parent_name || !*parent_name)
+ return;
+
+ if (strncmp(*parent_name, UNIPHIER_CLK_EXT, strlen(UNIPHIER_CLK_EXT)))
+ return;
+
+ index = of_property_match_string(np, "clock-names",
+ *parent_name + strlen(UNIPHIER_CLK_EXT));
+ new_name = of_clk_get_parent_name(np, index);
+ if (new_name)
+ *parent_name = new_name;
+}
+
+static struct clk * __init uniphier_clk_register(struct device_node *np,
+ void __iomem *regbase,
+ struct uniphier_clk_init_data *idata)
+{
+ int i;
+
+ switch (idata->type) {
+ case UNIPHIER_CLK_TYPE_FIXED_FACTOR:
+ uniphier_clk_update_parent_name(np,
+ &idata->data.factor.parent_name);
+ return clk_register_fixed_factor(NULL, idata->name,
+ idata->data.factor.parent_name,
+ CLK_SET_RATE_PARENT,
+ idata->data.factor.mult,
+ idata->data.factor.div);
+ case UNIPHIER_CLK_TYPE_FIXED_RATE:
+ return clk_register_fixed_rate(NULL, idata->name, NULL,
+ CLK_IS_ROOT,
+ idata->data.rate.fixed_rate);
+ case UNIPHIER_CLK_TYPE_GATE:
+ uniphier_clk_update_parent_name(np,
+ &idata->data.gate.parent_name);
+ return clk_register_gate(NULL, idata->name,
+ idata->data.gate.parent_name,
+ idata->data.gate.parent_name ?
+ CLK_SET_RATE_PARENT : CLK_IS_ROOT,
+ regbase + idata->data.gate.reg,
+ idata->data.gate.bit_idx, 0, NULL);
+ case UNIPHIER_CLK_TYPE_MUX:
+ for (i = 0; i < idata->data.mux.num_parents; i++)
+ uniphier_clk_update_parent_name(np,
+ &idata->data.mux.parent_names[i]);
+ return clk_register_mux(NULL, idata->name,
+ idata->data.mux.parent_names,
+ idata->data.mux.num_parents,
+ CLK_SET_RATE_PARENT,
+ regbase + idata->data.mux.reg,
+ idata->data.mux.shift,
+ ilog2(idata->data.mux.num_parents),
+ 0, NULL);
+ default:
+ WARN(1, "unsupported clock type\n");
+ return ERR_PTR(-EINVAL);
+ }
+}
+
+int __init uniphier_clk_init(struct device_node *np,
+ struct uniphier_clk_init_data *idata)
+{
+ struct clk_onecell_data *clk_data;
+ struct uniphier_clk_init_data *p;
+ void __iomem *regbase;
+ int max_index = 0;
+ int ret;
+
+ regbase = of_iomap(np, 0);
+ if (!regbase)
+ return -ENOMEM;
+
+ for (p = idata; p->name; p++)
+ max_index = max(max_index, p->output_index);
+
+ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->clk_num = max_index + 1;
+ clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *),
+ GFP_KERNEL);
+ if (!clk_data->clks) {
+ ret = -ENOMEM;
+ goto free_clk_data;
+ }
+
+ for (p = idata; p->name; p++) {
+ pr_debug("register %s (%s[%d])\n", p->name, np->name,
+ p->output_index);
+ p->clk = uniphier_clk_register(np, regbase, p);
+ if (IS_ERR(p->clk)) {
+ pr_err("failed to register %s\n", p->name);
+ ret = PTR_ERR(p->clk);
+ goto unregister;
+ }
+
+ if (p->output_index >= 0)
+ clk_data->clks[p->output_index] = p->clk;
+ }
+
+ ret = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+ if (ret)
+ goto unregister;
+
+ return ret;
+unregister:
+ for (p--; p >= idata; p--) {
+ pr_debug("unregister %s (%s[%d])\n", p->name, np->name,
+ p->output_index);
+ clk_unregister(p->clk);
+ p->clk = NULL;
+ }
+ kfree(clk_data->clks);
+free_clk_data:
+ kfree(clk_data);
+
+ pr_err("%s: init failed with error %d\n", np->full_name, ret);
+
+ return ret;
+}
diff --git a/drivers/clk/uniphier/clk-uniphier-mio.c b/drivers/clk/uniphier/clk-uniphier-mio.c
new file mode 100644
index 0000000..ad6491b
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-mio.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+#define UNIPHIER_MIO_CLK_SD_FIXED \
+ { \
+ .name = "sd-44m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 44444444, \
+ }, \
+ }, \
+ { \
+ .name = "sd-33m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 33333333, \
+ }, \
+ }, \
+ { \
+ .name = "sd-50m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 50000000, \
+ }, \
+ }, \
+ { \
+ .name = "sd-67m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 66666666, \
+ }, \
+ }, \
+ { \
+ .name = "sd-100m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 100000000, \
+ }, \
+ }, \
+ { \
+ .name = "sd-40m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 40000000, \
+ }, \
+ }, \
+ { \
+ .name = "sd-25m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 25000000, \
+ }, \
+ }, \
+ { \
+ .name = "sd-22m", \
+ .type = UNIPHIER_CLK_TYPE_FIXED_RATE, \
+ .output_index = -1, \
+ .data.rate = { \
+ .fixed_rate = 22222222, \
+ }, \
+ }
+
+
+#define UNIPHIER_MIO_CLK_SD(ch, index) \
+ { \
+ .name = "sd" #ch "-clksel0", \
+ .type = UNIPHIER_CLK_TYPE_MUX, \
+ .output_index = -1, \
+ .data.mux = { \
+ .parent_names = { \
+ "sd-44m", \
+ "sd-33m", \
+ "sd-50m", \
+ "sd-67m", \
+ }, \
+ .num_parents = 4, \
+ .reg = 0x30 + 0x200 * ch, \
+ .shift = 16, \
+ }, \
+ }, \
+ { \
+ .name = "sd" #ch "-clksel1", \
+ .type = UNIPHIER_CLK_TYPE_MUX, \
+ .output_index = -1, \
+ .data.mux = { \
+ .parent_names = { \
+ "sd-100m", \
+ "sd-40m", \
+ "sd-25m", \
+ "sd-22m", \
+ }, \
+ .num_parents = 4, \
+ .reg = 0x30 + 0x200 * ch, \
+ .shift = 8, \
+ }, \
+ }, \
+ { \
+ .name = "sd" #ch "-clkmode", \
+ .type = UNIPHIER_CLK_TYPE_MUX, \
+ .output_index = -1, \
+ .data.mux = { \
+ .parent_names = { \
+ "sd" #ch "-clksel0", \
+ "sd" #ch "-clksel1", \
+ }, \
+ .num_parents = 2, \
+ .reg = 0x30 + 0x200 * ch, \
+ .shift = 12, \
+ }, \
+ }, \
+ { \
+ .name = "sd" #ch "-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = "sd" #ch "-clkmode", \
+ .reg = 0x20 + 0x200 * ch, \
+ .bit_idx = 8, \
+ }, \
+ }, \
+ { \
+ .name = "sd" #ch "-bridge-reset", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = "sd" #ch "-clken", \
+ .reg = 0x110 + 0x200 * ch, \
+ .bit_idx = 26, \
+ }, \
+ }, \
+ { \
+ .name = "sd" #ch, \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = (index), \
+ .data.gate = { \
+ .parent_name = "sd" #ch "-bridge-reset", \
+ .reg = 0x110 + 0x200 * ch, \
+ .bit_idx = 0, \
+ }, \
+ }
+
+#define UNIPHIER_MIO_CLK_SD_HW_RESET(ch, index) \
+ { \
+ .name = "sd" #ch "-hw-reset", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = (index), \
+ .data.gate = { \
+ .parent_name = NULL, \
+ .reg = 0x80 + 0x200 * ch, \
+ .bit_idx = 0, \
+ }, \
+ }
+
+#define UNIPHIER_MIO_CLK_EHCI(ch, index) \
+ { \
+ .name = "ehci" #ch "-phy-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = UNIPHIER_CLK_EXT "ehci", \
+ .reg = 0x20 + 0x200 * ch, \
+ .bit_idx = 29, \
+ }, \
+ }, \
+ { \
+ .name = "ehci" #ch "-link-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = "ehci" #ch "-phy-clken", \
+ .reg = 0x20 + 0x200 * ch, \
+ .bit_idx = 28, \
+ }, \
+ }, \
+ { \
+ .name = "ehci" #ch "-bridge-reset", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = "ehci" #ch "-link-clken", \
+ .reg = 0x110 + 0x200 * ch, \
+ .bit_idx = 24, \
+ }, \
+ }, \
+ { \
+ .name = "ehci" #ch, \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = (index), \
+ .data.gate = { \
+ .parent_name = "ehci" #ch "-bridge-reset", \
+ .reg = 0x114 + 0x200 * ch, \
+ .bit_idx = 0, \
+ }, \
+ }
+
+#define UNIPHIER_MIO_CLK_DMAC(index) \
+ { \
+ .name = "miodmac-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = UNIPHIER_CLK_EXT "stdmac", \
+ .reg = 0x20, \
+ .bit_idx = 25, \
+ }, \
+ }, \
+ { \
+ .name = "miodmac", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = (index), \
+ .data.gate = { \
+ .parent_name = "miodmac-clken", \
+ .reg = 0x110, \
+ .bit_idx = 17, \
+ }, \
+ }
+
+static struct uniphier_clk_init_data ph1_sld3_mio_clk_idata[] __initdata = {
+ UNIPHIER_MIO_CLK_SD_FIXED,
+ UNIPHIER_MIO_CLK_SD(0, 0),
+ UNIPHIER_MIO_CLK_SD(1, 1),
+ UNIPHIER_MIO_CLK_SD_HW_RESET(0, 3),
+ UNIPHIER_MIO_CLK_EHCI(0, 4),
+ UNIPHIER_MIO_CLK_EHCI(1, 5),
+ UNIPHIER_MIO_CLK_EHCI(2, 6),
+ UNIPHIER_MIO_CLK_EHCI(3, 7),
+ UNIPHIER_MIO_CLK_DMAC(8),
+ { /* sentinel */ }
+};
+
+static struct uniphier_clk_init_data ph1_ld4_mio_clk_idata[] __initdata = {
+ UNIPHIER_MIO_CLK_SD_FIXED,
+ UNIPHIER_MIO_CLK_SD(0, 0),
+ UNIPHIER_MIO_CLK_SD(1, 1),
+ UNIPHIER_MIO_CLK_SD_HW_RESET(1, 3),
+ UNIPHIER_MIO_CLK_EHCI(0, 4),
+ UNIPHIER_MIO_CLK_EHCI(1, 5),
+ UNIPHIER_MIO_CLK_EHCI(2, 6),
+ UNIPHIER_MIO_CLK_DMAC(8),
+ { /* sentinel */ }
+};
+
+static struct uniphier_clk_init_data ph1_pro4_mio_clk_idata[] __initdata = {
+ UNIPHIER_MIO_CLK_SD_FIXED,
+ UNIPHIER_MIO_CLK_SD(0, 0),
+ UNIPHIER_MIO_CLK_SD(1, 1),
+ UNIPHIER_MIO_CLK_SD(2, 2),
+ UNIPHIER_MIO_CLK_SD_HW_RESET(1, 3),
+ UNIPHIER_MIO_CLK_EHCI(0, 4),
+ UNIPHIER_MIO_CLK_EHCI(1, 5),
+ UNIPHIER_MIO_CLK_DMAC(8),
+ { /* sentinel */ }
+};
+
+static struct uniphier_clk_init_data ph1_pro5_mio_clk_idata[] __initdata = {
+ UNIPHIER_MIO_CLK_SD_FIXED,
+ UNIPHIER_MIO_CLK_SD(0, 0),
+ UNIPHIER_MIO_CLK_SD(1, 1),
+ UNIPHIER_MIO_CLK_SD_HW_RESET(1, 3),
+ { /* sentinel */ }
+};
+
+static void __init ph1_sld3_mio_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_sld3_mio_clk_idata);
+}
+CLK_OF_DECLARE(ph1_sld3_mio_clk, "socionext,ph1-sld3-mioctrl",
+ ph1_sld3_mio_clk_init);
+
+static void __init ph1_ld4_mio_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_ld4_mio_clk_idata);
+}
+CLK_OF_DECLARE(ph1_ld4_mio_clk, "socionext,ph1-ld4-mioctrl",
+ ph1_ld4_mio_clk_init);
+CLK_OF_DECLARE(ph1_sld8_mio_clk, "socionext,ph1-sld8-mioctrl",
+ ph1_ld4_mio_clk_init);
+
+static void __init ph1_pro4_mio_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_pro4_mio_clk_idata);
+}
+CLK_OF_DECLARE(ph1_pro4_mio_clk, "socionext,ph1-pro4-mioctrl",
+ ph1_pro4_mio_clk_init);
+
+static void __init ph1_pro5_mio_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_pro5_mio_clk_idata);
+}
+CLK_OF_DECLARE(ph1_pro5_mio_clk, "socionext,ph1-pro5-mioctrl",
+ ph1_pro5_mio_clk_init);
+CLK_OF_DECLARE(proxstream2_mio_clk, "socionext,proxstream2-mioctrl",
+ ph1_pro5_mio_clk_init);
diff --git a/drivers/clk/uniphier/clk-uniphier-peri.c b/drivers/clk/uniphier/clk-uniphier-peri.c
new file mode 100644
index 0000000..adaae8e
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-peri.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#include <linux/clk-provider.h>
+
+#include "clk-uniphier.h"
+
+#define UNIPHIER_PERI_CLK_UART(ch, index) \
+ { \
+ .name = "uart" #ch "-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = UNIPHIER_CLK_EXT "uart", \
+ .reg = 0x24, \
+ .bit_idx = 19 + ch, \
+ }, \
+ }, \
+ { \
+ .name = "uart" #ch, \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = (index), \
+ .data.gate = { \
+ .parent_name = "uart" #ch "-clken", \
+ .reg = 0x114, \
+ .bit_idx = 19 + ch, \
+ }, \
+ }
+
+#define UNIPHIER_PERI_CLK_I2C_COMMON \
+ { \
+ .name = "i2c-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = UNIPHIER_CLK_EXT "i2c", \
+ .reg = 0x20, \
+ .bit_idx = 1, \
+ }, \
+ }, \
+ { \
+ .name = "i2c-reset", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = "i2c-clken", \
+ .reg = 0x110, \
+ .bit_idx = 1, \
+ }, \
+ }
+
+
+#define UNIPHIER_PERI_CLK_I2C(ch, index) \
+ { \
+ .name = "i2c" #ch "-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = "i2c-reset", \
+ .reg = 0x24, \
+ .bit_idx = 5 + ch, \
+ }, \
+ }, \
+ { \
+ .name = "i2c" #ch, \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = (index), \
+ .data.gate = { \
+ .parent_name = "i2c" #ch "-clken", \
+ .reg = 0x114, \
+ .bit_idx = 5 + ch, \
+ }, \
+ }
+
+#define UNIPHIER_PERI_CLK_FI2C(ch, index) \
+ { \
+ .name = "fi2c" #ch "-clken", \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = -1, \
+ .data.gate = { \
+ .parent_name = UNIPHIER_CLK_EXT "fi2c", \
+ .reg = 0x24, \
+ .bit_idx = 24 + ch, \
+ }, \
+ }, \
+ { \
+ .name = "fi2c" #ch, \
+ .type = UNIPHIER_CLK_TYPE_GATE, \
+ .output_index = index, \
+ .data.gate = { \
+ .parent_name = "fi2c" #ch "-clken", \
+ .reg = 0x114, \
+ .bit_idx = 24 + ch, \
+ }, \
+ }
+
+static struct uniphier_clk_init_data ph1_ld4_peri_clk_idata[] __initdata = {
+ UNIPHIER_PERI_CLK_UART(0, 0),
+ UNIPHIER_PERI_CLK_UART(1, 1),
+ UNIPHIER_PERI_CLK_UART(2, 2),
+ UNIPHIER_PERI_CLK_UART(3, 3),
+ UNIPHIER_PERI_CLK_I2C_COMMON,
+ UNIPHIER_PERI_CLK_I2C(0, 4),
+ UNIPHIER_PERI_CLK_I2C(1, 5),
+ UNIPHIER_PERI_CLK_I2C(2, 6),
+ UNIPHIER_PERI_CLK_I2C(3, 7),
+ UNIPHIER_PERI_CLK_I2C(4, 8),
+ { /* sentinel */ }
+};
+
+static struct uniphier_clk_init_data ph1_pro4_peri_clk_idata[] __initdata = {
+ UNIPHIER_PERI_CLK_UART(0, 0),
+ UNIPHIER_PERI_CLK_UART(1, 1),
+ UNIPHIER_PERI_CLK_UART(2, 2),
+ UNIPHIER_PERI_CLK_UART(3, 3),
+ UNIPHIER_PERI_CLK_FI2C(0, 4),
+ UNIPHIER_PERI_CLK_FI2C(1, 5),
+ UNIPHIER_PERI_CLK_FI2C(2, 6),
+ UNIPHIER_PERI_CLK_FI2C(3, 7),
+ /* no I2C ch4 */
+ UNIPHIER_PERI_CLK_FI2C(5, 9),
+ UNIPHIER_PERI_CLK_FI2C(6, 10),
+ { /* sentinel */ }
+};
+
+static struct uniphier_clk_init_data ph1_pro5_peri_clk_idata[] __initdata = {
+ UNIPHIER_PERI_CLK_UART(0, 0),
+ UNIPHIER_PERI_CLK_UART(1, 1),
+ UNIPHIER_PERI_CLK_UART(2, 2),
+ UNIPHIER_PERI_CLK_UART(3, 3),
+ UNIPHIER_PERI_CLK_FI2C(0, 4),
+ UNIPHIER_PERI_CLK_FI2C(1, 5),
+ UNIPHIER_PERI_CLK_FI2C(2, 6),
+ UNIPHIER_PERI_CLK_FI2C(3, 7),
+ UNIPHIER_PERI_CLK_FI2C(4, 8),
+ UNIPHIER_PERI_CLK_FI2C(5, 9),
+ UNIPHIER_PERI_CLK_FI2C(6, 10),
+ { /* sentinel */ }
+};
+
+static void __init ph1_ld4_peri_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_ld4_peri_clk_idata);
+}
+CLK_OF_DECLARE(ph1_ld4_peri_clk, "socionext,ph1-ld4-perictrl",
+ ph1_ld4_peri_clk_init);
+CLK_OF_DECLARE(ph1_sld8_peri_clk, "socionext,ph1-sld8-perictrl",
+ ph1_ld4_peri_clk_init);
+
+static void __init ph1_pro4_peri_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_pro4_peri_clk_idata);
+}
+CLK_OF_DECLARE(ph1_pro4_peri_clk, "socionext,ph1-pro4-perictrl",
+ ph1_pro4_peri_clk_init);
+
+static void __init ph1_pro5_peri_clk_init(struct device_node *np)
+{
+ uniphier_clk_init(np, ph1_pro5_peri_clk_idata);
+}
+CLK_OF_DECLARE(ph1_pro5_peri_clk, "socionext,ph1-pro5-perictrl",
+ ph1_pro5_peri_clk_init);
+CLK_OF_DECLARE(proxstream2_peri_clk, "socionext,proxstream2-perictrl",
+ ph1_pro5_peri_clk_init);
diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h
new file mode 100644
index 0000000..05277b6
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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 __CLK_UNIPHIER_H__
+#define __CLK_UNIPHIER_H__
+
+#include <linux/kernel.h>
+
+#define UNIPHIER_CLK_EXT "[EXT]"
+
+enum uniphier_clk_type {
+ UNIPHIER_CLK_TYPE_FIXED_FACTOR,
+ UNIPHIER_CLK_TYPE_FIXED_RATE,
+ UNIPHIER_CLK_TYPE_GATE,
+ UNIPHIER_CLK_TYPE_MUX,
+};
+
+struct uniphier_clk_fixed_factor_data {
+ const char *parent_name;
+ unsigned int mult;
+ unsigned int div;
+};
+
+struct uniphier_clk_fixed_rate_data {
+ unsigned long fixed_rate;
+};
+
+struct uniphier_clk_gate_data {
+ const char *parent_name;
+ unsigned int reg;
+ u8 bit_idx;
+};
+
+struct uniphier_clk_mux_data {
+ const char *parent_names[4];
+ u8 num_parents;
+ unsigned int reg;
+ u8 shift;
+};
+
+struct uniphier_clk_init_data {
+ const char *name;
+ enum uniphier_clk_type type;
+ int output_index;
+ union {
+ struct uniphier_clk_fixed_factor_data factor;
+ struct uniphier_clk_fixed_rate_data rate;
+ struct uniphier_clk_gate_data gate;
+ struct uniphier_clk_mux_data mux;
+ } data;
+ struct clk *clk;
+};
+
+int uniphier_clk_init(struct device_node *np,
+ struct uniphier_clk_init_data *idata);
+
+#endif /* __CLK_UNIPHIER_H__ */
--
1.9.1
More information about the linux-mtd
mailing list