From patchwork Mon Oct 23 07:14:23 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: 10022057 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 F2749601E8 for ; Mon, 23 Oct 2017 07:14:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E416C204FD for ; Mon, 23 Oct 2017 07:14:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D8FEC20602; Mon, 23 Oct 2017 07:14:41 +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.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, 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 48C9B204FD for ; Mon, 23 Oct 2017 07:14:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751146AbdJWHOk (ORCPT ); Mon, 23 Oct 2017 03:14:40 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:45831 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750803AbdJWHOk (ORCPT ); Mon, 23 Oct 2017 03:14:40 -0400 Received: by mail-wr0-f193.google.com with SMTP id y9so4030093wrb.2 for ; Mon, 23 Oct 2017 00:14:39 -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=HHk9PsN+Cdzdv1D/yACKq4k2gfEp2OeIyhBQPUYHkoI=; b=QpmwShS4nZZ0Ww+z83xropMkILcIkjYvRIcfCgoylb32nb4GlO3HXJiXcNPDachaEs +ZLqrRx0WIgs4H7SOPLOkcABnCDCBubZwdQdowXaASWxRbQqcWQzmSujVHwLq+lRsZfd uCtBbKFbzZdldwdfCzL0WUsgu5LBuAx5nk4kyAuMeNBu+QqJnA06R3rK0S/gX9cKBVds 3x9R0QZ4PLdyJNLFl/g6nmDlMYG3KBk0IYC08gntozpk3z/ib4fswiVfmjWA9oQpHsHB eTSAl1FNmqJMxKg179tTjP0uLbI3FyOYytjIzDicQbEZvPj///MFAZJS+Q4dX8if/2/S 1mcg== 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=HHk9PsN+Cdzdv1D/yACKq4k2gfEp2OeIyhBQPUYHkoI=; b=qKxkMSKVAeieTUO1+gGSxmBQl7ctITkjRJoc1QF4AxZbCG67478EuyywgS+VnFWcSN UEykgQN0zgOKTXIfhkjTtEDlBAzzAZBh3B9Ct1m9Qj6L0P4hfrg53dTTsUcG+xPiPiLQ V7j9yzMjfPpo+Aw0bcTNoIcDk4a7rT7iHI1QW1yUCTqIfo/6SOfimr0aauzWajlfo/qd nSmEdAaEk/FZvMmYOdTyqSwtEctJejacW9us4DhRBTTqXABy8ljX3SWMarjoQOK4kd6o UGLFGUwgdhaeH+ljxDFuj5c1lXOzRoydGLL62wszj8iz7FB6SDpvxZ9H+OsxJT1LRn5b uaeQ== X-Gm-Message-State: AMCzsaXo5Q6GSvd2bhwFd+qOp8Ksd5uyVlmZWetCFNYwvDVsrAzQ8OB/ NTIYBYtIBGZ3SyXz3R/HxXg= X-Google-Smtp-Source: ABhQp+Q+u8laJYKXRxwATgCYM5PnZDymleWHTMdkzgxIAmtIgTJ9io3I2vgLor1Oc4eytLbWnbgrwA== X-Received: by 10.223.173.165 with SMTP id w34mr10576228wrc.22.1508742878800; Mon, 23 Oct 2017 00:14:38 -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 u52sm10426072wrb.68.2017.10.23.00.14.37 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 23 Oct 2017 00:14:37 -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 v3 5/7] drm/i915: Add "panel orientation" property to the panel connector Date: Mon, 23 Oct 2017 09:14:23 +0200 Message-Id: <20171023071425.5090-6-hdegoede@redhat.com> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171023071425.5090-1-hdegoede@redhat.com> References: <20171023071425.5090-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 Ideally we could use the VBT for this, that would be simple, in intel_dsi_init() check dev_priv->vbt.dsi.config->rotation, set connector->display_info.panel_orientation accordingly and call drm_connector_init_panel_orientation_property(), done. Unfortunately vbt.dsi.config->rotation is always 0 even on tablets with an upside down LCD and where the GOP is properly rotating the EFI fb in hardware. So instead we end up reading the rotation from the primary plane. To read the info from the primary plane, we need to know which crtc the panel is hooked up to, so we do this the first time the panel encoder's get_config function get called, as by then the encoder crtc routing has been set up. This commit only implements the panel orientation property for DSI panels on BYT / CHT / BXT hardware, as all known non normal oriented panels are only found on this hardware. Signed-off-by: Hans de Goede --- Changes in v2: -Read back the rotation applied by the GOP from the primary plane instead of relying on dev_priv->vbt.dsi.config->rotation, because it seems that the VBT rotation filed is always 0 even on devices where the GOP does apply a rotation Changes in v3: -Rewrite the code to read back the orientation from the primary plane to contain all of this in intel_dsi.c instead of poking a bunch of holes between all the different layers --- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_dsi.c | 48 ++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_dsi.h | 2 ++ drivers/gpu/drm/i915/intel_panel.c | 16 +++++++++++++ 4 files changed, 67 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a05ab3a1ab27..29fb7a414bbe 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1728,6 +1728,7 @@ void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state); void intel_panel_disable_backlight(const struct drm_connector_state *old_conn_state); void intel_panel_destroy_backlight(struct drm_connector *connector); +void intel_panel_set_orientation(struct intel_panel *panel, int orientation); enum drm_connector_status intel_panel_detect(struct drm_i915_private *dev_priv); extern struct drm_display_mode *intel_find_panel_downclock( struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 66bbedc5fa01..86914d2f9f6a 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1084,13 +1084,16 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, struct drm_display_mode *adjusted_mode_sw; struct intel_crtc *intel_crtc; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_panel *panel = &intel_dsi->attached_connector->panel; unsigned int lane_count = intel_dsi->lane_count; unsigned int bpp, fmt; + int orientation; enum port port; u16 hactive, hfp, hsync, hbp, vfp, vsync, vbp; u16 hfp_sw, hsync_sw, hbp_sw; u16 crtc_htotal_sw, crtc_hsync_start_sw, crtc_hsync_end_sw, crtc_hblank_start_sw, crtc_hblank_end_sw; + u32 val; /* FIXME: hw readout should not depend on SW state */ intel_crtc = to_intel_crtc(encoder->base.crtc); @@ -1234,6 +1237,49 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, if (adjusted_mode->crtc_hblank_end == crtc_hblank_end_sw) adjusted_mode->crtc_hblank_end = adjusted_mode_sw->crtc_hblank_end; + + if (!intel_dsi->got_panel_orientation) { + val = I915_READ(PLANE_CTL(intel_crtc->pipe, 0)); + /* The rotation is used to correct for the panel orientation */ + switch (val & PLANE_CTL_ROTATE_MASK) { + case PLANE_CTL_ROTATE_0: + orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; + break; + case PLANE_CTL_ROTATE_90: + orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; + break; + case PLANE_CTL_ROTATE_180: + orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; + break; + case PLANE_CTL_ROTATE_270: + orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP; + break; + } + intel_panel_set_orientation(panel, orientation); + intel_dsi->got_panel_orientation = true; + } +} + +static void vlv_dsi_get_pipe_config(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); + struct intel_panel *panel = &intel_dsi->attached_connector->panel; + int orientation; + u32 val; + + if (!intel_dsi->got_panel_orientation) { + val = I915_READ(DSPCNTR(intel_crtc->plane)); + + if (val & DISPPLANE_ROTATE_180) + orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; + else + orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; + + intel_panel_set_orientation(panel, orientation); + intel_dsi->got_panel_orientation = true; + } } static void intel_dsi_get_config(struct intel_encoder *encoder, @@ -1245,6 +1291,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, if (IS_GEN9_LP(dev_priv)) bxt_dsi_get_pipe_config(encoder, pipe_config); + else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + vlv_dsi_get_pipe_config(encoder); pclk = intel_dsi_get_pclk(encoder, pipe_config->pipe_bpp, pipe_config); diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index 7afeb9580f41..92c2fe31f3fd 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -52,6 +52,8 @@ struct intel_dsi { /* if true, use HS mode, otherwise LP */ bool hs; + bool got_panel_orientation; + /* virtual channel */ int channel; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 37e6211c1f25..536e40a892cb 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1845,6 +1845,22 @@ void intel_panel_destroy_backlight(struct drm_connector *connector) panel->backlight.present = false; } +void intel_panel_set_orientation(struct intel_panel *panel, int orientation) +{ + struct intel_connector *panel_conn; + int width = 0, height = 0; + + if (panel->fixed_mode) { + width = panel->fixed_mode->hdisplay; + height = panel->fixed_mode->vdisplay; + } + + panel_conn = container_of(panel, struct intel_connector, panel); + panel_conn->base.display_info.panel_orientation = orientation; + drm_connector_init_panel_orientation_property(&panel_conn->base, + width, height); +} + /* Set up chip specific backlight functions */ static void intel_panel_init_backlight_funcs(struct intel_panel *panel)