intel: stratix10: Fix reliance on hard coded clock information
authorHadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Tue, 30 Jul 2019 14:18:17 +0000 (22:18 +0800)
committerHadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Tue, 13 Aug 2019 10:20:53 +0000 (18:20 +0800)
Extract clock information for UART, MMC & Watchdog from the platform
rather than hard code it

Signed-off-by: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Change-Id: I2582bd34a6da97bd75d5ccba5f93840e65f26b03

plat/intel/soc/stratix10/bl2_plat_setup.c
plat/intel/soc/stratix10/include/s10_clock_manager.h
plat/intel/soc/stratix10/include/s10_system_manager.h
plat/intel/soc/stratix10/include/stratix10_private.h
plat/intel/soc/stratix10/soc/s10_clock_manager.c

index 8e8b582fc0310b416f1356aa9f6b62cc1a3d80db..f24bbdec48996548c67945de1f705748ec4fc0c3 100644 (file)
@@ -73,9 +73,9 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
        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 @@ void bl2_el3_plat_arch_setup(void)
 
        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;
index 99eb7a6c3d855a70c362914845d15581686009f0..c800b9cf70d1038c3db0e1adfbece712a0a6d04c 100644 (file)
 #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
 #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
index 4500c6fbd1932465cb58d64af9cb9b9af674aaf7..a67d689fa8876d886ecb67eb83f5daabfe8548ae 100644 (file)
@@ -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))
index f437202fa58ad368c6988157741f77690396669d..85aff3aa7998ffab0cbfe877f4a8f94939ac2593 100644 (file)
@@ -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,                     \
index b4d0573548c8056c4b209d9104faf62a5cbff993..ed65c2ba8b7bff4a5e8cc2d9377b79ba1b31321c 100644 (file)
 
 #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 @@ void config_clkmgr_handoff(handoff *hoff_ptr)
        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 @@ int get_wdt_clk(handoff *hoff_ptr)
                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;
+}
+
+/* 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 l4_sys_free_clk;
+       return mmc_clk;
 }