Merge tag 'drm-next-2018-10-24' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-block.git] / drivers / gpu / drm / drm_fb_helper.c
index 9b111e8468477fa492e4e5616bc6a9701b0ef6b8..a502f3e519fdb668c685f392d518361e1e0a1ef2 100644 (file)
@@ -1599,6 +1599,25 @@ unlock:
 }
 EXPORT_SYMBOL(drm_fb_helper_ioctl);
 
+static bool drm_fb_pixel_format_equal(const struct fb_var_screeninfo *var_1,
+                                     const struct fb_var_screeninfo *var_2)
+{
+       return var_1->bits_per_pixel == var_2->bits_per_pixel &&
+              var_1->grayscale == var_2->grayscale &&
+              var_1->red.offset == var_2->red.offset &&
+              var_1->red.length == var_2->red.length &&
+              var_1->red.msb_right == var_2->red.msb_right &&
+              var_1->green.offset == var_2->green.offset &&
+              var_1->green.length == var_2->green.length &&
+              var_1->green.msb_right == var_2->green.msb_right &&
+              var_1->blue.offset == var_2->blue.offset &&
+              var_1->blue.length == var_2->blue.length &&
+              var_1->blue.msb_right == var_2->blue.msb_right &&
+              var_1->transp.offset == var_2->transp.offset &&
+              var_1->transp.length == var_2->transp.length &&
+              var_1->transp.msb_right == var_2->transp.msb_right;
+}
+
 /**
  * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var
  * @var: screeninfo to check
@@ -1609,7 +1628,6 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 {
        struct drm_fb_helper *fb_helper = info->par;
        struct drm_framebuffer *fb = fb_helper->fb;
-       int depth;
 
        if (var->pixclock != 0 || in_dbg_master())
                return -EINVAL;
@@ -1629,72 +1647,15 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
                return -EINVAL;
        }
 
-       switch (var->bits_per_pixel) {
-       case 16:
-               depth = (var->green.length == 6) ? 16 : 15;
-               break;
-       case 32:
-               depth = (var->transp.length > 0) ? 32 : 24;
-               break;
-       default:
-               depth = var->bits_per_pixel;
-               break;
-       }
-
-       switch (depth) {
-       case 8:
-               var->red.offset = 0;
-               var->green.offset = 0;
-               var->blue.offset = 0;
-               var->red.length = 8;
-               var->green.length = 8;
-               var->blue.length = 8;
-               var->transp.length = 0;
-               var->transp.offset = 0;
-               break;
-       case 15:
-               var->red.offset = 10;
-               var->green.offset = 5;
-               var->blue.offset = 0;
-               var->red.length = 5;
-               var->green.length = 5;
-               var->blue.length = 5;
-               var->transp.length = 1;
-               var->transp.offset = 15;
-               break;
-       case 16:
-               var->red.offset = 11;
-               var->green.offset = 5;
-               var->blue.offset = 0;
-               var->red.length = 5;
-               var->green.length = 6;
-               var->blue.length = 5;
-               var->transp.length = 0;
-               var->transp.offset = 0;
-               break;
-       case 24:
-               var->red.offset = 16;
-               var->green.offset = 8;
-               var->blue.offset = 0;
-               var->red.length = 8;
-               var->green.length = 8;
-               var->blue.length = 8;
-               var->transp.length = 0;
-               var->transp.offset = 0;
-               break;
-       case 32:
-               var->red.offset = 16;
-               var->green.offset = 8;
-               var->blue.offset = 0;
-               var->red.length = 8;
-               var->green.length = 8;
-               var->blue.length = 8;
-               var->transp.length = 8;
-               var->transp.offset = 24;
-               break;
-       default:
+       /*
+        * drm fbdev emulation doesn't support changing the pixel format at all,
+        * so reject all pixel format changing requests.
+        */
+       if (!drm_fb_pixel_format_equal(var, &info->var)) {
+               DRM_DEBUG("fbdev emulation doesn't support changing the pixel format\n");
                return -EINVAL;
        }
+
        return 0;
 }
 EXPORT_SYMBOL(drm_fb_helper_check_var);
@@ -3258,13 +3219,15 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
        if (!fb_helper)
                return -ENOMEM;
 
-       ret = drm_client_new(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
+       ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
        if (ret) {
                kfree(fb_helper);
                DRM_DEV_ERROR(dev->dev, "Failed to register client: %d\n", ret);
                return ret;
        }
 
+       drm_client_add(&fb_helper->client);
+
        fb_helper->preferred_bpp = preferred_bpp;
 
        ret = drm_fbdev_client_hotplug(&fb_helper->client);