drm/qxl: add qxl_add_mode helper function
authorGerd Hoffmann <kraxel@redhat.com>
Fri, 18 Jan 2019 12:20:18 +0000 (13:20 +0100)
committerGerd Hoffmann <kraxel@redhat.com>
Mon, 28 Jan 2019 13:24:53 +0000 (14:24 +0100)
Add a helper function to add custom video modes to a connector.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Noralf Trønnes <noralf@tronnes.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20190118122020.27596-22-kraxel@redhat.com
drivers/gpu/drm/qxl/qxl_display.c

index 4b901e81046719b389a0619607532bc84613b497..a0562d5a4fda7627849cf35e7b3b6cc2b83f23f7 100644 (file)
@@ -212,15 +212,36 @@ static int qxl_check_framebuffer(struct qxl_device *qdev,
        return qxl_check_mode(qdev, bo->surf.width, bo->surf.height);
 }
 
-static int qxl_add_monitors_config_modes(struct drm_connector *connector,
-                                         unsigned *pwidth,
-                                         unsigned *pheight)
+static int qxl_add_mode(struct drm_connector *connector,
+                       unsigned int width,
+                       unsigned int height,
+                       bool preferred)
+{
+       struct drm_device *dev = connector->dev;
+       struct qxl_device *qdev = dev->dev_private;
+       struct drm_display_mode *mode = NULL;
+       int rc;
+
+       rc = qxl_check_mode(qdev, width, height);
+       if (rc != 0)
+               return 0;
+
+       mode = drm_cvt_mode(dev, width, height, 60, false, false, false);
+       if (preferred)
+               mode->type |= DRM_MODE_TYPE_PREFERRED;
+       mode->hdisplay = width;
+       mode->vdisplay = height;
+       drm_mode_set_name(mode);
+       drm_mode_probed_add(connector, mode);
+       return 1;
+}
+
+static int qxl_add_monitors_config_modes(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct qxl_device *qdev = dev->dev_private;
        struct qxl_output *output = drm_connector_to_qxl_output(connector);
        int h = output->index;
-       struct drm_display_mode *mode = NULL;
        struct qxl_head *head;
 
        if (!qdev->monitors_config)
@@ -235,19 +256,7 @@ static int qxl_add_monitors_config_modes(struct drm_connector *connector,
        head = &qdev->client_monitors_config->heads[h];
        DRM_DEBUG_KMS("head %d is %dx%d\n", h, head->width, head->height);
 
-       mode = drm_cvt_mode(dev, head->width, head->height, 60, false, false,
-                           false);
-       mode->type |= DRM_MODE_TYPE_PREFERRED;
-       mode->hdisplay = head->width;
-       mode->vdisplay = head->height;
-       drm_mode_set_name(mode);
-       *pwidth = head->width;
-       *pheight = head->height;
-       drm_mode_probed_add(connector, mode);
-       /* remember the last custom size for mode validation */
-       qdev->monitors_config_width = mode->hdisplay;
-       qdev->monitors_config_height = mode->vdisplay;
-       return 1;
+       return qxl_add_mode(connector, head->width, head->height, true);
 }
 
 static struct mode_size {
@@ -273,22 +282,16 @@ static struct mode_size {
        {1920, 1200}
 };
 
-static int qxl_add_common_modes(struct drm_connector *connector,
-                                unsigned int pwidth,
-                                unsigned int pheight)
+static int qxl_add_common_modes(struct drm_connector *connector)
 {
-       struct drm_device *dev = connector->dev;
-       struct drm_display_mode *mode = NULL;
-       int i;
+       int i, ret = 0;
 
-       for (i = 0; i < ARRAY_SIZE(common_modes); i++) {
-               mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h,
-                                   60, false, false, false);
-               if (common_modes[i].w == pwidth && common_modes[i].h == pheight)
-                       mode->type |= DRM_MODE_TYPE_PREFERRED;
-               drm_mode_probed_add(connector, mode);
-       }
-       return i - 1;
+       for (i = 0; i < ARRAY_SIZE(common_modes); i++)
+               ret += qxl_add_mode(connector,
+                                   common_modes[i].w,
+                                   common_modes[i].h,
+                                   false);
+       return ret;
 }
 
 static void qxl_send_monitors_config(struct qxl_device *qdev)
@@ -991,14 +994,25 @@ free_mem:
 
 static int qxl_conn_get_modes(struct drm_connector *connector)
 {
+       struct drm_device *dev = connector->dev;
+       struct qxl_device *qdev = dev->dev_private;
+       struct qxl_output *output = drm_connector_to_qxl_output(connector);
        unsigned int pwidth = 1024;
        unsigned int pheight = 768;
        int ret = 0;
 
-       ret = qxl_add_monitors_config_modes(connector, &pwidth, &pheight);
-       if (ret < 0)
-               return ret;
-       ret += qxl_add_common_modes(connector, pwidth, pheight);
+       if (qdev->client_monitors_config) {
+               struct qxl_head *head;
+               head = &qdev->client_monitors_config->heads[output->index];
+               if (head->width)
+                       pwidth = head->width;
+               if (head->height)
+                       pheight = head->height;
+       }
+
+       ret += qxl_add_common_modes(connector);
+       ret += qxl_add_monitors_config_modes(connector);
+       drm_set_preferred_mode(connector, pwidth, pheight);
        return ret;
 }