All of lore.kernel.org
 help / color / mirror / Atom feed
* OMAP3: DVFS core patch set
@ 2008-12-11 15:52 Tero Kristo
  2008-12-11 15:52 ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tero Kristo
                   ` (2 more replies)
  0 siblings, 3 replies; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

This patch set provides DVFS support for OMAP3. First 16 patches contain
clock framework modifications from Paul Walmsley, which are needed for VDD2
OPP clock control to work properly. Rest of the patches are misc fixes for
DVFS control, providing locking interface for OPPs and providing support
for DPLL3 M2 rates higher than 2.



^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type
  2008-12-11 15:52 OMAP3: DVFS core patch set Tero Kristo
@ 2008-12-11 15:52 ` Tero Kristo
  2008-12-11 15:52   ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tero Kristo
  2008-12-15 19:06   ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tony Lindgren
  2008-12-12  1:59 ` OMAP3: DVFS core patch set Paul Walmsley
  2008-12-15 21:48 ` Kevin Hilman
  2 siblings, 2 replies; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Add a Non-cacheable Normal ARM executable memory type,
MT_MEMORY_NONCACHED.  This is needed for the OMAP3 SDRAM clock change
code, which must run from SRAM.  The SRAM must be marked as
non-cacheable memory to avoid dirty cache line writebacks to SDRAM
while the SDRAM controller is paused.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/include/asm/mach/map.h |    1 +
 arch/arm/mm/mmu.c               |   23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 39d949b..58cf91f 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -26,6 +26,7 @@ struct map_desc {
 #define MT_HIGH_VECTORS		8
 #define MT_MEMORY		9
 #define MT_ROM			10
+#define MT_MEMORY_NONCACHED	11
 
 #ifdef CONFIG_MMU
 extern void iotable_init(struct map_desc *, int);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 7f36c82..9ad6413 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -242,6 +242,10 @@ static struct mem_type mem_types[] = {
 		.prot_sect = PMD_TYPE_SECT,
 		.domain    = DOMAIN_KERNEL,
 	},
+	[MT_MEMORY_NONCACHED] = {
+		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+		.domain    = DOMAIN_KERNEL,
+	},
 };
 
 const struct mem_type *get_mem_type(unsigned int type)
@@ -405,9 +409,28 @@ static void __init build_mem_type_table(void)
 		kern_pgprot |= L_PTE_SHARED;
 		vecs_pgprot |= L_PTE_SHARED;
 		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
 	}
 
+	/*
+	 * Non-cacheable Normal - intended for memory areas that must
+	 * not cause cache line evictions when used
+	 */
+	if (cpu_arch >= CPU_ARCH_ARMv6) {
+		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+			/* Non-cacheable Normal is XCB = 001 */
+			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+				PMD_SECT_BUFFERED;
+		} else {
+			/* For both ARMv6 and non-TEX-remapping ARMv7 */
+			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+				PMD_SECT_TEX(1);
+		}
+	} else {
+		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+	}
+
 	for (i = 0; i < 16; i++) {
 		unsigned long v = pgprot_val(protection_map[i]);
 		protection_map[i] = __pgprot(v | user_pgprot);
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory
  2008-12-11 15:52 ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tero Kristo
@ 2008-12-11 15:52   ` Tero Kristo
  2008-12-11 15:52     ` [PATCH 03/23] OMAP3 SRAM: add ARM barriers to omap3_sram_configure_core_dpll Tero Kristo
  2008-12-15 19:07     ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tony Lindgren
  2008-12-15 19:06   ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tony Lindgren
  1 sibling, 2 replies; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Mark the SRAM (aka OCM RAM) as Non-cacheable Normal memory[1].  This
is to prevent the ARM from evicting existing cache lines to SDRAM
while code is executing from the SRAM.  Necessary since one of the
primary uses for the SRAM is to hold the code and data for the CORE
DPLL M2 divider reprogramming code, which must execute while the SDRC
is idled.  If the ARM attempts to write cache lines back to the while
the SRAM code is running, the ARM will stall[2].

TI deals with this problem in the CDP kernel by marking the SRAM as
Strongly-ordered memory.

Tero Kristo <tero.kristo@nokia.com> caught a bug in an earlier version of
this patch - thanks Tero.

...

1. ARMv7 ARM (DDI 0406A) pp. A3-30, A3-31, B3-32.

2. Private communication with Richard Woodruff <r-woodruff2@ti.com>

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Tero Kristo <tero.kristo@nokia.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
---
 arch/arm/plat-omap/sram.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 arch/arm/plat-omap/sram.c

diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
old mode 100755
new mode 100644
index abcc05b..04214e1
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -207,6 +207,15 @@ void __init omap_map_sram(void)
 		base = OMAP3_SRAM_PA;
 		base = ROUND_DOWN(base, PAGE_SIZE);
 		omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
+
+		/*
+		 * SRAM must be marked as non-cached on OMAP3 since the
+		 * CORE DPLL M2 divider change code (in SRAM) runs with the
+		 * SDRAM controller disabled, and if it is marked cached,
+		 * the ARM may attempt to write cache lines back to SDRAM
+		 * which will cause the system to hang.
+		 */
+		omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED;
 	}
 
 	omap_sram_io_desc[0].length = 1024 * 1024;	/* Use section desc */
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 03/23] OMAP3 SRAM: add ARM barriers to omap3_sram_configure_core_dpll
  2008-12-11 15:52   ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tero Kristo
@ 2008-12-11 15:52     ` Tero Kristo
  2008-12-11 15:52       ` [PATCH 04/23] OMAP3 clock: add interconnect barriers to CORE DPLL M2 change Tero Kristo
  2008-12-15 19:07     ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tony Lindgren
  1 sibling, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Add more barriers in the SRAM CORE DPLL M2 divider change code.

- Add a DSB SY after the function's entry point to flush all cached
  and buffered writes and wait for the interconnect to claim that they
  have completed[1].  The idea here is to force all delayed write
  traffic going to the SDRAM to at least post to the L3 interconnect
  before continuing.  If these writes are allowed to occur after the
  SDRC is idled, the writes will not be acknowledged and the ARM will
  stall.

  Note that in this case, it does not matter if the writes actually
  complete to the SDRAM - it is only necessary for the writes to leave
  the ARM itself.  If the writes are posted by the interconnect when
  the SDRC goes into idle, the writes will be delayed until the SDRC
  returns from idle[2].  If the SDRC is in the middle of a write when
  it is requested to enter idle, the SDRC will not acknowledge the
  idle request until the writes complete to the SDRAM.[3]

  The old-style DMB in sdram_in_selfrefresh is now superfluous, so,
  remove it.

- Add an ISB before the function's exit point to prevent the ARM from
  speculatively executing into SDRAM before the SDRAM is enabled[4].

...

1. ARMv7 ARM (DDI 0406A) A3-47, A3-48.

2. Private communication with Richard Woodruff <r-woodruff2@ti.com>.

3. Private communication with Richard Woodruff <r-woodruff2@ti.com>.

4. ARMv7 ARM (DDI 0406A) A3-48.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Richard Woodruff <r-woodruff2@ti.com>
---
 arch/arm/mach-omap2/sram34xx.S |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 2c71461..f4a356d 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -43,6 +43,7 @@
  */
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
+	dsb				@ flush buffered writes to interconnect
 	cmp	r3, #0x2
 	blne	configure_sdrc
 	cmp	r3, #0x2
@@ -58,6 +59,7 @@ ENTRY(omap3_sram_configure_core_dpll)
 	blne	wait_dll_lock
 	cmp	r3, #0x1
 	blne	configure_sdrc
+	isb				@ prevent speculative exec past here
 	mov 	r0, #0 			@ return value
 	ldmfd	sp!, {r1-r12, pc}	@ restore regs and return
 unlock_dll:
@@ -73,8 +75,6 @@ lock_dll:
 	str	r5, [r4]
 	bx	lr
 sdram_in_selfrefresh:
-	mov	r5, #0x0		@ Move 0 to R5
-	mcr	p15, 0, r5, c7, c10, 5	@ memory barrier
 	ldr	r4, omap3_sdrc_power	@ read the SDRC_POWER register
 	ldr	r5, [r4]		@ read the contents of SDRC_POWER
 	orr 	r5, r5, #0x40		@ enable self refresh on idle req
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 04/23] OMAP3 clock: add interconnect barriers to CORE DPLL M2 change
  2008-12-11 15:52     ` [PATCH 03/23] OMAP3 SRAM: add ARM barriers to omap3_sram_configure_core_dpll Tero Kristo
@ 2008-12-11 15:52       ` Tero Kristo
  2008-12-11 15:52         ` [PATCH 05/23] OMAP3 SRAM: clear the SDRC PWRENA bit during SDRC frequency change Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Where necessary, add interconnect barriers to force posted writes to
complete before continuing.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sram34xx.S |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index f4a356d..8d524f3 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -66,22 +66,23 @@ unlock_dll:
 	ldr	r4, omap3_sdrc_dlla_ctrl
 	ldr	r5, [r4]
 	orr	r5, r5, #0x4
-	str	r5, [r4]
+	str	r5, [r4]		@ (no OCP barrier needed)
 	bx	lr
 lock_dll:
 	ldr	r4, omap3_sdrc_dlla_ctrl
 	ldr	r5, [r4]
 	bic	r5, r5, #0x4
-	str	r5, [r4]
+	str	r5, [r4]		@ (no OCP barrier needed)
 	bx	lr
 sdram_in_selfrefresh:
 	ldr	r4, omap3_sdrc_power	@ read the SDRC_POWER register
 	ldr	r5, [r4]		@ read the contents of SDRC_POWER
 	orr 	r5, r5, #0x40		@ enable self refresh on idle req
 	str 	r5, [r4]		@ write back to SDRC_POWER register
+	ldr	r5, [r4]		@ posted-write barrier for SDRC
 	ldr	r4, omap3_cm_iclken1_core	@ read the CM_ICLKEN1_CORE reg
 	ldr	r5, [r4]
-	bic	r5, r5, #0x2		@ disable iclk bit for SRDC
+	bic	r5, r5, #0x2		@ disable iclk bit for SDRC
 	str 	r5, [r4]
 wait_sdrc_idle:
 	ldr 	r4, omap3_cm_idlest1_core
@@ -97,6 +98,7 @@ configure_core_dpll:
 	and	r5, r5, r6
 	orr	r5, r5, r3, lsl #0x1B	@ r3 contains the M2 val
 	str	r5, [r4]
+	ldr	r5, [r4]		@ posted-write barrier for CM
 	mov 	r5, #0x800		@ wait for the clock to stabilise
 	cmp	r3, #2
 	bne	wait_clk_stable
@@ -152,6 +154,7 @@ configure_sdrc:
 	str	r1, [r4]
 	ldr	r4, omap3_sdrc_actim_ctrlb
 	str	r2, [r4]
+	ldr	r2, [r4]		@ posted-write barrier for SDRC
 	bx	lr
 
 omap3_sdrc_power:
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 05/23] OMAP3 SRAM: clear the SDRC PWRENA bit during SDRC frequency change
  2008-12-11 15:52       ` [PATCH 04/23] OMAP3 clock: add interconnect barriers to CORE DPLL M2 change Tero Kristo
@ 2008-12-11 15:52         ` Tero Kristo
  2008-12-11 15:52           ` [PATCH 06/23] OMAP3 SDRC: Add 166MHz, 83MHz SDRC settings for the BeagleBoard Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Clear the SDRC_POWER.PWRENA bit before putting the SDRAM into self-refresh
mode.  This prevents the SDRC from attempting to power off the SDRAM,
which can cause the system to hang.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sram34xx.S |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 8d524f3..9a45415 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -77,7 +77,9 @@ lock_dll:
 sdram_in_selfrefresh:
 	ldr	r4, omap3_sdrc_power	@ read the SDRC_POWER register
 	ldr	r5, [r4]		@ read the contents of SDRC_POWER
+	mov	r9, r5			@ keep a copy of SDRC_POWER bits
 	orr 	r5, r5, #0x40		@ enable self refresh on idle req
+	bic 	r5, r5, #0x4		@ clear PWDENA
 	str 	r5, [r4]		@ write back to SDRC_POWER register
 	ldr	r5, [r4]		@ posted-write barrier for SDRC
 	ldr	r4, omap3_cm_iclken1_core	@ read the CM_ICLKEN1_CORE reg
@@ -128,10 +130,9 @@ wait_sdrc_idle1:
 	and 	r5, r5, #0x2
 	cmp	r5, #0
 	bne	wait_sdrc_idle1
+restore_sdrc_power_val:
 	ldr	r4, omap3_sdrc_power
-	ldr	r5, [r4]
-	bic 	r5, r5, #0x40
-	str 	r5, [r4]
+	str	r9, [r4]		@ restore SDRC_POWER, no barrier needed
 	bx	lr
 wait_dll_lock:
 	ldr	r4, omap3_sdrc_dlla_status
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 06/23] OMAP3 SDRC: Add 166MHz, 83MHz SDRC settings for the BeagleBoard
  2008-12-11 15:52         ` [PATCH 05/23] OMAP3 SRAM: clear the SDRC PWRENA bit during SDRC frequency change Tero Kristo
@ 2008-12-11 15:52           ` Tero Kristo
  2008-12-11 15:52             ` [PATCH 07/23] OMAP3 SDRC: initialize SDRC_POWER at boot Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

The BeagleBoard u-boot uses DPLL3 settings that result in 83000000 /
166000000 Hz clock rates for the SDRC, rather than the derated DPLL3
settings used by earlier bootloaders.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h |   22 +++++++++++++++++---
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
index ef35415..b6c1db3 100644
--- a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
+++ b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
@@ -20,34 +20,48 @@
 /* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
 static struct omap_sdrc_params mt46h32m32lf6_sdrc_params[] = {
 	[0] = {
-		.rate	     = 165941176,
+		.rate	     = 166000000,
 		.actim_ctrla = 0x9a9db4c6,
 		.actim_ctrlb = 0x00011217,
 		.rfr_ctrl    = 0x0004dc01,
 		.mr	     = 0x00000032,
 	},
 	[1] = {
+		.rate	     = 165941176,
+		.actim_ctrla = 0x9a9db4c6,
+		.actim_ctrlb = 0x00011217,
+		.rfr_ctrl    = 0x0004dc01,
+		.mr	     = 0x00000032,
+	},
+	[2] = {
 		.rate	     = 133333333,
 		.actim_ctrla = 0x7a19b485,
 		.actim_ctrlb = 0x00011213,
 		.rfr_ctrl    = 0x0003de01,
 		.mr	     = 0x00000032,
 	},
-	[2] = {
+	[3] = {
+		.rate	     = 83000000,
+		.actim_ctrla = 0x51512283,
+		.actim_ctrlb = 0x0001120c,
+		.rfr_ctrl    = 0x00025501,
+		.mr	     = 0x00000032,
+	},
+	[4] = {
 		.rate	     = 82970588,
 		.actim_ctrla = 0x51512283,
 		.actim_ctrlb = 0x0001120c,
 		.rfr_ctrl    = 0x00025501,
 		.mr	     = 0x00000032,
 	},
-	[3] = {
+	[5] = {
 		.rate	     = 66666666,
 		.actim_ctrla = 0x410d2243,
 		.actim_ctrlb = 0x0001120a,
 		.rfr_ctrl    = 0x0001d601,
 		.mr	     = 0x00000032,
 	},
-	[4] = {
+	[6] = {
 		.rate	     = 0
 	},
 };
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 07/23] OMAP3 SDRC: initialize SDRC_POWER at boot
  2008-12-11 15:52           ` [PATCH 06/23] OMAP3 SDRC: Add 166MHz, 83MHz SDRC settings for the BeagleBoard Tero Kristo
@ 2008-12-11 15:52             ` Tero Kristo
  2008-12-11 15:52               ` [PATCH 08/23] OMAP3 SRAM: renumber registers to make space for argument passing Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Initialize SDRC_POWER to a known-good setting when the kernel boots.
Necessary since some bootloaders don't initialize SDRC_POWER properly.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sdrc.c |   19 ++++++++++++++++++-
 1 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
index 2a30060..d62e4e1 100644
--- a/arch/arm/mach-omap2/sdrc.c
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -37,6 +37,10 @@ static struct omap_sdrc_params *sdrc_init_params;
 void __iomem *omap2_sdrc_base;
 void __iomem *omap2_sms_base;
 
+/* SDRC_POWER register bits */
+#define SDRC_POWER_EXTCLKDIS_SHIFT		3
+#define SDRC_POWER_PWDENA_SHIFT			2
+#define SDRC_POWER_PAGEPOLICY_SHIFT		0
 
 /**
  * omap2_sdrc_get_params - return SDRC register values for a given clock rate
@@ -74,7 +78,14 @@ void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
 	omap2_sms_base = omap2_globals->sms;
 }
 
-/* turn on smart idle modes for SDRAM scheduler and controller */
+/**
+ * omap2_sdrc_init - initialize SMS, SDRC devices on boot
+ * @sp: pointer to a null-terminated list of struct omap_sdrc_params
+ *
+ * Turn on smart idle modes for SDRAM scheduler and controller.
+ * Program a known-good configuration for the SDRC to deal with buggy
+ * bootloaders.
+ */
 void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
 {
 	u32 l;
@@ -90,4 +101,10 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
 	sdrc_write_reg(l, SDRC_SYSCONFIG);
 
 	sdrc_init_params = sp;
+
+	/* XXX Enable SRFRONIDLEREQ here also? */
+	l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
+		(1 << SDRC_POWER_PWDENA_SHIFT) |
+		(1 << SDRC_POWER_PAGEPOLICY_SHIFT);
+	sdrc_write_reg(l, SDRC_POWER);
 }
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 08/23] OMAP3 SRAM: renumber registers to make space for argument passing
  2008-12-11 15:52             ` [PATCH 07/23] OMAP3 SDRC: initialize SDRC_POWER at boot Tero Kristo
@ 2008-12-11 15:52               ` Tero Kristo
  2008-12-11 15:52                 ` [PATCH 09/23] OMAP3 clock: only unlock SDRC DLL if SDRC clk < 83MHz Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Renumber registers in omap3_sram_configure_core_dpll() assembly code to
make space for additional parameters.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sram34xx.S |  114 ++++++++++++++++++++--------------------
 1 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 9a45415..35131e5 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -63,50 +63,50 @@ ENTRY(omap3_sram_configure_core_dpll)
 	mov 	r0, #0 			@ return value
 	ldmfd	sp!, {r1-r12, pc}	@ restore regs and return
 unlock_dll:
-	ldr	r4, omap3_sdrc_dlla_ctrl
-	ldr	r5, [r4]
-	orr	r5, r5, #0x4
-	str	r5, [r4]		@ (no OCP barrier needed)
+	ldr	r11, omap3_sdrc_dlla_ctrl
+	ldr	r12, [r11]
+	orr	r12, r12, #0x4
+	str	r12, [r11]		@ (no OCP barrier needed)
 	bx	lr
 lock_dll:
-	ldr	r4, omap3_sdrc_dlla_ctrl
-	ldr	r5, [r4]
-	bic	r5, r5, #0x4
-	str	r5, [r4]		@ (no OCP barrier needed)
+	ldr	r11, omap3_sdrc_dlla_ctrl
+	ldr	r12, [r11]
+	bic	r12, r12, #0x4
+	str	r12, [r11]		@ (no OCP barrier needed)
 	bx	lr
 sdram_in_selfrefresh:
-	ldr	r4, omap3_sdrc_power	@ read the SDRC_POWER register
-	ldr	r5, [r4]		@ read the contents of SDRC_POWER
-	mov	r9, r5			@ keep a copy of SDRC_POWER bits
-	orr 	r5, r5, #0x40		@ enable self refresh on idle req
-	bic 	r5, r5, #0x4		@ clear PWDENA
-	str 	r5, [r4]		@ write back to SDRC_POWER register
-	ldr	r5, [r4]		@ posted-write barrier for SDRC
-	ldr	r4, omap3_cm_iclken1_core	@ read the CM_ICLKEN1_CORE reg
-	ldr	r5, [r4]
-	bic	r5, r5, #0x2		@ disable iclk bit for SDRC
-	str 	r5, [r4]
+	ldr	r11, omap3_sdrc_power	@ read the SDRC_POWER register
+	ldr	r12, [r11]		@ read the contents of SDRC_POWER
+	mov	r9, r12			@ keep a copy of SDRC_POWER bits
+	orr 	r12, r12, #0x40		@ enable self refresh on idle req
+	bic 	r12, r12, #0x4		@ clear PWDENA
+	str 	r12, [r11]		@ write back to SDRC_POWER register
+	ldr	r12, [r11]		@ posted-write barrier for SDRC
+	ldr	r11, omap3_cm_iclken1_core	@ read the CM_ICLKEN1_CORE reg
+	ldr	r12, [r11]
+	bic	r12, r12, #0x2		@ disable iclk bit for SDRC
+	str 	r12, [r11]
 wait_sdrc_idle:
-	ldr 	r4, omap3_cm_idlest1_core
-	ldr 	r5, [r4]
-	and 	r5, r5, #0x2		@ check for SDRC idle
-	cmp 	r5, #2
+	ldr 	r11, omap3_cm_idlest1_core
+	ldr 	r12, [r11]
+	and 	r12, r12, #0x2		@ check for SDRC idle
+	cmp 	r12, #2
 	bne 	wait_sdrc_idle
 	bx 	lr
 configure_core_dpll:
-	ldr 	r4, omap3_cm_clksel1_pll
-	ldr	r5, [r4]
-	ldr	r6, core_m2_mask_val	@ modify m2 for core dpll
-	and	r5, r5, r6
-	orr	r5, r5, r3, lsl #0x1B	@ r3 contains the M2 val
-	str	r5, [r4]
-	ldr	r5, [r4]		@ posted-write barrier for CM
-	mov 	r5, #0x800		@ wait for the clock to stabilise
+	ldr 	r11, omap3_cm_clksel1_pll
+	ldr	r12, [r11]
+	ldr	r10, core_m2_mask_val	@ modify m2 for core dpll
+	and	r12, r12, r10
+	orr	r12, r12, r3, lsl #0x1B	@ r3 contains the M2 val
+	str	r12, [r11]
+	ldr	r12, [r11]		@ posted-write barrier for CM
+	mov 	r12, #0x800		@ wait for the clock to stabilise
 	cmp	r3, #2
 	bne	wait_clk_stable
 	bx	lr
 wait_clk_stable:
-	subs 	r5, r5, #1
+	subs 	r12, r12, #1
 	bne	wait_clk_stable
 	nop
 	nop
@@ -120,42 +120,42 @@ wait_clk_stable:
 	nop
 	bx	lr
 enable_sdrc:
-	ldr 	r4, omap3_cm_iclken1_core
-	ldr	r5, [r4]
-	orr 	r5, r5, #0x2		@ enable iclk bit for SDRC
-	str 	r5, [r4]
+	ldr 	r11, omap3_cm_iclken1_core
+	ldr	r12, [r11]
+	orr 	r12, r12, #0x2		@ enable iclk bit for SDRC
+	str 	r12, [r11]
 wait_sdrc_idle1:
-	ldr 	r4, omap3_cm_idlest1_core
-	ldr	r5, [r4]
-	and 	r5, r5, #0x2
-	cmp	r5, #0
+	ldr 	r11, omap3_cm_idlest1_core
+	ldr	r12, [r11]
+	and 	r12, r12, #0x2
+	cmp	r12, #0
 	bne	wait_sdrc_idle1
 restore_sdrc_power_val:
-	ldr	r4, omap3_sdrc_power
-	str	r9, [r4]		@ restore SDRC_POWER, no barrier needed
+	ldr	r11, omap3_sdrc_power
+	str	r9, [r11]		@ restore SDRC_POWER, no barrier needed
 	bx	lr
 wait_dll_lock:
-	ldr	r4, omap3_sdrc_dlla_status
-	ldr	r5, [r4]
-	and 	r5, r5, #0x4
-	cmp	r5, #0x4
+	ldr	r11, omap3_sdrc_dlla_status
+	ldr	r12, [r11]
+	and 	r12, r12, #0x4
+	cmp	r12, #0x4
 	bne	wait_dll_lock
 	bx	lr
 wait_dll_unlock:
-	ldr	r4, omap3_sdrc_dlla_status
-	ldr	r5, [r4]
-	and	r5, r5, #0x4
-	cmp	r5, #0x0
+	ldr	r11, omap3_sdrc_dlla_status
+	ldr	r12, [r11]
+	and	r12, r12, #0x4
+	cmp	r12, #0x0
 	bne	wait_dll_unlock
 	bx	lr
 configure_sdrc:
-	ldr	r4, omap3_sdrc_rfr_ctrl
-	str	r0, [r4]
-	ldr	r4, omap3_sdrc_actim_ctrla
-	str	r1, [r4]
-	ldr	r4, omap3_sdrc_actim_ctrlb
-	str	r2, [r4]
-	ldr	r2, [r4]		@ posted-write barrier for SDRC
+	ldr	r11, omap3_sdrc_rfr_ctrl
+	str	r0, [r11]
+	ldr	r11, omap3_sdrc_actim_ctrla
+	str	r1, [r11]
+	ldr	r11, omap3_sdrc_actim_ctrlb
+	str	r2, [r11]
+	ldr	r2, [r11]		@ posted-write barrier for SDRC
 	bx	lr
 
 omap3_sdrc_power:
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 09/23] OMAP3 clock: only unlock SDRC DLL if SDRC clk < 83MHz
  2008-12-11 15:52               ` [PATCH 08/23] OMAP3 SRAM: renumber registers to make space for argument passing Tero Kristo
@ 2008-12-11 15:52                 ` Tero Kristo
  2008-12-11 15:52                   ` [PATCH 10/23] OMAP3 clock: use pr_debug() rather than pr_info() in some clock change code Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

According to the 34xx TRM Rev. K section 11.2.4.4.11.1 "Purpose of the
DLL/CDL Module," the SDRC delay-locked-loop can be locked at any SDRC
clock frequency from 83MHz to 166MHz.  CDP code unconditionally
unlocked the DLL whenever shifting to a lower SDRC speed, but this
seems unnecessary and error-prone, as the DLL is no longer able to
compensate for process, voltage, and temperature variations.  Instead,
only unlock the DLL when the SDRC clock rate would be less than 83MHz.

In situations where the DLL is unlocked, we should probably be
changing the FIXEDDELAY field, but currently we have no information on
how to calculate it.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c        |   11 ++++++++++-
 arch/arm/mach-omap2/sram34xx.S         |   13 +++++++------
 arch/arm/plat-omap/include/mach/sram.h |    3 ++-
 arch/arm/plat-omap/sram.c              |    7 ++++---
 4 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 3000c33..efeb9c9 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -48,6 +48,9 @@
 
 #define MAX_DPLL_WAIT_TRIES		1000000
 
+/* Minimum SDRC clock frequency that the SDRC DLL can lock at */
+#define MIN_SDRC_DLL_LOCK_FREQ		83000000
+
 struct omap_opp *curr_vdd1_prcm_set;
 struct omap_opp *curr_vdd2_prcm_set;
 static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
@@ -482,6 +485,7 @@ static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
 static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 new_div = 0;
+	u32 unlock_dll = 0;
 	unsigned long validrate, sdrcrate;
 	struct omap_sdrc_params *sp;
 
@@ -508,6 +512,11 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	if (!sp)
 		return -EINVAL;
 
+	if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
+		pr_debug("clock: will unlock SDRC DLL\n");
+		unlock_dll = 1;
+	}
+
 	pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
 		validrate);
 	pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
@@ -519,7 +528,7 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	/* REVISIT: Add SDRC_MR changing to this code also */
 	local_irq_disable();
 	omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
-				  sp->actim_ctrlb, new_div);
+				  sp->actim_ctrlb, new_div, unlock_dll);
 	local_irq_enable();
 
 	omap2_clksel_recalc(clk);
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 35131e5..c080c82 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -40,22 +40,23 @@
 /*
  * Change frequency of core dpll
  * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
+ * r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for
+ *      SDRC rates < 83MHz
  */
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
+	ldr	r4, [sp, #52]		@ pull extra args off the stack
 	dsb				@ flush buffered writes to interconnect
 	cmp	r3, #0x2
 	blne	configure_sdrc
-	cmp	r3, #0x2
+	cmp	r4, #0x1
+	bleq	unlock_dll
 	blne	lock_dll
-	cmp	r3, #0x1
-	blne	unlock_dll
 	bl	sdram_in_selfrefresh	@ put the SDRAM in self refresh
 	bl 	configure_core_dpll
 	bl	enable_sdrc
-	cmp	r3, #0x1
-	blne	wait_dll_unlock
-	cmp	r3, #0x2
+	cmp	r4, #0x1
+	bleq	wait_dll_unlock
 	blne	wait_dll_lock
 	cmp	r3, #0x1
 	blne	configure_sdrc
diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
index 0c0b45f..8ce41e0 100644
--- a/arch/arm/plat-omap/include/mach/sram.h
+++ b/arch/arm/plat-omap/include/mach/sram.h
@@ -23,7 +23,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 
 extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
 				     u32 sdrc_actim_ctrla,
-				     u32 sdrc_actim_ctrlb, u32 m2);
+				     u32 sdrc_actim_ctrlb, u32 m2,
+				     u32 unlock_dll);
 extern void omap3_sram_restore_context(void);
 
 /* Do not use these */
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 04214e1..65fcfdf 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -371,16 +371,17 @@ static inline int omap243x_sram_init(void)
 static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
 					      u32 sdrc_actim_ctrla,
 					      u32 sdrc_actim_ctrlb,
-					      u32 m2);
+					      u32 m2, u32 unlock_dll);
 u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
-			      u32 sdrc_actim_ctrlb, u32 m2)
+			      u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll)
  {
 	if (!_omap3_sram_configure_core_dpll)
 		omap_sram_error();
 
 	return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
 					       sdrc_actim_ctrla,
-					       sdrc_actim_ctrlb, m2);
+					       sdrc_actim_ctrlb, m2,
+					       unlock_dll);
  }
 
 #ifdef CONFIG_PM
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 10/23] OMAP3 clock: use pr_debug() rather than pr_info() in some clock change code
  2008-12-11 15:52                 ` [PATCH 09/23] OMAP3 clock: only unlock SDRC DLL if SDRC clk < 83MHz Tero Kristo
@ 2008-12-11 15:52                   ` Tero Kristo
  2008-12-11 15:52                     ` [PATCH 11/23] OMAP3 clock: remove wait for DPLL3 M2 clock to stabilize Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

The CORE DPLL M2 frequency change code should use pr_debug(), not
pr_info(), for its debug messages.  Same with
omap2_clksel_round_rate_div().  While here, convert a few printk(KERN_ERR ..
into pr_err().

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock.c     |   12 ++++++------
 arch/arm/mach-omap2/clock34xx.c |    8 ++++----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index b4ef3a3..7c7e60e 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -564,8 +564,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
 	const struct clksel_rate *clkr;
 	u32 last_div = 0;
 
-	printk(KERN_INFO "clock: clksel_round_rate_div: %s target_rate %ld\n",
-	       clk->name, target_rate);
+	pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
+		 clk->name, target_rate);
 
 	*new_div = 1;
 
@@ -579,7 +579,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
 
 		/* Sanity check */
 		if (clkr->div <= last_div)
-			printk(KERN_ERR "clock: clksel_rate table not sorted "
+			pr_err("clock: clksel_rate table not sorted "
 			       "for clock %s", clk->name);
 
 		last_div = clkr->div;
@@ -591,7 +591,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
 	}
 
 	if (!clkr->div) {
-		printk(KERN_ERR "clock: Could not find divisor for target "
+		pr_err("clock: Could not find divisor for target "
 		       "rate %ld for clock %s parent %s\n", target_rate,
 		       clk->name, clk->parent->name);
 		return ~0;
@@ -599,8 +599,8 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
 
 	*new_div = clkr->div;
 
-	printk(KERN_INFO "clock: new_div = %d, new_rate = %ld\n", *new_div,
-	       (clk->parent->rate / clkr->div));
+	pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+		 (clk->parent->rate / clkr->div));
 
 	return (clk->parent->rate / clkr->div);
 }
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index efeb9c9..adf0be3 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -517,10 +517,10 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 		unlock_dll = 1;
 	}
 
-	pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
-		validrate);
-	pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
-		sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
+	pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+		 validrate);
+	pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
+		 sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
 
 	/* REVISIT: SRAM code doesn't support other M2 divisors yet */
 	WARN_ON(new_div != 1 && new_div != 2);
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 11/23] OMAP3 clock: remove wait for DPLL3 M2 clock to stabilize
  2008-12-11 15:52                   ` [PATCH 10/23] OMAP3 clock: use pr_debug() rather than pr_info() in some clock change code Tero Kristo
@ 2008-12-11 15:52                     ` Tero Kristo
  2008-12-11 15:52                       ` [PATCH 12/23] OMAP3 clock: initialize SDRC timings at kernel start Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

The original CDP kernel that this code comes from waited for 0x800
loops after switching the CORE DPLL M2 divider.  This does not appear
to be necessary.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sram34xx.S |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index c080c82..84781a6 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -102,9 +102,6 @@ configure_core_dpll:
 	orr	r12, r12, r3, lsl #0x1B	@ r3 contains the M2 val
 	str	r12, [r11]
 	ldr	r12, [r11]		@ posted-write barrier for CM
-	mov 	r12, #0x800		@ wait for the clock to stabilise
-	cmp	r3, #2
-	bne	wait_clk_stable
 	bx	lr
 wait_clk_stable:
 	subs 	r12, r12, #1
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 12/23] OMAP3 clock: initialize SDRC timings at kernel start
  2008-12-11 15:52                     ` [PATCH 11/23] OMAP3 clock: remove wait for DPLL3 M2 clock to stabilize Tero Kristo
@ 2008-12-11 15:52                       ` Tero Kristo
  2008-12-11 15:52                         ` [PATCH 13/23] OMAP3 clock: add a short delay when lowering CORE clk rate Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

On the OMAP3, initialize SDRC timings when the kernel boots.  This ensures
that the kernel is running with known, optimized SDRC timings, rather than
whatever was configured by the bootloader.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c |    3 ---
 arch/arm/mach-omap2/io.c        |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index adf0be3..cea3840 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -495,9 +495,6 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	if (clk != &dpll3_m2_ck)
 		return -EINVAL;
 
-	if (rate == clk->rate)
-		return 0;
-
 	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
 	if (validrate != rate)
 		return -EINVAL;
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 5b529ae..6fb6c29 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <asm/tlb.h>
 
@@ -198,6 +199,38 @@ void __init omap2_map_common_io(void)
 	omapfb_reserve_sdram();
 }
 
+/*
+ * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
+ *
+ * Sets the CORE DPLL3 M2 divider to the same value that it's at
+ * currently.  This has the effect of setting the SDRC SDRAM AC timing
+ * registers to the values currently defined by the kernel.  Currently
+ * only defined for OMAP3; will return 0 if called on OMAP2.  Returns
+ * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2,
+ * or passes along the return value of clk_set_rate().
+ */
+static int __init _omap2_init_reprogram_sdrc(void)
+{
+	struct clk *dpll3_m2_ck;
+	int v = -EINVAL;
+
+	if (!cpu_is_omap34xx())
+		return 0;
+
+	dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
+	if (!dpll3_m2_ck)
+		return -EINVAL;
+
+	pr_info("Reprogramming SDRC\n");
+	v = clk_set_rate(dpll3_m2_ck, clk_get_rate(dpll3_m2_ck));
+	if (v)
+		pr_err("dpll3_m2_clk rate change failed: %d\n", v);
+
+	clk_put(dpll3_m2_ck);
+
+	return v;
+}
+
 void __init omap2_init_common_hw(struct omap_sdrc_params *sp,
 				 struct omap_opp *mpu_opps,
 				 struct omap_opp *dsp_opps,
@@ -212,5 +245,8 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sp,
 	omap2_clk_init();
 	omap_pm_if_init();
 	omap2_sdrc_init(sp);
+
+	_omap2_init_reprogram_sdrc();
+
 	gpmc_init();
 }
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 13/23] OMAP3 clock: add a short delay when lowering CORE clk rate
  2008-12-11 15:52                       ` [PATCH 12/23] OMAP3 clock: initialize SDRC timings at kernel start Tero Kristo
@ 2008-12-11 15:52                         ` Tero Kristo
  2008-12-11 15:52                           ` [PATCH 14/23] OMAP3 clock/SDRC: program SDRC_MR register during SDRC clock change Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

When changing the SDRAM clock from 166MHz to 83MHz via the CORE DPLL M2
divider, add a short delay before returning to SDRAM to allow the SDRC
time to stabilize.  Without this delay, the system is prone to random
panics upon re-entering SDRAM.

This time delay varies based on MPU frequency.  At 500MHz MPU frequency at
room temperature, 64 loops seems to work okay; so add another 32 loops for
environmental and process variation.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c        |   30 ++++++++++++++++++++++++++++--
 arch/arm/mach-omap2/sram34xx.S         |   20 +++++++++-----------
 arch/arm/plat-omap/include/mach/sram.h |    2 +-
 arch/arm/plat-omap/sram.c              |    8 +++++---
 4 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index cea3840..8ef0186 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -51,6 +51,20 @@
 /* Minimum SDRC clock frequency that the SDRC DLL can lock at */
 #define MIN_SDRC_DLL_LOCK_FREQ		83000000
 
+#define CYCLES_PER_MHZ			1000000
+
+/* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */
+#define SDRC_MPURATE_SCALE		8
+
+/* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */
+#define SDRC_MPURATE_BASE_SHIFT		9
+
+/*
+ * SDRC_MPURATE_LOOPS: Number of MPU loops to execute at
+ * 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize
+ */
+#define SDRC_MPURATE_LOOPS		96
+
 struct omap_opp *curr_vdd1_prcm_set;
 struct omap_opp *curr_vdd2_prcm_set;
 static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
@@ -486,7 +500,8 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 {
 	u32 new_div = 0;
 	u32 unlock_dll = 0;
-	unsigned long validrate, sdrcrate;
+	u32 c;
+	unsigned long validrate, sdrcrate, mpurate;
 	struct omap_sdrc_params *sp;
 
 	if (!clk || !rate)
@@ -514,6 +529,17 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 		unlock_dll = 1;
 	}
 
+	/*
+	 * XXX This only needs to be done when the CPU frequency changes
+	 */
+	mpurate = arm_fck.rate / CYCLES_PER_MHZ;
+	c = (mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
+	c += 1;  /* for safety */
+	c *= SDRC_MPURATE_LOOPS;
+	c >>= SDRC_MPURATE_SCALE;
+	if (c == 0)
+		c = 1;
+
 	pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
 		 validrate);
 	pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
@@ -525,7 +551,7 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	/* REVISIT: Add SDRC_MR changing to this code also */
 	local_irq_disable();
 	omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
-				  sp->actim_ctrlb, new_div, unlock_dll);
+				  sp->actim_ctrlb, new_div, unlock_dll, c);
 	local_irq_enable();
 
 	omap2_clksel_recalc(clk);
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 84781a6..8d4a88c 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -42,10 +42,14 @@
  * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
  * r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for
  *      SDRC rates < 83MHz
+ * r5 = number of MPU cycles to wait for SDRC to stabilize after
+ *      reprogramming the SDRC when switching to a slower MPU speed
+ *
  */
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
 	ldr	r4, [sp, #52]		@ pull extra args off the stack
+	ldr	r5, [sp, #56]		@ load extra args from the stack
 	dsb				@ flush buffered writes to interconnect
 	cmp	r3, #0x2
 	blne	configure_sdrc
@@ -59,7 +63,11 @@ ENTRY(omap3_sram_configure_core_dpll)
 	bleq	wait_dll_unlock
 	blne	wait_dll_lock
 	cmp	r3, #0x1
-	blne	configure_sdrc
+	beq	return_to_sdram
+	bl	configure_sdrc
+	mov	r12, r5			@ if slowing, wait for SDRC to stabilize
+	bl	wait_clk_stable
+return_to_sdram:
 	isb				@ prevent speculative exec past here
 	mov 	r0, #0 			@ return value
 	ldmfd	sp!, {r1-r12, pc}	@ restore regs and return
@@ -106,16 +114,6 @@ configure_core_dpll:
 wait_clk_stable:
 	subs 	r12, r12, #1
 	bne	wait_clk_stable
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
-	nop
 	bx	lr
 enable_sdrc:
 	ldr 	r11, omap3_cm_iclken1_core
diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
index 8ce41e0..54913fc 100644
--- a/arch/arm/plat-omap/include/mach/sram.h
+++ b/arch/arm/plat-omap/include/mach/sram.h
@@ -24,7 +24,7 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
 				     u32 sdrc_actim_ctrla,
 				     u32 sdrc_actim_ctrlb, u32 m2,
-				     u32 unlock_dll);
+				     u32 unlock_dll, u32 f);
 extern void omap3_sram_restore_context(void);
 
 /* Do not use these */
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 65fcfdf..8d27e91 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -371,9 +371,11 @@ static inline int omap243x_sram_init(void)
 static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
 					      u32 sdrc_actim_ctrla,
 					      u32 sdrc_actim_ctrlb,
-					      u32 m2, u32 unlock_dll);
+					      u32 m2, u32 unlock_dll,
+					      u32 f);
 u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
-			      u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll)
+			      u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll,
+			      u32 f)
  {
 	if (!_omap3_sram_configure_core_dpll)
 		omap_sram_error();
@@ -381,7 +383,7 @@ u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
 	return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
 					       sdrc_actim_ctrla,
 					       sdrc_actim_ctrlb, m2,
-					       unlock_dll);
+					       unlock_dll, f);
  }
 
 #ifdef CONFIG_PM
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 14/23] OMAP3 clock/SDRC: program SDRC_MR register during SDRC clock change
  2008-12-11 15:52                         ` [PATCH 13/23] OMAP3 clock: add a short delay when lowering CORE clk rate Tero Kristo
@ 2008-12-11 15:52                           ` Tero Kristo
  2008-12-11 15:52                             ` [PATCH 15/23] OMAP3 SRAM: add more comments on the SRAM code Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Program the SDRC_MR_0 register as well during SDRC clock changes.
This register allows selection of the memory CAS latency.  Some SDRAM
chips, such as the Qimonda HYB18M512160AF6, have a lower CAS latency
at lower clock rates.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/clock34xx.c        |    4 ++--
 arch/arm/mach-omap2/sram34xx.S         |    8 +++++++-
 arch/arm/plat-omap/include/mach/sram.h |    2 +-
 arch/arm/plat-omap/sram.c              |    6 +++---
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 8ef0186..47a8465 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -548,10 +548,10 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	/* REVISIT: SRAM code doesn't support other M2 divisors yet */
 	WARN_ON(new_div != 1 && new_div != 2);
 
-	/* REVISIT: Add SDRC_MR changing to this code also */
 	local_irq_disable();
 	omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
-				  sp->actim_ctrlb, new_div, unlock_dll, c);
+				  sp->actim_ctrlb, new_div, unlock_dll, c,
+				  sp->mr);
 	local_irq_enable();
 
 	omap2_clksel_recalc(clk);
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 8d4a88c..d13f1cc 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -44,12 +44,14 @@
  *      SDRC rates < 83MHz
  * r5 = number of MPU cycles to wait for SDRC to stabilize after
  *      reprogramming the SDRC when switching to a slower MPU speed
+ * r6 = SDRC_MR_0 register value
  *
  */
 ENTRY(omap3_sram_configure_core_dpll)
 	stmfd	sp!, {r1-r12, lr}	@ store regs to stack
 	ldr	r4, [sp, #52]		@ pull extra args off the stack
 	ldr	r5, [sp, #56]		@ load extra args from the stack
+	ldr	r6, [sp, #60]		@ load extra args from the stack
 	dsb				@ flush buffered writes to interconnect
 	cmp	r3, #0x2
 	blne	configure_sdrc
@@ -151,7 +153,9 @@ configure_sdrc:
 	str	r1, [r11]
 	ldr	r11, omap3_sdrc_actim_ctrlb
 	str	r2, [r11]
-	ldr	r2, [r11]		@ posted-write barrier for SDRC
+	ldr	r11, omap3_sdrc_mr_0
+	str	r6, [r11]
+	ldr	r6, [r11]		@ posted-write barrier for SDRC
 	bx	lr
 
 omap3_sdrc_power:
@@ -168,6 +172,8 @@ omap3_sdrc_actim_ctrla:
 	.word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
 omap3_sdrc_actim_ctrlb:
 	.word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
+omap3_sdrc_mr_0:
+	.word OMAP34XX_SDRC_REGADDR(SDRC_MR_0)
 omap3_sdrc_dlla_status:
 	.word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
 omap3_sdrc_dlla_ctrl:
diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
index 54913fc..d07da3b 100644
--- a/arch/arm/plat-omap/include/mach/sram.h
+++ b/arch/arm/plat-omap/include/mach/sram.h
@@ -24,7 +24,7 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
 				     u32 sdrc_actim_ctrla,
 				     u32 sdrc_actim_ctrlb, u32 m2,
-				     u32 unlock_dll, u32 f);
+				     u32 unlock_dll, u32 f, u32 sdrc_mr);
 extern void omap3_sram_restore_context(void);
 
 /* Do not use these */
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 8d27e91..68a1f69 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -372,10 +372,10 @@ static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
 					      u32 sdrc_actim_ctrla,
 					      u32 sdrc_actim_ctrlb,
 					      u32 m2, u32 unlock_dll,
-					      u32 f);
+					      u32 f, u32 sdrc_mr);
 u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
 			      u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll,
-			      u32 f)
+			      u32 f, u32 sdrc_mr)
  {
 	if (!_omap3_sram_configure_core_dpll)
 		omap_sram_error();
@@ -383,7 +383,7 @@ u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
 	return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
 					       sdrc_actim_ctrla,
 					       sdrc_actim_ctrlb, m2,
-					       unlock_dll, f);
+					       unlock_dll, f, sdrc_mr);
  }
 
 #ifdef CONFIG_PM
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 15/23] OMAP3 SRAM: add more comments on the SRAM code
  2008-12-11 15:52                           ` [PATCH 14/23] OMAP3 clock/SDRC: program SDRC_MR register during SDRC clock change Tero Kristo
@ 2008-12-11 15:52                             ` Tero Kristo
  2008-12-11 15:52                               ` [PATCH 16/23] OMAP3 SRAM: convert SRAM code to use macros rather than magic numbers Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Clean up comments and copyrights on the CORE DPLL3 M2 divider change code.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sram34xx.S |   45 +++++++++++++++++++++------------------
 1 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index d13f1cc..37a1e1f 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -3,13 +3,12 @@
  *
  * Omap3 specific functions that need to be run in internal SRAM
  *
- * (C) Copyright 2007
- * Texas Instruments Inc.
- * Rajendra Nayak <rnayak@ti.com>
+ * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
  *
- * (C) Copyright 2004
- * Texas Instruments, <www.ti.com>
+ * Rajendra Nayak <rnayak@ti.com>
  * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -38,13 +37,16 @@
 	.text
 
 /*
- * Change frequency of core dpll
- * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
- * r4 = Unlock SDRC DLL? (1 = yes, 0 = no) -- only unlock DLL for
+ * omap3_sram_configure_core_dpll - change DPLL3 M2 divider
+ * r0 = new SDRC_RFR_CTRL register contents
+ * r1 = new SDRC_ACTIM_CTRLA register contents
+ * r2 = new SDRC_ACTIM_CTRLB register contents
+ * r3 = new M2 divider setting (only 1 and 2 supported right now)
+ * r4 = unlock SDRC DLL? (1 = yes, 0 = no).  Only unlock DLL for
  *      SDRC rates < 83MHz
  * r5 = number of MPU cycles to wait for SDRC to stabilize after
  *      reprogramming the SDRC when switching to a slower MPU speed
- * r6 = SDRC_MR_0 register value
+ * r6 = new SDRC_MR_0 register value
  *
  */
 ENTRY(omap3_sram_configure_core_dpll)
@@ -53,22 +55,22 @@ ENTRY(omap3_sram_configure_core_dpll)
 	ldr	r5, [sp, #56]		@ load extra args from the stack
 	ldr	r6, [sp, #60]		@ load extra args from the stack
 	dsb				@ flush buffered writes to interconnect
-	cmp	r3, #0x2
-	blne	configure_sdrc
-	cmp	r4, #0x1
+	cmp	r3, #0x2		@ if increasing SDRC clk rate,
+	blne	configure_sdrc		@ program the SDRC regs early (for RFR)
+	cmp	r4, #0x1		@ set the intended DLL state
 	bleq	unlock_dll
 	blne	lock_dll
-	bl	sdram_in_selfrefresh	@ put the SDRAM in self refresh
-	bl 	configure_core_dpll
-	bl	enable_sdrc
-	cmp	r4, #0x1
+	bl	sdram_in_selfrefresh	@ put SDRAM in self refresh, idle SDRC
+	bl 	configure_core_dpll	@ change the DPLL3 M2 divider
+	bl	enable_sdrc		@ take SDRC out of idle
+	cmp	r4, #0x1		@ wait for DLL status to change
 	bleq	wait_dll_unlock
 	blne	wait_dll_lock
-	cmp	r3, #0x1
-	beq	return_to_sdram
-	bl	configure_sdrc
-	mov	r12, r5			@ if slowing, wait for SDRC to stabilize
-	bl	wait_clk_stable
+	cmp	r3, #0x1		@ if increasing SDRC clk rate,
+	beq	return_to_sdram		@ return to SDRAM code, otherwise,
+	bl	configure_sdrc		@ reprogram SDRC regs now
+	mov	r12, r5
+	bl	wait_clk_stable		@ wait for SDRC to stabilize
 return_to_sdram:
 	isb				@ prevent speculative exec past here
 	mov 	r0, #0 			@ return value
@@ -93,6 +95,7 @@ sdram_in_selfrefresh:
 	bic 	r12, r12, #0x4		@ clear PWDENA
 	str 	r12, [r11]		@ write back to SDRC_POWER register
 	ldr	r12, [r11]		@ posted-write barrier for SDRC
+idle_sdrc:
 	ldr	r11, omap3_cm_iclken1_core	@ read the CM_ICLKEN1_CORE reg
 	ldr	r12, [r11]
 	bic	r12, r12, #0x2		@ disable iclk bit for SDRC
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 16/23] OMAP3 SRAM: convert SRAM code to use macros rather than magic numbers
  2008-12-11 15:52                             ` [PATCH 15/23] OMAP3 SRAM: add more comments on the SRAM code Tero Kristo
@ 2008-12-11 15:52                               ` Tero Kristo
  2008-12-11 15:52                                 ` [PATCH 17/23] OMAP3: PM: Fixed VDD2 control to work from both sysfs and SRF API Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap; +Cc: Paul Walmsley

From: Paul Walmsley <paul@pwsan.com>

Convert omap3_sram_configure_core_dpll() to use macros rather than
magic numbers.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
---
 arch/arm/mach-omap2/sram34xx.S |   53 ++++++++++++++++++++++++++++-----------
 1 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 37a1e1f..16eb4ef 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -36,6 +36,29 @@
 
 	.text
 
+/* r4 parameters */
+#define SDRC_NO_UNLOCK_DLL		0x0
+#define SDRC_UNLOCK_DLL			0x1
+
+/* SDRC_DLLA_CTRL bit settings */
+#define DLLIDLE_MASK			0x4
+
+/* SDRC_DLLA_STATUS bit settings */
+#define LOCKSTATUS_MASK			0x4
+
+/* SDRC_POWER bit settings */
+#define SRFRONIDLEREQ_MASK		0x40
+#define PWDENA_MASK			0x4
+
+/* CM_IDLEST1_CORE bit settings */
+#define ST_SDRC_MASK			0x2
+
+/* CM_ICLKEN1_CORE bit settings */
+#define EN_SDRC_MASK			0x2
+
+/* CM_CLKSEL1_PLL bit settings */
+#define CORE_DPLL_CLKOUT_DIV_SHIFT	0x1b
+
 /*
  * omap3_sram_configure_core_dpll - change DPLL3 M2 divider
  * r0 = new SDRC_RFR_CTRL register contents
@@ -57,13 +80,13 @@ ENTRY(omap3_sram_configure_core_dpll)
 	dsb				@ flush buffered writes to interconnect
 	cmp	r3, #0x2		@ if increasing SDRC clk rate,
 	blne	configure_sdrc		@ program the SDRC regs early (for RFR)
-	cmp	r4, #0x1		@ set the intended DLL state
+	cmp	r4, #SDRC_UNLOCK_DLL	@ set the intended DLL state
 	bleq	unlock_dll
 	blne	lock_dll
 	bl	sdram_in_selfrefresh	@ put SDRAM in self refresh, idle SDRC
 	bl 	configure_core_dpll	@ change the DPLL3 M2 divider
 	bl	enable_sdrc		@ take SDRC out of idle
-	cmp	r4, #0x1		@ wait for DLL status to change
+	cmp	r4, #SDRC_UNLOCK_DLL	@ wait for DLL status to change
 	bleq	wait_dll_unlock
 	blne	wait_dll_lock
 	cmp	r3, #0x1		@ if increasing SDRC clk rate,
@@ -78,33 +101,33 @@ return_to_sdram:
 unlock_dll:
 	ldr	r11, omap3_sdrc_dlla_ctrl
 	ldr	r12, [r11]
-	orr	r12, r12, #0x4
+	orr	r12, r12, #DLLIDLE_MASK
 	str	r12, [r11]		@ (no OCP barrier needed)
 	bx	lr
 lock_dll:
 	ldr	r11, omap3_sdrc_dlla_ctrl
 	ldr	r12, [r11]
-	bic	r12, r12, #0x4
+	bic	r12, r12, #DLLIDLE_MASK
 	str	r12, [r11]		@ (no OCP barrier needed)
 	bx	lr
 sdram_in_selfrefresh:
 	ldr	r11, omap3_sdrc_power	@ read the SDRC_POWER register
 	ldr	r12, [r11]		@ read the contents of SDRC_POWER
 	mov	r9, r12			@ keep a copy of SDRC_POWER bits
-	orr 	r12, r12, #0x40		@ enable self refresh on idle req
-	bic 	r12, r12, #0x4		@ clear PWDENA
+	orr 	r12, r12, #SRFRONIDLEREQ_MASK	@ enable self refresh on idle
+	bic 	r12, r12, #PWDENA_MASK	@ clear PWDENA
 	str 	r12, [r11]		@ write back to SDRC_POWER register
 	ldr	r12, [r11]		@ posted-write barrier for SDRC
 idle_sdrc:
 	ldr	r11, omap3_cm_iclken1_core	@ read the CM_ICLKEN1_CORE reg
 	ldr	r12, [r11]
-	bic	r12, r12, #0x2		@ disable iclk bit for SDRC
+	bic	r12, r12, #EN_SDRC_MASK		@ disable iclk bit for SDRC
 	str 	r12, [r11]
 wait_sdrc_idle:
 	ldr 	r11, omap3_cm_idlest1_core
 	ldr 	r12, [r11]
-	and 	r12, r12, #0x2		@ check for SDRC idle
-	cmp 	r12, #2
+	and 	r12, r12, #ST_SDRC_MASK		@ check for SDRC idle
+	cmp 	r12, #ST_SDRC_MASK
 	bne 	wait_sdrc_idle
 	bx 	lr
 configure_core_dpll:
@@ -112,7 +135,7 @@ configure_core_dpll:
 	ldr	r12, [r11]
 	ldr	r10, core_m2_mask_val	@ modify m2 for core dpll
 	and	r12, r12, r10
-	orr	r12, r12, r3, lsl #0x1B	@ r3 contains the M2 val
+	orr	r12, r12, r3, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT
 	str	r12, [r11]
 	ldr	r12, [r11]		@ posted-write barrier for CM
 	bx	lr
@@ -123,12 +146,12 @@ wait_clk_stable:
 enable_sdrc:
 	ldr 	r11, omap3_cm_iclken1_core
 	ldr	r12, [r11]
-	orr 	r12, r12, #0x2		@ enable iclk bit for SDRC
+	orr 	r12, r12, #EN_SDRC_MASK		@ enable iclk bit for SDRC
 	str 	r12, [r11]
 wait_sdrc_idle1:
 	ldr 	r11, omap3_cm_idlest1_core
 	ldr	r12, [r11]
-	and 	r12, r12, #0x2
+	and 	r12, r12, #ST_SDRC_MASK
 	cmp	r12, #0
 	bne	wait_sdrc_idle1
 restore_sdrc_power_val:
@@ -138,14 +161,14 @@ restore_sdrc_power_val:
 wait_dll_lock:
 	ldr	r11, omap3_sdrc_dlla_status
 	ldr	r12, [r11]
-	and 	r12, r12, #0x4
-	cmp	r12, #0x4
+	and 	r12, r12, #LOCKSTATUS_MASK
+	cmp	r12, #LOCKSTATUS_MASK
 	bne	wait_dll_lock
 	bx	lr
 wait_dll_unlock:
 	ldr	r11, omap3_sdrc_dlla_status
 	ldr	r12, [r11]
-	and	r12, r12, #0x4
+	and	r12, r12, #LOCKSTATUS_MASK
 	cmp	r12, #0x0
 	bne	wait_dll_unlock
 	bx	lr
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 17/23] OMAP3: PM: Fixed VDD2 control to work from both sysfs and SRF API
  2008-12-11 15:52                               ` [PATCH 16/23] OMAP3 SRAM: convert SRAM code to use macros rather than magic numbers Tero Kristo
@ 2008-12-11 15:52                                 ` Tero Kristo
  2008-12-11 15:52                                   ` [PATCH 18/23] OMAP3: PM: Added DVFS OPP locking interface for VDD1 and VDD2 Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

SRF API for setting throughput requirement attempted to use throughput values
as parameter to set_opp() and sysfs was attempting to use OPP levels (1..3.)

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/pm.c                   |    5 +-
 arch/arm/mach-omap2/pm.h                   |    1 +
 arch/arm/mach-omap2/resource34xx.c         |   62 ++++++++++++++++++----------
 arch/arm/plat-omap/include/mach/omap34xx.h |    4 ++
 4 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 285f596..2dd1341 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -61,7 +61,6 @@ static struct kobj_attribute voltage_off_while_idle_attr =
 	__ATTR(voltage_off_while_idle, 0644, idle_show, idle_store);
 
 #ifdef CONFIG_OMAP_PM_SRF
-static struct device dummy_sysfs_dev;
 static ssize_t vdd_opp_show(struct kobject *, struct kobj_attribute *, char *);
 static ssize_t vdd_opp_store(struct kobject *k, struct kobj_attribute *,
 			  const char *buf, size_t n);
@@ -145,13 +144,13 @@ static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-		resource_request("vdd1_opp", &dummy_sysfs_dev, value);
+		set_opp_level(VDD1_OPP, value);
 	} else if (attr == &vdd2_opp_attr) {
 		if (value < 2 || value > 3) {
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-		resource_request("vdd2_opp", &dummy_sysfs_dev, value);
+		set_opp_level(VDD2_OPP, value);
 	} else {
 		return -EINVAL;
 	}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index a209819..4c0052f 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -42,6 +42,7 @@ extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
 #define omap3_pm_set_suspend_state(pwrdm,state) do {} while (0);
 #endif
 extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int set_opp_level(int res, u32 target_level);
 
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index 034318b..d2c4e1f 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -135,6 +135,8 @@ int set_pd_latency(struct shared_resource *resp, u32 latency)
 
 static struct clk *vdd1_clk;
 static struct clk *vdd2_clk;
+static struct shared_resource *vdd1_resp;
+static struct shared_resource *vdd2_resp;
 static struct device dummy_mpu_dev;
 static struct device dummy_dsp_dev;
 
@@ -154,19 +156,27 @@ void init_opp(struct shared_resource *resp)
 	if (strcmp(resp->name, "vdd1_opp") == 0) {
 		resp->curr_level = curr_vdd1_prcm_set->opp_id;
 		vdd1_clk = clk_get(NULL, "virt_vdd1_prcm_set");
+		vdd1_resp = resp;
 	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
 		resp->curr_level = curr_vdd2_prcm_set->opp_id;
 		vdd2_clk = clk_get(NULL, "virt_vdd2_prcm_set");
+		vdd2_resp = resp;
 	}
 	return;
 }
 
-int set_opp(struct shared_resource *resp, u32 target_level)
+int set_opp_level(int res, u32 target_level)
 {
-	unsigned long mpu_freq, mpu_old_freq, l3_freq, tput, t_opp;
-	int ind;
-	struct bus_throughput_db *tput_db;
+	unsigned long mpu_freq, mpu_old_freq, l3_freq, t_opp;
 	struct cpufreq_freqs freqs_notify;
+	struct shared_resource *resp;
+
+	if (res == VDD1_OPP)
+		resp = vdd1_resp;
+	else if (res == VDD2_OPP)
+		resp = vdd2_resp;
+	else
+		return 0;
 
 	if (resp->curr_level == target_level)
 		return 0;
@@ -174,7 +184,7 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 	if (!mpu_opps || !dsp_opps || !l3_opps)
 		return 0;
 
-	if (strcmp(resp->name, "vdd1_opp") == 0) {
+	if (res == VDD1_OPP) {
 		mpu_old_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
 					curr_vdd1_prcm_set->opp_id);
 		mpu_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
@@ -208,23 +218,7 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 		/* Send a post notification to CPUFreq */
 		cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
 #endif
-	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
-		tput_db = resp->resource_data;
-		tput = target_level;
-		/* using the throughput db map to the appropriate L3 Freq */
-		for (ind = 1; ind < MAX_VDD2_OPP; ind++)
-			if (tput_db->throughput[ind] > tput)
-				target_level = ind;
-
-		/* Set the highest OPP possible */
-		if (ind == MAX_VDD2_OPP)
-			target_level = ind-1;
-
-		if (resp->curr_level == target_level)
-			return 0;
-
-		resp->curr_level = target_level;
-
+	} else {
 		l3_freq = get_freq(l3_opps + MAX_VDD2_OPP,
 					target_level);
 		t_opp = ID_VDD(PRCM_VDD2) |
@@ -249,6 +243,30 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 	return 0;
 }
 
+int set_opp(struct shared_resource *resp, u32 target_level)
+{
+	unsigned long tput;
+	int ind;
+	struct bus_throughput_db *tput_db;
+
+	if (resp == vdd1_resp) {
+		set_opp_level(VDD1_OPP, target_level);
+	} else if (resp == vdd2_resp) {
+		tput_db = resp->resource_data;
+		tput = target_level;
+		/* using the throughput db map to the appropriate L3 Freq */
+		for (ind = 1; ind < MAX_VDD2_OPP; ind++)
+			if (tput_db->throughput[ind] > tput)
+				target_level = ind;
+
+		/* Set the highest OPP possible */
+		if (ind == MAX_VDD2_OPP)
+			target_level = ind-1;
+		set_opp_level(VDD2_OPP, target_level);
+	}
+	return 0;
+}
+
 /**
  * validate_opp - Validates if valid VDD1 OPP's are passed as the
  * target_level.
diff --git a/arch/arm/plat-omap/include/mach/omap34xx.h b/arch/arm/plat-omap/include/mach/omap34xx.h
index b64375e..6db9a6c 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -72,6 +72,10 @@
 #define OMAP34XX_DSP_IPI_BASE	(OMAP34XX_DSP_BASE + 0x1000000)
 #define OMAP34XX_DSP_MMU_BASE	(OMAP34XX_DSP_BASE + 0x2000000)
 
+/* VDD OPP identifiers */
+#define VDD1_OPP	0x1
+#define VDD2_OPP	0x2
+
 /* VDD1 OPPS */
 #define VDD1_OPP1	0x1
 #define VDD1_OPP2	0x2
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 18/23] OMAP3: PM: Added DVFS OPP locking interface for VDD1 and VDD2
  2008-12-11 15:52                                 ` [PATCH 17/23] OMAP3: PM: Fixed VDD2 control to work from both sysfs and SRF API Tero Kristo
@ 2008-12-11 15:52                                   ` Tero Kristo
  2008-12-11 15:52                                     ` [PATCH 19/23] OMAP3: Fix rate calculation bug in omap3_select_table_rate Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

Added two new files under /sys/power for controlling OPP locks. vdd1_lock and
vdd2_lock. You can write to these to select desired OPP level and it will be
locked at that level. Lock can be cleared by writing 0 to the same file.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/pm.c           |   55 ++++++++++++++++++++++++++++++++++-
 arch/arm/mach-omap2/pm.h           |    8 ++++-
 arch/arm/mach-omap2/resource34xx.c |   24 +++++++++++++--
 3 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 2dd1341..155bd8d 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -43,6 +43,8 @@ unsigned short clocks_off_while_idle;
 unsigned short enable_off_mode;
 unsigned short voltage_off_while_idle;
 atomic_t sleep_block = ATOMIC_INIT(0);
+static int vdd1_locked;
+static int vdd2_locked;
 
 static ssize_t idle_show(struct kobject *, struct kobj_attribute *, char *);
 static ssize_t idle_store(struct kobject *k, struct kobj_attribute *,
@@ -69,6 +71,11 @@ static struct kobj_attribute vdd1_opp_attr =
 
 static struct kobj_attribute vdd2_opp_attr =
 	__ATTR(vdd2_opp, 0644, vdd_opp_show, vdd_opp_store);
+static struct kobj_attribute vdd1_lock_attr =
+	__ATTR(vdd1_lock, 0644, vdd_opp_show, vdd_opp_store);
+static struct kobj_attribute vdd2_lock_attr =
+	__ATTR(vdd2_lock, 0644, vdd_opp_show, vdd_opp_store);
+
 #endif
 
 static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
@@ -127,6 +134,10 @@ static ssize_t vdd_opp_show(struct kobject *kobj, struct kobj_attribute *attr,
 		return sprintf(buf, "%hu\n", resource_get_level("vdd1_opp"));
 	else if (attr == &vdd2_opp_attr)
 		return sprintf(buf, "%hu\n", resource_get_level("vdd2_opp"));
+	else if (attr == &vdd1_lock_attr)
+		return sprintf(buf, "%hu\n", resource_get_opp_lock(VDD1_OPP));
+	else if (attr == &vdd2_lock_attr)
+		return sprintf(buf, "%hu\n", resource_get_opp_lock(VDD2_OPP));
 	else
 		return -EINVAL;
 }
@@ -135,22 +146,50 @@ static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 			  const char *buf, size_t n)
 {
 	unsigned short value;
+	int flags = 0;
 
 	if (sscanf(buf, "%hu", &value) != 1)
 		return -EINVAL;
 
+	/* Check locks */
+	if (attr == &vdd1_lock_attr) {
+		flags = OPP_IGNORE_LOCK;
+		attr = &vdd1_opp_attr;
+		if (vdd1_locked && value == 0) {
+			resource_unlock_opp(VDD1_OPP);
+			vdd1_locked = 0;
+			return n;
+		}
+		if (vdd1_locked == 0 && value != 0) {
+			resource_lock_opp(VDD1_OPP);
+			vdd1_locked = 1;
+		}
+	} else if (attr == &vdd2_lock_attr) {
+		flags = OPP_IGNORE_LOCK;
+		attr = &vdd2_opp_attr;
+		if (vdd2_locked && value == 0) {
+			resource_unlock_opp(VDD2_OPP);
+			vdd2_locked = 0;
+			return n;
+		}
+		if (vdd2_locked == 0 && value != 0) {
+			resource_lock_opp(VDD2_OPP);
+			vdd2_locked = 1;
+		}
+	}
+
 	if (attr == &vdd1_opp_attr) {
 		if (value < 1 || value > 5) {
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-		set_opp_level(VDD1_OPP, value);
+		resource_set_opp_level(VDD1_OPP, value, flags);
 	} else if (attr == &vdd2_opp_attr) {
 		if (value < 2 || value > 3) {
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-		set_opp_level(VDD2_OPP, value);
+		resource_set_opp_level(VDD2_OPP, value, flags);
 	} else {
 		return -EINVAL;
 	}
@@ -227,6 +266,18 @@ static int __init omap_pm_init(void)
 		printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
 		return error;
 	}
+
+	error = sysfs_create_file(power_kobj, &vdd1_lock_attr.attr);
+	if (error) {
+		printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
+		return error;
+	}
+
+	error = sysfs_create_file(power_kobj, &vdd2_lock_attr.attr);
+	if (error) {
+		printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
+		return error;
+	}
 #endif
 	voltage_off_while_idle = 0;
 	/* Going to 0V on anything under ES2.1 will eventually cause a crash */
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 4c0052f..4f98c86 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -42,7 +42,13 @@ extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
 #define omap3_pm_set_suspend_state(pwrdm,state) do {} while (0);
 #endif
 extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
-extern int set_opp_level(int res, u32 target_level);
+extern int resource_set_opp_level(int res, u32 target_level, int flags);
+extern int resource_access_opp_lock(int res, int delta);
+#define resource_lock_opp(res) resource_access_opp_lock(res, 1)
+#define resource_unlock_opp(res) resource_access_opp_lock(res, -1)
+#define resource_get_opp_lock(res) resource_access_opp_lock(res, 0)
+
+#define OPP_IGNORE_LOCK 0x1
 
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index d2c4e1f..e52260d 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -139,6 +139,8 @@ static struct shared_resource *vdd1_resp;
 static struct shared_resource *vdd2_resp;
 static struct device dummy_mpu_dev;
 static struct device dummy_dsp_dev;
+static int vdd1_lock;
+static int vdd2_lock;
 
 /**
  * init_opp - Initialize the OPP resource
@@ -165,7 +167,19 @@ void init_opp(struct shared_resource *resp)
 	return;
 }
 
-int set_opp_level(int res, u32 target_level)
+int resource_access_opp_lock(int res, int delta)
+{
+	if (res == VDD1_OPP) {
+		vdd1_lock += delta;
+		return vdd1_lock;
+	} else if (res == VDD2_OPP) {
+		vdd2_lock += delta;
+		return vdd2_lock;
+	}
+	return -EINVAL;
+}
+
+int resource_set_opp_level(int res, u32 target_level, int flags)
 {
 	unsigned long mpu_freq, mpu_old_freq, l3_freq, t_opp;
 	struct cpufreq_freqs freqs_notify;
@@ -185,6 +199,8 @@ int set_opp_level(int res, u32 target_level)
 		return 0;
 
 	if (res == VDD1_OPP) {
+		if (flags != OPP_IGNORE_LOCK && vdd1_lock)
+			return 0;
 		mpu_old_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
 					curr_vdd1_prcm_set->opp_id);
 		mpu_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
@@ -219,6 +235,8 @@ int set_opp_level(int res, u32 target_level)
 		cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
 #endif
 	} else {
+		if (flags != OPP_IGNORE_LOCK && vdd2_lock)
+			return 0;
 		l3_freq = get_freq(l3_opps + MAX_VDD2_OPP,
 					target_level);
 		t_opp = ID_VDD(PRCM_VDD2) |
@@ -250,7 +268,7 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 	struct bus_throughput_db *tput_db;
 
 	if (resp == vdd1_resp) {
-		set_opp_level(VDD1_OPP, target_level);
+		resource_set_opp_level(VDD1_OPP, target_level, 0);
 	} else if (resp == vdd2_resp) {
 		tput_db = resp->resource_data;
 		tput = target_level;
@@ -262,7 +280,7 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 		/* Set the highest OPP possible */
 		if (ind == MAX_VDD2_OPP)
 			target_level = ind-1;
-		set_opp_level(VDD2_OPP, target_level);
+		resource_set_opp_level(VDD2_OPP, target_level, 0);
 	}
 	return 0;
 }
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 19/23] OMAP3: Fix rate calculation bug in omap3_select_table_rate
  2008-12-11 15:52                                   ` [PATCH 18/23] OMAP3: PM: Added DVFS OPP locking interface for VDD1 and VDD2 Tero Kristo
@ 2008-12-11 15:52                                     ` Tero Kristo
  2008-12-11 15:52                                       ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

L3 divisor is not taken into account when trying to set DPLL3 clock.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/clock34xx.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 47a8465..cfd7f0f 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -939,6 +939,7 @@ static int omap3_select_table_rate(struct clk *clk, unsigned long rate)
 	struct omap_opp *prcm_vdd;
 	unsigned long found_speed = 0, curr_mpu_speed;
 	int index;
+	int l3_div;
 
 	if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))
 		return -EINVAL;
@@ -984,7 +985,9 @@ static int omap3_select_table_rate(struct clk *clk, unsigned long rate)
 					curr_mpu_speed/1000, found_speed/1000);
 #endif
 	} else {
-		clk_set_rate(dpll3_clk, prcm_vdd->rate);
+		l3_div = cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+			OMAP3430_CLKSEL_L3_MASK;
+		clk_set_rate(dpll3_clk, prcm_vdd->rate * l3_div);
 		curr_vdd2_prcm_set = prcm_vdd;
 		omap2_clksel_recalc(&core_ck);
 		propagate_rate(&core_ck);
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2
  2008-12-11 15:52                                     ` [PATCH 19/23] OMAP3: Fix rate calculation bug in omap3_select_table_rate Tero Kristo
@ 2008-12-11 15:52                                       ` Tero Kristo
  2008-12-11 15:52                                         ` [PATCH 21/23] OMAP3: PM: Prevented DVFS state switches when enabling off-mode Tero Kristo
  2008-12-11 16:06                                         ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Paul Walmsley
  0 siblings, 2 replies; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

Previously only 1 and 2 was supported. This is needed for DVFS VDD2 control.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/clock34xx.c        |    9 +++------
 arch/arm/mach-omap2/sram34xx.S         |    7 ++++---
 arch/arm/plat-omap/include/mach/sram.h |    7 +++++--
 arch/arm/plat-omap/sram.c              |    6 +++---
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index cfd7f0f..55b1425 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -516,9 +516,9 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 
 	sdrcrate = sdrc_ick.rate;
 	if (rate > clk->rate)
-		sdrcrate <<= ((rate / clk->rate) - 1);
+		sdrcrate <<= ((rate / clk->rate) >> 1);
 	else
-		sdrcrate >>= ((clk->rate / rate) - 1);
+		sdrcrate >>= ((clk->rate / rate) >> 1);
 
 	sp = omap2_sdrc_get_params(sdrcrate);
 	if (!sp)
@@ -545,13 +545,10 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 	pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
 		 sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
 
-	/* REVISIT: SRAM code doesn't support other M2 divisors yet */
-	WARN_ON(new_div != 1 && new_div != 2);
-
 	local_irq_disable();
 	omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
 				  sp->actim_ctrlb, new_div, unlock_dll, c,
-				  sp->mr);
+				  sp->mr, rate > clk->rate);
 	local_irq_enable();
 
 	omap2_clksel_recalc(clk);
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 16eb4ef..832cd76 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -70,6 +70,7 @@
  * r5 = number of MPU cycles to wait for SDRC to stabilize after
  *      reprogramming the SDRC when switching to a slower MPU speed
  * r6 = new SDRC_MR_0 register value
+ * r7 = increasing SDRC rate? (1 = yes, 0 = no)
  *
  */
 ENTRY(omap3_sram_configure_core_dpll)
@@ -78,8 +79,8 @@ ENTRY(omap3_sram_configure_core_dpll)
 	ldr	r5, [sp, #56]		@ load extra args from the stack
 	ldr	r6, [sp, #60]		@ load extra args from the stack
 	dsb				@ flush buffered writes to interconnect
-	cmp	r3, #0x2		@ if increasing SDRC clk rate,
-	blne	configure_sdrc		@ program the SDRC regs early (for RFR)
+	cmp	r7, #1			@ if increasing SDRC clk rate,
+	bleq	configure_sdrc		@ program the SDRC regs early (for RFR)
 	cmp	r4, #SDRC_UNLOCK_DLL	@ set the intended DLL state
 	bleq	unlock_dll
 	blne	lock_dll
@@ -89,7 +90,7 @@ ENTRY(omap3_sram_configure_core_dpll)
 	cmp	r4, #SDRC_UNLOCK_DLL	@ wait for DLL status to change
 	bleq	wait_dll_unlock
 	blne	wait_dll_lock
-	cmp	r3, #0x1		@ if increasing SDRC clk rate,
+	cmp	r7, #1			@ if increasing SDRC clk rate,
 	beq	return_to_sdram		@ return to SDRAM code, otherwise,
 	bl	configure_sdrc		@ reprogram SDRC regs now
 	mov	r12, r5
diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
index d07da3b..ad0a600 100644
--- a/arch/arm/plat-omap/include/mach/sram.h
+++ b/arch/arm/plat-omap/include/mach/sram.h
@@ -24,7 +24,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
 				     u32 sdrc_actim_ctrla,
 				     u32 sdrc_actim_ctrlb, u32 m2,
-				     u32 unlock_dll, u32 f, u32 sdrc_mr);
+				     u32 unlock_dll, u32 f, u32 sdrc_mr,
+				     u32 inc);
 extern void omap3_sram_restore_context(void);
 
 /* Do not use these */
@@ -62,7 +63,9 @@ extern unsigned long omap243x_sram_reprogram_sdrc_sz;
 
 extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
 					  u32 sdrc_actim_ctrla,
-					  u32 sdrc_actim_ctrlb, u32 m2);
+					  u32 sdrc_actim_ctrlb, u32 m2,
+					  u32 unlock_dll, u32 f, u32 sdrc_mr,
+					  u32 inc);
 extern unsigned long omap3_sram_configure_core_dpll_sz;
 
 #ifdef CONFIG_PM
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 68a1f69..9f6232f 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -372,10 +372,10 @@ static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
 					      u32 sdrc_actim_ctrla,
 					      u32 sdrc_actim_ctrlb,
 					      u32 m2, u32 unlock_dll,
-					      u32 f, u32 sdrc_mr);
+					      u32 f, u32 sdrc_mr, u32 inc);
 u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
 			      u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll,
-			      u32 f, u32 sdrc_mr)
+			      u32 f, u32 sdrc_mr, u32 inc)
  {
 	if (!_omap3_sram_configure_core_dpll)
 		omap_sram_error();
@@ -383,7 +383,7 @@ u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
 	return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
 					       sdrc_actim_ctrla,
 					       sdrc_actim_ctrlb, m2,
-					       unlock_dll, f, sdrc_mr);
+					       unlock_dll, f, sdrc_mr, inc);
  }
 
 #ifdef CONFIG_PM
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 21/23] OMAP3: PM: Prevented DVFS state switches when enabling off-mode
  2008-12-11 15:52                                       ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Tero Kristo
@ 2008-12-11 15:52                                         ` Tero Kristo
  2008-12-11 15:52                                           ` [PATCH 22/23] OMAP3: PM: Enable VDD2 OPP1 Tero Kristo
  2008-12-11 16:06                                         ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Paul Walmsley
  1 sibling, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

resource_refresh() call tried to refresh DVFS OPP levels also. This should
eventually be fixed in a way that DVFS VDD2 level is actually governed by
something.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/pm34xx.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index e0c952e..7367f68 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -783,8 +783,12 @@ void omap3_pm_off_mode_enable(int enable)
 		state = PWRDM_POWER_RET;
 
 #ifdef CONFIG_OMAP_PM_SRF
+	resource_lock_opp(VDD1_OPP);
+	resource_lock_opp(VDD2_OPP);
 	if (resource_refresh())
 		printk(KERN_ERR "Error: could not refresh resources\n");
+	resource_unlock_opp(VDD1_OPP);
+	resource_unlock_opp(VDD2_OPP);
 #endif
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		pwrst->next_state = state;
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 22/23] OMAP3: PM: Enable VDD2 OPP1
  2008-12-11 15:52                                         ` [PATCH 21/23] OMAP3: PM: Prevented DVFS state switches when enabling off-mode Tero Kristo
@ 2008-12-11 15:52                                           ` Tero Kristo
  2008-12-11 15:52                                             ` [PATCH 23/23] OMAP3: PM: Fix linker error without CONFIG_PM option Tero Kristo
  0 siblings, 1 reply; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

VDD2 OPP1 works at least with minimal kernel setup, there are some corner
cases where it fails though, like when you use USB. Board setup should make
sure and enable only working OPPs.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/pm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 155bd8d..1c6c93a 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -185,7 +185,7 @@ static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 		}
 		resource_set_opp_level(VDD1_OPP, value, flags);
 	} else if (attr == &vdd2_opp_attr) {
-		if (value < 2 || value > 3) {
+		if (value < 1 || value > 3) {
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 23/23] OMAP3: PM: Fix linker error without CONFIG_PM option
  2008-12-11 15:52                                           ` [PATCH 22/23] OMAP3: PM: Enable VDD2 OPP1 Tero Kristo
@ 2008-12-11 15:52                                             ` Tero Kristo
  0 siblings, 0 replies; 32+ messages in thread
From: Tero Kristo @ 2008-12-11 15:52 UTC (permalink / raw)
  To: linux-omap

omap3_save_scratchpad_contents() is not available without CONFIG_PM.

Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
---
 arch/arm/mach-omap2/clock34xx.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 55b1425..b38cb30 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -990,7 +990,9 @@ static int omap3_select_table_rate(struct clk *clk, unsigned long rate)
 		propagate_rate(&core_ck);
 	}
 
+#ifdef CONFIG_PM
 	omap3_save_scratchpad_contents();
+#endif
 
 	return 0;
 }
-- 
1.5.4.3


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2
  2008-12-11 15:52                                       ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Tero Kristo
  2008-12-11 15:52                                         ` [PATCH 21/23] OMAP3: PM: Prevented DVFS state switches when enabling off-mode Tero Kristo
@ 2008-12-11 16:06                                         ` Paul Walmsley
  2008-12-11 16:38                                           ` Tero.Kristo
  1 sibling, 1 reply; 32+ messages in thread
From: Paul Walmsley @ 2008-12-11 16:06 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap

Hi Tero

one comment on this patch ...

On Thu, 11 Dec 2008, Tero Kristo wrote:

> Previously only 1 and 2 was supported. This is needed for DVFS VDD2 control.

> diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
> index 16eb4ef..832cd76 100644
> --- a/arch/arm/mach-omap2/sram34xx.S
> +++ b/arch/arm/mach-omap2/sram34xx.S
> @@ -70,6 +70,7 @@
>   * r5 = number of MPU cycles to wait for SDRC to stabilize after
>   *      reprogramming the SDRC when switching to a slower MPU speed
>   * r6 = new SDRC_MR_0 register value
> + * r7 = increasing SDRC rate? (1 = yes, 0 = no)
>   *
>   */
>  ENTRY(omap3_sram_configure_core_dpll)
> @@ -78,8 +79,8 @@ ENTRY(omap3_sram_configure_core_dpll)
>  	ldr	r5, [sp, #56]		@ load extra args from the stack
>  	ldr	r6, [sp, #60]		@ load extra args from the stack

you will also need a

	ldr     r7, [sp, #64]           @ load extra args from the stack

here

>  	dsb				@ flush buffered writes to interconnect
> -	cmp	r3, #0x2		@ if increasing SDRC clk rate,
> -	blne	configure_sdrc		@ program the SDRC regs early (for RFR)
> +	cmp	r7, #1			@ if increasing SDRC clk rate,
> +	bleq	configure_sdrc		@ program the SDRC regs early (for RFR)
>  	cmp	r4, #SDRC_UNLOCK_DLL	@ set the intended DLL state
>  	bleq	unlock_dll
>  	blne	lock_dll
> @@ -89,7 +90,7 @@ ENTRY(omap3_sram_configure_core_dpll)
>  	cmp	r4, #SDRC_UNLOCK_DLL	@ wait for DLL status to change
>  	bleq	wait_dll_unlock
>  	blne	wait_dll_lock
> -	cmp	r3, #0x1		@ if increasing SDRC clk rate,
> +	cmp	r7, #1			@ if increasing SDRC clk rate,
>  	beq	return_to_sdram		@ return to SDRAM code, otherwise,
>  	bl	configure_sdrc		@ reprogram SDRC regs now
>  	mov	r12, r5
> diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
> index d07da3b..ad0a600 100644
> --- a/arch/arm/plat-omap/include/mach/sram.h
> +++ b/arch/arm/plat-omap/include/mach/sram.h
> @@ -24,7 +24,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
>  extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
>  				     u32 sdrc_actim_ctrla,
>  				     u32 sdrc_actim_ctrlb, u32 m2,
> -				     u32 unlock_dll, u32 f, u32 sdrc_mr);
> +				     u32 unlock_dll, u32 f, u32 sdrc_mr,
> +				     u32 inc);
>  extern void omap3_sram_restore_context(void);
>  
>  /* Do not use these */
> @@ -62,7 +63,9 @@ extern unsigned long omap243x_sram_reprogram_sdrc_sz;
>  
>  extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
>  					  u32 sdrc_actim_ctrla,
> -					  u32 sdrc_actim_ctrlb, u32 m2);
> +					  u32 sdrc_actim_ctrlb, u32 m2,
> +					  u32 unlock_dll, u32 f, u32 sdrc_mr,
> +					  u32 inc);
>  extern unsigned long omap3_sram_configure_core_dpll_sz;
>  
>  #ifdef CONFIG_PM
> diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
> index 68a1f69..9f6232f 100644
> --- a/arch/arm/plat-omap/sram.c
> +++ b/arch/arm/plat-omap/sram.c
> @@ -372,10 +372,10 @@ static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
>  					      u32 sdrc_actim_ctrla,
>  					      u32 sdrc_actim_ctrlb,
>  					      u32 m2, u32 unlock_dll,
> -					      u32 f, u32 sdrc_mr);
> +					      u32 f, u32 sdrc_mr, u32 inc);
>  u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
>  			      u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll,
> -			      u32 f, u32 sdrc_mr)
> +			      u32 f, u32 sdrc_mr, u32 inc)
>   {
>  	if (!_omap3_sram_configure_core_dpll)
>  		omap_sram_error();
> @@ -383,7 +383,7 @@ u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
>  	return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
>  					       sdrc_actim_ctrla,
>  					       sdrc_actim_ctrlb, m2,
> -					       unlock_dll, f, sdrc_mr);
> +					       unlock_dll, f, sdrc_mr, inc);
>   }
>  
>  #ifdef CONFIG_PM
> -- 
> 1.5.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


- Paul

^ permalink raw reply	[flat|nested] 32+ messages in thread

* RE: [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2
  2008-12-11 16:06                                         ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Paul Walmsley
@ 2008-12-11 16:38                                           ` Tero.Kristo
  0 siblings, 0 replies; 32+ messages in thread
From: Tero.Kristo @ 2008-12-11 16:38 UTC (permalink / raw)
  To: paul; +Cc: linux-omap

Hi,

>Hi Tero
>
>one comment on this patch ...
>
>On Thu, 11 Dec 2008, Tero Kristo wrote:
>
>> Previously only 1 and 2 was supported. This is needed for 
>DVFS VDD2 control.
>
>> diff --git a/arch/arm/mach-omap2/sram34xx.S 
>> b/arch/arm/mach-omap2/sram34xx.S index 16eb4ef..832cd76 100644
>> --- a/arch/arm/mach-omap2/sram34xx.S
>> +++ b/arch/arm/mach-omap2/sram34xx.S
>> @@ -70,6 +70,7 @@
>>   * r5 = number of MPU cycles to wait for SDRC to stabilize after
>>   *      reprogramming the SDRC when switching to a slower MPU speed
>>   * r6 = new SDRC_MR_0 register value
>> + * r7 = increasing SDRC rate? (1 = yes, 0 = no)
>>   *
>>   */
>>  ENTRY(omap3_sram_configure_core_dpll)
>> @@ -78,8 +79,8 @@ ENTRY(omap3_sram_configure_core_dpll)
>>  	ldr	r5, [sp, #56]		@ load extra args from the stack
>>  	ldr	r6, [sp, #60]		@ load extra args from the stack
>
>you will also need a
>
>	ldr     r7, [sp, #64]           @ load extra args from the stack
>
>here

Woops. Resending in a bit.

Funny though that this patch does not seem to affect system stability
too
much at initial testing, it did not cause any crash when I tried this
out.
Might cause problems in longer run / stress testing.

>>  	dsb				@ flush buffered writes 
>to interconnect
>> -	cmp	r3, #0x2		@ if increasing SDRC clk rate,
>> -	blne	configure_sdrc		@ program the SDRC regs 
>early (for RFR)
>> +	cmp	r7, #1			@ if increasing SDRC clk rate,
>> +	bleq	configure_sdrc		@ program the SDRC regs 
>early (for RFR)
>>  	cmp	r4, #SDRC_UNLOCK_DLL	@ set the intended DLL state
>>  	bleq	unlock_dll
>>  	blne	lock_dll
>> @@ -89,7 +90,7 @@ ENTRY(omap3_sram_configure_core_dpll)
>>  	cmp	r4, #SDRC_UNLOCK_DLL	@ wait for DLL status to change
>>  	bleq	wait_dll_unlock
>>  	blne	wait_dll_lock
>> -	cmp	r3, #0x1		@ if increasing SDRC clk rate,
>> +	cmp	r7, #1			@ if increasing SDRC clk rate,
>>  	beq	return_to_sdram		@ return to SDRAM code, 
>otherwise,
>>  	bl	configure_sdrc		@ reprogram SDRC regs now
>>  	mov	r12, r5
>> diff --git a/arch/arm/plat-omap/include/mach/sram.h 
>> b/arch/arm/plat-omap/include/mach/sram.h
>> index d07da3b..ad0a600 100644
>> --- a/arch/arm/plat-omap/include/mach/sram.h
>> +++ b/arch/arm/plat-omap/include/mach/sram.h
>> @@ -24,7 +24,8 @@ extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 
>> sdrc_rfr_val, int bypass);  extern u32 
>omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
>>  				     u32 sdrc_actim_ctrla,
>>  				     u32 sdrc_actim_ctrlb, u32 m2,
>> -				     u32 unlock_dll, u32 f, u32 
>sdrc_mr);
>> +				     u32 unlock_dll, u32 f, u32 sdrc_mr,
>> +				     u32 inc);
>>  extern void omap3_sram_restore_context(void);
>>  
>>  /* Do not use these */
>> @@ -62,7 +63,9 @@ extern unsigned long 
>> omap243x_sram_reprogram_sdrc_sz;
>>  
>>  extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
>>  					  u32 sdrc_actim_ctrla,
>> -					  u32 sdrc_actim_ctrlb, u32 m2);
>> +					  u32 sdrc_actim_ctrlb, u32 m2,
>> +					  u32 unlock_dll, u32 
>f, u32 sdrc_mr,
>> +					  u32 inc);
>>  extern unsigned long omap3_sram_configure_core_dpll_sz;
>>  
>>  #ifdef CONFIG_PM
>> diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c 
>> index 68a1f69..9f6232f 100644
>> --- a/arch/arm/plat-omap/sram.c
>> +++ b/arch/arm/plat-omap/sram.c
>> @@ -372,10 +372,10 @@ static u32 
>(*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
>>  					      u32 sdrc_actim_ctrla,
>>  					      u32 sdrc_actim_ctrlb,
>>  					      u32 m2, u32 unlock_dll,
>> -					      u32 f, u32 sdrc_mr);
>> +					      u32 f, u32 
>sdrc_mr, u32 inc);
>>  u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 
>sdrc_actim_ctrla,
>>  			      u32 sdrc_actim_ctrlb, u32 m2, u32 
>unlock_dll,
>> -			      u32 f, u32 sdrc_mr)
>> +			      u32 f, u32 sdrc_mr, u32 inc)
>>   {
>>  	if (!_omap3_sram_configure_core_dpll)
>>  		omap_sram_error();
>> @@ -383,7 +383,7 @@ u32 omap3_configure_core_dpll(u32 
>sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
>>  	return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
>>  					       sdrc_actim_ctrla,
>>  					       sdrc_actim_ctrlb, m2,
>> -					       unlock_dll, f, sdrc_mr);
>> +					       unlock_dll, f, 
>sdrc_mr, inc);
>>   }
>>  
>>  #ifdef CONFIG_PM
>> --
>> 1.5.4.3
>> 
>> --
>> To unsubscribe from this list: send the line "unsubscribe 
>linux-omap" 
>> in the body of a message to majordomo@vger.kernel.org More majordomo 
>> info at  http://vger.kernel.org/majordomo-info.html
>> 
>
>
>- Paul
>

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: OMAP3: DVFS core patch set
  2008-12-11 15:52 OMAP3: DVFS core patch set Tero Kristo
  2008-12-11 15:52 ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tero Kristo
@ 2008-12-12  1:59 ` Paul Walmsley
  2008-12-18  8:22   ` Paul Walmsley
  2008-12-15 21:48 ` Kevin Hilman
  2 siblings, 1 reply; 32+ messages in thread
From: Paul Walmsley @ 2008-12-12  1:59 UTC (permalink / raw)
  To: linux-omap; +Cc: Tero Kristo, peter.de-schrijver


Hello,

For anyone interested, here are some worst case measurements for CORE DVFS 
transition times with patches 1-16.

The test board was a 3430SDP ES2.0 GP.  Tests were run both with and 
without changing the VDD2 voltage; and at two different MPU frequencies.

No voltage change:
MPU @ 381MHz: 13 ticks (0.40 ms) worst-case
MPU @  83MHz: 38 ticks (1.19 ms) worst-case

With voltage change:
MPU @ 381MHz: 34 ticks (1.04 ms) worst-case
MPU @  83MHz: 130 ticks (3.97 ms) worst-case

Some important notes:

* Mean CORE DVFS times will be quite a bit lower, based on eyeballing the 
individual test run durations.  Variability was quite high; the above 
numbers would probably be considered outliers.

* The TI "September 11" u-boot on this board programs the CORE DPLL for a 
slightly derated frequency.  This causes the SDRC DLL to unlock on 
transitions to a lower frequency, and causes it to relock on transitions 
to a higher frequency.  Since a fixed bootloader would use 83000000 Hz and 
166000000 Hz, the DLL would lock at both frequencies, which may affect the 
above figures.

* Environmental parameters weren't tracked since the board is remote.

* Since the 32KiHz sync timer was used, there is a max roundoff 
variability of ((1/32768) * 2) seconds, or about 61 microseconds.

* The test script and additional test patches are available upon request 
by E-mailing me.

* I did not test at the highest MPU rate, for no real reason aside from 
381MHz is what the bootloader set the MPU to

* The tests were relatively short-duration; perhaps a few hundred 
transitions in each case.


Commentary:

* The variability caused by MPU rate was quite surprising.  I thought that 
the bulk of the time in this process would be MPU rate-invariant.


- Paul

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type
  2008-12-11 15:52 ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tero Kristo
  2008-12-11 15:52   ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tero Kristo
@ 2008-12-15 19:06   ` Tony Lindgren
  2008-12-15 19:58     ` Paul Walmsley
  1 sibling, 1 reply; 32+ messages in thread
From: Tony Lindgren @ 2008-12-15 19:06 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, Paul Walmsley

* Tero Kristo <tero.kristo@nokia.com> [081211 07:59]:
> From: Paul Walmsley <paul@pwsan.com>
> 
> Add a Non-cacheable Normal ARM executable memory type,
> MT_MEMORY_NONCACHED.  This is needed for the OMAP3 SDRAM clock change
> code, which must run from SRAM.  The SRAM must be marked as
> non-cacheable memory to avoid dirty cache line writebacks to SDRAM
> while the SDRAM controller is paused.

This should be discussed on LAKML.

Tony

> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> ---
>  arch/arm/include/asm/mach/map.h |    1 +
>  arch/arm/mm/mmu.c               |   23 +++++++++++++++++++++++
>  2 files changed, 24 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
> index 39d949b..58cf91f 100644
> --- a/arch/arm/include/asm/mach/map.h
> +++ b/arch/arm/include/asm/mach/map.h
> @@ -26,6 +26,7 @@ struct map_desc {
>  #define MT_HIGH_VECTORS		8
>  #define MT_MEMORY		9
>  #define MT_ROM			10
> +#define MT_MEMORY_NONCACHED	11
>  
>  #ifdef CONFIG_MMU
>  extern void iotable_init(struct map_desc *, int);
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index 7f36c82..9ad6413 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -242,6 +242,10 @@ static struct mem_type mem_types[] = {
>  		.prot_sect = PMD_TYPE_SECT,
>  		.domain    = DOMAIN_KERNEL,
>  	},
> +	[MT_MEMORY_NONCACHED] = {
> +		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
> +		.domain    = DOMAIN_KERNEL,
> +	},
>  };
>  
>  const struct mem_type *get_mem_type(unsigned int type)
> @@ -405,9 +409,28 @@ static void __init build_mem_type_table(void)
>  		kern_pgprot |= L_PTE_SHARED;
>  		vecs_pgprot |= L_PTE_SHARED;
>  		mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
> +		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
>  #endif
>  	}
>  
> +	/*
> +	 * Non-cacheable Normal - intended for memory areas that must
> +	 * not cause cache line evictions when used
> +	 */
> +	if (cpu_arch >= CPU_ARCH_ARMv6) {
> +		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
> +			/* Non-cacheable Normal is XCB = 001 */
> +			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
> +				PMD_SECT_BUFFERED;
> +		} else {
> +			/* For both ARMv6 and non-TEX-remapping ARMv7 */
> +			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
> +				PMD_SECT_TEX(1);
> +		}
> +	} else {
> +		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
> +	}
> +
>  	for (i = 0; i < 16; i++) {
>  		unsigned long v = pgprot_val(protection_map[i]);
>  		protection_map[i] = __pgprot(v | user_pgprot);
> -- 
> 1.5.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory
  2008-12-11 15:52   ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tero Kristo
  2008-12-11 15:52     ` [PATCH 03/23] OMAP3 SRAM: add ARM barriers to omap3_sram_configure_core_dpll Tero Kristo
@ 2008-12-15 19:07     ` Tony Lindgren
  1 sibling, 0 replies; 32+ messages in thread
From: Tony Lindgren @ 2008-12-15 19:07 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap, Paul Walmsley

* Tero Kristo <tero.kristo@nokia.com> [081211 07:58]:
> From: Paul Walmsley <paul@pwsan.com>
> 
> Mark the SRAM (aka OCM RAM) as Non-cacheable Normal memory[1].  This
> is to prevent the ARM from evicting existing cache lines to SDRAM
> while code is executing from the SRAM.  Necessary since one of the
> primary uses for the SRAM is to hold the code and data for the CORE
> DPLL M2 divider reprogramming code, which must execute while the SDRC
> is idled.  If the ARM attempts to write cache lines back to the while
> the SRAM code is running, the ARM will stall[2].
> 
> TI deals with this problem in the CDP kernel by marking the SRAM as
> Strongly-ordered memory.
> 
> Tero Kristo <tero.kristo@nokia.com> caught a bug in an earlier version of
> this patch - thanks Tero.

As I talked with Paul, we might want to set up two sections in SRAM.
One section that is cached and another that is not.

Tony

> 
> ...
> 
> 1. ARMv7 ARM (DDI 0406A) pp. A3-30, A3-31, B3-32.
> 
> 2. Private communication with Richard Woodruff <r-woodruff2@ti.com>
> 
> Signed-off-by: Paul Walmsley <paul@pwsan.com>
> Cc: Tero Kristo <tero.kristo@nokia.com>
> Cc: Richard Woodruff <r-woodruff2@ti.com>
> ---
>  arch/arm/plat-omap/sram.c |    9 +++++++++
>  1 files changed, 9 insertions(+), 0 deletions(-)
>  mode change 100755 => 100644 arch/arm/plat-omap/sram.c
> 
> diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
> old mode 100755
> new mode 100644
> index abcc05b..04214e1
> --- a/arch/arm/plat-omap/sram.c
> +++ b/arch/arm/plat-omap/sram.c
> @@ -207,6 +207,15 @@ void __init omap_map_sram(void)
>  		base = OMAP3_SRAM_PA;
>  		base = ROUND_DOWN(base, PAGE_SIZE);
>  		omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
> +
> +		/*
> +		 * SRAM must be marked as non-cached on OMAP3 since the
> +		 * CORE DPLL M2 divider change code (in SRAM) runs with the
> +		 * SDRAM controller disabled, and if it is marked cached,
> +		 * the ARM may attempt to write cache lines back to SDRAM
> +		 * which will cause the system to hang.
> +		 */
> +		omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED;
>  	}
>  
>  	omap_sram_io_desc[0].length = 1024 * 1024;	/* Use section desc */
> -- 
> 1.5.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type
  2008-12-15 19:06   ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tony Lindgren
@ 2008-12-15 19:58     ` Paul Walmsley
  0 siblings, 0 replies; 32+ messages in thread
From: Paul Walmsley @ 2008-12-15 19:58 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Tero Kristo, linux-omap

On Mon, 15 Dec 2008, Tony Lindgren wrote:

> * Tero Kristo <tero.kristo@nokia.com> [081211 07:59]:
> > From: Paul Walmsley <paul@pwsan.com>
> > 
> > Add a Non-cacheable Normal ARM executable memory type,
> > MT_MEMORY_NONCACHED.  This is needed for the OMAP3 SDRAM clock change
> > code, which must run from SRAM.  The SRAM must be marked as
> > non-cacheable memory to avoid dirty cache line writebacks to SDRAM
> > while the SDRAM controller is paused.
> 
> This should be discussed on LAKML.

Yeah, it's my understanding that these patches are targeted for the PM 
branch.


- Paul

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: OMAP3: DVFS core patch set
  2008-12-11 15:52 OMAP3: DVFS core patch set Tero Kristo
  2008-12-11 15:52 ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tero Kristo
  2008-12-12  1:59 ` OMAP3: DVFS core patch set Paul Walmsley
@ 2008-12-15 21:48 ` Kevin Hilman
  2 siblings, 0 replies; 32+ messages in thread
From: Kevin Hilman @ 2008-12-15 21:48 UTC (permalink / raw)
  To: Tero Kristo; +Cc: linux-omap

Tero Kristo <tero.kristo@nokia.com> writes:

> This patch set provides DVFS support for OMAP3. First 16 patches contain
> clock framework modifications from Paul Walmsley, which are needed for VDD2
> OPP clock control to work properly. Rest of the patches are misc fixes for
> DVFS control, providing locking interface for OPPs and providing support
> for DPLL3 M2 rates higher than 2.

Tero, Paul,

It seems most of these can be applied dirctly to l-o, correct?  

Can you separate this out into two series?  One which goes straight to
l-o for all the SRAM, SDRC and clock stuff.  And a separate one which
applies to the PM branch for the DVFS fixes, updates etc.

Thanks,

Kevin

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: OMAP3: DVFS core patch set
  2008-12-12  1:59 ` OMAP3: DVFS core patch set Paul Walmsley
@ 2008-12-18  8:22   ` Paul Walmsley
  0 siblings, 0 replies; 32+ messages in thread
From: Paul Walmsley @ 2008-12-18  8:22 UTC (permalink / raw)
  To: linux-omap; +Cc: Tero Kristo, peter.de-schrijver


a quick followup on this:

On Thu, 11 Dec 2008, Paul Walmsley wrote:

> With voltage change:
> MPU @  83MHz: 130 ticks (3.97 ms) worst-case

It recently occurred to me that part of this 130 tick time is due to the 
udelay()s in the SmartReflex code.  My test code did not update 
loops_per_jiffy when it did the MPU rate, so the udelay()s there would 
loop for longer than they should.  So that needs to be fixed and 
re-measured.

Presumably further improvements would be gained by converting 
sr_voltagescale_vcbypass() to be interrupt-driven, rather than polling for 
the voltage change to complete.  That should reduce the CORE DVFS 
time further.


- Paul

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2008-12-18  8:22 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-12-11 15:52 OMAP3: DVFS core patch set Tero Kristo
2008-12-11 15:52 ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tero Kristo
2008-12-11 15:52   ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tero Kristo
2008-12-11 15:52     ` [PATCH 03/23] OMAP3 SRAM: add ARM barriers to omap3_sram_configure_core_dpll Tero Kristo
2008-12-11 15:52       ` [PATCH 04/23] OMAP3 clock: add interconnect barriers to CORE DPLL M2 change Tero Kristo
2008-12-11 15:52         ` [PATCH 05/23] OMAP3 SRAM: clear the SDRC PWRENA bit during SDRC frequency change Tero Kristo
2008-12-11 15:52           ` [PATCH 06/23] OMAP3 SDRC: Add 166MHz, 83MHz SDRC settings for the BeagleBoard Tero Kristo
2008-12-11 15:52             ` [PATCH 07/23] OMAP3 SDRC: initialize SDRC_POWER at boot Tero Kristo
2008-12-11 15:52               ` [PATCH 08/23] OMAP3 SRAM: renumber registers to make space for argument passing Tero Kristo
2008-12-11 15:52                 ` [PATCH 09/23] OMAP3 clock: only unlock SDRC DLL if SDRC clk < 83MHz Tero Kristo
2008-12-11 15:52                   ` [PATCH 10/23] OMAP3 clock: use pr_debug() rather than pr_info() in some clock change code Tero Kristo
2008-12-11 15:52                     ` [PATCH 11/23] OMAP3 clock: remove wait for DPLL3 M2 clock to stabilize Tero Kristo
2008-12-11 15:52                       ` [PATCH 12/23] OMAP3 clock: initialize SDRC timings at kernel start Tero Kristo
2008-12-11 15:52                         ` [PATCH 13/23] OMAP3 clock: add a short delay when lowering CORE clk rate Tero Kristo
2008-12-11 15:52                           ` [PATCH 14/23] OMAP3 clock/SDRC: program SDRC_MR register during SDRC clock change Tero Kristo
2008-12-11 15:52                             ` [PATCH 15/23] OMAP3 SRAM: add more comments on the SRAM code Tero Kristo
2008-12-11 15:52                               ` [PATCH 16/23] OMAP3 SRAM: convert SRAM code to use macros rather than magic numbers Tero Kristo
2008-12-11 15:52                                 ` [PATCH 17/23] OMAP3: PM: Fixed VDD2 control to work from both sysfs and SRF API Tero Kristo
2008-12-11 15:52                                   ` [PATCH 18/23] OMAP3: PM: Added DVFS OPP locking interface for VDD1 and VDD2 Tero Kristo
2008-12-11 15:52                                     ` [PATCH 19/23] OMAP3: Fix rate calculation bug in omap3_select_table_rate Tero Kristo
2008-12-11 15:52                                       ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Tero Kristo
2008-12-11 15:52                                         ` [PATCH 21/23] OMAP3: PM: Prevented DVFS state switches when enabling off-mode Tero Kristo
2008-12-11 15:52                                           ` [PATCH 22/23] OMAP3: PM: Enable VDD2 OPP1 Tero Kristo
2008-12-11 15:52                                             ` [PATCH 23/23] OMAP3: PM: Fix linker error without CONFIG_PM option Tero Kristo
2008-12-11 16:06                                         ` [PATCH 20/23] OMAP3: Add support for DPLL3 divisor values higher than 2 Paul Walmsley
2008-12-11 16:38                                           ` Tero.Kristo
2008-12-15 19:07     ` [PATCH 02/23] OMAP3 SRAM: mark OCM RAM as Non-cacheable Normal memory Tony Lindgren
2008-12-15 19:06   ` [PATCH 01/23] ARM: MMU: add a Non-cacheable Normal executable memory type Tony Lindgren
2008-12-15 19:58     ` Paul Walmsley
2008-12-12  1:59 ` OMAP3: DVFS core patch set Paul Walmsley
2008-12-18  8:22   ` Paul Walmsley
2008-12-15 21:48 ` Kevin Hilman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.