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 <yamada.masahiro@socionext.com>
This commit is contained in:
		
							parent
							
								
									fcc238baee
								
							
						
					
					
						commit
						682e09ff9f
					
				|  | @ -58,8 +58,14 @@ static void uniphier_nand_pin_init(bool cs2) | |||
| 
 | ||||
| int board_init(void) | ||||
| { | ||||
| 	const struct uniphier_board_data *bd; | ||||
| 
 | ||||
| 	led_puts("U0"); | ||||
| 
 | ||||
| 	bd = uniphier_get_board_param(); | ||||
| 	if (!bd) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	switch (uniphier_get_soc_type()) { | ||||
| #if defined(CONFIG_ARCH_UNIPHIER_SLD3) | ||||
| 	case SOC_UNIPHIER_SLD3: | ||||
|  | @ -133,6 +139,7 @@ int board_init(void) | |||
| 		sg_set_pinsel(153, 14, 8, 4);	/* XIRQ4    -> XIRQ4 */ | ||||
| 		sg_set_iectrl(153); | ||||
| 		led_puts("U1"); | ||||
| 		uniphier_ld20_pll_init(bd); | ||||
| 		uniphier_ld20_clk_init(); | ||||
| 		cci500_init(2); | ||||
| 		break; | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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 */ | ||||
|  |  | |||
|  | @ -24,6 +24,9 @@ struct uniphier_board_data { | |||
| 	struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH]; | ||||
| 	unsigned int flags; | ||||
| 
 | ||||
| #define UNIPHIER_BD_DPLL_SSC_GET_RATE(f)	(((f) >> 8) & 0x3) | ||||
| #define UNIPHIER_BD_DPLL_SSC_RATE(r)		(((r) & 0x3) << 8) | ||||
| 
 | ||||
| #define UNIPHIER_BD_DDR3PLUS			BIT(2) | ||||
| 
 | ||||
| #define UNIPHIER_BD_BOARD_GET_TYPE(f)		((f) & 0x3) | ||||
|  | @ -84,6 +87,7 @@ int uniphier_sld3_dpll_init(const struct uniphier_board_data *bd); | |||
| int uniphier_ld4_dpll_init(const struct uniphier_board_data *bd); | ||||
| int uniphier_pro4_dpll_init(const struct uniphier_board_data *bd); | ||||
| int uniphier_sld8_dpll_init(const struct uniphier_board_data *bd); | ||||
| int uniphier_ld20_dpll_init(const struct uniphier_board_data *bd); | ||||
| 
 | ||||
| int uniphier_ld4_early_clk_init(const struct uniphier_board_data *bd); | ||||
| int uniphier_pro5_early_clk_init(const struct uniphier_board_data *bd); | ||||
|  | @ -101,6 +105,7 @@ int uniphier_ld11_umc_init(const struct uniphier_board_data *bd); | |||
| void uniphier_sld3_pll_init(void); | ||||
| void uniphier_ld4_pll_init(void); | ||||
| void uniphier_pro4_pll_init(void); | ||||
| int uniphier_ld20_pll_init(const struct uniphier_board_data *bd); | ||||
| 
 | ||||
| void uniphier_ld4_clk_init(void); | ||||
| void uniphier_pro4_clk_init(void); | ||||
|  |  | |||
|  | @ -32,12 +32,14 @@ int uniphier_ld20_init(const struct uniphier_board_data *bd) | |||
| 
 | ||||
| 	led_puts("L2"); | ||||
| 
 | ||||
| 	led_puts("L3"); | ||||
| 
 | ||||
| #ifdef CONFIG_SPL_SERIAL_SUPPORT | ||||
| 	preloader_console_init(); | ||||
| #endif | ||||
| 
 | ||||
| 	led_puts("L3"); | ||||
| 
 | ||||
| 	uniphier_ld20_dpll_init(bd); | ||||
| 
 | ||||
| 	led_puts("L4"); | ||||
| 
 | ||||
| 	{ | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| /*
 | ||||
|  * UniPhier SC (System Control) block registers for ARMv8 SoCs | ||||
|  * | ||||
|  * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> | ||||
|  * Copyright (C) 2016 Socionext Inc. | ||||
|  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com> | ||||
|  * | ||||
|  * SPDX-License-Identifier:	GPL-2.0+ | ||||
|  */ | ||||
|  | @ -11,6 +12,25 @@ | |||
| 
 | ||||
| #define SC_BASE_ADDR		0x61840000 | ||||
| 
 | ||||
| /* PLL type: SSC */ | ||||
| #define SC_CPLLCTRL	(SC_BASE_ADDR | 0x1400)	/* LD20: CPU/ARM */ | ||||
| #define SC_SPLLCTRL	(SC_BASE_ADDR | 0x1410)	/* LD20: misc */ | ||||
| #define SC_SPLL2CTRL	(SC_BASE_ADDR | 0x1420)	/* LD20: IPP */ | ||||
| #define SC_MPLLCTRL	(SC_BASE_ADDR | 0x1430)	/* LD20: Video codec */ | ||||
| #define SC_VPPLLCTRL	(SC_BASE_ADDR | 0x1440)	/* LD20: VPE etc. */ | ||||
| #define SC_GPPLLCTRL	(SC_BASE_ADDR | 0x1450)	/* LD20: GPU/Mali */ | ||||
| #define SC_DPLL0CTRL	(SC_BASE_ADDR | 0x1460)	/* LD20: DDR memory 0 */ | ||||
| #define SC_DPLL1CTRL	(SC_BASE_ADDR | 0x1470)	/* LD20: DDR memory 1 */ | ||||
| #define SC_DPLL2CTRL	(SC_BASE_ADDR | 0x1480)	/* LD20: DDR memory 2 */ | ||||
| 
 | ||||
| /* PLL type: VPLL27 */ | ||||
| #define SC_VPLL27FCTRL	(SC_BASE_ADDR | 0x1500) | ||||
| #define SC_VPLL27ACTRL	(SC_BASE_ADDR | 0x1520) | ||||
| 
 | ||||
| /* PLL type: DSPLL */ | ||||
| #define SC_VPLL8KCTRL	(SC_BASE_ADDR | 0x1540) | ||||
| #define SC_A2PLLCTRL	(SC_BASE_ADDR | 0x15C0) | ||||
| 
 | ||||
| #define SC_RSTCTRL		(SC_BASE_ADDR | 0x2000) | ||||
| #define SC_RSTCTRL3		(SC_BASE_ADDR | 0x2008) | ||||
| #define SC_RSTCTRL4		(SC_BASE_ADDR | 0x200c) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue