#define CLKMGR_STAT_PERPLLLOCKED(x) (((x) & 0x00010000) >> 16)
#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004
#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008
+#define CLKMGR_INTOSC_HZ 460000000
/* Main PLL Macros */
#define CLKMGR_MAINPLL_EN_RESET 0x000000ff
-#define CLKMGR_MAINPLL_PLLM_MDIV(x) ((x) & 0x000003ff)
-#define CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK 0x00000001
-#define CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK 0x00000002
-
-#define CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003f00) >> 8)
-#define CLKMGR_MAINPLL_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000f00) >> 8)
-#define CLKMGR_MAINPLL_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12)
-
-#define CLKMGR_MAINPLL_PLLGLOB_PSRC(x) (((x) & 0x00030000) >> 16)
-#define CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1 0x0
-#define CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC 0x1
-#define CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S 0x2
-#define CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003ff)
-#define CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00ff0000)
/* Peripheral PLL Macros */
#define CLKMGR_PERPLL_EN_RESET 0x00000fff
-#define CLKMGR_PERPLL_PLLM_MDIV(x) ((x) & 0x000003ff)
#define CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(x) (((x) << 0) & 0x0000ffff)
-#define CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK 0x00000001
-
-#define CLKMGR_PERPLL_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003f00) >> 8)
-#define CLKMGR_PERPLL_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000f00) >> 8)
-#define CLKMGR_PERPLL_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12)
-
-#define CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK 0x00000002
-#define CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003ff)
-#define CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00ff0000)
/* Altera Macros */
#define CLKMGR_ALTERA_EXTCNTRST_RESET 0xff
+/* Shared Macros */
+#define CLKMGR_PSRC(x) (((x) & 0x00030000) >> 16)
+#define CLKMGR_PSRC_MAIN 0
+#define CLKMGR_PSRC_PER 1
+
+#define CLKMGR_PLLGLOB_PSRC_EOSC1 0x0
+#define CLKMGR_PLLGLOB_PSRC_INTOSC 0x1
+#define CLKMGR_PLLGLOB_PSRC_F2S 0x2
+
+#define CLKMGR_PLLM_MDIV(x) ((x) & 0x000003ff)
+#define CLKMGR_PLLGLOB_PD_SET_MSK 0x00000001
+#define CLKMGR_PLLGLOB_RST_SET_MSK 0x00000002
+
+#define CLKMGR_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003f00) >> 8)
+#define CLKMGR_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000f00) >> 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12)
+
+#define CLKMGR_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003ff)
+#define CLKMGR_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00ff0000)
+
typedef struct {
uint32_t clk_freq_of_eosc1;
} CLOCK_SOURCE_CONFIG;
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
#include "agilex_clock_manager.h"
#include "agilex_handoff.h"
+#include "agilex_system_manager.h"
-static const CLOCK_SOURCE_CONFIG clk_source = {
- /* clk_freq_of_eosc1 */
- (uint32_t) 25000000,
- /* clk_freq_of_f2h_free */
- (uint32_t) 400000000,
- /* clk_freq_of_cb_intosc_ls */
- (uint32_t) 50000000,
-};
uint32_t wait_pll_lock(void)
{
/* Put both PLL in reset and power down */
mmio_clrbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
- CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK |
- CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK);
+ CLKMGR_PLLGLOB_PD_SET_MSK |
+ CLKMGR_PLLGLOB_RST_SET_MSK);
mmio_clrbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
- CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK |
- CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK);
+ CLKMGR_PLLGLOB_PD_SET_MSK |
+ CLKMGR_PLLGLOB_RST_SET_MSK);
/* Setup main PLL dividers */
- mdiv = CLKMGR_MAINPLL_PLLM_MDIV(hoff_ptr->main_pll_pllm);
+ mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->main_pll_pllm);
- arefclk_div = CLKMGR_MAINPLL_PLLGLOB_AREFCLKDIV(
+ arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
hoff_ptr->main_pll_pllglob);
- drefclk_div = CLKMGR_MAINPLL_PLLGLOB_DREFCLKDIV(
+ drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
hoff_ptr->main_pll_pllglob);
mscnt = 100 / (mdiv / BIT(drefclk_div));
hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
- CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(hscnt) |
- CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(mscnt));
+ CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
+ CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
hoff_ptr->main_pll_nocdiv);
hoff_ptr->main_pll_nocclk);
/* Setup peripheral PLL dividers */
- mdiv = CLKMGR_PERPLL_PLLM_MDIV(hoff_ptr->per_pll_pllm);
+ mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->per_pll_pllm);
- arefclk_div = CLKMGR_PERPLL_PLLGLOB_AREFCLKDIV(
+ arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
hoff_ptr->per_pll_pllglob);
- drefclk_div = CLKMGR_PERPLL_PLLGLOB_DREFCLKDIV(
+ drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
hoff_ptr->per_pll_pllglob);
mscnt = 100 / (mdiv / BIT(drefclk_div));
hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_VCOCALIB,
- CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(hscnt) |
- CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(mscnt));
+ CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
+ CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
hoff_ptr->per_pll_emacctl);
/* Take both PLL out of reset and power up */
mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
- CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK |
- CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK);
+ CLKMGR_PLLGLOB_PD_SET_MSK |
+ CLKMGR_PLLGLOB_RST_SET_MSK);
mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
- CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK |
- CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK);
+ CLKMGR_PLLGLOB_PD_SET_MSK |
+ CLKMGR_PLLGLOB_RST_SET_MSK);
wait_pll_lock();
CLKMGR_MAINPLL_EN_RESET);
mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EN,
CLKMGR_PERPLL_EN_RESET);
+
+ /* Pass clock source frequency into scratch register */
+ mmio_write_32(AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_1),
+ hoff_ptr->hps_osc_clk_h);
+ mmio_write_32(AGX_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, arefclkdiv, ref_clk;
-
- data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB);
+ uint32_t arefclkdiv, ref_clk;
+ uint32_t scr_reg;
- switch (CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) {
- case CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1:
- ref_clk = clk_source.clk_freq_of_eosc1;
+ switch (CLKMGR_PSRC(pllglob)) {
+ case CLKMGR_PLLGLOB_PSRC_EOSC1:
+ scr_reg = AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_1);
+ ref_clk = mmio_read_32(scr_reg);
break;
- case CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC:
- ref_clk = clk_source.clk_freq_of_cb_intosc_ls;
+ case CLKMGR_PLLGLOB_PSRC_INTOSC:
+ ref_clk = CLKMGR_INTOSC_HZ;
break;
- case CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S:
- ref_clk = clk_source.clk_freq_of_f2h_free;
+ case CLKMGR_PLLGLOB_PSRC_F2S:
+ scr_reg = AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_2);
+ ref_clk = mmio_read_32(scr_reg);
break;
default:
ref_clk = 0;
break;
}
- arefclkdiv = CLKMGR_MAINPLL_PLLGLOB_AREFCLKDIV(data32);
- mdiv = CLKMGR_MAINPLL_PLLM_MDIV(hoff_ptr->main_pll_pllm);
+ arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob);
+ ref_clk /= arefclkdiv;
+
+ return ref_clk;
+}
+
+/* Calculate clock frequency based on parameter */
+uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc)
+{
+ uint32_t clk_psrc, mdiv, ref_clk;
+ uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg;
+
+ clk_psrc = mmio_read_32(CLKMGR_MAINPLL + psrc_reg);
+
+ switch (CLKMGR_PSRC(clk_psrc)) {
+ case CLKMGR_PSRC_MAIN:
+ pllm_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLM;
+ pllc_reg = CLKMGR_MAINPLL + main_pllc;
+ pllglob_reg = CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB;
+ break;
+ case CLKMGR_PSRC_PER:
+ pllm_reg = CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM;
+ pllc_reg = CLKMGR_PERPLL + per_pllc;
+ pllglob_reg = CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB;
+ break;
+ default:
+ return 0;
+ }
+
+ ref_clk = get_ref_clk(mmio_read_32(pllglob_reg));
+ mdiv = CLKMGR_PLLM_MDIV(mmio_read_32(pllm_reg));
+ ref_clk *= mdiv;
+
+ pllc_div = mmio_read_32(pllc_reg) & 0x7ff;
+
+ return ref_clk / pllc_div;
+}
+
+/* Return L3 interconnect clock */
+uint32_t get_l3_clk(void)
+{
+ uint32_t l3_clk;
+
+ l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1,
+ CLKMGR_PERPLL_PLLC1);
+ return l3_clk;
+}
+
+/* Calculate clock frequency to be used for watchdog timer */
+uint32_t get_wdt_clk(void)
+{
+ uint32_t l3_clk, l4_sys_clk;
+
+ l3_clk = get_l3_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, l3_clk, l4_sp_clk;
+
+ l3_clk = get_l3_clk();
+
+ data32 = mmio_read_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV);
+ data32 = (data32 >> 16) & 0x3;
+
+ 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, mmc_clk;
+
+ mmc_clk = get_clk_freq(CLKMGR_ALTERA_SDMMCCTR,
+ CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3);
- ref_clk = (ref_clk / arefclkdiv) * mdiv;
- main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0x7ff);
- l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1);
- l4_sys_free_clk = l3_main_free_clk / 4;
+ data32 = mmio_read_32(CLKMGR_ALTERA + CLKMGR_ALTERA_SDMMCCTR);
+ data32 = (data32 & 0x7ff) + 1;
+ mmc_clk = (mmc_clk / data32) / 4;
- return l4_sys_free_clk;
+ return mmc_clk;
}