Messages in this thread Patch in this message | | | From | Masahiro Yamada <> | Subject | [PATCH v2,RESEND] clk: uniphier: add clock drivers for UniPhier SoCs | Date | Mon, 28 Dec 2015 19:20:58 +0900 |
| |
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@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@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@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@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@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@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@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@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@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@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@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
| |