From 6a3e4274e479a70069518679e45fe85ef3f30a36 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Sep 2016 03:33:09 +0900 Subject: ARM: uniphier: move PLL init code to U-Boot proper where possible The PLL for the DRAM interface must be initialized in SPL, but the others can be delayed until U-Boot proper. Move them from SPL to U-Boot proper to save the precious SPL memory footprint. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/clk/Makefile | 8 +- arch/arm/mach-uniphier/clk/dpll-tail.c | 21 +++++ arch/arm/mach-uniphier/clk/pll-ld4.c | 153 +++++++++++++++++++++++++++++++++ arch/arm/mach-uniphier/clk/pll-pro4.c | 110 ++++++++++++++++++++++++ arch/arm/mach-uniphier/clk/pll-sld3.c | 14 +++ arch/arm/mach-uniphier/clk/pll.h | 13 +++ 6 files changed, 315 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-uniphier/clk/dpll-tail.c create mode 100644 arch/arm/mach-uniphier/clk/pll-ld4.c create mode 100644 arch/arm/mach-uniphier/clk/pll-pro4.c create mode 100644 arch/arm/mach-uniphier/clk/pll-sld3.c create mode 100644 arch/arm/mach-uniphier/clk/pll.h (limited to 'arch/arm/mach-uniphier/clk') diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile index 1428e0c..b722781 100644 --- a/arch/arm/mach-uniphier/clk/Makefile +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -2,10 +2,10 @@ # 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 +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 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 0000000..2b88490 --- /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 + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#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/pll-ld4.c b/arch/arm/mach-uniphier/clk/pll-ld4.c new file mode 100644 index 0000000..13257e4 --- /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 +#include + +#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 0000000..cdd1fd4 --- /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 +#include + +#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 0000000..37a7c12 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/pll-sld3.c @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * 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 0000000..ef0f722 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/pll.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef MACH_PLL_H +#define MACH_PLL_H + +void uniphier_ld4_dpll_ssc_en(void); + +#endif /* MACH_PLL_H */ -- cgit v1.1 From fcc238baee1495ff9796dfc4e13f8069a152e85f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Sep 2016 03:33:10 +0900 Subject: ARM: uniphier: collect clock/PLL init code into a single directory Now PLLs for DRAM controller are initialized in SPL, and the others in U-Boot proper. Setting up all of them in a single directory will be helpful when we want to share code between SPL and U-Boot proper. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/clk/Makefile | 16 ++++++++ arch/arm/mach-uniphier/clk/dpll-ld4.c | 56 ++++++++++++++++++++++++++ arch/arm/mach-uniphier/clk/dpll-pro4.c | 60 ++++++++++++++++++++++++++++ arch/arm/mach-uniphier/clk/dpll-sld3.c | 13 ++++++ arch/arm/mach-uniphier/clk/dpll-sld8.c | 62 +++++++++++++++++++++++++++++ arch/arm/mach-uniphier/clk/early-clk-ld11.c | 32 +++++++++++++++ arch/arm/mach-uniphier/clk/early-clk-ld20.c | 34 ++++++++++++++++ arch/arm/mach-uniphier/clk/early-clk-ld4.c | 34 ++++++++++++++++ arch/arm/mach-uniphier/clk/early-clk-pro5.c | 40 +++++++++++++++++++ arch/arm/mach-uniphier/clk/early-clk-pxs2.c | 45 +++++++++++++++++++++ 10 files changed, 392 insertions(+) create mode 100644 arch/arm/mach-uniphier/clk/dpll-ld4.c create mode 100644 arch/arm/mach-uniphier/clk/dpll-pro4.c create mode 100644 arch/arm/mach-uniphier/clk/dpll-sld3.c create mode 100644 arch/arm/mach-uniphier/clk/dpll-sld8.c create mode 100644 arch/arm/mach-uniphier/clk/early-clk-ld11.c create mode 100644 arch/arm/mach-uniphier/clk/early-clk-ld20.c create mode 100644 arch/arm/mach-uniphier/clk/early-clk-ld4.c create mode 100644 arch/arm/mach-uniphier/clk/early-clk-pro5.c create mode 100644 arch/arm/mach-uniphier/clk/early-clk-pxs2.c (limited to 'arch/arm/mach-uniphier/clk') diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile index b722781..233e659 100644 --- a/arch/arm/mach-uniphier/clk/Makefile +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -2,6 +2,20 @@ # SPDX-License-Identifier: GPL-2.0+ # +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 + +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 @@ -11,3 +25,5 @@ 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 + +endif 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 0000000..a40b30d --- /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 +#include +#include + +#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 0000000..3ac48d6 --- /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 +#include +#include + +#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 0000000..0eb310c --- /dev/null +++ b/arch/arm/mach-uniphier/clk/dpll-sld3.c @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada + * + * 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 0000000..7faa5e8 --- /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 +#include + +#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/early-clk-ld11.c b/arch/arm/mach-uniphier/clk/early-clk-ld11.c new file mode 100644 index 0000000..c94d83c --- /dev/null +++ b/arch/arm/mach-uniphier/clk/early-clk-ld11.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#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 0000000..5201a55 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/early-clk-ld20.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2016 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#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 0000000..b6e8b64 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/early-clk-ld4.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#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 0000000..c41a8ea --- /dev/null +++ b/arch/arm/mach-uniphier/clk/early-clk-pro5.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#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 0000000..665ecd5 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/early-clk-pxs2.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +#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; +} -- cgit v1.1 From 682e09ff9f3514e79ee3382988b74f63b4bdd06b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 17 Sep 2016 03:33:11 +0900 Subject: ARM: uniphier: add PLL init code for LD20 SoC Initialize the DPLL (PLL for DRAM) in SPL, and others in U-Boot proper. Split the common code into pll-base-ld20.c for easier re-use. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/clk/Makefile | 6 +- arch/arm/mach-uniphier/clk/dpll-ld20.c | 22 ++++++ arch/arm/mach-uniphier/clk/pll-base-ld20.c | 123 +++++++++++++++++++++++++++++ arch/arm/mach-uniphier/clk/pll-ld20.c | 40 ++++++++++ arch/arm/mach-uniphier/clk/pll.h | 8 ++ 5 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-uniphier/clk/dpll-ld20.c create mode 100644 arch/arm/mach-uniphier/clk/pll-base-ld20.c create mode 100644 arch/arm/mach-uniphier/clk/pll-ld20.c (limited to 'arch/arm/mach-uniphier/clk') diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile index 233e659..c8d59ea 100644 --- a/arch/arm/mach-uniphier/clk/Makefile +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -12,7 +12,7 @@ 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 +obj-$(CONFIG_ARCH_UNIPHIER_LD20) += early-clk-ld20.o dpll-ld20.o else @@ -24,6 +24,8 @@ 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 0000000..1132313 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/dpll-ld20.c @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * 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/pll-base-ld20.c b/arch/arm/mach-uniphier/clk/pll-base-ld20.c new file mode 100644 index 0000000..a5027d2 --- /dev/null +++ b/arch/arm/mach-uniphier/clk/pll-base-ld20.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +#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 0000000..5e545da --- /dev/null +++ b/arch/arm/mach-uniphier/clk/pll-ld20.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include + +#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.h b/arch/arm/mach-uniphier/clk/pll.h index ef0f722..d7e9303 100644 --- a/arch/arm/mach-uniphier/clk/pll.h +++ b/arch/arm/mach-uniphier/clk/pll.h @@ -8,6 +8,14 @@ #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 */ -- cgit v1.1