diff options
Diffstat (limited to 'target/linux/s3c24xx/patches/0138-fix-suspend-backlight-timing-pm-debug.patch.patch')
-rwxr-xr-x | target/linux/s3c24xx/patches/0138-fix-suspend-backlight-timing-pm-debug.patch.patch | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches/0138-fix-suspend-backlight-timing-pm-debug.patch.patch b/target/linux/s3c24xx/patches/0138-fix-suspend-backlight-timing-pm-debug.patch.patch new file mode 100755 index 0000000000..35786690f9 --- /dev/null +++ b/target/linux/s3c24xx/patches/0138-fix-suspend-backlight-timing-pm-debug.patch.patch @@ -0,0 +1,269 @@ +From 36b19597a232bb198b3bab4003c0f0807c821274 Mon Sep 17 00:00:00 2001 +From: Andy Green <andy@openmoko.com> +Date: Fri, 25 Jul 2008 23:06:08 +0100 +Subject: [PATCH] fix-suspend-backlight-timing-pm-debug.patch + +This patch improves the smoothness of suspend and resume action. + +Taking out CONFIG_PM_DEBUG allows much more rapid resume (the low level +serial traffic appears to be synchronous) + +Added a platform callback in jbt driver and support in pcf50633 so we +can defer bringing up the backlight until the LCM is able to process +video again (which must happen after the glamo is up and producing +video beacuse the LCM is hooked to glamo SPI) + +GTA01 should not be affected by all this as the callback will default +to null and it is on pcf50606 + +Signed-off-by: Andy Green <andy@openmoko.com> +--- + arch/arm/mach-s3c2440/mach-gta02.c | 8 ++++++ + defconfig-2.6.24 | 4 +- + drivers/i2c/chips/pcf50633.c | 50 ++++++++++++++++++++++++++--------- + drivers/video/display/jbt6k74.c | 12 ++++++++- + include/linux/jbt6k74.h | 3 +- + include/linux/pcf50633.h | 6 ++++ + 6 files changed, 66 insertions(+), 17 deletions(-) + +diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c +index 1954121..e1984a9 100644 +--- a/arch/arm/mach-s3c2440/mach-gta02.c ++++ b/arch/arm/mach-s3c2440/mach-gta02.c +@@ -532,6 +532,7 @@ static struct pcf50633_platform_data gta02_pcf_pdata = { + }, + }, + }, ++ .defer_resume_backlight = 1, + }; + + #if 0 /* currently unused */ +@@ -828,9 +829,16 @@ void gta02_jbt6k74_reset(int devidx, int level) + glamo_lcm_reset(level); + } + ++/* finally bring up deferred backlight resume now LCM is resumed itself */ ++ ++void gta02_jbt6k74_resuming(int devidx) ++{ ++ pcf50633_backlight_resume(pcf50633_global); ++} + + const struct jbt6k74_platform_data jbt6k74_pdata = { + .reset = gta02_jbt6k74_reset, ++ .resuming = gta02_jbt6k74_resuming, + }; + + static struct spi_board_info gta02_spi_board_info[] = { +diff --git a/defconfig-2.6.24 b/defconfig-2.6.24 +index 4df10bf..34fa961 100644 +--- a/defconfig-2.6.24 ++++ b/defconfig-2.6.24 +@@ -161,7 +161,7 @@ CONFIG_CPU_LLSERIAL_S3C2440=y + # + # Power management + # +-CONFIG_S3C2410_PM_DEBUG=y ++# CONFIG_S3C2410_PM_DEBUG is not set + # CONFIG_S3C2410_PM_CHECK is not set + CONFIG_S3C_LOWLEVEL_UART_PORT=2 + +@@ -1754,7 +1754,7 @@ CONFIG_FORCED_INLINING=y + # CONFIG_SAMPLES is not set + # CONFIG_DEBUG_USER is not set + CONFIG_DEBUG_ERRORS=y +-CONFIG_DEBUG_LL=y ++# CONFIG_DEBUG_LL is not set + # CONFIG_DEBUG_ICEDCC is not set + # CONFIG_DEBUG_S3C_PORT is not set + CONFIG_DEBUG_S3C_UART=2 +diff --git a/drivers/i2c/chips/pcf50633.c b/drivers/i2c/chips/pcf50633.c +index cb4cad8..da58aa3 100644 +--- a/drivers/i2c/chips/pcf50633.c ++++ b/drivers/i2c/chips/pcf50633.c +@@ -1466,7 +1466,7 @@ static int pcf50633bl_set_intensity(struct backlight_device *bd) + struct pcf50633_data *pcf = bl_get_data(bd); + int intensity = bd->props.brightness; + int old_intensity = reg_read(pcf, PCF50633_REG_LEDOUT); +- u_int8_t ledena; ++ u_int8_t ledena = 2; + int ret; + + if (bd->props.power != FB_BLANK_UNBLANK) +@@ -1474,16 +1474,19 @@ static int pcf50633bl_set_intensity(struct backlight_device *bd) + if (bd->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + +- /* The PCF50633 seems to have some kind of oddity (bug?) when +- * the intensity was 0, you need to completely switch it off +- * and re-enable it, before it produces any output voltage again */ ++ /* The PCF50633 cannot handle LEDOUT = 0 (datasheet p60) ++ * if seen, you have to re-enable the LED unit ++ */ + + if (intensity != 0 && old_intensity == 0) { + ledena = reg_read(pcf, PCF50633_REG_LEDENA); + reg_write(pcf, PCF50633_REG_LEDENA, 0x00); + } + +- ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, ++ if (!intensity) /* illegal to set LEDOUT to 0 */ ++ ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, 2); ++ else ++ ret = reg_set_bit_mask(pcf, PCF50633_REG_LEDOUT, 0x3f, + intensity); + + if (intensity != 0 && old_intensity == 0) +@@ -1920,6 +1923,8 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state) + } + + /* turn off the backlight */ ++ __reg_write(pcf, PCF50633_REG_LEDDIM, 0); ++ __reg_write(pcf, PCF50633_REG_LEDOUT, 2); + __reg_write(pcf, PCF50633_REG_LEDENA, 0x00); + + pcf->standby_regs.int1m = __reg_read(pcf, PCF50633_REG_INT1M); +@@ -1938,17 +1943,30 @@ static int pcf50633_suspend(struct device *dev, pm_message_t state) + return 0; + } + ++/* ++ * if backlight resume is selected to be deferred by platform, then it ++ * can call this to finally reset backlight status (after LCM is resumed ++ * for example ++ */ ++ ++void pcf50633_backlight_resume(struct pcf50633_data *pcf) ++{ ++ __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout); ++ __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena); ++ __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim); ++} ++EXPORT_SYMBOL_GPL(pcf50633_backlight_resume); ++ ++ + static int pcf50633_resume(struct device *dev) + { + struct i2c_client *client = to_i2c_client(dev); + struct pcf50633_data *pcf = i2c_get_clientdata(client); + int i; + +- printk(KERN_INFO"a\n"); + /* mutex_lock(&pcf->lock); */ /* resume in atomic context */ + + __reg_write(pcf, PCF50633_REG_LEDENA, 0x01); +- printk(KERN_INFO"b\n"); + + /* Resume all saved registers that don't "survive" standby state */ + __reg_write(pcf, PCF50633_REG_INT1M, pcf->standby_regs.int1m); +@@ -1956,7 +1974,6 @@ static int pcf50633_resume(struct device *dev) + __reg_write(pcf, PCF50633_REG_INT3M, pcf->standby_regs.int3m); + __reg_write(pcf, PCF50633_REG_INT4M, pcf->standby_regs.int4m); + __reg_write(pcf, PCF50633_REG_INT5M, pcf->standby_regs.int5m); +- printk(KERN_INFO"c\n"); + + __reg_write(pcf, PCF50633_REG_OOCTIM2, pcf->standby_regs.ooctim2); + __reg_write(pcf, PCF50633_REG_AUTOOUT, pcf->standby_regs.autoout); +@@ -1967,17 +1984,24 @@ static int pcf50633_resume(struct device *dev) + __reg_write(pcf, PCF50633_REG_DOWN2ENA, pcf->standby_regs.down2ena); + __reg_write(pcf, PCF50633_REG_MEMLDOOUT, pcf->standby_regs.memldoout); + __reg_write(pcf, PCF50633_REG_MEMLDOENA, pcf->standby_regs.memldoena); +- __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout); +- __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena); +- __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim); +- printk(KERN_INFO"d\n"); ++ ++ /* platform can choose to defer backlight bringup */ ++ if (!pcf->pdata->defer_resume_backlight) { ++ __reg_write(pcf, PCF50633_REG_LEDOUT, pcf->standby_regs.ledout); ++ __reg_write(pcf, PCF50633_REG_LEDENA, pcf->standby_regs.ledena); ++ __reg_write(pcf, PCF50633_REG_LEDDIM, pcf->standby_regs.leddim); ++ } else { /* force backlight down, platform will restore later */ ++ __reg_write(pcf, PCF50633_REG_LEDOUT, 2); ++ __reg_write(pcf, PCF50633_REG_LEDENA, 0x20); ++ __reg_write(pcf, PCF50633_REG_LEDDIM, 1); ++ } ++ + /* FIXME: one big read? */ + for (i = 0; i < 7; i++) { + u_int8_t reg_out = PCF50633_REG_LDO1OUT + 2*i; + __reg_write(pcf, reg_out, pcf->standby_regs.ldo[i].out); + __reg_write(pcf, reg_out+1, pcf->standby_regs.ldo[i].ena); + } +- printk(KERN_INFO"e\n"); + + /* mutex_unlock(&pcf->lock); */ /* resume in atomic context */ + +diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c +index 7e11da7..178e2da 100644 +--- a/drivers/video/display/jbt6k74.c ++++ b/drivers/video/display/jbt6k74.c +@@ -647,9 +647,14 @@ static int jbt_suspend(struct spi_device *spi, pm_message_t state) + static void jbt_resume_work(struct work_struct *work) + { + struct jbt_info *jbt = container_of(work, struct jbt_info, work); ++ struct jbt6k74_platform_data *jbt6k74_pdata = ++ jbt->spi_dev->dev.platform_data; + + printk(KERN_INFO"jbt_resume_work waiting...\n"); +- msleep(2000); ++ /* 100ms is not enough here 2008-05-08 andy@openmoko.com ++ * if CONFIG_PM_DEBUG is enabled 2000ms is required ++ */ ++ msleep(400); + printk(KERN_INFO"jbt_resume_work GO...\n"); + + jbt6k74_enter_state(jbt, JBT_STATE_DEEP_STANDBY); +@@ -665,6 +670,11 @@ static void jbt_resume_work(struct work_struct *work) + } + jbt6k74_display_onoff(jbt, 1); + ++ /* this gives the platform a chance to bring up backlight now */ ++ ++ if (jbt6k74_pdata->resuming) ++ (jbt6k74_pdata->resuming)(0); ++ + printk(KERN_INFO"jbt_resume_work done...\n"); + } + +diff --git a/include/linux/jbt6k74.h b/include/linux/jbt6k74.h +index 3fbe178..0ac9124 100644 +--- a/include/linux/jbt6k74.h ++++ b/include/linux/jbt6k74.h +@@ -2,7 +2,8 @@ + #define __JBT6K74_H__ + + struct jbt6k74_platform_data { +- void (* reset)(int devindex, int level); ++ void (*reset)(int devindex, int level); ++ void (*resuming)(int devindex); /* called when LCM is resumed */ + }; + + #endif +diff --git a/include/linux/pcf50633.h b/include/linux/pcf50633.h +index b6a67ee..f427985 100644 +--- a/include/linux/pcf50633.h ++++ b/include/linux/pcf50633.h +@@ -61,6 +61,9 @@ pcf50633_usb_curlim_set(struct pcf50633_data *pcf, int ma); + extern void + pcf50633_charge_enable(struct pcf50633_data *pcf, int on); + ++extern void ++pcf50633_backlight_resume(struct pcf50633_data *pcf); ++ + #define PCF50633_FEAT_EXTON 0x00000001 /* not yet supported */ + #define PCF50633_FEAT_MBC 0x00000002 + #define PCF50633_FEAT_BBC 0x00000004 /* not yet supported */ +@@ -89,6 +92,9 @@ struct pcf50633_platform_data { + u_int8_t mbcc3; /* charger voltage / current */ + } charger; + pmu_cb *cb; ++ ++ /* post-resume backlight bringup */ ++ int defer_resume_backlight; + }; + + #endif /* _PCF50633_H */ +-- +1.5.6.3 + |