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

login
register
mail settings
Submitter SRICHARAN R
Date Jan. 31, 2013, 6:02 a.m.
Message ID <1359612150-20076-6-git-send-email-r.sricharan@ti.com>
Download mbox | patch
Permalink /patch/217100/
State Superseded
Delegated to: Tom Rini
Headers show

Comments

SRICHARAN R - Jan. 31, 2013, 6:02 a.m.
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>
---
 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(-)
Tom Rini - Jan. 31, 2013, 5:20 p.m.
On Thu, Jan 31, 2013 at 11:32:30AM +0530, R Sricharan wrote:

> 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>

With the caveat that a few formatting things looked odd, but I'm
assuming you ran this series past checkpatch.pl and it's clean:

Reviewed-by: Tom Rini <trini@ti.com>
SRICHARAN R - Feb. 1, 2013, 8:15 a.m.
Hi Tom,

On Thursday 31 January 2013 10:50 PM, Tom Rini wrote:
> On Thu, Jan 31, 2013 at 11:32:30AM +0530, R Sricharan wrote:
>
>> 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>
>
> With the caveat that a few formatting things looked odd, but I'm
> assuming you ran this series past checkpatch.pl and it's clean:
>
> Reviewed-by: Tom Rini <trini@ti.com>
>
I indeed ran checkpatch. There were no warnings, except for one patch 
where clocks data was moved from one file to other because of comments
exceeding 80 characters, but that was unavoidable. Otherwise, rest was 
fine.

Regards,
  Sricharan

Patch

diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 277dc66..92109fa 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -35,6 +35,7 @@ 
 #include <asm/cache.h>
 #include <asm/system.h>
 #include <asm/omap_common.h>
+#include <linux/compiler.h>
 
 #define ARMV7_DCACHE_WRITEBACK  0xe
 #define	ARMV7_DOMAIN_CLIENT	1
@@ -106,6 +107,10 @@  void spl_display_print(void)
 }
 #endif
 
+void __weak srcomp_enable(void)
+{
+}
+
 /*
  * Routine: s_init
  * Description: Does early system init of watchdog, muxing,  andclocks
@@ -132,6 +137,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 0d8c95d..620b99a 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 5c4c985..10648e5 100644
--- a/arch/arm/cpu/armv7/omap5/prcm-regs.c
+++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c
@@ -121,6 +121,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,
@@ -266,6 +267,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,
@@ -474,7 +476,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,
@@ -622,6 +624,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 685aad5..6f64186 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 0a7171b..28a0b3f 100644
--- a/arch/arm/include/asm/arch-omap5/omap.h
+++ b/arch/arm/include/asm/arch-omap5/omap.h
@@ -228,7 +228,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 25e832f..9d042e3 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 789e466..64f5efd 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;