From patchwork Thu Nov 7 15:32:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lipski, Mikita" X-Patchwork-Id: 11233213 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1748916B1 for ; Thu, 7 Nov 2019 15:32:51 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id F34E3214D8 for ; Thu, 7 Nov 2019 15:32:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F34E3214D8 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amd.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B99E16F711; Thu, 7 Nov 2019 15:32:36 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from NAM04-SN1-obe.outbound.protection.outlook.com (mail-eopbgr700056.outbound.protection.outlook.com [40.107.70.56]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2AFE46F709; Thu, 7 Nov 2019 15:32:32 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CncZeKk8jCJrV/lc9iaj5h5kQInH8cWTzNBjWv1nI428jk7ELRRiz6JoZ239jsVK7jaSeLVanAGRvVmlb1KgkC+Ghxp8afhCVd9UeQ96fm3u+74UnEoSvtq501+FvIdOI8cz15p6tEt4Vs1nChq4pBcSfwTAy3VU6l3LlNk2CMKKdCvLsb2XJ7wLF2TirWIXdMxTVwcDv/LwU7nK5I7We/QO6lZKbQBdgqCX5vfatT+QCiOz2PaA5zt/VQJWVocJ65cNwpnKJ1xiNqZNpslji5942ADFJ/sKUpKkDsCcCX4PBpo45Qq6jUlQ0M7qmDjeaET2CB83e9bI+hHHEel9Jg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tTBIyR3HOvIzIJ8AkTeEJXHSWsKag+du9dnyLyuhRvM=; b=lGhdoQlHbyx931E9m0uCg1AnOsDzfc1gh0+pYdX7+PNx1TjBg1ZYpPbPJavFHw8Lor/JbSO2CIDoLK6nwQu23e/iCz3F+HX14W6txUyHpolj2eAwT4s35jzUEGESGofvw4rtI/VihaAY1+HczdcigEUP4Bt+S3LS9Snj3Rk/ylftMJOwUQJD3BuoVD0Lro2k8mwQVg41bMqQHhlK38V+KS6nGxvN1tjfT8VbpZgCqm6K5bG4BKpIUdkMDJpArhAIBUaAOY9vPX2EWkOd1bPwB9d9QNMdFPgi5dp/kENG0DVNU/rhVdFdDjNpfYBXTHQwoOdk8PR6FSbxWDU65O5GKw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.freedesktop.org smtp.mailfrom=amd.com; dmarc=permerror action=none header.from=amd.com; dkim=none (message not signed); arc=none Received: from DM5PR12CA0013.namprd12.prod.outlook.com (2603:10b6:4:1::23) by MN2PR12MB3679.namprd12.prod.outlook.com (2603:10b6:208:159::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2430.24; Thu, 7 Nov 2019 15:32:30 +0000 Received: from DM3NAM03FT049.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e49::207) by DM5PR12CA0013.outlook.office365.com (2603:10b6:4:1::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2430.22 via Frontend Transport; Thu, 7 Nov 2019 15:32:30 +0000 Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from SATLEXMB02.amd.com (165.204.84.17) by DM3NAM03FT049.mail.protection.outlook.com (10.152.83.125) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.2430.20 via Frontend Transport; Thu, 7 Nov 2019 15:32:30 +0000 Received: from SATLEXMB01.amd.com (10.181.40.142) by SATLEXMB02.amd.com (10.181.40.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Thu, 7 Nov 2019 09:32:28 -0600 Received: from mlipski-pc.amd.com (10.180.168.240) by SATLEXMB01.amd.com (10.181.40.142) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Thu, 7 Nov 2019 09:32:28 -0600 From: To: Subject: [PATCH v6 12/13] drm/amd/display: MST DSC compute fair share Date: Thu, 7 Nov 2019 10:32:11 -0500 Message-ID: <20191107153212.1145-13-mikita.lipski@amd.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191107153212.1145-1-mikita.lipski@amd.com> References: <20191107153212.1145-1-mikita.lipski@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:165.204.84.17; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(4636009)(346002)(136003)(396003)(39860400002)(376002)(428003)(199004)(189003)(30864003)(70206006)(70586007)(1076003)(186003)(5660300002)(53416004)(4326008)(450100002)(478600001)(126002)(486006)(6666004)(356004)(426003)(14444005)(336012)(476003)(2616005)(11346002)(36756003)(305945005)(446003)(50466002)(48376002)(316002)(8676002)(76176011)(51416003)(6916009)(7696005)(2351001)(16586007)(86362001)(47776003)(54906003)(26005)(50226002)(2876002)(8936002)(81156014)(81166006)(2906002)(16060500001); DIR:OUT; SFP:1101; SCL:1; SRVR:MN2PR12MB3679; H:SATLEXMB02.amd.com; FPR:; SPF:None; LANG:en; PTR:InfoDomainNonexistent; A:1; MX:1; X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: bf56504b-49fb-42c1-aadb-08d76397b3a1 X-MS-TrafficTypeDiagnostic: MN2PR12MB3679: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-Forefront-PRVS: 0214EB3F68 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: QSTrJGdkC2pL53cOcPBlaUVLUfZUxit9PpgpK1GDKfxv0lyvBBtGx5iyC9YpPue6dteZA4zwhpQI/Le/AKQJXqtoQstreVHH7p1DsqJz+AbePGgLVu7ZZYCMbzZjs8t+wxLuSVxWMPuPbrKfCfbwUNiR1SvzMugGzKDnD8Je8+l3Wv8XrX73uPr/kU+e6WTjlx/g3nXnM2gCpmsGzxyk8IEGNdo2UcadWrMs3h+692eheDc2H8wqeJ4m9MqPyQBZa3bCajB377SWUkn24Ko+7oWQ+UVxIb4RPJet/Xu7klfh/flvInW+Hxww5h/X235yqZCaQnHpEP8I+ZdnaxF4OPKTTpnFCxeyxJtTxxmQLtfQaXhW+yxRDBzBazaijm3p4A05Wz/zu/DGq8wiCKoI7Fglj1bdytpwGlnPQg3Xup3Cp2TZPhwdxZz8i4dydXdG X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Nov 2019 15:32:30.0212 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: bf56504b-49fb-42c1-aadb-08d76397b3a1 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d; Ip=[165.204.84.17]; Helo=[SATLEXMB02.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB3679 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=tTBIyR3HOvIzIJ8AkTeEJXHSWsKag+du9dnyLyuhRvM=; b=B20ZokC3sYQWOXusiLxOJVLiyRXrLBdPOgL3sOmcHmKEFheAjGfHRY2G52i11/vewhGFxI2tV47oS4Z8/7PFTa/hiLBC6526+Or+qjP9KA19dhy8JM4AKisbPgNxLslYCAXhIY+g8FT7qVJUJW7WMY6KOgy3c3qTVye6Bd32fmc= X-Mailman-Original-Authentication-Results: spf=none (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; lists.freedesktop.org; dkim=none (message not signed) header.d=none;lists.freedesktop.org; dmarc=permerror action=none header.from=amd.com; X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Francis , Mikita Lipski , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: David Francis If there is limited link bandwidth on a MST network, it must be divided fairly between the streams on that network Implement an algorithm to determine the correct DSC config for each stream The algorithm: This [ ] ( ) represents the range of bandwidths possible for a given stream. The [] area represents the range of DSC configs, and the () represents no DSC. The bandwidth used increases from left to right. First, try disabling DSC on all streams [ ] (|) [ ] (|) Check this against the bandwidth limits of the link and each branch (including each endpoint). If it passes, the job is done Second, try maximum DSC compression on all streams that support DSC [| ] ( ) [| ] ( ) If this does not pass, then enabling this combination of streams is impossible Otherwise, divide the remaining bandwidth evenly amongst the streams [ | ] ( ) [ | ] ( ) If one or more of the streams reach minimum compression, evenly divide the reamining bandwidth amongst the remaining streams [ |] ( ) [ |] ( ) [ | ] ( ) [ | ] ( ) If all streams can reach minimum compression, disable compression greedily [ |] ( ) [ |] ( ) [ ] (|) Perform this algorithm on each full update, on each MST link with at least one DSC stream on it After the configs are computed, call dcn20_add_dsc_to_stream_resource on each stream with DSC enabled. It is only after all streams are created that we can know which of them will need DSC. Do all of this at the end of amdgpu atomic check. If it fails, fail check; This combination of timings cannot be supported. v2: Use drm_dp_mst_atomic_check to validate bw for certain dsc configurations Reviewed-by: Wenjing Liu Signed-off-by: David Francis Signed-off-by: Mikita Lipski --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 + .../display/amdgpu_dm/amdgpu_dm_mst_types.c | 397 ++++++++++++++++++ .../display/amdgpu_dm/amdgpu_dm_mst_types.h | 5 + .../drm/amd/display/dc/dcn20/dcn20_resource.c | 3 + .../drm/amd/display/dc/dcn20/dcn20_resource.h | 1 + 5 files changed, 410 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 105ab57515fe..609020a0549e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8064,6 +8064,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, if (ret) goto fail; +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT + if (!compute_mst_dsc_configs_for_state(state, dm_state->context)) + goto fail; +#endif if (dc_validate_global_state(dc, dm_state->context, false) != DC_OK) { ret = -EINVAL; goto fail; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 804a00082bee..6065f1d8e83e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -38,6 +38,8 @@ #include "i2caux_interface.h" +#include "dc/dcn20/dcn20_resource.h" + /* #define TRACE_DPCD */ #ifdef TRACE_DPCD @@ -491,3 +493,398 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, aconnector->connector_id); } +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +struct dsc_mst_fairness_params { + struct dc_crtc_timing *timing; + struct dc_sink *sink; + struct dc_dsc_bw_range bw_range; + bool compression_possible; + struct drm_dp_mst_port *port; +}; + +struct dsc_mst_fairness_vars { + int pbn; + bool dsc_enabled; + int bpp_x16; +}; + +static bool port_downstream_of_branch(struct drm_dp_mst_port *port, + struct drm_dp_mst_branch *branch) +{ + while (port->parent) { + if (port->parent == branch) + return true; + + if (port->parent->port_parent) + port = port->parent->port_parent; + else + break; + } + return false; +} + +static bool check_pbn_limit_on_branch(struct drm_dp_mst_branch *branch, + struct dsc_mst_fairness_params *params, + struct dsc_mst_fairness_vars *vars, int count) +{ + struct drm_dp_mst_port *port; + int i; + int pbn_limit = 0; + int pbn_used = 0; + + list_for_each_entry(port, &branch->ports, next) { + if (port->mstb) + if (!check_pbn_limit_on_branch(port->mstb, params, vars, count)) + return false; + + if (port->available_pbn > 0) + pbn_limit = port->available_pbn; + } + + for (i = 0; i < count; i++) { + if (port_downstream_of_branch(params[i].port, branch)) + pbn_used += vars[i].pbn; + } + + if (pbn_used > pbn_limit) + return false; + + return true; +} + +static bool check_bandwidth_limits(struct dc_link *dc_link, + struct dsc_mst_fairness_params *params, + struct dsc_mst_fairness_vars *vars, + int count) +{ + int link_timeslot_limit = 63; + int link_timeslots_used = 0; + int pbn_per_timeslot; + int i; + struct drm_dp_mst_topology_mgr *mst_mgr; + + /* kbits to pbn, dividing by 64 */ + + pbn_per_timeslot = dc_link_bandwidth_kbps(dc_link, + dc_link_get_link_cap(dc_link)) / (8 * 1000 * 54); + + /* Check link bandwidth limit */ + for (i = 0; i < count; i++) + link_timeslots_used += DIV_ROUND_UP(vars[i].pbn, pbn_per_timeslot); + + if (link_timeslots_used > link_timeslot_limit) + return false; + + /* Check branch bandwidth limit for each port on each branch */ + mst_mgr = params[0].port->mgr; + + if (!check_pbn_limit_on_branch(mst_mgr->mst_primary, params, vars, count)) + return false; + return true; +} + +static int kbps_to_peak_pbn(int kbps) +{ + u64 peak_kbps = kbps; + + peak_kbps *= 1006; + peak_kbps /= 1000; + return (int) DIV_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); +} + +static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params, + struct dsc_mst_fairness_vars *vars, + int count) +{ + int i; + + for (i = 0; i < count; i++) { + memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg)); + if (vars[i].dsc_enabled && dc_dsc_compute_config( + params[i].sink->ctx->dc->res_pool->dscs[0], + ¶ms[i].sink->sink_dsc_caps.dsc_dec_caps, + params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, + 0, + params[i].timing, + ¶ms[i].timing->dsc_cfg)) { + params[i].timing->flags.DSC = 1; + params[i].timing->dsc_cfg.bits_per_pixel = vars[i].bpp_x16; + } else { + params[i].timing->flags.DSC = 0; + } + + } + +} + +static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) +{ + struct dc_dsc_config dsc_config; + u64 kbps; + + kbps = (u64)pbn * 994 * 8 * 54 / 64; + dc_dsc_compute_config( + param.sink->ctx->dc->res_pool->dscs[0], + ¶m.sink->sink_dsc_caps.dsc_dec_caps, + param.sink->ctx->dc->debug.dsc_min_slice_height_override, + (int) kbps, param.timing, &dsc_config); + + return dsc_config.bits_per_pixel; +} + +static void increase_dsc_bpp(struct dc_link *dc_link, + struct dsc_mst_fairness_params *params, + struct dsc_mst_fairness_vars *vars, + int count) +{ + int i; + bool bpp_increased[MAX_PIPES]; + int initial_slack[MAX_PIPES]; + int min_initial_slack; + int next_index; + int remaining_to_increase = 0; + int pbn_per_timeslot; + int link_timeslots_used; + int fair_pbn_alloc; + + for (i = 0; i < count; i++) { + if (vars[i].dsc_enabled) { + initial_slack[i] = kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i].pbn; + bpp_increased[i] = false; + remaining_to_increase += 1; + } else { + initial_slack[i] = 0; + bpp_increased[i] = true; + } + } + + pbn_per_timeslot = dc_link_bandwidth_kbps(dc_link, + dc_link_get_link_cap(dc_link)) / (8 * 1000 * 54); + + while (remaining_to_increase) { + next_index = -1; + min_initial_slack = -1; + for (i = 0; i < count; i++) { + if (!bpp_increased[i]) { + if (min_initial_slack == -1 || min_initial_slack > initial_slack[i]) { + min_initial_slack = initial_slack[i]; + next_index = i; + } + } + } + + if (next_index == -1) + break; + + link_timeslots_used = 0; + + for (i = 0; i < count; i++) + link_timeslots_used += DIV_ROUND_UP(vars[i].pbn, pbn_per_timeslot); + + fair_pbn_alloc = (63 - link_timeslots_used) / remaining_to_increase * pbn_per_timeslot; + + if (initial_slack[next_index] > fair_pbn_alloc) { + vars[next_index].pbn += fair_pbn_alloc; + if (check_bandwidth_limits(dc_link, params, vars, count)) + vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn); + else + vars[next_index].pbn -= fair_pbn_alloc; + } else { + vars[next_index].pbn += initial_slack[next_index]; + if (check_bandwidth_limits(dc_link, params, vars, count)) + vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16; + else + vars[next_index].pbn -= initial_slack[next_index]; + } + + bpp_increased[next_index] = true; + remaining_to_increase--; + } +} + +static void try_disable_dsc(struct dc_link *dc_link, + struct dsc_mst_fairness_params *params, + struct dsc_mst_fairness_vars *vars, + int count) +{ + int i; + bool tried[MAX_PIPES]; + int kbps_increase[MAX_PIPES]; + int max_kbps_increase; + int next_index; + int remaining_to_try = 0; + + for (i = 0; i < count; i++) { + if (vars[i].dsc_enabled && vars[i].bpp_x16 == params[i].bw_range.max_target_bpp_x16) { + kbps_increase[i] = params[i].bw_range.stream_kbps - params[i].bw_range.max_kbps; + tried[i] = false; + remaining_to_try += 1; + } else { + kbps_increase[i] = 0; + tried[i] = true; + } + } + + while (remaining_to_try) { + next_index = -1; + max_kbps_increase = -1; + for (i = 0; i < count; i++) { + if (!tried[i]) { + if (max_kbps_increase == -1 || max_kbps_increase < kbps_increase[i]) { + max_kbps_increase = kbps_increase[i]; + next_index = i; + } + } + } + + if (next_index == -1) + break; + + vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); + + if (check_bandwidth_limits(dc_link, params, vars, count)) { + vars[next_index].dsc_enabled = false; + vars[next_index].bpp_x16 = 0; + } else { + vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); + } + + tried[next_index] = true; + remaining_to_try--; + } +} + +static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, + struct dc_state *dc_state, + struct dc_link *dc_link) +{ + int i; + struct dc_stream_state *stream; + struct dsc_mst_fairness_params params[MAX_PIPES]; + struct dsc_mst_fairness_vars vars[MAX_PIPES]; + struct amdgpu_dm_connector *aconnector; + int count = 0; + + memset(params, 0, sizeof(params)); + + /* Set up params */ + for (i = 0; i < dc_state->stream_count; i++) { + stream = dc_state->streams[i]; + + if (stream->link != dc_link) + continue; + + stream->timing.flags.DSC = 0; + + params[count].timing = &stream->timing; + params[count].sink = stream->sink; + aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; + params[count].port = aconnector->port; + params[count].compression_possible = stream->sink->sink_dsc_caps.dsc_dec_caps.is_dsc_supported; + if (!dc_dsc_compute_bandwidth_range( + stream->sink->ctx->dc->res_pool->dscs[0], + stream->sink->ctx->dc->debug.dsc_min_slice_height_override, + 8, 16, + &stream->sink->sink_dsc_caps.dsc_dec_caps, + &stream->timing, ¶ms[count].bw_range)) + params[count].bw_range.stream_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing); + + count++; + } + + /* Try no compression */ + for (i = 0; i < count; i++) { + vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i].dsc_enabled = false; + vars[i].bpp_x16 = 0; + drm_dp_atomic_find_vcpi_slots(state, + params[i].port->mgr, + params[i].port, + vars[i].pbn); + } + + if (!drm_dp_mst_atomic_check(state)) { + set_dsc_configs_from_fairness_vars(params, vars, count); + return true; + } + + /* Try max compression */ + for (i = 0; i < count; i++) { + if (params[i].compression_possible) { + vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); + vars[i].dsc_enabled = true; + vars[i].bpp_x16 = params[i].bw_range.min_target_bpp_x16; + } else { + vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); + vars[i].dsc_enabled = false; + vars[i].bpp_x16 = 0; + } + drm_dp_atomic_find_vcpi_slots(state, + params[i].port->mgr, + params[i].port, + vars[i].pbn); + } + if (drm_dp_mst_atomic_check(state)) + return false; + + /* Optimize degree of compression */ + increase_dsc_bpp(dc_link, params, vars, count); + + try_disable_dsc(dc_link, params, vars, count); + + set_dsc_configs_from_fairness_vars(params, vars, count); + + return true; +} + +bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, + struct dc_state *dc_state) +{ + int i, j; + struct dc_stream_state *stream; + bool computed_streams[MAX_PIPES]; + struct amdgpu_dm_connector *aconnector; + + for (i = 0; i < dc_state->stream_count; i++) + computed_streams[i] = false; + + for (i = 0; i < dc_state->stream_count; i++) { + stream = dc_state->streams[i]; + + if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) + continue; + + aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; + + if (!aconnector || !aconnector->dc_sink) + continue; + + if (!aconnector->dc_sink->sink_dsc_caps.dsc_dec_caps.is_dsc_supported) + continue; + + if (computed_streams[i]) + continue; + + mutex_lock(&aconnector->mst_mgr.lock); + if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) { + mutex_unlock(&aconnector->mst_mgr.lock); + return false; + } + mutex_unlock(&aconnector->mst_mgr.lock); + + for (j = 0; j < dc_state->stream_count; j++) { + if (dc_state->streams[j]->link == stream->link) + computed_streams[j] = true; + } + } + + for (i = 0; i < dc_state->stream_count; i++) { + stream = dc_state->streams[i]; + + if (stream->timing.flags.DSC == 1) + dcn20_add_stream_to_ctx(stream->ctx->dc, dc_state, stream); + } + + return true; +} +#endif diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h index 2da851b40042..3b8bb4ea51c7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.h @@ -32,4 +32,9 @@ struct amdgpu_dm_connector; void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, struct amdgpu_dm_connector *aconnector); + +#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT +bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, + struct dc_state *dc_state); +#endif #endif diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 3d5a79ff1151..468db6be5b83 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1501,6 +1501,9 @@ static enum dc_status add_dsc_to_stream_resource(struct dc *dc, if (pipe_ctx->stream != dc_stream) continue; + if (pipe_ctx->stream_res.dsc) + continue; + acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc); /* The number of DSCs can be less than the number of pipes */ diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h index fa00989584dc..f1cf8a634c9b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.h @@ -157,6 +157,7 @@ void dcn20_calculate_dlg_params( enum dc_status dcn20_build_mapped_resource(const struct dc *dc, struct dc_state *context, struct dc_stream_state *stream); enum dc_status dcn20_add_stream_to_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream); +enum dc_status dcn20_add_dsc_to_stream_resource(struct dc *dc, struct dc_state *dc_ctx, struct dc_stream_state *dc_stream); enum dc_status dcn20_remove_stream_from_ctx(struct dc *dc, struct dc_state *new_ctx, struct dc_stream_state *dc_stream); enum dc_status dcn20_get_default_swizzle_mode(struct dc_plane_state *plane_state);