From patchwork Mon Oct 23 09:24:59 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: 10022221 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 80430601E8 for ; Mon, 23 Oct 2017 09:25:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 724B228692 for ; Mon, 23 Oct 2017 09:25:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 66FF82881A; Mon, 23 Oct 2017 09:25:16 +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=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C7E4728692 for ; Mon, 23 Oct 2017 09:25:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751291AbdJWJZP (ORCPT ); Mon, 23 Oct 2017 05:25:15 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:56947 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751198AbdJWJZO (ORCPT ); Mon, 23 Oct 2017 05:25:14 -0400 Received: by mail-wr0-f195.google.com with SMTP id r79so16602609wrb.13 for ; Mon, 23 Oct 2017 02:25:14 -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=Lk3Df1okW5Sf/IzEQUT4nj1/+/eQywOPe+FZkJRiJBg=; b=nG2/lEJEf8+qtW4nc+CQcVMQ+vPWyQQCUijyXO3RRUdSVfkiTs7EEmf9jBwGIlaPgh 1KqA1rPXt+QpIIeiV7rcblZIDZBu215eutsWdu62ZK7r9kHFSo4kqQBl6319iedoLpdT t5cUVqirRRRi7/Uzrib9qX2nxcrA/+x4GeXfNjpiC2Il1npyB5Co/bU//NnqPjQakfiP lk9yFZuKT2/liBDm8SEeHbNhYqE/DSMutyjP3Bwa1l2gX0BwT1HYYd0sWy++vJWVhIDD EvdFYo8D45jaXdGruvHKh+4Wa4NziMiRLJutyqKIDofNMnm2if1FNTrGjgIDZoAUnrs8 UWmw== 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=Lk3Df1okW5Sf/IzEQUT4nj1/+/eQywOPe+FZkJRiJBg=; b=RIYVDW250jo9nPKJBhtulNqoXY4IngQUUzUMXk7V2BaIHKBWkCiLfzlUCONCDEXFa+ wqgBOHlflbODtY5w3Ra+nziYkCrmfAkLkKEM7Vuh7/zXI9Q4MHSXep84iMrBq1afl+S1 nR7r9efTb7rVZ5PbjI14l/hhfCfcpdoeq9MXQLLwnUmnB4Q8vTCoDRpdOuINMdwGkgxn kCcZGFIzXvBq2DFaFHFW3j1zRVGn2LMqyG+hoVwnXKUYlR6qNRHzjN5+ofUOONIwJfrD BQA/GgOSxVksqFUqYEUs4OllWxi/4DGPa2mmWkLodVP1sIqHw8hlXJM3Y42HAY9r+lPa yudw== X-Gm-Message-State: AMCzsaUw94GdmzZbzZPFMA071VLTVP7VWSlRWga6kH+QTRdXVVYMHBwb QDKGXyLimfciEBme2pfC9uc= X-Google-Smtp-Source: ABhQp+QIVVSxr7ZG1GYN3sKnJrr0C9acLEsTxY3t1FewLOv7DGmwftxtuXcq16VP5jA51BbDOiIDDw== X-Received: by 10.223.147.39 with SMTP id 36mr10065036wro.175.1508750713520; Mon, 23 Oct 2017 02:25:13 -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 t143sm2870584wmt.45.2017.10.23.02.25.11 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 02:25:12 -0700 (PDT) From: Hans de Goede X-Google-Original-From: Hans de Goede To: Daniel Vetter , Jani Nikula , Sean Paul , David Airlie , Bartlomiej Zolnierkiewicz Cc: Hans de Goede , Bastien Nocera , Daniel Drake , intel-gfx , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org Subject: [PATCH v4 4/7] drm/fb-helper: Apply panel orientation connector prop to the primary plane Date: Mon, 23 Oct 2017 11:24:59 +0200 Message-Id: <20171023092502.1095-5-hdegoede@redhat.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171023092502.1095-1-hdegoede@redhat.com> References: <20171023092502.1095-1-hdegoede@redhat.com> Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Apply the "panel orientation" drm connector prop to the primary plane so that fbcon and fbdev using userspace programs display the right way up. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=94894 Signed-off-by: Hans de Goede --- Changes in v2: -New patch in v2 of this patch-set Changes in v3: -Use a rotation member in struct drm_fb_helper_crtc and set that from drm_setup_crtcs instead of looping over all crtc's to find the right one later -Since we now no longer look at rotation quirks directly in the fbcon code, set fb_info.fbcon_rotate_hint when the panel is not mounted upright and we cannot use hardware rotation Changes in v4: -Make drm_fb_helper_init() init drm_fb_helper_crtc.rotation to DRM_MODE_ROTATE_0 for all crtcs, so that we do not end up setting the plane_state's rotation to an invalid value for disabled crtcs (caught by Fi.CI) --- drivers/gpu/drm/drm_fb_helper.c | 77 +++++++++++++++++++++++++++++++++++++++-- include/drm/drm_fb_helper.h | 8 +++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 116d1f1337c7..b5d075fbd3a5 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -41,6 +41,7 @@ #include #include +#include "drm_crtc_internal.h" #include "drm_crtc_helper_internal.h" static bool drm_fbdev_emulation = true; @@ -350,6 +351,7 @@ EXPORT_SYMBOL(drm_fb_helper_debug_leave); static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active) { struct drm_device *dev = fb_helper->dev; + struct drm_plane_state *plane_state; struct drm_plane *plane; struct drm_atomic_state *state; int i, ret; @@ -368,8 +370,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ retry: plane_mask = 0; drm_for_each_plane(plane, dev) { - struct drm_plane_state *plane_state; - plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { ret = PTR_ERR(plane_state); @@ -392,6 +392,11 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; + struct drm_plane *primary = mode_set->crtc->primary; + + /* Cannot fail as we've already gotten the plane state above */ + plane_state = drm_atomic_get_new_plane_state(state, primary); + plane_state->rotation = fb_helper->crtc_info[i].rotation; ret = __drm_atomic_helper_set_config(mode_set, state); if (ret != 0) @@ -821,6 +826,7 @@ int drm_fb_helper_init(struct drm_device *dev, if (!fb_helper->crtc_info[i].mode_set.connectors) goto out_free; fb_helper->crtc_info[i].mode_set.num_connectors = 0; + fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0; } i = 0; @@ -2334,6 +2340,57 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, return best_score; } +/* + * This function checks if rotation is necessary because of panel orientation + * and if it is, if it is supported. + * If rotation is necessary and supported, its gets set in fb_crtc.rotation. + * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets + * or-ed into fb_helper->rotations. In drm_setup_crtcs_fb() we check if only + * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do + * the unsupported rotation. + */ +static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_crtc *fb_crtc, + struct drm_connector *connector) +{ + struct drm_plane *plane = fb_crtc->mode_set.crtc->primary; + uint64_t valid_mask = 0; + int i, rotation; + + fb_crtc->rotation = DRM_MODE_ROTATE_0; + + switch (connector->display_info.panel_orientation) { + case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP: + rotation = DRM_MODE_ROTATE_180; + break; + case DRM_MODE_PANEL_ORIENTATION_LEFT_UP: + rotation = DRM_MODE_ROTATE_90; + break; + case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP: + rotation = DRM_MODE_ROTATE_270; + break; + default: + rotation = DRM_MODE_ROTATE_0; + } + + if (rotation == DRM_MODE_ROTATE_0 || !plane->rotation_property) { + fb_helper->rotations |= rotation; + return; + } + + for (i = 0; i < plane->rotation_property->num_values; i++) + valid_mask |= (1ULL << plane->rotation_property->values[i]); + + if (!(rotation & valid_mask)) { + fb_helper->rotations |= rotation; + return; + } + + fb_crtc->rotation = rotation; + /* Rotating in hardware, fbcon should not rotate */ + fb_helper->rotations |= DRM_MODE_ROTATE_0; +} + static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, u32 width, u32 height) { @@ -2393,6 +2450,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, drm_fb_helper_modeset_release(fb_helper, &fb_helper->crtc_info[i].mode_set); + fb_helper->rotations = 0; drm_fb_helper_for_each_connector(fb_helper, i) { struct drm_display_mode *mode = modes[i]; struct drm_fb_helper_crtc *fb_crtc = crtcs[i]; @@ -2412,6 +2470,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, modeset->mode = drm_mode_duplicate(dev, fb_crtc->desired_mode); drm_connector_get(connector); + drm_setup_crtc_rotation(fb_helper, fb_crtc, connector); modeset->connectors[modeset->num_connectors++] = connector; modeset->x = offset->x; modeset->y = offset->y; @@ -2453,6 +2512,20 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) } } mutex_unlock(&fb_helper->dev->mode_config.mutex); + + switch (fb_helper->rotations) { + case DRM_MODE_ROTATE_90: + info->fbcon_rotate_hint = FB_ROTATE_CCW; + break; + case DRM_MODE_ROTATE_180: + info->fbcon_rotate_hint = FB_ROTATE_UD; + break; + case DRM_MODE_ROTATE_270: + info->fbcon_rotate_hint = FB_ROTATE_CW; + break; + default: + info->fbcon_rotate_hint = FB_ROTATE_UR; + } } /* Note: Drops fb_helper->lock before returning. */ diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 33fe95927742..4ee834a077a2 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -48,6 +48,7 @@ struct drm_fb_helper_crtc { struct drm_mode_set mode_set; struct drm_display_mode *desired_mode; int x, y; + int rotation; }; /** @@ -158,6 +159,13 @@ struct drm_fb_helper { struct drm_fb_helper_crtc *crtc_info; int connector_count; int connector_info_alloc_count; + /** + * @rotations: + * Bitmask of all rotations requested for panel-orientation which + * could not be handled in hardware. If only one bit is set + * fbdev->fbcon_rotate_hint gets set to the requested rotation. + */ + int rotations; /** * @connector_info: *