aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2013-09-25 11:45:30 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-01 01:45:36 -0400
commitc11e928360777be8eaf5023032e9b6c62eb2c43e (patch)
tree3723d7e0cbc7e252314be4fe8e29ef67fd31b03f /drivers/gpu/drm/drm_crtc.c
parent448cce25f408be4c933f88ed8962455a0c16d0f8 (diff)
drm: Factor out common CRTC viewport checking code
Both setcrtc and page_flip are checking that the framebuffer is big enough for the defined crtc viewport (x, y, hdisplay, vdisplay). Factor that code out in a single function. Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Acked-by: Dave Airlie <airlied@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c70
1 files changed, 37 insertions, 33 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 090415f418b8..db058643b01d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -2063,6 +2063,37 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
2063} 2063}
2064EXPORT_SYMBOL(drm_mode_set_config_internal); 2064EXPORT_SYMBOL(drm_mode_set_config_internal);
2065 2065
2066/*
2067 * Checks that the framebuffer is big enough for the CRTC viewport
2068 * (x, y, hdisplay, vdisplay)
2069 */
2070static int drm_crtc_check_viewport(const struct drm_crtc *crtc,
2071 int x, int y,
2072 const struct drm_display_mode *mode,
2073 const struct drm_framebuffer *fb)
2074
2075{
2076 int hdisplay, vdisplay;
2077
2078 hdisplay = mode->hdisplay;
2079 vdisplay = mode->vdisplay;
2080
2081 if (crtc->invert_dimensions)
2082 swap(hdisplay, vdisplay);
2083
2084 if (hdisplay > fb->width ||
2085 vdisplay > fb->height ||
2086 x > fb->width - hdisplay ||
2087 y > fb->height - vdisplay) {
2088 DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
2089 fb->width, fb->height, hdisplay, vdisplay, x, y,
2090 crtc->invert_dimensions ? " (inverted)" : "");
2091 return -ENOSPC;
2092 }
2093
2094 return 0;
2095}
2096
2066/** 2097/**
2067 * drm_mode_setcrtc - set CRTC configuration 2098 * drm_mode_setcrtc - set CRTC configuration
2068 * @dev: drm device for the ioctl 2099 * @dev: drm device for the ioctl
@@ -2110,7 +2141,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
2110 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); 2141 DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
2111 2142
2112 if (crtc_req->mode_valid) { 2143 if (crtc_req->mode_valid) {
2113 int hdisplay, vdisplay;
2114 /* If we have a mode we need a framebuffer. */ 2144 /* If we have a mode we need a framebuffer. */
2115 /* If we pass -1, set the mode with the currently bound fb */ 2145 /* If we pass -1, set the mode with the currently bound fb */
2116 if (crtc_req->fb_id == -1) { 2146 if (crtc_req->fb_id == -1) {
@@ -2146,23 +2176,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
2146 2176
2147 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 2177 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
2148 2178
2149 hdisplay = mode->hdisplay; 2179 ret = drm_crtc_check_viewport(crtc, crtc_req->x, crtc_req->y,
2150 vdisplay = mode->vdisplay; 2180 mode, fb);
2151 2181 if (ret)
2152 if (crtc->invert_dimensions)
2153 swap(hdisplay, vdisplay);
2154
2155 if (hdisplay > fb->width ||
2156 vdisplay > fb->height ||
2157 crtc_req->x > fb->width - hdisplay ||
2158 crtc_req->y > fb->height - vdisplay) {
2159 DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
2160 fb->width, fb->height,
2161 hdisplay, vdisplay, crtc_req->x, crtc_req->y,
2162 crtc->invert_dimensions ? " (inverted)" : "");
2163 ret = -ENOSPC;
2164 goto out; 2182 goto out;
2165 } 2183
2166 } 2184 }
2167 2185
2168 if (crtc_req->count_connectors == 0 && mode) { 2186 if (crtc_req->count_connectors == 0 && mode) {
@@ -3579,7 +3597,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
3579 struct drm_framebuffer *fb = NULL, *old_fb = NULL; 3597 struct drm_framebuffer *fb = NULL, *old_fb = NULL;
3580 struct drm_pending_vblank_event *e = NULL; 3598 struct drm_pending_vblank_event *e = NULL;
3581 unsigned long flags; 3599 unsigned long flags;
3582 int hdisplay, vdisplay;
3583 int ret = -EINVAL; 3600 int ret = -EINVAL;
3584 3601
3585 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || 3602 if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS ||
@@ -3611,22 +3628,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
3611 if (!fb) 3628 if (!fb)
3612 goto out; 3629 goto out;
3613 3630
3614 hdisplay = crtc->mode.hdisplay; 3631 ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y, &crtc->mode, fb);
3615 vdisplay = crtc->mode.vdisplay; 3632 if (ret)
3616
3617 if (crtc->invert_dimensions)
3618 swap(hdisplay, vdisplay);
3619
3620 if (hdisplay > fb->width ||
3621 vdisplay > fb->height ||
3622 crtc->x > fb->width - hdisplay ||
3623 crtc->y > fb->height - vdisplay) {
3624 DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n",
3625 fb->width, fb->height, hdisplay, vdisplay, crtc->x, crtc->y,
3626 crtc->invert_dimensions ? " (inverted)" : "");
3627 ret = -ENOSPC;
3628 goto out; 3633 goto out;
3629 }
3630 3634
3631 if (crtc->fb->pixel_format != fb->pixel_format) { 3635 if (crtc->fb->pixel_format != fb->pixel_format) {
3632 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n"); 3636 DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");