From patchwork Fri Mar 30 22:59:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 7554 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id DFF361991DE for ; Fri, 30 Mar 2012 22:59:43 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 8136AA18097 for ; Fri, 30 Mar 2012 22:59:43 +0000 (UTC) Received: by iage36 with SMTP id e36so2245554iag.11 for ; Fri, 30 Mar 2012 15:59:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :dkim-signature:sender:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=aDVGqzKQWxggfkzjpDKzZce7NNoSriTO5x2E7zdWNIo=; b=eIL6Xmt4AljHc51K1AqOJVn5P2jUmHWAXabXW/rjliad1VUtAMt0Sq9DH916ACkRLH uBVjV/I2hoNJ/uVdbPQ08ghe+hBTDzbt/+AW1PMil1F6xsgj1OEM9LZ+QByyn/jm4TfM w/Sv2n+iU6mvQgNo1zz3SicZI4tcLeGFLnNkEUHV5fxXLaIcsOYDwbt/+mt6tdNM9Q87 wbZyO4nC23w4GQcgD7Lplxte+bjWvnrR7aJmdqtbQCfvwbmp0f6faI8lN3++TgnO0i2s qnf6HzNGQNeupJVxBSucbGiWGhS89m+BNXAHlgf2EEQdTcIY00VFQ1G9Pitl5fj5gmKr l0ZA== Received: by 10.43.134.199 with SMTP id id7mr114462icc.21.1333148382818; Fri, 30 Mar 2012 15:59:42 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.5.205 with SMTP id 13csp18015ibw; Fri, 30 Mar 2012 15:59:42 -0700 (PDT) Received: by 10.182.72.73 with SMTP id b9mr262725obv.34.1333148380883; Fri, 30 Mar 2012 15:59:40 -0700 (PDT) Received: from mail-ob0-f178.google.com (mail-ob0-f178.google.com [209.85.214.178]) by mx.google.com with ESMTPS id t2si7394454oef.53.2012.03.30.15.59.40 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 30 Mar 2012 15:59:40 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.214.178 as permitted sender) client-ip=209.85.214.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.214.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by obceq6 with SMTP id eq6so528036obc.37 for ; Fri, 30 Mar 2012 15:59:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer; bh=aDVGqzKQWxggfkzjpDKzZce7NNoSriTO5x2E7zdWNIo=; b=xxrMZU1utzqGO8dbVeP6c5UgqygK8GbGzxd1LXVCwp5KxEjRTIVkUPg189ulIpsVTG 0J5MEQUbICqxh0Sak+y6JKFSpYp28Me2BNb8i+UWjibppkH6DXVKgG4e9Hf6dtd+m4Vt QkwiA01icd++BWGoYNy0R6FhXc1C17T9ormcAOGr2SKbmMmdV9u25YzzC3girL8ZKsEG 8b9h4e6jfDIC3ZuVlOfW0ctd3YXNKBu+sQytUuFzehxNFTh0drHlm7QoolJ7ncS2McVB sG7vFx1RmK0bFRMRnLxsJDPfM5IEDxV9KhA5J0DtyJ+zgEbl+rSOu2FBWJOjxzCiws+Z X+jw== Received: by 10.60.20.100 with SMTP id m4mr327793oee.10.1333148380115; Fri, 30 Mar 2012 15:59:40 -0700 (PDT) Received: from localhost (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id dy7sm971926obb.5.2012.03.30.15.59.39 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 30 Mar 2012 15:59:39 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, Rob Clark Subject: [PATCH RFC] drm: support for rotated scanout Date: Fri, 30 Mar 2012 17:59:32 -0500 Message-Id: <1333148372-31870-1-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.9.1 X-Gm-Message-State: ALoCoQli74Ukfb6yO4+HZPhUHn+8hpstuT4z46AljfVE8CFeoat6BsyyRgANeiX/hH6zIJG/cnDu From: Rob Clark For drivers that can support rotated scanout, the extra parameter checking in drm-core, while nice, tends to get confused. To solve this drivers can set the crtc or plane invert_dimensions field so that the dimension checking takes into account the rotation that the driver is performing. --- Note: RFC still mainly because I've only tested the CRTC rotation so far.. still need to write some test code for plane rotation. drivers/gpu/drm/drm_crtc.c | 50 +++++++++++++++++++++++++++++-------------- include/drm/drm_crtc.h | 9 ++++++++ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 0dff444..261c9bd 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -375,6 +375,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, crtc->dev = dev; crtc->funcs = funcs; + crtc->invert_dimensions = false; mutex_lock(&dev->mode_config.mutex); @@ -609,6 +610,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, plane->base.properties = &plane->properties; plane->dev = dev; plane->funcs = funcs; + plane->invert_dimensions = false; plane->format_types = kmalloc(sizeof(uint32_t) * format_count, GFP_KERNEL); if (!plane->format_types) { @@ -1758,6 +1760,9 @@ int drm_mode_setplane(struct drm_device *dev, void *data, fb_width = fb->width << 16; fb_height = fb->height << 16; + if (plane->invert_dimensions) + swap(fb_width, fb_height); + /* Make sure source coordinates are inside the fb. */ if (plane_req->src_w > fb_width || plane_req->src_x > fb_width - plane_req->src_w || @@ -1856,6 +1861,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); if (crtc_req->mode_valid) { + int hdisplay, vdisplay; /* If we have a mode we need a framebuffer. */ /* If we pass -1, set the mode with the currently bound fb */ if (crtc_req->fb_id == -1) { @@ -1891,14 +1897,20 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - if (mode->hdisplay > fb->width || - mode->vdisplay > fb->height || - crtc_req->x > fb->width - mode->hdisplay || - crtc_req->y > fb->height - mode->vdisplay) { - DRM_DEBUG_KMS("Invalid CRTC viewport %ux%u+%u+%u for fb size %ux%u.\n", - mode->hdisplay, mode->vdisplay, - crtc_req->x, crtc_req->y, - fb->width, fb->height); + hdisplay = mode->hdisplay; + vdisplay = mode->vdisplay; + + if (crtc->invert_dimensions) + swap(hdisplay, vdisplay); + + if (hdisplay > fb->width || + vdisplay > fb->height || + crtc_req->x > fb->width - hdisplay || + crtc_req->y > fb->height - vdisplay) { + DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n", + fb->width, fb->height, + hdisplay, vdisplay, crtc_req->x, crtc_req->y, + crtc->invert_dimensions ? " (inverted)" : ""); ret = -ENOSPC; goto out; } @@ -3452,6 +3464,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, struct drm_framebuffer *fb; struct drm_pending_vblank_event *e = NULL; unsigned long flags; + int hdisplay, vdisplay; int ret = -EINVAL; if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || @@ -3481,14 +3494,19 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, goto out; fb = obj_to_fb(obj); - if (crtc->mode.hdisplay > fb->width || - crtc->mode.vdisplay > fb->height || - crtc->x > fb->width - crtc->mode.hdisplay || - crtc->y > fb->height - crtc->mode.vdisplay) { - DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d.\n", - fb->width, fb->height, - crtc->mode.hdisplay, crtc->mode.vdisplay, - crtc->x, crtc->y); + hdisplay = crtc->mode.hdisplay; + vdisplay = crtc->mode.vdisplay; + + if (crtc->invert_dimensions) + swap(hdisplay, vdisplay); + + if (hdisplay > fb->width || + vdisplay > fb->height || + crtc->x > fb->width - hdisplay || + crtc->y > fb->height - vdisplay) { + DRM_DEBUG_KMS("Invalid fb size %ux%u for CRTC viewport %ux%u+%d+%d%s.\n", + fb->width, fb->height, hdisplay, vdisplay, crtc->x, crtc->y, + crtc->invert_dimensions ? " (inverted)" : ""); ret = -ENOSPC; goto out; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index b5017c9..78dd5b5 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -364,6 +364,9 @@ struct drm_crtc_funcs { * @enabled: is this CRTC enabled? * @mode: current mode timings * @hwmode: mode timings as programmed to hw regs + * @invert_dimensions: for purposes of error checking crtc vs fb sizes, + * invert the width/height of the crtc. This is used if the driver + * is performing 90 or 270 degree rotated scanout * @x: x position on screen * @y: y position on screen * @funcs: CRTC control functions @@ -397,6 +400,8 @@ struct drm_crtc { */ struct drm_display_mode hwmode; + bool invert_dimensions; + int x, y; const struct drm_crtc_funcs *funcs; @@ -636,6 +641,9 @@ struct drm_plane_funcs { * @gamma_size: size of gamma table * @gamma_store: gamma correction table * @enabled: enabled flag + * @invert_dimensions: for purposes of error checking plane vs fb sizes, + * invert the width/height of the plane. This is used if the driver + * is performing 90 or 270 degree rotated scanout * @funcs: helper functions * @helper_private: storage for drver layer */ @@ -657,6 +665,7 @@ struct drm_plane { uint16_t *gamma_store; bool enabled; + bool invert_dimensions; const struct drm_plane_funcs *funcs; void *helper_private;