From patchwork Thu Feb 27 22:14:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Roper X-Patchwork-Id: 3736461 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 1EC3ABF13A for ; Thu, 27 Feb 2014 22:14:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2D91920221 for ; Thu, 27 Feb 2014 22:14:55 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 4040D2021C for ; Thu, 27 Feb 2014 22:14:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 62C9DFB970; Thu, 27 Feb 2014 14:14:47 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id B5DB1FB976; Thu, 27 Feb 2014 14:14:37 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 27 Feb 2014 14:14:37 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,557,1389772800"; d="scan'208";a="483170128" Received: from mdroper-hswdev.fm.intel.com (HELO mdroper-hswdev) ([10.1.134.215]) by fmsmga001.fm.intel.com with ESMTP; 27 Feb 2014 14:14:33 -0800 Received: from mattrope by mdroper-hswdev with local (Exim 4.80) (envelope-from ) id 1WJ9El-0001YM-11; Thu, 27 Feb 2014 14:15:27 -0800 From: Matt Roper To: dri-devel@lists.freedesktop.org Date: Thu, 27 Feb 2014 14:14:43 -0800 Message-Id: <1393539283-5901-5-git-send-email-matthew.d.roper@intel.com> X-Mailer: git-send-email 1.8.5.1 In-Reply-To: <1393539283-5901-1-git-send-email-matthew.d.roper@intel.com> References: <1393539283-5901-1-git-send-email-matthew.d.roper@intel.com> Cc: Intel Graphics Development Subject: [Intel-gfx] [PATCH 4/4] drm/i915: Register primary plane for each CRTC X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org X-Spam-Status: No, score=-4.2 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 Create a primary plane at CRTC init and hook up handlers for the various operations that may be performed on it. The DRM core will only advertise the primary planes to clients that set the appropriate capability bit. Since we're limited to the legacy plane operations at the moment (SetPlane and such) this isn't terribly interesting yet; the plane update handler will perform an MMIO flip of the display plane and the disable handler will disable the CRTC. Once we migrate more of the plane and CRTC info over to properties in preparation for atomic/nuclear operations, primary planes will be more useful. Cc: Intel Graphics Development Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/intel_display.c | 92 ++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9757010..d9a5cd5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8260,6 +8260,10 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) intel_crtc_cursor_set(crtc, NULL, 0, 0, 0); + drm_plane_cleanup(crtc->primary_plane); + kfree(crtc->primary_plane); + crtc->primary_plane = NULL; + drm_crtc_cleanup(crtc); kfree(intel_crtc); @@ -10272,17 +10276,105 @@ static void intel_shared_dpll_init(struct drm_device *dev) BUG_ON(dev_priv->num_shared_dpll > I915_NUM_PLLS); } +static int +intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + /* setplane API takes shifted source rectangle values; unshift them */ + src_x >>= 16; + src_y >>= 16; + src_w >>= 16; + src_h >>= 16; + + if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { + DRM_DEBUG_KMS("Unsuitable framebuffer for primary plane\n"); + return -EINVAL; + } + + /* + * Current hardware can't reposition the primary plane or scale it + * (although this could change in the future). This means that we + * don't actually need any of the destination (crtc) rectangle values, + * or the source rectangle width/height; only the source x/y winds up + * getting used for panning. Nevertheless, let's sanity check the + * incoming values to make sure userspace didn't think it could scale + * or reposition this plane. + */ + if (crtc_w != crtc->mode.hdisplay || crtc_h != crtc->mode.vdisplay || + crtc_x != 0 || crtc_y != 0) { + DRM_DEBUG_KMS("Primary plane must cover entire CRTC\n"); + return -EINVAL; + } + if (crtc_w != src_w || crtc_h != src_h) { + DRM_DEBUG_KMS("Can't scale primary plane\n"); + return -EINVAL; + } + + intel_pipe_set_base(crtc, src_x, src_y, fb); + dev_priv->display.crtc_enable(crtc); + + return 0; +} + +static int +intel_primary_plane_disable(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + if (!plane->fb) + return 0; + + if (WARN_ON(!plane->crtc || plane->crtc->primary_plane != plane)) + return -EINVAL; + + dev_priv->display.crtc_disable(plane->crtc); + + return 0; +} + +static void intel_primary_plane_destroy(struct drm_plane *plane) +{ + /* + * Since primary planes are never put on the mode_config plane list, + * this entry point should never be called. Primary plane cleanup + * happens during CRTC destruction. + */ + BUG(); +} + +static const struct drm_plane_funcs intel_primary_plane_funcs = { + .update_plane = intel_primary_plane_setplane, + .disable_plane = intel_primary_plane_disable, + .destroy = intel_primary_plane_destroy, +}; + static void intel_crtc_init(struct drm_device *dev, int pipe) { drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc; + struct drm_plane *primary_plane; int i; intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL); if (intel_crtc == NULL) return; + primary_plane = kzalloc(sizeof(*primary_plane), GFP_KERNEL); + if (primary_plane == NULL) { + kfree(intel_crtc); + return; + } + drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); + drm_plane_set_primary(dev, primary_plane, &intel_crtc->base, + &intel_primary_plane_funcs, NULL, 0); drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); for (i = 0; i < 256; i++) {