From patchwork Tue Feb 16 22:27:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Wentland X-Patchwork-Id: 8332831 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CF2B7C02AA for ; Tue, 16 Feb 2016 22:29:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E7609202FE for ; Tue, 16 Feb 2016 22:29:02 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id AA6BF202F8 for ; Tue, 16 Feb 2016 22:29:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5D3626E8D0; Tue, 16 Feb 2016 22:28:37 +0000 (UTC) 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-by2on0082.outbound.protection.outlook.com [207.46.100.82]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3202D6E8BD for ; Tue, 16 Feb 2016 22:28:33 +0000 (UTC) Received: from CY1PR12CA0009.namprd12.prod.outlook.com (10.160.137.19) by SN1PR12MB0718.namprd12.prod.outlook.com (10.163.209.20) with Microsoft SMTP Server (TLS) id 15.1.409.15; Tue, 16 Feb 2016 22:28:31 +0000 Received: from BY2NAM03FT021.eop-NAM03.prod.protection.outlook.com (2a01:111:f400:7e4a::208) by CY1PR12CA0009.outlook.office365.com (2a01:111:e400:4c1f::19) with Microsoft SMTP Server (TLS) id 15.1.409.15 via Frontend Transport; Tue, 16 Feb 2016 22:28:32 +0000 Authentication-Results: spf=none (sender IP is 165.204.84.221) 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 atltwp01.amd.com (165.204.84.221) by BY2NAM03FT021.mail.protection.outlook.com (10.152.84.222) with Microsoft SMTP Server id 15.1.415.6 via Frontend Transport; Tue, 16 Feb 2016 22:28:30 +0000 X-WSS-ID: 0O2NVRG-07-L5L-02 X-M-MSG: Received: from satlvexedge01.amd.com (satlvexedge01.amd.com [10.177.96.28]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by atltwp01.amd.com (Axway MailGate 5.3.1) with ESMTPS id 2C9C3CAE804 for ; Tue, 16 Feb 2016 17:28:28 -0500 (EST) Received: from SATLEXDAG03.amd.com (10.181.40.7) by satlvexedge01.amd.com (10.177.96.28) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 16 Feb 2016 16:28:31 -0600 Received: from STOREXDAG02.amd.com (10.1.13.11) by satlexdag03.amd.com (10.181.40.7) with Microsoft SMTP Server (TLS) id 14.3.266.1; Tue, 16 Feb 2016 17:28:28 -0500 Received: from cnhwentlanub.amd.com (172.29.225.36) by storexdag02.amd.com (10.1.13.11) with Microsoft SMTP Server id 14.3.266.1; Tue, 16 Feb 2016 17:28:27 -0500 From: Harry Wentland To: Subject: [PATCH v2 09/26] drm/amd/dal: IRQ Service Date: Tue, 16 Feb 2016 17:27:49 -0500 Message-ID: <4c57e913bcdf575f9b4036f152bb48bfdbd44dac.1455660367.git.harry.wentland@amd.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: 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.221; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(428002)(199003)(189002)(33646002)(92566002)(118296001)(1220700001)(1096002)(5003600100002)(50226001)(586003)(2950100001)(53416004)(450100001)(5008740100001)(5003940100001)(36756003)(76176999)(19580395003)(4326007)(77096005)(189998001)(48376002)(50466002)(110136002)(19580405001)(87936001)(2351001)(229853001)(50986999)(105586002)(101416001)(86362001)(2906002)(47776003)(106466001); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR12MB0718; H:atltwp01.amd.com; FPR:; SPF:None; MLV:sfv; A:1; MX:1; LANG:en; X-MS-Office365-Filtering-Correlation-Id: 53477151-cf07-4127-08e3-08d337207fb6 X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0718; 2:Vf8TsAPIzL4FKT6JIHC/9XviAf6gLWJ7k5vWLMJ6UBptKnS94l2y7P+8YvJXPWgGh0PVap5boH3vHKyxR6pnDDq4DlLjHKnAoXGIAV3Qn5pO6+J77A5IJVTXJkgubz7qNPkP7xK4P7d0BiOBWuzkUzpsZ7s7M6NsN66r+9csXHv99fY6LTtOIlzFjppN46Te; 3:C95NoQsckFYBzADmbKhz9leSp3SvD75t0t+VrRuya68ngcsgDITn3lmwcMSt04O8mEiDyShCuVyrmlEoXO2kHWmmaBkpJZwNlC19PJRVtoloU2FvlR20PF2A2s9STw+d+evbq0P7xxwzQEIh86EVK0wxRrzwbgdfnUI/Y2aC0c5BU+HekIqynyFPKa7aLj5pAKAIOvIznjwCXqoxjMf0sRk0bGgPGJwiHyoprwlGNn8=; 25:T6P40Nhu2TaSZQ5th6oxdK76XEg7ijx+Vhesl3nzOGUn8fBBSMUkSoL5WxGawD8gA2KG6T1I85zW3quqxhaovjsV3W5NIE9K1918SNiUiiAt7qIJt7dq17pKI1CTPGAn9VosaMRhmvENqGBJYhCS/aArLpDJ3r/1iLH1UTGgA0TguH9og9PkLdor/XpsuEdMlKO4/CGYRcW3adJ/a45bxC++pZI85ObtUcPMGIVryPzHTFjzpFm9vMIFKbssn3OR/9lZx61fKibSegX3Kx+It7p7OoUi+czZE4EbuJgkyW9pXbRSwztuVN5e2Zsmn4f/ X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0718; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0718; 20:wrRj+bHIdnQHUovaVhXAF1RcyECZFD/UuPQ5pCmyGn19Qdnrl0y+9f+gC26J7RubtqRLajZKMNwGCjoRvi52XwK6np7U3Ov3cFCVeUWb9jkw9MUza4W+Y36u/GgmC9Jy8k5ceNaHTiXnzNvRAUy2zs/LQgDzof9Wv5YyyejSL+zBGGo5YIncRDF2HyG7lERLT4Ediv2N4nmYDg7MtVCkk6ak1iPqrOf4RMYqEQV1MfvHAqcW2fuZJZF07z3gW3xqWqyCPw5r+vus33LjbTnvccmNB9Dviyv10YIAnEJFZcq4+sT7C6BlKsbZi54p4E/nTEd0krwsiEysCDVZJhrPiVpGpixQfZ2vHgM4M1hjK8JoU5btIzrmaIbmY7qCIODAkejisboSRiQpgJ0Lw8qDT9HDOuAc3INv4XCzYO0czDQTjscSlzeHl4x3IUZqiAGZZ/m6PLMqf7AW4BHBFya+BFV7vqhXRzfkL+ZPyaBXWHHNx4yOyagKP7ieb3ujPECM X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13017025)(13015025)(5005006)(13018025)(13023025)(13024025)(8121501046)(10201501046)(3002001); SRVR:SN1PR12MB0718; BCL:0; PCL:0; RULEID:; SRVR:SN1PR12MB0718; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0718; 4:WAPVItXvc+ZgaOHXwBcURQwDhuTPqEIcHsXZV7EGkazhc6cN0GGtJuaQF1k3kbw7mczablZIFg9qPBAA7r2oVepCgJ/xY1etCQu00WSM6eHZTNBM5C/uECBHUFZ4yfyM2wcY56WbZKo7eVCRBGI5AI6XpfhiSZGMbOWwHuCjSUrmVYFFv8euxn71OgPl4rjn1DqrcZzKhSZYgRKC5eMnTxH3evORdc96y1swP5NUKe2zaUxKMjFrN6lf+4pI3jgT8BPZl4ZaOW6ul5hCF2vxiOYozpyXfqfO5ThwrBInsB/yXOGbEdCxPSKCY2xyc76wH/6ynZLUwW7+xEqCjWEdrWb/bNOmTg5gqlacGbLh1soh5mQ1PJOssLBncXFwC0wgPUKk/yjZZTTWUYkZlVqE9G/whC8CcCpcK0K2nOX10ePwzxsteA8BC02bhN1oEuovUgxTQW/Gy5qPURJTuF+JEQGRmwicKw4dPY2NLTavfO+Zpj5bTIW+0LevXI57E/MQ X-Forefront-PRVS: 0854128AF0 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; SN1PR12MB0718; 23:7rfxxJUPy/szXBT2iIvSKVPt7BdY2LLnQQvc6aY4p?= =?us-ascii?Q?90YPLgEshOUC0rBOjVqbNMR7qQAq2aKz4ZrM2/JaX25lWn26YxzdIK5Sfa8n?= =?us-ascii?Q?Nx5LNRPr8/PZQGta5HIVSo5fC5zLPnbUQ6PaTqWl04cZMQ39b1Ym71UF7U+7?= =?us-ascii?Q?U0kt/T3DKOFmnIeksuDO/I/fw/dVOd1GqE42m7/a8eZwZlsXuk6w90c+0it9?= =?us-ascii?Q?U5GRPIkMTjnNKJZfhVaTk+EuqgoNVX1jkFEgkZF66ob9gBsebd0C3PmPKGBA?= =?us-ascii?Q?JQ1cDPDylyDYaKp8DMlmDVLlUnfSrxSa/jyBFx2oHlJQKRhUJDntjFSTHWyH?= =?us-ascii?Q?ry+iimA/5E5ernnUIDVQ10xx9gDykCruHKBEm80ty5hIhdKvMqrR7XDI6YKD?= =?us-ascii?Q?rAQymklu03nzggYUF9aa91Og9YnoJ7TJB9L1EOcr7Qpnc4yi2td8r6ehomYz?= =?us-ascii?Q?Kw3fqa9Job1Xjfpc04N1yEpYrvej6m4nMI45SQ/mhXlYYSKLSAhjEIGl/JWy?= =?us-ascii?Q?HMJeSRd5GOxe4wu5rfclOU/mp4FJ1G+tZ7JcozaLbgWQXv3GpFoABezYSdfO?= =?us-ascii?Q?s2QRE8nvQEFJSsEdUZAxh8uJ8eg1ViGQfrKSQoJA60ZSJar8bQweFF6cBphN?= =?us-ascii?Q?CoNc4LT5ODL1XZz6qkVjebRRQXdRAB8Ct0VGFwzDWD8IcMx1AD3Bugf1rWFT?= =?us-ascii?Q?w0cp6xdzk4wuLC+OLefbye59AefxtN3PSGExxiuhTZInRy4l1qER03W0Bz4I?= =?us-ascii?Q?a5RqtfjjzZu3lrIwHi5iqCMa6bZSPqWGoJNVRQv5wEvgdYTgj1sPXizKUvb+?= =?us-ascii?Q?wRAWgojXAC3pjTAb8cDVsCPrc2pn4W5WetVOiKxBj8LzQEmBYdc06L1wg05a?= =?us-ascii?Q?ofExG+oSjnaQcf+CLtGtYkuUaAoGcTJBz2LPjotpHJrcOI0ZB9q6mHz75Mhw?= =?us-ascii?Q?WJmhHcv6ZL60nQA0EFctO2zicDsbryiUJtdb5EYbckvYSGyN1/JsH96KiKSA?= =?us-ascii?Q?5kSAJZTnnDCdJ6l8tUrUjG7?= X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0718; 5:wCrsyjqRa4jhISpueRKNlm/OL3Ur9hS2Gbzo1YiPbRBSKLYTnuZk7wAjNMKxfnq84rresW+DfdKwa0difqlzlGVP3we7jkdhUjTr5s9EdAqIzFm6flXgKgJxTcEyMBSfIgpRPGHTM99mw8ANAlQpgA==; 24:HhN5vNRBEOy5EzYjHlv1eC2mjoSWPy6VquOMIr84WyNgZeBoXpyBny+gl0KfQE461AWegxA6rjdB90iKIU/L5opRS9pQpEzXczhih4qKh0Q=; 20:Xtpmne4WBorPRND41Fah5DKOx/vlFl1sUjWPBC9znMFr2s0UpmQeZilMo8BvcNKTEcQFr+r+DZ+O9mBJlvqKJP9ACFrycR2/L4E3ULBOTcRoBEI96h1rlwv7HtklSVdHVVu5zGm6IaObHjQjFlSmmziOCnKfUyUqU8RnhbeYgOHuIOS0+z+ub+3JxDvcc/7Ci3zeNkBh07+UB59qvYeObbui/tWBp6rH+/QZkaPwmCm+KlAb93TZn8veLsWB2jSp SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Feb 2016 22:28:30.5176 (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.221]; Helo=[atltwp01.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0718 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.2 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 Interface to set and ack DCE interrupts. Signed-off-by: Harry Wentland Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/dal/dc/irq/Makefile | 21 ++ .../drm/amd/dal/dc/irq/dce110/irq_service_dce110.c | 389 +++++++++++++++++++++ .../drm/amd/dal/dc/irq/dce110/irq_service_dce110.h | 34 ++ drivers/gpu/drm/amd/dal/dc/irq/irq_service.c | 177 ++++++++++ drivers/gpu/drm/amd/dal/dc/irq/irq_service.h | 85 +++++ 5 files changed, 706 insertions(+) create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/Makefile create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/irq_service.c create mode 100644 drivers/gpu/drm/amd/dal/dc/irq/irq_service.h diff --git a/drivers/gpu/drm/amd/dal/dc/irq/Makefile b/drivers/gpu/drm/amd/dal/dc/irq/Makefile new file mode 100644 index 000000000000..f1c5faf94b83 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/irq/Makefile @@ -0,0 +1,21 @@ +# +# Makefile for the 'audio' sub-component of DAL. +# It provides the control and status of HW adapter resources, +# that are global for the ASIC and sharable between pipes. + +IRQ = irq_service.o + +AMD_DAL_IRQ = $(addprefix $(AMDDALPATH)/dc/irq/,$(IRQ)) + +AMD_DAL_FILES += $(AMD_DAL_IRQ) + +############################################################################### +# DCE 11x +############################################################################### +ifdef CONFIG_DRM_AMD_DAL_DCE11_0 +IRQ_DCE11 = irq_service_dce110.o + +AMD_DAL_IRQ_DCE11 = $(addprefix $(AMDDALPATH)/dc/irq/dce110/,$(IRQ_DCE11)) + +AMD_DAL_FILES += $(AMD_DAL_IRQ_DCE11) +endif diff --git a/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c new file mode 100644 index 000000000000..4085b6f6e7fd --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.c @@ -0,0 +1,389 @@ +/* + * 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/logger_interface.h" + +#include "irq_service_dce110.h" + +#include "dce/dce_11_0_d.h" +#include "dce/dce_11_0_sh_mask.h" +#include "ivsrcid/ivsrcid_vislands30.h" + +static bool hpd_ack( + struct irq_service *irq_service, + const struct irq_source_info *info) +{ + uint32_t addr = info->status_reg; + uint32_t value = dm_read_reg(irq_service->ctx, addr); + uint32_t current_status = + get_reg_field_value( + value, + DC_HPD_INT_STATUS, + DC_HPD_SENSE_DELAYED); + + dal_irq_service_ack_generic(irq_service, info); + + value = dm_read_reg(irq_service->ctx, info->enable_reg); + + set_reg_field_value( + value, + current_status ? 0 : 1, + DC_HPD_INT_CONTROL, + DC_HPD_INT_POLARITY); + + dm_write_reg(irq_service->ctx, info->enable_reg, value); + + return true; +} + +static const struct irq_source_info_funcs hpd_irq_info_funcs = { + .set = NULL, + .ack = hpd_ack +}; + +static const struct irq_source_info_funcs hpd_rx_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static const struct irq_source_info_funcs pflip_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +static const struct irq_source_info_funcs vblank_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + +#define hpd_int_entry(reg_num)\ + [DC_IRQ_SOURCE_HPD1 + reg_num] = {\ + .enable_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\ + .enable_mask = DC_HPD_INT_CONTROL__DC_HPD_INT_EN_MASK,\ + .enable_value = {\ + DC_HPD_INT_CONTROL__DC_HPD_INT_EN_MASK,\ + ~DC_HPD_INT_CONTROL__DC_HPD_INT_EN_MASK\ + },\ + .ack_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\ + .ack_mask = DC_HPD_INT_CONTROL__DC_HPD_INT_ACK_MASK,\ + .ack_value = DC_HPD_INT_CONTROL__DC_HPD_INT_ACK_MASK,\ + .status_reg = mmHPD ## reg_num ## _DC_HPD_INT_STATUS,\ + .funcs = &hpd_irq_info_funcs\ + } + +#define hpd_rx_int_entry(reg_num)\ + [DC_IRQ_SOURCE_HPD1RX + reg_num] = {\ + .enable_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\ + .enable_mask = DC_HPD_INT_CONTROL__DC_HPD_RX_INT_EN_MASK,\ + .enable_value = {\ + DC_HPD_INT_CONTROL__DC_HPD_RX_INT_EN_MASK,\ + ~DC_HPD_INT_CONTROL__DC_HPD_RX_INT_EN_MASK },\ + .ack_reg = mmHPD ## reg_num ## _DC_HPD_INT_CONTROL,\ + .ack_mask = DC_HPD_INT_CONTROL__DC_HPD_RX_INT_ACK_MASK,\ + .ack_value = DC_HPD_INT_CONTROL__DC_HPD_RX_INT_ACK_MASK,\ + .status_reg = mmHPD ## reg_num ## _DC_HPD_INT_STATUS,\ + .funcs = &hpd_rx_irq_info_funcs\ + } +#define pflip_int_entry(reg_num)\ + [DC_IRQ_SOURCE_PFLIP1 + reg_num] = {\ + .enable_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_CONTROL,\ + .enable_mask =\ + GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\ + .enable_value = {\ + GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK,\ + ~GRPH_INTERRUPT_CONTROL__GRPH_PFLIP_INT_MASK_MASK},\ + .ack_reg = mmDCP ## reg_num ## _GRPH_INTERRUPT_STATUS,\ + .ack_mask = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\ + .ack_value = GRPH_INTERRUPT_STATUS__GRPH_PFLIP_INT_CLEAR_MASK,\ + .status_reg = mmDCP ## reg_num ##_GRPH_INTERRUPT_STATUS,\ + .funcs = &pflip_irq_info_funcs\ + } + +#define vsync_int_entry(reg_num) \ + [DC_IRQ_SOURCE_CRTC ## reg_num ## VSYNC] = dummy_irq_entry() + +#define vupdate_int_entry(reg_num)\ + [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ + .enable_reg = mmCRTC ## reg_num ## _CRTC_INTERRUPT_CONTROL,\ + .enable_mask =\ + CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\ + .enable_value = {\ + CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK,\ + ~CRTC_INTERRUPT_CONTROL__CRTC_V_UPDATE_INT_MSK_MASK},\ + .ack_reg = mmCRTC ## reg_num ## _CRTC_V_UPDATE_INT_STATUS,\ + .ack_mask =\ + CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ + .ack_value =\ + CRTC_V_UPDATE_INT_STATUS__CRTC_V_UPDATE_INT_CLEAR_MASK,\ + .funcs = &vblank_irq_info_funcs\ + } + +#define dummy_irq_entry() \ + {\ + .funcs = &dummy_irq_info_funcs\ + } + +#define i2c_int_entry(reg_num) \ + [DC_IRQ_SOURCE_I2C_DDC ## reg_num] = dummy_irq_entry() + +#define azalia_int_entry(reg_num) \ + [DC_IRQ_SOURCE_AZALIA ## reg_num] = dummy_irq_entry() + +#define dp_sink_int_entry(reg_num) \ + [DC_IRQ_SOURCE_DPSINK ## reg_num] = dummy_irq_entry() + +#define gpio_pad_int_entry(reg_num) \ + [DC_IRQ_SOURCE_GPIOPAD ## reg_num] = dummy_irq_entry() + +#define dc_underflow_int_entry(reg_num) \ + [DC_IRQ_SOURCE_DC ## reg_num ## UNDERFLOW] = dummy_irq_entry() + +static bool dummy_set( + struct irq_service *irq_service, + const struct irq_source_info *info, + bool enable) +{ + dal_logger_write( + irq_service->ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_IRQ_SERVICE, + "%s: called for non-implemented irq source\n", + __func__); + return false; +} + +static bool dummy_ack( + struct irq_service *irq_service, + const struct irq_source_info *info) +{ + dal_logger_write( + irq_service->ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_IRQ_SERVICE, + "%s: called for non-implemented irq source\n", + __func__); + return false; +} + +static const struct irq_source_info_funcs dummy_irq_info_funcs = { + .set = dummy_set, + .ack = dummy_ack +}; + +static const struct irq_source_info +irq_source_info_dce110[DAL_IRQ_SOURCES_NUMBER] = { + [DC_IRQ_SOURCE_INVALID] = dummy_irq_entry(), + hpd_int_entry(0), + hpd_int_entry(1), + hpd_int_entry(2), + hpd_int_entry(3), + hpd_int_entry(4), + hpd_int_entry(5), + hpd_rx_int_entry(0), + hpd_rx_int_entry(1), + hpd_rx_int_entry(2), + hpd_rx_int_entry(3), + hpd_rx_int_entry(4), + hpd_rx_int_entry(5), + i2c_int_entry(1), + i2c_int_entry(2), + i2c_int_entry(3), + i2c_int_entry(4), + i2c_int_entry(5), + i2c_int_entry(6), + azalia_int_entry(0), + azalia_int_entry(1), + azalia_int_entry(2), + azalia_int_entry(3), + azalia_int_entry(4), + azalia_int_entry(5), + dp_sink_int_entry(1), + dp_sink_int_entry(2), + dp_sink_int_entry(3), + dp_sink_int_entry(4), + dp_sink_int_entry(5), + dp_sink_int_entry(6), + vsync_int_entry(1), + vsync_int_entry(2), + vsync_int_entry(3), + vsync_int_entry(3), + vsync_int_entry(4), + vsync_int_entry(5), + [DC_IRQ_SOURCE_TIMER] = dummy_irq_entry(), + pflip_int_entry(0), + pflip_int_entry(1), + pflip_int_entry(2), + pflip_int_entry(3), + pflip_int_entry(4), + pflip_int_entry(5), + [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(), + gpio_pad_int_entry(0), + gpio_pad_int_entry(1), + gpio_pad_int_entry(2), + gpio_pad_int_entry(3), + gpio_pad_int_entry(4), + gpio_pad_int_entry(5), + gpio_pad_int_entry(6), + gpio_pad_int_entry(7), + gpio_pad_int_entry(8), + gpio_pad_int_entry(9), + gpio_pad_int_entry(10), + gpio_pad_int_entry(11), + gpio_pad_int_entry(12), + gpio_pad_int_entry(13), + gpio_pad_int_entry(14), + gpio_pad_int_entry(15), + gpio_pad_int_entry(16), + gpio_pad_int_entry(17), + gpio_pad_int_entry(18), + gpio_pad_int_entry(19), + gpio_pad_int_entry(20), + gpio_pad_int_entry(21), + gpio_pad_int_entry(22), + gpio_pad_int_entry(23), + gpio_pad_int_entry(24), + gpio_pad_int_entry(25), + gpio_pad_int_entry(26), + gpio_pad_int_entry(27), + gpio_pad_int_entry(28), + gpio_pad_int_entry(29), + gpio_pad_int_entry(30), + dc_underflow_int_entry(1), + dc_underflow_int_entry(2), + dc_underflow_int_entry(3), + dc_underflow_int_entry(4), + dc_underflow_int_entry(5), + dc_underflow_int_entry(6), + [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), + [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), + vupdate_int_entry(0), + vupdate_int_entry(1), + vupdate_int_entry(2), + vupdate_int_entry(3), + vupdate_int_entry(4), + vupdate_int_entry(5), +}; + +static enum dc_irq_source to_dal_irq_source( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id) +{ + switch (src_id) { + case VISLANDS30_IV_SRCID_D1_V_UPDATE_INT: + return DC_IRQ_SOURCE_VUPDATE1; + case VISLANDS30_IV_SRCID_D2_V_UPDATE_INT: + return DC_IRQ_SOURCE_VUPDATE2; + case VISLANDS30_IV_SRCID_D3_V_UPDATE_INT: + return DC_IRQ_SOURCE_VUPDATE3; + case VISLANDS30_IV_SRCID_D4_V_UPDATE_INT: + return DC_IRQ_SOURCE_VUPDATE4; + case VISLANDS30_IV_SRCID_D5_V_UPDATE_INT: + return DC_IRQ_SOURCE_VUPDATE5; + case VISLANDS30_IV_SRCID_D6_V_UPDATE_INT: + return DC_IRQ_SOURCE_VUPDATE6; + case VISLANDS30_IV_SRCID_D1_GRPH_PFLIP: + return DC_IRQ_SOURCE_PFLIP1; + case VISLANDS30_IV_SRCID_D2_GRPH_PFLIP: + return DC_IRQ_SOURCE_PFLIP2; + case VISLANDS30_IV_SRCID_D3_GRPH_PFLIP: + return DC_IRQ_SOURCE_PFLIP3; + case VISLANDS30_IV_SRCID_D4_GRPH_PFLIP: + return DC_IRQ_SOURCE_PFLIP4; + case VISLANDS30_IV_SRCID_D5_GRPH_PFLIP: + return DC_IRQ_SOURCE_PFLIP5; + case VISLANDS30_IV_SRCID_D6_GRPH_PFLIP: + return DC_IRQ_SOURCE_PFLIP6; + + case VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A: + /* generic src_id for all HPD and HPDRX interrupts */ + switch (ext_id) { + case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_A: + return DC_IRQ_SOURCE_HPD1; + case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_B: + return DC_IRQ_SOURCE_HPD2; + case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_C: + return DC_IRQ_SOURCE_HPD3; + case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_D: + return DC_IRQ_SOURCE_HPD4; + case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_E: + return DC_IRQ_SOURCE_HPD5; + case VISLANDS30_IV_EXTID_HOTPLUG_DETECT_F: + return DC_IRQ_SOURCE_HPD6; + case VISLANDS30_IV_EXTID_HPD_RX_A: + return DC_IRQ_SOURCE_HPD1RX; + case VISLANDS30_IV_EXTID_HPD_RX_B: + return DC_IRQ_SOURCE_HPD2RX; + case VISLANDS30_IV_EXTID_HPD_RX_C: + return DC_IRQ_SOURCE_HPD3RX; + case VISLANDS30_IV_EXTID_HPD_RX_D: + return DC_IRQ_SOURCE_HPD4RX; + case VISLANDS30_IV_EXTID_HPD_RX_E: + return DC_IRQ_SOURCE_HPD5RX; + case VISLANDS30_IV_EXTID_HPD_RX_F: + return DC_IRQ_SOURCE_HPD6RX; + default: + return DC_IRQ_SOURCE_INVALID; + } + break; + + default: + return DC_IRQ_SOURCE_INVALID; + } +} + +static const struct irq_service_funcs irq_service_funcs_dce110 = { + .to_dal_irq_source = to_dal_irq_source +}; + +bool construct( + struct irq_service *irq_service, + struct irq_service_init_data *init_data) +{ + if (!dal_irq_service_construct(irq_service, init_data)) + return false; + + irq_service->info = irq_source_info_dce110; + irq_service->funcs = &irq_service_funcs_dce110; + + return true; +} + +struct irq_service *dal_irq_service_dce110_create( + struct irq_service_init_data *init_data) +{ + struct irq_service *irq_service = dm_alloc(init_data->ctx, sizeof(*irq_service)); + + if (!irq_service) + return NULL; + + if (construct(irq_service, init_data)) + return irq_service; + + dm_free(init_data->ctx, irq_service); + return NULL; +} diff --git a/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h new file mode 100644 index 000000000000..d6c28e940403 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/irq/dce110/irq_service_dce110.h @@ -0,0 +1,34 @@ +/* + * 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_IRQ_SERVICE_DCE110_H__ +#define __DAL_IRQ_SERVICE_DCE110_H__ + +#include "../irq_service.h" + +struct irq_service *dal_irq_service_dce110_create( + struct irq_service_init_data *init_data); + +#endif diff --git a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c new file mode 100644 index 000000000000..137233134a53 --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.c @@ -0,0 +1,177 @@ +/* + * 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/irq_service_interface.h" +#include "include/logger_interface.h" + +#if defined(CONFIG_DRM_AMD_DAL_DCE11_0) +#include "dce110/irq_service_dce110.h" +#endif + +#include "irq_service.h" + +bool dal_irq_service_construct( + struct irq_service *irq_service, + struct irq_service_init_data *init_data) +{ + if (!init_data || !init_data->ctx) + return false; + + irq_service->ctx = init_data->ctx; + return true; +} + +struct irq_service *dal_irq_service_create( + enum dce_version version, + struct irq_service_init_data *init_data) +{ + switch (version) { +#if defined(CONFIG_DRM_AMD_DAL_DCE10_0) + case DCE_VERSION_10_0: + return dal_irq_service_dce110_create(init_data); +#endif +#if defined(CONFIG_DRM_AMD_DAL_DCE11_0) + case DCE_VERSION_11_0: + return dal_irq_service_dce110_create(init_data); +#endif + default: + return NULL; + } +} + +void dal_irq_service_destroy(struct irq_service **irq_service) +{ + if (!irq_service || !*irq_service) { + BREAK_TO_DEBUGGER(); + return; + } + + dm_free((*irq_service)->ctx, *irq_service); + + *irq_service = NULL; +} + +const struct irq_source_info *find_irq_source_info( + struct irq_service *irq_service, + enum dc_irq_source source) +{ + if (source > DAL_IRQ_SOURCES_NUMBER || source < DC_IRQ_SOURCE_INVALID) + return NULL; + + return &irq_service->info[source]; +} + +void dal_irq_service_set_generic( + struct irq_service *irq_service, + const struct irq_source_info *info, + bool enable) +{ + uint32_t addr = info->enable_reg; + uint32_t value = dm_read_reg(irq_service->ctx, addr); + + value = (value & ~info->enable_mask) | + (info->enable_value[enable ? 0 : 1] & info->enable_mask); + dm_write_reg(irq_service->ctx, addr, value); +} + +bool dal_irq_service_set( + struct irq_service *irq_service, + enum dc_irq_source source, + bool enable) +{ + const struct irq_source_info *info = + find_irq_source_info(irq_service, source); + + if (!info) { + dal_logger_write( + irq_service->ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_IRQ_SERVICE, + "%s: cannot find irq info table entry for %d\n", + __func__, + source); + return false; + } + + dal_irq_service_ack(irq_service, source); + + if (info->funcs->set) + return info->funcs->set(irq_service, info, enable); + + dal_irq_service_set_generic(irq_service, info, enable); + + return true; +} + +void dal_irq_service_ack_generic( + struct irq_service *irq_service, + const struct irq_source_info *info) +{ + uint32_t addr = info->ack_reg; + uint32_t value = dm_read_reg(irq_service->ctx, addr); + + value = (value & ~info->ack_mask) | + (info->ack_value & info->ack_mask); + dm_write_reg(irq_service->ctx, addr, value); +} + +bool dal_irq_service_ack( + struct irq_service *irq_service, + enum dc_irq_source source) +{ + const struct irq_source_info *info = + find_irq_source_info(irq_service, source); + + if (!info) { + dal_logger_write( + irq_service->ctx->logger, + LOG_MAJOR_ERROR, + LOG_MINOR_COMPONENT_IRQ_SERVICE, + "%s: cannot find irq info table entry for %d\n", + __func__, + source); + return false; + } + + if (info->funcs->ack) + return info->funcs->ack(irq_service, info); + + dal_irq_service_ack_generic(irq_service, info); + + return true; +} + +enum dc_irq_source dal_irq_service_to_irq_source( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id) +{ + return irq_service->funcs->to_dal_irq_source( + irq_service, + src_id, + ext_id); +} diff --git a/drivers/gpu/drm/amd/dal/dc/irq/irq_service.h b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.h new file mode 100644 index 000000000000..a2a2d6965c2f --- /dev/null +++ b/drivers/gpu/drm/amd/dal/dc/irq/irq_service.h @@ -0,0 +1,85 @@ +/* + * 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_IRQ_SERVICE_H__ +#define __DAL_IRQ_SERVICE_H__ + +#include "include/irq_service_interface.h" + +#include "irq_types.h" + +struct irq_service; +struct irq_source_info; + +struct irq_source_info_funcs { + bool (*set)( + struct irq_service *irq_service, + const struct irq_source_info *info, + bool enable); + bool (*ack)( + struct irq_service *irq_service, + const struct irq_source_info *info); +}; + +struct irq_source_info { + uint32_t src_id; + uint32_t ext_id; + uint32_t enable_reg; + uint32_t enable_mask; + uint32_t enable_value[2]; + uint32_t ack_reg; + uint32_t ack_mask; + uint32_t ack_value; + uint32_t status_reg; + const struct irq_source_info_funcs *funcs; +}; + +struct irq_service_funcs { + enum dc_irq_source (*to_dal_irq_source)( + struct irq_service *irq_service, + uint32_t src_id, + uint32_t ext_id); +}; + +struct irq_service { + struct dc_context *ctx; + const struct irq_source_info *info; + const struct irq_service_funcs *funcs; +}; + +bool dal_irq_service_construct( + struct irq_service *irq_service, + struct irq_service_init_data *init_data); + +void dal_irq_service_ack_generic( + struct irq_service *irq_service, + const struct irq_source_info *info); + +void dal_irq_service_set_generic( + struct irq_service *irq_service, + const struct irq_source_info *info, + bool enable); + +#endif