summaryrefslogtreecommitdiff
path: root/arch/arm/mach-uniphier/clk
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2016-09-18 12:12:04 -0400
committerTom Rini <trini@konsulko.com>2016-09-18 14:05:30 -0400
commit9a6535e05f17acf03e891266a650cb6029124743 (patch)
treefec0cd46e0f050812deecf89b8bb349c8fdffd0e /arch/arm/mach-uniphier/clk
parentb58d3512442357cb023bce69f55c08b9fd21beaa (diff)
parentf9d7e17e844f9e94c39a8c95f73a4454097a6948 (diff)
Merge branch 'master' of git://git.denx.de/u-boot-uniphier
Diffstat (limited to 'arch/arm/mach-uniphier/clk')
-rw-r--r--arch/arm/mach-uniphier/clk/Makefile28
-rw-r--r--arch/arm/mach-uniphier/clk/dpll-ld20.c22
-rw-r--r--arch/arm/mach-uniphier/clk/dpll-ld4.c56
-rw-r--r--arch/arm/mach-uniphier/clk/dpll-pro4.c60
-rw-r--r--arch/arm/mach-uniphier/clk/dpll-sld3.c13
-rw-r--r--arch/arm/mach-uniphier/clk/dpll-sld8.c62
-rw-r--r--arch/arm/mach-uniphier/clk/dpll-tail.c21
-rw-r--r--arch/arm/mach-uniphier/clk/early-clk-ld11.c32
-rw-r--r--arch/arm/mach-uniphier/clk/early-clk-ld20.c34
-rw-r--r--arch/arm/mach-uniphier/clk/early-clk-ld4.c34
-rw-r--r--arch/arm/mach-uniphier/clk/early-clk-pro5.c40
-rw-r--r--arch/arm/mach-uniphier/clk/early-clk-pxs2.c45
-rw-r--r--arch/arm/mach-uniphier/clk/pll-base-ld20.c123
-rw-r--r--arch/arm/mach-uniphier/clk/pll-ld20.c40
-rw-r--r--arch/arm/mach-uniphier/clk/pll-ld4.c153
-rw-r--r--arch/arm/mach-uniphier/clk/pll-pro4.c110
-rw-r--r--arch/arm/mach-uniphier/clk/pll-sld3.c14
-rw-r--r--arch/arm/mach-uniphier/clk/pll.h21
18 files changed, 903 insertions, 5 deletions
diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile
index 1428e0c9cc..c8d59eabe3 100644
--- a/arch/arm/mach-uniphier/clk/Makefile
+++ b/arch/arm/mach-uniphier/clk/Makefile
@@ -2,12 +2,30 @@
# SPDX-License-Identifier: GPL-2.0+
#
-obj-$(CONFIG_ARCH_UNIPHIER_SLD3) += clk-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD4) += clk-ld4.o
-obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += clk-pro4.o
-obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += clk-ld4.o
+ifdef CONFIG_SPL_BUILD
+
+obj-$(CONFIG_ARCH_UNIPHIER_SLD3) += early-clk-ld4.o dpll-sld3.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD4) += early-clk-ld4.o dpll-ld4.o
+obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += early-clk-ld4.o dpll-pro4.o
+obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += early-clk-ld4.o dpll-sld8.o
+obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += early-clk-pro5.o
+obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += early-clk-pxs2.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += early-clk-pxs2.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD11) += early-clk-ld11.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD20) += early-clk-ld20.o dpll-ld20.o
+
+else
+
+obj-$(CONFIG_ARCH_UNIPHIER_SLD3) += clk-ld4.o pll-sld3.o dpll-tail.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD4) += clk-ld4.o pll-ld4.o dpll-tail.o
+obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += clk-pro4.o pll-pro4.o dpll-tail.o
+obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += clk-ld4.o pll-ld4.o dpll-tail.o
obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += clk-pro5.o
obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += clk-pxs2.o
obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-pxs2.o
obj-$(CONFIG_ARCH_UNIPHIER_LD11) += clk-ld11.o
-obj-$(CONFIG_ARCH_UNIPHIER_LD20) += clk-ld20.o
+obj-$(CONFIG_ARCH_UNIPHIER_LD20) += clk-ld20.o pll-ld20.o
+
+endif
+
+obj-$(CONFIG_ARCH_UNIPHIER_LD20) += pll-base-ld20.o
diff --git a/arch/arm/mach-uniphier/clk/dpll-ld20.c b/arch/arm/mach-uniphier/clk/dpll-ld20.c
new file mode 100644
index 0000000000..113231307a
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/dpll-ld20.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "../init.h"
+#include "../sc64-regs.h"
+#include "pll.h"
+
+int uniphier_ld20_dpll_init(const struct uniphier_board_data *bd)
+{
+ unsigned int dpll_ssc_rate = UNIPHIER_BD_DPLL_SSC_GET_RATE(bd->flags);
+ unsigned int dram_freq = bd->dram_freq;
+
+ uniphier_ld20_sscpll_init(SC_DPLL0CTRL, dram_freq, dpll_ssc_rate, 2);
+ uniphier_ld20_sscpll_init(SC_DPLL1CTRL, dram_freq, dpll_ssc_rate, 2);
+ uniphier_ld20_sscpll_init(SC_DPLL2CTRL, dram_freq, dpll_ssc_rate, 2);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/dpll-ld4.c b/arch/arm/mach-uniphier/clk/dpll-ld4.c
new file mode 100644
index 0000000000..a40b30d0e0
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/dpll-ld4.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+
+#undef DPLL_SSC_RATE_1PER
+
+int uniphier_ld4_dpll_init(const struct uniphier_board_data *bd)
+{
+ unsigned int dram_freq = bd->dram_freq;
+ u32 tmp;
+
+ /*
+ * Set Frequency
+ * Set 0xc(1600MHz)/0xd(1333MHz)/0xe(1066MHz)
+ * to FOUT (DPLLCTRL.bit[29:20])
+ */
+ tmp = readl(SC_DPLLCTRL);
+ tmp &= ~0x000f0000;
+ switch (dram_freq) {
+ case 1333:
+ tmp |= 0x000d0000;
+ break;
+ case 1600:
+ tmp |= 0x000c0000;
+ break;
+ default:
+ pr_err("Unsupported frequency");
+ return -EINVAL;
+ }
+
+#if defined(DPLL_SSC_RATE_1PER)
+ tmp &= ~SC_DPLLCTRL_SSC_RATE;
+#else
+ tmp |= SC_DPLLCTRL_SSC_RATE;
+#endif
+ writel(tmp, SC_DPLLCTRL);
+
+ tmp = readl(SC_DPLLCTRL2);
+ tmp |= SC_DPLLCTRL2_NRSTDS;
+ writel(tmp, SC_DPLLCTRL2);
+
+ /* Wait 500 usec until dpll gets stable */
+ udelay(500);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/dpll-pro4.c b/arch/arm/mach-uniphier/clk/dpll-pro4.c
new file mode 100644
index 0000000000..3ac48d6365
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/dpll-pro4.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+
+#undef DPLL_SSC_RATE_1PER
+
+int uniphier_pro4_dpll_init(const struct uniphier_board_data *bd)
+{
+ unsigned int dram_freq = bd->dram_freq;
+ u32 tmp;
+
+ /*
+ * Set Frequency
+ * Set 0xc(1600MHz)/0xd(1333MHz)/0xe(1066MHz)
+ * to FOUT ( DPLLCTRL.bit[29:20] )
+ */
+ tmp = readl(SC_DPLLCTRL);
+ tmp &= ~(0x000f0000);
+ switch (dram_freq) {
+ case 1333:
+ tmp |= 0x000d0000;
+ break;
+ case 1600:
+ tmp |= 0x000c0000;
+ break;
+ default:
+ pr_err("Unsupported frequency");
+ return -EINVAL;
+ }
+
+ /*
+ * Set Moduration rate
+ * Set 0x0(1%)/0x1(2%) to SSC_RATE(DPLLCTRL.bit[15])
+ */
+#if defined(DPLL_SSC_RATE_1PER)
+ tmp &= ~0x00008000;
+#else
+ tmp |= 0x00008000;
+#endif
+ writel(tmp, SC_DPLLCTRL);
+
+ tmp = readl(SC_DPLLCTRL2);
+ tmp |= SC_DPLLCTRL2_NRSTDS;
+ writel(tmp, SC_DPLLCTRL2);
+
+ /* Wait until dpll gets stable */
+ udelay(500);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/dpll-sld3.c b/arch/arm/mach-uniphier/clk/dpll-sld3.c
new file mode 100644
index 0000000000..0eb310ceb8
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/dpll-sld3.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "../init.h"
+
+int uniphier_sld3_dpll_init(const struct uniphier_board_data *bd)
+{
+ /* add pll init code here */
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/dpll-sld8.c b/arch/arm/mach-uniphier/clk/dpll-sld8.c
new file mode 100644
index 0000000000..7faa5e85b6
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/dpll-sld8.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+
+int uniphier_sld8_dpll_init(const struct uniphier_board_data *bd)
+{
+ u32 tmp;
+ /*
+ * Set DPLL SSC parameters for DPLLCTRL3
+ * [23] DIVN_TEST 0x1
+ * [22:16] DIVN 0x50
+ * [10] FREFSEL_TEST 0x1
+ * [9:8] FREFSEL 0x2
+ * [4] ICPD_TEST 0x1
+ * [3:0] ICPD 0xb
+ */
+ tmp = readl(SC_DPLLCTRL3);
+ tmp &= ~0x00ff0717;
+ tmp |= 0x00d0061b;
+ writel(tmp, SC_DPLLCTRL3);
+
+ /*
+ * Set DPLL SSC parameters for DPLLCTRL
+ * <-1%> <-2%>
+ * [29:20] SSC_UPCNT 132 (0x084) 132 (0x084)
+ * [14:0] SSC_dK 6335(0x18bf) 12710(0x31a6)
+ */
+ tmp = readl(SC_DPLLCTRL);
+ tmp &= ~0x3ff07fff;
+#ifdef DPLL_SSC_RATE_1PER
+ tmp |= 0x084018bf;
+#else
+ tmp |= 0x084031a6;
+#endif
+ writel(tmp, SC_DPLLCTRL);
+
+ /*
+ * Set DPLL SSC parameters for DPLLCTRL2
+ * [31:29] SSC_STEP 0
+ * [27] SSC_REG_REF 1
+ * [26:20] SSC_M 79 (0x4f)
+ * [19:0] SSC_K 964689 (0xeb851)
+ */
+ tmp = readl(SC_DPLLCTRL2);
+ tmp &= ~0xefffffff;
+ tmp |= 0x0cfeb851;
+ writel(tmp, SC_DPLLCTRL2);
+
+ /* Wait 500 usec until dpll gets stable */
+ udelay(500);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/dpll-tail.c b/arch/arm/mach-uniphier/clk/dpll-tail.c
new file mode 100644
index 0000000000..2b88490f42
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/dpll-tail.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2011-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+
+#include "../sc-regs.h"
+#include "pll.h"
+
+void uniphier_ld4_dpll_ssc_en(void)
+{
+ u32 tmp;
+
+ tmp = readl(SC_DPLLCTRL);
+ tmp |= SC_DPLLCTRL_SSC_EN;
+ writel(tmp, SC_DPLLCTRL);
+}
diff --git a/arch/arm/mach-uniphier/clk/early-clk-ld11.c b/arch/arm/mach-uniphier/clk/early-clk-ld11.c
new file mode 100644
index 0000000000..c94d83c4ed
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/early-clk-ld11.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc64-regs.h"
+
+int uniphier_ld11_early_clk_init(const struct uniphier_board_data *bd)
+{
+ u32 tmp;
+
+ /* deassert reset */
+ tmp = readl(SC_RSTCTRL7);
+ tmp |= SC_RSTCTRL7_UMC31 | SC_RSTCTRL7_UMC30;
+ writel(tmp, SC_RSTCTRL7);
+
+ /* provide clocks */
+ tmp = readl(SC_CLKCTRL4);
+ tmp |= SC_CLKCTRL4_PERI;
+ writel(tmp, SC_CLKCTRL4);
+
+ tmp = readl(SC_CLKCTRL7);
+ tmp |= SC_CLKCTRL7_UMC31 | SC_CLKCTRL7_UMC30;
+ writel(tmp, SC_CLKCTRL7);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/early-clk-ld20.c b/arch/arm/mach-uniphier/clk/early-clk-ld20.c
new file mode 100644
index 0000000000..5201a55940
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/early-clk-ld20.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc64-regs.h"
+
+int uniphier_ld20_early_clk_init(const struct uniphier_board_data *bd)
+{
+ u32 tmp;
+
+ /* deassert reset */
+ tmp = readl(SC_RSTCTRL7);
+ tmp |= SC_RSTCTRL7_UMCSB | SC_RSTCTRL7_UMCA2 | SC_RSTCTRL7_UMCA1 |
+ SC_RSTCTRL7_UMCA0 | SC_RSTCTRL7_UMC32 | SC_RSTCTRL7_UMC31 |
+ SC_RSTCTRL7_UMC30;
+ writel(tmp, SC_RSTCTRL7);
+
+ /* provide clocks */
+ tmp = readl(SC_CLKCTRL4);
+ tmp |= SC_CLKCTRL4_PERI;
+ writel(tmp, SC_CLKCTRL4);
+
+ tmp = readl(SC_CLKCTRL7);
+ tmp |= SC_CLKCTRL7_UMCSB | SC_CLKCTRL7_UMC32 | SC_CLKCTRL7_UMC31 |
+ SC_CLKCTRL7_UMC30;
+ writel(tmp, SC_CLKCTRL7);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/early-clk-ld4.c b/arch/arm/mach-uniphier/clk/early-clk-ld4.c
new file mode 100644
index 0000000000..b6e8b646f9
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/early-clk-ld4.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+
+int uniphier_ld4_early_clk_init(const struct uniphier_board_data *bd)
+{
+ u32 tmp;
+
+ /* deassert reset */
+ tmp = readl(SC_RSTCTRL);
+
+ tmp |= SC_RSTCTRL_NRST_UMC1 | SC_RSTCTRL_NRST_UMC0;
+ if (spl_boot_device() != BOOT_DEVICE_NAND)
+ tmp &= ~SC_RSTCTRL_NRST_NAND;
+ writel(tmp, SC_RSTCTRL);
+ readl(SC_RSTCTRL); /* dummy read */
+
+ /* provide clocks */
+ tmp = readl(SC_CLKCTRL);
+ tmp |= SC_CLKCTRL_CEN_UMC | SC_CLKCTRL_CEN_SBC | SC_CLKCTRL_CEN_PERI;
+ writel(tmp, SC_CLKCTRL);
+ readl(SC_CLKCTRL); /* dummy read */
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/early-clk-pro5.c b/arch/arm/mach-uniphier/clk/early-clk-pro5.c
new file mode 100644
index 0000000000..c41a8ead2e
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/early-clk-pro5.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+
+int uniphier_pro5_early_clk_init(const struct uniphier_board_data *bd)
+{
+ u32 tmp;
+
+ /*
+ * deassert reset
+ * UMCA2: Ch1 (DDR3)
+ * UMCA1, UMC31: Ch0 (WIO1)
+ * UMCA0, UMC30: Ch0 (WIO0)
+ */
+ tmp = readl(SC_RSTCTRL4);
+ tmp |= SC_RSTCTRL4_NRST_UMCSB | SC_RSTCTRL4_NRST_UMCA2 |
+ SC_RSTCTRL4_NRST_UMCA1 | SC_RSTCTRL4_NRST_UMCA0 |
+ SC_RSTCTRL4_NRST_UMC31 | SC_RSTCTRL4_NRST_UMC30;
+ writel(tmp, SC_RSTCTRL4);
+ readl(SC_RSTCTRL); /* dummy read */
+
+ /* provide clocks */
+ tmp = readl(SC_CLKCTRL);
+ tmp |= SC_CLKCTRL_CEN_SBC | SC_CLKCTRL_CEN_PERI;
+ writel(tmp, SC_CLKCTRL);
+ tmp = readl(SC_CLKCTRL4);
+ tmp |= SC_CLKCTRL4_CEN_UMCSB | SC_CLKCTRL4_CEN_UMC1 |
+ SC_CLKCTRL4_CEN_UMC0;
+ writel(tmp, SC_CLKCTRL4);
+ readl(SC_CLKCTRL4); /* dummy read */
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/early-clk-pxs2.c b/arch/arm/mach-uniphier/clk/early-clk-pxs2.c
new file mode 100644
index 0000000000..665ecd510f
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/early-clk-pxs2.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+
+int uniphier_pxs2_early_clk_init(const struct uniphier_board_data *bd)
+{
+ u32 tmp;
+
+ /* deassert reset */
+ if (spl_boot_device() != BOOT_DEVICE_NAND) {
+ tmp = readl(SC_RSTCTRL);
+ tmp &= ~SC_RSTCTRL_NRST_NAND;
+ writel(tmp, SC_RSTCTRL);
+ };
+
+ tmp = readl(SC_RSTCTRL4);
+ tmp |= SC_RSTCTRL4_NRST_UMCSB | SC_RSTCTRL4_NRST_UMCA2 |
+ SC_RSTCTRL4_NRST_UMCA1 | SC_RSTCTRL4_NRST_UMCA0 |
+ SC_RSTCTRL4_NRST_UMC32 | SC_RSTCTRL4_NRST_UMC31 |
+ SC_RSTCTRL4_NRST_UMC30;
+ writel(tmp, SC_RSTCTRL4);
+ readl(SC_RSTCTRL4); /* dummy read */
+
+ /* provide clocks */
+ tmp = readl(SC_CLKCTRL);
+ tmp |= SC_CLKCTRL_CEN_SBC | SC_CLKCTRL_CEN_PERI;
+ writel(tmp, SC_CLKCTRL);
+
+ tmp = readl(SC_CLKCTRL4);
+ tmp |= SC_CLKCTRL4_CEN_UMCSB | SC_CLKCTRL4_CEN_UMC2 |
+ SC_CLKCTRL4_CEN_UMC1 | SC_CLKCTRL4_CEN_UMC0;
+ writel(tmp, SC_CLKCTRL4);
+ readl(SC_CLKCTRL4); /* dummy read */
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/pll-base-ld20.c b/arch/arm/mach-uniphier/clk/pll-base-ld20.c
new file mode 100644
index 0000000000..a5027d2079
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/pll-base-ld20.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+#include "pll.h"
+
+/* PLL type: SSC */
+#define SC_PLLCTRL_SSC_DK_MASK GENMASK(14, 0)
+#define SC_PLLCTRL_SSC_EN BIT(31)
+#define SC_PLLCTRL2_NRSTDS BIT(28)
+#define SC_PLLCTRL2_SSC_JK_MASK GENMASK(26, 0)
+
+/* PLL type: VPLL27 */
+#define SC_VPLL27CTRL_WP BIT(0)
+#define SC_VPLL27CTRL3_K_LD BIT(28)
+
+/* PLL type: DSPLL */
+#define SC_DSPLLCTRL2_K_LD BIT(28)
+
+int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq,
+ unsigned int ssc_rate, unsigned int divn)
+{
+ void __iomem *base;
+ u32 tmp;
+
+ base = ioremap(reg_base, SZ_16);
+ if (!base)
+ return -ENOMEM;
+
+ if (freq != UNIPHIER_PLL_FREQ_DEFAULT) {
+ tmp = readl(base); /* SSCPLLCTRL */
+ tmp &= ~SC_PLLCTRL_SSC_DK_MASK;
+ tmp |= (487 * freq * ssc_rate / divn / 512) &
+ SC_PLLCTRL_SSC_DK_MASK;
+ writel(tmp, base);
+
+ tmp = readl(base + 4);
+ tmp &= ~SC_PLLCTRL2_SSC_JK_MASK;
+ tmp |= (41859 * freq / divn) & SC_PLLCTRL2_SSC_JK_MASK;
+
+ udelay(50);
+ }
+
+ tmp = readl(base + 4); /* SSCPLLCTRL2 */
+ tmp |= SC_PLLCTRL2_NRSTDS;
+ writel(tmp, base + 4);
+
+ iounmap(base);
+
+ return 0;
+}
+
+int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base)
+{
+ void __iomem *base;
+ u32 tmp;
+
+ base = ioremap(reg_base, SZ_16);
+ if (!base)
+ return -ENOMEM;
+
+ mdelay(1);
+
+ tmp = readl(base); /* SSCPLLCTRL */
+ tmp |= SC_PLLCTRL_SSC_EN;
+ writel(tmp, base);
+
+ iounmap(base);
+
+ return 0;
+}
+
+int uniphier_ld20_vpll27_init(unsigned long reg_base)
+{
+ void __iomem *base;
+ u32 tmp;
+
+ base = ioremap(reg_base, SZ_16);
+ if (!base)
+ return -ENOMEM;
+
+ tmp = readl(base); /* VPLL27CTRL */
+ tmp |= SC_VPLL27CTRL_WP; /* write protect off */
+ writel(tmp, base);
+
+ tmp = readl(base + 8); /* VPLL27CTRL3 */
+ tmp |= SC_VPLL27CTRL3_K_LD;
+ writel(tmp, base + 8);
+
+ tmp = readl(base); /* VPLL27CTRL */
+ tmp &= ~SC_VPLL27CTRL_WP; /* write protect on */
+ writel(tmp, base);
+
+ iounmap(base);
+
+ return 0;
+}
+
+int uniphier_ld20_dspll_init(unsigned long reg_base)
+{
+ void __iomem *base;
+ u32 tmp;
+
+ base = ioremap(reg_base, SZ_16);
+ if (!base)
+ return -ENOMEM;
+
+ tmp = readl(base + 8); /* DSPLLCTRL2 */
+ tmp |= SC_DSPLLCTRL2_K_LD;
+ writel(tmp, base + 8);
+
+ iounmap(base);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/pll-ld20.c b/arch/arm/mach-uniphier/clk/pll-ld20.c
new file mode 100644
index 0000000000..5e545da227
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/pll-ld20.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+#include "../init.h"
+#include "../sc64-regs.h"
+#include "pll.h"
+
+int uniphier_ld20_pll_init(const struct uniphier_board_data *bd)
+{
+ unsigned int dpll_ssc_rate = UNIPHIER_BD_DPLL_SSC_GET_RATE(bd->flags);
+
+ uniphier_ld20_sscpll_init(SC_CPLLCTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 4);
+ /* do nothing for SPLL */
+ uniphier_ld20_sscpll_init(SC_SPLL2CTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 4);
+ uniphier_ld20_sscpll_init(SC_MPLLCTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2);
+ uniphier_ld20_sscpll_init(SC_VPPLLCTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 4);
+ uniphier_ld20_sscpll_init(SC_GPPLLCTRL, UNIPHIER_PLL_FREQ_DEFAULT, 0, 2);
+
+ mdelay(1);
+
+ if (dpll_ssc_rate > 0) {
+ uniphier_ld20_sscpll_ssc_en(SC_DPLL0CTRL);
+ uniphier_ld20_sscpll_ssc_en(SC_DPLL1CTRL);
+ uniphier_ld20_sscpll_ssc_en(SC_DPLL2CTRL);
+ }
+
+ uniphier_ld20_vpll27_init(SC_VPLL27FCTRL);
+ uniphier_ld20_vpll27_init(SC_VPLL27ACTRL);
+
+ uniphier_ld20_dspll_init(SC_VPLL8KCTRL);
+ uniphier_ld20_dspll_init(SC_A2PLLCTRL);
+
+ return 0;
+}
diff --git a/arch/arm/mach-uniphier/clk/pll-ld4.c b/arch/arm/mach-uniphier/clk/pll-ld4.c
new file mode 100644
index 0000000000..13257e4d16
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/pll-ld4.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2013-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+#include "../sg-regs.h"
+#include "pll.h"
+
+static void upll_init(void)
+{
+ u32 tmp, clk_mode_upll, clk_mode_axosel;
+
+ tmp = readl(SG_PINMON0);
+ clk_mode_upll = tmp & SG_PINMON0_CLK_MODE_UPLLSRC_MASK;
+ clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
+
+ /* set 0 to SNRT(UPLLCTRL.bit28) and K_LD(UPLLCTRL.bit[27]) */
+ tmp = readl(SC_UPLLCTRL);
+ tmp &= ~0x18000000;
+ writel(tmp, SC_UPLLCTRL);
+
+ if (clk_mode_upll == SG_PINMON0_CLK_MODE_UPLLSRC_DEFAULT) {
+ if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_U ||
+ clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_A) {
+ /* AXO: 25MHz */
+ tmp &= ~0x07ffffff;
+ tmp |= 0x0228f5c0;
+ } else {
+ /* AXO: default 24.576MHz */
+ tmp &= ~0x07ffffff;
+ tmp |= 0x02328000;
+ }
+ }
+
+ writel(tmp, SC_UPLLCTRL);
+
+ /* set 1 to K_LD(UPLLCTRL.bit[27]) */
+ tmp |= 0x08000000;
+ writel(tmp, SC_UPLLCTRL);
+
+ /* wait 10 usec */
+ udelay(10);
+
+ /* set 1 to SNRT(UPLLCTRL.bit[28]) */
+ tmp |= 0x10000000;
+ writel(tmp, SC_UPLLCTRL);
+}
+
+static void vpll_init(void)
+{
+ u32 tmp, clk_mode_axosel;
+
+ tmp = readl(SG_PINMON0);
+ clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
+
+ /* set 1 to VPLA27WP and VPLA27WP */
+ tmp = readl(SC_VPLL27ACTRL);
+ tmp |= 0x00000001;
+ writel(tmp, SC_VPLL27ACTRL);
+ tmp = readl(SC_VPLL27BCTRL);
+ tmp |= 0x00000001;
+ writel(tmp, SC_VPLL27BCTRL);
+
+ /* Set 0 to VPLA_K_LD and VPLB_K_LD */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp &= ~0x10000000;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp &= ~0x10000000;
+ writel(tmp, SC_VPLL27BCTRL3);
+
+ /* Set 0 to VPLA_SNRST and VPLB_SNRST */
+ tmp = readl(SC_VPLL27ACTRL2);
+ tmp &= ~0x10000000;
+ writel(tmp, SC_VPLL27ACTRL2);
+ tmp = readl(SC_VPLL27BCTRL2);
+ tmp &= ~0x10000000;
+ writel(tmp, SC_VPLL27BCTRL2);
+
+ /* Set 0x20 to VPLA_SNRST and VPLB_SNRST */
+ tmp = readl(SC_VPLL27ACTRL2);
+ tmp &= ~0x0000007f;
+ tmp |= 0x00000020;
+ writel(tmp, SC_VPLL27ACTRL2);
+ tmp = readl(SC_VPLL27BCTRL2);
+ tmp &= ~0x0000007f;
+ tmp |= 0x00000020;
+ writel(tmp, SC_VPLL27BCTRL2);
+
+ if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_U ||
+ clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ_A) {
+ /* AXO: 25MHz */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x00066664;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x00066664;
+ writel(tmp, SC_VPLL27BCTRL3);
+ } else {
+ /* AXO: default 24.576MHz */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x000f5800;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x000f5800;
+ writel(tmp, SC_VPLL27BCTRL3);
+ }
+
+ /* Set 1 to VPLA_K_LD and VPLB_K_LD */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27BCTRL3);
+
+ /* wait 10 usec */
+ udelay(10);
+
+ /* Set 0 to VPLA_SNRST and VPLB_SNRST */
+ tmp = readl(SC_VPLL27ACTRL2);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27ACTRL2);
+ tmp = readl(SC_VPLL27BCTRL2);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27BCTRL2);
+
+ /* set 0 to VPLA27WP and VPLA27WP */
+ tmp = readl(SC_VPLL27ACTRL);
+ tmp &= ~0x00000001;
+ writel(tmp, SC_VPLL27ACTRL);
+ tmp = readl(SC_VPLL27BCTRL);
+ tmp |= ~0x00000001;
+ writel(tmp, SC_VPLL27BCTRL);
+}
+
+void uniphier_ld4_pll_init(void)
+{
+ upll_init();
+ vpll_init();
+ uniphier_ld4_dpll_ssc_en();
+}
diff --git a/arch/arm/mach-uniphier/clk/pll-pro4.c b/arch/arm/mach-uniphier/clk/pll-pro4.c
new file mode 100644
index 0000000000..cdd1fd4bf1
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/pll-pro4.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013-2014 Panasonic Corporation
+ * Copyright (C) 2015-2016 Socionext Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+
+#include "../init.h"
+#include "../sc-regs.h"
+#include "../sg-regs.h"
+#include "pll.h"
+
+static void vpll_init(void)
+{
+ u32 tmp, clk_mode_axosel;
+
+ /* Set VPLL27A & VPLL27B */
+ tmp = readl(SG_PINMON0);
+ clk_mode_axosel = tmp & SG_PINMON0_CLK_MODE_AXOSEL_MASK;
+
+ /* 25MHz or 6.25MHz is default for Pro4R, no need to set VPLLA/B */
+ if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ ||
+ clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_6250KHZ)
+ return;
+
+ /* Disable write protect of VPLL27ACTRL[2-7]*, VPLL27BCTRL[2-8] */
+ tmp = readl(SC_VPLL27ACTRL);
+ tmp |= 0x00000001;
+ writel(tmp, SC_VPLL27ACTRL);
+ tmp = readl(SC_VPLL27BCTRL);
+ tmp |= 0x00000001;
+ writel(tmp, SC_VPLL27BCTRL);
+
+ /* Unset VPLA_K_LD and VPLB_K_LD bit */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp &= ~0x10000000;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp &= ~0x10000000;
+ writel(tmp, SC_VPLL27BCTRL3);
+
+ /* Set VPLA_M and VPLB_M to 0x20 */
+ tmp = readl(SC_VPLL27ACTRL2);
+ tmp &= ~0x0000007f;
+ tmp |= 0x00000020;
+ writel(tmp, SC_VPLL27ACTRL2);
+ tmp = readl(SC_VPLL27BCTRL2);
+ tmp &= ~0x0000007f;
+ tmp |= 0x00000020;
+ writel(tmp, SC_VPLL27BCTRL2);
+
+ if (clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_25000KHZ ||
+ clk_mode_axosel == SG_PINMON0_CLK_MODE_AXOSEL_6250KHZ) {
+ /* Set VPLA_K and VPLB_K for AXO: 25MHz */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x00066666;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x00066666;
+ writel(tmp, SC_VPLL27BCTRL3);
+ } else {
+ /* Set VPLA_K and VPLB_K for AXO: 24.576 MHz */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x000f5800;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp &= ~0x000fffff;
+ tmp |= 0x000f5800;
+ writel(tmp, SC_VPLL27BCTRL3);
+ }
+
+ /* wait 1 usec */
+ udelay(1);
+
+ /* Set VPLA_K_LD and VPLB_K_LD to load K parameters */
+ tmp = readl(SC_VPLL27ACTRL3);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27ACTRL3);
+ tmp = readl(SC_VPLL27BCTRL3);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27BCTRL3);
+
+ /* Unset VPLA_SNRST and VPLB_SNRST bit */
+ tmp = readl(SC_VPLL27ACTRL2);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27ACTRL2);
+ tmp = readl(SC_VPLL27BCTRL2);
+ tmp |= 0x10000000;
+ writel(tmp, SC_VPLL27BCTRL2);
+
+ /* Enable write protect of VPLL27ACTRL[2-7]*, VPLL27BCTRL[2-8] */
+ tmp = readl(SC_VPLL27ACTRL);
+ tmp &= ~0x00000001;
+ writel(tmp, SC_VPLL27ACTRL);
+ tmp = readl(SC_VPLL27BCTRL);
+ tmp &= ~0x00000001;
+ writel(tmp, SC_VPLL27BCTRL);
+}
+
+void uniphier_pro4_pll_init(void)
+{
+ vpll_init();
+ uniphier_ld4_dpll_ssc_en();
+}
diff --git a/arch/arm/mach-uniphier/clk/pll-sld3.c b/arch/arm/mach-uniphier/clk/pll-sld3.c
new file mode 100644
index 0000000000..37a7c12782
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/pll-sld3.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "../init.h"
+#include "pll.h"
+
+void uniphier_sld3_pll_init(void)
+{
+ uniphier_ld4_dpll_ssc_en();
+}
diff --git a/arch/arm/mach-uniphier/clk/pll.h b/arch/arm/mach-uniphier/clk/pll.h
new file mode 100644
index 0000000000..d7e93037d6
--- /dev/null
+++ b/arch/arm/mach-uniphier/clk/pll.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef MACH_PLL_H
+#define MACH_PLL_H
+
+#define UNIPHIER_PLL_FREQ_DEFAULT (0)
+
+void uniphier_ld4_dpll_ssc_en(void);
+
+int uniphier_ld20_sscpll_init(unsigned long reg_base, unsigned int freq,
+ unsigned int ssc_rate, unsigned int divn);
+int uniphier_ld20_sscpll_ssc_en(unsigned long reg_base);
+int uniphier_ld20_vpll27_init(unsigned long reg_base);
+int uniphier_ld20_dspll_init(unsigned long reg_base);
+
+#endif /* MACH_PLL_H */