diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 8e8b582..f24bbde 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -73,9 +73,9 @@ deassert_peripheral_reset(); config_hps_hs_before_warm_reset(); - watchdog_init(get_wdt_clk(&reverse_handoff_ptr)); + watchdog_init(get_wdt_clk()); - console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, + console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE, &console); socfpga_delay_timer_init(); @@ -107,7 +107,7 @@ enable_mmu_el3(0); - dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000); + dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000, get_mmc_clk()); info.mmc_dev_type = MMC_IS_SD; info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3; diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h index 99eb7a6..c800b9c 100644 --- a/plat/intel/soc/stratix10/include/s10_clock_manager.h +++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h @@ -50,10 +50,13 @@ #define ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000000ff) #define ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(x) (((x) & 0x00030000) >> 16) -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1 0x0 -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC 0x1 -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S 0x2 +#define ALT_CLKMGR_PSRC(x) (((x) & 0x00030000) >> 16) +#define ALT_CLKMGR_SRC_MAIN 0 +#define ALT_CLKMGR_SRC_PER 1 + +#define ALT_CLKMGR_PLLGLOB_PSRC_EOSC1 0x0 +#define ALT_CLKMGR_PLLGLOB_PSRC_INTOSC 0x1 +#define ALT_CLKMGR_PLLGLOB_PSRC_F2S 0x2 #define ALT_CLKMGR_PERPLL 0xffd100a4 #define ALT_CLKMGR_PERPLL_EN 0x0 @@ -83,14 +86,11 @@ #define ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) #define ALT_CLKMGR_PERPLL_VCOCALIB 0x58 - -typedef struct { - uint32_t clk_freq_of_eosc1; - uint32_t clk_freq_of_f2h_free; - uint32_t clk_freq_of_cb_intosc_ls; -} CLOCK_SOURCE_CONFIG; +#define ALT_CLKMGR_INTOSC_HZ 460000000 void config_clkmgr_handoff(handoff *hoff_ptr); -int get_wdt_clk(handoff *hoff_ptr); +uint32_t get_wdt_clk(void); +uint32_t get_uart_clk(void); +uint32_t get_mmc_clk(void); #endif diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h index 4500c6f..a67d689 100644 --- a/plat/intel/soc/stratix10/include/s10_system_manager.h +++ b/plat/intel/soc/stratix10/include/s10_system_manager.h @@ -62,6 +62,9 @@ #define S10_SYSMGR_CORE(x) (0xffd12000 + (x)) #define SYSMGR_MMC 0x28 #define SYSMGR_MMC_DRVSEL(x) (((x) & 0x7) << 0) +#define SYSMGR_BOOT_SCRATCH_COLD_0 0x200 +#define SYSMGR_BOOT_SCRATCH_COLD_1 0x204 +#define SYSMGR_BOOT_SCRATCH_COLD_2 0x208 #define DISABLE_L4_FIREWALL (BIT(0) | BIT(16) | BIT(24)) diff --git a/plat/intel/soc/stratix10/include/stratix10_private.h b/plat/intel/soc/stratix10/include/stratix10_private.h index f437202..85aff3a 100644 --- a/plat/intel/soc/stratix10/include/stratix10_private.h +++ b/plat/intel/soc/stratix10/include/stratix10_private.h @@ -10,9 +10,9 @@ #define S10_MMC_REG_BASE 0xff808000 #define EMMC_DESC_SIZE (1<<20) -#define EMMC_INIT_PARAMS(base) \ +#define EMMC_INIT_PARAMS(base, clk) \ { .bus_width = MMC_BUS_WIDTH_4, \ - .clk_rate = 50000000, \ + .clk_rate = (clk), \ .desc_base = (base), \ .desc_size = EMMC_DESC_SIZE, \ .flags = 0, \ diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c index b4d0573..ed65c2b 100644 --- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c +++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c @@ -13,15 +13,8 @@ #include "s10_clock_manager.h" #include "s10_handoff.h" +#include "s10_system_manager.h" -static const CLOCK_SOURCE_CONFIG clk_source = { - /* clk_freq_of_eosc1 */ - (uint32_t) 25000000, - /* clk_freq_of_f2h_free */ - (uint32_t) 460000000, - /* clk_freq_of_cb_intosc_ls */ - (uint32_t) 50000000, -}; void wait_pll_lock(void) { @@ -195,24 +188,32 @@ mmio_write_32(ALT_CLKMGR + ALT_CLKMGR_INTRCLR, ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK | ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); + + /* Pass clock source frequency into scratch register */ + mmio_write_32(S10_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_1), + hoff_ptr->hps_osc_clk_h); + mmio_write_32(S10_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_2), + hoff_ptr->fpga_clk_hz); + } -int get_wdt_clk(handoff *hoff_ptr) +/* Extract reference clock from platform clock source */ +uint32_t get_ref_clk(uint32_t pllglob) { - int main_noc_base_clk, l3_main_free_clk, l4_sys_free_clk; - int data32, mdiv, refclkdiv, ref_clk; + uint32_t data32, mdiv, refclkdiv, ref_clk; + uint32_t scr_reg; - data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); - - switch (ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) { - case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1: - ref_clk = clk_source.clk_freq_of_eosc1; + switch (ALT_CLKMGR_PSRC(pllglob)) { + case ALT_CLKMGR_PLLGLOB_PSRC_EOSC1: + scr_reg = S10_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_1); + ref_clk = mmio_read_32(scr_reg); break; - case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC: - ref_clk = clk_source.clk_freq_of_cb_intosc_ls; + case ALT_CLKMGR_PLLGLOB_PSRC_INTOSC: + ref_clk = ALT_CLKMGR_INTOSC_HZ; break; - case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S: - ref_clk = clk_source.clk_freq_of_f2h_free; + case ALT_CLKMGR_PLLGLOB_PSRC_F2S: + scr_reg = S10_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_2); + ref_clk = mmio_read_32(scr_reg); break; default: ref_clk = 0; @@ -220,14 +221,89 @@ break; } - refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(data32); + refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(pllglob); data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK); mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32); + ref_clk = (ref_clk / refclkdiv) * (6 + mdiv); - main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0xff); - l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1); - l4_sys_free_clk = l3_main_free_clk / 4; + return ref_clk; +} - return l4_sys_free_clk; +/* Calculate L3 interconnect main clock */ +uint32_t get_l3_clk(uint32_t ref_clk) +{ + uint32_t noc_base_clk, l3_clk, noc_clk, data32; + uint32_t pllc1_reg; + + noc_clk = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK); + + switch (ALT_CLKMGR_PSRC(noc_clk)) { + case ALT_CLKMGR_SRC_MAIN: + pllc1_reg = ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1; + break; + case ALT_CLKMGR_SRC_PER: + pllc1_reg = ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1; + break; + default: + pllc1_reg = 0; + assert(0); + break; + } + + data32 = mmio_read_32(pllc1_reg); + noc_base_clk = ref_clk / (data32 & 0xff); + l3_clk = noc_base_clk / (noc_clk + 1); + + return l3_clk; +} + +/* Calculate clock frequency to be used for watchdog timer */ +uint32_t get_wdt_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, l4_sys_clk; + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + l4_sys_clk = l3_clk / 4; + + return l4_sys_clk; +} + +/* Calculate clock frequency to be used for UART driver */ +uint32_t get_uart_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, l4_sp_clk; + + data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV); + data32 = (data32 >> 16) & 0x3; + data32 = 1 << data32; + + l4_sp_clk = (l3_clk / data32); + + return l4_sp_clk; +} + +/* Calculate clock frequency to be used for SDMMC driver */ +uint32_t get_mmc_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, mmc_clk; + + data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK); + mmc_clk = (l3_clk / (data32 + 1)) / 4; + + return mmc_clk; }