Backmerge tag 'v4.9-rc4' into drm-next
Linux 4.9-rc4 This is needed for nouveau development.
This commit is contained in:
@@ -131,7 +131,12 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
|
||||
return 0;
|
||||
fail:
|
||||
for (i = 0; i < fb_helper->connector_count; i++) {
|
||||
kfree(fb_helper->connector_info[i]);
|
||||
struct drm_fb_helper_connector *fb_helper_connector =
|
||||
fb_helper->connector_info[i];
|
||||
|
||||
drm_connector_unreference(fb_helper_connector->connector);
|
||||
|
||||
kfree(fb_helper_connector);
|
||||
fb_helper->connector_info[i] = NULL;
|
||||
}
|
||||
fb_helper->connector_count = 0;
|
||||
@@ -600,6 +605,24 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_blank);
|
||||
|
||||
static void drm_fb_helper_modeset_release(struct drm_fb_helper *helper,
|
||||
struct drm_mode_set *modeset)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < modeset->num_connectors; i++) {
|
||||
drm_connector_unreference(modeset->connectors[i]);
|
||||
modeset->connectors[i] = NULL;
|
||||
}
|
||||
modeset->num_connectors = 0;
|
||||
|
||||
drm_mode_destroy(helper->dev, modeset->mode);
|
||||
modeset->mode = NULL;
|
||||
|
||||
/* FIXME should hold a ref? */
|
||||
modeset->fb = NULL;
|
||||
}
|
||||
|
||||
static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
|
||||
{
|
||||
int i;
|
||||
@@ -609,10 +632,12 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
|
||||
kfree(helper->connector_info[i]);
|
||||
}
|
||||
kfree(helper->connector_info);
|
||||
|
||||
for (i = 0; i < helper->crtc_count; i++) {
|
||||
kfree(helper->crtc_info[i].mode_set.connectors);
|
||||
if (helper->crtc_info[i].mode_set.mode)
|
||||
drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
|
||||
struct drm_mode_set *modeset = &helper->crtc_info[i].mode_set;
|
||||
|
||||
drm_fb_helper_modeset_release(helper, modeset);
|
||||
kfree(modeset->connectors);
|
||||
}
|
||||
kfree(helper->crtc_info);
|
||||
}
|
||||
@@ -641,7 +666,9 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
|
||||
clip->x2 = clip->y2 = 0;
|
||||
spin_unlock_irqrestore(&helper->dirty_lock, flags);
|
||||
|
||||
helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
|
||||
/* call dirty callback only when it has been really touched */
|
||||
if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2)
|
||||
helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2085,7 +2112,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
|
||||
struct drm_fb_helper_crtc **crtcs;
|
||||
struct drm_display_mode **modes;
|
||||
struct drm_fb_offset *offsets;
|
||||
struct drm_mode_set *modeset;
|
||||
bool *enabled;
|
||||
int width, height;
|
||||
int i;
|
||||
@@ -2133,45 +2159,35 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
|
||||
|
||||
/* need to set the modesets up here for use later */
|
||||
/* fill out the connector<->crtc mappings into the modesets */
|
||||
for (i = 0; i < fb_helper->crtc_count; i++) {
|
||||
modeset = &fb_helper->crtc_info[i].mode_set;
|
||||
modeset->num_connectors = 0;
|
||||
modeset->fb = NULL;
|
||||
}
|
||||
for (i = 0; i < fb_helper->crtc_count; i++)
|
||||
drm_fb_helper_modeset_release(fb_helper,
|
||||
&fb_helper->crtc_info[i].mode_set);
|
||||
|
||||
for (i = 0; i < fb_helper->connector_count; i++) {
|
||||
struct drm_display_mode *mode = modes[i];
|
||||
struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
|
||||
struct drm_fb_offset *offset = &offsets[i];
|
||||
modeset = &fb_crtc->mode_set;
|
||||
struct drm_mode_set *modeset = &fb_crtc->mode_set;
|
||||
|
||||
if (mode && fb_crtc) {
|
||||
struct drm_connector *connector =
|
||||
fb_helper->connector_info[i]->connector;
|
||||
|
||||
DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
|
||||
mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
|
||||
|
||||
fb_crtc->desired_mode = mode;
|
||||
fb_crtc->x = offset->x;
|
||||
fb_crtc->y = offset->y;
|
||||
if (modeset->mode)
|
||||
drm_mode_destroy(dev, modeset->mode);
|
||||
modeset->mode = drm_mode_duplicate(dev,
|
||||
fb_crtc->desired_mode);
|
||||
modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
|
||||
drm_connector_reference(connector);
|
||||
modeset->connectors[modeset->num_connectors++] = connector;
|
||||
modeset->fb = fb_helper->fb;
|
||||
modeset->x = offset->x;
|
||||
modeset->y = offset->y;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear out any old modes if there are no more connected outputs. */
|
||||
for (i = 0; i < fb_helper->crtc_count; i++) {
|
||||
modeset = &fb_helper->crtc_info[i].mode_set;
|
||||
if (modeset->num_connectors == 0) {
|
||||
BUG_ON(modeset->fb);
|
||||
if (modeset->mode)
|
||||
drm_mode_destroy(dev, modeset->mode);
|
||||
modeset->mode = NULL;
|
||||
}
|
||||
}
|
||||
out:
|
||||
kfree(crtcs);
|
||||
kfree(modes);
|
||||
|
Reference in New Issue
Block a user