arm64/imx9: ccm: add default clk init
This adds enablers for setting various clocks to some default values. Also, this provides helpers to grant nonsecure access to a number of clocks. Bootloader may utilize these to make the system boot in a deterministic manner. Signed-off-by: Eero Nurkkala <eero.nurkkala@offcode.fi>
This commit is contained in:
parent
db24702fc5
commit
48cf91a7be
@ -158,7 +158,7 @@
|
|||||||
#define CCM_CR_AUTH_TZ_USER (1 << 8) /* Bit 8: Clock root can be changed in user mode (TZ_USER) */
|
#define CCM_CR_AUTH_TZ_USER (1 << 8) /* Bit 8: Clock root can be changed in user mode (TZ_USER) */
|
||||||
#define CCM_CR_AUTH_TZ_NS (1 << 9) /* Bit 9: Clock root can be changed in non-secure mode (TZ_NS) */
|
#define CCM_CR_AUTH_TZ_NS (1 << 9) /* Bit 9: Clock root can be changed in non-secure mode (TZ_NS) */
|
||||||
/* Bit 10: Reserved */
|
/* Bit 10: Reserved */
|
||||||
#define CCM_CR_AUTH_LOCK_TZ (1 << 11) /* Bit 1: Lock TrustZone settings (LOCK_TZ) */
|
#define CCM_CR_AUTH_LOCK_TZ (1 << 11) /* Bit 11: Lock TrustZone settings (LOCK_TZ) */
|
||||||
/* Bits 12-14: Reserved */
|
/* Bits 12-14: Reserved */
|
||||||
#define CCM_CR_AUTH_LOCK_LIST (1 << 12) /* Bit 15: Lock whitelist settings (LOCK_LIST) */
|
#define CCM_CR_AUTH_LOCK_LIST (1 << 12) /* Bit 15: Lock whitelist settings (LOCK_LIST) */
|
||||||
#define CCM_CR_AUTH_WHITE_LIST_SHIFT (16) /* Bits 16-31: Allow domains to change clock (WHITE_LIST) */
|
#define CCM_CR_AUTH_WHITE_LIST_SHIFT (16) /* Bits 16-31: Allow domains to change clock (WHITE_LIST) */
|
||||||
@ -337,6 +337,12 @@
|
|||||||
#define CCM_LPCG_AUTH_WHITE_LIST_SHIFT (16) /* Bits 16-31: Allow domains to change clock (WHITE_LIST) */
|
#define CCM_LPCG_AUTH_WHITE_LIST_SHIFT (16) /* Bits 16-31: Allow domains to change clock (WHITE_LIST) */
|
||||||
#define CCM_LPCG_AUTH_WHITE_LIST_MASK (0xffff << CCM_LPCG_AUTH_WHITE_LIST_SHIFT)
|
#define CCM_LPCG_AUTH_WHITE_LIST_MASK (0xffff << CCM_LPCG_AUTH_WHITE_LIST_SHIFT)
|
||||||
|
|
||||||
|
/* Auth access bits */
|
||||||
|
|
||||||
|
#define CCM_AUTH_TZ_USER(n) ((n) << 8)
|
||||||
|
#define CCM_AUTH_TZ_NS(n) ((n) << 9)
|
||||||
|
#define CCM_AUTH_LOCK_TZ(n) ((n) << 11)
|
||||||
|
|
||||||
/* Clock roots */
|
/* Clock roots */
|
||||||
|
|
||||||
#define CCM_CR_A55PERIPH 0 /* CLOCK Root Arm A55 Periph. */
|
#define CCM_CR_A55PERIPH 0 /* CLOCK Root Arm A55 Periph. */
|
||||||
@ -570,12 +576,14 @@
|
|||||||
#define CCM_SHARED_EXT_CLK 0
|
#define CCM_SHARED_EXT_CLK 0
|
||||||
#define CCM_SHARED_A55_CLK 1
|
#define CCM_SHARED_A55_CLK 1
|
||||||
#define CCM_SHARED_DRAM_CLK 2
|
#define CCM_SHARED_DRAM_CLK 2
|
||||||
|
#define CCM_SHARED_GPR_COUNT 7
|
||||||
|
|
||||||
/* Other parameters */
|
/* Other parameters */
|
||||||
|
|
||||||
#define ROOT_MUX_MAX 4 /* Count of root clock MUX options */
|
#define ROOT_MUX_MAX 4 /* Count of root clock MUX options */
|
||||||
#define CCM_CR_COUNT 94 /* Count of clock roots */
|
#define CCM_CR_COUNT 94 /* Count of clock roots */
|
||||||
#define CCM_LPCG_COUNT 126 /* Counte of clock gates */
|
#define CCM_LPCG_COUNT 126 /* Count of clock gates */
|
||||||
|
#define CCM_OSCPLL_COUNT 18 /* Count of osc plls */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@ -708,4 +716,30 @@ static const int g_ccm_root_mux[][ROOT_MUX_MAX] =
|
|||||||
{OSC_24M, AUDIO_PLL1OUT, VIDEO_PLL1OUT, SYS_PLL1PFD2}, /* Pal Came Scan */
|
{OSC_24M, AUDIO_PLL1OUT, VIDEO_PLL1OUT, SYS_PLL1PFD2}, /* Pal Came Scan */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CCM_ARM_A55_PERIPH_CLK_ROOT 0
|
||||||
|
#define CCM_ARM_A55_MTR_BUS_CLK_ROOT 1
|
||||||
|
#define CCM_ARM_A55_CLK_ROOT 2
|
||||||
|
#define CCM_M33_CLK_ROOT 3
|
||||||
|
#define CCM_ELE_CLK_ROOT 4
|
||||||
|
#define CCM_BUS_WAKEUP_CLK_ROOT 5
|
||||||
|
#define CCM_BUS_AON_CLK_ROOT 6
|
||||||
|
#define CCM_WAKEUP_AXI_CLK_ROOT 7
|
||||||
|
#define CCM_SWO_TRACE_CLK_ROOT 8
|
||||||
|
#define CCM_M33_SYSTICK_CLK_ROOT 9
|
||||||
|
#define CCM_NIC_CLK_ROOT 65
|
||||||
|
#define CCM_NIC_APB_CLK_ROOT 66
|
||||||
|
#define CCM_DRAM_ALT_CLK_ROOT 76
|
||||||
|
#define CCM_DRAM_APB_CLK_ROOT 77
|
||||||
|
#define CCM_CLK_ROOT_NUM 95
|
||||||
|
|
||||||
|
#define CCM_OSCPLL_END 19
|
||||||
|
#define CCM_CCGR_NUM 127
|
||||||
|
|
||||||
|
#define CCM_SHARED_GPR_DRAM_CLK 2
|
||||||
|
#define CCM_SHARED_GPR_DRAM_CLK_SEL_PLL 0
|
||||||
|
#define CCM_SHARED_GPR_DRAM_CLK_SEL_CCM BIT(0)
|
||||||
|
#define CCM_SHARED_GPR_NUM 8
|
||||||
|
|
||||||
|
#define MHZ(x) ((x) * 1000000UL)
|
||||||
|
|
||||||
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_CCM_H */
|
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX93_IMX93_CCM_H */
|
||||||
|
@ -49,6 +49,206 @@
|
|||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ccm_clk_src_tz_access
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Clock source access contol enable.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* pscll - Clock source
|
||||||
|
* non_secure - Grant non-secure access
|
||||||
|
* user_mode - Grant user mode access
|
||||||
|
* lock_tz - Lock settings
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int imx9_ccm_clk_src_tz_access(uint32_t oscpll, bool non_secure,
|
||||||
|
bool user_mode, bool lock_tz)
|
||||||
|
{
|
||||||
|
if (oscpll > CCM_OSCPLL_COUNT)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyreg32(IMX9_CCM_OSCPLL_AUTH(oscpll), 0,
|
||||||
|
CCM_AUTH_TZ_USER(user_mode) |
|
||||||
|
CCM_AUTH_TZ_NS(non_secure) |
|
||||||
|
CCM_AUTH_LOCK_TZ(lock_tz));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: ccm_clk_root_tz_access
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Root clock access control enable.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* clk_root_id - Root clock id
|
||||||
|
* non_secure - Grant non-secure access
|
||||||
|
* user_mode - Grant user mode access
|
||||||
|
* lock_tz - Lock settings
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int imx9_ccm_clk_root_tz_access(uint32_t clk_root_id, bool non_secure,
|
||||||
|
bool user_mode, bool lock_tz)
|
||||||
|
{
|
||||||
|
if (clk_root_id > CCM_CR_COUNT)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyreg32(IMX9_CCM_CR_AUTH(clk_root_id), 0,
|
||||||
|
CCM_AUTH_TZ_USER(user_mode) |
|
||||||
|
CCM_AUTH_TZ_NS(non_secure) |
|
||||||
|
CCM_AUTH_LOCK_TZ(lock_tz));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_lpcg_tz_access
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Low power clock gatig unit access enable.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* lpcg - Clock id
|
||||||
|
* non_secure - Grant non-secure access
|
||||||
|
* user_mode - Grant user mode access
|
||||||
|
* lock_tz - Lock settings
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int imx9_ccm_lpcg_tz_access(uint32_t lpcg, bool non_secure,
|
||||||
|
bool user_mode, bool lock_tz)
|
||||||
|
{
|
||||||
|
if (lpcg > CCM_LPCG_COUNT)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyreg32(IMX9_CCM_LPCG_AUTH(lpcg), 0,
|
||||||
|
CCM_AUTH_TZ_USER(user_mode) |
|
||||||
|
CCM_AUTH_TZ_NS(non_secure) |
|
||||||
|
CCM_AUTH_LOCK_TZ(lock_tz));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_shared_gpr_tz_access
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* General purpose access enable.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* grp - Gpr id
|
||||||
|
* non_secure - Grant non-secure access
|
||||||
|
* user_mode - Grant user mode access
|
||||||
|
* lock_tz - Lock settings
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int imx9_ccm_shared_gpr_tz_access(uint32_t gpr, bool non_secure,
|
||||||
|
bool user_mode, bool lock_tz)
|
||||||
|
{
|
||||||
|
if (gpr > CCM_SHARED_GPR_COUNT)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyreg32(IMX9_CCM_GPR_SH_AUTH(gpr), 0,
|
||||||
|
CCM_AUTH_TZ_USER(user_mode) |
|
||||||
|
CCM_AUTH_TZ_NS(non_secure) |
|
||||||
|
CCM_AUTH_LOCK_TZ(lock_tz));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_clock_prepare
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Prepares the clocks, grants non-secure access for clocks.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero on success, a negated error code otherwise
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int imx9_ccm_clock_prepare(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* allow for non-secure access */
|
||||||
|
|
||||||
|
for (i = 0; i < CCM_OSCPLL_END; i++)
|
||||||
|
{
|
||||||
|
ret = imx9_ccm_clk_src_tz_access(i, true, false, false);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < CCM_CLK_ROOT_NUM; i++)
|
||||||
|
{
|
||||||
|
ret = imx9_ccm_clk_root_tz_access(i, true, false, false);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < CCM_CCGR_NUM; i++)
|
||||||
|
{
|
||||||
|
ret = imx9_ccm_lpcg_tz_access(i, true, false, false);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < CCM_SHARED_GPR_NUM; i++)
|
||||||
|
{
|
||||||
|
ret = imx9_ccm_shared_gpr_tz_access(i, true, false, false);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -195,3 +395,166 @@ int imx9_ccm_gate_on(int gate, bool enabled)
|
|||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_shared_gpr_set
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set shared gpr clock register value
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gpr - General purpose clock index
|
||||||
|
* val - Value
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int imx9_ccm_shared_gpr_set(uint32_t gpr, uint32_t val)
|
||||||
|
{
|
||||||
|
if (gpr > CCM_SHARED_GPR_COUNT)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
putreg32(val, IMX9_CCM_GPR_SH(gpr));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_clock_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes bus clocks for a known default state.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success, a negated error value otherwise
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int imx9_ccm_clock_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = imx9_ccm_clock_prepare();
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set A55 clk to 500M. This clock root is normally used as intermediate
|
||||||
|
* clock source for A55 core / DSU when doing ARM PLL reconfig. Set it to
|
||||||
|
* 500 MHz.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_ARM_A55_CLK_ROOT, SYS_PLL1PFD0, 2);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set A55 periphal to 333 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_ARM_A55_PERIPH_CLK_ROOT,
|
||||||
|
SYS_PLL1PFD0, 3);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set A55 mtr bus to 133 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_ARM_A55_MTR_BUS_CLK_ROOT,
|
||||||
|
SYS_PLL1PFD1DIV2, 3);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ELE to 200 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_ELE_CLK_ROOT, SYS_PLL1PFD1DIV2, 2);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bus_wakeup to 133 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_BUS_WAKEUP_CLK_ROOT,
|
||||||
|
SYS_PLL1PFD1DIV2, 3);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bus_AON to 133 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_BUS_AON_CLK_ROOT, SYS_PLL1PFD1DIV2,
|
||||||
|
3);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* M33 to 200 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_M33_CLK_ROOT, SYS_PLL1PFD1DIV2, 2);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WAKEUP_AXI to 312.5 MHz, because of FEC only can support to 320M for
|
||||||
|
* generating MII clock at 2.5 MHz
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_WAKEUP_AXI_CLK_ROOT, SYS_PLL1PFD2,
|
||||||
|
2);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SWO TRACE to 133 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_SWO_TRACE_CLK_ROOT,
|
||||||
|
SYS_PLL1PFD1DIV2, 3);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* M33 systetick to 24 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_M33_SYSTICK_CLK_ROOT, OSC_24M, 1);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NIC to 400 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_NIC_CLK_ROOT, SYS_PLL1PFD1, 2);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NIC_APB to 133 MHz */
|
||||||
|
|
||||||
|
ret = imx9_ccm_configure_root_clock(CCM_NIC_APB_CLK_ROOT, SYS_PLL1PFD1DIV2,
|
||||||
|
3);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
@ -85,4 +85,38 @@ int imx9_ccm_root_clock_on(int root, bool enabled);
|
|||||||
|
|
||||||
int imx9_ccm_gate_on(int gate, bool enabled);
|
int imx9_ccm_gate_on(int gate, bool enabled);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_shared_gpr_set
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Set shared gpr clock register value
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* gpr - General purpose clock index
|
||||||
|
* val - Value
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) is returned on success. A negated errno value is returned on
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int imx9_ccm_shared_gpr_set(uint32_t gpr, uint32_t val);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_clock_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes bus clocks for a known default state.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success, a negated error value otherwise
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int imx9_ccm_clock_init(void);
|
||||||
|
|
||||||
#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_CCM_H */
|
#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_CCM_H */
|
||||||
|
@ -67,6 +67,11 @@ static int pll_init(uintptr_t reg, bool frac, struct pll_parms_s *parm)
|
|||||||
{
|
{
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
|
if (!frac)
|
||||||
|
{
|
||||||
|
modifyreg32(PLL_CLR(PLL_CTRL(reg)), 0, PLL_CTRL_HW_CTRL_SEL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Bypass and disable PLL */
|
/* Bypass and disable PLL */
|
||||||
|
|
||||||
putreg32(PLL_CTRL_CLKMUX_BYPASS, PLL_SET(PLL_CTRL(reg)));
|
putreg32(PLL_CTRL_CLKMUX_BYPASS, PLL_SET(PLL_CTRL(reg)));
|
||||||
@ -80,14 +85,15 @@ static int pll_init(uintptr_t reg, bool frac, struct pll_parms_s *parm)
|
|||||||
|
|
||||||
putreg32(val, PLL_DIV(reg));
|
putreg32(val, PLL_DIV(reg));
|
||||||
|
|
||||||
/* Disable spread spectrum */
|
|
||||||
|
|
||||||
putreg32(PLL_SPREAD_SPECTRUM_ENABLE, PLL_CLR(PLL_SPREAD_SPECTRUM(reg)));
|
|
||||||
|
|
||||||
/* Set the fractional parts */
|
/* Set the fractional parts */
|
||||||
|
|
||||||
if (frac)
|
if (frac)
|
||||||
{
|
{
|
||||||
|
/* Disable spread spectrum */
|
||||||
|
|
||||||
|
putreg32(PLL_SPREAD_SPECTRUM_ENABLE,
|
||||||
|
PLL_CLR(PLL_SPREAD_SPECTRUM(reg)));
|
||||||
|
|
||||||
putreg32(PLL_NUMERATOR_MFN(parm->mfn), PLL_NUMERATOR(reg));
|
putreg32(PLL_NUMERATOR_MFN(parm->mfn), PLL_NUMERATOR(reg));
|
||||||
putreg32(PLL_DENOMINATOR_MFD(parm->mfd), PLL_DENOMINATOR(reg));
|
putreg32(PLL_DENOMINATOR_MFD(parm->mfd), PLL_DENOMINATOR(reg));
|
||||||
}
|
}
|
||||||
@ -108,6 +114,7 @@ static int pll_init(uintptr_t reg, bool frac, struct pll_parms_s *parm)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IMX9_CFG_PLLS
|
||||||
static int pll_pfd_init(uintptr_t reg, int pfd, struct pfd_parms_s *pfdparm)
|
static int pll_pfd_init(uintptr_t reg, int pfd, struct pfd_parms_s *pfdparm)
|
||||||
{
|
{
|
||||||
uint32_t ctrl;
|
uint32_t ctrl;
|
||||||
@ -175,6 +182,7 @@ static int pll_pfd_init(uintptr_t reg, int pfd, struct pfd_parms_s *pfdparm)
|
|||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_IMX9_CFG_PLLS */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint32_t calculate_vco_freq(const struct pll_parms_s *parm, bool frac)
|
static uint32_t calculate_vco_freq(const struct pll_parms_s *parm, bool frac)
|
||||||
@ -352,6 +360,34 @@ static uint32_t pll_pfd_freq_out(uintptr_t reg, int pfd, int div2)
|
|||||||
return ((uint64_t)vco * 5) / (parm.mfi * 5 + parm.mfn) / div2;
|
return ((uint64_t)vco * 5) / (parm.mfi * 5 + parm.mfn) / div2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: imx9_ccm_dram_disable_bypass
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Disable clock bypass
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*>
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_IMX9_BOOTLOADER
|
||||||
|
static void imx9_dram_disable_bypass(void)
|
||||||
|
{
|
||||||
|
/* Set DRAM APB to 133Mhz */
|
||||||
|
|
||||||
|
imx9_ccm_configure_root_clock(CCM_DRAM_APB_CLK_ROOT, SYS_PLL1PFD1DIV2, 3);
|
||||||
|
|
||||||
|
/* Switch from DRAM clock root from CCM to PLL */
|
||||||
|
|
||||||
|
imx9_ccm_shared_gpr_set(CCM_SHARED_GPR_DRAM_CLK,
|
||||||
|
CCM_SHARED_GPR_DRAM_CLK_SEL_PLL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -369,10 +405,13 @@ static uint32_t pll_pfd_freq_out(uintptr_t reg, int pfd, int div2)
|
|||||||
void imx9_clockconfig(void)
|
void imx9_clockconfig(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_IMX9_BOOTLOADER
|
#ifdef CONFIG_IMX9_BOOTLOADER
|
||||||
|
struct imx9_pll_cfg_s pll_arm = ARMPLL_CFG;
|
||||||
|
struct imx9_pll_cfg_s pll_ddr = DRAMPLL_CFG;
|
||||||
|
#ifdef CONFIG_IMX9_CFG_PLLS
|
||||||
struct imx9_pll_cfg_s pll_cfgs[] = PLL_CFGS;
|
struct imx9_pll_cfg_s pll_cfgs[] = PLL_CFGS;
|
||||||
struct imx9_pfd_cfg_s pfd_cfgs[] = PFD_CFGS;
|
struct imx9_pfd_cfg_s pfd_cfgs[] = PFD_CFGS;
|
||||||
struct imx9_pll_cfg_s pll_arm = ARMPLL_CFG;
|
|
||||||
int i;
|
int i;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set the CPU clock */
|
/* Set the CPU clock */
|
||||||
|
|
||||||
@ -380,6 +419,13 @@ void imx9_clockconfig(void)
|
|||||||
pll_init(pll_arm.reg, pll_arm.frac, &pll_arm.parms);
|
pll_init(pll_arm.reg, pll_arm.frac, &pll_arm.parms);
|
||||||
putreg32(CCM_GPR_A55_CLK_SEL_PLL, IMX9_CCM_GPR_SH_SET(CCM_SHARED_A55_CLK));
|
putreg32(CCM_GPR_A55_CLK_SEL_PLL, IMX9_CCM_GPR_SH_SET(CCM_SHARED_A55_CLK));
|
||||||
|
|
||||||
|
/* DRAM clk to 933 MHz */
|
||||||
|
|
||||||
|
pll_init(pll_ddr.reg, pll_ddr.frac, &pll_ddr.parms);
|
||||||
|
imx9_dram_disable_bypass();
|
||||||
|
|
||||||
|
#ifdef CONFIG_IMX9_CFG_PLLS
|
||||||
|
|
||||||
/* Run the PLL configuration */
|
/* Run the PLL configuration */
|
||||||
|
|
||||||
for (i = 0; i < nitems(pll_cfgs); i++)
|
for (i = 0; i < nitems(pll_cfgs); i++)
|
||||||
@ -396,6 +442,7 @@ void imx9_clockconfig(void)
|
|||||||
pll_pfd_init(cfg->reg, cfg->pfd, &cfg->parms);
|
pll_pfd_init(cfg->reg, cfg->pfd, &cfg->parms);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* CONFIG_IMX9_BOOTLOADER */
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ARMPLL_CFG PLL_CFG(IMX9_ARMPLL_BASE, false, PLL_PARMS(1, 2, 141, 0, 0))
|
#define ARMPLL_CFG PLL_CFG(IMX9_ARMPLL_BASE, false, PLL_PARMS(1, 2, 141, 0, 0))
|
||||||
#define DRAMPLL_CFG PLL_CFG(IMX9_DRAMPLL_BASE, true, PLL_PARMS(1, 2, 155, 1, 2))
|
#define DRAMPLL_CFG PLL_CFG(IMX9_DRAMPLL_BASE, true, PLL_PARMS(1, 4, 155, 1, 2))
|
||||||
|
|
||||||
#define PLL_CFGS \
|
#define PLL_CFGS \
|
||||||
{ \
|
{ \
|
||||||
|
Loading…
Reference in New Issue
Block a user