--- Begin Message ---
Author: werner
Date: 2008-03-25 09:53:27 +0100 (Tue, 25 Mar 2008)
New Revision: 4244
Modified:
branches/src/target/kernel/2.6.24.x/patches/smedia-glamo.patch
Log:
Subject: [PATCH] fix-glamo-reissue-memory-settings-during-resume.patch
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 <[EMAIL PROTECTED]>
---
drivers/mfd/glamo/glamo-core.c | 93 ++++++++++++++++++++++++++++++----------
drivers/mfd/glamo/glamo-core.h | 2 -
2 files changed, 71 insertions(+), 24 deletions(-)
Modified: branches/src/target/kernel/2.6.24.x/patches/smedia-glamo.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/smedia-glamo.patch
2008-03-25 07:51:24 UTC (rev 4243)
+++ branches/src/target/kernel/2.6.24.x/patches/smedia-glamo.patch
2008-03-25 08:53:27 UTC (rev 4244)
@@ -522,7 +522,7 @@
===================================================================
--- /dev/null
+++ linux-2.6.24/drivers/mfd/glamo/glamo-core.c
-@@ -0,0 +1,1097 @@
+@@ -0,0 +1,1151 @@
+/* Smedia Glamo 336x/337x driver
+ *
+ * (C) 2007 by OpenMoko, Inc.
@@ -1101,19 +1101,31 @@
+ ***********************************************************************/
+
+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;
@@ -1122,7 +1134,7 @@
+
+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 },
@@ -1137,8 +1149,8 @@
+ { 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 },
@@ -1156,11 +1168,9 @@
+ { 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
@@ -1204,7 +1214,42 @@
+ { 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 = {
+ { GLAMO_REG_CLOCK_MEMORY, 0x3aaa },
@@ -1281,6 +1326,11 @@
+ /* 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);
@@ -1288,7 +1338,10 @@
+ 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 */
++
++ glamo_run_script(glamo, glamo_resume_script,
++ ARRAY_SIZE(glamo_resume_script), 0);
++
+ break;
+ case GLAMO_POWER_STANDBY:
+ /* enable memory self-refresh */
@@ -1527,7 +1580,8 @@
+ 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),
@@ -2612,7 +2666,7 @@
+};
+
+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,
--- End Message ---
--- Begin Message ---
Author: erin_yueh
Date: 2008-03-25 11:33:45 +0100 (Tue, 25 Mar 2008)
New Revision: 4245
Modified:
trunk/src/target/gsm/src/gsmd/unsolicited.c
Log:
gsmd: fix clip & colp parser problem (Erin Yueh)
Modified: trunk/src/target/gsm/src/gsmd/unsolicited.c
===================================================================
--- trunk/src/target/gsm/src/gsmd/unsolicited.c 2008-03-25 08:53:27 UTC (rev
4244)
+++ trunk/src/target/gsm/src/gsmd/unsolicited.c 2008-03-25 10:33:45 UTC (rev
4245)
@@ -348,24 +348,32 @@
struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT,
GSMD_EVT_IN_CLIP,
sizeof(struct gsmd_evt_auxdata));
struct gsmd_evt_auxdata *aux;
- const char *comma = strchr(param, ',');
+ struct gsm_extrsp *er;
- if (!ucmd)
+ if (!ucmd)
return -ENOMEM;
aux = (struct gsmd_evt_auxdata *) ucmd->buf;
- if (!comma)
- return -EINVAL;
+ er = extrsp_parse(gsmd_tallocs, param);
-
- if (comma - param > GSMD_ADDR_MAXLEN)
+ if ( !er )
+ return -ENOMEM;
+
+ if ( er->num_tokens >= 2 &&
+ er->tokens[0].type == GSMD_ECMD_RTT_STRING &&
+ er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) {
+ /*
+ * <number>,<type>[,<subaddr>,<satype>[,[<alpha>][,<CLI
validity>]]]
+ */
+
+ strcpy(aux->u.clip.addr.number, er->tokens[0].u.string);
+ aux->u.clip.addr.type = er->tokens[1].u.numeric;
+ } else {
+ DEBUGP("Invalid Input : Parse error\n");
return -EINVAL;
+ }
- aux->u.clip.addr.number[0] = '\0';
- strncat(aux->u.clip.addr.number, param, comma-param);
- /* FIXME: parse of subaddr, etc. */
-
return usock_evt_send(gsmd, ucmd, GSMD_EVT_IN_CLIP);
}
@@ -376,23 +384,32 @@
struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT,
GSMD_EVT_OUT_COLP,
sizeof(struct gsmd_evt_auxdata));
struct gsmd_evt_auxdata *aux;
- const char *comma = strchr(param, ',');
+ struct gsm_extrsp *er;
if (!ucmd)
return -ENOMEM;
aux = (struct gsmd_evt_auxdata *) ucmd->buf;
- if (!comma)
+ er = extrsp_parse(gsmd_tallocs, param);
+
+ if ( !er )
+ return -ENOMEM;
+
+ if ( er->num_tokens >= 2 &&
+ er->tokens[0].type == GSMD_ECMD_RTT_STRING &&
+ er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC ) {
+ /*
+ * <number>,<type>[,<subaddr>,<satype> [,<alpha>]]
+ */
+
+ strcpy(aux->u.colp.addr.number, er->tokens[0].u.string);
+ aux->u.colp.addr.type = er->tokens[1].u.numeric;
+ } else {
+ DEBUGP("Invalid Input : Parse error\n");
return -EINVAL;
+ }
- if (comma - param > GSMD_ADDR_MAXLEN)
- return -EINVAL;
-
- aux->u.colp.addr.number[0] = '\0';
- strncat(aux->u.colp.addr.number, param, comma-param);
- /* FIXME: parse of subaddr, etc. */
-
return usock_evt_send(gsmd, ucmd, GSMD_EVT_OUT_COLP);
}
--- End Message ---