diff options
Diffstat (limited to 'drivers/video/omap2/omapfb/omapfb-main.c')
-rw-r--r-- | drivers/video/omap2/omapfb/omapfb-main.c | 166 |
1 files changed, 33 insertions, 133 deletions
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 602b71a92d3..505bc12a303 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -46,10 +46,6 @@ static char *def_vram; static int def_vrfb; static int def_rotate; static int def_mirror; -static bool auto_update; -static unsigned int auto_update_freq; -module_param(auto_update, bool, 0); -module_param(auto_update_freq, uint, 0644); #ifdef DEBUG unsigned int omapfb_debug; @@ -1246,7 +1242,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi) struct omapfb_info *ofbi = FB2OFB(fbi); struct omapfb2_device *fbdev = ofbi->fbdev; struct omap_dss_device *display = fb2display(fbi); - struct omapfb_display_data *d; int r = 0; if (!display) @@ -1254,8 +1249,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi) omapfb_lock(fbdev); - d = get_display_data(fbdev, display); - switch (blank) { case FB_BLANK_UNBLANK: if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) @@ -1264,11 +1257,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi) if (display->driver->resume) r = display->driver->resume(display); - if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) && - d->update_mode == OMAPFB_AUTO_UPDATE && - !d->auto_update_work_enabled) - omapfb_start_auto_update(fbdev, display); - break; case FB_BLANK_NORMAL: @@ -1280,9 +1268,6 @@ static int omapfb_blank(int blank, struct fb_info *fbi) if (display->state != OMAP_DSS_DISPLAY_ACTIVE) goto exit; - if (d->auto_update_work_enabled) - omapfb_stop_auto_update(fbdev, display); - if (display->driver->suspend) r = display->driver->suspend(display); @@ -1739,78 +1724,6 @@ err: return r; } -static void omapfb_auto_update_work(struct work_struct *work) -{ - struct omap_dss_device *dssdev; - struct omap_dss_driver *dssdrv; - struct omapfb_display_data *d; - u16 w, h; - unsigned int freq; - struct omapfb2_device *fbdev; - - d = container_of(work, struct omapfb_display_data, - auto_update_work.work); - - dssdev = d->dssdev; - dssdrv = dssdev->driver; - fbdev = d->fbdev; - - if (!dssdrv || !dssdrv->update) - return; - - if (dssdrv->sync) - dssdrv->sync(dssdev); - - dssdrv->get_resolution(dssdev, &w, &h); - dssdrv->update(dssdev, 0, 0, w, h); - - freq = auto_update_freq; - if (freq == 0) - freq = 20; - queue_delayed_work(fbdev->auto_update_wq, - &d->auto_update_work, HZ / freq); -} - -void omapfb_start_auto_update(struct omapfb2_device *fbdev, - struct omap_dss_device *display) -{ - struct omapfb_display_data *d; - - if (fbdev->auto_update_wq == NULL) { - struct workqueue_struct *wq; - - wq = create_singlethread_workqueue("omapfb_auto_update"); - - if (wq == NULL) { - dev_err(fbdev->dev, "Failed to create workqueue for " - "auto-update\n"); - return; - } - - fbdev->auto_update_wq = wq; - } - - d = get_display_data(fbdev, display); - - INIT_DELAYED_WORK(&d->auto_update_work, omapfb_auto_update_work); - - d->auto_update_work_enabled = true; - - omapfb_auto_update_work(&d->auto_update_work.work); -} - -void omapfb_stop_auto_update(struct omapfb2_device *fbdev, - struct omap_dss_device *display) -{ - struct omapfb_display_data *d; - - d = get_display_data(fbdev, display); - - cancel_delayed_work_sync(&d->auto_update_work); - - d->auto_update_work_enabled = false; -} - /* initialize fb_info, var, fix to something sane based on the display */ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) { @@ -1945,21 +1858,10 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev) } for (i = 0; i < fbdev->num_displays; i++) { - struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; - - if (fbdev->displays[i].auto_update_work_enabled) - omapfb_stop_auto_update(fbdev, dssdev); - - if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) - dssdev->driver->disable(dssdev); - - omap_dss_put_device(dssdev); - } + if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED) + fbdev->displays[i]->driver->disable(fbdev->displays[i]); - if (fbdev->auto_update_wq != NULL) { - flush_workqueue(fbdev->auto_update_wq); - destroy_workqueue(fbdev->auto_update_wq); - fbdev->auto_update_wq = NULL; + omap_dss_put_device(fbdev->displays[i]); } dev_set_drvdata(fbdev->dev, NULL); @@ -2182,14 +2084,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev, int r; u8 bpp; struct omap_video_timings timings, temp_timings; - struct omapfb_display_data *d; r = omapfb_mode_to_timings(mode_str, &timings, &bpp); if (r) return r; - d = get_display_data(fbdev, display); - d->bpp_override = bpp; + fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display; + fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; + ++fbdev->num_bpp_overrides; if (display->driver->check_timings) { r = display->driver->check_timings(display, &timings); @@ -2215,14 +2117,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev, static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, struct omap_dss_device *dssdev) { - struct omapfb_display_data *d; + int i; BUG_ON(dssdev->driver->get_recommended_bpp == NULL); - d = get_display_data(fbdev, dssdev); - - if (d->bpp_override != 0) - return d->bpp_override; + for (i = 0; i < fbdev->num_bpp_overrides; ++i) { + if (dssdev == fbdev->bpp_overrides[i].dssdev) + return fbdev->bpp_overrides[i].bpp; + } return dssdev->driver->get_recommended_bpp(dssdev); } @@ -2254,9 +2156,9 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev) display = NULL; for (i = 0; i < fbdev->num_displays; ++i) { - if (strcmp(fbdev->displays[i].dssdev->name, + if (strcmp(fbdev->displays[i]->name, display_str) == 0) { - display = fbdev->displays[i].dssdev; + display = fbdev->displays[i]; break; } } @@ -2280,7 +2182,6 @@ static int omapfb_init_display(struct omapfb2_device *fbdev, struct omap_dss_device *dssdev) { struct omap_dss_driver *dssdrv = dssdev->driver; - struct omapfb_display_data *d; int r; r = dssdrv->enable(dssdev); @@ -2290,20 +2191,8 @@ static int omapfb_init_display(struct omapfb2_device *fbdev, return r; } - d = get_display_data(fbdev, dssdev); - - d->fbdev = fbdev; - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { u16 w, h; - - if (auto_update) { - omapfb_start_auto_update(fbdev, dssdev); - d->update_mode = OMAPFB_AUTO_UPDATE; - } else { - d->update_mode = OMAPFB_MANUAL_UPDATE; - } - if (dssdrv->enable_te) { r = dssdrv->enable_te(dssdev, 1); if (r) { @@ -2312,6 +2201,16 @@ static int omapfb_init_display(struct omapfb2_device *fbdev, } } + if (dssdrv->set_update_mode) { + r = dssdrv->set_update_mode(dssdev, + OMAP_DSS_UPDATE_MANUAL); + if (r) { + dev_err(fbdev->dev, + "Failed to set update mode\n"); + return r; + } + } + dssdrv->get_resolution(dssdev, &w, &h); r = dssdrv->update(dssdev, 0, 0, w, h); if (r) { @@ -2320,7 +2219,15 @@ static int omapfb_init_display(struct omapfb2_device *fbdev, return r; } } else { - d->update_mode = OMAPFB_AUTO_UPDATE; + if (dssdrv->set_update_mode) { + r = dssdrv->set_update_mode(dssdev, + OMAP_DSS_UPDATE_AUTO); + if (r) { + dev_err(fbdev->dev, + "Failed to set update mode\n"); + return r; + } + } } return 0; @@ -2368,8 +2275,6 @@ static int omapfb_probe(struct platform_device *pdev) fbdev->num_displays = 0; dssdev = NULL; for_each_dss_dev(dssdev) { - struct omapfb_display_data *d; - omap_dss_get_device(dssdev); if (!dssdev->driver) { @@ -2377,12 +2282,7 @@ static int omapfb_probe(struct platform_device *pdev) r = -ENODEV; } - d = &fbdev->displays[fbdev->num_displays++]; - d->dssdev = dssdev; - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) - d->update_mode = OMAPFB_MANUAL_UPDATE; - else - d->update_mode = OMAPFB_AUTO_UPDATE; + fbdev->displays[fbdev->num_displays++] = dssdev; } if (r) |