summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiu Ying <b17645@freescale.com>2010-07-28 17:37:15 +0800
committerLiu Ying <b17645@freescale.com>2010-07-29 09:40:59 +0800
commit97906e809da716463f3c8b8e5a87bc670ba6e9e7 (patch)
treedc857a6c81ab22b6fa216c27d99c915496e7eec5
parent9789d9238f6e12ba022cb7479335f04580e1fe82 (diff)
ENGR00125665 ELCDIF FB:Support suspend and resume functions
1)Release console semaphore when leaving custom suspend function. 2)Reinitialize ELCDIF framebuffer if system resumes and the framebuffer is unblanked before entering into suspend mode. 3)Gate off elcdif_axi_clk when system is in suspend mode. Signed-off-by: Liu Ying <b17645@freescale.com>
-rw-r--r--drivers/video/mxc/mxc_elcdif_fb.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/drivers/video/mxc/mxc_elcdif_fb.c b/drivers/video/mxc/mxc_elcdif_fb.c
index 44587d28c7f9..1619a6593f64 100644
--- a/drivers/video/mxc/mxc_elcdif_fb.c
+++ b/drivers/video/mxc/mxc_elcdif_fb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
*/
/*
@@ -64,7 +64,8 @@
#define ELCDIF_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R')
struct mxc_elcdif_fb_data {
- int is_blank;
+ int cur_blank;
+ int next_blank;
int output_pix_fmt;
int elcdif_mode;
ssize_t mem_size;
@@ -806,7 +807,7 @@ static int mxc_elcdif_fb_set_par(struct fb_info *fbi)
return -ENOMEM;
}
- if (data->is_blank)
+ if (data->next_blank != FB_BLANK_UNBLANK)
return 0;
/* init next panel */
@@ -950,7 +951,7 @@ static int mxc_elcdif_fb_wait_for_vsync(u32 channel, struct fb_info *info)
(struct mxc_elcdif_fb_data *)info->par;
int ret = 0;
- if (data->is_blank) {
+ if (data->cur_blank != FB_BLANK_UNBLANK) {
dev_err(info->device, "can't wait for VSYNC when fb "
"is blank\n");
return -EINVAL;
@@ -1002,22 +1003,28 @@ static int mxc_elcdif_fb_blank(int blank, struct fb_info *info)
(struct mxc_elcdif_fb_data *)info->par;
int ret = 0;
- if (data->is_blank == (blank != FB_BLANK_UNBLANK))
+ if (data->cur_blank == blank)
return ret;
- if (blank == FB_BLANK_UNBLANK) {
- if (!g_elcdif_pix_clk_enable) {
- clk_enable(g_elcdif_pix_clk);
- g_elcdif_pix_clk_enable = true;
- }
+ data->next_blank = blank;
+
+ if (!g_elcdif_pix_clk_enable) {
+ clk_enable(g_elcdif_pix_clk);
+ g_elcdif_pix_clk_enable = true;
}
ret = mxc_elcdif_blank_panel(blank);
if (ret == 0)
- data->is_blank = (blank != FB_BLANK_UNBLANK);
+ data->cur_blank = blank;
else
return ret;
- if (data->is_blank) {
+ if (blank == FB_BLANK_UNBLANK) {
+ ret = mxc_elcdif_fb_set_par(info);
+ if (ret)
+ return ret;
+ }
+
+ if (data->cur_blank != FB_BLANK_UNBLANK) {
if (g_elcdif_axi_clk_enable) {
clk_disable(g_elcdif_axi_clk);
g_elcdif_axi_clk_enable = false;
@@ -1048,7 +1055,7 @@ static int mxc_elcdif_fb_pan_display(struct fb_var_screeninfo *var,
int ret = 0;
unsigned long base;
- if (data->is_blank) {
+ if (data->cur_blank != FB_BLANK_UNBLANK) {
dev_err(info->device, "can't do pan display when fb "
"is blank\n");
return -EINVAL;
@@ -1171,7 +1178,7 @@ static int mxc_elcdif_fb_probe(struct platform_device *pdev)
}
data = (struct mxc_elcdif_fb_data *)fbi->par;
- data->is_blank = false;
+ data->cur_blank = data->next_blank = FB_BLANK_UNBLANK;
fbi->var.activate = FB_ACTIVATE_NOW;
fbi->fbops = &mxc_elcdif_fb_ops;
@@ -1334,9 +1341,9 @@ static int mxc_elcdif_fb_suspend(struct platform_device *pdev,
acquire_console_sem();
fb_set_suspend(fbi, 1);
- saved_blank = data->is_blank;
+ saved_blank = data->cur_blank;
mxc_elcdif_fb_blank(FB_BLANK_POWERDOWN, fbi);
- data->is_blank = saved_blank;
+ data->next_blank = saved_blank;
if (!g_elcdif_pix_clk_enable) {
clk_enable(g_elcdif_pix_clk);
g_elcdif_pix_clk_enable = true;
@@ -1347,7 +1354,11 @@ static int mxc_elcdif_fb_suspend(struct platform_device *pdev,
clk_disable(g_elcdif_pix_clk);
g_elcdif_pix_clk_enable = false;
}
-
+ if (g_elcdif_axi_clk_enable) {
+ clk_disable(g_elcdif_axi_clk);
+ g_elcdif_axi_clk_enable = false;
+ }
+ release_console_sem();
return 0;
}
@@ -1357,20 +1368,7 @@ static int mxc_elcdif_fb_resume(struct platform_device *pdev)
struct mxc_elcdif_fb_data *data = (struct mxc_elcdif_fb_data *)fbi->par;
acquire_console_sem();
- if (!g_elcdif_pix_clk_enable) {
- clk_enable(g_elcdif_pix_clk);
- g_elcdif_pix_clk_enable = true;
- }
- mxc_init_elcdif();
- mxc_elcdif_init_panel();
- mxc_elcdif_dma_init(fbi->fix.smem_start);
- mxc_elcdif_run();
- if (g_elcdif_pix_clk_enable) {
- clk_disable(g_elcdif_pix_clk);
- g_elcdif_pix_clk_enable = false;
- }
- if (!data->is_blank)
- mxc_elcdif_fb_blank(FB_BLANK_UNBLANK, fbi);
+ mxc_elcdif_fb_blank(data->next_blank, fbi);
fb_set_suspend(fbi, 0);
release_console_sem();