mode management changes between local and external display.
authorSanjay Rama Reddy <sanjay.rama.reddy@intel.com>
Mon, 30 Jan 2012 22:17:19 +0000 (00:17 +0200)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:29:39 +0000 (12:29 +0300)
- Defining our policy of setting the FB and surface dimensions
  of frame buffer equal to local display dimensions and choosing
  panel fitting for external display when needed. This is required since
  Medfield hardware supports panel fitting only for HDMI pipe.
- Also, remove the modes selection limitations at drm during hdmi hotplug.
  During drm_fb_helper_hotplug_event, the max_width and max_height are
  reseted to the size of available framebuffer (which is equal to local
  display), and thus removes all the hdmi modes that are greater than this
  limit thus not allowing modes like 1080P to get selected for HDMI.
  Hence changed the reset logic.

Signed-off-by: Arun Kannan <arun.kannan@intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
drivers/gpu/drm/drm_fb_helper.c
drivers/staging/mrst/drv/psb_fb.c

index 594f4ae..c1ca16b 100644 (file)
@@ -1423,8 +1423,13 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
        }
        DRM_DEBUG_KMS("\n");
 
-       max_width = fb_helper->fb->width;
-       max_height = fb_helper->fb->height;
+       /* Use max size from mode_config instead of fb size to enable inclusion
+        * of higher resolution modes for external display.
+        * Local display is configured with fb size.
+        */
+       max_width = fb_helper->dev->mode_config.max_width;
+       max_height = fb_helper->dev->mode_config.max_height;
+
        bpp_sel = fb_helper->fb->bits_per_pixel;
 
        count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
index dd3a278..47be30f 100644 (file)
@@ -442,9 +442,29 @@ static int psbfb_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surfac
        struct psb_fbdev * psb_fbdev = (struct psb_fbdev *)helper;
        int new_fb = 0;
        int ret;
+       struct drm_device *dev = helper->dev;
+       struct drm_display_mode *dsi_mode = NULL;
 
        DRM_DEBUG("%s\n", __FUNCTION__);
 
+       /* Mode management between local and external displays:
+        * Frame buffer and surface dimensions will always be equal to
+        * local display mode value.
+        */
+
+       if (sizes != NULL) {
+               /* local display desired mode */
+               dsi_mode = helper->crtc_info[0].desired_mode;
+               if (dsi_mode) {
+                       DRM_INFO("setting fb and surface dimensions to %dx%d\n",
+                                       dsi_mode->hdisplay, dsi_mode->vdisplay);
+                       sizes->fb_width  = dsi_mode->hdisplay;
+                       sizes->fb_height = dsi_mode->vdisplay;
+                       sizes->surface_width  = dsi_mode->hdisplay;
+                       sizes->surface_height = dsi_mode->vdisplay;
+               }
+       }
+
        if(!helper->fb) {
                ret = psbfb_create(psb_fbdev, sizes);
                if(ret) {