diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/drm_crtc.c | 14 | ||||
| -rw-r--r-- | linux-core/drm_crtc.h | 4 | ||||
| -rw-r--r-- | linux-core/intel_display.c | 1 | 
3 files changed, 18 insertions, 1 deletions
| diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index fdf4c70e..1e69eca3 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -1048,6 +1048,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  	struct drm_crtc **save_crtcs, *new_crtc;  	bool save_enabled = crtc->enabled;  	bool changed = false; +	bool flip_or_move = false;  	struct drm_output *output;  	int count = 0, ro; @@ -1055,11 +1056,13 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  	if (!save_crtcs)  		return -ENOMEM; +	/* We should be able to check here if the fb has the same properties +	 * and then just flip_or_move it */  	if (crtc->fb != fb)  		changed = true;  	if (crtc_info->x != crtc->x || crtc_info->y != crtc->y) -		changed = true; +		flip_or_move = true;  	if (new_mode && !drm_mode_equal(new_mode, &crtc->mode))  		changed = true; @@ -1082,6 +1085,10 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  		}  	} +	/* mode_set_base is not a required function */ +	if (flip_or_move && !crtc->funcs->mode_set_base) +		changed = true; +  	if (changed) {  		crtc->fb = fb;  		crtc->enabled = (new_mode != NULL); @@ -1102,7 +1109,10 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  			crtc->desired_mode = new_mode;  		}  		drm_disable_unused_functions(dev); +	} else if (flip_or_move) { +		crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);  	} +  	kfree(save_crtcs);  	return 0;  } @@ -1564,6 +1574,7 @@ int drm_mode_setcrtc(struct drm_device *dev,  	if (crtc_req->count_outputs > 0) {  		u32 out_id; +		/* Maybe we should check that count_outputs is a sensible value. */  		output_set = kmalloc(crtc_req->count_outputs *  				     sizeof(struct drm_output *), GFP_KERNEL);  		if (!output_set) { @@ -1589,6 +1600,7 @@ int drm_mode_setcrtc(struct drm_device *dev,  		}  	} +	/* What happens to output_set, leak? */  	ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb);  out: diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 54e0c000..65c3704a 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -325,6 +325,10 @@ struct drm_crtc_funcs {  	/* Actually set the mode */  	void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,  			 struct drm_display_mode *adjusted_mode, int x, int y); + +	/* Move the crtc on the current fb to the given position *optional* */ +	void (*mode_set_base)(struct drm_crtc *crtc, int x, int y); +  	/* Set gamma on the CRTC */  	void (*gamma_set)(struct drm_crtc *crtc, u16 r, u16 g, u16 b,  			  int regno); diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index a81cfe69..e75d3c07 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -1083,6 +1083,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {  	.unlock = intel_crtc_unlock,  	.mode_fixup = intel_crtc_mode_fixup,  	.mode_set = intel_crtc_mode_set, +	.mode_set_base = intel_pipe_set_base,  	.gamma_set = intel_crtc_gamma_set,  	.prepare = intel_crtc_prepare,  	.commit = intel_crtc_commit, | 
