From patchwork Mon Dec 14 22:20:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Aurabindo Pillai X-Patchwork-Id: 11973251 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7888C4361B for ; Mon, 14 Dec 2020 22:21:50 +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 68017224F9 for ; Mon, 14 Dec 2020 22:21:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 68017224F9 Authentication-Results: mail.kernel.org; dmarc=fail (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 C32BC6E154; Mon, 14 Dec 2020 22:21:49 +0000 (UTC) Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2084.outbound.protection.outlook.com [40.107.237.84]) by gabe.freedesktop.org (Postfix) with ESMTPS id 375BF89F5F; Mon, 14 Dec 2020 22:21:46 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HTY9cYgR0GRXfmGQtx+6GZjAyR62C4SnKy4hpN82Ue+pBUzRRbRiDNjAN6lUv+uDJaDN7zttjuQL4PNruwtrzbglVIy0u4hWlTFURoygZuq293f5NbX35FtLECyA1oyQqBB2gzcX5dxlJh13XbJNmWxFiRk7BGVnVigCCLKecSNujJxZMpmi67NyNCaYAM/Yjtg00obZDVnjSTMGszwkZ53DeaangoDRVHkFC+a48Ij4vnaTv0WcRddMMlsu8eh1uS5JqXndS5jfh1TsOR8TGf0HWkRG5SkgAQzw+LfemDK0TzCdx/Wps46Nacs9kHs83XnCn6YFD8rJvgR7wzY1og== 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=/yX3Y5pk4rRcjy2Lm4A66Y5lTJJvJ+w9+uOmYHLBbyM=; b=lCGJ7rmdzkDARs6OslAVTJJHO9TEV0MFMsMfEI7hAnS8mv2dUBTnQWG8yVCkKdhbmS3OxRORXUUBZvUvaWhBFmbIzfHIvFc54HRzH8CkwOZjDcMYdUnOZgf/pIdwsOUmzQ5jZuaXuZJplrHGBC9b0q82Uu9SGxhK5Oh8DAAeRjtDZIIo+gtmMdl3BEnzbrylt3hsTrvAZQPwnYZ+CAdVVB0jofhMpQn/qf96oFSCMZavUT+wOlXeHv0C6Kna/S1xAIezynv27fwaSfYXst8QaH1FrCv6RgyTtwE8LdhdwaTf8mFY7NnUH3xpNx8u2vAWQI/1ZP3hVx6wCFQNpsl3Gg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=softfail (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.freedesktop.org smtp.mailfrom=amd.com; dmarc=fail (p=none sp=none pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none 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=/yX3Y5pk4rRcjy2Lm4A66Y5lTJJvJ+w9+uOmYHLBbyM=; b=FaqQ7R7Ma0OZsPaOssCzYHpitXxEbSNogYBmeF17qNQKAQSzqPiZAhKjg+mppKF66O1fVYkAMnpqFfSFsG9pR7hcjYLVxcNSPTfvO5EUs9s0ovsKvGPilW5tkf+QOYfJLSyRfOL/MxNeqiDqLbG6IuRMq+QpDkhGDNiv9+e9Ink= Received: from DM5PR12CA0070.namprd12.prod.outlook.com (2603:10b6:3:103::32) by DM6PR12MB3417.namprd12.prod.outlook.com (2603:10b6:5:118::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12; Mon, 14 Dec 2020 22:21:44 +0000 Received: from DM6NAM11FT028.eop-nam11.prod.protection.outlook.com (2603:10b6:3:103:cafe::6d) by DM5PR12CA0070.outlook.office365.com (2603:10b6:3:103::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12 via Frontend Transport; Mon, 14 Dec 2020 22:21:44 +0000 X-MS-Exchange-Authentication-Results: spf=softfail (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=fail action=none header.from=amd.com; Received-SPF: SoftFail (protection.outlook.com: domain of transitioning amd.com discourages use of 165.204.84.17 as permitted sender) Received: from SATLEXMB01.amd.com (165.204.84.17) by DM6NAM11FT028.mail.protection.outlook.com (10.13.173.140) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.3654.20 via Frontend Transport; Mon, 14 Dec 2020 22:21:42 +0000 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB01.amd.com (10.181.40.142) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Mon, 14 Dec 2020 16:21:31 -0600 Received: from SATLEXMB01.amd.com (10.181.40.142) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Mon, 14 Dec 2020 16:21:31 -0600 Received: from elite-desk-aura.amd.com (10.180.168.240) by SATLEXMB01.amd.com (10.181.40.142) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Mon, 14 Dec 2020 16:21:30 -0600 From: Aurabindo Pillai To: , Subject: [PATCH v3 2/3] drm/amd/display: Add freesync video modes based on preferred modes Date: Mon, 14 Dec 2020 17:20:35 -0500 Message-ID: <20201214222036.561352-3-aurabindo.pillai@amd.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201214222036.561352-1-aurabindo.pillai@amd.com> References: <20201214222036.561352-1-aurabindo.pillai@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 62de128f-9809-41e2-d3f7-08d8a07ea2a4 X-MS-TrafficTypeDiagnostic: DM6PR12MB3417: X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2887; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7efZ1BeqRvMoRfInlkLj6QT1k6km7GtOjXRwI1piXX7unvAhqVyP4XNelNZy6UOmSBsjYkSRSC42nnx17pyFYV+Z7+fgQnIab3Me0xj50uJSyzPhPB5AVlpAXZPPFYfderti1Hz87t/qNUNRU6tPBxyfwFSKx5/Sw5Il4CiOmPfEKEYuofP78eD8pOfszPYHTbsyrnzlkr9nR6DrQXTj9bJtzw6AhExJU/4nvyRqmFv4mEPVD0m9Na2g83bViHw0X3iFkxe3WOutTtXuH0zwD2Qap3VrZ0Qp3W8o5ppGwPHu3otm3jlDujDZPYLUIy0tgsnsCp2+X2AHUyFxo6eHo3ZbDexBDWQKSBd+Hg8eqDzcc9ZhyKM9j9xIuObsd1/Agw3yCPsxslO6mq/7EYiHsw== X-Forefront-Antispam-Report: CIP:165.204.84.17; CTRY:US; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SATLEXMB01.amd.com; PTR:ErrorRetry; CAT:NONE; SFS:(4636009)(136003)(376002)(346002)(46966005)(82310400003)(8936002)(83380400001)(44832011)(356005)(2906002)(26005)(5660300002)(450100002)(81166007)(70586007)(8676002)(4326008)(7696005)(47076004)(508600001)(36756003)(110136005)(2616005)(1076003)(54906003)(186003)(426003)(70206006)(86362001)(336012); DIR:OUT; SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Dec 2020 22:21:42.7080 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 62de128f-9809-41e2-d3f7-08d8a07ea2a4 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=[SATLEXMB01.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT028.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB3417 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alexander.deucher@amd.com, aurabindo.pillai@amd.com, nicholas.kazlauskas@amd.com, shashank.sharma@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" [Why&How] If experimental freesync video mode module parameter is enabled, add few extra display modes into the driver's mode list corresponding to common video frame rates. When userspace sets these modes, no modeset will be performed (if current mode was one of freesync modes or the base freesync mode based off which timings have been generated for the rest of the freesync modes) since these modes only differ from the base mode with front porch timing. Signed-off-by: Aurabindo Pillai Acked-by: Christian König --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 167 ++++++++++++++++++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 + 2 files changed, 169 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 e7ee2467eadb..c1ffd33e9d83 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5174,6 +5174,59 @@ static void dm_enable_per_frame_crtc_master_sync(struct dc_state *context) set_master_stream(context->streams, context->stream_count); } +static struct drm_display_mode * +get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector, + bool use_probed_modes) +{ + struct drm_display_mode *m, *m_pref = NULL; + u16 current_refresh, highest_refresh; + struct list_head *list_head = use_probed_modes ? + &aconnector->base.probed_modes : + &aconnector->base.modes; + + if (aconnector->freesync_vid_base.clock != 0) + return &aconnector->freesync_vid_base; + + /* Find the preferred mode */ + list_for_each_entry (m, list_head, head) { + if (m->type & DRM_MODE_TYPE_PREFERRED) { + m_pref = m; + break; + } + } + + if (!m_pref) { + /* Probably an EDID with no preferred mode. Fallback to first entry */ + m_pref = list_first_entry_or_null( + &aconnector->base.modes, struct drm_display_mode, head); + if (!m_pref) { + DRM_DEBUG_DRIVER("No preferred mode found in EDID\n"); + return NULL; + } + } + + highest_refresh = drm_mode_vrefresh(m_pref); + + /* + * Find the mode with highest refresh rate with same resolution. + * For some monitors, preferred mode is not the mode with highest + * supported refresh rate. + */ + list_for_each_entry (m, list_head, head) { + current_refresh = drm_mode_vrefresh(m); + + if (m->hdisplay == m_pref->hdisplay && + m->vdisplay == m_pref->vdisplay && + highest_refresh < current_refresh) { + highest_refresh = current_refresh; + m_pref = m; + } + } + + aconnector->freesync_vid_base = *m_pref; + return m_pref; +} + static struct dc_stream_state * create_stream_for_sink(struct amdgpu_dm_connector *aconnector, const struct drm_display_mode *drm_mode, @@ -6999,6 +7052,119 @@ static void amdgpu_dm_connector_ddc_get_modes(struct drm_connector *connector, } } +static bool is_duplicate_mode(struct amdgpu_dm_connector *aconnector, + struct drm_display_mode *mode) +{ + struct drm_display_mode *m; + + list_for_each_entry (m, &aconnector->base.probed_modes, head) { + if (drm_mode_equal(m, mode)) + return true; + } + + return false; +} + +static uint add_fs_modes(struct amdgpu_dm_connector *aconnector, + struct detailed_data_monitor_range *range) +{ + const struct drm_display_mode *m; + struct drm_display_mode *new_mode; + uint i; + uint64_t target_vtotal, target_vtotal_diff; + uint32_t new_modes_count = 0; + uint64_t num, den; + + /* Standard FPS values + * + * 23.976 - TV/NTSC + * 24 - Cinema + * 25 - TV/PAL + * 29.97 - TV/NTSC + * 30 - TV/NTSC + * 48 - Cinema HFR + * 50 - TV/PAL + */ + const uint32_t common_rates[] = { 23976, 24000, 25000, 29970, 30000, + 48000, 50000, 60000, 72000, 96000 }; + + /* + * Find mode with highest refresh rate with the same resolution + * as the preferred mode. Some monitors report a preferred mode + * with lower resolution than the highest refresh rate supported. + */ + + m = get_highest_refresh_rate_mode(aconnector, true); + if (!m) + return 0; + + for (i = 0; i < ARRAY_SIZE(common_rates); i++) { + if (drm_mode_vrefresh(m) * 1000 < common_rates[i]) + continue; + + if (common_rates[i] < range->min_vfreq * 1000) + continue; + + num = (unsigned long long)m->clock * 1000 * 1000; + den = common_rates[i] * (unsigned long long)m->htotal; + target_vtotal = div_u64(num, den); + target_vtotal_diff = target_vtotal - m->vtotal; + + /* Check for illegal modes */ + if (m->vsync_start + target_vtotal_diff < m->vdisplay || + m->vsync_end + target_vtotal_diff < m->vsync_start || + m->vtotal + target_vtotal_diff < m->vsync_end) + continue; + + new_mode = drm_mode_duplicate(aconnector->base.dev, m); + if (!new_mode) + goto out; + + new_mode->vtotal += (u16)target_vtotal_diff; + new_mode->vsync_start += (u16)target_vtotal_diff; + new_mode->vsync_end += (u16)target_vtotal_diff; + new_mode->type &= ~DRM_MODE_TYPE_PREFERRED; + new_mode->type |= DRM_MODE_TYPE_DRIVER; + + if (!is_duplicate_mode(aconnector, new_mode)) { + drm_mode_probed_add(&aconnector->base, new_mode); + new_modes_count += 1; + } else + drm_mode_destroy(aconnector->base.dev, new_mode); + } + out: + return new_modes_count; +} + +static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connector, + struct edid *edid) +{ + uint8_t i; + struct detailed_timing *timing; + struct detailed_non_pixel *data; + struct detailed_data_monitor_range *range; + struct amdgpu_dm_connector *amdgpu_dm_connector = + to_amdgpu_dm_connector(connector); + + if (!(amdgpu_exp_freesync_vid_mode && edid)) + return; + + if (edid->version == 1 && edid->revision > 1) { + for (i = 0; i < 4; i++) { + timing = &edid->detailed_timings[i]; + data = &timing->data.other_data; + range = &data->data.range; + + /* Check if monitor has continuous frequency mode */ + if (data->type == EDID_DETAIL_MONITOR_RANGE && + range->max_vfreq - range->min_vfreq > 10) { + amdgpu_dm_connector->num_modes += add_fs_modes(amdgpu_dm_connector, range); + break; + } + } + } +} + static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) { struct amdgpu_dm_connector *amdgpu_dm_connector = @@ -7014,6 +7180,7 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) } else { amdgpu_dm_connector_ddc_get_modes(connector, edid); amdgpu_dm_connector_add_common_modes(encoder, connector); + amdgpu_dm_connector_add_freesync_modes(connector, edid); } amdgpu_dm_fbc_init(connector); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 251af783f6b1..f5a5f1ad7dba 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -413,6 +413,8 @@ struct amdgpu_dm_connector { #endif bool force_yuv420_output; struct dsc_preferred_settings dsc_settings; + /* Cached display modes */ + struct drm_display_mode freesync_vid_base; }; #define to_amdgpu_dm_connector(x) container_of(x, struct amdgpu_dm_connector, base)