|
|
|
@ -24,6 +24,7 @@ |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include <common.h> |
|
|
|
|
#include <div64.h> |
|
|
|
|
#include <asm/io.h> |
|
|
|
|
#include <asm/errno.h> |
|
|
|
|
#include <asm/arch/imx-regs.h> |
|
|
|
@ -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) |
|
|
|
@ -146,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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -171,17 +172,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; |
|
|
|
|
} |
|
|
|
@ -193,25 +191,20 @@ 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); |
|
|
|
|
} |
|
|
|
|
freq /= ((CCM_GET_DIVIDER(pdr4, |
|
|
|
|
MXC_CCM_PDR4_UART_PRDF_MASK, |
|
|
|
|
MXC_CCM_PDR4_UART_PRDF_OFFSET) + 1) * |
|
|
|
|
(CCM_GET_DIVIDER(pdr4, |
|
|
|
|
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)); |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
@ -255,16 +248,13 @@ 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; |
|
|
|
|
if (reg4 & 0x200) { |
|
|
|
|
usb_podf = (reg4 >> 22) & 0x3F; |
|
|
|
|
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_prdf + 1) * (usb_podf + 1)); |
|
|
|
|
ret_val = pll / (usb_podf + 1); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
printf("Unknown clock: %d\n", clk); |
|
|
|
@ -287,18 +277,16 @@ 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)); |
|
|
|
|
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: |
|
|
|
@ -306,16 +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); |
|
|
|
|
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)); |
|
|
|
|
decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (pdf + 1); |
|
|
|
|
break; |
|
|
|
|
case MSHC_CLK: |
|
|
|
|
pre_pdf = readl(&ccm->pdr1); |
|
|
|
@ -323,39 +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; |
|
|
|
|
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)); |
|
|
|
|
decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (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)); |
|
|
|
|
decode_pll(readl(&ccm->ppctl), MXC_HCLK)) / (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)); |
|
|
|
|
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: |
|
|
|
|