diff --git a/drivers/clock_control/clock_control_agilex5.c b/drivers/clock_control/clock_control_agilex5.c index c3c88b62507..938c18703e6 100644 --- a/drivers/clock_control/clock_control_agilex5.c +++ b/drivers/clock_control/clock_control_agilex5.c @@ -25,12 +25,8 @@ struct clock_control_data { static int clock_init(const struct device *dev) { - DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE); - /* Initialize the low layer clock driver */ - clock_agilex5_ll_init(DEVICE_MMIO_GET(dev)); - - LOG_INF("Intel Agilex5 clock driver initialized!"); + LOG_DBG("Intel Agilex5 clock driver initialized!"); return 0; } @@ -54,13 +50,25 @@ static int clock_get_rate(const struct device *dev, clock_control_subsys_t sub_s break; case INTEL_SOCFPGA_CLOCK_MMC: - *rate = get_mmc_clk(); + *rate = get_sdmmc_clk(); break; case INTEL_SOCFPGA_CLOCK_TIMER: *rate = get_timer_clk(); break; + case INTEL_SOCFPGA_CLOCK_QSPI: + *rate = get_qspi_clk(); + break; + + case INTEL_SOCFPGA_CLOCK_I2C: + *rate = get_i2c_clk(); + break; + + case INTEL_SOCFPGA_CLOCK_I3C: + *rate = get_i3c_clk(); + break; + default: LOG_ERR("Clock ID %ld is not supported\n", (intptr_t)sub_system); return -ENOTSUP; diff --git a/drivers/clock_control/clock_control_agilex5_ll.c b/drivers/clock_control/clock_control_agilex5_ll.c index a7308323309..bde406cd44b 100644 --- a/drivers/clock_control/clock_control_agilex5_ll.c +++ b/drivers/clock_control/clock_control_agilex5_ll.c @@ -1,181 +1,254 @@ /* - * Copyright (c) 2022-2023, Intel Corporation. + * Copyright (c) 2022-2024, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include #include +#include #include "clock_control_agilex5_ll.h" LOG_MODULE_REGISTER(clock_control_agilex5_ll, CONFIG_CLOCK_CONTROL_LOG_LEVEL); -/* Clock manager individual group base addresses. */ -struct clock_agilex5_ll_params { - mm_reg_t base_addr; - mm_reg_t mainpll_addr; - mm_reg_t peripll_addr; - mm_reg_t ctl_addr; -}; - -/* Clock manager low layer(ll) params object. */ -static struct clock_agilex5_ll_params clock_agilex5_ll; - -/* Initialize the clock ll with the given base address */ -void clock_agilex5_ll_init(mm_reg_t base_addr) -{ - /* Clock manager module base address. */ - clock_agilex5_ll.base_addr = base_addr; - - /* Clock manager main PLL base address. */ - clock_agilex5_ll.mainpll_addr = clock_agilex5_ll.base_addr + CLKMGR_MAINPLL_OFFSET; - - /* Clock manager peripheral PLL base address. */ - clock_agilex5_ll.peripll_addr = clock_agilex5_ll.base_addr + CLKMGR_PERPLL_OFFSET; - - /* Clock manager control module base address. */ - clock_agilex5_ll.ctl_addr = clock_agilex5_ll.base_addr + CLKMGR_INTEL_OFFSET; -} - /* Extract reference clock from platform clock source */ -static uint32_t get_ref_clk(uint32_t pllglob) +static uint32_t get_ref_clk(mm_reg_t pllglob_reg, mm_reg_t pllm_reg) { - uint32_t arefclkdiv, ref_clk; - uint32_t scr_reg; + uint32_t arefclkdiv = 0U; + uint32_t ref_clk = 0U; + uint32_t mdiv = 0U; + uint32_t pllglob_val = 0U; + uint32_t pllm_val = 0U; + + /* Read pllglob and pllm registers */ + pllglob_val = sys_read32(pllglob_reg); + pllm_val = sys_read32(pllm_reg); /* * Based on the clock source, read the values from System Manager boot * scratch registers. These values are filled by boot loader based on * hand-off data. */ - switch (CLKMGR_PSRC(pllglob)) { - case CLKMGR_PLLGLOB_PSRC_EOSC1: - scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1); - ref_clk = sys_read32(scr_reg); + switch (CLKCTRL_PSRC(pllglob_val)) { + case CLKCTRL_PLLGLOB_PSRC_EOSC1: + ref_clk = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)); break; - case CLKMGR_PLLGLOB_PSRC_INTOSC: - ref_clk = CLKMGR_INTOSC_HZ; + case CLKCTRL_PLLGLOB_PSRC_INTOSC: + ref_clk = CLKCTRL_INTOSC_HZ; break; - case CLKMGR_PLLGLOB_PSRC_F2S: - scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2); - ref_clk = sys_read32(scr_reg); + case CLKCTRL_PLLGLOB_PSRC_F2S: + ref_clk = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2)); break; default: ref_clk = 0; - LOG_ERR("Invalid VCO input clock source"); + __ASSERT(0, "Invalid input clock source"); break; } - /* Reference clock divider, to get the effective reference clock. */ - arefclkdiv = CLKMGR_PLLGLOB_AREFCLKDIV(pllglob); + /* Get reference clock divider */ + arefclkdiv = CLKCTRL_PLLGLOB_AREFCLKDIV(pllglob_val); + __ASSERT(arefclkdiv != 0, "Reference clock divider is zero"); ref_clk /= arefclkdiv; + /* Feedback clock divider */ + mdiv = CLKCTRL_PLLM_MDIV(pllm_val); + ref_clk *= mdiv; + + LOG_DBG("%s: ref_clk %u\n", __func__, ref_clk); + return ref_clk; } /* Calculate clock frequency based on parameter */ -static uint32_t get_clk_freq(uint32_t psrc_reg, uint32_t main_pllc, uint32_t per_pllc) +static uint32_t get_clk_freq(mm_reg_t psrc_reg, mm_reg_t mainpllc_reg, + mm_reg_t perpllc_reg) { - uint32_t clk_psrc, mdiv, ref_clk; - uint32_t pllm_reg, pllc_reg, pllc_div, pllglob_reg; + uint32_t clock_val = 0U; + uint32_t clk_psrc = 0U; + uint32_t pllcx_div = 0U; - clk_psrc = sys_read32(clock_agilex5_ll.mainpll_addr + psrc_reg); - - switch (CLKMGR_PSRC(clk_psrc)) { - case CLKMGR_PSRC_MAIN: - pllm_reg = clock_agilex5_ll.mainpll_addr + CLKMGR_MAINPLL_PLLM; - pllc_reg = clock_agilex5_ll.mainpll_addr + main_pllc; - pllglob_reg = clock_agilex5_ll.mainpll_addr + CLKMGR_MAINPLL_PLLGLOB; + /* + * Select source for the active 5:1 clock selection when the PLL + * is not bypassed + */ + clk_psrc = sys_read32(psrc_reg); + switch (GET_CLKCTRL_CLKSRC(clk_psrc)) { + case CLKCTRL_CLKSRC_MAIN: + clock_val = get_ref_clk(CLKCTRL_MAINPLL(PLLGLOB), CLKCTRL_MAINPLL(PLLM)); + pllcx_div = (sys_read32(mainpllc_reg) & CLKCTRL_PLLCX_DIV_MSK); + __ASSERT(pllcx_div != 0, "Main PLLC clock divider is zero"); + clock_val /= pllcx_div; break; - case CLKMGR_PSRC_PER: - pllm_reg = clock_agilex5_ll.peripll_addr + CLKMGR_PERPLL_PLLM; - pllc_reg = clock_agilex5_ll.peripll_addr + per_pllc; - pllglob_reg = clock_agilex5_ll.peripll_addr + CLKMGR_PERPLL_PLLGLOB; + case CLKCTRL_CLKSRC_PER: + clock_val = get_ref_clk(CLKCTRL_PERPLL(PLLGLOB), CLKCTRL_PERPLL(PLLM)); + pllcx_div = (sys_read32(perpllc_reg) & CLKCTRL_PLLCX_DIV_MSK); + __ASSERT(pllcx_div != 0, "Peripheral PLLC clock divider is zero"); + clock_val /= pllcx_div; + break; + + case CLKCTRL_CLKSRC_OSC1: + clock_val = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1)); + break; + + case CLKCTRL_CLKSRC_INTOSC: + clock_val = CLKCTRL_INTOSC_HZ; + break; + + case CLKCTRL_CLKSRC_FPGA: + clock_val = sys_read32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2)); break; default: - return 0; + __ASSERT(0, "Invalid clock source select"); + break; } - ref_clk = get_ref_clk(sys_read32(pllglob_reg)); - mdiv = CLKMGR_PLLM_MDIV(sys_read32(pllm_reg)); - ref_clk *= mdiv; + LOG_DBG("%s: clock source %lu and its value %u\n", + __func__, GET_CLKCTRL_CLKSRC(clk_psrc), clock_val); - /* Clock slice divider ration in binary code. */ - pllc_div = CLKMGR_PLLC_DIV(sys_read32(pllc_reg)); - - return ref_clk / pllc_div; + return clock_val; } -/* Return L3 interconnect clock */ -uint32_t get_l3_clk(void) +/* Get L3 free clock */ +static uint32_t get_l3_main_free_clk(void) { - uint32_t l3_clk; - - l3_clk = get_clk_freq(CLKMGR_MAINPLL_NOCCLK, CLKMGR_MAINPLL_PLLC1, CLKMGR_PERPLL_PLLC1); - - return l3_clk; + return get_clk_freq(CLKCTRL_MAINPLL(NOCCLK), + CLKCTRL_MAINPLL(PLLC3), + CLKCTRL_PERPLL(PLLC1)); } -/* Calculate clock frequency to be used for mpu */ +/* Get L4 mp clock */ +static uint32_t get_l4_mp_clk(void) +{ + uint32_t l3_main_free_clk = get_l3_main_free_clk(); + uint32_t mainpll_nocdiv_l4mp = BIT(GET_CLKCTRL_MAINPLL_NOCDIV_L4MP( + sys_read32(CLKCTRL_MAINPLL(NOCDIV)))); + + uint32_t l4_mp_clk = (l3_main_free_clk / mainpll_nocdiv_l4mp); + + return l4_mp_clk; +} + +/* + * Get L4 sp clock. + * "l4_sp_clk" (100MHz) will be used for slow peripherals like UART, I2C, + * Timers ...etc. + */ +static uint32_t get_l4_sp_clk(void) +{ + uint32_t l3_main_free_clk = get_l3_main_free_clk(); + uint32_t mainpll_nocdiv_l4sp = BIT(GET_CLKCTRL_MAINPLL_NOCDIV_L4SP( + sys_read32(CLKCTRL_MAINPLL(NOCDIV)))); + + uint32_t l4_sp_clk = (l3_main_free_clk / mainpll_nocdiv_l4sp); + + return l4_sp_clk; +} + +/* Get MPU clock */ uint32_t get_mpu_clk(void) { - uint32_t mpu_clk; + uint8_t cpu_id = arch_curr_cpu()->id; + uint32_t ctr_reg = 0U; + uint32_t clock_val = 0U; - mpu_clk = get_clk_freq(CLKMGR_MAINPLL_MPUCLK, CLKMGR_MAINPLL_PLLC0, CLKMGR_PERPLL_PLLC0); + if (cpu_id > CLKCTRL_CPU_ID_CORE1) { + clock_val = get_clk_freq(CLKCTRL_CTLGRP(CORE23CTR), + CLKCTRL_MAINPLL(PLLC0), + CLKCTRL_PERPLL(PLLC0)); + } else { + clock_val = get_clk_freq(CLKCTRL_CTLGRP(CORE01CTR), + CLKCTRL_MAINPLL(PLLC1), + CLKCTRL_PERPLL(PLLC0)); + } - return mpu_clk; + switch (cpu_id) { + case CLKCTRL_CPU_ID_CORE0: + case CLKCTRL_CPU_ID_CORE1: + ctr_reg = CLKCTRL_CTLGRP(CORE01CTR); + break; + + case CLKCTRL_CPU_ID_CORE2: + ctr_reg = CLKCTRL_CTLGRP(CORE2CTR); + break; + + case CLKCTRL_CPU_ID_CORE3: + ctr_reg = CLKCTRL_CTLGRP(CORE3CTR); + break; + + default: + break; + } + + /* Division setting for ping pong counter in clock slice */ + clock_val /= 1 + (sys_read32(ctr_reg) & CLKCTRL_PLLCX_DIV_MSK); + + return clock_val; } /* Calculate clock frequency to be used for watchdog timer */ uint32_t get_wdt_clk(void) { - uint32_t l4_sys_clk; + uint32_t l3_main_free_clk = get_l3_main_free_clk(); + uint32_t mainpll_nocdiv_l4sysfreeclk = BIT(GET_CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE( + sys_read32(CLKCTRL_MAINPLL(NOCDIV)))); + uint32_t l4_sys_free_clk = (l3_main_free_clk / mainpll_nocdiv_l4sysfreeclk); - l4_sys_clk = (get_l3_clk() >> 2); - - return l4_sys_clk; + return l4_sys_free_clk; } -/* Calculate clock frequency to be used for UART driver */ +/* Get clock frequency to be used for UART driver */ uint32_t get_uart_clk(void) { - uint32_t mainpll_nocdiv, l4_sp_clk; - - mainpll_nocdiv = sys_read32(clock_agilex5_ll.mainpll_addr + CLKMGR_MAINPLL_NOCDIV); - mainpll_nocdiv = CLKMGR_MAINPLL_L4SPDIV(mainpll_nocdiv); - - l4_sp_clk = (get_l3_clk() >> mainpll_nocdiv); - - return l4_sp_clk; + return get_l4_sp_clk(); } /* Calculate clock frequency to be used for SDMMC driver */ -uint32_t get_mmc_clk(void) +uint32_t get_sdmmc_clk(void) { - uint32_t sdmmc_ctr, mmc_clk; + uint32_t l4_mp_clk = get_l4_mp_clk(); + uint32_t mainpll_nocdiv = sys_read32(CLKCTRL_MAINPLL(NOCDIV)); + uint32_t sdmmc_clk = l4_mp_clk / BIT(GET_CLKCTRL_MAINPLL_NOCDIV_SPHY(mainpll_nocdiv)); - mmc_clk = get_clk_freq(CLKMGR_INTEL_SDMMCCTR, CLKMGR_MAINPLL_PLLC3, CLKMGR_PERPLL_PLLC3); - - sdmmc_ctr = sys_read32(clock_agilex5_ll.ctl_addr + CLKMGR_INTEL_SDMMCCTR); - sdmmc_ctr = CLKMGR_INTEL_SDMMC_CNT(sdmmc_ctr); - mmc_clk = ((mmc_clk / sdmmc_ctr) >> 2); - - return mmc_clk; + return sdmmc_clk; } /* Calculate clock frequency to be used for Timer driver */ uint32_t get_timer_clk(void) { - uint32_t l4_sys_clk; - - l4_sys_clk = (get_l3_clk() >> 2); - - return l4_sys_clk; + return get_l4_sp_clk(); +} + +/* Calculate clock frequency to be used for QSPI driver */ +uint32_t get_qspi_clk(void) +{ + uint32_t scr_reg, ref_clk; + + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_0); + ref_clk = sys_read32(scr_reg); + + /* + * In ATF, the qspi clock is divided by 1000 and loaded in scratch cold register 0 + * So in Zephyr, reverting back the clock frequency by multiplying by 1000. + */ + return (ref_clk * 1000); +} + +/* Calculate clock frequency to be used for I2C driver */ +uint32_t get_i2c_clk(void) +{ + return get_l4_sp_clk(); +} + +/* Calculate clock frequency to be used for I3C driver */ +uint32_t get_i3c_clk(void) +{ + return get_l4_mp_clk(); } diff --git a/drivers/clock_control/clock_control_agilex5_ll.h b/drivers/clock_control/clock_control_agilex5_ll.h index 57c44fd9be0..fcccc7382be 100644 --- a/drivers/clock_control/clock_control_agilex5_ll.h +++ b/drivers/clock_control/clock_control_agilex5_ll.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023, Intel Corporation. + * Copyright (c) 2022-2024, Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,109 +8,176 @@ #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_AGILEX5_LL_H_ #include +#include #include -/* Clock manager register offsets */ -#define CLKMGR_CTRL 0x00 -#define CLKMGR_STAT 0x04 -#define CLKMGR_INTRCLR 0x14 +/* Clock control MMIO register base address */ +#define CLKCTRL_BASE_ADDR DT_REG_ADDR(DT_NODELABEL(clock)) -/* Clock manager main PLL group register offsets */ -#define CLKMGR_MAINPLL_OFFSET 0x24 -#define CLKMGR_MAINPLL_EN 0x00 -#define CLKMGR_MAINPLL_BYPASS 0x0C -#define CLKMGR_MAINPLL_MPUCLK 0x18 -#define CLKMGR_MAINPLL_BYPASSS 0x10 -#define CLKMGR_MAINPLL_NOCCLK 0x1C -#define CLKMGR_MAINPLL_NOCDIV 0x20 -#define CLKMGR_MAINPLL_PLLGLOB 0x24 -#define CLKMGR_MAINPLL_FDBCK 0x28 -#define CLKMGR_MAINPLL_MEM 0x2C -#define CLKMGR_MAINPLL_MEMSTAT 0x30 -#define CLKMGR_MAINPLL_VCOCALIB 0x34 -#define CLKMGR_MAINPLL_PLLC0 0x38 -#define CLKMGR_MAINPLL_PLLC1 0x3C -#define CLKMGR_MAINPLL_PLLC2 0x40 -#define CLKMGR_MAINPLL_PLLC3 0x44 -#define CLKMGR_MAINPLL_PLLM 0x48 -#define CLKMGR_MAINPLL_LOSTLOCK 0x54 +/* Clock manager/control register offsets */ +#define CLKCTRL_OFFSET 0x00 +#define CLKCTRL_CTRL 0x00 +#define CLKCTRL_STAT 0x04 +#define CLKCTRL_TESTIOCTRL 0x08 +#define CLKCTRL_INTRGEN 0x0C +#define CLKCTRL_INTRMSK 0x10 +#define CLKCTRL_INTRCLR 0x14 +#define CLKCTRL_INTRSTS 0x18 +#define CLKCTRL_INTRSTK 0x1C +#define CLKCTRL_INTRRAW 0x20 -/* Clock manager peripheral PLL group register offsets */ -#define CLKMGR_PERPLL_OFFSET 0x7C -#define CLKMGR_PERPLL_EN 0x00 -#define CLKMGR_PERPLL_BYPASS 0x0C -#define CLKMGR_PERPLL_BYPASSS 0x10 -#define CLKMGR_PERPLL_EMACCTL 0x18 -#define CLKMGR_PERPLL_GPIODIV 0x1C -#define CLKMGR_PERPLL_PLLGLOB 0x20 -#define CLKMGR_PERPLL_FDBCK 0x24 -#define CLKMGR_PERPLL_MEM 0x28 -#define CLKMGR_PERPLL_MEMSTAT 0x2C -#define CLKMGR_PERPLL_VCOCALIB 0x30 -#define CLKMGR_PERPLL_PLLC0 0x34 -#define CLKMGR_PERPLL_PLLC1 0x38 -#define CLKMGR_PERPLL_PLLC2 0x3C -#define CLKMGR_PERPLL_PLLC3 0x40 -#define CLKMGR_PERPLL_PLLM 0x44 -#define CLKMGR_PERPLL_LOSTLOCK 0x50 +#define CLKCTRL(x) (CLKCTRL_BASE_ADDR + CLKCTRL_##_reg) -/* Clock manager control/intel group register offsets */ -#define CLKMGR_INTEL_OFFSET 0xD0 -#define CLKMGR_INTEL_JTAG 0x00 -#define CLKMGR_INTEL_EMACACTR 0x4 -#define CLKMGR_INTEL_EMACBCTR 0x8 -#define CLKMGR_INTEL_EMACPTPCTR 0x0C -#define CLKMGR_INTEL_GPIODBCTR 0x10 -#define CLKMGR_INTEL_SDMMCCTR 0x14 -#define CLKMGR_INTEL_S2FUSER0CTR 0x18 -#define CLKMGR_INTEL_S2FUSER1CTR 0x1C -#define CLKMGR_INTEL_PSIREFCTR 0x20 -#define CLKMGR_INTEL_EXTCNTRST 0x24 +/* Clock manager/control main PLL group register offsets */ +#define CLKCTRL_MAINPLL_OFFSET 0x24 +#define CLKCTRL_MAINPLL_EN 0x00 +#define CLKCTRL_MAINPLL_ENS 0x04 +#define CLKCTRL_MAINPLL_ENR 0x08 +#define CLKCTRL_MAINPLL_BYPASS 0x0C +#define CLKCTRL_MAINPLL_BYPASSS 0x10 +#define CLKCTRL_MAINPLL_BYPASSR 0x14 +#define CLKCTRL_MAINPLL_NOCCLK 0x1C +#define CLKCTRL_MAINPLL_NOCDIV 0x20 +#define CLKCTRL_MAINPLL_PLLGLOB 0x24 +#define CLKCTRL_MAINPLL_FDBCK 0x28 +#define CLKCTRL_MAINPLL_MEM 0x2C +#define CLKCTRL_MAINPLL_MEMSTAT 0x30 +#define CLKCTRL_MAINPLL_VCOCALIB 0x34 +#define CLKCTRL_MAINPLL_PLLC0 0x38 +#define CLKCTRL_MAINPLL_PLLC1 0x3C +#define CLKCTRL_MAINPLL_PLLC2 0x40 +#define CLKCTRL_MAINPLL_PLLC3 0x44 +#define CLKCTRL_MAINPLL_PLLM 0x48 +#define CLKCTRL_MAINPLL_FHOP 0x4C +#define CLKCTRL_MAINPLL_SSC 0x50 +#define CLKCTRL_MAINPLL_LOSTLOCK 0x54 -/* Clock manager macros */ -#define CLKMGR_CTRL_BOOTMODE_SET_MSK 0x00000001U -#define CLKMGR_STAT_BUSY_E_BUSY 0x1 -#define CLKMGR_STAT_BUSY(x) (((x) & 0x00000001U) >> 0) -#define CLKMGR_STAT_MAINPLLLOCKED(x) (((x) & 0x00000100U) >> 8) -#define CLKMGR_STAT_PERPLLLOCKED(x) (((x) & 0x00010000U) >> 16) -#define CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004U -#define CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008U -#define CLKMGR_MAINPLL_L4SPDIV(x) (((x) >> 16) & 0x3) -#define CLKMGR_INTOSC_HZ 460000000U +#define CLKCTRL_MAINPLL_BASE_ADDR (CLKCTRL_BASE_ADDR + CLKCTRL_MAINPLL_OFFSET) +#define CLKCTRL_MAINPLL(_reg) (CLKCTRL_MAINPLL_BASE_ADDR + CLKCTRL_MAINPLL_##_reg) + +/* Clock manager/control peripheral PLL group register offsets */ +#define CLKCTRL_PERPLL_OFFSET 0x7C +#define CLKCTRL_PERPLL_EN 0x00 +#define CLKCTRL_PERPLL_ENS 0x04 +#define CLKCTRL_PERPLL_ENR 0x08 +#define CLKCTRL_PERPLL_BYPASS 0x0C +#define CLKCTRL_PERPLL_BYPASSS 0x10 +#define CLKCTRL_PERPLL_BYPASSR 0x14 +#define CLKCTRL_PERPLL_EMACCTL 0x18 +#define CLKCTRL_PERPLL_GPIODIV 0x1C +#define CLKCTRL_PERPLL_PLLGLOB 0x20 +#define CLKCTRL_PERPLL_FDBCK 0x24 +#define CLKCTRL_PERPLL_MEM 0x28 +#define CLKCTRL_PERPLL_MEMSTAT 0x2C +#define CLKCTRL_PERPLL_VCOCALIB 0x30 +#define CLKCTRL_PERPLL_PLLC0 0x34 +#define CLKCTRL_PERPLL_PLLC1 0x38 +#define CLKCTRL_PERPLL_PLLC2 0x3C +#define CLKCTRL_PERPLL_PLLC3 0x40 +#define CLKCTRL_PERPLL_PLLM 0x44 +#define CLKCTRL_PERPLL_FHOP 0x48 +#define CLKCTRL_PERPLL_SSC 0x4C +#define CLKCTRL_PERPLL_LOSTLOCK 0x50 + +#define CLKCTRL_PERPLL_BASE_ADDR (CLKCTRL_BASE_ADDR + CLKCTRL_PERPLL_OFFSET) +#define CLKCTRL_PERPLL(_reg) (CLKCTRL_PERPLL_BASE_ADDR + CLKCTRL_PERPLL_##_reg) + +/* Clock manager/control controller group register offsets */ +#define CLKCTRL_CTLGRP_OFFSET 0xD0 +#define CLKCTRL_CTLGRP_JTAG 0x00 +#define CLKCTRL_CTLGRP_EMACACTR 0x04 +#define CLKCTRL_CTLGRP_EMACBCTR 0x08 +#define CLKCTRL_CTLGRP_EMACPTPCTR 0x0C +#define CLKCTRL_CTLGRP_GPIODBCTR 0x10 +#define CLKCTRL_CTLGRP_S2FUSER0CTR 0x18 +#define CLKCTRL_CTLGRP_S2FUSER1CTR 0x1C +#define CLKCTRL_CTLGRP_PSIREFCTR 0x20 +#define CLKCTRL_CTLGRP_EXTCNTRST 0x24 +#define CLKCTRL_CTLGRP_USB31CTR 0x28 +#define CLKCTRL_CTLGRP_DSUCTR 0x2C +#define CLKCTRL_CTLGRP_CORE01CTR 0x30 +#define CLKCTRL_CTLGRP_CORE23CTR 0x34 +#define CLKCTRL_CTLGRP_CORE2CTR 0x38 +#define CLKCTRL_CTLGRP_CORE3CTR 0x3C +#define CLKCTRL_CTLGRP_SRL_CON_PLLCTR 0x40 + +#define CLKCTRL_CTLGRP_BASE_ADDR (CLKCTRL_BASE_ADDR + CLKCTRL_CTLGRP_OFFSET) +#define CLKCTRL_CTLGRP(_reg) (CLKCTRL_CTLGRP_BASE_ADDR + CLKCTRL_CTLGRP_##_reg) + + +/* Clock manager/control macros */ +#define CLKCTRL_CTRL_BOOTMODE_SET_MSK 0x00000001U +#define CLKCTRL_STAT_BUSY_E_BUSY 0x1 +#define CLKCTRL_STAT_BUSY(x) (((x) & 0x00000001U) >> 0) +#define CLKCTRL_STAT_MAINPLLLOCKED(x) (((x) & 0x00000100U) >> 8) +#define CLKCTRL_STAT_PERPLLLOCKED(x) (((x) & 0x00010000U) >> 16) +#define CLKCTRL_INTRCLR_MAINLOCKLOST_SET_MSK 0x00000004U +#define CLKCTRL_INTRCLR_PERLOCKLOST_SET_MSK 0x00000008U +#define CLKCTRL_MAINPLL_L4SPDIV(x) (((x) >> 16) & 0x3) +#define CLKCTRL_INTOSC_HZ 460000000U + +#define CLKCTRL_CLKSRC_MASK GENMASK(18, 16) +#define CLKCTRL_CLKSRC_OFFSET 16 +#define CLKCTRL_CLKSRC_MAIN 0 +#define CLKCTRL_CLKSRC_PER 1 +#define CLKCTRL_CLKSRC_OSC1 2 +#define CLKCTRL_CLKSRC_INTOSC 3 +#define CLKCTRL_CLKSRC_FPGA 4 +#define CLKCTRL_PLLCX_DIV_MSK GENMASK(10, 0) +#define GET_CLKCTRL_CLKSRC(x) (((x) & CLKCTRL_CLKSRC_MASK) >> \ + CLKCTRL_CLKSRC_OFFSET) /* Shared Macros */ -#define CLKMGR_PSRC(x) (((x) & 0x00030000U) >> 16) -#define CLKMGR_PSRC_MAIN 0 -#define CLKMGR_PSRC_PER 1 +#define CLKCTRL_PSRC(x) (((x) & 0x00030000U) >> 16) +#define CLKCTRL_PSRC_MAIN 0 +#define CLKCTRL_PSRC_PER 1 -#define CLKMGR_PLLGLOB_PSRC_EOSC1 0x0 -#define CLKMGR_PLLGLOB_PSRC_INTOSC 0x1 -#define CLKMGR_PLLGLOB_PSRC_F2S 0x2 +#define CLKCTRL_PLLGLOB_PSRC_EOSC1 0x0 +#define CLKCTRL_PLLGLOB_PSRC_INTOSC 0x1 +#define CLKCTRL_PLLGLOB_PSRC_F2S 0x2 -#define CLKMGR_PLLM_MDIV(x) ((x) & 0x000003FFU) -#define CLKMGR_PLLGLOB_PD_SET_MSK 0x00000001U -#define CLKMGR_PLLGLOB_RST_SET_MSK 0x00000002U +#define CLKCTRL_PLLM_MDIV(x) ((x) & 0x000003FFU) +#define CLKCTRL_PLLGLOB_PD_SET_MSK 0x00000001U +#define CLKCTRL_PLLGLOB_RST_SET_MSK 0x00000002U -#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 CLKCTRL_PLLGLOB_REFCLKDIV(x) (((x) & 0x00003F00) >> 8) +#define CLKCTRL_PLLGLOB_AREFCLKDIV(x) (((x) & 0x00000F00) >> 8) +#define CLKCTRL_PLLGLOB_DREFCLKDIV(x) (((x) & 0x00003000) >> 12) -#define CLKMGR_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003FF) -#define CLKMGR_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00FF0000) +#define CLKCTRL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003FF) +#define CLKCTRL_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00FF0000) -#define CLKMGR_CLR_LOSTLOCK_BYPASS 0x20000000U -#define CLKMGR_PLLC_DIV(x) ((x) & 0x7FF) -#define CLKMGR_INTEL_SDMMC_CNT(x) (((x) & 0x7FF) + 1) +#define CLKCTRL_CLR_LOSTLOCK_BYPASS 0x20000000U +#define CLKCTRL_PLLC_DIV(x) ((x) & 0x7FF) +#define CLKCTRL_CTRL_SDMMC_CNT(x) (((x) & 0x7FF) + 1) -/** - * @brief Initialize the low layer clock control driver - * - * @param base_addr : Clock control device MMIO base address - * - * @return void - */ -void clock_agilex5_ll_init(mm_reg_t base_addr); +#define CLKCTRL_CPU_ID_CORE0 0 +#define CLKCTRL_CPU_ID_CORE1 1 +#define CLKCTRL_CPU_ID_CORE2 2 +#define CLKCTRL_CPU_ID_CORE3 3 + + +#define CLKCTRL_MAINPLL_NOCDIV_L4MP_MASK GENMASK(5, 4) +#define CLKCTRL_MAINPLL_NOCDIV_L4MP_OFFSET 4 +#define GET_CLKCTRL_MAINPLL_NOCDIV_L4MP(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_L4MP_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_L4MP_OFFSET) + +#define CLKCTRL_MAINPLL_NOCDIV_L4SP_MASK GENMASK(7, 6) +#define CLKCTRL_MAINPLL_NOCDIV_L4SP_OFFSET 6 +#define GET_CLKCTRL_MAINPLL_NOCDIV_L4SP(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_L4SP_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_L4SP_OFFSET) + + +#define CLKCTRL_MAINPLL_NOCDIV_SPHY_MASK GENMASK(17, 16) +#define CLKCTRL_MAINPLL_NOCDIV_SPHY_OFFSET 16 +#define GET_CLKCTRL_MAINPLL_NOCDIV_SPHY(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_SPHY_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_SPHY_OFFSET) + +#define CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_MASK GENMASK(3, 2) +#define CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_OFFSET 2 +#define GET_CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE(x) (((x) & CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_MASK) >> \ + CLKCTRL_MAINPLL_NOCDIV_L4SYSFREE_OFFSET) /** * @brief Get MPU(Micro Processor Unit) clock value @@ -146,7 +213,7 @@ uint32_t get_uart_clk(void); * * @return returns MMC clock value */ -uint32_t get_mmc_clk(void); +uint32_t get_sdmmc_clk(void); /** * @brief Get Timer peripheral clock value @@ -157,4 +224,31 @@ uint32_t get_mmc_clk(void); */ uint32_t get_timer_clk(void); +/** + * @brief Get QSPI peripheral clock value + * + * @param void + * + * @return returns QSPI clock value + */ +uint32_t get_qspi_clk(void); + +/** + * @brief Get I2C peripheral clock value + * + * @param void + * + * @return returns I2C clock value + */ +uint32_t get_i2c_clk(void); + +/** + * @brief Get I3C peripheral clock value + * + * @param void + * + * @return returns I3C clock value + */ +uint32_t get_i3c_clk(void); + #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_AGILEX5_LL_H_ */ diff --git a/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h b/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h index 9e98057068e..36c7de89cb5 100644 --- a/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h +++ b/include/zephyr/dt-bindings/clock/intel_socfpga_clock.h @@ -13,5 +13,8 @@ #define INTEL_SOCFPGA_CLOCK_UART 2 #define INTEL_SOCFPGA_CLOCK_MMC 3 #define INTEL_SOCFPGA_CLOCK_TIMER 4 +#define INTEL_SOCFPGA_CLOCK_QSPI 5 +#define INTEL_SOCFPGA_CLOCK_I2C 6 +#define INTEL_SOCFPGA_CLOCK_I3C 7 #endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_INTEL_SOCFPGA_CLOCK_H_ */ diff --git a/soc/intel/intel_socfpga/agilex5/mmu_regions.c b/soc/intel/intel_socfpga/agilex5/mmu_regions.c index 984c729bddd..b921d1cd3cd 100644 --- a/soc/intel/intel_socfpga/agilex5/mmu_regions.c +++ b/soc/intel/intel_socfpga/agilex5/mmu_regions.c @@ -8,6 +8,10 @@ #include static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("CLOCK", + DT_REG_ADDR(DT_NODELABEL(clock)), + DT_REG_SIZE(DT_NODELABEL(clock)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), /* System manager register that required by clock driver */ MMU_REGION_FLAT_ENTRY("SYSTEM_MANAGER",