- UID
- 1029342
- 性别
- 男
|
3.在调试的过程中,还出现过跟LCD唤醒相关的问题。主要就是两个问题
一个问题是,在唤醒LCD之后,LCD会花屏。原以为拿到的这个代码已经做好了睡眠/唤醒,看了代码才发现,这个代码在睡眠之前,没有保存LCD的设置,在唤醒之后是重新初始化LCD的控制器,所以会出现花屏的现象,所以自己重新实现了s3c2410fb_suspend和s3c2410fb_resume两个函数,代码如下:
static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
{
struct fb_info *fbinfo = platform_get_drvdata(dev);
struct s3c2410fb_info *info = fbinfo->par;
unsigned long flags;
s3c2410fb_stop_lcd(info);
local_irq_save(flags);
lcdcon1 = readl(info->io + S3C2410_LCDCON1);
lcdcon2 = readl(info->io + S3C2410_LCDCON2);
lcdcon3 = readl(info->io + S3C2410_LCDCON3);
lcdcon4 = readl(info->io + S3C2410_LCDCON4);
lcdcon5 = readl(info->io + S3C2410_LCDCON5);
lcdsaddr1 = readl(info->io + S3C2410_LCDSADDR1);
lcdsaddr2 = readl(info->io + S3C2410_LCDSADDR2);
lcdsaddr3 = readl(info->io + S3C2410_LCDSADDR3);
redlut = readl(info->io + S3C2410_REDLUT);
greenlut = readl(info->io + S3C2410_GREENLUT);
bluelut = readl(info->io + S3C2410_BLUELUT);
dithmode = readl(info->io + S3C2410_DITHMODE);
tpal = readl(info->io + S3C2410_TPAL);
lcdintpnd = readl(info->io + S3C2410_LCDINTPND);
lcdsrcpnd = readl(info->io + S3C2410_LCDSRCPND);
lcdintmsk = readl(info->io + S3C2410_LCDINTMSK);
lpcsel = readl(info->io + S3C2410_LPCSEL);
lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
local_irq_restore(flags);
/* sleep before disabling the clock, we need to ensure
* the LCD DMA engine is not going to get back on the bus
* before the clock goes off again (bjd) */
msleep(1);
clk_disable(info->clk);
/*
* shutdown the LCD power and backlight power
*/
s3c2410_gpio_setpin(S3C2410_GPG12, 0);
s3c2410_gpio_setpin(S3C2410_GPG4, 1);
return 0;
}
static int s3c2410fb_resume(struct platform_device *dev)
{
struct fb_info *fbinfo = platform_get_drvdata(dev);
struct s3c2410fb_info *info = fbinfo->par;
struct s3c2410fb_mach_info *mach_info = info->dev->platform_data;
unsigned long flags;
int i;
printk("=======framebuffer resume.=====\n");
s3c2410_gpio_setpin(S3C2410_GPG4, 0);
msleep(10);
// s3c2410_gpio_setpin(S3C2410_GPG12, 1);
// msleep(10);
clk_enable(info->clk);
msleep(1);
local_irq_save(flags);
writel(lcdcon1,info->io + S3C2410_LCDCON1);
writel(lcdcon2,info->io + S3C2410_LCDCON2);
writel(lcdcon3,info->io + S3C2410_LCDCON3);
writel(lcdcon4,info->io + S3C2410_LCDCON4);
writel(lcdcon5,info->io + S3C2410_LCDCON5);
writel(lcdsaddr1,info->io + S3C2410_LCDSADDR1);
writel(lcdsaddr2 ,info->io + S3C2410_LCDSADDR2);
writel(lcdsaddr3,info->io + S3C2410_LCDSADDR3);
writel(redlut,info->io + S3C2410_REDLUT);
writel(greenlut,info->io + S3C2410_GREENLUT);
writel(bluelut,info->io + S3C2410_BLUELUT);
writel(dithmode,info->io + S3C2410_DITHMODE);
writel(tpal,info->io + S3C2410_TPAL);
writel(lcdintpnd,info->io + S3C2410_LCDINTPND);
writel(lcdsrcpnd,info->io + S3C2410_LCDSRCPND);
writel(lcdintmsk,info->io + S3C2410_LCDINTMSK);
writel(lpcsel,info->io + S3C2410_LPCSEL);
local_irq_restore(flags);
msleep(1);
local_irq_save(flags);
/* modify the gpio(s) with interrupts set (bjd) */
modify_gpio(S3C2410_GPCUP, mach_info->gpcup, mach_info->gpcup_mask);
modify_gpio(S3C2410_GPCCON, mach_info->gpccon, mach_info->gpccon_mask);
modify_gpio(S3C2410_GPDUP, mach_info->gpdup, mach_info->gpdup_mask);
modify_gpio(S3C2410_GPDCON, mach_info->gpdcon, mach_info->gpdcon_mask);
// s3c2410fb_init_registers(fbinfo);
s3c2410_gpio_cfgpin(S3C2410_GPG12, S3C2410_GPG12_OUTP); // back light control
s3c2410_gpio_cfgpin(S3C2410_GPG4, S3C2410_GPG4_OUTP);
local_irq_restore(flags);
// s3c2410_gpio_setpin(S3C2410_GPG12, 1);
// s3c2410_gpio_setpin(S3C2410_GPG4, 0);
// s3c2440_pwm_set(1);
writel(readl(info->io + S3C2410_LCDCON1) | S3C2410_LCDCON1_ENVID, info->io+S3C2410_LCDCON1);
msleep(50);
s3c2410_gpio_setpin(S3C2410_GPG12, 1);
msleep(10);
return 0;
}
大致意思就是在进入睡眠之前要保存LCD的各个控制器中的设置内容,关闭LCD,关闭背光;在唤醒之后打开LCD,恢复LCD控制的内容,特别注意在最后使能LCD,也就是ritel(readl(info->io + S3C2410_LCDCON1) | S3C2410_LCDCON1_ENVID, info->io+S3C2410_LCDCON1),否则就会出现LCD显示错位的情况,然后打开背光。 |
|