From f2940f3e80beb11e9e0c317e5b748ec0c92b116f Mon Sep 17 00:00:00 2001 From: Ye Li Date: Tue, 31 Jan 2023 16:42:25 +0800 Subject: [PATCH] imx: imx8ulp: Update clocks to meet max rate restrictions Update PLL3/PLL4 PFD and USDHC clocks to meet maximum frequency restrictions. Detail clock rate changes in the patch: PLL3 PFD2: 389M -> 324M PLL3 PFD3: 336M -> 389M PLL3 PFD3: DIV1 336M -> 389M (OD), 194M (ND/LD) PLL3 PFD3: DIV2 336M -> 194M (OD), 97M (ND/LD) PLL4 PFD0: 792M -> 594M PLL4 PFD2: 792M -> 316.8M NIC_AP: 96M (ND) -> 192M, 48M (LD) -> 96M NIC_LPAV: 198 (ND) -> 192M, 99M (LD) -> 96M USDHC0: PLL3 PFD3 DIV1, 389M (OD), 194M (ND/LD) USDHC1: PLL3 PFD3 DIV2, 194M (OD), 97M (ND/LD) USDHC2: PLL3 PFD3 DIV2, 194M (OD), 97M (ND/LD) Signed-off-by: Ye Li Reviewed-by: Peng Fan --- arch/arm/mach-imx/imx8ulp/cgc.c | 71 +++++++++++++++++-------------- arch/arm/mach-imx/imx8ulp/clock.c | 50 +++++++++------------- 2 files changed, 57 insertions(+), 64 deletions(-) diff --git a/arch/arm/mach-imx/imx8ulp/cgc.c b/arch/arm/mach-imx/imx8ulp/cgc.c index 104109e693..d2fadb4877 100644 --- a/arch/arm/mach-imx/imx8ulp/cgc.c +++ b/arch/arm/mach-imx/imx8ulp/cgc.c @@ -136,42 +136,34 @@ void cgc1_pll3_init(ulong freq) clrbits_le32(&cgc1_regs->pll3div_vco, BIT(7)); clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F); - - if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 0); - clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 3 << 21); /* 195M */ - } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { - setbits_le32(&cgc1_regs->pll3pfdcfg, 21 << 0); - clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21); /* 231M */ - } else { - setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* 324M */ - } - + setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 0); /* PFD0 324M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(7)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(6))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 8); - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8); + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 8); /* PFD1 389M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(15)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(14))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 16); - setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 16); + setbits_le32(&cgc1_regs->pll3pfdcfg, 30 << 16); /* PFD2 324M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(23)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(22))) ; clrbits_le32(&cgc1_regs->pll3pfdcfg, 0x3F << 24); - setbits_le32(&cgc1_regs->pll3pfdcfg, 29 << 24); + setbits_le32(&cgc1_regs->pll3pfdcfg, 25 << 24); /* PFD3 389M */ clrbits_le32(&cgc1_regs->pll3pfdcfg, BIT(31)); while (!(readl(&cgc1_regs->pll3pfdcfg) & BIT(30))) ; clrbits_le32(&cgc1_regs->pll3div_pfd0, 0x3f3f3f3f); - clrbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f); - + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) + clrsetbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f, 0x03010000); /* Set PFD3 DIV1 to 194M, PFD3 DIV2 to 97M */ + else + clrsetbits_le32(&cgc1_regs->pll3div_pfd1, 0x3f3f3f3f, 0x01000000); /* Set PFD3 DIV1 to 389M, PFD3 DIV2 to 194M */ clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(7)); clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(15)); clrbits_le32(&cgc1_regs->pll3div_pfd0, BIT(23)); @@ -182,6 +174,17 @@ void cgc1_pll3_init(ulong freq) clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(23)); clrbits_le32(&cgc1_regs->pll3div_pfd1, BIT(31)); + /* NIC_AP: + * OD source PLL3 PFD0, 324M + * ND source FRO192, 192M + * LD source FRO192, 96M + */ + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { + clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21), 1 << 21); + } else { + clrbits_le32(&cgc1_regs->nicclk, GENMASK(26, 21)); + } + if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { /* nicclk select pll3 pfd0 */ clrsetbits_le32(&cgc1_regs->nicclk, GENMASK(29, 28), BIT(28)); @@ -222,20 +225,9 @@ void cgc2_pll4_init(bool pll4_reset) /* Enable all 4 PFDs */ setbits_le32(&cgc2_regs->pll4pfdcfg, 18 << 0); /* 528 */ - if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8); - /* 99Mhz for NIC_LPAV */ - clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 3 << 21); - } else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 8); - /* 198Mhz for NIC_LPAV */ - clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21); - } else { - setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */ - clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21)); - } - setbits_le32(&cgc2_regs->pll4pfdcfg, 12 << 16); /* 792 */ - setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396 */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 8); /* 316.8Mhz for NIC_LPAV */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 30 << 16); /* 316.8Mhz */ + setbits_le32(&cgc2_regs->pll4pfdcfg, 24 << 24); /* 396Mhz */ clrbits_le32(&cgc2_regs->pll4pfdcfg, BIT(7) | BIT(15) | BIT(23) | BIT(31)); @@ -247,9 +239,22 @@ void cgc2_pll4_init(bool pll4_reset) clrbits_le32(&cgc2_regs->pll4div_pfd0, BIT(7) | BIT(15) | BIT(23) | BIT(31)); clrbits_le32(&cgc2_regs->pll4div_pfd1, BIT(7) | BIT(15) | BIT(23) | BIT(31)); - clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28)); - while (!(readl(&cgc2_regs->niclpavclk) & BIT(27))) - ; + /* NIC_LPAV: + * OD source PLL4 PFD1, 316.8M + * ND source FRO192, 192M + * LD source FRO192, 96M + */ + if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) { + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21), 1 << 21); + } else { + clrbits_le32(&cgc2_regs->niclpavclk, GENMASK(26, 21)); + } + + if (!IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) && !IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { + clrsetbits_le32(&cgc2_regs->niclpavclk, GENMASK(29, 28), BIT(28)); + while (!(readl(&cgc2_regs->niclpavclk) & BIT(27))) + ; + } } void cgc2_pll4_pfd_config(enum cgc_clk pllpfd, u32 pfd) diff --git a/arch/arm/mach-imx/imx8ulp/clock.c b/arch/arm/mach-imx/imx8ulp/clock.c index 3e88f4633c..36d12943a0 100644 --- a/arch/arm/mach-imx/imx8ulp/clock.c +++ b/arch/arm/mach-imx/imx8ulp/clock.c @@ -182,37 +182,20 @@ void clock_init_late(void) */ cgc1_pll3_init(540672000); - if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE) || IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) { - pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD2_DIV2); - pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV2); - pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV2); - pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); - } else { - pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD1_DIV2); - pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD2_DIV1); - pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); - - pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); - pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD2_DIV1); - pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); - pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); - } + pcc_clock_enable(4, SDHC0_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC0_PCC4_SLOT, PLL3_PFD3_DIV1); /* 389M for OD, 194M for LD/ND*/ + pcc_clock_enable(4, SDHC0_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC0_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC1_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC1_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND */ + pcc_clock_enable(4, SDHC1_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC1_PCC4_SLOT, false); + + pcc_clock_enable(4, SDHC2_PCC4_SLOT, false); + pcc_clock_sel(4, SDHC2_PCC4_SLOT, PLL3_PFD3_DIV2); /* 194M for OD, 97M for LD/ND*/ + pcc_clock_enable(4, SDHC2_PCC4_SLOT, true); + pcc_reset_peripheral(4, SDHC2_PCC4_SLOT, false); /* enable MU0_MUB clock before access the register of MU0_MUB */ pcc_clock_enable(3, MU0_B_PCC3_SLOT, true); @@ -425,6 +408,8 @@ void reset_lcdclk(void) pcc_reset_peripheral(5, DCNANO_PCC5_SLOT, true); } +/* PLL4 PFD0 max frequency */ +#define PLL4_PFD0_MAX_RATE 600000 /*khz*/ void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz) { u8 pcd, best_pcd = 0; @@ -443,6 +428,9 @@ void mxs_set_lcdclk(u32 base_addr, u32 freq_in_khz) for (div = 1; div <= 64; div++) { parent_rate = pll4_rate; parent_rate = parent_rate * 18 / pfd; + if (parent_rate > PLL4_PFD0_MAX_RATE) + continue; + parent_rate = parent_rate / div; for (pcd = 0; pcd < 8; pcd++) { -- 2.39.5