From patchwork Sun Apr 20 10:44:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: akash.goel@intel.com X-Patchwork-Id: 4021001 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 779609F319 for ; Sun, 20 Apr 2014 10:41:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 89200201EF for ; Sun, 20 Apr 2014 10:41:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 7A4EA201BA for ; Sun, 20 Apr 2014 10:41:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8CC6F6E137; Sun, 20 Apr 2014 03:41:31 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 0EAB46E137 for ; Sun, 20 Apr 2014 03:41:30 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 20 Apr 2014 03:36:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,891,1389772800"; d="scan'208";a="524233251" Received: from akashgoe-desktop.iind.intel.com ([10.223.82.34]) by orsmga002.jf.intel.com with ESMTP; 20 Apr 2014 03:41:27 -0700 From: akash.goel@intel.com To: intel-gfx@lists.freedesktop.org Date: Sun, 20 Apr 2014 16:14:18 +0530 Message-Id: <1397990658-24812-1-git-send-email-akash.goel@intel.com> X-Mailer: git-send-email 1.9.2 In-Reply-To: <1395805781-21617-1-git-send-email-akash.goel@intel.com> References: <1395805781-21617-1-git-send-email-akash.goel@intel.com> Cc: Akash Goel Subject: [Intel-gfx] [PATCH v4 2/4] drm/i915: New drm crtc property for varying the Pipe Src size X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Akash Goel This patch adds a new drm crtc property for varying the Pipe Src size or the Panel fitter input size. Pipe Src controls the size that is scaled from. This will allow to dynamically flip (without modeset) the frame buffers of different resolutions v2: Added a check to fail the set property call if Panel fitter is disabled & new PIPESRC programming do not match with PIPE timings. Removed the pitch mismatch check on frame buffer, when being flipped. This is currently done only for VLV/HSW. v3: Modified the check, added in v2, to consider the platforms having Split PCH. v4: Refactored based on latest codebase. Used 'UINT_MAX' macro in place of constant. Testcase: igt/kms_panel_fitter_test Signed-off-by: Akash Goel --- drivers/gpu/drm/i915/i915_drv.h | 6 +++ drivers/gpu/drm/i915/intel_display.c | 76 +++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7d6acb4..104a232 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1441,6 +1441,12 @@ struct drm_i915_private { struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; + /* + * Property to dynamically vary the size of the + * PIPESRC or Panel fitter input size + */ + struct drm_property *input_size_property; + uint32_t hw_context_size; struct list_head context_list; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f26be4e..5484ae2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8902,8 +8902,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, * Note that pitch changes could also affect these register. */ if (INTEL_INFO(dev)->gen > 3 && - (fb->offsets[0] != crtc->primary->fb->offsets[0] || - fb->pitches[0] != crtc->primary->fb->pitches[0])) + (fb->offsets[0] != crtc->primary->fb->offsets[0])) + return -EINVAL; + + /* + * Bypassing the fb pitch check for VLV/HSW, as purportedly there + * is a dynamic flip support in VLV/HSW. This will allow to + * flip fbs of different resolutions without doing a modeset. + * TBD, confirm the same for other newer gen platforms also. + */ + if (INTEL_INFO(dev)->gen > 3 && + !IS_VALLEYVIEW(dev) && !IS_HASWELL(dev) && + (fb->pitches[0] != crtc->primary->fb->pitches[0])) return -EINVAL; if (i915_terminally_wedged(&dev_priv->gpu_error)) @@ -10422,11 +10432,71 @@ out_config: return ret; } +static void intel_create_crtc_properties(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + if (!dev_priv->input_size_property) + dev_priv->input_size_property = + drm_property_create_range(dev, 0, "input size", + 0, UINT_MAX); + + if (dev_priv->input_size_property) + drm_object_attach_property(&intel_crtc->base.base, + dev_priv->input_size_property, + 0); +} + static int intel_crtc_set_property(struct drm_crtc *crtc, struct drm_property *property, uint64_t val) { + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int ret = -ENOENT; + if (property == dev_priv->input_size_property) { + int new_width = (int)((val >> 16) & 0xffff); + int new_height = (int)(val & 0xffff); + const struct drm_display_mode *adjusted_mode = + &intel_crtc->config.adjusted_mode; + + if ((new_width == intel_crtc->config.pipe_src_w) && + (new_height == intel_crtc->config.pipe_src_h)) + return 0; + + if (((adjusted_mode->crtc_hdisplay != new_width) || + (adjusted_mode->crtc_vdisplay != new_height)) && + ((HAS_PCH_SPLIT(dev) && + (!intel_crtc->config.pch_pfit.enabled)) || + (!HAS_PCH_SPLIT(dev) && + (!intel_crtc->config.gmch_pfit.control)))) { + DRM_ERROR("PIPESRC mismatch with Pipe timings &" + "PF is disabled\n"); + return -EINVAL; + } + + intel_crtc->config.pipe_src_w = new_width; + intel_crtc->config.pipe_src_h = new_height; + + intel_crtc->config.requested_mode.hdisplay = new_width; + intel_crtc->config.requested_mode.vdisplay = new_height; + + crtc->mode.hdisplay = new_width; + crtc->mode.vdisplay = new_height; + + /* pipesrc controls the size that is scaled from, which should + * always be the user's requested size. + */ + I915_WRITE(PIPESRC(intel_crtc->pipe), + ((intel_crtc->config.pipe_src_w - 1) << 16) | + (intel_crtc->config.pipe_src_h - 1)); + + return 0; + } + return ret; } @@ -10577,6 +10647,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); + + intel_create_crtc_properties(&intel_crtc->base); } enum pipe intel_get_pipe_from_connector(struct intel_connector *connector)