From e7619554173a9d9f72dc19f97a804afea135f07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 14 Aug 2012 10:32:54 +0000 Subject: mx35: Fix decode_pll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MFN bit-field of the PLL registers represents a signed value. See the reference manual. Signed-off-by: Benoît Thébaudeau Cc: Stefano Babic --- arch/arm/cpu/arm1136/mx35/generic.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/arm/cpu/arm1136/mx35/generic.c') diff --git a/arch/arm/cpu/arm1136/mx35/generic.c b/arch/arm/cpu/arm1136/mx35/generic.c index d435e8af69..de7503c015 100644 --- a/arch/arm/cpu/arm1136/mx35/generic.c +++ b/arch/arm/cpu/arm1136/mx35/generic.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include @@ -129,15 +130,17 @@ static int get_ahb_div(u32 pdr0) static u32 decode_pll(u32 reg, u32 infreq) { u32 mfi = (reg >> 10) & 0xf; - u32 mfn = reg & 0x3f; - u32 mfd = (reg >> 16) & 0x3f; + s32 mfn = reg & 0x3ff; + u32 mfd = (reg >> 16) & 0x3ff; u32 pd = (reg >> 26) & 0xf; mfi = mfi <= 5 ? 5 : mfi; + mfn = mfn >= 512 ? mfn - 1024 : mfn; mfd += 1; pd += 1; - return ((2 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000; + return lldiv(2 * (u64)infreq * (mfi * mfd + mfn), + mfd * pd); } static u32 get_mcu_main_clk(void) -- cgit v1.2.1 From 82e1b543b51fb514731992eeb2a6bdcdc279950e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 14 Aug 2012 10:33:27 +0000 Subject: mx35: Fix clock dividers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clock dividers that were used do not match at all the reference manual. They were either completely broken, or came from an early silicon revision incompatible with the current one. Signed-off-by: Benoît Thébaudeau Cc: Stefano Babic --- arch/arm/cpu/arm1136/mx35/generic.c | 48 ++++++++++++++----------------------- 1 file changed, 18 insertions(+), 30 deletions(-) (limited to 'arch/arm/cpu/arm1136/mx35/generic.c') diff --git a/arch/arm/cpu/arm1136/mx35/generic.c b/arch/arm/cpu/arm1136/mx35/generic.c index de7503c015..e4b07d0744 100644 --- a/arch/arm/cpu/arm1136/mx35/generic.c +++ b/arch/arm/cpu/arm1136/mx35/generic.c @@ -174,17 +174,14 @@ static u32 get_ipg_per_clk(void) u32 pdr4 = readl(&ccm->pdr4); u32 div; if (pdr0 & MXC_CCM_PDR0_PER_SEL) { - div = (CCM_GET_DIVIDER(pdr4, - MXC_CCM_PDR4_PER0_PRDF_MASK, - MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1) * - (CCM_GET_DIVIDER(pdr4, + div = CCM_GET_DIVIDER(pdr4, MXC_CCM_PDR4_PER0_PODF_MASK, - MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1); + MXC_CCM_PDR4_PER0_PODF_OFFSET) + 1; } else { div = CCM_GET_DIVIDER(pdr0, MXC_CCM_PDR0_PER_PODF_MASK, MXC_CCM_PDR0_PER_PODF_OFFSET) + 1; - freq /= get_ahb_div(pdr0); + div *= get_ahb_div(pdr0); } return freq / div; } @@ -202,19 +199,16 @@ u32 imx_get_uartclk(void) freq = decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ); } - freq /= ((CCM_GET_DIVIDER(pdr4, - MXC_CCM_PDR4_UART_PRDF_MASK, - MXC_CCM_PDR4_UART_PRDF_OFFSET) + 1) * - (CCM_GET_DIVIDER(pdr4, + freq /= CCM_GET_DIVIDER(pdr4, MXC_CCM_PDR4_UART_PODF_MASK, - MXC_CCM_PDR4_UART_PODF_OFFSET) + 1)); + MXC_CCM_PDR4_UART_PODF_OFFSET) + 1; return freq; } unsigned int mxc_get_main_clock(enum mxc_main_clock clk) { u32 nfc_pdf, hsp_podf; - u32 pll, ret_val = 0, usb_prdf, usb_podf; + u32 pll, ret_val = 0, usb_podf; struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; @@ -258,8 +252,7 @@ unsigned int mxc_get_main_clock(enum mxc_main_clock clk) ret_val = pll / (nfc_pdf + 1); break; case USB_CLK: - usb_prdf = (reg4 >> 25) & 0x7; - usb_podf = (reg4 >> 22) & 0x7; + usb_podf = (reg4 >> 22) & 0x3F; if (reg4 & 0x200) { pll = get_mcu_main_clk(); } else { @@ -267,7 +260,7 @@ unsigned int mxc_get_main_clock(enum mxc_main_clock clk) CONFIG_MX35_HCLK_FREQ); } - ret_val = pll / ((usb_prdf + 1) * (usb_podf + 1)); + ret_val = pll / (usb_podf + 1); break; default: printf("Unknown clock: %d\n", clk); @@ -290,11 +283,10 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) case UART2_BAUD: case UART3_BAUD: clk_sel = mpdr3 & (1 << 14); - pre_pdf = (mpdr4 >> 13) & 0x7; - pdf = (mpdr4 >> 10) & 0x7; + pdf = (mpdr4 >> 10) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - ((pre_pdf + 1) * (pdf + 1)); + (pdf + 1); break; case SSI1_BAUD: pre_pdf = (mpdr2 >> 24) & 0x7; @@ -314,11 +306,10 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) break; case CSI_BAUD: clk_sel = mpdr2 & (1 << 7); - pre_pdf = (mpdr2 >> 16) & 0x7; - pdf = (mpdr2 >> 19) & 0x7; + pdf = (mpdr2 >> 16) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - ((pre_pdf + 1) * (pdf + 1)); + (pdf + 1); break; case MSHC_CLK: pre_pdf = readl(&ccm->pdr1); @@ -331,27 +322,24 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) break; case ESDHC1_CLK: clk_sel = mpdr3 & 0x40; - pre_pdf = mpdr3 & 0x7; - pdf = (mpdr3>>3) & 0x7; + pdf = mpdr3 & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - ((pre_pdf + 1) * (pdf + 1)); + (pdf + 1); break; case ESDHC2_CLK: clk_sel = mpdr3 & 0x40; - pre_pdf = (mpdr3 >> 8) & 0x7; - pdf = (mpdr3 >> 11) & 0x7; + pdf = (mpdr3 >> 8) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - ((pre_pdf + 1) * (pdf + 1)); + (pdf + 1); break; case ESDHC3_CLK: clk_sel = mpdr3 & 0x40; - pre_pdf = (mpdr3 >> 16) & 0x7; - pdf = (mpdr3 >> 19) & 0x7; + pdf = (mpdr3 >> 16) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - ((pre_pdf + 1) * (pdf + 1)); + (pdf + 1); break; case SPDIF_CLK: clk_sel = mpdr3 & 0x400000; -- cgit v1.2.1 From 9c6c5c06764b7762a016b0ede002511139166fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Tue, 21 Aug 2012 11:07:20 +0000 Subject: mx35: Define default SoC input clock frequencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define default SoC input clock frequencies for i.MX35 in order to get rid of duplicated definitions. Signed-off-by: Benoît Thébaudeau Cc: Stefano Babic Acked-by: Stefano Babic --- arch/arm/cpu/arm1136/mx35/generic.c | 43 ++++++++++++++----------------------- 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'arch/arm/cpu/arm1136/mx35/generic.c') diff --git a/arch/arm/cpu/arm1136/mx35/generic.c b/arch/arm/cpu/arm1136/mx35/generic.c index e4b07d0744..ef65176eed 100644 --- a/arch/arm/cpu/arm1136/mx35/generic.c +++ b/arch/arm/cpu/arm1136/mx35/generic.c @@ -149,9 +149,7 @@ static u32 get_mcu_main_clk(void) struct ccm_regs *ccm = (struct ccm_regs *)IMX_CCM_BASE; arm_div = get_arm_div(readl(&ccm->pdr0), &fi, &fd); - fi *= - decode_pll(readl(&ccm->mpctl), - CONFIG_MX35_HCLK_FREQ); + fi *= decode_pll(readl(&ccm->mpctl), MXC_HCLK); return fi / (arm_div * fd); } @@ -193,12 +191,10 @@ u32 imx_get_uartclk(void) (struct ccm_regs *)IMX_CCM_BASE; u32 pdr4 = readl(&ccm->pdr4); - if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U) { + if (readl(&ccm->pdr3) & MXC_CCM_PDR3_UART_M_U) freq = get_mcu_main_clk(); - } else { - freq = decode_pll(readl(&ccm->ppctl), - CONFIG_MX35_HCLK_FREQ); - } + else + freq = decode_pll(readl(&ccm->ppctl), MXC_HCLK); freq /= CCM_GET_DIVIDER(pdr4, MXC_CCM_PDR4_UART_PODF_MASK, MXC_CCM_PDR4_UART_PODF_OFFSET) + 1; @@ -253,12 +249,10 @@ unsigned int mxc_get_main_clock(enum mxc_main_clock clk) break; case USB_CLK: usb_podf = (reg4 >> 22) & 0x3F; - if (reg4 & 0x200) { + if (reg4 & 0x200) pll = get_mcu_main_clk(); - } else { - pll = decode_pll(readl(&ccm->ppctl), - CONFIG_MX35_HCLK_FREQ); - } + else + pll = decode_pll(readl(&ccm->ppctl), MXC_HCLK); ret_val = pll / (usb_podf + 1); break; @@ -285,15 +279,14 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) clk_sel = mpdr3 & (1 << 14); pdf = (mpdr4 >> 10) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - (pdf + 1); + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); break; case SSI1_BAUD: pre_pdf = (mpdr2 >> 24) & 0x7; pdf = mpdr2 & 0x3F; clk_sel = mpdr2 & (1 << 6); ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / ((pre_pdf + 1) * (pdf + 1)); break; case SSI2_BAUD: @@ -301,15 +294,14 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) pdf = (mpdr2 >> 8) & 0x3F; clk_sel = mpdr2 & (1 << 6); ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / ((pre_pdf + 1) * (pdf + 1)); break; case CSI_BAUD: clk_sel = mpdr2 & (1 << 7); pdf = (mpdr2 >> 16) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - (pdf + 1); + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); break; case MSHC_CLK: pre_pdf = readl(&ccm->pdr1); @@ -317,36 +309,33 @@ unsigned int mxc_get_peri_clock(enum mxc_peri_clock clk) pdf = (pre_pdf >> 22) & 0x3F; pre_pdf = (pre_pdf >> 28) & 0x7; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / ((pre_pdf + 1) * (pdf + 1)); break; case ESDHC1_CLK: clk_sel = mpdr3 & 0x40; pdf = mpdr3 & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - (pdf + 1); + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); break; case ESDHC2_CLK: clk_sel = mpdr3 & 0x40; pdf = (mpdr3 >> 8) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - (pdf + 1); + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); break; case ESDHC3_CLK: clk_sel = mpdr3 & 0x40; pdf = (mpdr3 >> 16) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / - (pdf + 1); + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); break; case SPDIF_CLK: clk_sel = mpdr3 & 0x400000; pre_pdf = (mpdr3 >> 29) & 0x7; pdf = (mpdr3 >> 23) & 0x3F; ret_val = ((clk_sel != 0) ? mxc_get_main_clock(CPU_CLK) : - decode_pll(readl(&ccm->ppctl), CONFIG_MX35_HCLK_FREQ)) / + decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / ((pre_pdf + 1) * (pdf + 1)); break; default: -- cgit v1.2.1