[Intel-gfx] [RFC v4 18/25] drm/client: Make the display modes available to clients
Give clients easy access to the display modes. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_client.c | 159 +-- include/drm/drm_client.h | 25 +++ 2 files changed, 148 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 764c556630b8..bce1630a0db2 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -8,6 +8,7 @@ * Copyright (c) 2007 Dave Airlie */ +#include #include #include @@ -54,6 +55,7 @@ struct drm_client_display *drm_client_display_create(struct drm_device *dev) } display->dev = dev; + INIT_LIST_HEAD(&display->modes); display->modeset_count = num_crtc; drm_for_each_crtc(crtc, dev) @@ -84,12 +86,16 @@ EXPORT_SYMBOL(drm_client_display_create); */ void drm_client_display_free(struct drm_client_display *display) { + struct drm_display_mode *mode, *tmp; struct drm_mode_set *modeset; unsigned int i; if (!display) return; + list_for_each_entry_safe(mode, tmp, &display->modes, head) + drm_mode_destroy(display->dev, mode); + drm_client_display_for_each_modeset(modeset, display) { if (modeset->mode) drm_mode_destroy(display->dev, modeset->mode); @@ -670,22 +676,70 @@ static int drm_pick_crtcs(struct drm_client_display *display, return best_score; } -/** - * drm_client_find_display() - Find display - * @dev: DRM device - * @width: Maximum display mode width (optional) - * @height: Maximum display mode height (optional) - * - * This function returns a display the client can use if available. - * - * Free resources by calling drm_client_display_free(). - * - * Returns: - * A &drm_client_display on success, NULL if no connectors are found - * or error pointer on failure. - */ -struct drm_client_display * -drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int height) +/* Give the client a static list of display modes */ +static int drm_client_display_copy_modes(struct drm_client_display *display) +{ + int hdisplay = 0, vdisplay = 0, vrefresh; + struct drm_device *dev = display->dev; + struct drm_display_mode *mode, *copy; + struct drm_connector *connector; + struct drm_mode_set *modeset; + unsigned int count = 0; + + drm_client_display_for_each_modeset(modeset, display) { + if (!modeset->num_connectors || !modeset->mode) + continue; + + connector = modeset->connectors[0]; + mode = modeset->mode; + count++; + + if (modeset->num_connectors == 2) { + /* Cloned output */ + copy = drm_mode_duplicate(dev, modeset->mode); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + display->mode = copy; + + return 0; + } + + if (!modeset->y) + hdisplay += modeset->mode->hdisplay; + if (!modeset->x) + vdisplay += modeset->mode->vdisplay; + vrefresh = modeset->mode->vrefresh; + } + + if (!count) + return 0; + + if (count == 1) { + struct drm_display_mode *iter; + + list_for_each_entry(iter, &connector->modes, head) { + copy = drm_mode_duplicate(dev, iter); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + if (!display->mode && drm_mode_equal(iter, mode)) + display->mode = copy; + } + } else { + /* Combined tile mode. Only the default one for now */ + copy = drm_cvt_mode(dev, hdisplay, vdisplay, vrefresh, false, false, false); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + display->mode = copy; + } + + return 0; +} + +static struct drm_client_display * +drm_client_find_display_default(struct drm_device *dev, unsigned int width, unsigned int height) { struct drm_client_display_offset *offsets; struct drm_client_display *display; @@ -695,25 +749,6 @@ drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int int i, connector_count; bool *enabled; - DRM_DEBUG_KMS("\n"); - - if (!width) - width = dev->mode_config.max_width; - if (!height) - height = dev->mode_config.max_height; - - mutex_lock(&dev->mode_config.mutex); - if (!drm_client_probe_connector_modes(dev, width, hei
[Intel-gfx] [RFC v4 18/25] drm/client: Make the display modes available to clients
Give clients easy access to the display modes. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_client.c | 159 +-- include/drm/drm_client.h | 25 +++ 2 files changed, 148 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 764c556630b8..bce1630a0db2 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -8,6 +8,7 @@ * Copyright (c) 2007 Dave Airlie */ +#include #include #include @@ -54,6 +55,7 @@ struct drm_client_display *drm_client_display_create(struct drm_device *dev) } display->dev = dev; + INIT_LIST_HEAD(&display->modes); display->modeset_count = num_crtc; drm_for_each_crtc(crtc, dev) @@ -84,12 +86,16 @@ EXPORT_SYMBOL(drm_client_display_create); */ void drm_client_display_free(struct drm_client_display *display) { + struct drm_display_mode *mode, *tmp; struct drm_mode_set *modeset; unsigned int i; if (!display) return; + list_for_each_entry_safe(mode, tmp, &display->modes, head) + drm_mode_destroy(display->dev, mode); + drm_client_display_for_each_modeset(modeset, display) { if (modeset->mode) drm_mode_destroy(display->dev, modeset->mode); @@ -670,22 +676,70 @@ static int drm_pick_crtcs(struct drm_client_display *display, return best_score; } -/** - * drm_client_find_display() - Find display - * @dev: DRM device - * @width: Maximum display mode width (optional) - * @height: Maximum display mode height (optional) - * - * This function returns a display the client can use if available. - * - * Free resources by calling drm_client_display_free(). - * - * Returns: - * A &drm_client_display on success, NULL if no connectors are found - * or error pointer on failure. - */ -struct drm_client_display * -drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int height) +/* Give the client a static list of display modes */ +static int drm_client_display_copy_modes(struct drm_client_display *display) +{ + int hdisplay = 0, vdisplay = 0, vrefresh; + struct drm_device *dev = display->dev; + struct drm_display_mode *mode, *copy; + struct drm_connector *connector; + struct drm_mode_set *modeset; + unsigned int count = 0; + + drm_client_display_for_each_modeset(modeset, display) { + if (!modeset->num_connectors || !modeset->mode) + continue; + + connector = modeset->connectors[0]; + mode = modeset->mode; + count++; + + if (modeset->num_connectors == 2) { + /* Cloned output */ + copy = drm_mode_duplicate(dev, modeset->mode); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + display->mode = copy; + + return 0; + } + + if (!modeset->y) + hdisplay += modeset->mode->hdisplay; + if (!modeset->x) + vdisplay += modeset->mode->vdisplay; + vrefresh = modeset->mode->vrefresh; + } + + if (!count) + return 0; + + if (count == 1) { + struct drm_display_mode *iter; + + list_for_each_entry(iter, &connector->modes, head) { + copy = drm_mode_duplicate(dev, iter); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + if (!display->mode && drm_mode_equal(iter, mode)) + display->mode = copy; + } + } else { + /* Combined tile mode. Only the default one for now */ + copy = drm_cvt_mode(dev, hdisplay, vdisplay, vrefresh, false, false, false); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + display->mode = copy; + } + + return 0; +} + +static struct drm_client_display * +drm_client_find_display_default(struct drm_device *dev, unsigned int width, unsigned int height) { struct drm_client_display_offset *offsets; struct drm_client_display *display; @@ -695,25 +749,6 @@ drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int int i, connector_count; bool *enabled; - DRM_DEBUG_KMS("\n"); - - if (!width) - width = dev->mode_config.max_width; - if (!height) - height = dev->mode_config.max_height; - - mutex_lock(&dev->mode_config.mutex); - if (!drm_client_probe_connector_modes(dev, width, hei
[Intel-gfx] [RFC v4 18/25] drm/client: Make the display modes available to clients
Give clients easy access to the display modes. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_client.c | 159 +-- include/drm/drm_client.h | 25 +++ 2 files changed, 148 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index 764c556630b8..bce1630a0db2 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -8,6 +8,7 @@ * Copyright (c) 2007 Dave Airlie */ +#include #include #include @@ -54,6 +55,7 @@ struct drm_client_display *drm_client_display_create(struct drm_device *dev) } display->dev = dev; + INIT_LIST_HEAD(&display->modes); display->modeset_count = num_crtc; drm_for_each_crtc(crtc, dev) @@ -84,12 +86,16 @@ EXPORT_SYMBOL(drm_client_display_create); */ void drm_client_display_free(struct drm_client_display *display) { + struct drm_display_mode *mode, *tmp; struct drm_mode_set *modeset; unsigned int i; if (!display) return; + list_for_each_entry_safe(mode, tmp, &display->modes, head) + drm_mode_destroy(display->dev, mode); + drm_client_display_for_each_modeset(modeset, display) { if (modeset->mode) drm_mode_destroy(display->dev, modeset->mode); @@ -670,22 +676,70 @@ static int drm_pick_crtcs(struct drm_client_display *display, return best_score; } -/** - * drm_client_find_display() - Find display - * @dev: DRM device - * @width: Maximum display mode width (optional) - * @height: Maximum display mode height (optional) - * - * This function returns a display the client can use if available. - * - * Free resources by calling drm_client_display_free(). - * - * Returns: - * A &drm_client_display on success, NULL if no connectors are found - * or error pointer on failure. - */ -struct drm_client_display * -drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int height) +/* Give the client a static list of display modes */ +static int drm_client_display_copy_modes(struct drm_client_display *display) +{ + int hdisplay = 0, vdisplay = 0, vrefresh; + struct drm_device *dev = display->dev; + struct drm_display_mode *mode, *copy; + struct drm_connector *connector; + struct drm_mode_set *modeset; + unsigned int count = 0; + + drm_client_display_for_each_modeset(modeset, display) { + if (!modeset->num_connectors || !modeset->mode) + continue; + + connector = modeset->connectors[0]; + mode = modeset->mode; + count++; + + if (modeset->num_connectors == 2) { + /* Cloned output */ + copy = drm_mode_duplicate(dev, modeset->mode); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + display->mode = copy; + + return 0; + } + + if (!modeset->y) + hdisplay += modeset->mode->hdisplay; + if (!modeset->x) + vdisplay += modeset->mode->vdisplay; + vrefresh = modeset->mode->vrefresh; + } + + if (!count) + return 0; + + if (count == 1) { + struct drm_display_mode *iter; + + list_for_each_entry(iter, &connector->modes, head) { + copy = drm_mode_duplicate(dev, iter); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + if (!display->mode && drm_mode_equal(iter, mode)) + display->mode = copy; + } + } else { + /* Combined tile mode. Only the default one for now */ + copy = drm_cvt_mode(dev, hdisplay, vdisplay, vrefresh, false, false, false); + if (!copy) + return -ENOMEM; + list_add_tail(©->head, &display->modes); + display->mode = copy; + } + + return 0; +} + +static struct drm_client_display * +drm_client_find_display_default(struct drm_device *dev, unsigned int width, unsigned int height) { struct drm_client_display_offset *offsets; struct drm_client_display *display; @@ -695,25 +749,6 @@ drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int int i, connector_count; bool *enabled; - DRM_DEBUG_KMS("\n"); - - if (!width) - width = dev->mode_config.max_width; - if (!height) - height = dev->mode_config.max_height; - - mutex_lock(&dev->mode_config.mutex); - if (!drm_client_probe_connector_modes(dev, width, hei