]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/kernel-video.git/commitdiff
OMAPDSS: OMAPFB : Add support for default display scaling.
authorDandawate Saket <dsaket@ti.com>
Thu, 27 Jun 2013 07:20:42 +0000 (00:20 -0700)
committerPraneeth Bajjuri <praneeth@ti.com>
Fri, 12 Jul 2013 22:28:58 +0000 (17:28 -0500)
Currently it is assumed that frame buffer size
is same as default panel size. With this assumption
GFX pipeline is always presented to default display FBDev.
GFX pipeline cannot scale so we cannot have a frame
buffer which is not equal to panel size (LCD | HDMI).
Updated the current logic of omapfb to pick video pipelines
in case scaling is required for FB to be presented to default
panel.

To provide FB size option is provided via command line.
e.g
omapfb.fb_opt=0,720,1280,1,640,480
each element is [fb_ix,width,height]

Change-Id: I0b546932ff9119166e123b7bf08352ca836b0842
Signed-off-by: Dandawate Saket <dsaket@ti.com>
drivers/video/omap2/omapfb/omapfb-ioctl.c
drivers/video/omap2/omapfb/omapfb-main.c
drivers/video/omap2/omapfb/omapfb.h
include/video/omapdss.h

index c92ed5d6445e6ab11bbc1779c777b1c1ecd5e78e..dc9da240713fc2c2b4dbd638f402906f7211b716 100644 (file)
@@ -885,8 +885,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                        break;
                }
 
-               display->driver->get_resolution(display, &xres, &yres);
-
+               get_fb_resolution(display, &xres, &yres);
                p.display_info.xres = xres;
                p.display_info.yres = yres;
 
index 783236d72595fa6381b75b8b9830b8fc1eb38661..d0b1ff18351d49378c1fa62972d585d9416030c2 100644 (file)
@@ -51,6 +51,22 @@ static unsigned int auto_update_freq;
 module_param(auto_update, bool, 0);
 module_param(auto_update_freq, uint, 0644);
 
+/* Max 4 framebuffers assumed : FB-ix-W-H */
+#define MAX_FB_COUNT   4
+#define ELEMENT_COUNT  3
+struct fb_options {
+       int ix;
+       int width;
+       int height;
+};
+static int fb_opt[MAX_FB_COUNT*ELEMENT_COUNT] = {      -1, -1, -1,
+                                                       -1, -1, -1,
+                                                       -1, -1, -1,
+                                                       -1, -1, -1};
+
+module_param_array(fb_opt, int, NULL, 0);
+MODULE_PARM_DESC(fb_opt, "FB[ix][w][h]");
+
 #ifdef DEBUG
 bool omapfb_debug;
 module_param_named(debug, omapfb_debug, bool, 0644);
@@ -58,6 +74,39 @@ static bool omapfb_test_pattern;
 module_param_named(test, omapfb_test_pattern, bool, 0644);
 #endif
 
+static bool intialize_dev_fb_resolution(u16 display_ix,
+                       struct omap_dss_device *dssdev)
+{
+       struct fb_options *pfb_opt = NULL;
+
+       if (display_ix > MAX_FB_COUNT || !dssdev)
+               return false;
+
+       pfb_opt = (struct fb_options *)&fb_opt[display_ix*ELEMENT_COUNT];
+
+       DBG("cmd line dev ix %d - W %d - H %d\n",
+               pfb_opt->ix, pfb_opt->width , pfb_opt->height);
+
+       if (pfb_opt->ix != -1) {
+               dssdev->panel.fb_xres = pfb_opt->width;
+               dssdev->panel.fb_yres = pfb_opt->height;
+       } else {
+               dssdev->panel.fb_xres = dssdev->panel.timings.x_res;
+               dssdev->panel.fb_yres = dssdev->panel.timings.y_res;
+       }
+       DBG("init dev %s dev-%d:w-%d:h-%d\n", dssdev->name, display_ix,
+                       dssdev->panel.fb_xres, dssdev->panel.fb_yres);
+       return true;
+}
+
+void get_fb_resolution(struct omap_dss_device *dssdev, u16 *xres, u16 *yres)
+{
+       *xres = dssdev->panel.fb_xres;
+       *yres = dssdev->panel.fb_yres;
+       DBG("%s %s %d x %d", __func__, dssdev->name, *xres, *yres);
+       return;
+}
+
 static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
 static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
                struct omap_dss_device *dssdev);
@@ -757,6 +806,31 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
        return 0;
 }
 
+
+bool check_fb_scale(struct omap_dss_device *dssdev)
+{
+       u16 fb_w, fb_h , pn_w , pn_h;
+       struct omap_dss_driver *dssdrv;
+
+       if (!dssdev || !dssdev->driver)
+               return false;
+       DBG("default device %s", dssdev->name);
+       fb_w = fb_h = pn_w = pn_h = 0;
+       dssdrv = dssdev->driver;
+
+       get_fb_resolution(dssdev, &fb_w, &fb_h);
+       if (fb_w <= 0 || fb_h <= 0)
+               return false;
+
+       if (dssdrv->get_resolution)
+               dssdrv->get_resolution(dssdev, &pn_w, &pn_h);
+
+       if (fb_w != pn_w || fb_h != pn_h)
+               return true;
+       else
+               return false;
+}
+
 /*
  * ---------------------------------------------------------------------------
  * fbdev framework callbacks
@@ -951,6 +1025,7 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
        u16 posx, posy;
        u16 outw, outh;
        int i;
+       struct omap_dss_device *display = fb2display(fbi);
 
 #ifdef DEBUG
        if (omapfb_test_pattern)
@@ -973,14 +1048,22 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
                }
 
                if (init || (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+                       u16 p_width , p_height;
                        int rotation = (var->rotate + ofbi->rotation[i]) % 4;
+                       p_width = var->xres;
+                       p_height = var->yres;
+                       if (display && display->driver &&
+                               display->driver->get_resolution)
+                                       display->driver->get_resolution(display,
+                                                       &p_width, &p_height);
+
                        if (rotation == FB_ROTATE_CW ||
                                        rotation == FB_ROTATE_CCW) {
-                               outw = var->yres;
-                               outh = var->xres;
+                               outw = p_height;
+                               outh = p_width;
                        } else {
-                               outw = var->xres;
-                               outh = var->yres;
+                               outw = p_width;
+                               outh = p_height;
                        }
                } else {
                        struct omap_overlay_info info;
@@ -1522,8 +1605,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
        if (!size) {
                u16 w, h;
 
-               display->driver->get_resolution(display, &w, &h);
-
+               get_fb_resolution(display, &w, &h);
                if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
                        size = max(omap_vrfb_min_phys_size(w, h, bytespp),
                                        omap_vrfb_min_phys_size(h, w, bytespp));
@@ -1847,8 +1929,7 @@ static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
                u16 w, h;
                int rotation = (var->rotate + ofbi->rotation[0]) % 4;
 
-               display->driver->get_resolution(display, &w, &h);
-
+               get_fb_resolution(display, &w, &h);
                if (rotation == FB_ROTATE_CW ||
                                rotation == FB_ROTATE_CCW) {
                        var->xres = h;
@@ -2530,6 +2611,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
        int i;
        struct omap_dss_device *def_display;
        struct omap_dss_device *dssdev;
+       u16 fb_ov_start_ix = 0;
 
        DBG("omapfb_probe\n");
 
@@ -2589,14 +2671,6 @@ static int __init omapfb_probe(struct platform_device *pdev)
                goto cleanup;
        }
 
-       fbdev->num_overlays = omap_dss_get_num_overlays();
-       for (i = 0; i < fbdev->num_overlays; i++)
-               fbdev->overlays[i] = omap_dss_get_overlay(i);
-
-       fbdev->num_managers = omap_dss_get_num_overlay_managers();
-       for (i = 0; i < fbdev->num_managers; i++)
-               fbdev->managers[i] = omap_dss_get_overlay_manager(i);
-
        def_display = NULL;
 
        for (i = 0; i < fbdev->num_displays; ++i) {
@@ -2626,19 +2700,33 @@ static int __init omapfb_probe(struct platform_device *pdev)
                goto cleanup;
        }
 
+       fbdev->num_managers = omap_dss_get_num_overlay_managers();
+       for (i = 0; i < fbdev->num_managers; i++)
+               fbdev->managers[i] = omap_dss_get_overlay_manager(i);
+
        if (def_mode && strlen(def_mode) > 0) {
                if (omapfb_parse_def_modes(fbdev))
                        dev_warn(&pdev->dev, "cannot parse default modes\n");
        } else if (def_display && def_display->driver->set_timings &&
                        def_display->driver->check_timings) {
                struct omap_video_timings t;
-
                r = omapfb_find_best_mode(def_display, &t);
-
                if (r == 0)
                        def_display->driver->set_timings(def_display, &t);
        }
 
+       for (i = 0; i < fbdev->num_displays; i++) {
+               if (!intialize_dev_fb_resolution(i, fbdev->displays[i].dssdev))
+                       goto cleanup;
+       }
+
+       fbdev->num_overlays = omap_dss_get_num_overlays();
+       if (def_display && check_fb_scale(def_display)) {
+               fb_ov_start_ix = 1;
+               fbdev->num_overlays -= 1;
+       }
+       for (i = 0; i < fbdev->num_overlays; i++)
+               fbdev->overlays[i] = omap_dss_get_overlay(i+fb_ov_start_ix);
        r = omapfb_create_framebuffers(fbdev);
        if (r)
                goto cleanup;
index f375ec81a937cb50852b4c4c48ed23b84854f675..a5f305fad23f25ad9c46ec98bffa6bed66bf6903 100644 (file)
@@ -153,6 +153,9 @@ int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
 int omapfb_enable_vsync(struct omapfb2_device *fbdev);
 void omapfb_disable_vsync(struct omapfb2_device *fbdev);
 
+void get_fb_resolution(struct omap_dss_device *dssdev,
+               u16 *xres, u16 *yres);
+
 /* find the display connected to this fb, if any */
 static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 {
index 5c5d15a3195cca814990b9c1e99bb7f4cc9e4ba6..cfbd9541a44a1442af16dc64f11596d399d6460f 100755 (executable)
@@ -799,7 +799,9 @@ struct omap_dss_device {
                struct s3d_disp_info s3d_info;
                u32 width_in_um;
                u32 height_in_um;
-       } panel;
+                       u16 fb_xres;
+                       u16 fb_yres;
+       } panel;
 
        struct {
                u8 pixel_size;