Commit 1b043677 authored by Gerd Hoffmann's avatar Gerd Hoffmann

drm/qxl: add qxl_add_mode helper function

Add a helper function to add custom video modes to a connector.
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Acked-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: http://patchwork.freedesktop.org/patch/msgid/20190118122020.27596-22-kraxel@redhat.com
parent feba24de
...@@ -212,15 +212,36 @@ static int qxl_check_framebuffer(struct qxl_device *qdev, ...@@ -212,15 +212,36 @@ static int qxl_check_framebuffer(struct qxl_device *qdev,
return qxl_check_mode(qdev, bo->surf.width, bo->surf.height); return qxl_check_mode(qdev, bo->surf.width, bo->surf.height);
} }
static int qxl_add_monitors_config_modes(struct drm_connector *connector, static int qxl_add_mode(struct drm_connector *connector,
unsigned *pwidth, unsigned int width,
unsigned *pheight) 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 drm_device *dev = connector->dev;
struct qxl_device *qdev = dev->dev_private; struct qxl_device *qdev = dev->dev_private;
struct qxl_output *output = drm_connector_to_qxl_output(connector); struct qxl_output *output = drm_connector_to_qxl_output(connector);
int h = output->index; int h = output->index;
struct drm_display_mode *mode = NULL;
struct qxl_head *head; struct qxl_head *head;
if (!qdev->monitors_config) if (!qdev->monitors_config)
...@@ -235,19 +256,7 @@ static int qxl_add_monitors_config_modes(struct drm_connector *connector, ...@@ -235,19 +256,7 @@ static int qxl_add_monitors_config_modes(struct drm_connector *connector,
head = &qdev->client_monitors_config->heads[h]; head = &qdev->client_monitors_config->heads[h];
DRM_DEBUG_KMS("head %d is %dx%d\n", h, head->width, head->height); 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, return qxl_add_mode(connector, head->width, head->height, true);
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;
} }
static struct mode_size { static struct mode_size {
...@@ -273,22 +282,16 @@ static struct mode_size { ...@@ -273,22 +282,16 @@ static struct mode_size {
{1920, 1200} {1920, 1200}
}; };
static int qxl_add_common_modes(struct drm_connector *connector, static int qxl_add_common_modes(struct drm_connector *connector)
unsigned int pwidth,
unsigned int pheight)
{ {
struct drm_device *dev = connector->dev; int i, ret = 0;
struct drm_display_mode *mode = NULL;
int i;
for (i = 0; i < ARRAY_SIZE(common_modes); i++) { for (i = 0; i < ARRAY_SIZE(common_modes); i++)
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, ret += qxl_add_mode(connector,
60, false, false, false); common_modes[i].w,
if (common_modes[i].w == pwidth && common_modes[i].h == pheight) common_modes[i].h,
mode->type |= DRM_MODE_TYPE_PREFERRED; false);
drm_mode_probed_add(connector, mode); return ret;
}
return i - 1;
} }
static void qxl_send_monitors_config(struct qxl_device *qdev) static void qxl_send_monitors_config(struct qxl_device *qdev)
...@@ -991,14 +994,25 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id) ...@@ -991,14 +994,25 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id)
static int qxl_conn_get_modes(struct drm_connector *connector) 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 pwidth = 1024;
unsigned int pheight = 768; unsigned int pheight = 768;
int ret = 0; int ret = 0;
ret = qxl_add_monitors_config_modes(connector, &pwidth, &pheight); if (qdev->client_monitors_config) {
if (ret < 0) struct qxl_head *head;
return ret; head = &qdev->client_monitors_config->heads[output->index];
ret += qxl_add_common_modes(connector, pwidth, pheight); 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; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment