drivers: clock_control: Agilex5 clock control driver updates
The clock controller/manager registers are updated with the correct divider values by bootloader via hand-off data, so now we can use the clock controller to get the clock value of each peripheral during the run time. Signed-off-by: Girisha Dengi <girisha.dengi@intel.com>
This commit is contained in:
parent
e7629bb278
commit
36e71c839f
5 changed files with 381 additions and 199 deletions
|
@ -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;
|
||||
|
|
|
@ -1,181 +1,254 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, Intel Corporation.
|
||||
* Copyright (c) 2022-2024, Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/arch/cpu.h>
|
||||
#include <socfpga_system_manager.h>
|
||||
#include <zephyr/sys/__assert.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
|
|
@ -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 <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <zephyr/sys/sys_io.h>
|
||||
|
||||
/* 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_ */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include <zephyr/arch/arm64/arm_mmu.h>
|
||||
|
||||
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",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue