arm: am33xx: Add support for mulitiple PLL input frequencies

am335x supports various sysclk frequencies which can be determined
using sysboot pins. PLLs should be configures based on this
sysclk frequency. Add PLL configurations for all supported
frequencies.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
diff --git a/arch/arm/include/asm/arch-am33xx/clock.h b/arch/arm/include/asm/arch-am33xx/clock.h
index acf3fd5..19ccf5c 100644
--- a/arch/arm/include/asm/arch-am33xx/clock.h
+++ b/arch/arm/include/asm/arch-am33xx/clock.h
@@ -12,6 +12,7 @@
 #define _CLOCKS_H_
 
 #include <asm/arch/clocks_am33xx.h>
+#include <asm/arch/hardware.h>
 
 #ifdef CONFIG_TI81XX
 #include <asm/arch/clock_ti81xx.h>
@@ -103,6 +104,12 @@
 extern const struct dpll_regs dpll_core_regs;
 extern const struct dpll_regs dpll_per_regs;
 extern const struct dpll_regs dpll_ddr_regs;
+extern const struct dpll_params dpll_mpu_opp[NUM_CRYSTAL_FREQ][NUM_OPPS];
+extern const struct dpll_params dpll_core_1000MHz[NUM_CRYSTAL_FREQ];
+extern const struct dpll_params dpll_per_192MHz[NUM_CRYSTAL_FREQ];
+extern const struct dpll_params dpll_ddr2_266MHz[NUM_CRYSTAL_FREQ];
+extern const struct dpll_params dpll_ddr3_303MHz[NUM_CRYSTAL_FREQ];
+extern const struct dpll_params dpll_ddr3_400MHz[NUM_CRYSTAL_FREQ];
 
 extern struct cm_wkuppll *const cmwkup;
 
diff --git a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
index dfdb6c7..653ec1b 100644
--- a/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
+++ b/arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
@@ -26,6 +26,8 @@
 #define CM_DLL_CTRL_NO_OVERRIDE	0x0
 #define CM_DLL_READYST		0x4
 
+#define NUM_OPPS	6
+
 extern void enable_dmm_clocks(void);
 extern const struct dpll_params dpll_core_opp100;
 extern struct dpll_params dpll_mpu_opp100;
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index dd950e5..3437e61 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -61,5 +61,18 @@
 /* CPSW Config space */
 #define CPSW_BASE			0x4A100000
 
+/* Control status register */
+#define CTRL_CRYSTAL_FREQ_SRC_MASK		(1 << 31)
+#define CTRL_CRYSTAL_FREQ_SRC_SHIFT		31
+#define CTRL_CRYSTAL_FREQ_SELECTION_MASK	(0x3 << 29)
+#define CTRL_CRYSTAL_FREQ_SELECTION_SHIFT	29
+#define CTRL_SYSBOOT_15_14_MASK			(0x3 << 22)
+#define CTRL_SYSBOOT_15_14_SHIFT		22
+
+#define CTRL_CRYSTAL_FREQ_SRC_SYSBOOT		0x0
+#define CTRL_CRYSTAL_FREQ_SRC_EFUSE		0x1
+
+#define NUM_CRYSTAL_FREQ			0x4
+
 int clk_get(int clk);
 #endif /* __AM33XX_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h b/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
index a7da6b5..af69ac6 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware_am43xx.h
@@ -85,19 +85,6 @@
 #define	USBOTGSSX_CLKCTRL_OPTFCLKEN_REFCLK960	(1 << 8)
 #define	USBPHY0_CLKCTRL_OPTFCLKEN_CLK32K	(1 << 8)
 
-/* Control status register */
-#define CTRL_CRYSTAL_FREQ_SRC_MASK		(1 << 31)
-#define CTRL_CRYSTAL_FREQ_SRC_SHIFT		31
-#define CTRL_CRYSTAL_FREQ_SELECTION_MASK	(0x3 << 29)
-#define CTRL_CRYSTAL_FREQ_SELECTION_SHIFT	29
-#define CTRL_SYSBOOT_15_14_MASK			(0x3 << 22)
-#define CTRL_SYSBOOT_15_14_SHIFT		22
-
-#define CTRL_CRYSTAL_FREQ_SRC_SYSBOOT		0x0
-#define CTRL_CRYSTAL_FREQ_SRC_EFUSE		0x1
-
-#define NUM_CRYSTAL_FREQ			0x4
-
 /* EDMA3 Base Address */
 #define EDMA3_BASE				0x49000000
 
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 903398f..4e78aaf 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -46,3 +46,4 @@
 void enable_usb_clocks(int index);
 void disable_usb_clocks(int index);
 void do_board_detect(void);
+u32 get_sys_clk_index(void);
diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c
index 568f36f..e2db15b 100644
--- a/arch/arm/mach-omap2/am33xx/board.c
+++ b/arch/arm/mach-omap2/am33xx/board.c
@@ -242,8 +242,6 @@
  */
 __weak void am33xx_spl_board_init(void)
 {
-	do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
-	do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
 }
 
 #if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
diff --git a/arch/arm/mach-omap2/am33xx/clock_am33xx.c b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
index 7b841b2..1780bbd 100644
--- a/arch/arm/mach-omap2/am33xx/clock_am33xx.c
+++ b/arch/arm/mach-omap2/am33xx/clock_am33xx.c
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <asm/arch/cpu.h>
+#include <asm/arch/sys_proto.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/hardware.h>
 #include <asm/io.h>
@@ -55,26 +56,94 @@
 		CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1};
 const struct dpll_params dpll_core_opp100 = {
 		1000, OSC-1, -1, -1, 10, 8, 4};
-const struct dpll_params dpll_mpu = {
-		MPUPLL_M_300, OSC-1, 1, -1, -1, -1, -1};
-const struct dpll_params dpll_core = {
-		50, OSC-1, -1, -1, 1, 1, 1};
-const struct dpll_params dpll_per = {
-		960, OSC-1, 5, -1, -1, -1, -1};
 
-const struct dpll_params *get_dpll_mpu_params(void)
+const struct dpll_params dpll_mpu_opp[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
+	{	/* 19.2 MHz */
+		{125, 3, 2, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{125, 3, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{150, 3, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{125, 2, 1, -1, -1, -1, -1},	/* OPP TB */
+		{625, 11, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+	{	/* 24 MHz */
+		{25, 0, 2, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{25, 0, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{30, 0, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{100, 3, 1, -1, -1, -1, -1},	/* OPP TB */
+		{125, 2, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+	{	/* 25 MHz */
+		{24, 0, 2, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{24, 0, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{144, 4, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{32, 0, 1, -1, -1, -1, -1},	/* OPP TB */
+		{40, 0, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+	{	/* 26 MHz */
+		{300, 12, 2, -1, -1, -1, -1},	/* OPP 50 */
+		{-1, -1, -1, -1, -1, -1, -1},	/* OPP RESERVED	*/
+		{300, 12, 1, -1, -1, -1, -1},	/* OPP 100 */
+		{360, 12, 1, -1, -1, -1, -1},	/* OPP 120 */
+		{400, 12, 1, -1, -1, -1, -1},	/* OPP TB */
+		{500, 12, 1, -1, -1, -1, -1}	/* OPP NT */
+	},
+};
+
+const struct dpll_params dpll_core_1000MHz[NUM_CRYSTAL_FREQ] = {
+		{625, 11, -1, -1, 10, 8, 4},	/* 19.2 MHz */
+		{125, 2, -1, -1, 10, 8, 4},	/* 24 MHz */
+		{40, 0, -1, -1, 10, 8, 4},	/* 25 MHz */
+		{500, 12, -1, -1, 10, 8, 4}	/* 26 MHz */
+};
+
+const struct dpll_params dpll_per_192MHz[NUM_CRYSTAL_FREQ] = {
+		{400, 7, 5, -1, -1, -1, -1},	/* 19.2 MHz */
+		{400, 9, 5, -1, -1, -1, -1},	/* 24 MHz */
+		{384, 9, 5, -1, -1, -1, -1},	/* 25 MHz */
+		{480, 12, 5, -1, -1, -1, -1}	/* 26 MHz */
+};
+
+const struct dpll_params dpll_ddr3_303MHz[NUM_CRYSTAL_FREQ] = {
+		{505, 15, 2, -1, -1, -1, -1}, /*19.2*/
+		{101, 3, 2, -1, -1, -1, -1}, /* 24 MHz */
+		{303, 24, 1, -1, 4, -1, -1}, /* 25 MHz */
+		{303, 12, 2, -1, 4, -1, -1}  /* 26 MHz */
+};
+
+const struct dpll_params dpll_ddr3_400MHz[NUM_CRYSTAL_FREQ] = {
+		{125, 5, 1, -1, -1, -1, -1}, /*19.2*/
+		{50, 2, 1, -1, -1, -1, -1}, /* 24 MHz */
+		{16, 0, 1, -1, 4, -1, -1}, /* 25 MHz */
+		{200, 12, 1, -1, 4, -1, -1}  /* 26 MHz */
+};
+
+const struct dpll_params dpll_ddr2_266MHz[NUM_CRYSTAL_FREQ] = {
+		{665, 47, 1, -1, -1, -1, -1}, /*19.2*/
+		{133, 11, 1, -1, -1, -1, -1}, /* 24 MHz */
+		{266, 24, 1, -1, 4, -1, -1}, /* 25 MHz */
+		{133, 12, 1, -1, 4, -1, -1}  /* 26 MHz */
+};
+
+__weak const struct dpll_params *get_dpll_mpu_params(void)
 {
-	return &dpll_mpu;
+	return &dpll_mpu_opp100;
 }
 
 const struct dpll_params *get_dpll_core_params(void)
 {
-	return &dpll_core;
+	int ind = get_sys_clk_index();
+
+	return &dpll_core_1000MHz[ind];
 }
 
 const struct dpll_params *get_dpll_per_params(void)
 {
-	return &dpll_per;
+	int ind = get_sys_clk_index();
+
+	return &dpll_per_192MHz[ind];
 }
 
 void setup_clocks_for_console(void)
diff --git a/arch/arm/mach-omap2/am33xx/sys_info.c b/arch/arm/mach-omap2/am33xx/sys_info.c
index 58bfa5c..564bae6 100644
--- a/arch/arm/mach-omap2/am33xx/sys_info.c
+++ b/arch/arm/mach-omap2/am33xx/sys_info.c
@@ -68,6 +68,24 @@
 	return readl(&cstat->statusreg) & SYSBOOT_MASK;
 }
 
+u32 get_sys_clk_index(void)
+{
+	struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
+	u32 ind = readl(&ctrl->statusreg);
+
+#ifdef CONFIG_AM43XX
+	u32 src;
+	src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
+	if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
+		return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
+			CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
+	else /* Value read from SYS BOOT pins */
+#endif
+		return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
+			CTRL_SYSBOOT_15_14_SHIFT);
+}
+
+
 #ifdef CONFIG_DISPLAY_CPUINFO
 static char *cpu_revs[] = {
 		"1.0",