From 323d1f9d5bebfe55e97e23c8094055685665afef Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 22 Sep 2015 00:27:39 +0900 Subject: ARM: uniphier: allow to enable multiple SoCs Before this commit, the Kconfig menu in mach-uniphier only allowed us to choose one SoC to be compiled. Each SoC has its own defconfig file for the build-test coverage. Consequently, some defconfig files are duplicated with only the difference in CONFIG_DEFAULT_DEVICE_TREE and CONFIG_{SOC_NAME}=y. Now, most of board-specific parameters have been moved to device trees, so it makes sense to include init code of multiple SoCs into a single image as long as the SoCs have similar architecture. In fact, some SoCs of UniPhier family are very similar: - PH1-LD4 and PH1-sLD8 - PH1-LD6b and ProXstream2 (will be added in the upcoming commit) This commit will be helpful to merge some defconfig files for better maintainability. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c | 163 +++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c (limited to 'arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c') diff --git a/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c b/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c new file mode 100644 index 0000000..906c22f --- /dev/null +++ b/arch/arm/mach-uniphier/pll/pll-init-ph1-pro4.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2011-2015 Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +#undef DPLL_SSC_RATE_1PER + +static int dpll_init(unsigned int 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); + + return 0; +} + +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); +} + +int ph1_pro4_pll_init(const struct uniphier_board_data *bd) +{ + int ret; + + ret = dpll_init(bd->dram_freq); + if (ret) + return ret; + vpll_init(); + + /* + * Wait 500 usec until dpll get stable + * We wait 1 usec in vpll_init() so 1 usec can be saved here. + */ + udelay(499); + + return 0; +} -- cgit v1.1