Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / drm_fb_helper.c
index 4b968f5b9c8503dcc5998c208520b10bc34d5b4f..1b8f013ffa6503ec960cee3bdb9cb7c3fa78d2bc 100644 (file)
@@ -1821,17 +1821,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
        if (ret < 0)
                return ret;
 
-       /*
-        * Set the fb pointer - usually drm_setup_crtcs does this for hotplug
-        * events, but at init time drm_setup_crtcs needs to be called before
-        * the fb is allocated (since we need to figure out the desired size of
-        * the fb before we can allocate it ...). Hence we need to fix things up
-        * here again.
-        */
-       for (i = 0; i < fb_helper->crtc_count; i++)
-               if (fb_helper->crtc_info[i].mode_set.num_connectors)
-                       fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
-
        return 0;
 }
 
@@ -1893,8 +1882,6 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
        info->var.xoffset = 0;
        info->var.yoffset = 0;
        info->var.activate = FB_ACTIVATE_NOW;
-       info->var.height = -1;
-       info->var.width = -1;
 
        switch (fb->format->depth) {
        case 8:
@@ -2410,9 +2397,9 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
                struct drm_display_mode *mode = modes[i];
                struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
                struct drm_fb_offset *offset = &offsets[i];
-               struct drm_mode_set *modeset = &fb_crtc->mode_set;
 
                if (mode && fb_crtc) {
+                       struct drm_mode_set *modeset = &fb_crtc->mode_set;
                        struct drm_connector *connector =
                                fb_helper->connector_info[i]->connector;
 
@@ -2426,7 +2413,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
                                                           fb_crtc->desired_mode);
                        drm_connector_get(connector);
                        modeset->connectors[modeset->num_connectors++] = connector;
-                       modeset->fb = fb_helper->fb;
                        modeset->x = offset->x;
                        modeset->y = offset->y;
                }
@@ -2438,6 +2424,37 @@ out:
        kfree(enabled);
 }
 
+/*
+ * This is a continuation of drm_setup_crtcs() that sets up anything related
+ * to the framebuffer. During initialization, drm_setup_crtcs() is called before
+ * the framebuffer has been allocated (fb_helper->fb and fb_helper->fbdev).
+ * So, any setup that touches those fields needs to be done here instead of in
+ * drm_setup_crtcs().
+ */
+static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
+{
+       struct fb_info *info = fb_helper->fbdev;
+       int i;
+
+       for (i = 0; i < fb_helper->crtc_count; i++)
+               if (fb_helper->crtc_info[i].mode_set.num_connectors)
+                       fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
+
+       mutex_lock(&fb_helper->dev->mode_config.mutex);
+       drm_fb_helper_for_each_connector(fb_helper, i) {
+               struct drm_connector *connector =
+                                       fb_helper->connector_info[i]->connector;
+
+               /* use first connected connector for the physical dimensions */
+               if (connector->status == connector_status_connected) {
+                       info->var.width = connector->display_info.width_mm;
+                       info->var.height = connector->display_info.height_mm;
+                       break;
+               }
+       }
+       mutex_unlock(&fb_helper->dev->mode_config.mutex);
+}
+
 /* Note: Drops fb_helper->lock before returning. */
 static int
 __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
@@ -2463,6 +2480,7 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper,
 
                return ret;
        }
+       drm_setup_crtcs_fb(fb_helper);
 
        fb_helper->deferred_setup = false;
 
@@ -2591,6 +2609,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
        DRM_DEBUG_KMS("\n");
 
        drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
+       drm_setup_crtcs_fb(fb_helper);
        mutex_unlock(&fb_helper->lock);
 
        drm_fb_helper_set_par(fb_helper->fbdev);