From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a01:111:f400:fe49::72c; helo=nam03-dm3-obe.outbound.protection.outlook.com; envelope-from=christopher.co@microsoft.com; receiver=edk2-devel@lists.01.org Received: from NAM03-DM3-obe.outbound.protection.outlook.com (mail-dm3nam03on072c.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe49::72c]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D4E452098EAB9 for ; Thu, 19 Jul 2018 23:33:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=twbb46x7YDHvkCPDYp2Uyxiiv4oY5SVC6H3gIASRCqw=; b=ly3E4mcxd0xeFvsNrx8ZjvMEQ4CJbVlE82ZaO+yGs6+mdcc89EGHwFkaEHuCm/nhWs4MaCSagr+qxjWw68Q9SNBkonN6rmGQSjBrJ/UHJlRIVwyKW0r8Tk0b51DW8+hfg7Wivtgpsr8DUzIKgJ6hse2VlV5zjALnhzegPbDpCdU= Received: from SN6PR2101MB1136.namprd21.prod.outlook.com (52.132.114.25) by SN6PR2101MB1117.namprd21.prod.outlook.com (52.132.115.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.995.1; Fri, 20 Jul 2018 06:33:48 +0000 Received: from SN6PR2101MB1136.namprd21.prod.outlook.com ([fe80::78f8:214:33a:3c4]) by SN6PR2101MB1136.namprd21.prod.outlook.com ([fe80::78f8:214:33a:3c4%5]) with mapi id 15.20.0995.008; Fri, 20 Jul 2018 06:33:48 +0000 From: Chris Co To: "edk2-devel@lists.01.org" CC: Ard Biesheuvel , Leif Lindholm , Michael D Kinney Thread-Topic: [PATCH edk2-platforms 04/13] Silicon/NXP: Add i.MX6 Timer DXE driver Thread-Index: AQHUH/OdNl4R4AQ49UeoQG0MCBsyEA== Date: Fri, 20 Jul 2018 06:33:48 +0000 Message-ID: <20180720063328.26856-5-christopher.co@microsoft.com> References: <20180720063328.26856-1-christopher.co@microsoft.com> In-Reply-To: <20180720063328.26856-1-christopher.co@microsoft.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: CY4PR18CA0029.namprd18.prod.outlook.com (2603:10b6:903:9a::15) To SN6PR2101MB1136.namprd21.prod.outlook.com (2603:10b6:805:4::25) x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [2001:4898:80e8:a:75ac:13c7:7dde:5215] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; SN6PR2101MB1117; 6:VL4l2SUQVRfaO9MOsNK2tRo6UX3DgJ6+2rvnQrojuLSYkTqW0Q6sKyrhuKM/mFM/MnX+zyLuSHzpZW5hAYyEfALS6tFTsi46mfU6isLotSZU4AJcLFrX2o9MCPheVyvwWWcm5jCQBJj5pyCnS+Rz2Gd2oUYkKFGdcJpoQck3YF88V7F+57g3PuGrQ+2n2uCoqb8o/sv+mmKlGshai9KMEgG4m+s+x5k0z/zOETARVCNtCEJcR1tYViBU9nBRBWT9gmxwODRK6qgtythwFuiqsHfoVtVP7sZWmiVYtbf6A/na8eVhqsSw28Ucv0wNZuvgSsE1TMpxhp1SwwvpdPj6cGwVJwcZbb49AO+DZsO8fZYsXLYbsmTmBfMBMR1mAqMICmjcrpQ81kZPFPyiimbHqu7kmA79FNE4q7dfxbxxCqhObk7qhJKoS34AfbidcXjUt/qlTKgHIb9bmq53tRzmbw==; 5:FVwF/m0kHlDzAqHM52YDLgoE8AV9fqapmAtNfZnvO+VyoFHmexuYLEcYm4OjXppFb8P9yS3gAfKKMqCdxC/KPH9bKUIDyofqf4w0WhrD9zXIdMQQazFbpXH0SK5qAEh3xnub0pr3VJ1ztHv7YomT6oYocJ+i4+Hn2rXAblzoomQ=; 7:RCUlzPPdAbnZQax9eH196FZI+vYAVNd77rpPI/xSnZ8t7eaGqbwO9boL/OMdtNk6wpThwCrP3ZArfPld2NqDmjD9FEGTW4WrwGXVUMJ8F/14NDgaD0ikD1Vb6KTZTUC8DJNN58IQs7cH6ZBIUDzfQKP4ydQtNr/gI+HGUWekGPOw8uMc7UQ0WNgiRYXw3Gvg1KnFnPwYBYprviiUx6aNkNyeOO/GneMmKryB3t7MEE+kMCM2voF4uu6+4fcp0G7k x-ms-office365-filtering-correlation-id: 23dec226-dba7-49e5-1f14-08d5ee0abfd7 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(5600067)(711020)(4618075)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(2017052603328)(7193020); SRVR:SN6PR2101MB1117; x-ms-traffictypediagnostic: SN6PR2101MB1117: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Christopher.Co@microsoft.com; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(28532068793085)(278428928389397)(89211679590171)(228905959029699); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(10201501046)(3231311)(944501410)(52105095)(2018427008)(93006095)(93001095)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011)(7699016); SRVR:SN6PR2101MB1117; BCL:0; PCL:0; RULEID:; SRVR:SN6PR2101MB1117; x-forefront-prvs: 073966E86B x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(1496009)(396003)(39860400002)(366004)(346002)(376002)(136003)(199004)(189003)(52116002)(8676002)(81156014)(105586002)(2616005)(446003)(53376002)(256004)(99286004)(46003)(11346002)(22452003)(106356001)(97736004)(6306002)(14444005)(6436002)(6506007)(386003)(72206003)(86612001)(6116002)(5660300001)(76176011)(25786009)(966005)(102836004)(1076002)(53936002)(81166006)(2900100001)(6512007)(478600001)(476003)(10290500003)(6916009)(16799955002)(186003)(2351001)(14454004)(5250100002)(36756003)(19627235002)(6486002)(54906003)(2501003)(10090500001)(86362001)(4326008)(8936002)(5640700003)(68736007)(2906002)(305945005)(15188155005)(486006)(7736002)(316002)(44824005); DIR:OUT; SFP:1102; SCL:1; SRVR:SN6PR2101MB1117; H:SN6PR2101MB1136.namprd21.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: 3ftFJ3CnxpBaYTZ0cCD39XN9vxZV558Ur7doNukGjR2EmlMCkG2vzKCf8u5JBKiy3m2EsQ/gAe8o23tTD9tJzd7AAkH30qW9iTN6aFOXBzPTLTW3NiWRXEVNIil9OsJDmd7hs3gL9Ft4W7clZkXvd3A0kHkqRn9kYzmqlKXYerZT2JiU7SDKjmTVCN16xTrsZUyPWhprpcCLdBq7Kdq7Mxnt6gMWmgp0TQMldmy2TvSYDB0X1I+kj2HoCFpYxF8OLFj+4+YYUMSrpv5UwofLz3OINbCVuers+aFrMpreV7Dr6GjG7dAZugzqtHRgHzSXfrYGPdmriIlMeWAgk6GNa67J1yLgwNGNmPj2oOvn01A= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 23dec226-dba7-49e5-1f14-08d5ee0abfd7 X-MS-Exchange-CrossTenant-originalarrivaltime: 20 Jul 2018 06:33:48.3423 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR2101MB1117 Subject: [PATCH edk2-platforms 04/13] Silicon/NXP: Add i.MX6 Timer DXE driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Jul 2018 06:33:51 -0000 Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable This adds DXE support for EPIT timer on NXP i.MX6 SoCs. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Christopher Co Cc: Ard Biesheuvel Cc: Leif Lindholm Cc: Michael D Kinney --- Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c | 268 ++++++++++++++++++= ++ Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf | 55 ++++ 2 files changed, 323 insertions(+) diff --git a/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c b/Silicon/NXP/iMX= 6Pkg/Drivers/TimerDxe/Timer.c new file mode 100644 index 000000000000..75c98dcff9ea --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c @@ -0,0 +1,268 @@ +/** @file +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the B= SD License +* which accompanies this distribution. The full text of the license may = be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +* +**/ + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// The notification function to call on every timer interrupt. +volatile EFI_TIMER_NOTIFY mTimerNotifyFunction =3D (EFI_TIMER_NOTIFY) NULL= ; +EFI_EVENT EfiExitBootServicesEvent =3D (EFI_EVENT) NULL; + +// Cached copy of the Hardware Interrupt protocol instance +EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt =3D NULL; + +// Cached interrupt vector +volatile UINTN mVector; +UINT64 mCurrentTimerPeriod; + +EFI_STATUS +EFIAPI +TimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +{ + DEBUG ((DEBUG_VERBOSE, "++TimerDriverRegisterHandler()\n")); + if ((NotifyFunction =3D=3D NULL) && (mTimerNotifyFunction =3D=3D NULL)) = { + return EFI_INVALID_PARAMETER; + } + + if ((NotifyFunction !=3D NULL) && (mTimerNotifyFunction !=3D NULL)) { + return EFI_ALREADY_STARTED; + } + + mTimerNotifyFunction =3D NotifyFunction; + DEBUG ((DEBUG_VERBOSE, "--TimerDriverRegisterHandler()=3Dok\n")); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +TimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +{ + EFI_STATUS Status; + UINT32 TimerCount; + UINT16 epitPreScalar; + + DEBUG ((DEBUG_VERBOSE, "++TimerDriverSetTimerPeriod(%d)\n", TimerPeriod)= ); + + PCSP_EPIT_REG g_pEPIT =3D (PCSP_EPIT_REG) CSP_BASE_REG_PA_EPIT1; + + DEBUG ((DEBUG_VERBOSE, "TimerDriverSetTimerPeriod() disable timer. EPIT_= REG adr=3D%p\n", g_pEPIT)); + + // First stop the timer. + INSREG32BF(&g_pEPIT->CR,EPIT_CR_EN,EPIT_CR_EN_DISABLE); + + if (TimerPeriod =3D=3D 0) { + Status =3D gInterrupt->DisableInterruptSource(gInterrupt, mVector); + mCurrentTimerPeriod =3D 0; + DEBUG ((DEBUG_VERBOSE, "--TimerDriverSetTimerPeriod() Timer Disabled\n= ")); + return Status; + } + + // configure EPIT to be sourced from iMX6 24 MHz crystal oscialltor per + // i.MX 6Dual/6Quad Applications Processor Reference Manual, Rev. 3, 07/= 2015 + // aim to have UEFI tick counting at 1 MHz clock or another frequency as= set in pcd value + epitPreScalar =3D 68; + DEBUG((DEBUG_VERBOSE, "TimerDriverSetTimerPeriod() using corrected EPIT = prescalar=3D%d\n", epitPreScalar)); + + OUTREG32(&g_pEPIT->CR, + CSP_BITFVAL(EPIT_CR_ENMOD, EPIT_CR_ENMOD_LOAD) | + CSP_BITFVAL(EPIT_CR_OCIEN, EPIT_CR_OCIEN_ENABLE) | + CSP_BITFVAL(EPIT_CR_RLD, EPIT_CR_RLD_RELOAD) | + CSP_BITFVAL(EPIT_CR_PRESCALAR, (epitPreScalar-1)) | // bits 4-15, 0= 00 to FFF. + CSP_BITFVAL(EPIT_CR_SWR, EPIT_CR_SWR_NORESET) | + CSP_BITFVAL(EPIT_CR_IOVW, EPIT_CR_IOVW_OVR) | + CSP_BITFVAL(EPIT_CR_DBGEN, EPIT_CR_DBGEN_ACTIVE) | + CSP_BITFVAL(EPIT_CR_WAITEN, EPIT_CR_WAITEN_ENABLE) | + CSP_BITFVAL(EPIT_CR_DOZEN, EPIT_CR_DOZEN_ENABLE) | + CSP_BITFVAL(EPIT_CR_STOPEN, EPIT_CR_STOPEN_ENABLE) | + CSP_BITFVAL(EPIT_CR_OM, EPIT_CR_OM_DICONNECT) | + CSP_BITFVAL(EPIT_CR_CLKSRC, EPIT_CR_CLKSRC_IPGCLK)); // source is cr= ystal clock source (24 MHz) + + // Clear timer compare interrupt flag (write-1-clear) + OUTREG32(&g_pEPIT->SR, CSP_BITFMASK(EPIT_SR_OCIF)); + // Set the new compare value + TimerCount =3D (UINT32)(TimerPeriod / 10); + + if((UINT64)TimerCount > (UINT64)0xffffffff) + TimerCount =3D 0xffffffff; + + mCurrentTimerPeriod =3D TimerPeriod; + + OUTREG32(&g_pEPIT->CMPR, TimerCount); + OUTREG32(&g_pEPIT->LR, TimerCount); + Status =3D gInterrupt->EnableInterruptSource(gInterrupt, mVector); + // turn the timer on + INSREG32BF(&g_pEPIT->CR,EPIT_CR_EN,EPIT_CR_EN_ENABLE); + + DEBUG ((DEBUG_VERBOSE, "--TimerDriverSetTimerPeriod(%d)=3D%Xh\n", TimerP= eriod,Status)); + return Status; +} + +EFI_STATUS +EFIAPI +TimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +{ + *TimerPeriod =3D mCurrentTimerPeriod; + DEBUG ((DEBUG_VERBOSE, "+-TimerDriverGetTimerPeriod(%d)=3Dok\n", mCurren= tTimerPeriod)); + return EFI_SUCCESS; +} + +VOID +EFIAPI +TimerInterruptHandler ( + IN HARDWARE_INTERRUPT_SOURCE Source, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EFI_TPL OriginalTPL; + PCSP_EPIT_REG g_pEPIT =3D (PCSP_EPIT_REG) CSP_BASE_REG_PA_EPIT1; + + // + // DXE core uses this callback for the EFI timer tick. The DXE core uses= locks + // that raise to TPL_HIGH and then restore back to current level. Thus w= e need + // to make sure TPL level is set to TPL_HIGH while we are handling the t= imer tick. + // + OriginalTPL =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); + + // Check if the timer interrupt is active + if (INREG32 (&g_pEPIT->SR) !=3D 0) { + // Acknowledge the EPIT interrupt + OUTREG32 (&g_pEPIT->SR, 0x1); + + // Signal end of interrupt early to help avoid losing subsequent ticks= from long duration handlers + gInterrupt->EndOfInterrupt (gInterrupt, Source); + + if (mTimerNotifyFunction) { + mTimerNotifyFunction (mCurrentTimerPeriod); + } + } + + gBS->RestoreTPL (OriginalTPL); +} + +EFI_STATUS +EFIAPI +TimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +{ + return EFI_UNSUPPORTED; +} + +EFI_TIMER_ARCH_PROTOCOL gTimer =3D { + TimerDriverRegisterHandler, + TimerDriverSetTimerPeriod, + TimerDriverGetTimerPeriod, + TimerDriverGenerateSoftInterrupt +}; + +VOID +EFIAPI +ExitBootServicesEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "Disabling EPIT timer on ExitBootServicesEvent")); + + // Disable the timer + Status =3D TimerDriverSetTimerPeriod(&gTimer, 0); + ASSERT_EFI_ERROR (Status); +} + +EFI_STATUS +EFIAPI +TimerInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HANDLE Handle =3D NULL; + EFI_STATUS Status; + DEBUG ((DEBUG_VERBOSE, "++TimerInitialize()\n")); + + mVector =3D IRQ_EPIT1; + + // Find the interrupt controller protocol. ASSERT if not found. + Status =3D gBS->LocateProtocol ( + &gHardwareInterruptProtocolGuid, + NULL, + (VOID **) &gInterrupt); + + ASSERT_EFI_ERROR (Status); + + // Disable the timer + Status =3D TimerDriverSetTimerPeriod (&gTimer, 0); + ASSERT_EFI_ERROR (Status); + + // Install interrupt handler + Status =3D gInterrupt->RegisterInterruptSource (gInterrupt, mVector, Tim= erInterruptHandler); + ASSERT_EFI_ERROR (Status); + + // Set up default timer + Status =3D TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32 (PcdTimerPe= riod)); + ASSERT_EFI_ERROR (Status); + + DEBUG (( + DEBUG_VERBOSE, + "EPIT Timer initialized to default period %d x 100ns ~ %dms\n", + FixedPcdGet32(PcdTimerPeriod), + FixedPcdGet32(PcdTimerPeriod) / 10000)); + + // Install the Timer Architectural Protocol onto a new handle + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiTimerArchProtocolGuid, + &gTimer, + NULL); + + ASSERT_EFI_ERROR(Status); + + // Register for an ExitBootServicesEvent + Status =3D gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_NOTIFY, + ExitBootServicesEvent, + NULL, + &EfiExitBootServicesEvent); + + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_VERBOSE, "--TimerInitialize()\n")); + return Status; +} diff --git a/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf b/Silicon/NX= P/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf new file mode 100644 index 000000000000..d574b99533ca --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf @@ -0,0 +1,55 @@ +#/** @file +# +# Copyright (c) 2009, Apple Inc. All rights reserved.
+# Copyright (c) Microsoft Corporation. All rights reserved. +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD License +# which accompanies this distribution. The full text of the license may = be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IM= PLIED. +# +#**/ + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D iMX6TimerDxe + FILE_GUID =3D 7CAF576F-F1D9-4104-A922-CB64537FD7AE + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D TimerInitialize + +[Sources.common] + Timer.c + +[Packages] + MdePkg/MdePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + Silicon/NXP/iMX6Pkg/iMX6Pkg.dec + +[LibraryClasses] + BaseLib + UefiRuntimeServicesTableLib + PerformanceLib + UefiLib + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + UefiDriverEntryPoint + IoLib + +[Guids] + +[Protocols] + gEfiTimerArchProtocolGuid + gHardwareInterruptProtocolGuid + +[Pcd.common] + gEmbeddedTokenSpaceGuid.PcdTimerPeriod + gEmbeddedTokenSpaceGuid.PcdEmbeddedFdPerformanceCounterPeriodInNanosecon= ds + +[Depex] + gHardwareInterruptProtocolGuid --=20 2.16.2.gvfs.1.33.gf5370f1