[PATCH] fix-glamo-reissue-memory-settings-during-resume.patch

Andy Green andy at openmoko.com
Mon Mar 24 15:46:43 CET 2008


The "black snow" effect after resume seems to be caused by the
memory in the glamo needing to be reset after the
"deep power down".  This patch rewrites a subset of registers in
that area on resume (reinitializing them all destroys the video
output action) and removes the black snow issue.

The "black snow" is logical corruption of the pixel data in the
glamo confirmed by locking a scope to VYSNC and looking at the
pixel data at the same offset over multiple frames, it was
changing frame by frame logically for the same offset.  So it
makes sense the underlying cause of problems here is the memory
in the Glamo.

Also, sometimes when the SD card was kicked into 16MHz speed after
resume it failed, this is also believed to be to the Glamo internal
memory which the SD peripheral also uses being in a bad state on
resume and this might also be helped.

Signed-off-by: Andy Green <andy at openmoko.com>
---

 drivers/mfd/glamo/glamo-core.c |   93 ++++++++++++++++++++++++++++++----------
 drivers/mfd/glamo/glamo-core.h |    2 -
 2 files changed, 71 insertions(+), 24 deletions(-)


diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index 68f1439..4eb3195 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -602,19 +602,31 @@ EXPORT_SYMBOL_GPL(glamo_engine_reclock);
  ***********************************************************************/
 
 int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
-		     int len)
+		     int len, int may_sleep)
 {
 	int i;
 
 	for (i = 0; i < len; i++) {
 		struct glamo_script *line = &script[i];
 
-		if (line->reg == 0xffff)
+		switch (line->reg) {
+		case 0xffff:
 			return 0;
-		else if (line->reg == 0xfffe)
-			msleep(line->val);
-		else
+		case 0xfffe:
+			if (may_sleep)
+				msleep(line->val);
+			else
+				mdelay(line->val);
+			break;
+		case 0xfffd:
+			/* spin until PLLs lock */
+			while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
+				;
+			break;
+		default:
 			__reg_write(glamo, script[i].reg, script[i].val);
+			break;
+		}
 	}
 
 	return 0;
@@ -623,7 +635,7 @@ EXPORT_SYMBOL(glamo_run_script);
 
 static struct glamo_script glamo_init_script[] = {
 	{ GLAMO_REG_CLOCK_HOST,		0x1000 },
-		{ 0xfffe, 1 },
+		{ 0xfffe, 2 },
 	{ GLAMO_REG_CLOCK_MEMORY, 	0x1000 },
 	{ GLAMO_REG_CLOCK_MEMORY,	0x2000 },
 	{ GLAMO_REG_CLOCK_LCD,		0x1000 },
@@ -638,8 +650,8 @@ static struct glamo_script glamo_init_script[] = {
 	{ GLAMO_REG_CLOCK_RISC1,	0x1000 },
 	{ GLAMO_REG_CLOCK_MPEG,		0x3000 },
 	{ GLAMO_REG_CLOCK_MPEG,		0x3000 },
-	{ GLAMO_REG_CLOCK_MPROC,	0x100f },
-		{ 0xfffe, 1 },
+	{ GLAMO_REG_CLOCK_MPROC,	0x1000 /*0x100f*/ },
+		{ 0xfffe, 2 },
 	{ GLAMO_REG_CLOCK_HOST,		0x0000 },
 	{ GLAMO_REG_CLOCK_MEMORY,	0x0000 },
 	{ GLAMO_REG_CLOCK_LCD,		0x0000 },
@@ -657,11 +669,9 @@ static struct glamo_script glamo_init_script[] = {
 	{ GLAMO_REG_CLOCK_MPEG,		0x0000 },
 	{ GLAMO_REG_CLOCK_MPEG,		0x0000 },
 #endif
-	{ GLAMO_REG_CLOCK_MPROC,	0x000f },
-		{ 0xfffe, 1 },
 	{ GLAMO_REG_PLL_GEN1,		0x05db },	/* 48MHz */
 	{ GLAMO_REG_PLL_GEN3,		0x09c3 },	/* 80MHz */
-		{ 0xfffe, 50 },
+		{ 0xfffd, 0 },
 	/*
 	 * b9 of this register MUST be zero to get any interrupts on INT#
 	 * the other set bits enable all the engine interrupt sources
@@ -676,13 +686,9 @@ static struct glamo_script glamo_init_script[] = {
 	{ 0x212,	0x0000 },
 	{ 0x214,	0x4000 },
 	{ 0x216,	0xf00e },
-	{ GLAMO_REG_MEM_TYPE,		0x0874 /*0x0874 */ }, /* 8MB, 16 word pg wr+rd */
-	{ GLAMO_REG_MEM_GEN,		0xff8f /*0xafaf*/ }, /* 63 grants min + max */
-	/*
-	 * the register below originally 0x0108 makes unreliable Glamo MMC
-	 * write operations.  Cranked to 0x05ad to add a wait state, the
-	 * unreliability is not seen after 4GB of write / read testing
-	 */
+	{ GLAMO_REG_MEM_TYPE,		0x0874 }, /* 8MB, 16 word pg wr+rd */
+	{ GLAMO_REG_MEM_GEN,		0xafaf }, /* 63 grants min + max */
+
 	{ GLAMO_REG_MEM_TIMING1,	0x0108 },
 	{ GLAMO_REG_MEM_TIMING2,	0x0010 }, /* Taa = 3 MCLK */
 	{ GLAMO_REG_MEM_TIMING3,	0x0000 },
@@ -705,6 +711,41 @@ static struct glamo_script glamo_init_script[] = {
 	{ GLAMO_REG_CLOCK_MEMORY,	0x000b },
 };
 
+static struct glamo_script glamo_resume_script[] = {
+	{ GLAMO_REG_IRQ_ENABLE,		0x01ff },
+	{ GLAMO_REG_CLOCK_GEN6,		0x2000 },
+	{ GLAMO_REG_CLOCK_GEN7,		0x0001 }, /* 0101 */
+	{ GLAMO_REG_CLOCK_GEN8,		0x0100 },
+	{ GLAMO_REG_CLOCK_HOST,		0x000d },
+	{ 0x200,	0x0ef0 },
+	{ 0x202, 	0x07ff },
+	{ 0x212,	0x0000 },
+	{ 0x214,	0x4000 },
+	{ 0x216,	0xf00e },
+	{ GLAMO_REG_MEM_TYPE,		0x0874 }, /* 8MB, 16 word pg wr+rd */
+	{ GLAMO_REG_MEM_GEN,		0xafaf }, /* 63 grants min + max */
+
+	{ GLAMO_REG_MEM_TIMING1,	0x0108 },
+	{ GLAMO_REG_MEM_TIMING2,	0x0010 }, /* Taa = 3 MCLK */
+	{ GLAMO_REG_MEM_TIMING3,	0x0000 },
+	{ GLAMO_REG_MEM_TIMING4,	0x0000 }, /* CE1# delay fall/rise */
+	{ GLAMO_REG_MEM_TIMING5,	0x0000 }, /* UB# LB# */
+	{ GLAMO_REG_MEM_TIMING6,	0x0000 }, /* OE# */
+	{ GLAMO_REG_MEM_TIMING7,	0x0000 }, /* WE# */
+	{ GLAMO_REG_MEM_TIMING8,	0x1002 }, /* MCLK delay, was 0x1000 */
+	{ GLAMO_REG_MEM_TIMING9,	0x6006 },
+	{ GLAMO_REG_MEM_TIMING10,	0x00ff },
+	{ GLAMO_REG_MEM_TIMING11,	0x0001 },
+	{ GLAMO_REG_MEM_POWER1,		0x0020 },
+	{ GLAMO_REG_MEM_POWER2,		0x0000 },
+	{ GLAMO_REG_MEM_DRAM1,		0x0000 },
+		{ 0xfffe, 1 },
+	{ GLAMO_REG_MEM_DRAM1,		0xc100 },
+		{ 0xfffe, 1 },
+	{ GLAMO_REG_MEM_DRAM1,		0xe100 },
+	{ GLAMO_REG_MEM_DRAM2,		0x01d6 },
+	{ GLAMO_REG_CLOCK_MEMORY,	0x000b },
+};
 
 #if 0 /* MM370 */
 static const struct glamo_script regs_vram_2mb = {
@@ -784,6 +825,11 @@ static void glamo_power(struct glamo_core *glamo,
 		/* power up PLL1 and PLL2 */
 		__reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN6, 0x0001, 0xffff);
 		__reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0x0000);
+
+		/* spin until PLL1 and PLL2 lock */
+		while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
+			;
+
 		/* enable memory clock and get it out of deep pwrdown */
 		__reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
 				   GLAMO_CLOCK_MEM_EN_MOCACLK, 0xffff);
@@ -791,10 +837,10 @@ static void glamo_power(struct glamo_core *glamo,
 				   GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0x0000);
 		__reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
 				   GLAMO_MEM_DRAM1_SELF_REFRESH, 0x0000);
-		/* FIXME: reset pll's */
-		/* spin until PLL1 lock */
-		while (!(__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 1))
-			;
+
+		glamo_run_script(glamo, glamo_resume_script,
+				 ARRAY_SIZE(glamo_resume_script), 0);
+
 		break;
 	case GLAMO_POWER_STANDBY:
 		/* enable memory self-refresh */
@@ -1121,7 +1167,8 @@ static int __init glamo_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, glamo);
 
 	dev_dbg(&glamo->pdev->dev, "running init script\n");
-	glamo_run_script(glamo, glamo_init_script, ARRAY_SIZE(glamo_init_script));
+	glamo_run_script(glamo, glamo_init_script,
+			 ARRAY_SIZE(glamo_init_script), 1);
 
 	dev_info(&glamo->pdev->dev, "Glamo core now %uHz CPU / %uHz Memory)\n",
 		 glamo_pll_rate(glamo, GLAMO_PLL1),
diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
index b56ee81..cf89f03 100644
--- a/drivers/mfd/glamo/glamo-core.h
+++ b/drivers/mfd/glamo/glamo-core.h
@@ -37,7 +37,7 @@ struct glamo_script {
 };
 
 int glamo_run_script(struct glamo_core *glamo,
-		     struct glamo_script *script, int len);
+		     struct glamo_script *script, int len, int may_sleep);
 
 enum glamo_engine {
 	GLAMO_ENGINE_CAPTURE,





More information about the openmoko-kernel mailing list