#include <asm/arch/clk.h>
#include <asm/arch/periph.h>
+#define PLL_DIV_1024 1024
+#define PLL_DIV_65535 65535
+#define PLL_DIV_65536 65536
+
/* *
* This structure is to store the src bit, div bit and prediv bit
* positions of the peripheral clocks of the src and div registers
static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
{
unsigned long m, p, s = 0, mask, fout;
+ unsigned int div;
unsigned int freq;
/*
* APLL_CON: MIDV [25:16]
if (pllreg == EPLL) {
k = k & 0xffff;
/* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
- fout = (m + k / 65536) * (freq / (p * (1 << s)));
+ fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
} else if (pllreg == VPLL) {
k = k & 0xfff;
- /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
- fout = (m + k / 1024) * (freq / (p * (1 << s)));
+
+ /*
+ * Exynos4210
+ * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
+ *
+ * Exynos4412
+ * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
+ *
+ * Exynos5250
+ * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
+ */
+ if (proid_is_exynos4210())
+ div = PLL_DIV_1024;
+ else if (proid_is_exynos4412())
+ div = PLL_DIV_65535;
+ else if (proid_is_exynos5250())
+ div = PLL_DIV_65536;
+ else
+ return 0;
+
+ fout = (m + k / div) * (freq / (p * (1 << s)));
} else {
- /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */
- fout = m * (freq / (p * (1 << s)));
+ /*
+ * Exynos4210
+ * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
+ *
+ * Exynos4412 / Exynos5250
+ * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
+ */
+ if (proid_is_exynos4210())
+ fout = m * (freq / (p * (1 << s)));
+ else
+ fout = m * (freq / (p * (1 << (s - 1))));
}
return fout;