From patchwork Fri Mar 7 09:08:40 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: 3788701 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 1A7E39F1CD for ; Fri, 7 Mar 2014 09:09:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E52C620274 for ; Fri, 7 Mar 2014 09:09:41 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 9F8172026F for ; Fri, 7 Mar 2014 09:09:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F024EFABC9; Fri, 7 Mar 2014 01:09:37 -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 2358FFABC9 for ; Fri, 7 Mar 2014 01:09:35 -0800 (PST) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP; 07 Mar 2014 01:09:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,606,1389772800"; d="scan'208";a="495728599" Received: from fmsmsx103.amr.corp.intel.com ([10.19.9.34]) by orsmga002.jf.intel.com with ESMTP; 07 Mar 2014 01:09:34 -0800 Received: from fmsmsx114.amr.corp.intel.com (10.18.116.8) by FMSMSX103.amr.corp.intel.com (10.19.9.34) with Microsoft SMTP Server (TLS) id 14.3.123.3; Fri, 7 Mar 2014 01:09:34 -0800 Received: from bgsmsx151.gar.corp.intel.com (10.224.48.42) by FMSMSX114.amr.corp.intel.com (10.18.116.8) with Microsoft SMTP Server (TLS) id 14.3.123.3; Fri, 7 Mar 2014 01:09:34 -0800 Received: from bgsmsx103.gar.corp.intel.com ([169.254.4.75]) by BGSMSX151.gar.corp.intel.com ([169.254.3.159]) with mapi id 14.03.0123.003; Fri, 7 Mar 2014 14:38:41 +0530 From: "Goel, Akash" To: =?iso-8859-1?Q?Ville_Syrj=E4l=E4_=28ville=2Esyrjala=40linux=2Eintel=2Ecom?= =?iso-8859-1?Q?=29?= Thread-Topic: Request for feedback : [RFC] Added a new 'window size' property for connector Thread-Index: Ac855Ly7IdQzY3GoRyK3JSCkqeyRig== Date: Fri, 7 Mar 2014 09:08:40 +0000 Message-ID: <8BF5CF93467D8C498F250C96583BC09CC7C1D8@BGSMSX103.gar.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.223.10.10] MIME-Version: 1.0 Cc: "intel-gfx@lists.freedesktop.org" Subject: [Intel-gfx] Request for feedback : [RFC] Added a new 'window size' property for connector 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: , 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, 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 Hi Ville, Please review this patch. This is just a provisional patch. Here we have tried to extend the 'scaling mode' property by adding a new 'manual' mode and User will have to specify the display window (Panel fitter's output) through another property. But this may not be enough. To support the arbitrary use of Panel fitter, as per your & Chris's suggestions, we can use the following 2 approaches. 1. Introduce a new property (of blob type) through which a structure would be passed, which will have the Panel fitter input (PIPESRC) & output info. Using this Driver can then do a modeset internally. 'fb_id' info will also be required to passed here, conforming to the PIPESRC. Or 2. Add the border info to the display mode structure which will control the Panel fitter output. The panel fitter input (i.e. PIPESRC) will be provided through the regular 'hdisplay', 'vdisplay' fields. This way the PIPESRC programing & Panel fitter mode update could be done in a single modeset call. In both the cases, we can have an additional check that if only the Panel fitter input (fb size) is getting changed & Panel fitter reprogramming is not required, then a full modeset can be avoided except the PIPESRC programming. This could allow to dynamically flip the frame buffers of different resolution without a modeset. Best regards Akash -----Original Message----- From: Goel, Akash Sent: Tuesday, March 04, 2014 3:42 PM To: intel-gfx@lists.freedesktop.org Cc: Goel, Akash; G, Pallavi Subject: [RFC] drm/i915 : Added a new 'window size' property for connector From: Akash Goel Added a new 'window size' property for connectors. This can be used to control the output window size of Panel fitter. Also addd a new mode 'Manual' to existing 'scaling mode' property. Signed-off-by: G Pallavi Signed-off-by: Akash Goel --- drivers/gpu/drm/drm_crtc.c | 1 + drivers/gpu/drm/i915/intel_dp.c | 58 ++++++++++++++++++--- drivers/gpu/drm/i915/intel_drv.h | 8 +++ drivers/gpu/drm/i915/intel_panel.c | 104 +++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 3 ++ include/uapi/drm/drm_mode.h | 1 + 6 files changed, 167 insertions(+), 8 deletions(-) -- 1.8.5.2 diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 35ea15d..1d237b5 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -123,6 +123,7 @@ static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = { DRM_MODE_SCALE_FULLSCREEN, "Full" }, { DRM_MODE_SCALE_CENTER, "Center" }, { DRM_MODE_SCALE_ASPECT, "Full aspect" }, + { DRM_MODE_SCALE_MANUAL, "Manual" }, }; /* diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index c512d78..c697b7a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -886,12 +886,22 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { intel_fixed_panel_mode(intel_connector->panel.fixed_mode, adjusted_mode); - if (!HAS_PCH_SPLIT(dev)) - intel_gmch_panel_fitting(intel_crtc, pipe_config, - intel_connector->panel.fitting_mode); - else - intel_pch_panel_fitting(intel_crtc, pipe_config, - intel_connector->panel.fitting_mode); + if (!HAS_PCH_SPLIT(dev)) { + if (intel_connector->panel.fitting_mode == DRM_MODE_SCALE_MANUAL) + intel_gmch_manual_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.display_window_size); + else + intel_gmch_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.fitting_mode); + } + else { + if (intel_connector->panel.fitting_mode == DRM_MODE_SCALE_MANUAL) + intel_pch_manual_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.display_window_size); + else + intel_pch_panel_fitting(intel_crtc, pipe_config, + intel_connector->panel.fitting_mode); + } } if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK) @@ -3376,14 +3386,36 @@ intel_dp_set_property(struct drm_connector *connector, } if (intel_connector->panel.fitting_mode == val) { - /* the eDP scaling property is not changed */ - return 0; + /* Check if display window size has changed */ + if ((val == DRM_MODE_SCALE_MANUAL) && + intel_connector->panel.display_window_size_changed) + intel_connector->panel.display_window_size_changed = 0; + else { + /* the eDP scaling property is not changed */ + return 0; + } } intel_connector->panel.fitting_mode = val; + if (val != DRM_MODE_SCALE_MANUAL) + intel_connector->panel.display_window_size = 0; + goto done; } + if (is_edp(intel_dp) && + property == connector->dev->mode_config.window_size_property) { + if (intel_connector->panel.display_window_size == val) { + /* the eDP panel window size property is not changed */ + intel_connector->panel.display_window_size_changed = 0; + return 0; + } + intel_connector->panel.display_window_size = val; + intel_connector->panel.display_window_size_changed = 1; + + return 0; + } + return -EINVAL; done: @@ -3517,6 +3549,16 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect connector->dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_ASPECT); intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT; + + connector->dev->mode_config.window_size_property = + drm_property_create_range(connector->dev, 0, + "window size", 0, 0xFFFFFFFF); + drm_object_attach_property( + &connector->base, + connector->dev->mode_config.window_size_property, + 0); + intel_connector->panel.display_window_size = 0; + intel_connector->panel.display_window_size_changed = 0; } } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a4ffc02..5247b6b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -157,6 +157,8 @@ struct intel_panel { struct drm_display_mode *fixed_mode; struct drm_display_mode *downclock_mode; int fitting_mode; + u32 display_window_size; + bool display_window_size_changed; /* backlight */ struct { @@ -841,9 +843,15 @@ void intel_fixed_panel_mode(const struct drm_display_mode *fixed_mode, void intel_pch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); +void intel_pch_manual_panel_fitting(struct intel_crtc *intel_crtc, + struct intel_crtc_config *pipe_config, + u32 display_window_size); void intel_gmch_panel_fitting(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config, int fitting_mode); +void intel_gmch_manual_panel_fitting(struct intel_crtc *crtc, + struct intel_crtc_config *pipe_config, + u32 display_window_size); void intel_panel_set_backlight(struct intel_connector *connector, u32 level, u32 max); int intel_panel_setup_backlight(struct drm_connector *connector); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index cb05840..2965975 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -114,6 +114,48 @@ done: pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0; } +void +intel_pch_manual_panel_fitting(struct intel_crtc *intel_crtc, + struct intel_crtc_config *pipe_config, + u32 display_window_size) +{ + struct drm_display_mode *adjusted_mode; + int x, y; + u32 tot_width, tot_height; + u32 dst_width, dst_height; + + adjusted_mode = &pipe_config->adjusted_mode; + + tot_width = adjusted_mode->crtc_hdisplay; + tot_height = adjusted_mode->crtc_vdisplay; + + dst_width = ((display_window_size >> 16) & 0xffff); + dst_height = (display_window_size & 0xffff); + + x = y = 0; + + if (tot_width < dst_width) { + DRM_ERROR("width is too big\n"); + return; + } else if (dst_width & 1) { + DRM_ERROR("width must be even\n"); + return; + } else if (tot_height < dst_height) { + DRM_ERROR("height is too big\n"); + return; + } else if (dst_height & 1) { + DRM_ERROR("height must be even\n"); + return; + } + + x = (adjusted_mode->hdisplay - dst_width + 1)/2; + y = (adjusted_mode->vdisplay - dst_height + 1)/2; + + pipe_config->pch_pfit.pos = (x << 16) | y; + pipe_config->pch_pfit.size = (dst_width << 16) | dst_height; + pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0; } + static void centre_horizontally(struct drm_display_mode *mode, int width) @@ -323,6 +365,68 @@ out: pipe_config->gmch_pfit.lvds_border_bits = border; } +void intel_gmch_manual_panel_fitting(struct intel_crtc *intel_crtc, + struct intel_crtc_config *pipe_config, + u32 display_window_size) +{ + u32 pfit_control = 0, border = 0; + u32 pf_horizontal_ratio, pf_vertical_ratio; + struct drm_display_mode *adjusted_mode; + u32 tot_width, tot_height; + u32 src_width, src_height; /* pipesrc.x, pipesrc.y */ + u32 dst_width, dst_height; + + adjusted_mode = &pipe_config->adjusted_mode; + + src_width = pipe_config->pipe_src_w; + src_height = pipe_config->pipe_src_h; + + tot_width = adjusted_mode->crtc_hdisplay; + tot_height = adjusted_mode->crtc_vdisplay; + + dst_width = ((display_window_size >> 16) & 0xffff); + dst_height = (display_window_size & 0xffff); + + pf_horizontal_ratio = panel_fitter_scaling(src_width, dst_width); + pf_vertical_ratio = panel_fitter_scaling(src_height, dst_height); + +/* Max Downscale ratio of 1.125, expressed in 1.12 fixed point format +*/ #define MAX_DOWNSCALE_RATIO (0x9 << 9) + + if (pf_horizontal_ratio > MAX_DOWNSCALE_RATIO) { + DRM_ERROR("width is too small\n"); + return; + } else if (tot_width < dst_width) { + DRM_ERROR("width is too big\n"); + return; + } else if (dst_width & 1) { + DRM_ERROR("width must be even\n"); + return; + } else if (pf_vertical_ratio > MAX_DOWNSCALE_RATIO) { + DRM_ERROR("height is too small\n"); + return; + } else if (tot_height < dst_height) { + DRM_ERROR("height is too big\n"); + return; + } else if (dst_height & 1) { + DRM_ERROR("height must be even\n"); + return; + } + + centre_horizontally(adjusted_mode, dst_width); + centre_vertically(adjusted_mode, dst_height); + border = LVDS_BORDER_ENABLE; + + /* PFIT_SCALING_PROGRAMMED is de-featured on BYT */ + pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; + pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | +PFIT_FILTER_FUZZY); + + pipe_config->gmch_pfit.control = pfit_control; + pipe_config->gmch_pfit.lvds_border_bits = border; + + return; +} + static u32 intel_panel_compute_brightness(struct intel_connector *connector, u32 val) { diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f764654..625d7fd 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -902,6 +902,9 @@ struct drm_mode_config { struct drm_property *scaling_mode_property; struct drm_property *dirty_info_property; + /* Panel fitter output property */ + struct drm_property *window_size_property; + /* dumb ioctl parameters */ uint32_t preferred_depth, prefer_shadow; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index f104c26..a187dac 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -87,6 +87,7 @@ #define DRM_MODE_SCALE_FULLSCREEN 1 /* Full screen, ignore aspect */ #define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */ #define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */ +#define DRM_MODE_SCALE_MANUAL 4 /* User can control display window size */ /* Dithering mode options */ #define DRM_MODE_DITHERING_OFF 0