All of lore.kernel.org
 help / color / mirror / Atom feed
From: chin.liang.see at intel.com <chin.liang.see@intel.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 02/14] arm: socfpga: stratix10: Add Clock Manager driver for Stratix10 SoC
Date: Thu,  5 Oct 2017 21:07:19 +0800	[thread overview]
Message-ID: <1507208851-32672-3-git-send-email-chin.liang.see@intel.com> (raw)
In-Reply-To: <1507208851-32672-1-git-send-email-chin.liang.see@intel.com>

From: Chin Liang See <chin.liang.see@intel.com>

Add Clock Manager driver support for Stratix SoC

Signed-off-by: Chin Liang See <chin.liang.see@intel.com>
--
Changes in v2
- Declared defines for constant value used
- Fixed spacing and comments
---
 arch/arm/mach-socfpga/Makefile                     |   4 +
 arch/arm/mach-socfpga/clock_manager.c              |   4 +-
 arch/arm/mach-socfpga/clock_manager_s10.c          | 355 +++++++++++++++++++++
 arch/arm/mach-socfpga/include/mach/clock_manager.h |   2 +
 .../mach-socfpga/include/mach/clock_manager_s10.h  | 210 ++++++++++++
 arch/arm/mach-socfpga/include/mach/handoff_s10.h   |  29 ++
 arch/arm/mach-socfpga/wrap_pll_config_s10.c        |  44 +++
 7 files changed, 646 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-socfpga/clock_manager_s10.c
 create mode 100644 arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
 create mode 100644 arch/arm/mach-socfpga/include/mach/handoff_s10.h
 create mode 100644 arch/arm/mach-socfpga/wrap_pll_config_s10.c

diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 286bfef..e5f9dd7 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -30,6 +30,10 @@ obj-y	+= pinmux_arria10.o
 obj-y	+= reset_manager_arria10.o
 endif
 
+ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
+obj-y	+= clock_manager_s10.o
+obj-y	+= wrap_pll_config_s10.o
+endif
 ifdef CONFIG_SPL_BUILD
 obj-y	+= spl.o
 ifdef CONFIG_TARGET_SOCFPGA_GEN5
diff --git a/arch/arm/mach-socfpga/clock_manager.c b/arch/arm/mach-socfpga/clock_manager.c
index cb6ae03..f9450a4 100644
--- a/arch/arm/mach-socfpga/clock_manager.c
+++ b/arch/arm/mach-socfpga/clock_manager.c
@@ -21,7 +21,7 @@ void cm_wait_for_lock(u32 mask)
 	do {
 #if defined(CONFIG_TARGET_SOCFPGA_GEN5)
 		inter_val = readl(&clock_manager_base->inter) & mask;
-#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
+#else
 		inter_val = readl(&clock_manager_base->stat) & mask;
 #endif
 		/* Wait for stable lock */
@@ -52,7 +52,7 @@ int set_cpu_clk_info(void)
 
 #if defined(CONFIG_TARGET_SOCFPGA_GEN5)
 	gd->bd->bi_ddr_freq = cm_get_sdram_clk_hz() / 1000000;
-#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
+#else
 	gd->bd->bi_ddr_freq = 0;
 #endif
 
diff --git a/arch/arm/mach-socfpga/clock_manager_s10.c b/arch/arm/mach-socfpga/clock_manager_s10.c
new file mode 100644
index 0000000..cfb6708
--- /dev/null
+++ b/arch/arm/mach-socfpga/clock_manager_s10.c
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2016-2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock_manager.h>
+#include <asm/arch/handoff_s10.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct socfpga_clock_manager *clock_manager_base =
+	(struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
+
+/*
+ * function to write the bypass register which requires a poll of the
+ * busy bit
+ */
+static void cm_write_bypass_mainpll(uint32_t val)
+{
+	writel(val, &clock_manager_base->main_pll.bypass);
+	cm_wait_for_fsm();
+}
+
+static void cm_write_bypass_perpll(uint32_t val)
+{
+	writel(val, &clock_manager_base->per_pll.bypass);
+	cm_wait_for_fsm();
+}
+
+/* function to write the ctrl register which requires a poll of the busy bit */
+static void cm_write_ctrl(uint32_t val)
+{
+	writel(val, &clock_manager_base->ctrl);
+	cm_wait_for_fsm();
+}
+
+/*
+ * Setup clocks while making no assumptions about previous state of the clocks.
+ */
+void cm_basic_init(const struct cm_config * const cfg)
+{
+	uint32_t mdiv, refclkdiv, mscnt, hscnt, vcocalib;
+
+	if (cfg == 0)
+		return;
+
+	/* Put all plls in bypass */
+	cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL);
+	cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL);
+
+	/* setup main PLL dividers where calculate the vcocalib value */
+	mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
+		CLKMGR_FDBCK_MDIV_MASK;
+	refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
+		     CLKMGR_PLLGLOB_REFCLKDIV_MASK;
+	mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
+	hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
+		CLKMGR_HSCNT_CONST;
+	vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
+		   ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
+		   CLKMGR_VCOCALIB_MSCNT_OFFSET);
+
+	writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
+		~CLKMGR_PLLGLOB_RST_MASK),
+		&clock_manager_base->main_pll.pllglob);
+	writel(cfg->main_pll_fdbck, &clock_manager_base->main_pll.fdbck);
+	writel(vcocalib, &clock_manager_base->main_pll.vcocalib);
+	writel(cfg->main_pll_pllc0, &clock_manager_base->main_pll.pllc0);
+	writel(cfg->main_pll_pllc1, &clock_manager_base->main_pll.pllc1);
+	writel(cfg->main_pll_nocdiv, &clock_manager_base->main_pll.nocdiv);
+
+	/* setup peripheral PLL dividers */
+	/* calculate the vcocalib value */
+	mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
+		CLKMGR_FDBCK_MDIV_MASK;
+	refclkdiv = (cfg->per_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
+		     CLKMGR_PLLGLOB_REFCLKDIV_MASK;
+	mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
+	hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
+		CLKMGR_HSCNT_CONST;
+	vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
+		   ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
+		   CLKMGR_VCOCALIB_MSCNT_OFFSET);
+
+	writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
+		~CLKMGR_PLLGLOB_RST_MASK),
+		&clock_manager_base->per_pll.pllglob);
+	writel(cfg->per_pll_fdbck, &clock_manager_base->per_pll.fdbck);
+	writel(vcocalib, &clock_manager_base->per_pll.vcocalib);
+	writel(cfg->per_pll_pllc0, &clock_manager_base->per_pll.pllc0);
+	writel(cfg->per_pll_pllc1, &clock_manager_base->per_pll.pllc1);
+	writel(cfg->per_pll_emacctl, &clock_manager_base->per_pll.emacctl);
+	writel(cfg->per_pll_gpiodiv, &clock_manager_base->per_pll.gpiodiv);
+
+	/* Take both PLL out of reset and power up */
+	setbits_le32(&clock_manager_base->main_pll.pllglob,
+		     CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
+	setbits_le32(&clock_manager_base->per_pll.pllglob,
+		     CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
+
+#define LOCKED_MASK \
+	(CLKMGR_STAT_MAINPLL_LOCKED | \
+	CLKMGR_STAT_PERPLL_LOCKED)
+
+	cm_wait_for_lock(LOCKED_MASK);
+
+	/*
+	 * Dividers for C2 to C9 only init after PLLs are lock. As dividers
+	 * only take effect upon value change, we shall set a maximum value as
+	 * default value.
+	 */
+	writel(0xff, &clock_manager_base->main_pll.mpuclk);
+	writel(0xff, &clock_manager_base->main_pll.nocclk);
+	writel(0xff, &clock_manager_base->main_pll.cntr2clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr3clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr4clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr5clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr6clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr7clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr8clk);
+	writel(0xff, &clock_manager_base->main_pll.cntr9clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr2clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr3clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr4clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr5clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr6clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr7clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr8clk);
+	writel(0xff, &clock_manager_base->per_pll.cntr9clk);
+
+	writel(cfg->main_pll_mpuclk, &clock_manager_base->main_pll.mpuclk);
+	writel(cfg->main_pll_nocclk, &clock_manager_base->main_pll.nocclk);
+	writel(cfg->main_pll_cntr2clk, &clock_manager_base->main_pll.cntr2clk);
+	writel(cfg->main_pll_cntr3clk, &clock_manager_base->main_pll.cntr3clk);
+	writel(cfg->main_pll_cntr4clk, &clock_manager_base->main_pll.cntr4clk);
+	writel(cfg->main_pll_cntr5clk, &clock_manager_base->main_pll.cntr5clk);
+	writel(cfg->main_pll_cntr6clk, &clock_manager_base->main_pll.cntr6clk);
+	writel(cfg->main_pll_cntr7clk, &clock_manager_base->main_pll.cntr7clk);
+	writel(cfg->main_pll_cntr8clk, &clock_manager_base->main_pll.cntr8clk);
+	writel(cfg->main_pll_cntr9clk, &clock_manager_base->main_pll.cntr9clk);
+	writel(cfg->per_pll_cntr2clk, &clock_manager_base->per_pll.cntr2clk);
+	writel(cfg->per_pll_cntr3clk, &clock_manager_base->per_pll.cntr3clk);
+	writel(cfg->per_pll_cntr4clk, &clock_manager_base->per_pll.cntr4clk);
+	writel(cfg->per_pll_cntr5clk, &clock_manager_base->per_pll.cntr5clk);
+	writel(cfg->per_pll_cntr6clk, &clock_manager_base->per_pll.cntr6clk);
+	writel(cfg->per_pll_cntr7clk, &clock_manager_base->per_pll.cntr7clk);
+	writel(cfg->per_pll_cntr8clk, &clock_manager_base->per_pll.cntr8clk);
+	writel(cfg->per_pll_cntr9clk, &clock_manager_base->per_pll.cntr9clk);
+
+	/* Take all PLLs out of bypass */
+	cm_write_bypass_mainpll(0);
+	cm_write_bypass_perpll(0);
+
+	/* clear safe mode / out of boot mode */
+	cm_write_ctrl(readl(&clock_manager_base->ctrl)
+			& ~(CLKMGR_CTRL_SAFEMODE));
+
+	/* Now ungate non-hw-managed clocks */
+	writel(~0, &clock_manager_base->main_pll.en);
+	writel(~0, &clock_manager_base->per_pll.en);
+
+	/* Clear the loss of lock bits (write 1 to clear) */
+	writel(CLKMGR_INTER_PERPLLLOST_MASK | CLKMGR_INTER_MAINPLLLOST_MASK,
+	       &clock_manager_base->intrclr);
+}
+
+static unsigned long cm_get_main_vco_clk_hz(void)
+{
+	 unsigned long fref, refdiv, mdiv, reg, vco;
+
+	reg = readl(&clock_manager_base->main_pll.pllglob);
+
+	fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
+		CLKMGR_PLLGLOB_VCO_PSRC_MASK;
+	switch (fref) {
+	case CLKMGR_VCO_PSRC_EOSC1:
+		fref = cm_get_osc_clk_hz(0);
+		break;
+	case CLKMGR_VCO_PSRC_INTOSC:
+		fref = cm_get_intosc_clk_hz();
+		break;
+	case CLKMGR_VCO_PSRC_F2S:
+		fref = cm_get_fpga_clk_hz();
+		break;
+	}
+
+	refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
+		  CLKMGR_PLLGLOB_REFCLKDIV_MASK;
+
+	reg = readl(&clock_manager_base->main_pll.fdbck);
+	mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
+
+	vco = fref / refdiv;
+	vco = vco * (CLKMGR_MDIV_CONST + mdiv);
+	return vco;
+}
+
+static unsigned long cm_get_per_vco_clk_hz(void)
+{
+	unsigned long fref, refdiv, mdiv, reg, vco;
+
+	reg = readl(&clock_manager_base->per_pll.pllglob);
+
+	fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
+		CLKMGR_PLLGLOB_VCO_PSRC_MASK;
+	switch (fref) {
+	case CLKMGR_VCO_PSRC_EOSC1:
+		fref = cm_get_osc_clk_hz(0);
+		break;
+	case CLKMGR_VCO_PSRC_INTOSC:
+		fref = cm_get_intosc_clk_hz();
+		break;
+	case CLKMGR_VCO_PSRC_F2S:
+		fref = cm_get_fpga_clk_hz();
+		break;
+	}
+
+	refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
+		  CLKMGR_PLLGLOB_REFCLKDIV_MASK;
+
+	reg = readl(&clock_manager_base->per_pll.fdbck);
+	mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
+
+	vco = fref / refdiv;
+	vco = vco * (CLKMGR_MDIV_CONST + mdiv);
+	return vco;
+}
+
+unsigned long cm_get_mpu_clk_hz(void)
+{
+	unsigned long clock = readl(&clock_manager_base->main_pll.mpuclk);
+	clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
+
+	switch (clock) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = cm_get_main_vco_clk_hz();
+		clock /= (readl(&clock_manager_base->main_pll.pllc0) &
+			  CLKMGR_PLLC0_DIV_MASK);
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		clock = cm_get_per_vco_clk_hz();
+		clock /= (readl(&clock_manager_base->per_pll.pllc0) &
+			  CLKMGR_CLKCNT_MSK);
+		break;
+
+	case CLKMGR_CLKSRC_OSC1:
+		clock = cm_get_osc_clk_hz(0);
+		break;
+
+	case CLKMGR_CLKSRC_INTOSC:
+		clock = cm_get_intosc_clk_hz();
+		break;
+
+	case CLKMGR_CLKSRC_FPGA:
+		clock = cm_get_fpga_clk_hz();
+		break;
+	}
+
+	clock /= 1 + (readl(&clock_manager_base->main_pll.mpuclk) &
+		CLKMGR_CLKCNT_MSK);
+	return clock;
+}
+
+unsigned int cm_get_l3_main_clk_hz(void)
+{
+	uint32_t clock = readl(&clock_manager_base->main_pll.nocclk);
+	clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
+
+	switch (clock) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = cm_get_main_vco_clk_hz();
+		clock /= (readl(&clock_manager_base->main_pll.pllc1) &
+			  CLKMGR_PLLC0_DIV_MASK);
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		clock = cm_get_per_vco_clk_hz();
+		clock /= (readl(&clock_manager_base->per_pll.pllc1) &
+			  CLKMGR_CLKCNT_MSK);
+		break;
+
+	case CLKMGR_CLKSRC_OSC1:
+		clock = cm_get_osc_clk_hz(0);
+		break;
+
+	case CLKMGR_CLKSRC_INTOSC:
+		clock = cm_get_intosc_clk_hz();
+		break;
+
+	case CLKMGR_CLKSRC_FPGA:
+		clock = cm_get_fpga_clk_hz();
+		break;
+	}
+
+	clock /= 1 + (readl(&clock_manager_base->main_pll.nocclk) &
+		CLKMGR_CLKCNT_MSK);
+	return clock;
+}
+
+unsigned int cm_get_mmc_controller_clk_hz(void)
+{
+	uint32_t clock = readl(&clock_manager_base->per_pll.cntr6clk);
+	clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
+
+	switch (clock) {
+	case CLKMGR_CLKSRC_MAIN:
+		clock = cm_get_l3_main_clk_hz();
+		clock /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) &
+			CLKMGR_CLKCNT_MSK);
+		break;
+
+	case CLKMGR_CLKSRC_PER:
+		clock = cm_get_l3_main_clk_hz();
+		clock /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) &
+			CLKMGR_CLKCNT_MSK);
+		break;
+
+	case CLKMGR_CLKSRC_OSC1:
+		clock = cm_get_osc_clk_hz(0);
+		break;
+
+	case CLKMGR_CLKSRC_INTOSC:
+		clock = cm_get_intosc_clk_hz();
+		break;
+
+	case CLKMGR_CLKSRC_FPGA:
+		clock = cm_get_fpga_clk_hz();
+		break;
+	}
+	return clock / 4;
+}
+
+unsigned int cm_get_l4_sp_clk_hz(void)
+{
+	uint32_t clock = cm_get_l3_main_clk_hz();
+
+	clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >>
+		  CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
+	return clock;
+}
+
+void cm_print_clock_quick_summary(void)
+{
+	printf("MPU         %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
+	printf("L3 main     %d kHz\n", cm_get_l3_main_clk_hz() / 1000);
+	printf("Main VCO    %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000));
+	printf("Per VCO     %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000));
+	printf("EOSC1       %d kHz\n", cm_get_osc_clk_hz(0) / 1000);
+	printf("HPS MMC     %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
+	printf("UART        %d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
+}
diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager.h b/arch/arm/mach-socfpga/include/mach/clock_manager.h
index 4c6b1f8..ddf814f 100644
--- a/arch/arm/mach-socfpga/include/mach/clock_manager.h
+++ b/arch/arm/mach-socfpga/include/mach/clock_manager.h
@@ -17,6 +17,8 @@ void cm_print_clock_quick_summary(void);
 #include <asm/arch/clock_manager_gen5.h>
 #elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
 #include <asm/arch/clock_manager_arria10.h>
+#elif defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
+#include <asm/arch/clock_manager_s10.h>
 #endif
 
 #endif /* _CLOCK_MANAGER_H_ */
diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
new file mode 100644
index 0000000..831cf2c
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016-2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef	_CLOCK_MANAGER_S10_
+#define	_CLOCK_MANAGER_S10_
+
+/* Clock speed accessors */
+unsigned long cm_get_mpu_clk_hz(void);
+unsigned long cm_get_sdram_clk_hz(void);
+unsigned int cm_get_l4_sp_clk_hz(void);
+unsigned int cm_get_mmc_controller_clk_hz(void);
+unsigned int cm_get_qspi_controller_clk_hz(void);
+unsigned int cm_get_spi_controller_clk_hz(void);
+const unsigned int cm_get_osc_clk_hz(const int osc);
+const unsigned int cm_get_f2s_per_ref_clk_hz(void);
+const unsigned int cm_get_f2s_sdr_ref_clk_hz(void);
+const unsigned int cm_get_intosc_clk_hz(void);
+const unsigned int cm_get_fpga_clk_hz(void);
+
+#define CLKMGR_EOSC1_HZ		25000000
+#define CLKMGR_INTOSC_HZ	460000000
+#define CLKMGR_FPGA_CLK_HZ	50000000
+
+/* Clock configuration accessors */
+const struct cm_config * const cm_get_default_config(void);
+
+struct cm_config {
+	/* main group */
+	uint32_t main_pll_mpuclk;
+	uint32_t main_pll_nocclk;
+	uint32_t main_pll_cntr2clk;
+	uint32_t main_pll_cntr3clk;
+	uint32_t main_pll_cntr4clk;
+	uint32_t main_pll_cntr5clk;
+	uint32_t main_pll_cntr6clk;
+	uint32_t main_pll_cntr7clk;
+	uint32_t main_pll_cntr8clk;
+	uint32_t main_pll_cntr9clk;
+	uint32_t main_pll_nocdiv;
+	uint32_t main_pll_pllglob;
+	uint32_t main_pll_fdbck;
+	uint32_t main_pll_pllc0;
+	uint32_t main_pll_pllc1;
+	uint32_t spare;
+
+	/* peripheral group */
+	uint32_t per_pll_cntr2clk;
+	uint32_t per_pll_cntr3clk;
+	uint32_t per_pll_cntr4clk;
+	uint32_t per_pll_cntr5clk;
+	uint32_t per_pll_cntr6clk;
+	uint32_t per_pll_cntr7clk;
+	uint32_t per_pll_cntr8clk;
+	uint32_t per_pll_cntr9clk;
+	uint32_t per_pll_emacctl;
+	uint32_t per_pll_gpiodiv;
+	uint32_t per_pll_pllglob;
+	uint32_t per_pll_fdbck;
+	uint32_t per_pll_pllc0;
+	uint32_t per_pll_pllc1;
+
+	/* incoming clock */
+	uint32_t hps_osc_clk_hz;
+	uint32_t fpga_clk_hz;
+};
+
+void cm_basic_init(const struct cm_config * const cfg);
+
+struct socfpga_clock_manager_main_pll {
+	u32	en;
+	u32	ens;
+	u32	enr;
+	u32	bypass;
+	u32	bypasss;
+	u32	bypassr;
+	u32	mpuclk;
+	u32	nocclk;
+	u32	cntr2clk;
+	u32	cntr3clk;
+	u32	cntr4clk;
+	u32	cntr5clk;
+	u32	cntr6clk;
+	u32	cntr7clk;
+	u32	cntr8clk;
+	u32	cntr9clk;
+	u32	nocdiv;
+	u32	pllglob;
+	u32	fdbck;
+	u32	mem;
+	u32	memstat;
+	u32	pllc0;
+	u32	pllc1;
+	u32	vcocalib;
+	u32	_pad_0x90_0xA0[5];
+};
+
+struct socfpga_clock_manager_per_pll {
+	u32	en;
+	u32	ens;
+	u32	enr;
+	u32	bypass;
+	u32	bypasss;
+	u32	bypassr;
+	u32	cntr2clk;
+	u32	cntr3clk;
+	u32	cntr4clk;
+	u32	cntr5clk;
+	u32	cntr6clk;
+	u32	cntr7clk;
+	u32	cntr8clk;
+	u32	cntr9clk;
+	u32	emacctl;
+	u32	gpiodiv;
+	u32	pllglob;
+	u32	fdbck;
+	u32	mem;
+	u32	memstat;
+	u32	pllc0;
+	u32	pllc1;
+	u32	vcocalib;
+	u32	_pad_0x100_0x124[10];
+};
+
+struct socfpga_clock_manager {
+	u32	ctrl;
+	u32	stat;
+	u32	testioctrl;
+	u32	intrgen;
+	u32	intrmsk;
+	u32	intrclr;
+	u32	intrsts;
+	u32	intrstk;
+	u32	intrraw;
+	u32	_pad_0x24_0x2c[3];
+	struct socfpga_clock_manager_main_pll main_pll;
+	struct socfpga_clock_manager_per_pll per_pll;
+};
+
+#define CLKMGR_CTRL_SAFEMODE				(1 << 0)
+#define CLKMGR_BYPASS_MAINPLL_ALL			0x00000007
+#define CLKMGR_BYPASS_PERPLL_ALL			0x0000007f
+
+#define CLKMGR_INTER_MAINPLLLOCKED_MASK			0x00000001
+#define CLKMGR_INTER_PERPLLLOCKED_MASK			0x00000002
+#define CLKMGR_INTER_MAINPLLLOST_MASK			0x00000004
+#define CLKMGR_INTER_PERPLLLOST_MASK			0x00000008
+#define CLKMGR_STAT_BUSY				(1 << 0)
+#define CLKMGR_STAT_MAINPLL_LOCKED			(1 << 8)
+#define CLKMGR_STAT_PERPLL_LOCKED			(1 << 9)
+
+#define CLKMGR_PLLGLOB_PD_MASK				0x00000001
+#define CLKMGR_PLLGLOB_RST_MASK				0x00000002
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK			0X3
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET			16
+#define CLKMGR_VCO_PSRC_EOSC1				0
+#define CLKMGR_VCO_PSRC_INTOSC				1
+#define CLKMGR_VCO_PSRC_F2S				2
+#define CLKMGR_PLLGLOB_REFCLKDIV_MASK			0X3f
+#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET			8
+
+#define CLKMGR_CLKSRC_MASK				0x7
+#define CLKMGR_CLKSRC_OFFSET				16
+#define CLKMGR_CLKSRC_MAIN				0
+#define CLKMGR_CLKSRC_PER				1
+#define CLKMGR_CLKSRC_OSC1				2
+#define CLKMGR_CLKSRC_INTOSC				3
+#define CLKMGR_CLKSRC_FPGA				4
+#define CLKMGR_CLKCNT_MSK				0x7ff
+
+#define CLKMGR_FDBCK_MDIV_MASK				0xff
+#define CLKMGR_FDBCK_MDIV_OFFSET			24
+
+#define CLKMGR_PLLC0_DIV_MASK				0xff
+#define CLKMGR_PLLC1_DIV_MASK				0xff
+#define CLKMGR_PLLC0_EN_OFFSET				27
+#define CLKMGR_PLLC1_EN_OFFSET				24
+
+#define CLKMGR_NOCDIV_L4MAIN_OFFSET			0
+#define CLKMGR_NOCDIV_L4MPCLK_OFFSET			8
+#define CLKMGR_NOCDIV_L4SPCLK_OFFSET			16
+#define CLKMGR_NOCDIV_CSATCLK_OFFSET			24
+#define CLKMGR_NOCDIV_CSTRACECLK_OFFSET			26
+#define CLKMGR_NOCDIV_CSPDBGCLK_OFFSET			28
+
+#define CLKMGR_NOCDIV_L4SPCLK_MASK			0X3
+#define CLKMGR_NOCDIV_DIV1				0
+#define CLKMGR_NOCDIV_DIV2				1
+#define CLKMGR_NOCDIV_DIV4				2
+#define CLKMGR_NOCDIV_DIV8				3
+#define CLKMGR_CSPDBGCLK_DIV1				0
+#define CLKMGR_CSPDBGCLK_DIV4				1
+
+#define CLKMGR_MSCNT_CONST				200
+#define CLKMGR_MDIV_CONST				6
+#define CLKMGR_HSCNT_CONST				9
+
+#define CLKMGR_VCOCALIB_MSCNT_MASK			0xff
+#define CLKMGR_VCOCALIB_MSCNT_OFFSET			9
+#define CLKMGR_VCOCALIB_HSCNT_MASK			0xff
+
+#define CLKMGR_EMACCTL_EMAC0SEL_OFFSET			26
+#define CLKMGR_EMACCTL_EMAC1SEL_OFFSET			27
+#define CLKMGR_EMACCTL_EMAC2SEL_OFFSET			28
+
+#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK		0x00000020
+
+#endif /* _CLOCK_MANAGER_S10_ */
diff --git a/arch/arm/mach-socfpga/include/mach/handoff_s10.h b/arch/arm/mach-socfpga/include/mach/handoff_s10.h
new file mode 100644
index 0000000..d4b89ac
--- /dev/null
+++ b/arch/arm/mach-socfpga/include/mach/handoff_s10.h
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (C) 2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _HANDOFF_S10_H_
+#define _HANDOFF_S10_H_
+
+/*
+ * Offset for HW handoff from Quartus tools
+ */
+#define CONFIG_HANDOFF_BASE		0xFFE3F000
+#define CONFIG_HANDOFF_MUX		(CONFIG_HANDOFF_BASE + 0x10)
+#define CONFIG_HANDOFF_IOCTL		(CONFIG_HANDOFF_BASE + 0x1A0)
+#define CONFIG_HANDOFF_FPGA		(CONFIG_HANDOFF_BASE + 0x330)
+#define CONFIG_HANODFF_DELAY		(CONFIG_HANDOFF_BASE + 0x3F0)
+#define CONFIG_HANDOFF_CLOCK		(CONFIG_HANDOFF_BASE + 0x580)
+#define CONFIG_HANDOFF_MISC		(CONFIG_HANDOFF_BASE + 0x610)
+#define CONFIG_HANDOFF_MAGIC_MUX	0x504D5558
+#define CONFIG_HANDOFF_MAGIC_IOCTL	0x494F4354
+#define CONFIG_HANDOFF_MAGIC_FPGA	0x46504741
+#define CONFIG_HANDOFF_MAGIC_DELAY	0x444C4159
+#define CONFIG_HANDOFF_MAGIC_CLOCK	0x434C4B53
+#define CONFIG_HANDOFF_MAGIC_MISC	0x4D495343
+#define CONFIG_HANDOFF_OFFSET_LENGTH	0x4
+#define CONFIG_HANDOFF_OFFSET_DATA	0x10
+
+#endif /* _HANDOFF_S10_H_ */
diff --git a/arch/arm/mach-socfpga/wrap_pll_config_s10.c b/arch/arm/mach-socfpga/wrap_pll_config_s10.c
new file mode 100644
index 0000000..3f19534
--- /dev/null
+++ b/arch/arm/mach-socfpga/wrap_pll_config_s10.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016-2017 Intel Corporation <www.intel.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <asm/arch/clock_manager.h>
+#include <asm/io.h>
+#include <asm/arch/handoff_s10.h>
+
+const struct cm_config * const cm_get_default_config(void)
+{
+	struct cm_config *cm_handoff_cfg = (struct cm_config *)
+		(CONFIG_HANDOFF_CLOCK + CONFIG_HANDOFF_OFFSET_DATA);
+	u32 *conversion = (u32 *)cm_handoff_cfg;
+	u32 i;
+
+	if (swab32(readl(CONFIG_HANDOFF_CLOCK)) == CONFIG_HANDOFF_MAGIC_CLOCK) {
+		writel(swab32(readl(CONFIG_HANDOFF_CLOCK)),
+			CONFIG_HANDOFF_CLOCK);
+		for (i = 0; i < (sizeof(*cm_handoff_cfg) / sizeof(u32)); i++)
+			conversion[i] = swab32(conversion[i]);
+		return cm_handoff_cfg;
+	} else if (readl(CONFIG_HANDOFF_CLOCK) == CONFIG_HANDOFF_MAGIC_CLOCK) {
+		return cm_handoff_cfg;
+	} else
+		return 0;
+}
+
+const unsigned int cm_get_osc_clk_hz(const int osc)
+{
+	return CLKMGR_EOSC1_HZ;
+}
+
+const unsigned int cm_get_intosc_clk_hz(void)
+{
+	return CLKMGR_INTOSC_HZ;
+}
+
+const unsigned int cm_get_fpga_clk_hz(void)
+{
+	return CLKMGR_FPGA_CLK_HZ;
+}
-- 
2.2.2

  parent reply	other threads:[~2017-10-05 13:07 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-05 13:07 [U-Boot] [PATCH v2 00/14] Enable Stratix10 SoC support chin.liang.see at intel.com
2017-10-05 13:07 ` [U-Boot] [PATCH v2 01/14] arm: socfpga: stratix10: Add base address map for Statix10 SoC chin.liang.see at intel.com
2017-10-09 21:03   ` Dinh Nguyen
2017-10-05 13:07 ` chin.liang.see at intel.com [this message]
2017-10-10 20:23   ` [U-Boot] [PATCH v2 02/14] arm: socfpga: stratix10: Add Clock Manager driver for Stratix10 SoC Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 03/14] arm: socfpga: stratix10: Add Reset " chin.liang.see at intel.com
2017-10-10 20:42   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 04/14] arm: socfpga: stratix10: Add pinmux support " chin.liang.see at intel.com
2017-10-10 21:00   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 05/14] arm: socfpga: stratix10: Add misc " chin.liang.see at intel.com
2017-10-10 21:17   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 06/14] arm: socfpga: stratix10: Add mailbox " chin.liang.see at intel.com
2017-10-10 22:32   ` Dinh Nguyen
2017-10-11  9:33   ` Dinh Nguyen
2017-10-11 15:11     ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 07/14] arm: socfpga: stratix10: Add MMU " chin.liang.see at intel.com
2017-10-05 13:07 ` [U-Boot] [PATCH v2 08/14] arm: dts: Add dts " chin.liang.see at intel.com
2017-10-10 22:56   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 09/14] arm: socfpga: Restructure the SPL file chin.liang.see at intel.com
2017-10-11  9:16   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 10/14] arm: socfpga: stratix10: Add SPL driver for Stratix10 SoC chin.liang.see at intel.com
2017-10-11  9:23   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 11/14] arm: socfpga: stratix10: Add timer support " chin.liang.see at intel.com
2017-10-11  9:25   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 12/14] ddr: altera: stratix10: Add DDR " chin.liang.see at intel.com
2017-10-11 20:46   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 13/14] board: altera: stratix10: Add socdk board " chin.liang.see at intel.com
2017-10-11 20:52   ` Dinh Nguyen
2017-10-05 13:07 ` [U-Boot] [PATCH v2 14/14] arm: socfpga: stratix10: Enable Stratix10 SoC build chin.liang.see at intel.com
2017-10-11 21:31   ` Dinh Nguyen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1507208851-32672-3-git-send-email-chin.liang.see@intel.com \
    --to=chin.liang.see@intel.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.