diff options
author | Shashank Sharma <shashanks@nvidia.com> | 2012-12-05 14:11:25 +0530 |
---|---|---|
committer | Matthew Pedro <mapedro@nvidia.com> | 2012-12-20 18:05:46 -0800 |
commit | 4f8461ffb6746c7f4a2258834afead13bcb29d72 (patch) | |
tree | 34d5e8ba44bf1e4d5770229f439444127749888a /drivers/video/tegra/fb.c | |
parent | a7d49070ee698d42f0fffee54d184c6ebb6ce487 (diff) |
arm: tegra: fb: Set new mode to all vc's
Send change all vc's notification from HDMI hot-plug reader to
fbcon, so that the new selected mode can be applied on all the
vc's from vc1 to vc6. This sometimes causes corruption on HDMI
hot plugin, when fbcon is mapped to HDMI
Bug 1166008
Signed-off-by: Shashank Sharma <shashanks@nvidia.com>
Change-Id: Id173de3014597f79c8c8b31bbbee7c9c560547b6
Reviewed-on: http://git-master/r/168683
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
Tested-by: Matthew Pedro <mapedro@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/fb.c')
-rw-r--r-- | drivers/video/tegra/fb.c | 68 |
1 files changed, 26 insertions, 42 deletions
diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c index 46cbabfe73f0..f69048f62cc2 100644 --- a/drivers/video/tegra/fb.c +++ b/drivers/video/tegra/fb.c @@ -493,33 +493,15 @@ const struct fb_videomode *tegra_fb_find_best_mode( return best; } -static int tegra_fb_activate_mode(struct tegra_fb_info *fb_info, - struct fb_var_screeninfo *var) -{ - int err; - struct fb_info *info = fb_info->info; - - var->activate |= FB_ACTIVATE_FORCE; - console_lock(); - info->flags |= FBINFO_MISC_USEREVENT; - err = fb_set_var(info, var); - info->flags &= ~FBINFO_MISC_USEREVENT; - console_unlock(); - if (err) - return err; - return 0; -} - void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info, struct fb_monspecs *specs, bool (*mode_filter)(const struct tegra_dc *dc, struct fb_videomode *mode)) { int i; - int ret = 0; + bool first = false; struct fb_event event; struct fb_info *info = fb_info->info; - const struct fb_videomode *best_mode = NULL; struct fb_var_screeninfo var = {0,}; mutex_lock(&fb_info->info->lock); @@ -558,6 +540,13 @@ void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info, fb_var_to_videomode(&m, &var); fb_add_videomode(&m, &fb_info->info->modelist); + /* EDID stds recommend first detailed mode + to be applied as default,but if first mode + doesn't pass mode filter, we have to select + and apply other mode. So flag on if first + mode passes mode filter */ + if (!i) + first = true; } } else { fb_add_videomode(&specs->modedb[i], @@ -565,36 +554,31 @@ void tegra_fb_update_monspecs(struct tegra_fb_info *fb_info, } } - /* Get the best mode from modedb and apply on fb */ - var.xres = 0; - var.yres = 0; - best_mode = tegra_fb_find_best_mode(&var, &info->modelist); - - /* Update framebuffer with best mode */ - fb_videomode_to_var(&var, best_mode); - - /* TODO: Get proper way of getting rid of a 0 bpp */ - if (!var.bits_per_pixel) - var.bits_per_pixel = 32; - - memcpy(&info->var, &var, sizeof(struct fb_var_screeninfo)); - - ret = tegra_fb_activate_mode(fb_info, &var); - if (ret) - return; + /* We can't apply first detailed mode, so get the best mode + based on resolution and apply on fb */ + if (!first) { + var.xres = 0; + var.yres = 0; + info->mode = (struct fb_videomode *) + tegra_fb_find_best_mode(&var, &info->modelist); + } + /* Prepare fb info with new mode details */ + fb_videomode_to_var(&info->var, info->mode); event.info = fb_info->info; #ifdef CONFIG_FRAMEBUFFER_CONSOLE -/* Lock the console before sending the noti. Fbconsole - * on HDMI might be using console - */ + /* Send a noti to change fb_display[].mode for all vc's */ + console_lock(); + fb_notifier_call_chain(FB_EVENT_MODE_CHANGE_ALL, &event); + console_unlock(); + + /* Notify framebuffer console about mode change */ console_lock(); -#endif fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); -#ifdef CONFIG_FRAMEBUFFER_CONSOLE -/* Unlock the console */ console_unlock(); +#else + fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); #endif mutex_unlock(&fb_info->info->lock); |