From patchwork Fri Aug 25 14:57:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 9923109 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 41053602BD for ; Sat, 26 Aug 2017 04:44:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 30B7C2844E for ; Sat, 26 Aug 2017 04:44:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 24FB0285B1; Sat, 26 Aug 2017 04:44:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1ABA02844E for ; Sat, 26 Aug 2017 04:44:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BE62B6E1E0; Sat, 26 Aug 2017 04:44:23 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr0-x244.google.com (mail-wr0-x244.google.com [IPv6:2a00:1450:400c:c0c::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5BCE76E8AE; Fri, 25 Aug 2017 14:57:48 +0000 (UTC) Received: by mail-wr0-x244.google.com with SMTP id p8so26428wrf.3; Fri, 25 Aug 2017 07:57:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xaW7rVLAlPiDoBH6qoWQYH/3uz1UrICOPUNg3ie/noA=; b=grzSKqPV/5EfspqXM/GZ8xerOxmWDwsU6u9+kj8CRXh2CB6bOvJ5JwG8p9rHGcl4rc Wv/LCB3XUkdS2mnA6vJO8Gd6nE27JyL+AN+Kvh39oCvHlk6MjwS6G65QQ3Qs8UQ1l9TX nIZgN6/kt3ftGXuYiKQWaMlA4veUYalWJOmp/DM4XKnnSaCDfWXgrT6pi39lqSipPJbN IJpuIDJvmAZLPKjSovteq0+JIgjqQGKwKwLIzd/1bZ49YEho8riOGV9Noc448AahTiBy djabWBes3BgtuuNTi+NAPakep8r8++Hhffc8Z1rEUlXf/yDghXBe9LLyYP8s6HsNaJyx 2QDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xaW7rVLAlPiDoBH6qoWQYH/3uz1UrICOPUNg3ie/noA=; b=ISML6XDPzR60TiShMFQ1wntkQbpLKUk3tNq+YvDwM0iCgRVZwJaYwDdYpTHpazPMiw cZA+NHorr2xxOubQq6eS5Vrr1x4kP3D0VJPF6EPaFLoKpjlq9LNXFx4+wt6/xVqgBB24 cqTYJqvULu6Vld2AnLb/nQCViu/GSocOPW83/zmgY0hbu79oAAg1XJnhwmq/h+amgs9U 6Eu6zho4Q+QiAFUp1W9Mn8uHaoscF8jXWs+nUdDOGikgtWJI4728lysNOBNIvqw3tTCe ESi6xsAdFHNs/siqIm4lIcQIJ2nb7veHKhZDXe4iAr0IDg4p1zRkcryW13XTdlxq7z7Z TB0Q== X-Gm-Message-State: AHYfb5iHj9KX+/uilZx/pe5WgoM8zgoWwSA01czeet6oAZs7IV9MN4K0 TMzehW/LWKsXPA== X-Received: by 10.223.184.173 with SMTP id i42mr851917wrf.281.1503673066590; Fri, 25 Aug 2017 07:57:46 -0700 (PDT) Received: from shalem.localdomain.com (546A5441.cm-12-3b.dynamic.ziggo.nl. [84.106.84.65]) by smtp.gmail.com with ESMTPSA id i80sm2096595wmh.40.2017.08.25.07.57.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 25 Aug 2017 07:57:44 -0700 (PDT) From: Hans de Goede X-Google-Original-From: Hans de Goede To: Daniel Vetter , Jani Nikula , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Subject: [PATCH v4] drm/i915: Deal with upside-down mounted LCD panels Date: Fri, 25 Aug 2017 16:57:30 +0200 Message-Id: <20170825145730.26924-2-hdegoede@redhat.com> X-Mailer: git-send-email 2.13.4 In-Reply-To: <20170825145730.26924-1-hdegoede@redhat.com> References: <20170825145730.26924-1-hdegoede@redhat.com> X-Mailman-Approved-At: Sat, 26 Aug 2017 04:44:19 +0000 Cc: Hans de Goede , intel-gfx , dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP On some (Bay Trail) devices the LCD panel is mounted upside-down. This commit uses the code to read back the initial rotation of the primary plane in get_initial_plane_config from Ville Syrjala's "drm/fb-helper: Inherit rotation wip" patch and when re-using the initial fb it stores that in intel_crtc.initial_rotation. It adds an intel_plane_get_rotation helper which combines this initial_rotation with any rotation requested by userspace and uses this in all places which look at a planes rotation, thus transparently dealing with upside-down LCD panels without requiring any user-space or fbcon changes. This fixes the kernel boot messages switching from being shown the right way up in efifb to being shown upside down as soon as a native kms driver loads, as well as any graphics displayed by userspace being upside-down. Note this only deals with upside-down LCD panels / 180 degrees rotation as the hardware in question only supports 180 degrees rotation in hardware. The one model known which has a panel mounted with 90/270 degrees rotation will need to be fully dealt with in userspace, even the firmware boot screen / menus are rotated 90 degrees on this one and there simply is nothing the kernel can do about this. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=94894 Cc: Ville Syrjala Signed-off-by: Hans de Goede --- Changes in v2: -Fix brown paperbag bug s/val & mask/val & ~mask/ to clear old rotation bits Changes in v3: -Rebase on current (2017 aug. 22) drm-intel-next-queued Changes in v4: -Fix compiler warning from unhandled case in intel_fixup_initial_subpixel_order --- drivers/gpu/drm/i915/intel_atomic_plane.c | 7 ++- drivers/gpu/drm/i915/intel_display.c | 93 +++++++++++++++++++++++++------ drivers/gpu/drm/i915/intel_drv.h | 32 +++++++++++ drivers/gpu/drm/i915/intel_fbc.c | 2 +- drivers/gpu/drm/i915/intel_pm.c | 6 +- drivers/gpu/drm/i915/intel_sprite.c | 14 ++--- 6 files changed, 123 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c index ee76fab7bb6f..824aaba5112b 100644 --- a/drivers/gpu/drm/i915/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c @@ -116,6 +116,7 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane = to_intel_plane(plane); const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; + unsigned int rotation = intel_plane_get_rotation(state); int ret; /* @@ -135,7 +136,7 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, intel_state->clip.y2 = crtc_state->base.enable ? crtc_state->pipe_src_h : 0; - if (state->fb && drm_rotation_90_or_270(state->rotation)) { + if (state->fb && drm_rotation_90_or_270(rotation)) { struct drm_format_name_buf format_name; if (state->fb->modifier != I915_FORMAT_MOD_Y_TILED && @@ -164,8 +165,8 @@ int intel_plane_atomic_check_with_state(struct intel_crtc_state *crtc_state, /* CHV ignores the mirror bit when the rotate bit is set :( */ if (IS_CHERRYVIEW(dev_priv) && - state->rotation & DRM_MODE_ROTATE_180 && - state->rotation & DRM_MODE_REFLECT_X) { + rotation & DRM_MODE_ROTATE_180 && + rotation & DRM_MODE_REFLECT_X) { DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eda1aa0c343c..a5fe9f9f1bf0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2277,7 +2277,7 @@ void intel_add_fb_offsets(int *x, int *y, { const struct intel_framebuffer *intel_fb = to_intel_framebuffer(state->base.fb); - unsigned int rotation = state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&state->base); if (drm_rotation_90_or_270(rotation)) { *x += intel_fb->rotated[plane].x; @@ -2330,7 +2330,7 @@ static u32 intel_adjust_tile_offset(int *x, int *y, const struct drm_i915_private *dev_priv = to_i915(state->base.plane->dev); const struct drm_framebuffer *fb = state->base.fb; unsigned int cpp = fb->format->cpp[plane]; - unsigned int rotation = state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&state->base); unsigned int pitch = intel_fb_pitch(fb, plane, rotation); WARN_ON(new_offset > old_offset); @@ -2434,7 +2434,7 @@ u32 intel_compute_tile_offset(int *x, int *y, struct intel_plane *intel_plane = to_intel_plane(state->base.plane); struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev); const struct drm_framebuffer *fb = state->base.fb; - unsigned int rotation = state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&state->base); int pitch = intel_fb_pitch(fb, plane, rotation); u32 alignment; @@ -2792,6 +2792,46 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state, } static void +intel_fixup_initial_subpixel_order(struct drm_connector *connector, + u8 initial_rotation) +{ + enum subpixel_order new_order; + + /* We only support an initial rotation of DRM_MODE_ROTATE_180 for now */ + if (initial_rotation != DRM_MODE_ROTATE_180) + return; + + switch (connector->display_info.subpixel_order) { + case SubPixelHorizontalRGB: new_order = SubPixelHorizontalBGR; break; + case SubPixelHorizontalBGR: new_order = SubPixelHorizontalRGB; break; + case SubPixelVerticalRGB: new_order = SubPixelVerticalBGR; break; + case SubPixelVerticalBGR: new_order = SubPixelVerticalRGB; break; + default: + return; /* Leave none / unkown subpixel order unchanged. */ + } + + connector->display_info.subpixel_order = new_order; +} + +static void +intel_set_initial_rotation(struct intel_crtc *intel_crtc, u8 rotation) +{ + struct drm_crtc_state *state = intel_crtc->base.state; + struct drm_device *dev = intel_crtc->base.dev; + struct drm_connector_list_iter conn_iter; + struct drm_connector *conn; + + intel_crtc->initial_rotation = rotation; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(conn, &conn_iter) { + if (state->connector_mask & (1 << drm_connector_index(conn))) + intel_fixup_initial_subpixel_order(conn, rotation); + } + drm_connector_list_iter_end(&conn_iter); +} + +static void intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, struct intel_initial_plane_config *plane_config) { @@ -2858,9 +2898,11 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, return; valid_fb: + intel_set_initial_rotation(intel_crtc, plane_config->rotation); + mutex_lock(&dev->struct_mutex); intel_state->vma = - intel_pin_and_fence_fb_obj(fb, primary->state->rotation); + intel_pin_and_fence_fb_obj(fb, intel_crtc->initial_rotation); mutex_unlock(&dev->struct_mutex); if (IS_ERR(intel_state->vma)) { DRM_ERROR("failed to pin boot fb on pipe %d: %li\n", @@ -2986,7 +3028,7 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state static int skl_check_main_surface(struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); int x = plane_state->base.src.x1 >> 16; int y = plane_state->base.src.y1 >> 16; int w = drm_rect_width(&plane_state->base.src) >> 16; @@ -3064,7 +3106,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); int max_width = skl_max_plane_width(fb, 1, rotation); int max_height = 4096; int x = plane_state->base.src.x1 >> 17; @@ -3095,6 +3137,7 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) struct intel_plane *plane = to_intel_plane(plane_state->base.plane); struct intel_crtc *crtc = to_intel_crtc(plane_state->base.crtc); const struct drm_framebuffer *fb = plane_state->base.fb; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); int src_x = plane_state->base.src.x1 >> 16; int src_y = plane_state->base.src.y1 >> 16; int hsub = fb->format->hsub; @@ -3117,7 +3160,7 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) return -EINVAL; } - if (plane_state->base.rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) { + if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180)) { DRM_DEBUG_KMS("RC support only with 0/180 degree rotation %x\n", plane_state->base.rotation); return -EINVAL; @@ -3136,7 +3179,7 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state) int skl_check_plane_surface(struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); int ret; if (!plane_state->base.visible) @@ -3181,7 +3224,7 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state, to_i915(plane_state->base.plane->dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); u32 dspcntr; dspcntr = DISPLAY_PLANE_ENABLE | DISPPLANE_GAMMA_ENABLE; @@ -3254,7 +3297,8 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) /* HSW/BDW do this automagically in hardware */ if (!IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)) { - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = + intel_plane_get_rotation(&plane_state->base); int src_w = drm_rect_width(&plane_state->base.src) >> 16; int src_h = drm_rect_height(&plane_state->base.src) >> 16; @@ -3508,7 +3552,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev); const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 plane_ctl; @@ -3543,7 +3587,7 @@ static void skylake_update_primary_plane(struct intel_plane *plane, enum plane_id plane_id = plane->id; enum pipe pipe = plane->pipe; u32 plane_ctl = plane_state->ctl; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); u32 stride = skl_plane_stride(fb, 0, rotation); u32 aux_stride = skl_plane_stride(fb, 1, rotation); u32 surf_addr = plane_state->main.offset; @@ -7506,6 +7550,9 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, plane_config->tiling = I915_TILING_X; fb->modifier = I915_FORMAT_MOD_X_TILED; } + + if (val & DISPPLANE_ROTATE_180) + plane_config->rotation = DRM_MODE_ROTATE_180; } pixel_format = val & DISPPLANE_PIXFORMAT_MASK; @@ -8559,6 +8606,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc, goto error; } + if ((val & PLANE_CTL_ROTATE_MASK) == PLANE_CTL_ROTATE_180) + plane_config->rotation = DRM_MODE_ROTATE_180; + base = I915_READ(PLANE_SURF(pipe, 0)) & 0xfffff000; plane_config->base = base; @@ -8644,6 +8694,9 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc, plane_config->tiling = I915_TILING_X; fb->modifier = I915_FORMAT_MOD_X_TILED; } + + if (val & DISPPLANE_ROTATE_180) + plane_config->rotation = DRM_MODE_ROTATE_180; } pixel_format = val & DISPPLANE_PIXFORMAT_MASK; @@ -9349,7 +9402,7 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state) /* ILK+ do this automagically */ if (HAS_GMCH_DISPLAY(dev_priv) && - plane_state->base.rotation & DRM_MODE_ROTATE_180) + intel_plane_get_rotation(&plane_state->base) & DRM_MODE_ROTATE_180) base += (plane_state->base.crtc_h * plane_state->base.crtc_w - 1) * fb->format->cpp[0]; @@ -9571,7 +9624,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state, return 0; } - if (plane_state->base.rotation & DRM_MODE_ROTATE_180) + if (intel_plane_get_rotation(&plane_state->base) & DRM_MODE_ROTATE_180) cntl |= CURSOR_ROTATE_180; return cntl; @@ -9604,7 +9657,7 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state) * cursors. */ if (HAS_CUR_FBC(dev_priv) && - plane_state->base.rotation & DRM_MODE_ROTATE_0) { + intel_plane_get_rotation(&plane_state->base) & DRM_MODE_ROTATE_0) { if (height < 8 || height > width) return false; } else { @@ -12775,7 +12828,8 @@ intel_prepare_plane_fb(struct drm_plane *plane, } else { struct i915_vma *vma; - vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation); + vma = intel_pin_and_fence_fb_obj(fb, + intel_plane_get_rotation(new_state)); if (!IS_ERR(vma)) to_intel_plane_state(new_state)->vma = vma; else @@ -13155,7 +13209,8 @@ intel_legacy_cursor_update(struct drm_plane *plane, goto out_unlock; } } else { - vma = intel_pin_and_fence_fb_obj(fb, new_plane_state->rotation); + vma = intel_pin_and_fence_fb_obj(fb, + intel_plane_get_rotation(new_plane_state)); if (IS_ERR(vma)) { DRM_DEBUG_KMS("failed to pin object\n"); @@ -14625,7 +14680,9 @@ int intel_modeset_init(struct drm_device *dev) drm_modeset_unlock_all(dev); for_each_intel_crtc(dev, crtc) { - struct intel_initial_plane_config plane_config = {}; + struct intel_initial_plane_config plane_config = { + .rotation = DRM_MODE_ROTATE_0 + }; if (!crtc->active) continue; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 17649f13091c..de3314ca8f0a 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -447,6 +447,7 @@ struct intel_initial_plane_config { unsigned int tiling; int size; u32 base; + uint8_t rotation; /* DRM_MODE_ROTATE_* */ }; #define SKL_MIN_SRC_W 8 @@ -802,6 +803,12 @@ struct intel_crtc { unsigned long long enabled_power_domains; struct intel_overlay *overlay; + /* + * Initial DRM_MODE_ROTATE_* as read back from the hardware at init, + * this is used to compensate for e.g. upside-down mounted lcd-panels. + */ + uint8_t initial_rotation; + /* Display surface base address adjustement for pageflips. Note that on * gen4+ this only adjusts up to a tile, offsets within a tile are * handled in the hw itself (with the TILEOFF register). */ @@ -1464,6 +1471,31 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) return i915_ggtt_offset(state->vma); } +static inline unsigned int +intel_plane_get_rotation(const struct drm_plane_state *plane_state) +{ + unsigned int rotation = plane_state->rotation; + unsigned int new_rotation = DRM_MODE_ROTATE_0; + struct intel_crtc *intel_crtc; + + if (!plane_state->crtc) + return rotation; + + /* We only support an initial rotation of DRM_MODE_ROTATE_180 for now */ + intel_crtc = to_intel_crtc(plane_state->crtc); + if (intel_crtc->initial_rotation != DRM_MODE_ROTATE_180) + return rotation; + + switch (rotation & DRM_MODE_ROTATE_MASK) { + case DRM_MODE_ROTATE_0: new_rotation = DRM_MODE_ROTATE_180; break; + case DRM_MODE_ROTATE_90: new_rotation = DRM_MODE_ROTATE_270; break; + case DRM_MODE_ROTATE_180: new_rotation = DRM_MODE_ROTATE_0; break; + case DRM_MODE_ROTATE_270: new_rotation = DRM_MODE_ROTATE_90; break; + } + + return (rotation & ~DRM_MODE_ROTATE_MASK) | new_rotation; +} + u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); u32 skl_plane_stride(const struct drm_framebuffer *fb, int plane, diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c index 3fca9fa39a8e..eb9010061316 100644 --- a/drivers/gpu/drm/i915/intel_fbc.c +++ b/drivers/gpu/drm/i915/intel_fbc.c @@ -737,7 +737,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate; - cache->plane.rotation = plane_state->base.rotation; + cache->plane.rotation = intel_plane_get_rotation(&plane_state->base); /* * Src coordinates are already rotated by 270 degrees for * the 90/270 degree plane rotation cases (to match the diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d5ff0b9f999f..da8d66f00848 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -4080,6 +4080,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, { struct drm_framebuffer *fb = pstate->fb; struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); + unsigned int rotation = intel_plane_get_rotation(pstate); uint32_t src_w, src_h; uint32_t min_scanlines = 8; uint8_t plane_bpp; @@ -4117,7 +4118,7 @@ skl_ddb_min_alloc(const struct drm_plane_state *pstate, else plane_bpp = fb->format->cpp[0]; - if (drm_rotation_90_or_270(pstate->rotation)) { + if (drm_rotation_90_or_270(rotation)) { switch (plane_bpp) { case 1: min_scanlines = 32; @@ -4382,6 +4383,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, struct intel_plane *plane = to_intel_plane(intel_pstate->base.plane); const struct drm_plane_state *pstate = &intel_pstate->base; const struct drm_framebuffer *fb = pstate->fb; + unsigned int rotation = intel_plane_get_rotation(pstate); uint32_t latency = dev_priv->wm.skl_latency[level]; uint_fixed_16_16_t method1, method2; uint_fixed_16_16_t plane_blocks_per_line; @@ -4434,7 +4436,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv, fb->format->cpp[0]; plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate); - if (drm_rotation_90_or_270(pstate->rotation)) { + if (drm_rotation_90_or_270(rotation)) { switch (cpp) { case 1: diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 524933b01483..ad061078fb0e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -237,7 +237,7 @@ skl_update_plane(struct intel_plane *plane, u32 plane_ctl = plane_state->ctl; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 surf_addr = plane_state->main.offset; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); u32 stride = skl_plane_stride(fb, 0, rotation); u32 aux_stride = skl_plane_stride(fb, 1, rotation); int crtc_x = plane_state->base.dst.x1; @@ -367,7 +367,7 @@ static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 sprctl; @@ -507,7 +507,7 @@ static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state, struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev); const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 sprctl; @@ -647,7 +647,7 @@ static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state, struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev); const struct drm_framebuffer *fb = plane_state->base.fb; - unsigned int rotation = plane_state->base.rotation; + unsigned int rotation = intel_plane_get_rotation(&plane_state->base); const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; u32 dvscntr; @@ -780,6 +780,7 @@ intel_check_sprite_plane(struct intel_plane *plane, struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc); struct drm_framebuffer *fb = state->base.fb; + unsigned int rotation = intel_plane_get_rotation(&state->base); int crtc_x, crtc_y; unsigned int crtc_w, crtc_h; uint32_t src_x, src_y, src_w, src_h; @@ -834,8 +835,7 @@ intel_check_sprite_plane(struct intel_plane *plane, * coordinates and sizes. We probably need some way to decide whether * more strict checking should be done instead. */ - drm_rect_rotate(src, fb->width << 16, fb->height << 16, - state->base.rotation); + drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation); hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); BUG_ON(hscale < 0); @@ -876,7 +876,7 @@ intel_check_sprite_plane(struct intel_plane *plane, drm_rect_height(dst) * vscale - drm_rect_height(src)); drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, - state->base.rotation); + rotation); /* sanity check to make sure the src viewport wasn't enlarged */ WARN_ON(src->x1 < (int) state->base.src_x ||