From patchwork Tue Apr 8 21:43:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 14043721 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2D246C369A1 for ; Tue, 8 Apr 2025 21:44:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B2EC910E770; Tue, 8 Apr 2025 21:44:19 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="XR2WdJPR"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1594B10E76F; Tue, 8 Apr 2025 21:44:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1744148658; x=1775684658; h=from:to:subject:date:message-id:in-reply-to:references: content-transfer-encoding:mime-version; bh=BDl9p7KHp4pIvi8iAyu/6zPoM4meydAh5bKRzmXElFs=; b=XR2WdJPR4ZSBOoqgULwXqJiZabxSo22icRYU1/YP6zK4pQNfiuQKj7du iqKw5m4W+DWl23E21IY5CFWkaVM30yKjF/kNXHkN8PdPgsbqxlBwjmKID af9SVrmat71VlAxr5A0FVH8kIxZRK5BgOgy+t5RFl8RDedy2e2v/EAXZR hvajQJKHvl16QK0cvSNDyR9W4pQpY31HIKble146EC1xpgeElwoNszWZY uWzTPFd/zeAK7fX95Pu/IekAVDC6VdGXcI5o6l23UlVp808sVKlbozGJ6 gr7kxi6WNPZmzWxc7LwR5KaCWY+aOS3zdwf+NZ3xECSFsGx4mU573AFTb g==; X-CSE-ConnectionGUID: zkzAPRPfRp6k8Avx2K0fxQ== X-CSE-MsgGUID: 5ZAOjxZATZyFf0BYX4N/3w== X-IronPort-AV: E=McAfee;i="6700,10204,11397"; a="44746768" X-IronPort-AV: E=Sophos;i="6.15,199,1739865600"; d="scan'208";a="44746768" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2025 14:44:18 -0700 X-CSE-ConnectionGUID: +HH9OTcAQ/qlmnifggM4kg== X-CSE-MsgGUID: CO24pHdjROOcH1Wig9wZew== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.15,199,1739865600"; d="scan'208";a="128381241" Received: from orsmsx902.amr.corp.intel.com ([10.22.229.24]) by orviesa006.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Apr 2025 14:44:18 -0700 Received: from ORSMSX901.amr.corp.intel.com (10.22.229.23) by ORSMSX902.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.14; Tue, 8 Apr 2025 14:44:17 -0700 Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by ORSMSX901.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.14 via Frontend Transport; Tue, 8 Apr 2025 14:44:17 -0700 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (104.47.58.44) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.44; Tue, 8 Apr 2025 14:44:16 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=MNIdzJcpfHtaOvLPYIT5kLGx2wgWrY7+tP/IRG0CYJX8SYEAG+tp1vx/KWuAf0C2aXQuL81yzFZaf2Oo3DwF/lKvTQvmRZyFS5ADaTxEUkvKUsoPo3FOW/pXDJ4c5DuZj4jTR+uxO4jR865JWLJ6knni9lW5xAJ3ux36TlaKSTwPvRCBe4mkEX6XWughAhnUdZZh395+/daau0IseavezTGO8FS2LXBLWn7pAYLFexf3NZfjbHwbbccgjPz4NMgHR/yk7/0JyMnO1Lsoj2U10CCfQ/RQX+j0AR+gITqFJCGc9gKd+00tdDjyKdcP0ZjkrF8g8t+TF6YDm4RpXVSeaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RMY6D4xCdkT4NiqrrHr5/MIg7rNBLh9TPohueQ40+RA=; b=kOfu6MrV1YHoiq9iF8YYeXGf0qq4WPdaMTR9w0Du4tliOkUWdrz9zvTs6X/J+bSyL9Julcj3/Quw6joz54G3WDeETnqAeDwj+hLPuduWnZIIVhHrRs9sSUsf6t6XQNxzm1n/zV/vSeFBxZksLhKPhPH6zstrBJv0bycHVJdIn9BJyzf229+xh9OxuRhMhPaQ6aFLtZT0zDm6DboZBzXMl2ds+7zIKUnA2yn9mdHM2B2GxoQDXnzPadZvDmMCFXHvAt0HqV6k38+1seVTp9U3+FyZGLDcLjMhKLsZmfW09G0y12yqMilMvnVeJDZPmlSm9DiaNZ56VeyZiFKh38AFGQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from SJ0PR11MB4845.namprd11.prod.outlook.com (2603:10b6:a03:2d1::10) by MW4PR11MB7101.namprd11.prod.outlook.com (2603:10b6:303:219::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8606.27; Tue, 8 Apr 2025 21:44:00 +0000 Received: from SJ0PR11MB4845.namprd11.prod.outlook.com ([fe80::8900:d137:e757:ac9f]) by SJ0PR11MB4845.namprd11.prod.outlook.com ([fe80::8900:d137:e757:ac9f%6]) with mapi id 15.20.8606.033; Tue, 8 Apr 2025 21:44:00 +0000 From: Imre Deak To: , Subject: [PATCH 09/10] drm/i915: Add support for forcing the link bpp on a connector Date: Wed, 9 Apr 2025 00:43:39 +0300 Message-ID: <20250408214342.1953197-10-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20250408214342.1953197-1-imre.deak@intel.com> References: <20250408214342.1953197-1-imre.deak@intel.com> X-ClientProxiedBy: DU2PR04CA0060.eurprd04.prod.outlook.com (2603:10a6:10:234::35) To SJ0PR11MB4845.namprd11.prod.outlook.com (2603:10b6:a03:2d1::10) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR11MB4845:EE_|MW4PR11MB7101:EE_ X-MS-Office365-Filtering-Correlation-Id: e8a072e1-c637-435e-7f02-08dd76e678c7 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|1800799024|376014; X-Microsoft-Antispam-Message-Info: =?utf-8?q?vtxcP2PrPSzNmZtmfHwVt/8IaF6u83T?= =?utf-8?q?21PAGXtpyKf19ysQMEHW4wz2JPf0Hvz02wqWs4SXM+O8c1d1GadjR/C2OuxGx8AgB?= =?utf-8?q?JoYSHXZRvYdi+zdbBGuPqhiPBHR1P+yivaIsuonbfhhIzRNPqG4ddkjbPhP0MEPbZ?= =?utf-8?q?zlo+1mHOyFg2gLbxCRzaHIpW73dxZU4EtsPl8zWXgznCjwZW4cMk8D+k8+5nJ83Fu?= =?utf-8?q?rwhtY+zKi+wRELLkPqLmOq0Sgfkn41cFshkobZUU/DardnzR74ykRzR+ETX1kmv6w?= =?utf-8?q?OKa9LaljPetJrg7sWZnBB76lO8Lp2so5/ZF+qOw9jADzuafnsk+ExFpYQWprf3e9d?= =?utf-8?q?1QUQUV2W4qCvBpDfxKdPK8FhSDixY2HfQ0DqBvM6IRUyX3ftSKdWI+cmqNVv97W6v?= =?utf-8?q?18PECa7d6jMhHb5lOSKjc00V9yI0Pl99NYwko6q/Be8+b6ld2R2oY8rl0iDqSeDrS?= =?utf-8?q?8pAWR6/ptvtnrdi4KvOSP8iVTBf0FlsDTTpoF4B/yWDVgkN9oFsL1pX0vK8DxWi/t?= =?utf-8?q?CLW52WEuZ6eLZcUMd0f/vLa6yKifmIkZUo92euzqcM9TvmXPNVly8wVND6VlRX804?= =?utf-8?q?AfAN9eqa7xeO8FdlIaPdTDHmoukXOp28lYEGtPuq2BCLRPsrtr8Xz6q+UXEeWVSnK?= =?utf-8?q?JJb6b6RpdKGRTtodX05SCOeCoPsfzCj/OSeR3LY78nKKqzBXLLFQYtvg4Rg3vjhRz?= =?utf-8?q?zK0nYPIodcgwwCsNvJfl2QIN+2uhKr3qH+PuPZZtQEUFql/iJLAhlyvgLtjkBidMT?= =?utf-8?q?YEtN5RWGKx0k3Ez5lVmtRJy4JUU+WMoZ16Qa+HVYOrMcqUVpcXYUmk2rkocRRPvDQ?= =?utf-8?q?2vJSTm/L0LRskTvDstLV5kivnl1nypeW6G2aeYyL8Hmox6DOsDZKDA4tdxhR3Ofzg?= =?utf-8?q?fNHpIbC6ikY+aGKOl1/85y8k0MoJWWvnBpvQaOSHDvFByglK77f2cW4svkNeS/j5N?= =?utf-8?q?0pXnWKfU42lCOdJPIWhlJTWstun2DYG3VsVJyVVRzNvPmAB8MatW2gdhJXqYCzTqv?= =?utf-8?q?rq0T5AVdcDJeqvvnhWBcxo/XUz7Ejk5pQM9t/WT1X1LzhurinMPTxgH/RVxJzGUA/?= =?utf-8?q?cvGBK9qR9xWwmI5DAcN/Z8CvsMFdBZlznyhwOC3mXz7i9274sdih+XPscHs9F7zPU?= =?utf-8?q?DHceonQ5droh0U9nxOsjsn12nwEn9NqrYsm57vs1gYljHeQFXyZ0mvjau6sbgHKZk?= =?utf-8?q?qYKBp22TasGBt1gU7COZBAVWwlsAYo2DPTJXMV3E7Nga4z98KAYslpikzuTR603JU?= =?utf-8?q?7pWKiGLIh/K9hj1BS0RmktN4anDjghhwe8QI5d091t0i/lRCfm7htD+nGXRIaETXa?= =?utf-8?q?EOmtGW2pr5AD?= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SJ0PR11MB4845.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(366016)(1800799024)(376014); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?nHqSbiqjBEq5TuiMqInrfE3NTQAa?= =?utf-8?q?hHblK709zpdqEANZUMzJUvxK16ENfySI9szHnHLTiXdl/Zr0vwOIU7bEe1JSwc2lu?= =?utf-8?q?eS3JQpVMk2PkluUAL7nr8pLV+GEBimXBd185RPIgzNP7M7ngAJAUGqrvqad9X+b7e?= =?utf-8?q?dNl9Vyt2zi/rImXBTdRP+kBFKATpS/aPPNpreQvPBtG42LYttXTUEt4T8wzuLAIy1?= =?utf-8?q?5qrWqBL5wY//DsC93fv/xis3rTAO6rjfeW72iOhPxuftofynokGaBVdqJgRkDO3nm?= =?utf-8?q?nyRDaO/XsdIvdvsy9P/91nYZezEoovu6oFJ8AuVapnOqQ/4bLttO3Va7n1JJkX0JL?= =?utf-8?q?i/JsOgyybRK5JXAxi13GxJvDOjxYGRPyPjBCdiXoDh1Wr2Q5WGhT1aPDpGLbcassI?= =?utf-8?q?vkKRYxF2IHzDiJrd1VKNaz9qZY8lUtw232jeJ/i8v/ynfKmXispm802aqeaAH6kik?= =?utf-8?q?8cNK2015sQ1A1BvjqBlkhD1KcOXflL58G4agP0Q4VVy7RjBfwIlvJULhOn2iDgity?= =?utf-8?q?Bvo97fcrT8x4X6TQJ2YptbsV6Yi8jZItTgMcONPV6HrLhgqmAnZ0Q853O1Xcq0YuN?= =?utf-8?q?gMk4kOHHCWw7XkzxUYYRQ6llsF4jEr3O3ZbY26Ey1kZ9DWANHw0kKU9siGU/fajqz?= =?utf-8?q?cDDLH6AoNqwPKfhzlyY6Lv5+hXSMUohykbXTd3avt6QpwLu/WTF30VhcEgbMfVTOS?= =?utf-8?q?qTffBVI09dYbuDhucFqCOBIPFE7cv1Oj4pUp4D/JByhaiwyY/87eTsvX29Ed1oh6V?= =?utf-8?q?cYk5CIPuME33d2U1XjWQXRiLfPeoMCVN7hVsvsh2/3glpxf80TEREehbwOqeb5V5j?= =?utf-8?q?XEaGkSFma/T7NjidXdisKJiZGvxAY0+L2NFsYv0r5xcrctquy/8N7UxDJGlER+hyd?= =?utf-8?q?ZQgM9d9i5DGmQX44ak0vO8cr1nUUw5Ivnd6hbSE28sqRxhb+FE/p4ZssW20ZXlPRB?= =?utf-8?q?v/JsEJJ3DFcUm5d2mzSQoOK+hmdFazclZF+nBKpU1iPgvvLQm6y0urKDSYprrvgKy?= =?utf-8?q?IFlT6jskojGCyO1pLAWE/zFZ5pWtTaSJatYlEPc+XM/hi4xRsI4rTm/iLbEiNjHvy?= =?utf-8?q?C/hMO3exgdhYGtSuGa1SWQeh4cbHLmIMaILFIjLPI+cuq1UP0034N7/+7+sxbxkcj?= =?utf-8?q?WcTeE6Spa02ZPNErEZJWxIDRkGtcySf7lkWOPQNJTnimUqrZuTUxkFkrTtD/O6HNU?= =?utf-8?q?87lsLUI9fG14Vd+GcnjapOvpEqZ1mly3t9d3osMbsBny7Ll92fFI2InrGCJTahU8P?= =?utf-8?q?xTCRm1adoGKqppiXN1QbKmPmvZIXu6IDYdDrVGWD55ZvcxZxvCZdIuS7iS3C56r7F?= =?utf-8?q?OJ1VvNl9UKFFGVUhEDCmYHZNPYUfbL/aNaI3oXsaRj3B9ccVpaI0D+6mWW0oV8dxP?= =?utf-8?q?9lQBG0Cgf/soL/D8367fWh67phD2NvvHrpABRUOTNSd0iTRNUV6mkqzWGHP2AAU7m?= =?utf-8?q?OKgFczis8oGUIeiguKLRrnjPUivgKgrYuqmUT4ACV0/MtP/ze6kdf6rqv12XYSowD?= =?utf-8?q?9N4Sxn7M+ByC?= X-MS-Exchange-CrossTenant-Network-Message-Id: e8a072e1-c637-435e-7f02-08dd76e678c7 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR11MB4845.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Apr 2025 21:43:59.9731 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: zNq36mi3Yd1/lq6rUKEq1E1Yseh0kUyuxjBT1ojquCFHBaD9J0nGmkDNI6kYaHD4DQmx0+LDz3FEWeM8c0fXWQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW4PR11MB7101 X-OriginatorOrg: intel.com X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Add support for forcing the link bpp on a connector via a connector debugfs entry. During reducing link bpps due to a link BW limit, keep bpps close to their forced value. Signed-off-by: Imre Deak --- .../drm/i915/display/intel_display_types.h | 4 + drivers/gpu/drm/i915/display/intel_link_bw.c | 204 +++++++++++++++++- drivers/gpu/drm/i915/display/intel_link_bw.h | 2 + 3 files changed, 203 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 94468a9d2e0d3..6862cb4885b18 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -550,6 +550,10 @@ struct intel_connector { struct intel_dp *dp; } mst; + struct { + int force_bpp_x16; + } link; + /* Work struct to schedule a uevent on link train failure */ struct work_struct modeset_retry_work; diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.c b/drivers/gpu/drm/i915/display/intel_link_bw.c index a10cd39926075..2a05fac53aa78 100644 --- a/drivers/gpu/drm/i915/display/intel_link_bw.c +++ b/drivers/gpu/drm/i915/display/intel_link_bw.c @@ -3,6 +3,9 @@ * Copyright © 2023 Intel Corporation */ +#include +#include + #include #include @@ -10,11 +13,35 @@ #include "intel_crtc.h" #include "intel_display_core.h" #include "intel_display_types.h" +#include "intel_dp.h" #include "intel_dp_mst.h" #include "intel_dp_tunnel.h" #include "intel_fdi.h" #include "intel_link_bw.h" +static int get_forced_link_bpp_x16(struct intel_atomic_state *state, + const struct intel_crtc *crtc) +{ + struct drm_connector_state *conn_state; + struct drm_connector *_connector; + int force_bpp_x16 = INT_MAX; + int i; + + for_each_new_connector_in_state(&state->base, _connector, conn_state, i) { + struct intel_connector *connector = to_intel_connector(_connector); + + if (conn_state->crtc != &crtc->base) + continue; + + if (!connector->link.force_bpp_x16) + continue; + + force_bpp_x16 = min(force_bpp_x16, connector->link.force_bpp_x16); + } + + return force_bpp_x16 < INT_MAX ? force_bpp_x16 : 0; +} + /** * intel_link_bw_init_limits - initialize BW limits * @state: Atomic state @@ -31,9 +58,10 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state, limits->force_fec_pipes = 0; limits->bpp_limit_reached_pipes = 0; for_each_pipe(display, pipe) { + struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); const struct intel_crtc_state *crtc_state = - intel_atomic_get_new_crtc_state(state, - intel_crtc_for_pipe(display, pipe)); + intel_atomic_get_new_crtc_state(state, crtc); + int forced_bpp_x16 = get_forced_link_bpp_x16(state, crtc); if (state->base.duplicated && crtc_state) { limits->max_bpp_x16[pipe] = crtc_state->max_link_bpp_x16; @@ -42,15 +70,19 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state, } else { limits->max_bpp_x16[pipe] = INT_MAX; } + + if (forced_bpp_x16) + limits->max_bpp_x16[pipe] = min(limits->max_bpp_x16[pipe], forced_bpp_x16); } } /** - * intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe + * __intel_link_bw_reduce_bpp - reduce maximum link bpp for a selected pipe * @state: atomic state * @limits: link BW limits * @pipe_mask: mask of pipes to select from * @reason: explanation of why bpp reduction is needed + * @reduce_forced_bpp: allow reducing bpps below their forced link bpp * * Select the pipe from @pipe_mask with the biggest link bpp value and set the * maximum of link bpp in @limits below this value. Modeset the selected pipe, @@ -64,10 +96,11 @@ void intel_link_bw_init_limits(struct intel_atomic_state *state, * - %-ENOSPC if no pipe can further reduce its link bpp * - Other negative error, if modesetting the selected pipe failed */ -int intel_link_bw_reduce_bpp(struct intel_atomic_state *state, - struct intel_link_bw_limits *limits, - u8 pipe_mask, - const char *reason) +static int __intel_link_bw_reduce_bpp(struct intel_atomic_state *state, + struct intel_link_bw_limits *limits, + u8 pipe_mask, + const char *reason, + bool reduce_forced_bpp) { struct intel_display *display = to_intel_display(state); enum pipe max_bpp_pipe = INVALID_PIPE; @@ -97,6 +130,10 @@ int intel_link_bw_reduce_bpp(struct intel_atomic_state *state, */ link_bpp_x16 = fxp_q4_from_int(crtc_state->pipe_bpp); + if (!reduce_forced_bpp && + link_bpp_x16 <= get_forced_link_bpp_x16(state, crtc)) + continue; + if (link_bpp_x16 > max_bpp_x16) { max_bpp_x16 = link_bpp_x16; max_bpp_pipe = crtc->pipe; @@ -112,6 +149,21 @@ int intel_link_bw_reduce_bpp(struct intel_atomic_state *state, BIT(max_bpp_pipe)); } +int intel_link_bw_reduce_bpp(struct intel_atomic_state *state, + struct intel_link_bw_limits *limits, + u8 pipe_mask, + const char *reason) +{ + int ret; + + /* Try to keep any forced link BPP. */ + ret = __intel_link_bw_reduce_bpp(state, limits, pipe_mask, reason, false); + if (ret == -ENOSPC) + ret = __intel_link_bw_reduce_bpp(state, limits, pipe_mask, reason, true); + + return ret; +} + /** * intel_link_bw_set_bpp_limit_for_pipe - set link bpp limit for a pipe to its minimum * @state: atomic state @@ -245,3 +297,141 @@ int intel_link_bw_atomic_check(struct intel_atomic_state *state, return -EAGAIN; } + +static int force_link_bpp_show(struct seq_file *m, void *data) +{ + struct intel_connector *connector = m->private; + + seq_printf(m, FXP_Q4_FMT "\n", FXP_Q4_ARGS(connector->link.force_bpp_x16)); + + return 0; +} + +static int str_to_fxp_q4_uint(const char *str, int *val_x16) +{ + unsigned int val; + int err; + + err = kstrtouint(str, 10, &val); + if (err) + return err; + + if (val > INT_MAX >> 4) + return -ERANGE; + + *val_x16 = fxp_q4_from_int(val); + + return 0; +} + +/* modifies str */ +static int str_to_fxp_q4(char *str, int *val_x16) +{ + const char *int_str; + char *frac_str; + int frac_val; + int err; + + int_str = strim(str); + frac_str = strchr(int_str, '.'); + + if (frac_str) + *frac_str++ = '\0'; + + err = str_to_fxp_q4_uint(int_str, val_x16); + if (err) + return err; + + if (!frac_str) + return 0; + + if (*frac_str == '+') /* otherwise valid in front of an unsigned integer */ + return -EINVAL; + + err = str_to_fxp_q4_uint(frac_str, &frac_val); + if (err) + return err; + + *val_x16 += DIV_ROUND_CLOSEST(frac_val, int_pow(10, strlen(frac_str))); + + return 0; +} + +static int user_str_to_fxp_q4(const char __user *ubuf, size_t len, int *val_x16) +{ + char *kbuf; + int err; + + kbuf = memdup_user_nul(ubuf, len); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); + + err = str_to_fxp_q4(kbuf, val_x16); + + kfree(kbuf); + + return err; +} + +static bool connector_supports_dsc(struct intel_connector *connector) +{ + struct intel_display *display = to_intel_display(connector); + + switch (connector->base.connector_type) { + case DRM_MODE_CONNECTOR_eDP: + return intel_dp_has_dsc(connector); + case DRM_MODE_CONNECTOR_DisplayPort: + if (connector->mst.dp) + return HAS_DSC_MST(display); + + return HAS_DSC(display); + default: + return false; + } +} + +static ssize_t +force_link_bpp_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct intel_connector *connector = m->private; + struct intel_display *display = to_intel_display(connector); + int min_bpp; + int bpp_x16; + int err; + + err = user_str_to_fxp_q4(ubuf, len, &bpp_x16); + if (err) + return err; + + if (connector_supports_dsc(connector)) + min_bpp = intel_dp_dsc_min_src_compressed_bpp(); + else + min_bpp = intel_display_min_pipe_bpp(); + + if (bpp_x16 && + (bpp_x16 < fxp_q4_from_int(min_bpp) || + bpp_x16 > fxp_q4_from_int(intel_display_max_pipe_bpp(display)))) + return -EINVAL; + + err = drm_modeset_lock_single_interruptible(&display->drm->mode_config.connection_mutex); + if (err) + return err; + + connector->link.force_bpp_x16 = bpp_x16; + + drm_modeset_unlock(&display->drm->mode_config.connection_mutex); + + *offp += len; + + return len; +} +DEFINE_SHOW_STORE_ATTRIBUTE(force_link_bpp); + +void intel_link_bw_connector_debugfs_add(struct intel_connector *connector) +{ + struct dentry *root = connector->base.debugfs_entry; + + debugfs_create_file("i915_force_link_bpp", 0644, root, + connector, &force_link_bpp_fops); +} diff --git a/drivers/gpu/drm/i915/display/intel_link_bw.h b/drivers/gpu/drm/i915/display/intel_link_bw.h index e69049cf178f6..b499042e62b13 100644 --- a/drivers/gpu/drm/i915/display/intel_link_bw.h +++ b/drivers/gpu/drm/i915/display/intel_link_bw.h @@ -11,6 +11,7 @@ #include "intel_display_limits.h" struct intel_atomic_state; +struct intel_connector; struct intel_crtc_state; struct intel_link_bw_limits { @@ -32,5 +33,6 @@ bool intel_link_bw_set_bpp_limit_for_pipe(struct intel_atomic_state *state, enum pipe pipe); int intel_link_bw_atomic_check(struct intel_atomic_state *state, struct intel_link_bw_limits *new_limits); +void intel_link_bw_connector_debugfs_add(struct intel_connector *connector); #endif