mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-12 15:44:01 +08:00
fbdev: sh_mobile_lcdcfb: add blanking support
Add a blanking callback to the LCDC driver in order to support both FBIOBLANK and TIOCLINUX blanking ioctls. LCDC clocks are also released if the requested blanking level is superior to FB_BLANK_NORMAL, to allow runtime PM to disable the clocks if possible. Signed-off-by: Alexandre Courbot <gnurou@gmail.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
bacbe55b63
commit
8857b9aa7e
@ -977,6 +977,49 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Screen blanking. Behavior is as follows:
|
||||||
|
* FB_BLANK_UNBLANK: screen unblanked, clocks enabled
|
||||||
|
* FB_BLANK_NORMAL: screen blanked, clocks enabled
|
||||||
|
* FB_BLANK_VSYNC,
|
||||||
|
* FB_BLANK_HSYNC,
|
||||||
|
* FB_BLANK_POWEROFF: screen blanked, clocks disabled
|
||||||
|
*/
|
||||||
|
static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct sh_mobile_lcdc_chan *ch = info->par;
|
||||||
|
struct sh_mobile_lcdc_priv *p = ch->lcdc;
|
||||||
|
|
||||||
|
/* blank the screen? */
|
||||||
|
if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) {
|
||||||
|
struct fb_fillrect rect = {
|
||||||
|
.width = info->var.xres,
|
||||||
|
.height = info->var.yres,
|
||||||
|
};
|
||||||
|
sh_mobile_lcdc_fillrect(info, &rect);
|
||||||
|
}
|
||||||
|
/* turn clocks on? */
|
||||||
|
if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) {
|
||||||
|
sh_mobile_lcdc_clk_on(p);
|
||||||
|
}
|
||||||
|
/* turn clocks off? */
|
||||||
|
if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) {
|
||||||
|
/* make sure the screen is updated with the black fill before
|
||||||
|
* switching the clocks off. one vsync is not enough since
|
||||||
|
* blanking may occur in the middle of a refresh. deferred io
|
||||||
|
* mode will reenable the clocks and update the screen in time,
|
||||||
|
* so it does not need this. */
|
||||||
|
if (!info->fbdefio) {
|
||||||
|
sh_mobile_wait_for_vsync(info);
|
||||||
|
sh_mobile_wait_for_vsync(info);
|
||||||
|
}
|
||||||
|
sh_mobile_lcdc_clk_off(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
ch->blank_status = blank;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct fb_ops sh_mobile_lcdc_ops = {
|
static struct fb_ops sh_mobile_lcdc_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
|
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
|
||||||
@ -985,6 +1028,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
|
|||||||
.fb_fillrect = sh_mobile_lcdc_fillrect,
|
.fb_fillrect = sh_mobile_lcdc_fillrect,
|
||||||
.fb_copyarea = sh_mobile_lcdc_copyarea,
|
.fb_copyarea = sh_mobile_lcdc_copyarea,
|
||||||
.fb_imageblit = sh_mobile_lcdc_imageblit,
|
.fb_imageblit = sh_mobile_lcdc_imageblit,
|
||||||
|
.fb_blank = sh_mobile_lcdc_blank,
|
||||||
.fb_pan_display = sh_mobile_fb_pan_display,
|
.fb_pan_display = sh_mobile_fb_pan_display,
|
||||||
.fb_ioctl = sh_mobile_ioctl,
|
.fb_ioctl = sh_mobile_ioctl,
|
||||||
.fb_open = sh_mobile_open,
|
.fb_open = sh_mobile_open,
|
||||||
|
@ -37,6 +37,7 @@ struct sh_mobile_lcdc_chan {
|
|||||||
struct completion vsync_completion;
|
struct completion vsync_completion;
|
||||||
struct fb_var_screeninfo display_var;
|
struct fb_var_screeninfo display_var;
|
||||||
int use_count;
|
int use_count;
|
||||||
|
int blank_status;
|
||||||
struct mutex open_lock; /* protects the use counter */
|
struct mutex open_lock; /* protects the use counter */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user