From patchwork Thu Feb 11 17:19:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Wentland X-Patchwork-Id: 8283121 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 38C869F3CD for ; Thu, 11 Feb 2016 17:20:48 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 39A20202FE for ; Thu, 11 Feb 2016 17:20:43 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 08C06203AB for ; Thu, 11 Feb 2016 17:20:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9EE156E8CD; Thu, 11 Feb 2016 09:20:33 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2on0085.outbound.protection.outlook.com [207.46.100.85]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9F5E06E893 for ; Thu, 11 Feb 2016 09:20:32 -0800 (PST) Received: from CY1PR12CA0073.namprd12.prod.outlook.com (10.163.230.41) by CY1PR12MB0856.namprd12.prod.outlook.com (10.164.70.14) with Microsoft SMTP Server (TLS) id 15.1.403.16; Thu, 11 Feb 2016 17:20:29 +0000 Received: from BY2NAM03FT009.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e4a::208) by CY1PR12CA0073.outlook.office365.com (2a01:111:e400:c42b::41) with Microsoft SMTP Server (TLS) id 15.1.403.16 via Frontend Transport; Thu, 11 Feb 2016 17:20:29 +0000 Authentication-Results: spf=none (sender IP is 165.204.84.222) 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; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from atltwp02.amd.com (165.204.84.222) by BY2NAM03FT009.mail.protection.outlook.com (10.152.84.120) with Microsoft SMTP Server id 15.1.415.6 via Frontend Transport; Thu, 11 Feb 2016 17:20:28 +0000 X-WSS-ID: 0O2E85Z-08-09L-02 X-M-MSG: Received: from satlvexedge02.amd.com (satlvexedge02.amd.com [10.177.96.29]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by atltwp02.amd.com (Axway MailGate 5.3.1) with ESMTPS id 22F66D22F90 for ; Thu, 11 Feb 2016 12:20:23 -0500 (EST) Received: from SATLEXDAG02.amd.com (10.181.40.5) by SATLVEXEDGE02.amd.com (10.177.96.29) with Microsoft SMTP Server (TLS) id 14.3.195.1; Thu, 11 Feb 2016 11:20:59 -0600 Received: from STOREXDAG03.amd.com (10.1.13.12) by SATLEXDAG02.amd.com (10.181.40.5) with Microsoft SMTP Server (TLS) id 14.3.266.1; Thu, 11 Feb 2016 12:20:27 -0500 Received: from cnhwentlanub.amd.com (172.29.225.36) by storexdag03.amd.com (10.1.13.12) with Microsoft SMTP Server id 14.3.266.1; Thu, 11 Feb 2016 12:20:25 -0500 From: Harry Wentland To: Subject: [PATCH 06/29] drm/amd/dal: Adapter Service Date: Thu, 11 Feb 2016 12:19:46 -0500 Message-ID: <1455211209-26733-7-git-send-email-harry.wentland@amd.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455211209-26733-1-git-send-email-harry.wentland@amd.com> References: <1455211209-26733-1-git-send-email-harry.wentland@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:165.204.84.222; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(428002)(189002)(199003)(87936001)(1096002)(19580405001)(48376002)(77096005)(5003940100001)(101416001)(92566002)(229853001)(19580395003)(2351001)(450100001)(586003)(36756003)(86362001)(11100500001)(189998001)(4326007)(5008740100001)(50226001)(2906002)(1220700001)(105586002)(50466002)(50986999)(575784001)(76176999)(2950100001)(106466001)(53416004)(33646002)(5003600100002)(47776003)(579004)(559001); DIR:OUT; SFP:1101; SCL:1; SRVR:CY1PR12MB0856; H:atltwp02.amd.com; FPR:; SPF:None; MLV:sfv; MX:1; A:1; LANG:en; X-MS-Office365-Filtering-Correlation-Id: 1d9aab7d-74d9-4de7-afc8-08d33307a343 X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0856; 2:HiiOSJomDnFpPM0sZse4/LPDdm23mW3f5Y2DI7NjALdfQxXk5LDJ2Rg1s4rc2sXJUNKu5tBB/ziwV8SaEtGeo+jEqrDrt4XP3NX4DHnXE59RDcvAnrs89BMC9BhdHh7nOkot5qxFoRTA4hpdR829rWnsN/6yc/Gv/gqQ5eeszIUjEQ+jBLDcwb9hpv4cYBhT; 3:3jrSLnBCKO84j7bdVeYVBF5Q1QSZh4s8nWhvTsWbZsxJnbaM0jpE5a73iMewhlxi7oVlnTD3HzLwvv0lN101kyUrNxQaP3a5Cq3n+BG6Pdpv/WXRtC3WaKxaM0Ho6TPkAYYSH+iBNY7kup3eLfnX9RPbkLqcPFoumZeTx9xsatchRYUCDVJI/crzFurpllecjVScROi1X4qBZf/YYzZ5kRIl4S5HaRV4FeM+KbRm7uM=; 25:hjrcF1lCaDQKpnibwc89HZuck35IuXxdY24rheKqq0U4R8y7AQCr7LeNXmssDDqY2Uj7GPRHYX8ujWPrBvRH5yklJcV8p/kfpIYWY6yairERRAGkm3d3u2Au/43uDgDYlupoNkPBS/tlPQH/+vGq4SSwbJ/AKlVZT0QrLZl9zhGWKGGJmgzsHV12FKx0Ca7S936d32ZKmda9BIyfr2qN3QS7dCyXhMuaIv5iXLiZAW+gmPEZAPtRp3qWI8tq8EYURXuwiIBfneckGiyOET1hAvlMLNRVoZ1rupsKoYCyWIo1aI13O2TVftgnVCHMl9SX X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR12MB0856; X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0856; 20:NytwluLKYQUW4ZMdO26l6vo/+YSQqs2ZkEfQzfA+DSRTn0825TF5HbPQnwApeQZMzBFiQpUKml8mU8B1oOlZQi4KQQFeyngJbdRrToAmcTScCUrD+4dS2BYvY2EtrWDF29xLYgNb8KeAA/LHemM08S1s/871tnA5yD0Ekqvjbb3PGeVsk3T5Lqbwo1LaCDTz4kuXH5q3oEUmJoxdCuonjduspDQI6iW0lRSpYzghaBMR1o16aiNlBMDA4nDmshKv/6eSr4CabjrZpKRDM5AzOr1TZ5IRJepuH9YAjyRRZ75UxsalfPfeHmy5l0tH3KBXY3A6gocUq6C9p/NlzRD41egu8Gp4Scw02SdLTSeOXzyvtQpJzgGV46hNkPSGR4mjq3oE2pPEPp56CGNgbH5+ESj/Y6nNMCtt7jVQ3HI6dytOhZL8WvBhajzpQsOva7ia6rCjS1MShqzjF5D2woCm8RvBWR79VBbyKy7sHKkBskmYBCxRssjPttCG8DA5W+EN X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13018025)(13024025)(13015025)(13023025)(13017025)(5005006)(8121501046)(3002001)(10201501046); SRVR:CY1PR12MB0856; BCL:0; PCL:0; RULEID:; SRVR:CY1PR12MB0856; X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0856; 4:TPLhfy+sTGn/Cxlu6F4jff4ISd5ND3gcrxHbpPXyNj6qDNBRFrUfpdfXNDrBJFPdntKAPpFwvEh+hfc7UBSQaL/yKxONaErxgQi608fwEf0tiXs+B5Cl0CfxKQjudrpcm1CTXDveafmKP1AH/eO2M9p6cFXfInD1HkCWy9xlPKw5auIlPCL64kETRdBen5OAhBZwUpMR28NUwrTyziW6JliHhOadZynYYDFOCH/U5zi3zClQivczOXi2TN7yHBMF5+uJcNLR5qth6ssUnAPfMxtbf0EFaPcjKcSf+0MATWifBdBf1YM3Wev2umHoqO5RUFqkhQiDctRuMJEO7v6TeEM9I3UUhqiJ7j5tyHX3eSZPscr43LBh0rSolCvCl4Z4jR+cWy3Q5l/vpGQpzlXm5Qg2zG3UFv5obc6FFHJL3zwUpSKu4puyES1fGYVH6GI8cS7y/dv5m4xsWbD0BHghmXpDKsTmuNn+rwy50R1pEE/nMd2Ue3TsJUr7NVH5SI+R X-Forefront-PRVS: 08497C3D99 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY1PR12MB0856; 23:K3o9KuI1yf2XWzdwK/vZ6J8C6yYxOhgh+oFPKX5Up?= =?us-ascii?Q?DvRqu6MF5RdTZNQWQzupYTWWZj1SuFLR6mUqax1ATeH8my2+XTZLOL3X57FS?= =?us-ascii?Q?Ys2Z/6axSQdvVUCLSgScwRe7CmHjOPsmGI23aQG7hpBQfjCIvtfU9V1+0bJ5?= =?us-ascii?Q?9U0S+Km61HVuwFNyz0SweEbBuQbIC71evQxrb+iSQzQYD1xhgl8PWAiDztvo?= =?us-ascii?Q?n1CFVPGJoesgNtGnNffwrWxpLaZkNRXo5Q2IegaCJLSTPzXuYvWuqusFTHao?= =?us-ascii?Q?9Me9x0SLRMO6d5CEUJ9++Hj6tpwiwDh7j1P37Jy1Rx6QpodHKI/JF0NzwKlu?= =?us-ascii?Q?DDeiJCQibLwDGbohkgUdt4kWfH9mgI9WSag9pFJhcQ1jXbnswQ0POwiyDYRj?= =?us-ascii?Q?mzaXfbC/jfzEIePUUB5AIuMfOuKMyUmPRnu9vqJs93+Vo6YrmaONraexhjkJ?= =?us-ascii?Q?yU3zWS/Odvu9oDRby36gbIESVZ/KK8kFGDifReRs46eY0CmDEvzercGwmsX4?= =?us-ascii?Q?smDLpe/52Wh8IcCJ5csthf3k5IvfffI25OCzdQlEUQK6cP5eteqNCGy4JmF7?= =?us-ascii?Q?CirV09cG8Tmks07k4Fnss/fokVt7tIbyLLkjvanFf5q6eXpMW+9hyVpqwjam?= =?us-ascii?Q?3LolmpusKxuUuFkghKmBEePzC6yLD4WKyosqF+A/K7ZqQBolTh86utpZvQPZ?= =?us-ascii?Q?kBvcy+thLSy/tOwO4pLILCGxxEt9CKDPMuy9yiqWIRgm393mz0AnVtdKiL5t?= =?us-ascii?Q?a7H159+hdMcVbI+4NXhloWukaSUdYDNhhVnA8cTW8svspmaeVk/957OhJTNU?= =?us-ascii?Q?Ipv8nLCESewcvrcNheO4IFus8DyblyGkfzUcc8ToP/povnB8KNmY8W0pexDO?= =?us-ascii?Q?GSpx/E8tztNUr7k5ZDxQoLBbqM/Erfl7MyFCkHnd6xi9FZE4Nr+c2g9DBPTE?= =?us-ascii?Q?Ouo2sjwWOWqF+9zH1qCIh5bM4SQMYDGvZozAQ11Dwt1k9gyUnnYMsvxNJv+b?= =?us-ascii?Q?m0okLuZKtFCqcX7nxQMsudODK8VSkhLXGJMSzBsW4r/IVRZ3c4qUIu1UHtmz?= =?us-ascii?Q?/GnfRU=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0856; 5:UmDLrqbxvAeDSCXfhhu9VVpnzYzdYrbVhJN8ERV5WYvE9PT0f7g8Bi6FycFCa1AcGuPZkRQzKIdw7L2vmJVqqvbk0xiCLzA5lE3x+cGcZmVBf0sy+GkV36qzsdETtaRiqMPk0NpWIMzYThYybotpOQ==; 24:IU8exDy3/5EbnY6BzMicKacSqSUkG8QoTY1akS5mLvSbQWakYs2ccQhcOdp7yZTk3T3Tlc1i70MGQbzq/WgR6G3UFHMCnpCbX791bx/a0Sw=; 20:ay6SXGKRwXeCwtJbGkeFKO6bDY1mCFEAMRoaMe382EPsYOWABuEKUTyhBhkqxPwW4qiHlThOlgXbV/zPPgsWkt8NtIbt2J40zT8H2TPsiRoGecfqTg79ej23Eplcx+d0+yyqyoSQLKKAtzP1dPIVkbIJ/WgZ3p34EbJRdBlAcP3eaIaOUKuAF6bcXuQotqunsMmiA1l9DepoCdxILHsFrkXeBrrCoZvygEgKqIDs63ScIriJkPdaYUz/vHdPLsLx SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Feb 2016 17:20:28.4562 (UTC) 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.222]; Helo=[atltwp02.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR12MB0856 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.4 required=5.0 tests=BAD_ENC_HEADER,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 Provides information about ASIC features and capabilities. Also provides access to ASIC resources such as VBIOS, GPIO and I2cAux Manager Signed-off-by: Harry Wentland Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/dal/dc/adapter/Makefile | 24 + .../gpu/drm/amd/dal/dc/adapter/adapter_service.c | 2089 ++++++++++++++++++++ .../gpu/drm/amd/dal/dc/adapter/adapter_service.h | 71 + .../adapter/dce110/hw_ctx_adapter_service_dce110.c | 304 +++ .../adapter/dce110/hw_ctx_adapter_service_dce110.h | 40 + .../diagnostics/hw_ctx_adapter_service_diag.c | 133 ++ .../diagnostics/hw_ctx_adapter_service_diag.h | 33 + .../amd/dal/dc/adapter/hw_ctx_adapter_service.c | 164 ++ .../amd/dal/dc/adapter/hw_ctx_adapter_service.h | 86 + .../drm/amd/dal/dc/adapter/wireless_data_source.c | 208 ++ .../drm/amd/dal/dc/adapter/wireless_data_source.h | 80 + 11 files changed, 3232 insertions(+) create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/Makefile create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c create mode 100644 drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/Makefile b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile new file mode 100644 index 000000000000..2c6ca7a513bd --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/Makefile @@ -0,0 +1,24 @@ +# +# Makefile for the 'adapter' sub-component of DAL. +# It provides the control and status of HW adapter. + +ADAPTER = adapter_service.o hw_ctx_adapter_service.o wireless_data_source.o + +AMD_DAL_ADAPTER = $(addprefix $(AMDDALPATH)/dc/adapter/,$(ADAPTER)) + +AMD_DAL_FILES += $(AMD_DAL_ADAPTER) + + +############################################################################### +# DCE 11x +############################################################################### + +ifdef CONFIG_DRM_AMD_DAL_DCE11_0 +AMD_DAL_FILES += $(AMDDALPATH)/dc/adapter/dce110/hw_ctx_adapter_service_dce110.o +endif + +############################################################################### +# FPGA Diagnositcs +############################################################################### + +AMD_DAL_FILES += $(AMDDALPATH)/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.o diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c new file mode 100644 index 000000000000..dd2f931fe9a1 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.c @@ -0,0 +1,2089 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "dm_services.h" + +#include "dc_bios_types.h" + +#include "include/adapter_service_interface.h" +#include "include/i2caux_interface.h" +#include "include/asic_capability_types.h" +#include "include/gpio_service_interface.h" +#include "include/asic_capability_interface.h" +#include "include/logger_interface.h" + +#include "adapter_service.h" + +#include "hw_ctx_adapter_service.h" +#include "wireless_data_source.h" + +#include "atom.h" + +#if defined(CONFIG_DRM_AMD_DAL_DCE11_0) +#include "dce110/hw_ctx_adapter_service_dce110.h" +#endif + +#include "diagnostics/hw_ctx_adapter_service_diag.h" + +/* + * Adapter service feature entry table. + * + * This is an array of features that is used to generate feature set. Each + * entry consists three element: + * + * Feature name, default value, and if this feature is a boolean type. A + * feature can only be a boolean or int type. + * + * Example 1: a boolean type feature + * FEATURE_ENABLE_HW_EDID_POLLING, false, true + * + * First element is feature name: EATURE_ENABLE_HW_EDID_POLLING, it has a + * default value 0, and it is a boolean feature. + * + * Example 2: an int type feature + * FEATURE_DCP_PROGRAMMING_WA, 0x1FF7, false + * + * In this case, the default value is 0x1FF7 and not a boolean type, which + * makes it an int type. + */ + +static struct feature_source_entry feature_entry_table[] = { + /* Feature name | default value | is boolean type */ + {FEATURE_ENABLE_HW_EDID_POLLING, false, true}, + {FEATURE_DP_SINK_DETECT_POLL_DATA_PIN, false, true}, + {FEATURE_UNDERFLOW_INTERRUPT, false, true}, + {FEATURE_ALLOW_WATERMARK_ADJUSTMENT, false, true}, + {FEATURE_LIGHT_SLEEP, false, true}, + {FEATURE_DCP_DITHER_FRAME_RANDOM_ENABLE, false, true}, + {FEATURE_DCP_DITHER_RGB_RANDOM_ENABLE, false, true}, + {FEATURE_DCP_DITHER_HIGH_PASS_RANDOM_ENABLE, false, true}, + {FEATURE_LINE_BUFFER_ENHANCED_PIXEL_DEPTH, false, true}, + {FEATURE_MAXIMIZE_URGENCY_WATERMARKS, false, true}, + {FEATURE_MAXIMIZE_STUTTER_MARKS, false, true}, + {FEATURE_MAXIMIZE_NBP_MARKS, false, true}, + /* + * We meet HW I2C issue when test S3 resume on KB. + * An EPR is created for debug the issue. + * Make Test has already been implemented + * with HW I2C. The work load for revert back to SW I2C in make test + * is big. Below is workaround for this issue. + * Driver uses SW I2C. + * Make Test uses HW I2C. + */ + {FEATURE_RESTORE_USAGE_I2C_SW_ENGINE, false, true}, + {FEATURE_USE_MAX_DISPLAY_CLK, false, true}, + {FEATURE_ALLOW_EDP_RESOURCE_SHARING, false, true}, + {FEATURE_SUPPORT_DP_YUV, false, true}, + {FEATURE_SUPPORT_DP_Y_ONLY, false, true}, + {FEATURE_DISABLE_DP_GTC_SYNC, true, true}, + {FEATURE_MODIFY_TIMINGS_FOR_WIRELESS, false, true}, + {FEATURE_DCP_BIT_DEPTH_REDUCTION_MODE, 0, false}, + {FEATURE_DCP_DITHER_MODE, 0, false}, + {FEATURE_DCP_PROGRAMMING_WA, 0, false}, + {FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, false, true}, + {FEATURE_ENABLE_DFS_BYPASS, false, true}, + {FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT, false, true}, + {FEATURE_MAX_COFUNC_NON_DP_DISPLAYS, 2, false}, + {FEATURE_WIRELESS_LIMIT_720P, false, true}, + {FEATURE_MODIFY_TIMINGS_FOR_WIRELESS, false, true}, + {FEATURE_SUPPORTED_HDMI_CONNECTION_NUM, 0, false}, + {FEATURE_DETECT_REQUIRE_HPD_HIGH, false, true}, + {FEATURE_NO_HPD_LOW_POLLING_VCC_OFF, false, true}, + {FEATURE_LB_HIGH_RESOLUTION, false, true}, + {FEATURE_MAX_CONTROLLER_NUM, 0, false}, + {FEATURE_DRR_SUPPORT, AS_DRR_SUPPORT_ENABLED, false}, + {FEATURE_STUTTER_MODE, 15, false}, + {FEATURE_DP_DISPLAY_FORCE_SS_ENABLE, false, true}, + {FEATURE_REPORT_CE_MODE_ONLY, false, true}, + {FEATURE_ALLOW_OPTIMIZED_MODE_AS_DEFAULT, false, true}, + {FEATURE_DDC_READ_FORCE_REPEATED_START, false, true}, + {FEATURE_FORCE_TIMING_RESYNC, false, true}, + {FEATURE_TMDS_DISABLE_DITHERING, false, true}, + {FEATURE_HDMI_DISABLE_DITHERING, false, true}, + {FEATURE_DP_DISABLE_DITHERING, false, true}, + {FEATURE_EMBEDDED_DISABLE_DITHERING, true, true}, + {FEATURE_ALLOW_SELF_REFRESH, false, true}, + {FEATURE_ALLOW_DYNAMIC_PIXEL_ENCODING_CHANGE, false, true}, + {FEATURE_ALLOW_HSYNC_VSYNC_ADJUSTMENT, false, true}, + {FEATURE_FORCE_PSR, false, true}, + {FEATURE_PSR_SETUP_TIME_TEST, 0, false}, + {FEATURE_POWER_GATING_PIPE_IN_TILE, true, true}, + {FEATURE_POWER_GATING_LB_PORTION, true, true}, + {FEATURE_PREFER_3D_TIMING, false, true}, + {FEATURE_VARI_BRIGHT_ENABLE, true, true}, + {FEATURE_PSR_ENABLE, false, true}, + {FEATURE_WIRELESS_ENABLE_COMPRESSED_AUDIO, false, true}, + {FEATURE_WIRELESS_INCLUDE_UNVERIFIED_TIMINGS, true, true}, + {FEATURE_EDID_STRESS_READ, false, true}, + {FEATURE_DP_FRAME_PACK_STEREO3D, false, true}, + {FEATURE_DISPLAY_PREFERRED_VIEW, 0, false}, + {FEATURE_ALLOW_HDMI_WITHOUT_AUDIO, false, true}, + {FEATURE_ABM_2_0, false, true}, + {FEATURE_SUPPORT_MIRABILIS, false, true}, + {FEATURE_OPTIMIZATION, 0xFFFF, false}, + {FEATURE_PERF_MEASURE, 0, false}, + {FEATURE_MIN_BACKLIGHT_LEVEL, 0, false}, + {FEATURE_MAX_BACKLIGHT_LEVEL, 255, false}, + {FEATURE_LOAD_DMCU_FIRMWARE, true, true}, + {FEATURE_DISABLE_AZ_CLOCK_GATING, false, true}, + {FEATURE_ENABLE_GPU_SCALING, false, true}, + {FEATURE_DONGLE_SINK_COUNT_CHECK, true, true}, + {FEATURE_INSTANT_UP_SCALE_DOWN_SCALE, false, true}, + {FEATURE_TILED_DISPLAY, false, true}, + {FEATURE_PREFERRED_ABM_CONFIG_SET, 0, false}, + {FEATURE_CHANGE_SW_I2C_SPEED, 50, false}, + {FEATURE_CHANGE_HW_I2C_SPEED, 50, false}, + {FEATURE_CHANGE_I2C_SPEED_CONTROL, false, true}, + {FEATURE_DEFAULT_PSR_LEVEL, 0, false}, + {FEATURE_MAX_CLOCK_SOURCE_NUM, 0, false}, + {FEATURE_REPORT_SINGLE_SELECTED_TIMING, false, true}, + {FEATURE_ALLOW_HDMI_HIGH_CLK_DP_DONGLE, true, true}, + {FEATURE_SUPPORT_EXTERNAL_PANEL_DRR, false, true}, + {FEATURE_LVDS_SAFE_PIXEL_CLOCK_RANGE, 0, false}, + {FEATURE_ABM_CONFIG, 0, false}, + {FEATURE_WIRELESS_ENABLE, false, true}, + {FEATURE_ALLOW_DIRECT_MEMORY_ACCESS_TRIG, false, true}, + {FEATURE_FORCE_STATIC_SCREEN_EVENT_TRIGGERS, 0, false}, + {FEATURE_USE_PPLIB, true, true}, + {FEATURE_DISABLE_LPT_SUPPORT, false, true}, + {FEATURE_DUMMY_FBC_BACKEND, false, true}, + {FEATURE_DPMS_AUDIO_ENDPOINT_CONTROL, true, true}, + {FEATURE_DISABLE_FBC_COMP_CLK_GATE, false, true}, + {FEATURE_PIXEL_PERFECT_OUTPUT, false, true}, + {FEATURE_8BPP_SUPPORTED, false, true} +}; + + +/* Stores entire ASIC features by sets */ +uint32_t adapter_feature_set[FEATURE_MAXIMUM/32]; + +enum { + LEGACY_MAX_NUM_OF_CONTROLLERS = 2, + DEFAULT_NUM_COFUNC_NON_DP_DISPLAYS = 2 +}; + +/* + * get_feature_entries_num + * + * Get number of feature entries + */ +static inline uint32_t get_feature_entries_num(void) +{ + return ARRAY_SIZE(feature_entry_table); +} + +static void get_platform_info_methods( + struct adapter_service *as) +{ + struct platform_info_params params; + uint32_t mask = 0; + + params.data = &mask; + params.method = PM_GET_AVAILABLE_METHODS; + + if (dm_get_platform_info(as->ctx, ¶ms)) + as->platform_methods_mask = mask; + + +} + +static void initialize_backlight_caps( + struct adapter_service *as) +{ + struct firmware_info fw_info; + struct embedded_panel_info panel_info; + struct platform_info_ext_brightness_caps caps; + struct platform_info_params params; + bool custom_curve_present = false; + bool custom_min_max_present = false; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (!(PM_GET_EXTENDED_BRIGHNESS_CAPS & as->platform_methods_mask)) { + dal_logger_write(as->ctx->logger, + LOG_MAJOR_BACKLIGHT, + LOG_MINOR_BACKLIGHT_BRIGHTESS_CAPS, + "This method is not supported\n"); + return; + } + + if (dcb->funcs->get_firmware_info(dcb, &fw_info) != BP_RESULT_OK || + dcb->funcs->get_embedded_panel_info(dcb, &panel_info) != BP_RESULT_OK) + return; + + params.data = ∩︀ + params.method = PM_GET_EXTENDED_BRIGHNESS_CAPS; + + if (dm_get_platform_info(as->ctx, ¶ms)) { + as->ac_level_percentage = caps.basic_caps.ac_level_percentage; + as->dc_level_percentage = caps.basic_caps.dc_level_percentage; + custom_curve_present = (caps.data_points_num > 0); + custom_min_max_present = true; + } else + return; + /* Choose minimum backlight level base on priority: + * extended caps,VBIOS,default */ + if (custom_min_max_present) + as->backlight_8bit_lut[0] = caps.min_input_signal; + + else if (fw_info.min_allowed_bl_level > 0) + as->backlight_8bit_lut[0] = fw_info.min_allowed_bl_level; + + else + as->backlight_8bit_lut[0] = DEFAULT_MIN_BACKLIGHT; + + /* Choose maximum backlight level base on priority: + * extended caps,default */ + if (custom_min_max_present) + as->backlight_8bit_lut[100] = caps.max_input_signal; + + else + as->backlight_8bit_lut[100] = DEFAULT_MAX_BACKLIGHT; + + if (as->backlight_8bit_lut[100] > ABSOLUTE_BACKLIGHT_MAX) + as->backlight_8bit_lut[100] = ABSOLUTE_BACKLIGHT_MAX; + + if (as->backlight_8bit_lut[0] > as->backlight_8bit_lut[100]) + as->backlight_8bit_lut[0] = as->backlight_8bit_lut[100]; + + if (custom_curve_present) { + uint16_t index = 1; + uint16_t i; + uint16_t num_of_data_points = (caps.data_points_num <= 99 ? + caps.data_points_num : 99); + /* Filling translation table from data points - + * between every two provided data points we + * lineary interpolate missing values + */ + for (i = 0 ; i < num_of_data_points; i++) { + uint16_t luminance = caps.data_points[i].luminance; + uint16_t signal_level = + caps.data_points[i].signal_level; + + if (signal_level < as->backlight_8bit_lut[0]) + signal_level = as->backlight_8bit_lut[0]; + + if (signal_level > as->backlight_8bit_lut[100]) + signal_level = as->backlight_8bit_lut[100]; + + /* Lineary interpolate missing values */ + if (index < luminance) { + uint16_t base_value = + as->backlight_8bit_lut[index-1]; + uint16_t delta_signal = + signal_level - base_value; + uint16_t delta_luma = luminance - index + 1; + uint16_t step = delta_signal; + + for (; index < luminance ; index++) { + as->backlight_8bit_lut[index] = + base_value + + (step / delta_luma); + step += delta_signal; + } + } + /* Now [index == luminance], so we can add + * data point to the translation table */ + as->backlight_8bit_lut[index++] = signal_level; + } + /* Complete the final segment of interpolation - + * between last datapoint and maximum value */ + if (index < 100) { + uint16_t base_value = as->backlight_8bit_lut[index-1]; + uint16_t delta_signal = + as->backlight_8bit_lut[100]-base_value; + uint16_t delta_luma = 100 - index + 1; + uint16_t step = delta_signal; + + for (; index < 100 ; index++) { + as->backlight_8bit_lut[index] = base_value + + (step / delta_luma); + step += delta_signal; + } + } + } + /* build backlight translation table based on default curve */ + else { + /* Default backlight curve can be defined by + * polinomial F(x) = A(x*x) + Bx + C. + * Backlight curve should always satisfy + * F(0) = min, F(100) = max, so polinomial coefficients are: + * A is 0.0255 - B/100 - min/10000 - + * (255-max)/10000 = (max - min)/10000 - B/100 + * B is adjustable factor to modify the curve. + * Bigger B results in less concave curve. + * B range is [0..(max-min)/100] + * C is backlight minimum + */ + uint16_t delta = as->backlight_8bit_lut[100] - + as->backlight_8bit_lut[0]; + uint16_t coeffc = as->backlight_8bit_lut[0]; + uint16_t coeffb = (BACKLIGHT_CURVE_COEFFB < delta ? + BACKLIGHT_CURVE_COEFFB : delta); + uint16_t coeffa = delta - coeffb; + uint16_t i; + uint32_t temp; + + for (i = 1; i < 100 ; i++) { + temp = (coeffa * i * i) / BACKLIGHT_CURVE_COEFFA_FACTOR; + as->backlight_8bit_lut[i] = temp + (coeffb * i) / + BACKLIGHT_CURVE_COEFFB_FACTOR + coeffc; + } + } + as->backlight_caps_initialized = true; +} + +static void log_overriden_features( + struct adapter_service *as, + const char *feature_name, + enum adapter_feature_id id, + bool bool_feature, + uint32_t value) +{ + if (bool_feature) + dal_logger_write(as->ctx->logger, + LOG_MAJOR_FEATURE_OVERRIDE, + LOG_MINOR_FEATURE_OVERRIDE, + "Overridden %s is %s now\n", + feature_name, + (value == 0) ? "disabled" : "enabled"); + else + dal_logger_write(as->ctx->logger, + LOG_MAJOR_FEATURE_OVERRIDE, + LOG_MINOR_FEATURE_OVERRIDE, + "Overridden %s new value: %d\n", + feature_name, + value); +} + +/************************************* + * Local static functions definition * + *************************************/ + +#define check_bool_feature(feature) \ +case FEATURE_ ## feature: \ + if (param->bool_param_enable_mask & \ + (1 << DAL_PARAM_ ## feature)) { \ + *data = param->bool_param_values & \ + (1 << DAL_PARAM_ ## feature); \ + ret = true; \ + feature_name = "FEATURE_" #feature; \ + } \ + break + +#define check_int_feature(feature) \ +case FEATURE_ ## feature: \ + if (param->int_param_values[DAL_PARAM_ ## feature] != \ + DAL_PARAM_INVALID_INT) { \ + *data = param->int_param_values[DAL_PARAM_ ## feature];\ + ret = true;\ + bool_feature = false;\ + feature_name = "FEATURE_" #feature;\ + } \ + break + +/* + * override_default_parameters + * + * Override features (from runtime parameter) + * corresponding to Adapter Service Feature ID + */ +static bool override_default_parameters( + struct adapter_service *as, + const struct dal_override_parameters *param, + const uint32_t idx, + uint32_t *data) +{ + bool ret = false; + bool bool_feature = true; + char *feature_name; + + if (idx >= get_feature_entries_num()) { + ASSERT_CRITICAL(false); + return false; + } + + switch (feature_entry_table[idx].feature_id) { + check_int_feature(MAX_COFUNC_NON_DP_DISPLAYS); + check_int_feature(DRR_SUPPORT); + check_bool_feature(LIGHT_SLEEP); + check_bool_feature(MAXIMIZE_STUTTER_MARKS); + check_bool_feature(MAXIMIZE_URGENCY_WATERMARKS); + check_bool_feature(USE_MAX_DISPLAY_CLK); + check_bool_feature(ENABLE_DFS_BYPASS); + check_bool_feature(POWER_GATING_PIPE_IN_TILE); + check_bool_feature(POWER_GATING_LB_PORTION); + check_bool_feature(PSR_ENABLE); + check_bool_feature(VARI_BRIGHT_ENABLE); + check_bool_feature(USE_PPLIB); + check_bool_feature(DISABLE_LPT_SUPPORT); + check_bool_feature(DUMMY_FBC_BACKEND); + check_bool_feature(ENABLE_GPU_SCALING); + default: + return false; + } + if (ret) + log_overriden_features( + as, + feature_name, + feature_entry_table[idx].feature_id, + bool_feature, + *data); + + return ret; +} + +/* + * get_feature_value_from_data_sources + * + * For a given feature, determine its value from ASIC cap and wireless + * data source. + * idx : index of feature_entry_table for the feature id. + */ +static bool get_feature_value_from_data_sources( + const struct adapter_service *as, + const uint32_t idx, + uint32_t *data) +{ + if (idx >= get_feature_entries_num()) { + ASSERT_CRITICAL(false); + return false; + } + + switch (feature_entry_table[idx].feature_id) { + case FEATURE_MAX_COFUNC_NON_DP_DISPLAYS: + *data = as->asic_cap->data[ASIC_DATA_MAX_COFUNC_NONDP_DISPLAYS]; + break; + + case FEATURE_WIRELESS_LIMIT_720P: + *data = as->asic_cap->caps.WIRELESS_LIMIT_TO_720P; + break; + + case FEATURE_WIRELESS_FULL_TIMING_ADJUSTMENT: + *data = as->asic_cap->caps.WIRELESS_FULL_TIMING_ADJUSTMENT; + break; + + case FEATURE_MODIFY_TIMINGS_FOR_WIRELESS: + *data = as->asic_cap->caps.WIRELESS_TIMING_ADJUSTMENT; + break; + + case FEATURE_SUPPORTED_HDMI_CONNECTION_NUM: + *data = + as->asic_cap->data[ASIC_DATA_SUPPORTED_HDMI_CONNECTION_NUM]; + break; + + case FEATURE_DETECT_REQUIRE_HPD_HIGH: + *data = as->asic_cap->caps.HPD_CHECK_FOR_EDID; + break; + + case FEATURE_NO_HPD_LOW_POLLING_VCC_OFF: + *data = as->asic_cap->caps.NO_VCC_OFF_HPD_POLLING; + break; + + case FEATURE_STUTTER_MODE: + *data = as->asic_cap->data[ASIC_DATA_STUTTERMODE]; + break; + + case FEATURE_WIRELESS_ENABLE: + *data = as->wireless_data.wireless_enable; + break; + + case FEATURE_8BPP_SUPPORTED: + *data = as->asic_cap->caps.SUPPORT_8BPP; + break; + + default: + return false; + } + + return true; +} + +/* get_bool_value + * + * Get the boolean value of a given feature + */ +static bool get_bool_value( + const uint32_t set, + const uint32_t idx) +{ + if (idx >= 32) { + ASSERT_CRITICAL(false); + return false; + } + + return ((set & (1 << idx)) != 0); +} + +/* + * get_hpd_info + * + * Get HPD information from BIOS + */ +static bool get_hpd_info(struct adapter_service *as, + struct graphics_object_id id, + struct graphics_object_hpd_info *info) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + return BP_RESULT_OK == dcb->funcs->get_hpd_info(dcb, id, info); +} + +/* + * lookup_feature_entry + * + * Find the entry index of a given feature in feature table + */ +static uint32_t lookup_feature_entry( + enum adapter_feature_id feature_id) +{ + uint32_t entries_num = get_feature_entries_num(); + uint32_t i = 0; + + while (i != entries_num) { + if (feature_entry_table[i].feature_id == feature_id) + break; + + ++i; + } + + return i; +} + +/* + * set_bool_value + * + * Set the boolean value of a given feature + */ +static void set_bool_value( + uint32_t *set, + const uint32_t idx, + bool value) +{ + if (idx >= 32) { + ASSERT_CRITICAL(false); + return; + } + + if (value) + *set |= (1 << idx); + else + *set &= ~(1 << idx); +} + +/* + * generate_feature_set + * + * Generate the internal feature set from multiple data sources + */ +static bool generate_feature_set( + struct adapter_service *as, + const struct dal_override_parameters *param) +{ + uint32_t i = 0; + uint32_t value = 0; + uint32_t set_idx = 0; + uint32_t internal_idx = 0; + uint32_t entry_num = 0; + const struct feature_source_entry *entry = NULL; + + dm_memset(adapter_feature_set, 0, sizeof(adapter_feature_set)); + entry_num = get_feature_entries_num(); + + + while (i != entry_num) { + entry = &feature_entry_table[i]; + + if (entry->feature_id <= FEATURE_UNKNOWN || + entry->feature_id >= FEATURE_MAXIMUM) { + ASSERT_CRITICAL(false); + return false; + } + + set_idx = (uint32_t)((entry->feature_id - 1) / 32); + internal_idx = (uint32_t)((entry->feature_id - 1) % 32); + + /* TODO: wireless, runtime parameter, vbios */ + if (!override_default_parameters(as, param, i, &value)) { + if (!get_feature_value_from_data_sources( + as, i, &value)) { + /* + * Can't find feature values from + * above data sources + * Assign default value + */ + value = entry->default_value; + } + } + + if (entry->is_boolean_type) + set_bool_value(&adapter_feature_set[set_idx], + internal_idx, + value != 0); + else + adapter_feature_set[set_idx] = value; + + i++; + } + + return true; +} + + +/* + * create_hw_ctx + * + * Create HW context for adapter service. This is DCE specific. + */ +static struct hw_ctx_adapter_service *create_hw_ctx( + enum dce_version dce_version, + enum dce_environment dce_environment, + struct dc_context *ctx) +{ + if (IS_FPGA_MAXIMUS_DC(dce_environment)) + return dal_adapter_service_create_hw_ctx_diag(ctx); + + switch (dce_version) { +#if defined(CONFIG_DRM_AMD_DAL_DCE10_0) + case DCE_VERSION_10_0: + return dal_adapter_service_create_hw_ctx_dce110(ctx); +#endif +#if defined(CONFIG_DRM_AMD_DAL_DCE11_0) + case DCE_VERSION_11_0: + return dal_adapter_service_create_hw_ctx_dce110(ctx); +#endif + default: + ASSERT_CRITICAL(false); + return NULL; + } +} + +/* + * adapter_service_destruct + * + * Release memory of objects in adapter service + */ +static void adapter_service_destruct( + struct adapter_service *as) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + dal_adapter_service_destroy_hw_ctx(&as->hw_ctx); + dal_i2caux_destroy(&as->i2caux); + dal_gpio_service_destroy(&as->gpio_service); + dal_asic_capability_destroy(&as->asic_cap); + + dcb->funcs->destroy_integrated_info(dcb, &as->integrated_info); + + if (as->dcb_internal) { + /* We are responsible only for destruction of Internal BIOS. + * The External one will be destroyed by its creator. */ + dal_bios_parser_destroy(&as->dcb_internal); + } +} + +/* + * adapter_service_construct + * + * Construct the derived type of adapter service + */ +static bool adapter_service_construct( + struct adapter_service *as, + struct as_init_data *init_data) +{ + struct dc_bios *dcb; + enum dce_version dce_version; + + if (!init_data) + return false; + + /* Create ASIC capability */ + as->ctx = init_data->ctx; + as->asic_cap = dal_asic_capability_create( + &init_data->hw_init_data, as->ctx); + + if (!as->asic_cap) { + ASSERT_CRITICAL(false); + return false; + } + +#if defined(CONFIG_DRM_AMD_DAL_DCE11_0) + if (dal_adapter_service_get_dce_version(as) == DCE_VERSION_11_0) { + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(feature_entry_table); i++) { + enum adapter_feature_id id = + feature_entry_table[i].feature_id; + if (id == FEATURE_MAXIMIZE_URGENCY_WATERMARKS || + id == FEATURE_MAXIMIZE_STUTTER_MARKS || + id == FEATURE_MAXIMIZE_NBP_MARKS) + feature_entry_table[i].default_value = true; + } + } +#endif + + /* Generate feature set table */ + if (!generate_feature_set(as, init_data->display_param)) { + ASSERT_CRITICAL(false); + goto failed_to_generate_features; + } + + as->dce_environment = init_data->dce_environment; + + if (init_data->vbios_override) + as->dcb_override = init_data->vbios_override; + else { + /* Create BIOS parser */ + init_data->bp_init_data.ctx = init_data->ctx; + + as->dcb_internal = dal_bios_parser_create( + &init_data->bp_init_data, as); + + if (!as->dcb_internal) { + ASSERT_CRITICAL(false); + goto failed_to_create_bios_parser; + } + } + + dcb = dal_adapter_service_get_bios_parser(as); + + dce_version = dal_adapter_service_get_dce_version(as); + + /* Create GPIO service */ + as->gpio_service = dal_gpio_service_create( + dce_version, + as->dce_environment, + as->ctx); + + if (!as->gpio_service) { + ASSERT_CRITICAL(false); + goto failed_to_create_gpio_service; + } + + /* Create I2C AUX */ + as->i2caux = dal_i2caux_create(as, as->ctx); + + if (!as->i2caux) { + ASSERT_CRITICAL(false); + goto failed_to_create_i2caux; + } + + /* Create Adapter Service HW Context*/ + as->hw_ctx = create_hw_ctx( + dce_version, + as->dce_environment, + as->ctx); + + if (!as->hw_ctx) { + ASSERT_CRITICAL(false); + goto failed_to_create_hw_ctx; + } + + /* Avoid wireless encoder creation in upstream branch. */ + + /* Integrated info is not provided on discrete ASIC. NULL is allowed */ + as->integrated_info = dcb->funcs->create_integrated_info(dcb); + + dcb->funcs->post_init(dcb); + + /* Generate backlight translation table and initializes + other brightness properties */ + as->backlight_caps_initialized = false; + + get_platform_info_methods(as); + + initialize_backlight_caps(as); + + return true; + +failed_to_generate_features: + dal_adapter_service_destroy_hw_ctx(&as->hw_ctx); + +failed_to_create_hw_ctx: + dal_i2caux_destroy(&as->i2caux); + +failed_to_create_i2caux: + dal_gpio_service_destroy(&as->gpio_service); + +failed_to_create_gpio_service: + if (as->dcb_internal) + dal_bios_parser_destroy(&as->dcb_internal); + +failed_to_create_bios_parser: + dal_asic_capability_destroy(&as->asic_cap); + + return false; +} + +/* + * Global function definition + */ + +/* + * dal_adapter_service_create + * + * Create adapter service + */ +struct adapter_service *dal_adapter_service_create( + struct as_init_data *init_data) +{ + struct adapter_service *as; + + as = dm_alloc(init_data->ctx, sizeof(struct adapter_service)); + + if (!as) { + ASSERT_CRITICAL(false); + return NULL; + } + + if (adapter_service_construct(as, init_data)) + return as; + + ASSERT_CRITICAL(false); + + dm_free(init_data->ctx, as); + + return NULL; +} + +/* + * dal_adapter_service_destroy + * + * Destroy adapter service and objects it contains + */ +void dal_adapter_service_destroy( + struct adapter_service **as) +{ + if (!as) { + ASSERT_CRITICAL(false); + return; + } + + if (!*as) { + ASSERT_CRITICAL(false); + return; + } + + adapter_service_destruct(*as); + + dm_free((*as)->ctx, *as); + + *as = NULL; +} + +/* + * dal_adapter_service_get_dce_version + * + * Get the DCE version of current ASIC + */ +enum dce_version dal_adapter_service_get_dce_version( + const struct adapter_service *as) +{ + uint32_t version = as->asic_cap->data[ASIC_DATA_DCE_VERSION]; + + switch (version) { +#if defined(CONFIG_DRM_AMD_DAL_DCE10_0) + case 0x100: + return DCE_VERSION_10_0; +#endif +#if defined(CONFIG_DRM_AMD_DAL_DCE11_0) + case 0x110: + return DCE_VERSION_11_0; +#endif + default: + ASSERT_CRITICAL(false); + return DCE_VERSION_UNKNOWN; + } +} + +enum dce_environment dal_adapter_service_get_dce_environment( + const struct adapter_service *as) +{ + return as->dce_environment; +} + + +/* + * dal_adapter_service_get_controllers_num + * + * Get number of controllers + */ +uint8_t dal_adapter_service_get_controllers_num( + struct adapter_service *as) +{ + uint32_t result = as->asic_cap->data[ASIC_DATA_CONTROLLERS_NUM]; + + /* Check the "max num of controllers" feature, + * use it for debugging purposes only */ + /* TODO implement + * dal_adapter_service_get_feature_value(as, ) */ + + return result; +} + +/** Get total number of connectors. + * + * \param as Adapter Service + * + * \return Total number of connectors. It is up-to-the caller to decide + * if the number is valid. + */ +uint8_t dal_adapter_service_get_connectors_num( + struct adapter_service *as) +{ + uint8_t vbios_connectors_num = 0; + uint8_t wireless_connectors_num = 0; + struct dc_bios *dcb; + + dcb = dal_adapter_service_get_bios_parser(as); + + vbios_connectors_num = dcb->funcs->get_connectors_number(dcb); + + wireless_connectors_num = wireless_get_connectors_num(as); + + return vbios_connectors_num + wireless_connectors_num; +} + +static bool is_wireless_object(struct graphics_object_id id) +{ + if ((id.type == OBJECT_TYPE_ENCODER && + id.id == ENCODER_ID_INTERNAL_WIRELESS) || + (id.type == OBJECT_TYPE_CONNECTOR && id.id == + CONNECTOR_ID_WIRELESS) || + (id.type == OBJECT_TYPE_CONNECTOR && id.id == + CONNECTOR_ID_MIRACAST)) + return true; + return false; +} + +/** + * Get the number of source objects of an object + * + * \param [in] as: Adapter Service + * + * \param [in] id: The graphics object id + * + * \return + * The number of the source objects of an object + */ +uint32_t dal_adapter_service_get_src_num( + struct adapter_service *as, struct graphics_object_id id) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (is_wireless_object(id)) + return wireless_get_srcs_num(as, id); + else + return dcb->funcs->get_src_number(dcb, id); +} + +/** + * Get the source objects of an object + * + * \param [in] id The graphics object id + * \param [in] index Enumerating index which starts at 0 + * + * \return If enumerating successfully, return the VALID source object id, + * otherwise, returns "zeroed out" object id. + * Client should call dal_graphics_object_id_is_valid() to check + * weather the id is valid. + */ +struct graphics_object_id dal_adapter_service_get_src_obj( + struct adapter_service *as, + struct graphics_object_id id, + uint32_t index) +{ + struct graphics_object_id src_object_id; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (is_wireless_object(id)) + src_object_id = wireless_get_src_obj_id(as, id, index); + else { + if (BP_RESULT_OK != dcb->funcs->get_src_obj(dcb, id, index, + &src_object_id)) { + src_object_id = + dal_graphics_object_id_init( + 0, + ENUM_ID_UNKNOWN, + OBJECT_TYPE_UNKNOWN); + } + } + + return src_object_id; +} + +/** Get connector object id associated with a connector index. + * + * \param as Adapter Service + * + * \param connector_index Index of connector between zero and total number + * returned by dal_adapter_service_get_connectors_num() + * + * \return graphics object id corresponding to the connector_index. + */ +struct graphics_object_id dal_adapter_service_get_connector_obj_id( + struct adapter_service *as, + uint8_t connector_index) +{ + struct dc_bios *dcb; + uint8_t bios_connectors_num; + + dcb = dal_adapter_service_get_bios_parser(as); + + bios_connectors_num = dcb->funcs->get_connectors_number(dcb); + + if (connector_index >= bios_connectors_num) + return wireless_get_connector_id(as, connector_index); + else + return dcb->funcs->get_connector_id(dcb, connector_index); +} + +bool dal_adapter_service_get_device_tag( + struct adapter_service *as, + struct graphics_object_id connector_object_id, + uint32_t device_tag_index, + struct connector_device_tag_info *info) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (BP_RESULT_OK == dcb->funcs->get_device_tag(dcb, + connector_object_id, device_tag_index, info)) + return true; + else + return false; +} + +/* Check if DeviceId is supported by ATOM_OBJECT_HEADER support info */ +bool dal_adapter_service_is_device_id_supported(struct adapter_service *as, + struct device_id id) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + return dcb->funcs->is_device_id_supported(dcb, id); +} + +bool dal_adapter_service_is_meet_underscan_req(struct adapter_service *as) +{ + struct firmware_info fw_info; + enum bp_result bp_result = dal_adapter_service_get_firmware_info( + as, &fw_info); + uint32_t disp_clk_limit = + as->asic_cap->data[ASIC_DATA_MIN_DISPCLK_FOR_UNDERSCAN]; + if (BP_RESULT_OK == bp_result) { + dal_logger_write(as->ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_ADAPTER_SERVICE, + "Read firmware is NULL"); + return false; + } + if (fw_info.default_display_engine_pll_frequency < disp_clk_limit) + return false; + return true; +} + +bool dal_adapter_service_underscan_for_hdmi_only(struct adapter_service *as) +{ + return as->asic_cap->caps.UNDERSCAN_FOR_HDMI_ONLY; +} +/* + * dal_adapter_service_get_clock_sources_num + * + * Get number of clock sources + */ +uint8_t dal_adapter_service_get_clock_sources_num( + struct adapter_service *as) +{ + struct firmware_info fw_info; + uint32_t max_clk_src = 0; + uint32_t num = as->asic_cap->data[ASIC_DATA_CLOCKSOURCES_NUM]; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + /* + * Check is system supports the use of the External clock source + * as a clock source for DP + */ + enum bp_result bp_result = dcb->funcs->get_firmware_info(dcb, &fw_info); + + if (BP_RESULT_OK == bp_result && + fw_info.external_clock_source_frequency_for_dp != 0) + ++num; + + /* + * Add clock source for wireless if supported + */ + num += (uint32_t)wireless_get_clocks_num(as); + + /* Check the "max number of clock sources" feature */ + if (dal_adapter_service_get_feature_value( + FEATURE_MAX_CLOCK_SOURCE_NUM, + &max_clk_src, + sizeof(uint32_t))) + if ((max_clk_src != 0) && (max_clk_src < num)) + num = max_clk_src; + + return num; +} + +/* + * dal_adapter_service_get_func_controllers_num + * + * Get number of controllers + */ +uint8_t dal_adapter_service_get_func_controllers_num( + struct adapter_service *as) +{ + uint32_t result = + as->asic_cap->data[ASIC_DATA_FUNCTIONAL_CONTROLLERS_NUM]; + + /* Check the "max num of controllers" feature, + * use it for debugging purposes only */ + + /* Limit number of controllers by OS */ + + struct asic_feature_flags flags; + + flags.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS]; + + if (flags.bits.LEGACY_CLIENT && + (result > LEGACY_MAX_NUM_OF_CONTROLLERS)) + result = LEGACY_MAX_NUM_OF_CONTROLLERS; + + return result; +} + +/* + * dal_adapter_service_is_feature_supported + * + * Return if a given feature is supported by the ASIC. The feature has to be + * a boolean type. + */ +bool dal_adapter_service_is_feature_supported( + enum adapter_feature_id feature_id) +{ + bool data = 0; + + dal_adapter_service_get_feature_value(feature_id, &data, sizeof(bool)); + + return data; +} + +/** + * Reports maximum number of confunctional non-DP displays. + * Value can be overriden if FEATURE_REPORT_SINGLE_SELECTED_TIMING feature is + * enabled. + * + * \return + * Maximum number of confunctional non-DP displays + */ +uint32_t dal_adapter_service_get_max_cofunc_non_dp_displays(void) +{ + uint32_t non_dp_displays = DEFAULT_NUM_COFUNC_NON_DP_DISPLAYS; + + if (true == dal_adapter_service_get_feature_value( + FEATURE_MAX_COFUNC_NON_DP_DISPLAYS, + &non_dp_displays, + sizeof(non_dp_displays))) { + /* the cached value exist */ + /* TODO: add more logic as per-DAL2 */ + } + + return non_dp_displays; +} + +uint32_t dal_adapter_service_get_single_selected_timing_signals(void) +{ + uint32_t signals_bitmap = 0; + + if (dal_adapter_service_is_feature_supported( + FEATURE_REPORT_SINGLE_SELECTED_TIMING)) { + /* the cached value exist */ + /* TODO: add more logic as per-DAL2 */ + signals_bitmap = 0; + } + + return signals_bitmap; +} + +/* + * dal_adapter_service_get_i2c_info + * + * Get I2C information from BIOS + */ +bool dal_adapter_service_get_i2c_info( + struct adapter_service *as, + struct graphics_object_id id, + struct graphics_object_i2c_info *i2c_info) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (!i2c_info) { + ASSERT_CRITICAL(false); + return false; + } + + return BP_RESULT_OK == dcb->funcs->get_i2c_info(dcb, id, i2c_info); +} + +/* + * dal_adapter_service_obtain_ddc + * + * Obtain DDC + */ +struct ddc *dal_adapter_service_obtain_ddc( + struct adapter_service *as, + struct graphics_object_id id) +{ + struct graphics_object_i2c_info i2c_info; + struct gpio_ddc_hw_info hw_info; + + + if (!dal_adapter_service_get_i2c_info(as, id, &i2c_info)) + return NULL; + + hw_info.ddc_channel = i2c_info.i2c_line; + hw_info.hw_supported = i2c_info.i2c_hw_assist; + + return dal_gpio_service_create_ddc( + as->gpio_service, + i2c_info.gpio_info.clk_a_register_index, + 1 << i2c_info.gpio_info.clk_a_shift, + &hw_info); +} + +/* + * dal_adapter_service_release_ddc + * + * Release DDC + */ +void dal_adapter_service_release_ddc( + struct adapter_service *as, + struct ddc *ddc) +{ + dal_gpio_service_destroy_ddc(&ddc); +} + +/* + * dal_adapter_service_obtain_hpd_irq + * + * Obtain HPD interrupt request + */ +struct irq *dal_adapter_service_obtain_hpd_irq( + struct adapter_service *as, + struct graphics_object_id id) +{ + enum bp_result bp_result; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + struct graphics_object_hpd_info hpd_info; + struct gpio_pin_info pin_info; + + if (!get_hpd_info(as, id, &hpd_info)) + return NULL; + + bp_result = dcb->funcs->get_gpio_pin_info(dcb, + hpd_info.hpd_int_gpio_uid, &pin_info); + + if (bp_result != BP_RESULT_OK) { + ASSERT(bp_result == BP_RESULT_NORECORD); + return NULL; + } + + return dal_gpio_service_create_irq( + as->gpio_service, + pin_info.offset, + pin_info.mask); +} + +/* + * dal_adapter_service_release_irq + * + * Release interrupt request + */ +void dal_adapter_service_release_irq( + struct adapter_service *as, + struct irq *irq) +{ + dal_gpio_service_destroy_irq(&irq); +} + +/* + * dal_adapter_service_get_ss_info_num + * + * Get number of spread spectrum entries from BIOS + */ +uint32_t dal_adapter_service_get_ss_info_num( + struct adapter_service *as, + enum as_signal_type signal) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + return dcb->funcs->get_ss_entry_number(dcb, signal); +} + +/* + * dal_adapter_service_get_ss_info + * + * Get spread spectrum info from BIOS + */ +bool dal_adapter_service_get_ss_info( + struct adapter_service *as, + enum as_signal_type signal, + uint32_t idx, + struct spread_spectrum_info *info) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + enum bp_result bp_result = dcb->funcs->get_spread_spectrum_info(dcb, + signal, idx, info); + + return BP_RESULT_OK == bp_result; +} + +/* + * dal_adapter_service_get_integrated_info + * + * Get integrated information on BIOS + */ +bool dal_adapter_service_get_integrated_info( + struct adapter_service *as, + struct integrated_info *info) +{ + if (info == NULL || as->integrated_info == NULL) + return false; + + dm_memmove(info, as->integrated_info, sizeof(struct integrated_info)); + + return true; +} + +/* + * dal_adapter_service_is_dfs_bypass_enabled + * + * Check if DFS bypass is enabled + */ +bool dal_adapter_service_is_dfs_bypass_enabled( + struct adapter_service *as) +{ + if (as->integrated_info == NULL) + return false; + if ((as->integrated_info->gpu_cap_info & DFS_BYPASS_ENABLE) && + dal_adapter_service_is_feature_supported( + FEATURE_ENABLE_DFS_BYPASS)) + return true; + else + return false; +} + +/* + * dal_adapter_service_get_sw_i2c_speed + * + * Get SW I2C speed + */ +uint32_t dal_adapter_service_get_sw_i2c_speed( + struct adapter_service *as) +{ + /* TODO: only from ASIC caps. Feature key is not implemented*/ + return as->asic_cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ]; +} + +/* + * dal_adapter_service_get_hw_i2c_speed + * + * Get HW I2C speed + */ +uint32_t dal_adapter_service_get_hw_i2c_speed( + struct adapter_service *as) +{ + /* TODO: only from ASIC caps. Feature key is not implemented*/ + return as->asic_cap->data[ASIC_DATA_DEFAULT_I2C_SPEED_IN_KHZ]; +} + +/* + * dal_adapter_service_get_mc_latency + * + * Get memory controller latency + */ +uint32_t dal_adapter_service_get_mc_latency( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_MC_LATENCY]; +} + +/* + * dal_adapter_service_get_asic_vram_bit_width + * + * Get the video RAM bit width set on the ASIC + */ +uint32_t dal_adapter_service_get_asic_vram_bit_width( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_VRAM_BITWIDTH]; +} + +/* + * dal_adapter_service_get_asic_bugs + * + * Get the bug flags set on this ASIC + */ +struct asic_bugs dal_adapter_service_get_asic_bugs( + struct adapter_service *as) +{ + return as->asic_cap->bugs; +} + + +struct dal_asic_runtime_flags dal_adapter_service_get_asic_runtime_flags( + struct adapter_service *as) +{ + return as->asic_cap->runtime_flags; +} + +/* + * dal_adapter_service_get_line_buffer_size + * + * Get line buffer size + */ +uint32_t dal_adapter_service_get_line_buffer_size( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_LINEBUFFER_SIZE]; +} + +/* + * dal_adapter_service_get_bandwidth_tuning_params + * + * Get parameters for bandwidth tuning + */ +bool dal_adapter_service_get_bandwidth_tuning_params( + struct adapter_service *as, + union bandwidth_tuning_params *params) +{ + /* TODO: add implementation */ + /* note: data comes from runtime parameters */ + return false; +} + +/* + * dal_adapter_service_get_feature_flags + * + * Get a copy of ASIC feature flags + */ +struct asic_feature_flags dal_adapter_service_get_feature_flags( + struct adapter_service *as) +{ + struct asic_feature_flags result = { { 0 } }; + + if (!as) { + ASSERT_CRITICAL(false); + return result; + } + + result.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS]; + + return result; +} + +/* + * dal_adapter_service_get_dram_bandwidth_efficiency + * + * Get efficiency of DRAM + */ +uint32_t dal_adapter_service_get_dram_bandwidth_efficiency( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_DRAM_BANDWIDTH_EFFICIENCY]; +} + +/* + * dal_adapter_service_obtain_gpio + * + * Obtain GPIO + */ +struct gpio *dal_adapter_service_obtain_gpio( + struct adapter_service *as, + enum gpio_id id, + uint32_t en) +{ + return dal_gpio_service_create_gpio_ex( + as->gpio_service, id, en, + GPIO_PIN_OUTPUT_STATE_DEFAULT); +} + +/* + * dal_adapter_service_obtain_stereo_gpio + * + * Obtain GPIO for stereo3D + */ +struct gpio *dal_adapter_service_obtain_stereo_gpio( + struct adapter_service *as) +{ + const bool have_param_stereo_gpio = false; + + struct asic_feature_flags result; + + result.raw = as->asic_cap->data[ASIC_DATA_FEATURE_FLAGS]; + + /* Case 1 : Workstation stereo */ + if (result.bits.WORKSTATION_STEREO) { + /* "active low" <--> "default 3d right eye polarity" = false */ + return dal_gpio_service_create_gpio_ex(as->gpio_service, + GPIO_ID_GENERIC, GPIO_GENERIC_A, + GPIO_PIN_OUTPUT_STATE_ACTIVE_LOW); + /* Case 2 : runtime parameter override for sideband stereo */ + } else if (have_param_stereo_gpio) { + /* TODO implement */ + return NULL; + /* Case 3 : VBIOS gives us GPIO for sideband stereo */ + } else { + const struct graphics_object_id id = + dal_graphics_object_id_init(GENERIC_ID_STEREO, + ENUM_ID_1, OBJECT_TYPE_GENERIC); + + struct bp_gpio_cntl_info cntl_info; + struct gpio_pin_info pin_info; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + /* Get GPIO record for this object. + * Stereo GPIO record should have exactly one entry + * where active state defines stereosync polarity */ + if (1 != dcb->funcs->get_gpio_record( + dcb, id, &cntl_info, + 1)) { + return NULL; + } else if (BP_RESULT_OK + != dcb->funcs->get_gpio_pin_info( + dcb, cntl_info.id, + &pin_info)) { + /*ASSERT_CRITICAL(false);*/ + return NULL; + } else { + return dal_gpio_service_create_gpio_ex(as->gpio_service, + pin_info.offset, pin_info.mask, + cntl_info.state); + } + } +} + +/* + * dal_adapter_service_release_gpio + * + * Release GPIO + */ +void dal_adapter_service_release_gpio( + struct adapter_service *as, + struct gpio *gpio) +{ + dal_gpio_service_destroy_gpio(&gpio); +} + +/* + * dal_adapter_service_get_firmware_info + * + * Get firmware information from BIOS + */ +bool dal_adapter_service_get_firmware_info( + struct adapter_service *as, + struct firmware_info *info) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + return dcb->funcs->get_firmware_info(dcb, info) == BP_RESULT_OK; +} + +/* + * dal_adapter_service_get_audio_support + * + * Get information on audio support + */ +union audio_support dal_adapter_service_get_audio_support( + struct adapter_service *as) +{ + return dal_adapter_service_hw_ctx_get_audio_support(as->hw_ctx); +} + +/* + * dal_adapter_service_get_stream_engines_num + * + * Get number of stream engines + */ +uint8_t dal_adapter_service_get_stream_engines_num( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_DIGFE_NUM]; +} + +/* + * dal_adapter_service_get_feature_value + * + * Get the cached value of a given feature. This value can be a boolean, int, + * or characters. + */ +bool dal_adapter_service_get_feature_value( + const enum adapter_feature_id feature_id, + void *data, + uint32_t size) +{ + uint32_t entry_idx = 0; + uint32_t set_idx = 0; + uint32_t set_internal_idx = 0; + + if (feature_id >= FEATURE_MAXIMUM || feature_id <= FEATURE_UNKNOWN) { + ASSERT_CRITICAL(false); + return false; + } + + if (data == NULL) { + ASSERT_CRITICAL(false); + return false; + } + + entry_idx = lookup_feature_entry(feature_id); + set_idx = (uint32_t)((feature_id - 1)/32); + set_internal_idx = (uint32_t)((feature_id - 1) % 32); + + if (entry_idx >= get_feature_entries_num()) { + /* Cannot find this entry */ + ASSERT_CRITICAL(false); + return false; + } + + if (feature_entry_table[entry_idx].is_boolean_type) { + if (size != sizeof(bool)) { + ASSERT_CRITICAL(false); + return false; + } + + *(bool *)data = get_bool_value(adapter_feature_set[set_idx], + set_internal_idx); + } else { + if (size != sizeof(uint32_t)) { + ASSERT_CRITICAL(false); + return false; + } + + *(uint32_t *)data = adapter_feature_set[set_idx]; + } + + return true; +} + +/* + * dal_adapter_service_get_memory_type_multiplier + * + * Get multiplier for the memory type + */ +uint32_t dal_adapter_service_get_memory_type_multiplier( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_MEMORYTYPE_MULTIPLIER]; +} + +/* + * dal_adapter_service_get_bios_parser + * + * Get BIOS parser handler + */ +struct dc_bios *dal_adapter_service_get_bios_parser( + struct adapter_service *as) +{ + return as->dcb_override ? as->dcb_override : as->dcb_internal; +} + +/* + * dal_adapter_service_get_i2caux + * + * Get i2c aux handler + */ +struct i2caux *dal_adapter_service_get_i2caux( + struct adapter_service *as) +{ + return as->i2caux; +} + +bool dal_adapter_service_initialize_hw_data( + struct adapter_service *as) +{ + return as->hw_ctx->funcs->power_up(as->hw_ctx); +} + +struct graphics_object_id dal_adapter_service_enum_fake_path_resource( + struct adapter_service *as, + uint32_t index) +{ + return as->hw_ctx->funcs->enum_fake_path_resource(as->hw_ctx, index); +} + +struct graphics_object_id dal_adapter_service_enum_stereo_sync_object( + struct adapter_service *as, + uint32_t index) +{ + return as->hw_ctx->funcs->enum_stereo_sync_object(as->hw_ctx, index); +} + +struct graphics_object_id dal_adapter_service_enum_sync_output_object( + struct adapter_service *as, + uint32_t index) +{ + return as->hw_ctx->funcs->enum_sync_output_object(as->hw_ctx, index); +} + +struct graphics_object_id dal_adapter_service_enum_audio_object( + struct adapter_service *as, + uint32_t index) +{ + return as->hw_ctx->funcs->enum_audio_object(as->hw_ctx, index); +} + + +void dal_adapter_service_update_audio_connectivity( + struct adapter_service *as, + uint32_t number_of_audio_capable_display_path) +{ + as->hw_ctx->funcs->update_audio_connectivity( + as->hw_ctx, + number_of_audio_capable_display_path, + dal_adapter_service_get_controllers_num(as)); +} + +bool dal_adapter_service_has_embedded_display_connector( + struct adapter_service *as) +{ + uint8_t index; + uint8_t num_connectors = dal_adapter_service_get_connectors_num(as); + + if (num_connectors == 0 || num_connectors > ENUM_ID_COUNT) + return false; + + for (index = 0; index < num_connectors; index++) { + struct graphics_object_id obj_id = + dal_adapter_service_get_connector_obj_id(as, index); + enum connector_id connector_id = + dal_graphics_object_id_get_connector_id(obj_id); + + if ((connector_id == CONNECTOR_ID_LVDS) || + (connector_id == CONNECTOR_ID_EDP)) + return true; + } + + return false; +} + +bool dal_adapter_service_get_embedded_panel_info( + struct adapter_service *as, + struct embedded_panel_info *info) +{ + enum bp_result result; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (info == NULL) + /*TODO: add DALASSERT_MSG here*/ + return false; + + result = dcb->funcs->get_embedded_panel_info(dcb, info); + + return result == BP_RESULT_OK; +} + +bool dal_adapter_service_enum_embedded_panel_patch_mode( + struct adapter_service *as, + uint32_t index, + struct embedded_panel_patch_mode *mode) +{ + enum bp_result result; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (mode == NULL) + /*TODO: add DALASSERT_MSG here*/ + return false; + + result = dcb->funcs->enum_embedded_panel_patch_mode(dcb, index, mode); + + return result == BP_RESULT_OK; +} + +bool dal_adapter_service_get_faked_edid_len( + struct adapter_service *as, + uint32_t *len) +{ + enum bp_result result; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + result = dcb->funcs->get_faked_edid_len(dcb, len); + + return result == BP_RESULT_OK; +} + +bool dal_adapter_service_get_faked_edid_buf( + struct adapter_service *as, + uint8_t *buf, + uint32_t len) +{ + enum bp_result result; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + result = dcb->funcs->get_faked_edid_buf(dcb, buf, len); + + return result == BP_RESULT_OK; + +} + +/* + * dal_adapter_service_is_fusion + * + * Is this Fusion ASIC + */ +bool dal_adapter_service_is_fusion(struct adapter_service *as) +{ + return as->asic_cap->caps.IS_FUSION; +} + +/* + * dal_adapter_service_is_dfsbyass_dynamic + * + * + **/ +bool dal_adapter_service_is_dfsbyass_dynamic(struct adapter_service *as) +{ + return as->asic_cap->caps.DFSBYPASS_DYNAMIC_SUPPORT; +} + +/* + * dal_adapter_service_should_optimize + * + * @brief Reports whether driver settings allow requested optimization + * + * @param + * as: adapter service handler + * feature: for which optimization is validated + * + * @return + * true if requested feature can be optimized + */ +bool dal_adapter_service_should_optimize( + struct adapter_service *as, enum optimization_feature feature) +{ + uint32_t supported_optimization = 0; + struct dal_asic_runtime_flags flags; + + if (!dal_adapter_service_get_feature_value(FEATURE_OPTIMIZATION, + &supported_optimization, sizeof(uint32_t))) + return false; + + /* Retrieve ASIC runtime flags */ + flags = dal_adapter_service_get_asic_runtime_flags(as); + + /* Check runtime flags against different optimization features */ + switch (feature) { + case OF_SKIP_HW_PROGRAMMING_ON_ENABLED_EMBEDDED_DISPLAY: + if (!flags.flags.bits.OPTIMIZED_DISPLAY_PROGRAMMING_ON_BOOT) + return false; + break; + + case OF_SKIP_RESET_OF_ALL_HW_ON_S3RESUME: + if (as->integrated_info == NULL || + !flags.flags.bits.SKIP_POWER_DOWN_ON_RESUME) + return false; + break; + case OF_SKIP_POWER_DOWN_INACTIVE_ENCODER: + if (!dal_adapter_service_get_asic_runtime_flags(as).flags.bits. + SKIP_POWER_DOWN_ON_RESUME) + return false; + break; + default: + break; + } + + return (supported_optimization & feature) != 0; +} + +/* + * dal_adapter_service_is_in_accelerated_mode + * + * @brief Determine if driver is in accelerated mode + * + * @param + * as: Adapter Service handler + * + * @out + * True if driver is in accelerated mode, false otherwise. + */ +bool dal_adapter_service_is_in_accelerated_mode(struct adapter_service *as) +{ + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + return dcb->funcs->is_accelerated_mode(dcb); +} + +struct ddc *dal_adapter_service_obtain_ddc_from_i2c_info( + struct adapter_service *as, + struct graphics_object_i2c_info *info) +{ + struct gpio_ddc_hw_info hw_info = { + info->i2c_hw_assist, + info->i2c_line }; + return dal_gpio_service_create_ddc(as->gpio_service, + info->gpio_info.clk_a_register_index, + (1 << info->gpio_info.clk_a_shift), &hw_info); +} + +struct bdf_info dal_adapter_service_get_adapter_info(struct adapter_service *as) +{ + return as->bdf_info; +} + +/* + * dal_adapter_service_should_psr_skip_wait_for_pll_lock + * + * @brief Determine if this ASIC needs to wait on PLL lock bit + * + * @param + * as: Adapter Service handle + * + * @out + * True if ASIC does not need to wait for PLL lock bit, i.e. skip the wait. + */ +bool dal_adapter_service_should_psr_skip_wait_for_pll_lock( + struct adapter_service *as) +{ + return as->asic_cap->caps.SKIP_PSR_WAIT_FOR_PLL_LOCK_BIT; +} + +bool dal_adapter_service_is_lid_open(struct adapter_service *as) +{ + bool is_lid_open = false; + struct platform_info_params params; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + params.data = &is_lid_open; + params.method = PM_GET_LID_STATE; + + if ((PM_GET_LID_STATE & as->platform_methods_mask) && + dm_get_platform_info(as->ctx, ¶ms)) + return is_lid_open; + +#if defined(CONFIG_DRM_AMD_DAL_VBIOS_PRESENT) + return dcb->funcs->is_lid_open(dcb); +#else + return false; +#endif +} + +bool dal_adapter_service_get_panel_backlight_default_levels( + struct adapter_service *as, + struct panel_backlight_levels *levels) +{ + if (!as->backlight_caps_initialized) + return false; + + levels->ac_level_percentage = as->ac_level_percentage; + levels->dc_level_percentage = as->dc_level_percentage; + return true; +} + +bool dal_adapter_service_get_panel_backlight_boundaries( + struct adapter_service *as, + struct panel_backlight_boundaries *boundaries) +{ + if (!as->backlight_caps_initialized) + return false; + if (boundaries != NULL) { + boundaries->min_signal_level = as->backlight_8bit_lut[0]; + boundaries->max_signal_level = + as->backlight_8bit_lut[SIZEOF_BACKLIGHT_LUT - 1]; + return true; + } + return false; +} + + +uint32_t dal_adapter_service_get_view_port_pixel_granularity( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_VIEWPORT_PIXEL_GRANULARITY]; +} + +/** + * Get number of paths per DP 1.2 connector from the runtime parameter if it + * exists. + * A check to see if MST is supported for the generation of ASIC is done + * + * \return + * Number of paths per DP 1.2 connector is exists in runtime parameters + * or ASIC cap + */ +uint32_t dal_adapter_service_get_num_of_path_per_dp_mst_connector( + struct adapter_service *as) +{ + if (as->asic_cap->caps.DP_MST_SUPPORTED == 0) { + /* ASIC doesn't support DP MST at all */ + return 0; + } + + return as->asic_cap->data[ASIC_DATA_PATH_NUM_PER_DPMST_CONNECTOR]; +} + +uint32_t dal_adapter_service_get_num_of_underlays( + struct adapter_service *as) +{ + return as->asic_cap->data[ASIC_DATA_NUM_OF_VIDEO_PLANES]; +} + +bool dal_adapter_service_get_encoder_cap_info( + struct adapter_service *as, + struct graphics_object_id id, + struct graphics_object_encoder_cap_info *info) +{ + struct bp_encoder_cap_info bp_cap_info = {0}; + enum bp_result result; + struct dc_bios *dcb = dal_adapter_service_get_bios_parser(as); + + if (NULL == info) { + ASSERT_CRITICAL(false); + return false; + } + + /* + * Retrieve Encoder Capability Information from VBIOS and store the + * call result (success or fail) + * Info from VBIOS about HBR2 has two fields: + * + * - dpHbr2Cap: indicates supported/not supported by HW Encoder + * - dpHbr2En : indicates DP spec compliant/not compliant + */ + result = dcb->funcs->get_encoder_cap_info(dcb, id, &bp_cap_info); + + /* Set dp_hbr2_validated flag (it's equal to Enable) */ + info->dp_hbr2_validated = bp_cap_info.DP_HBR2_EN; + + if (result == BP_RESULT_OK) { + info->dp_hbr2_cap = bp_cap_info.DP_HBR2_CAP; + return true; + } + + return false; +} + +bool dal_adapter_service_is_mc_tuning_req(struct adapter_service *as) +{ + return as->asic_cap->caps.NEED_MC_TUNING ? true : false; +} diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h new file mode 100644 index 000000000000..60464e89cc5b --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/adapter_service.h @@ -0,0 +1,71 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_ADAPTER_SERVICE_H__ +#define __DAL_ADAPTER_SERVICE_H__ + +/* Include */ +#include "dc_bios_types.h" +#include "include/adapter_service_interface.h" +#include "wireless_data_source.h" + +/* + * Forward declaration + */ +struct gpio_service; +struct asic_cap; + + +/* Adapter service */ +struct adapter_service { + struct dc_context *ctx; + struct asic_capability *asic_cap; + struct dc_bios *dcb_internal;/* created by DC */ + struct dc_bios *dcb_override;/* supplied by creator of DC */ + enum dce_environment dce_environment; + struct gpio_service *gpio_service; + struct i2caux *i2caux; + struct wireless_data wireless_data; + struct hw_ctx_adapter_service *hw_ctx; + struct integrated_info *integrated_info; + struct bdf_info bdf_info; + uint32_t platform_methods_mask; + uint32_t ac_level_percentage; + uint32_t dc_level_percentage; + uint32_t backlight_caps_initialized; + uint32_t backlight_8bit_lut[SIZEOF_BACKLIGHT_LUT]; +}; + +/* Type of feature with its runtime parameter and default value */ +struct feature_source_entry { + enum adapter_feature_id feature_id; + uint32_t default_value; + bool is_boolean_type; +}; + +/* Stores entire ASIC features by sets */ +extern uint32_t adapter_feature_set[]; + +#endif /* __DAL_ADAPTER_SERVICE_H__ */ diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c new file mode 100644 index 000000000000..f10bee6f2b83 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.c @@ -0,0 +1,304 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "dm_services.h" + +#include "../hw_ctx_adapter_service.h" + +#include "hw_ctx_adapter_service_dce110.h" + +#include "include/logger_interface.h" +#include "include/grph_object_id.h" + +#include "dce/dce_11_0_d.h" +#include "dce/dce_11_0_sh_mask.h" + +#ifndef mmCC_DC_HDMI_STRAPS +#define mmCC_DC_HDMI_STRAPS 0x4819 +#define CC_DC_HDMI_STRAPS__HDMI_DISABLE_MASK 0x40 +#define CC_DC_HDMI_STRAPS__HDMI_DISABLE__SHIFT 0x6 +#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER_MASK 0x700 +#define CC_DC_HDMI_STRAPS__AUDIO_STREAM_NUMBER__SHIFT 0x8 +#endif + +static const struct graphics_object_id invalid_go = { + 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN, 0 +}; + +/* Macro */ +#define AUDIO_STRAPS_HDMI_ENABLE 0x2 + +#define FROM_HW_CTX(ptr) \ + container_of((ptr), struct hw_ctx_adapter_service_dce110, base) + +static const uint32_t audio_index_reg_offset[] = { + /*CZ has 3 DIGs but 4 audio endpoints*/ + mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_INDEX, + mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_INDEX, + mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_INDEX, + mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_INDEX +}; + +static const uint32_t audio_data_reg_offset[] = { + mmAZF0ENDPOINT0_AZALIA_F0_CODEC_ENDPOINT_DATA, + mmAZF0ENDPOINT1_AZALIA_F0_CODEC_ENDPOINT_DATA, + mmAZF0ENDPOINT2_AZALIA_F0_CODEC_ENDPOINT_DATA, + mmAZF0ENDPOINT3_AZALIA_F0_CODEC_ENDPOINT_DATA, +}; + +enum { + MAX_NUMBER_OF_AUDIO_PINS = 4 +}; + +static void destruct( + struct hw_ctx_adapter_service_dce110 *hw_ctx) +{ + /* There is nothing to destruct at the moment */ + dal_adapter_service_destruct_hw_ctx(&hw_ctx->base); +} + +static void destroy( + struct hw_ctx_adapter_service *ptr) +{ + struct hw_ctx_adapter_service_dce110 *hw_ctx = + FROM_HW_CTX(ptr); + + destruct(hw_ctx); + + dm_free(ptr->ctx, hw_ctx); +} + +/* + * enum_audio_object + * + * @brief enumerate audio object + * + * @param + * const struct hw_ctx_adapter_service *hw_ctx - [in] provides num of endpoints + * uint32_t index - [in] audio index + * + * @return + * grphic object id + */ +static struct graphics_object_id enum_audio_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + uint32_t number_of_connected_audio_endpoints = + FROM_HW_CTX(hw_ctx)->number_of_connected_audio_endpoints; + + if (index >= number_of_connected_audio_endpoints || + number_of_connected_audio_endpoints == 0) + return invalid_go; + else + return dal_graphics_object_id_init( + AUDIO_ID_INTERNAL_AZALIA, + (enum object_enum_id)(index + 1), + OBJECT_TYPE_AUDIO); +} + +static uint32_t get_number_of_connected_audio_endpoints_multistream( + struct dc_context *ctx) +{ + uint32_t num_connected_audio_endpoints = 0; + uint32_t i; + uint32_t default_config = + ixAZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT; + + /* find the total number of streams available via the + * AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT + * registers (one for each pin) starting from pin 1 + * up to the max number of audio pins. + * We stop on the first pin where + * PORT_CONNECTIVITY == 1 (as instructed by HW team). + */ + for (i = 0; i < MAX_NUMBER_OF_AUDIO_PINS; i++) { + uint32_t value = 0; + + set_reg_field_value(value, + default_config, + AZALIA_F0_CODEC_ENDPOINT_INDEX, + AZALIA_ENDPOINT_REG_INDEX); + + dm_write_reg(ctx, audio_index_reg_offset[i], value); + + value = 0; + value = dm_read_reg(ctx, audio_data_reg_offset[i]); + + /* 1 means not supported*/ + if (get_reg_field_value(value, + AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT, + PORT_CONNECTIVITY) == 1) + break; + + num_connected_audio_endpoints++; + } + + return num_connected_audio_endpoints; + +} + +/* + * get_number_of_connected_audio_endpoints + */ +static uint32_t get_number_of_connected_audio_endpoints( + struct hw_ctx_adapter_service *hw_ctx) +{ + uint32_t addr = mmCC_DC_HDMI_STRAPS; + uint32_t value = 0; + uint32_t field = 0; + + if (hw_ctx->cached_audio_straps == AUDIO_STRAPS_NOT_ALLOWED) + /* audio straps indicate no audio supported */ + return 0; + + value = dm_read_reg(hw_ctx->ctx, addr); + + field = get_reg_field_value( + value, CC_DC_HDMI_STRAPS, AUDIO_STREAM_NUMBER); + if (field == 1) + /* multi streams not supported */ + return 1; + else if (field == 0) + /* multi streams supported */ + return get_number_of_connected_audio_endpoints_multistream( + hw_ctx->ctx); + + /* unexpected value */ + ASSERT_CRITICAL(false); + return field; +} + + +/* + * power_up + * + * @brief + * Determine and cache audio support from register. + * + * @param + * struct hw_ctx_adapter_service *hw_ctx - [in] adapter service hw context + * + * @return + * true if succeed, false otherwise + */ +static bool power_up( + struct hw_ctx_adapter_service *hw_ctx) +{ + struct hw_ctx_adapter_service_dce110 *hw_ctx_dce11 = + FROM_HW_CTX(hw_ctx); + /* Allow DP audio all the time + * without additional pinstrap check on Fusion */ + + + { + uint32_t value = 0; + uint32_t field = 0; + + value = dm_read_reg(hw_ctx->ctx, mmCC_DC_HDMI_STRAPS); + field = get_reg_field_value( + value, CC_DC_HDMI_STRAPS, HDMI_DISABLE); + + if (field == 0) { + hw_ctx->cached_audio_straps = AUDIO_STRAPS_DP_HDMI_AUDIO; + } else { + value = dm_read_reg( + hw_ctx->ctx, mmDC_PINSTRAPS); + field = get_reg_field_value( + value, + DC_PINSTRAPS, + DC_PINSTRAPS_AUDIO); + + if (field & AUDIO_STRAPS_HDMI_ENABLE) + hw_ctx->cached_audio_straps = + AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE; + else + hw_ctx->cached_audio_straps = + AUDIO_STRAPS_DP_AUDIO_ALLOWED; + } + + } + + /* get the number of connected audio endpoints */ + hw_ctx_dce11->number_of_connected_audio_endpoints = + get_number_of_connected_audio_endpoints(hw_ctx); + + return true; +} + +static void update_audio_connectivity( + struct hw_ctx_adapter_service *hw_ctx, + uint32_t number_of_audio_capable_display_path, + uint32_t number_of_controllers) +{ + /* this one should be empty on DCE110 */ +} + +static const struct hw_ctx_adapter_service_funcs funcs = { + .destroy = destroy, + .power_up = power_up, + .enum_fake_path_resource = NULL, + .enum_stereo_sync_object = NULL, + .enum_sync_output_object = NULL, + .enum_audio_object = enum_audio_object, + .update_audio_connectivity = update_audio_connectivity +}; + +static bool construct( + struct hw_ctx_adapter_service_dce110 *hw_ctx, + struct dc_context *ctx) +{ + if (!dal_adapter_service_construct_hw_ctx(&hw_ctx->base, ctx)) { + ASSERT_CRITICAL(false); + return false; + } + + hw_ctx->base.funcs = &funcs; + hw_ctx->number_of_connected_audio_endpoints = 0; + + return true; +} + +struct hw_ctx_adapter_service * + dal_adapter_service_create_hw_ctx_dce110( + struct dc_context *ctx) +{ + struct hw_ctx_adapter_service_dce110 *hw_ctx = + dm_alloc(ctx, sizeof(struct hw_ctx_adapter_service_dce110)); + + if (!hw_ctx) { + ASSERT_CRITICAL(false); + return NULL; + } + + if (construct(hw_ctx, ctx)) + return &hw_ctx->base; + + ASSERT_CRITICAL(false); + + dm_free(ctx, hw_ctx); + + return NULL; +} diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h new file mode 100644 index 000000000000..092b67173dc4 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/dce110/hw_ctx_adapter_service_dce110.h @@ -0,0 +1,40 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__ +#define __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__ + +struct hw_ctx_adapter_service_dce110 { + struct hw_ctx_adapter_service base; + uint32_t number_of_connected_audio_endpoints; +}; + +struct hw_ctx_adapter_service * + dal_adapter_service_create_hw_ctx_dce110( + struct dc_context *ctx); + +#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DCE110_H__ */ + + diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c new file mode 100644 index 000000000000..4f5f0403af84 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.c @@ -0,0 +1,133 @@ +/* + * Copyright 2012-16 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +/* FPGA Diagnostics version of AS HW CTX. */ + +#include "dm_services.h" + +#include "../hw_ctx_adapter_service.h" + +#include "hw_ctx_adapter_service_diag.h" + +#include "include/logger_interface.h" +#include "include/grph_object_id.h" + +static const struct graphics_object_id invalid_go = { + 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN +}; + +static void destroy( + struct hw_ctx_adapter_service *hw_ctx) +{ +} + +static bool power_up( + struct hw_ctx_adapter_service *hw_ctx) +{ + return true; +} + +static struct graphics_object_id enum_fake_path_resource( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static struct graphics_object_id enum_stereo_sync_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static struct graphics_object_id enum_sync_output_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static struct graphics_object_id enum_audio_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static void update_audio_connectivity( + struct hw_ctx_adapter_service *hw_ctx, + uint32_t number_of_audio_capable_display_path, + uint32_t number_of_controllers) +{ +} + +static const struct hw_ctx_adapter_service_funcs funcs = { + destroy, + power_up, + enum_fake_path_resource, + enum_stereo_sync_object, + enum_sync_output_object, + enum_audio_object, + update_audio_connectivity +}; + +static bool construct( + struct hw_ctx_adapter_service *hw_ctx, + struct dc_context *ctx) + +{ + if (!dal_adapter_service_construct_hw_ctx(hw_ctx, ctx)) { + ASSERT_CRITICAL(false); + return false; + } + + hw_ctx->funcs = &funcs; + + return true; +} + +struct hw_ctx_adapter_service *dal_adapter_service_create_hw_ctx_diag( + struct dc_context *ctx) +{ + struct hw_ctx_adapter_service *hw_ctx = dm_alloc(ctx, + sizeof(*hw_ctx)); + + if (!hw_ctx) { + ASSERT_CRITICAL(false); + return NULL; + } + + if (construct(hw_ctx, ctx)) + return hw_ctx; + + ASSERT_CRITICAL(false); + + dm_free(ctx, hw_ctx); + + return NULL; +} + +/*****************************************************************************/ diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h new file mode 100644 index 000000000000..39ae7524506c --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/diagnostics/hw_ctx_adapter_service_diag.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012-16 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_DIAG_H__ +#define __DAL_HW_CTX_ADAPTER_SERVICE_DIAG_H__ + + +struct hw_ctx_adapter_service *dal_adapter_service_create_hw_ctx_diag( + struct dc_context *ctx); + +#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_DIAG_H__ */ diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c new file mode 100644 index 000000000000..12eabe0c3f89 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.c @@ -0,0 +1,164 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include "dm_services.h" +#include "include/adapter_service_types.h" +#include "include/grph_object_id.h" +#include "hw_ctx_adapter_service.h" + +static const struct graphics_object_id invalid_go = { + 0, ENUM_ID_UNKNOWN, OBJECT_TYPE_UNKNOWN +}; + +static void destroy( + struct hw_ctx_adapter_service *hw_ctx) +{ + /* Attention! + * You must override impl method in derived class */ + BREAK_TO_DEBUGGER(); +} + +static bool power_up( + struct hw_ctx_adapter_service *hw_ctx) +{ + /* Attention! + * You must override impl method in derived class */ + BREAK_TO_DEBUGGER(); + + return false; +} + +static struct graphics_object_id enum_fake_path_resource( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static struct graphics_object_id enum_stereo_sync_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static struct graphics_object_id enum_sync_output_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + return invalid_go; +} + +static struct graphics_object_id enum_audio_object( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index) +{ + /* by default, we only allow one audio */ + + if (index > 0) + return invalid_go; + else if (hw_ctx->cached_audio_straps == AUDIO_STRAPS_NOT_ALLOWED) + return invalid_go; + else + return dal_graphics_object_id_init( + AUDIO_ID_INTERNAL_AZALIA, + ENUM_ID_1, + OBJECT_TYPE_AUDIO); +} + +static void update_audio_connectivity( + struct hw_ctx_adapter_service *hw_ctx, + uint32_t number_of_audio_capable_display_path, + uint32_t number_of_controllers) +{ + /* Attention! + * You must override impl method in derived class */ + BREAK_TO_DEBUGGER(); +} + +static const struct hw_ctx_adapter_service_funcs funcs = { + destroy, + power_up, + enum_fake_path_resource, + enum_stereo_sync_object, + enum_sync_output_object, + enum_audio_object, + update_audio_connectivity +}; + +bool dal_adapter_service_construct_hw_ctx( + struct hw_ctx_adapter_service *hw_ctx, + struct dc_context *ctx) +{ + + hw_ctx->ctx = ctx; + hw_ctx->funcs = &funcs; + hw_ctx->cached_audio_straps = AUDIO_STRAPS_NOT_ALLOWED; + + return true; +} + +union audio_support dal_adapter_service_hw_ctx_get_audio_support( + const struct hw_ctx_adapter_service *hw_ctx) +{ + union audio_support result; + + result.raw = 0; + + switch (hw_ctx->cached_audio_straps) { + case AUDIO_STRAPS_DP_HDMI_AUDIO: + result.bits.HDMI_AUDIO_NATIVE = true; + /* do not break ! */ + case AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE: + result.bits.HDMI_AUDIO_ON_DONGLE = true; + /* do not break ! */ + case AUDIO_STRAPS_DP_AUDIO_ALLOWED: + result.bits.DP_AUDIO = true; + break; + default: + break; + } + + return result; +} + +void dal_adapter_service_destruct_hw_ctx( + struct hw_ctx_adapter_service *hw_ctx) +{ + /* There is nothing to destruct at the moment */ +} + +void dal_adapter_service_destroy_hw_ctx( + struct hw_ctx_adapter_service **ptr) +{ + if (!ptr || !*ptr) { + BREAK_TO_DEBUGGER(); + return; + } + + (*ptr)->funcs->destroy(*ptr); + + *ptr = NULL; +} diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h new file mode 100644 index 000000000000..f98c2d428b2a --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/hw_ctx_adapter_service.h @@ -0,0 +1,86 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_HW_CTX_ADAPTER_SERVICE_H__ +#define __DAL_HW_CTX_ADAPTER_SERVICE_H__ + +enum audio_straps { + AUDIO_STRAPS_NOT_ALLOWED = 0, + AUDIO_STRAPS_DP_AUDIO_ALLOWED, + AUDIO_STRAPS_DP_HDMI_AUDIO_ON_DONGLE, + AUDIO_STRAPS_DP_HDMI_AUDIO +}; + +struct hw_ctx_adapter_service; + +struct hw_ctx_adapter_service_funcs { + void (*destroy)( + struct hw_ctx_adapter_service *hw_ctx); + /* Initializes relevant HW registers + * and caches relevant data from HW registers */ + bool (*power_up)( + struct hw_ctx_adapter_service *hw_ctx); + /* Enumerate fake path resources */ + struct graphics_object_id (*enum_fake_path_resource)( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index); + /* Enumerate stereo sync objects */ + struct graphics_object_id (*enum_stereo_sync_object)( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index); + /* Enumerate (H/V) sync output objects */ + struct graphics_object_id (*enum_sync_output_object)( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index); + /* Enumerate audio objects */ + struct graphics_object_id (*enum_audio_object)( + const struct hw_ctx_adapter_service *hw_ctx, + uint32_t index); + void (*update_audio_connectivity)( + struct hw_ctx_adapter_service *hw_ctx, + uint32_t number_of_audio_capable_display_path, + uint32_t number_of_controllers); +}; + +struct hw_ctx_adapter_service { + struct dc_context *ctx; + const struct hw_ctx_adapter_service_funcs *funcs; + enum audio_straps cached_audio_straps; +}; + +bool dal_adapter_service_construct_hw_ctx( + struct hw_ctx_adapter_service *hw_ctx, + struct dc_context *ctx); + +union audio_support dal_adapter_service_hw_ctx_get_audio_support( + const struct hw_ctx_adapter_service *hw_ctx); + +void dal_adapter_service_destruct_hw_ctx( + struct hw_ctx_adapter_service *hw_ctx); + +void dal_adapter_service_destroy_hw_ctx( + struct hw_ctx_adapter_service **ptr); + +#endif /* __DAL_HW_CTX_ADAPTER_SERVICE_H__ */ diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c new file mode 100644 index 000000000000..0b1151ec5a2c --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.c @@ -0,0 +1,208 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + + +#include "dm_services.h" +#include "adapter_service.h" +#include "wireless_data_source.h" + +#include "atom.h" + +/*construct wireless data*/ +bool wireless_data_init(struct wireless_data *data, + struct dc_bios *dcb, + struct wireless_init_data *init_data) +{ + struct firmware_info info; + + if (data == NULL || dcb == NULL || init_data == NULL) { + ASSERT_CRITICAL(false); + return false; + } + + data->miracast_connector_enable = false; + data->wireless_disp_path_enable = false; + data->wireless_enable = false; + + /* Wireless it not supported if VCE is not supported */ + if (!init_data->vce_supported) + return true; + + if (init_data->miracast_target_required) + data->miracast_connector_enable = true; + + /* + * If override is in place for platform support, we will both + * enable wireless display as a feature (i.e. CCC aspect) and + * enable the wireless display path without any further checks. + */ + if (init_data->platform_override) { + data->wireless_enable = true; + data->wireless_disp_path_enable = true; + } else { + /* + * Check if SBIOS sets remote display enable, exposed + * through VBIOS. This is only valid for APU, not dGPU + */ + dcb->funcs->get_firmware_info(dcb, &info); + + if ((REMOTE_DISPLAY_ENABLE == info.remote_display_config) && + init_data->fusion) { + data->wireless_enable = true; + data->wireless_disp_path_enable = true; + } + } + + /* + * If remote display path override is enabled, we enable just the + * remote display path. This is mainly used for testing purposes + */ + if (init_data->remote_disp_path_override) + data->wireless_disp_path_enable = true; + + return true; +} + +uint8_t wireless_get_clocks_num( + struct adapter_service *as) +{ + if (as->wireless_data.wireless_enable || + as->wireless_data.wireless_disp_path_enable) + return 1; + else + return 0; +} + +static uint8_t wireless_get_encoders_num( + struct adapter_service *as) +{ + if (as->wireless_data.wireless_enable || + as->wireless_data.wireless_disp_path_enable) + return 1; + else + return 0; +} + +uint8_t wireless_get_connectors_num( + struct adapter_service *as) +{ + uint8_t wireless_connectors_num = 0; + + if (as->wireless_data.wireless_enable && + as->wireless_data.miracast_connector_enable) + wireless_connectors_num++; + + if (as->wireless_data.wireless_disp_path_enable) + wireless_connectors_num++; + + return wireless_connectors_num; +} + +struct graphics_object_id wireless_get_connector_id( + struct adapter_service *as, + uint8_t index) +{ + struct graphics_object_id unknown_object_id = + dal_graphics_object_id_init( + 0, + ENUM_ID_UNKNOWN, + OBJECT_TYPE_UNKNOWN); + + if (!as->wireless_data.wireless_enable && + !as->wireless_data.wireless_disp_path_enable) + return unknown_object_id; + + else if (!as->wireless_data.miracast_connector_enable) + return dal_graphics_object_id_init( + CONNECTOR_ID_WIRELESS, + ENUM_ID_1, + OBJECT_TYPE_CONNECTOR); + + switch (index) { + case 0: + return dal_graphics_object_id_init( + CONNECTOR_ID_WIRELESS, + ENUM_ID_1, + OBJECT_TYPE_CONNECTOR); + break; + case 1: + return dal_graphics_object_id_init( + CONNECTOR_ID_MIRACAST, + ENUM_ID_1, + OBJECT_TYPE_CONNECTOR); + break; + default: + return unknown_object_id; + } +} + +uint8_t wireless_get_srcs_num( + struct adapter_service *as, + struct graphics_object_id id) +{ + switch (id.type) { + case OBJECT_TYPE_CONNECTOR: + return wireless_get_encoders_num(as); + case OBJECT_TYPE_ENCODER: + return 1; + + default: + ASSERT_CRITICAL(false); + break; + } + + return 0; +} + +struct graphics_object_id wireless_get_src_obj_id( + struct adapter_service *as, + struct graphics_object_id id, + uint8_t index) +{ + if (index < wireless_get_srcs_num(as, id)) { + switch (id.type) { + case OBJECT_TYPE_CONNECTOR: + return dal_graphics_object_id_init( + ENCODER_ID_INTERNAL_WIRELESS, + ENUM_ID_1, + OBJECT_TYPE_ENCODER); + break; + case OBJECT_TYPE_ENCODER: + return dal_graphics_object_id_init( + 0, + ENUM_ID_1, + OBJECT_TYPE_GPU); + break; + default: + ASSERT_CRITICAL(false); + break; + } + } + + return dal_graphics_object_id_init( + 0, + ENUM_ID_UNKNOWN, + OBJECT_TYPE_UNKNOWN); +} diff --git a/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h new file mode 100644 index 000000000000..b64089e3960e --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/adapter/wireless_data_source.h @@ -0,0 +1,80 @@ +/* + * Copyright 2012-15 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DAL_WIRELESS_DATA_SOURCE_H__ +#define __DAL_WIRELESS_DATA_SOURCE_H__ + +/* Include */ +#include "include/grph_object_id.h" + +/* + * Forward declaration + */ +struct adapter_service; +struct dc_bios; + +/* Wireless data init structure */ +struct wireless_init_data { + bool fusion; /* Fusion flag */ + bool platform_override; /* Override for platform BIOS option */ + bool remote_disp_path_override; /* Override enabling wireless path */ + bool vce_supported; /* Existence of VCE block on this DCE */ + bool miracast_target_required; /* OS requires Miracast target */ +}; + +/* Wireless data */ +struct wireless_data { + bool wireless_enable; + bool wireless_disp_path_enable; + bool miracast_connector_enable; +}; + + +/*construct wireless data*/ +bool wireless_data_init( + struct wireless_data *data, + struct dc_bios *dcb, + struct wireless_init_data *init_data); + +uint8_t wireless_get_clocks_num( + struct adapter_service *as); + +uint8_t wireless_get_connectors_num( + struct adapter_service *as); + +struct graphics_object_id wireless_get_connector_id( + struct adapter_service *as, + uint8_t connector_index); + +uint8_t wireless_get_srcs_num( + struct adapter_service *as, + struct graphics_object_id id); + +struct graphics_object_id wireless_get_src_obj_id( + struct adapter_service *as, + struct graphics_object_id id, + uint8_t index); + +#endif /* __DAL_WIRELESS_DATA_SOURCE_H__ */