之前移植LCD的时候,一切正常,但是当尝试把log输出到lcd的时候,总是会出现10分钟黑屏,无论如何都唤不醒
通过打log,最终定位到s3c_fb_blank这个函数。
static int s3c_fb_blank(int blank_mode, struct fb_info *info) { struct s3c_fb_win *win = info->par; struct s3c_fb *sfb = win->parent; unsigned int index = win->index; u32 wincon; printk("lj:s3c_fb_blank:blank mode:%d\n",blank_mode); dev_dbg(sfb->dev, "blank mode %d\n", blank_mode); pm_runtime_get_sync(sfb->dev); wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4)); switch (blank_mode) { case FB_BLANK_POWERDOWN: wincon &= ~WINCONx_ENWIN; sfb->enabled &= ~(1 << index); /* fall through to FB_BLANK_NORMAL */ case FB_BLANK_NORMAL: /* disable the DMA and display 0x0 (black) */ shadow_protect_win(win, 1); dump_stack(); writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x00),//liujia disable the black screen sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); break; case FB_BLANK_UNBLANK: shadow_protect_win(win, 1); writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); wincon |= WINCONx_ENWIN; sfb->enabled |= (1 << index); break; case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND: default: pm_runtime_put_sync(sfb->dev); return 1; } shadow_protect_win(win, 1); writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4)); shadow_protect_win(win, 0); /* Check the enabled state to see if we need to be running the * main LCD interface, as if there are no active windows then * it is highly likely that we also do not need to output * anything. */ /* We could do something like the following code, but the current * system of using framebuffer events means that we cannot make * the distinction between just window 0 being inactive and all * the windows being down. * * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0); */ /* we're stuck with this until we can do something about overriding * the power control using the blanking event for a single fb. */ if (index == sfb->pdata->default_win) { shadow_protect_win(win, 1); s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0); shadow_protect_win(win, 0); } pm_runtime_put_sync(sfb->dev); return 0; }
这个寄存器的意思是,当MAPCOLEN_F使能的时候,他会把LCD显示成MAPCOLOR设置成颜色,关闭LCD的DMA功能,然后Framebuffer就不能刷新LCD了。
这也许就是FB_BLANK_NORMAL,这个的功能吧,把LCD一直刷成某个颜色。
参考http://blog.csdn.net/zanget/article/details/6569743这个 大侠的博客,
加入dump_stack
case FB_BLANK_NORMAL: /* disable the DMA and display 0x0 (black) */ shadow_protect_win(win, 1); dump_stack(); writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x00),//liujia disable the black screen sfb->regs + sfb->variant.winmap + (index * 4)); shadow_protect_win(win, 0); break;
<7>[ 61.285759] lj:s3c_fb_blank:blank mode:1 <7>[ 61.285772] lj:shadow_protect_win:1 <7>[ 61.285816] [<80013120>] (unwind_backtrace+0x0/0xec) from [<801af0b8>] (s3c_fb_blank+0x84/0x180) <7>[ 61.285835] [<801af0b8>] (s3c_fb_blank+0x84/0x180) from [<801a2bcc>] (fb_blank+0x3c/0x68) <7>[ 61.285852] [<801a2bcc>] (fb_blank+0x3c/0x68) from [<801a9690>] (fbcon_blank+0x118/0x260) <7>[ 61.285875] [<801a9690>] (fbcon_blank+0x118/0x260) from [<801c7594>] (do_blank_screen+0x1b8/0x258) <7>[ 61.285892] [<801c7594>] (do_blank_screen+0x1b8/0x258) from [<801c884c>] (console_callback+0xe4/0x114) <7>[ 61.285909] [<801c884c>] (console_callback+0xe4/0x114) from [<8002e12c>] (process_one_work+0x1e8/0x318) <7>[ 61.285927] [<8002e12c>] (process_one_work+0x1e8/0x318) from [<800301c0>] (worker_thread+0x1b4/0x2b4) <7>[ 61.285947] [<800301c0>] (worker_thread+0x1b4/0x2b4) from [<80033438>] (kthread+0x88/0x94) <7>[ 61.285969] [<80033438>] (kthread+0x88/0x94) from [<8000ec20>] (kernel_thread_exit+0x0/0x8) <7>[ 61.285979] lj:shadow_protect_win:0 <7>[ 61.285984] lj:shadow_protect_win:1 <7>[ 61.285990] lj:shadow_protect_win:0 <7>[ 61.285995] lj:shadow_protect_win:1 <7>[ 61.286001] lj:s3c_fb_set_par <7>[ 61.286005] lj:shadow_protect_win:0