diff mbox

[U-Boot,V3,5/5] ARM: OMAP5: srcomp: enable slew rate compensation cells after powerup

Message ID 1360668825-15798-6-git-send-email-r.sricharan@ti.com
State Accepted
Delegated to: Tom Rini
Headers show

Commit Message

SRICHARAN R Feb. 12, 2013, 11:33 a.m. UTC
From: Lokesh Vutla <lokeshvutla@ti.com>

After power-up SRCOMP cells are by-passed by default in OMAP5.
Software has to enable these SRCOMP sells.
For ES2: All 5 SRCOMP cells needs to be enabled.
For ES1: Only 4 SRCOMP cells in core power domain are enabled.
	 The 1 in wkup domain is not enabled because smart i/os
	 of wkup domain work with default compensation code.

Signed-off-by: R Sricharan <r.sricharan@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Reviewed-by: Tom Rini <trini@ti.com>
Cc: Tom Rini <trini@ti.com>
---
 [v2] Addressed Tom Rini's <trini@ti.com> comments
 [v3] No Change

 arch/arm/cpu/armv7/omap-common/hwinit-common.c |    6 ++
 arch/arm/cpu/armv7/omap5/hwinit.c              |  116 ++++++++++++++++++++++++
 arch/arm/cpu/armv7/omap5/prcm-regs.c           |    5 +-
 arch/arm/include/asm/arch-omap5/clocks.h       |    4 +
 arch/arm/include/asm/arch-omap5/omap.h         |   19 ++++
 arch/arm/include/asm/arch-omap5/sys_proto.h    |    1 +
 arch/arm/include/asm/omap_common.h             |    2 +
 7 files changed, 152 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index e5a5eb6..60af7eb 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -33,6 +33,7 @@ 
 #include <asm/sizes.h>
 #include <asm/emif.h>
 #include <asm/omap_common.h>
+#include <linux/compiler.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -100,6 +101,10 @@  void spl_display_print(void)
 }
 #endif
 
+void __weak srcomp_enable(void)
+{
+}
+
 /*
  * Routine: s_init
  * Description: Does early system init of watchdog, muxing,  andclocks
@@ -126,6 +131,7 @@  void s_init(void)
 	watchdog_init();
 	set_mux_conf_regs();
 #ifdef CONFIG_SPL_BUILD
+	srcomp_enable();
 	setup_clocks_for_console();
 
 	gd = &gdata;
diff --git a/arch/arm/cpu/armv7/omap5/hwinit.c b/arch/arm/cpu/armv7/omap5/hwinit.c
index 8e66a96..f083198 100644
--- a/arch/arm/cpu/armv7/omap5/hwinit.c
+++ b/arch/arm/cpu/armv7/omap5/hwinit.c
@@ -32,6 +32,7 @@ 
 #include <asm/armv7.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/arch/clocks.h>
 #include <asm/sizes.h>
 #include <asm/utils.h>
 #include <asm/arch/gpio.h>
@@ -182,6 +183,121 @@  void do_io_settings(void)
 	writel(EFUSE_3, (*ctrl)->control_efuse_3);
 	writel(EFUSE_4, (*ctrl)->control_efuse_4);
 }
+
+static const struct srcomp_params srcomp_parameters[NUM_SYS_CLKS] = {
+	{0x45, 0x1},	/* 12 MHz   */
+	{-1, -1},	/* 13 MHz   */
+	{0x63, 0x2},	/* 16.8 MHz */
+	{0x57, 0x2},	/* 19.2 MHz */
+	{0x20, 0x1},	/* 26 MHz   */
+	{-1, -1},	/* 27 MHz   */
+	{0x41, 0x3}	/* 38.4 MHz */
+};
+
+void srcomp_enable(void)
+{
+	u32 srcomp_value, mul_factor, div_factor, clk_val, i;
+	u32 sysclk_ind	= get_sys_clk_index();
+	u32 omap_rev	= omap_revision();
+
+	mul_factor = srcomp_parameters[sysclk_ind].multiply_factor;
+	div_factor = srcomp_parameters[sysclk_ind].divide_factor;
+
+	for (i = 0; i < 4; i++) {
+		srcomp_value = readl((*ctrl)->control_srcomp_north_side + i*4);
+		srcomp_value &=
+			~(MULTIPLY_FACTOR_XS_MASK | DIVIDE_FACTOR_XS_MASK);
+		srcomp_value |= (mul_factor << MULTIPLY_FACTOR_XS_SHIFT) |
+			(div_factor << DIVIDE_FACTOR_XS_SHIFT);
+		writel(srcomp_value, (*ctrl)->control_srcomp_north_side + i*4);
+	}
+
+	if ((omap_rev == OMAP5430_ES1_0) || (omap_rev == OMAP5432_ES1_0)) {
+		clk_val = readl((*prcm)->cm_coreaon_io_srcomp_clkctrl);
+		clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK;
+		writel(clk_val, (*prcm)->cm_coreaon_io_srcomp_clkctrl);
+
+		for (i = 0; i < 4; i++) {
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~PWRDWN_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+
+			while (((readl((*ctrl)->control_srcomp_north_side + i*4)
+				& SRCODE_READ_XS_MASK) >>
+				SRCODE_READ_XS_SHIFT) == 0)
+				;
+
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~OVERRIDE_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+		}
+	} else {
+		srcomp_value = readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value &= ~(MULTIPLY_FACTOR_XS_MASK |
+				  DIVIDE_FACTOR_XS_MASK);
+		srcomp_value |= (mul_factor << MULTIPLY_FACTOR_XS_SHIFT) |
+				(div_factor << DIVIDE_FACTOR_XS_SHIFT);
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+
+		for (i = 0; i < 4; i++) {
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value |= SRCODE_OVERRIDE_SEL_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~OVERRIDE_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+		}
+
+		srcomp_value =
+			readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value |= SRCODE_OVERRIDE_SEL_XS_MASK;
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+
+		srcomp_value =
+			readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value &= ~OVERRIDE_XS_MASK;
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+
+		clk_val = readl((*prcm)->cm_coreaon_io_srcomp_clkctrl);
+		clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK;
+		writel(clk_val, (*prcm)->cm_coreaon_io_srcomp_clkctrl);
+
+		clk_val = readl((*prcm)->cm_wkupaon_io_srcomp_clkctrl);
+		clk_val |= OPTFCLKEN_SRCOMP_FCLK_MASK;
+		writel(clk_val, (*prcm)->cm_wkupaon_io_srcomp_clkctrl);
+
+		for (i = 0; i < 4; i++) {
+			while (((readl((*ctrl)->control_srcomp_north_side + i*4)
+				& SRCODE_READ_XS_MASK) >>
+				SRCODE_READ_XS_SHIFT) == 0)
+				;
+
+			srcomp_value =
+				readl((*ctrl)->control_srcomp_north_side + i*4);
+			srcomp_value &= ~SRCODE_OVERRIDE_SEL_XS_MASK;
+			writel(srcomp_value,
+			       (*ctrl)->control_srcomp_north_side + i*4);
+		}
+
+		while (((readl((*ctrl)->control_srcomp_east_side_wkup) &
+			SRCODE_READ_XS_MASK) >> SRCODE_READ_XS_SHIFT) == 0)
+			;
+
+		srcomp_value =
+			readl((*ctrl)->control_srcomp_east_side_wkup);
+		srcomp_value &= ~SRCODE_OVERRIDE_SEL_XS_MASK;
+		writel(srcomp_value, (*ctrl)->control_srcomp_east_side_wkup);
+	}
+}
 #endif
 
 void config_data_eye_leveling_samples(u32 emif_base)
diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c
index 58c9d50..5e5abcc 100644
--- a/arch/arm/cpu/armv7/omap5/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -149,6 +149,7 @@  struct prcm_regs const omap5_es1_prcm = {
 
 	/* cm2.core */
 	.cm_coreaon_bandgap_clkctrl = 0x4a008648,
+	.cm_coreaon_io_srcomp_clkctrl = 0x4a008650,
 	.cm_l3_1_clkstctrl = 0x4a008700,
 	.cm_l3_1_dynamicdep = 0x4a008708,
 	.cm_l3_1_l3_1_clkctrl = 0x4a008720,
@@ -294,6 +295,7 @@  struct prcm_regs const omap5_es1_prcm = {
 	.cm_wkup_rtc_clkctrl = 0x4ae07880,
 	.cm_wkup_bandgap_clkctrl = 0x4ae07888,
 	.cm_wkupaon_scrm_clkctrl = 0x4ae07890,
+	.cm_wkupaon_io_srcomp_clkctrl = 0x4ae07898,
 	.prm_vc_val_bypass = 0x4ae07ba0,
 	.prm_vc_cfg_i2c_mode = 0x4ae07bb4,
 	.prm_vc_cfg_i2c_clk = 0x4ae07bb8,
@@ -502,7 +504,7 @@  struct prcm_regs const omap5_es2_prcm = {
 	.cm_ssc_deltamstep_dpll_unipro = 0x4a0081e8,
 	.cm_ssc_modfreqdiv_dpll_unipro = 0x4a0081ec,
 	.cm_coreaon_bandgap_clkctrl = 0x4a008648,
-
+	.cm_coreaon_io_srcomp_clkctrl = 0x4a008650,
 
 	/* cm2.core */
 	.cm_l3_1_clkstctrl = 0x4a008700,
@@ -650,6 +652,7 @@  struct prcm_regs const omap5_es2_prcm = {
 	.cm_wkup_rtc_clkctrl = 0x4ae07980,
 	.cm_wkup_bandgap_clkctrl = 0x4ae07988,
 	.cm_wkupaon_scrm_clkctrl = 0x4ae07990,
+	.cm_wkupaon_io_srcomp_clkctrl = 0x4ae07998,
 	.prm_vc_val_bypass = 0x4ae07ca0,
 	.prm_vc_cfg_i2c_mode = 0x4ae07cb4,
 	.prm_vc_cfg_i2c_clk = 0x4ae07cb8,
diff --git a/arch/arm/include/asm/arch-omap5/clocks.h b/arch/arm/include/asm/arch-omap5/clocks.h
index 829d10f..52299fa 100644
--- a/arch/arm/include/asm/arch-omap5/clocks.h
+++ b/arch/arm/include/asm/arch-omap5/clocks.h
@@ -186,6 +186,10 @@ 
 #define OPTFCLKEN_SCRM_CORE_SHIFT		8
 #define OPTFCLKEN_SCRM_CORE_MASK		(1 << 8)
 
+/* CM_COREAON_IO_SRCOMP_CLKCTRL */
+#define OPTFCLKEN_SRCOMP_FCLK_SHIFT		8
+#define OPTFCLKEN_SRCOMP_FCLK_MASK		(1 << 8)
+
 /* Clock frequencies */
 #define OMAP_SYS_CLK_FREQ_38_4_MHZ	38400000
 #define OMAP_SYS_CLK_IND_38_4_MHZ	6
diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h
index ba2775b..d29be93 100644
--- a/arch/arm/include/asm/arch-omap5/omap.h
+++ b/arch/arm/include/asm/arch-omap5/omap.h
@@ -229,7 +229,26 @@  struct s32ktimer {
 #define CH_FLAGS_CHFLASH	(0x1 << 2)
 #define CH_FLAGS_CHMMCSD	(0x1 << 3)
 
+/* CONTROL_SRCOMP_XXX_SIDE */
+#define OVERRIDE_XS_SHIFT		30
+#define OVERRIDE_XS_MASK		(1 << 30)
+#define SRCODE_READ_XS_SHIFT		12
+#define SRCODE_READ_XS_MASK		(0xff << 12)
+#define PWRDWN_XS_SHIFT			11
+#define PWRDWN_XS_MASK			(1 << 11)
+#define DIVIDE_FACTOR_XS_SHIFT		4
+#define DIVIDE_FACTOR_XS_MASK		(0x7f << 4)
+#define MULTIPLY_FACTOR_XS_SHIFT	1
+#define MULTIPLY_FACTOR_XS_MASK		(0x7 << 1)
+#define SRCODE_OVERRIDE_SEL_XS_SHIFT	0
+#define SRCODE_OVERRIDE_SEL_XS_MASK	(1 << 0)
+
 #ifndef __ASSEMBLY__
+struct srcomp_params {
+	s8 divide_factor;
+	s8 multiply_factor;
+};
+
 struct omap_boot_parameters {
 	char *boot_message;
 	unsigned int mem_boot_descriptor;
diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index 201ed6f..b8d841d 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -59,6 +59,7 @@  int omap_vc_bypass_send_value(u8 sa, u8 reg_addr, u8 reg_data);
 u32 warm_reset(void);
 void force_emif_self_refresh(void);
 void get_ioregs(const struct ctrl_ioregs **regs);
+void srcomp_enable(void);
 
 /*
  * This is used to verify if the configuration header
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 8a886ec..0af0c33 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -153,6 +153,7 @@  struct prcm_regs {
 
 	/* cm2.core */
 	u32 cm_coreaon_bandgap_clkctrl;
+	u32 cm_coreaon_io_srcomp_clkctrl;
 	u32 cm_l3_1_clkstctrl;
 	u32 cm_l3_1_dynamicdep;
 	u32 cm_l3_1_l3_1_clkctrl;
@@ -300,6 +301,7 @@  struct prcm_regs {
 	u32 cm_wkup_rtc_clkctrl;
 	u32 cm_wkup_bandgap_clkctrl;
 	u32 cm_wkupaon_scrm_clkctrl;
+	u32 cm_wkupaon_io_srcomp_clkctrl;
 	u32 prm_vc_val_bypass;
 	u32 prm_vc_cfg_i2c_mode;
 	u32 prm_vc_cfg_i2c_clk;