Add Clock Manager driver support for Stratix SoC Signed-off-by: Chin Liang See <chin.liang.see@intel.com> Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>lime2-spi
parent
641f7470b6
commit
508791a035
@ -0,0 +1,380 @@ |
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2016-2018 Intel Corporation <www.intel.com> |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/clock_manager.h> |
||||
#include <asm/arch/handoff_s10.h> |
||||
#include <asm/arch/system_manager.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static const struct socfpga_clock_manager *clock_manager_base = |
||||
(struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS; |
||||
static const struct socfpga_system_manager *sysmgr_regs = |
||||
(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; |
||||
|
||||
/*
|
||||
* function to write the bypass register which requires a poll of the |
||||
* busy bit |
||||
*/ |
||||
static void cm_write_bypass_mainpll(u32 val) |
||||
{ |
||||
writel(val, &clock_manager_base->main_pll.bypass); |
||||
cm_wait_for_fsm(); |
||||
} |
||||
|
||||
static void cm_write_bypass_perpll(u32 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(u32 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) |
||||
{ |
||||
u32 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(); |
||||
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(); |
||||
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(); |
||||
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) |
||||
{ |
||||
u32 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(); |
||||
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) |
||||
{ |
||||
u32 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(); |
||||
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) |
||||
{ |
||||
u32 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; |
||||
} |
||||
|
||||
unsigned int cm_get_qspi_controller_clk_hz(void) |
||||
{ |
||||
return readl(&sysmgr_regs->boot_scratch_cold0); |
||||
} |
||||
|
||||
unsigned int cm_get_spi_controller_clk_hz(void) |
||||
{ |
||||
u32 clock = cm_get_l3_main_clk_hz(); |
||||
|
||||
clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >> |
||||
CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK)); |
||||
return clock; |
||||
} |
||||
|
||||
unsigned int cm_get_l4_sys_free_clk_hz(void) |
||||
{ |
||||
return cm_get_l3_main_clk_hz() / 4; |
||||
} |
||||
|
||||
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() / 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); |
||||
} |
@ -0,0 +1,210 @@ |
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* |
||||
* Copyright (C) 2016-2018 Intel Corporation <www.intel.com> |
||||
* |
||||
*/ |
||||
|
||||
#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(void); |
||||
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 */ |
||||
u32 main_pll_mpuclk; |
||||
u32 main_pll_nocclk; |
||||
u32 main_pll_cntr2clk; |
||||
u32 main_pll_cntr3clk; |
||||
u32 main_pll_cntr4clk; |
||||
u32 main_pll_cntr5clk; |
||||
u32 main_pll_cntr6clk; |
||||
u32 main_pll_cntr7clk; |
||||
u32 main_pll_cntr8clk; |
||||
u32 main_pll_cntr9clk; |
||||
u32 main_pll_nocdiv; |
||||
u32 main_pll_pllglob; |
||||
u32 main_pll_fdbck; |
||||
u32 main_pll_pllc0; |
||||
u32 main_pll_pllc1; |
||||
u32 spare; |
||||
|
||||
/* peripheral group */ |
||||
u32 per_pll_cntr2clk; |
||||
u32 per_pll_cntr3clk; |
||||
u32 per_pll_cntr4clk; |
||||
u32 per_pll_cntr5clk; |
||||
u32 per_pll_cntr6clk; |
||||
u32 per_pll_cntr7clk; |
||||
u32 per_pll_cntr8clk; |
||||
u32 per_pll_cntr9clk; |
||||
u32 per_pll_emacctl; |
||||
u32 per_pll_gpiodiv; |
||||
u32 per_pll_pllglob; |
||||
u32 per_pll_fdbck; |
||||
u32 per_pll_pllc0; |
||||
u32 per_pll_pllc1; |
||||
|
||||
/* incoming clock */ |
||||
u32 hps_osc_clk_hz; |
||||
u32 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 BIT(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 BIT(0) |
||||
#define CLKMGR_STAT_MAINPLL_LOCKED BIT(8) |
||||
#define CLKMGR_STAT_PERPLL_LOCKED BIT(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_ */ |
@ -0,0 +1,34 @@ |
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
* |
||||
* Copyright (C) 2016-2018 Intel Corporation <www.intel.com> |
||||
* |
||||
*/ |
||||
|
||||
#ifndef _HANDOFF_S10_H_ |
||||
#define _HANDOFF_S10_H_ |
||||
|
||||
/*
|
||||
* Offset for HW handoff from Quartus tools |
||||
*/ |
||||
#define S10_HANDOFF_BASE 0xFFE3F000 |
||||
#define S10_HANDOFF_MUX (S10_HANDOFF_BASE + 0x10) |
||||
#define S10_HANDOFF_IOCTL (S10_HANDOFF_BASE + 0x1A0) |
||||
#define S10_HANDOFF_FPGA (S10_HANDOFF_BASE + 0x330) |
||||
#define S10_HANODFF_DELAY (S10_HANDOFF_BASE + 0x3F0) |
||||
#define S10_HANDOFF_CLOCK (S10_HANDOFF_BASE + 0x580) |
||||
#define S10_HANDOFF_MISC (S10_HANDOFF_BASE + 0x610) |
||||
#define S10_HANDOFF_MAGIC_MUX 0x504D5558 |
||||
#define S10_HANDOFF_MAGIC_IOCTL 0x494F4354 |
||||
#define S10_HANDOFF_MAGIC_FPGA 0x46504741 |
||||
#define S10_HANDOFF_MAGIC_DELAY 0x444C4159 |
||||
#define S10_HANDOFF_MAGIC_CLOCK 0x434C4B53 |
||||
#define S10_HANDOFF_MAGIC_MISC 0x4D495343 |
||||
#define S10_HANDOFF_OFFSET_LENGTH 0x4 |
||||
#define S10_HANDOFF_OFFSET_DATA 0x10 |
||||
|
||||
#define S10_HANDOFF_CLOCK_OSC (S10_HANDOFF_BASE + 0x608) |
||||
#define S10_HANDOFF_CLOCK_FPGA (S10_HANDOFF_BASE + 0x60C) |
||||
|
||||
#define S10_HANDOFF_SIZE 4096 |
||||
|
||||
#endif /* _HANDOFF_S10_H_ */ |
@ -0,0 +1,59 @@ |
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2016-2018 Intel Corporation <www.intel.com> |
||||
* |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/arch/clock_manager.h> |
||||
#include <asm/io.h> |
||||
#include <asm/arch/handoff_s10.h> |
||||
#include <asm/arch/system_manager.h> |
||||
|
||||
static const struct socfpga_system_manager *sysmgr_regs = |
||||
(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; |
||||
|
||||
const struct cm_config * const cm_get_default_config(void) |
||||
{ |
||||
struct cm_config *cm_handoff_cfg = (struct cm_config *) |
||||
(S10_HANDOFF_CLOCK + S10_HANDOFF_OFFSET_DATA); |
||||
u32 *conversion = (u32 *)cm_handoff_cfg; |
||||
u32 i; |
||||
u32 handoff_clk = readl(S10_HANDOFF_CLOCK); |
||||
|
||||
if (swab32(handoff_clk) == S10_HANDOFF_MAGIC_CLOCK) { |
||||
writel(swab32(handoff_clk), S10_HANDOFF_CLOCK); |
||||
for (i = 0; i < (sizeof(*cm_handoff_cfg) / sizeof(u32)); i++) |
||||
conversion[i] = swab32(conversion[i]); |
||||
return cm_handoff_cfg; |
||||
} else if (handoff_clk == S10_HANDOFF_MAGIC_CLOCK) { |
||||
return cm_handoff_cfg; |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
const unsigned int cm_get_osc_clk_hz(void) |
||||
{ |
||||
#ifdef CONFIG_SPL_BUILD |
||||
u32 clock = readl(S10_HANDOFF_CLOCK_OSC); |
||||
|
||||
writel(clock, &sysmgr_regs->boot_scratch_cold1); |
||||
#endif |
||||
return readl(&sysmgr_regs->boot_scratch_cold1); |
||||
} |
||||
|
||||
const unsigned int cm_get_intosc_clk_hz(void) |
||||
{ |
||||
return CLKMGR_INTOSC_HZ; |
||||
} |
||||
|
||||
const unsigned int cm_get_fpga_clk_hz(void) |
||||
{ |
||||
#ifdef CONFIG_SPL_BUILD |
||||
u32 clock = readl(S10_HANDOFF_CLOCK_FPGA); |
||||
|
||||
writel(clock, &sysmgr_regs->boot_scratch_cold2); |
||||
#endif |
||||
return readl(&sysmgr_regs->boot_scratch_cold2); |
||||
} |
Loading…
Reference in new issue