From patchwork Thu Aug 14 09:24:27 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: 4723271 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 795AF9F375 for ; Thu, 14 Aug 2014 09:20:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7FF2320148 for ; Thu, 14 Aug 2014 09:20:52 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 732592010E for ; Thu, 14 Aug 2014 09:20:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BEAA56E643; Thu, 14 Aug 2014 02:20:50 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTP id 620796E643 for ; Thu, 14 Aug 2014 02:20:49 -0700 (PDT) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP; 14 Aug 2014 02:12:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="372277651" Received: from akashgoe-desktop.iind.intel.com ([10.223.82.144]) by FMSMGA003.fm.intel.com with ESMTP; 14 Aug 2014 02:16:57 -0700 From: akash.goel@intel.com To: intel-gfx@lists.freedesktop.org Date: Thu, 14 Aug 2014 14:54:27 +0530 Message-Id: <1408008267-11443-7-git-send-email-akash.goel@intel.com> X-Mailer: git-send-email 1.9.2 In-Reply-To: <1408008267-11443-1-git-send-email-akash.goel@intel.com> References: <1408008267-11443-1-git-send-email-akash.goel@intel.com> Cc: shobhit.kumar@intel.com, Akash Goel Subject: [Intel-gfx] [PATCH 6/6] drm/i915: New drm crtc property for varying the Crtc 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.9 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 the frame buffers of different resolutions. For this Driver internally enables the Panel fitter or Hw scaler if its a Fixed mode panel & new Pipe Src values differ from the Pipe timings Signed-off-by: Akash Goel Signed-off-by: Pallavi G --- drivers/gpu/drm/drm_crtc.c | 7 ++++ drivers/gpu/drm/drm_fb_helper.c | 7 ++++ drivers/gpu/drm/i915/intel_display.c | 72 ++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 7 ++++ 4 files changed, 93 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index f09b752..328efac 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -5169,3 +5169,10 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, supported_rotations); } EXPORT_SYMBOL(drm_mode_create_rotation_property); + +struct drm_property *drm_mode_create_crtc_size_property(struct drm_device *dev) +{ + return drm_property_create_range(dev, 0, "crtc size", + 0, UINT_MAX); +} +EXPORT_SYMBOL(drm_mode_create_crtc_size_property); diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 63d7b8e..6eb1949 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -307,6 +307,13 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper) struct drm_crtc *crtc = mode_set->crtc; int ret; + if (dev->mode_config.crtc_size_property) { + crtc->crtc_w = crtc->crtc_h = 0; + drm_object_property_set_value(&crtc->base, + dev->mode_config.crtc_size_property, + 0); + } + if (crtc->funcs->cursor_set) { ret = crtc->funcs->cursor_set(crtc, NULL, 0, 0, 0); if (ret) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a75d1a0..7c417fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10183,6 +10183,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, pipe_config->pipe_src_w = pipe_config->requested_mode.crtc_hdisplay; pipe_config->pipe_src_h = pipe_config->requested_mode.crtc_vdisplay; + /* Set the Pipe Src values as per the crtc size property values */ + if (crtc->crtc_w && crtc->crtc_h) { + pipe_config->pipe_src_w = crtc->crtc_w; + pipe_config->pipe_src_h = crtc->crtc_h; + } + encoder_retry: /* Ensure the port clock defaults are reset when retrying. */ pipe_config->port_clock = 0; @@ -11438,11 +11444,67 @@ out_config: return ret; } +static int intel_crtc_set_property(struct drm_crtc *crtc, + struct drm_property *prop, + uint64_t val) +{ + struct drm_device *dev = crtc->dev; + int ret = -ENOENT; + + if (prop == dev->mode_config.crtc_size_property) { + int old_width, old_height; + int new_width = (int)((val >> 16) & 0xffff); + int new_height = (int)(val & 0xffff); + const struct drm_framebuffer *fb = crtc->primary->fb; + + if ((new_width == crtc->crtc_w) && + (new_height == crtc->crtc_h)) + return 0; + + /* Check if property is resetted, so just return */ + if ((new_width == 0) && (new_height) == 0) { + crtc->crtc_w = crtc->crtc_h = 0; + /* FIXME, Is modeset required here ?. Actually the + current FB may not be compatible with the mode */ + return 0; + } else if ((new_width == 0) || (new_height == 0)) + return -EINVAL; + + /* Check if the current FB is compatible with new requested + Pipesrc values by the User */ + if (new_width > fb->width || + new_height > fb->height || + crtc->x > fb->width - new_width || + crtc->y > fb->height - new_height) { + DRM_DEBUG_KMS("New Pipe Src values %dx%d is incompatible with current fb size & viewport %ux%u+%d+%d\n", + new_width, new_height, fb->width, fb->height, crtc->x, crtc->y); + return -EINVAL; + } + + old_width = crtc->crtc_w; + old_height = crtc->crtc_h; + + crtc->crtc_w = new_width; + crtc->crtc_h = new_height; + + /* Currently do a modeset always, this will also + * enable & configure the Panel fitter accordingly */ + ret = intel_crtc_restore_mode(crtc); + if (ret) { + crtc->crtc_w = old_width; + crtc->crtc_h = old_height; + } + } + + return ret; +} + static const struct drm_crtc_funcs intel_crtc_funcs = { .gamma_set = intel_crtc_gamma_set, .set_config = intel_crtc_set_config, .destroy = intel_crtc_destroy, .page_flip = intel_crtc_page_flip, + .set_property = intel_crtc_set_property, }; static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, @@ -11963,6 +12025,16 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe); + + if (!dev->mode_config.crtc_size_property) + dev->mode_config.crtc_size_property = + drm_mode_create_crtc_size_property(dev); + + if (dev->mode_config.crtc_size_property) + drm_object_attach_property(&intel_crtc->base.base, + dev->mode_config.crtc_size_property, + 0); + return; fail: diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 0375d75..b409003 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -354,6 +354,11 @@ struct drm_crtc { bool invert_dimensions; int x, y; + + /* Gets set only through the crtc_size property */ + int crtc_w; + int crtc_h; + const struct drm_crtc_funcs *funcs; /* CRTC gamma size for reporting to userspace */ @@ -826,6 +831,7 @@ struct drm_mode_config { struct drm_property *path_property; struct drm_property *plane_type_property; struct drm_property *rotation_property; + struct drm_property *crtc_size_property; /* DVI-I properties */ struct drm_property *dvi_i_subconnector_property; @@ -1137,6 +1143,7 @@ extern int drm_format_vert_chroma_subsampling(uint32_t format); extern const char *drm_get_format_name(uint32_t format); extern struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, unsigned int supported_rotations); +extern struct drm_property *drm_mode_create_crtc_size_property(struct drm_device *dev); extern unsigned int drm_rotation_simplify(unsigned int rotation, unsigned int supported_rotations);