From patchwork Wed Mar 25 23:21:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chandra Konduru X-Patchwork-Id: 6095971 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 519BEBF90F for ; Wed, 25 Mar 2015 23:22:06 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 43ECF20381 for ; Wed, 25 Mar 2015 23:22:05 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 2759420357 for ; Wed, 25 Mar 2015 23:22:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 74B3A6E958; Wed, 25 Mar 2015 16:22:03 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 5D11D6E958 for ; Wed, 25 Mar 2015 16:22:02 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 25 Mar 2015 16:22:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,467,1422950400"; d="scan'208";a="685705518" Received: from cmkondur-desk2.fm.intel.com ([10.19.123.59]) by fmsmga001.fm.intel.com with ESMTP; 25 Mar 2015 16:22:02 -0700 From: Chandra Konduru To: intel-gfx@lists.freedesktop.org Date: Wed, 25 Mar 2015 16:21:26 -0700 Message-Id: <1427325686-29959-1-git-send-email-chandra.konduru@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1426896282-23215-9-git-send-email-chandra.konduru@intel.com> References: <1426896282-23215-9-git-send-email-chandra.konduru@intel.com> Cc: ander.conselvan.de.oliveira@intel.com, daniel.vetter@intel.com Subject: [Intel-gfx] [PATCH 08/21 v3] drm/i915: Add helper function to update scaler_users in crtc_state X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 This helper function stages a scaler request for a plane/crtc into crtc_state->scaler_users (which is a bit field). It also performs required checks before staging any change into scaler_state. v2: -updates to use single copy of scaler limits (Matt) -added force detach parameter for pfit disable purpose (me) v3: -updated function header to kerneldoc format (Matt) -dropped need_scaling checks (Matt) Signed-off-by: Chandra Konduru --- drivers/gpu/drm/i915/intel_display.c | 143 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 3 + 2 files changed, 146 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 29d46fc..5c365f3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12387,6 +12387,149 @@ intel_cleanup_plane_fb(struct drm_plane *plane, } } +/** + * skl_update_scaler_users - Stages update to crtc's scaler state + * @intel_crtc: crtc + * @crtc_state: crtc_state + * @plane: plane (NULL indicates crtc is requesting update) + * @plane_state: plane's state + * @force_detach: request unconditional detachment of scaler + * + * This function updates scaler state for requested plane or crtc. + * To request scaler usage update for a plane, caller shall pass plane pointer. + * To request scaler usage update for crtc, caller shall pass plane pointer + * as NULL. + * + * Return + * 0 - scaler_usage updated successfully + * error - requested scaling cannot be supported or other error condition + */ +int +skl_update_scaler_users( + struct intel_crtc *intel_crtc, struct intel_crtc_state *crtc_state, + struct intel_plane *intel_plane, struct intel_plane_state *plane_state, + int force_detach) +{ + int need_scaling; + int idx; + int src_w, src_h, dst_w, dst_h; + int scaler_id; + struct drm_framebuffer *fb; + struct intel_crtc_scaler_state *scaler_state; + + if (!intel_crtc || !crtc_state || + (intel_plane && intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)) + return 0; + + scaler_state = &crtc_state->scaler_state; + + if (!scaler_state->num_scalers) { + DRM_DEBUG_KMS("crtc_state = %p, num_scalers = %d\n", crtc_state, + scaler_state->num_scalers); + return 0; + } + + idx = intel_plane ? drm_plane_index(&intel_plane->base) : SKL_CRTC_INDEX; + fb = intel_plane ? plane_state->base.fb : NULL; + + if (intel_plane) { + src_w = drm_rect_width(&plane_state->src) >> 16; + src_h = drm_rect_height(&plane_state->src) >> 16; + dst_w = drm_rect_width(&plane_state->dst); + dst_h = drm_rect_height(&plane_state->dst); + scaler_id = plane_state->scaler_id; + } else { + struct drm_display_mode *adjusted_mode = + &crtc_state->base.adjusted_mode; + src_w = crtc_state->pipe_src_w; + src_h = crtc_state->pipe_src_h; + dst_w = adjusted_mode->hdisplay; + dst_h = adjusted_mode->vdisplay; + scaler_id = scaler_state->scaler_id; + } + need_scaling = (src_w != dst_w || src_h != dst_h); + + /* + * if plane is being disabled or scaler is no more required or force detach + * - free scaler binded to this plane/crtc + * - in order to do this, update crtc->scaler_usage + * + * Here scaler state in crtc_state is set free so that + * scaler can be assigned to other user. Actual register + * update to free the scaler is done in plane/panel-fit programming. + * For this purpose crtc/plane_state->scaler_id isn't reset here. + */ + if (force_detach || !need_scaling || (intel_plane && + (!fb || !plane_state->visible))) { + if (scaler_id >= 0) { + scaler_state->scaler_users &= ~(1 << idx); + scaler_state->scalers[scaler_id].in_use = 0; + + DRM_DEBUG_KMS("Staged freeing scaler id %u.%u from %s:%d " + "crtc_state = %p scaler_users = 0x%x\n", + intel_crtc->pipe, scaler_id, intel_plane ? "PLANE" : "CRTC", + intel_plane ? intel_plane->base.base.id : + intel_crtc->base.base.id, crtc_state, + scaler_state->scaler_users); + } + return 0; + } + + /* range checks */ + if (src_w < scaler_state->min_src_w || src_h < scaler_state->min_src_h || + dst_w < scaler_state->min_dst_w || dst_h < scaler_state->min_dst_h || + + src_w > scaler_state->max_src_w || src_h > scaler_state->max_src_h || + dst_w > scaler_state->max_dst_w || dst_h > scaler_state->max_dst_h) { + DRM_DEBUG_KMS("%s:%d scaler_user index %u.%u: src %ux%u dst %ux%u " + "size is out of scaler range\n", + intel_plane ? "PLANE" : "CRTC", + intel_plane ? intel_plane->base.base.id : intel_crtc->base.base.id, + intel_crtc->pipe, idx, src_w, src_h, dst_w, dst_h); + return -EINVAL; + } + + /* check colorkey */ + if (intel_plane && intel_colorkey_enabled(intel_plane)) { + DRM_DEBUG_KMS("PLANE:%d scaling with color key not allowed", + intel_plane->base.base.id); + return -EINVAL; + } + + /* Check src format */ + if (intel_plane) { + switch (fb->pixel_format) { + case DRM_FORMAT_RGB565: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_YUYV: + case DRM_FORMAT_YVYU: + case DRM_FORMAT_UYVY: + case DRM_FORMAT_VYUY: + break; + default: + DRM_DEBUG_KMS("PLANE:%d FB:%d unsupported scaling format 0x%x\n", + intel_plane->base.base.id, fb->base.id, fb->pixel_format); + return -EINVAL; + } + } + + /* mark this plane as a scaler user in crtc_state */ + scaler_state->scaler_users |= (1 << idx); + DRM_DEBUG_KMS("%s:%d staged scaling request for %ux%u->%ux%u " + "crtc_state = %p scaler_users = 0x%x\n", + intel_plane ? "PLANE" : "CRTC", + intel_plane ? intel_plane->base.base.id : intel_crtc->base.base.id, + src_w, src_h, dst_w, dst_h, crtc_state, scaler_state->scaler_users); + return 0; +} + static int intel_check_primary_plane(struct drm_plane *plane, struct intel_plane_state *state) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1da5087..f5d53c9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1138,6 +1138,9 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, struct intel_crtc_state *pipe_config); void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc); void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file); +int skl_update_scaler_users(struct intel_crtc *intel_crtc, + struct intel_crtc_state *crtc_state, struct intel_plane *intel_plane, + struct intel_plane_state *plane_state, int force_detach); /* intel_dp.c */ void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);