From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.38.135; helo=nam02-bl2-obe.outbound.protection.outlook.com; envelope-from=christopher.co@microsoft.com; receiver=edk2-devel@lists.01.org Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-bl2nam02on0135.outbound.protection.outlook.com [104.47.38.135]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 483B6211518F1 for ; Fri, 21 Sep 2018 01:26:11 -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=BJ4EsQ7kJzeYAymcQf33OqEgVSqhuC1+vxpHiaLjlKY=; b=ceFz8veqTl0/HU0b/P96UTgSXl7+OtRxASGo6qNsl2cPyiaQiVrbCRXI+K6WHh/b0g+YoaaVUGLbRNipIRrAVjNcL6Z4o+8zeIUiUXDPgwLYoOQCYyqnZiZYAioqgzEAnejCALf/Grtm5NB4owpFeGIPiDGJRfelQDzavmbZPOc= Received: from DM5PR2101MB1128.namprd21.prod.outlook.com (52.132.133.20) by DM5PR2101MB0727.namprd21.prod.outlook.com (10.167.110.39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1185.6; Fri, 21 Sep 2018 08:26:09 +0000 Received: from DM5PR2101MB1128.namprd21.prod.outlook.com ([fe80::81f8:300e:d90:d49]) by DM5PR2101MB1128.namprd21.prod.outlook.com ([fe80::81f8:300e:d90:d49%3]) with mapi id 15.20.1164.008; Fri, 21 Sep 2018 08:26:09 +0000 From: Chris Co To: "edk2-devel@lists.01.org" CC: Ard Biesheuvel , Leif Lindholm , Michael D Kinney Thread-Topic: [PATCH edk2-platforms 17/27] Silicon/NXP: Add i.MX6 USB Phy Library Thread-Index: AQHUUYS/GvAKY8UZdkifCMG0yfZ+lg== Date: Fri, 21 Sep 2018 08:26:09 +0000 Message-ID: <20180921082542.35768-18-christopher.co@microsoft.com> References: <20180921082542.35768-1-christopher.co@microsoft.com> In-Reply-To: <20180921082542.35768-1-christopher.co@microsoft.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: MWHPR17CA0054.namprd17.prod.outlook.com (2603:10b6:300:93::16) To DM5PR2101MB1128.namprd21.prod.outlook.com (2603:10b6:4:a8::20) x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [2001:4898:80e8:8:388a:edc9:7085:c18] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DM5PR2101MB0727; 6:OQrPurpKxetQBJtRO+4qCmw0hCeie4Bxx+HPUVMPph0jwU8tX7dWNQ+Yt/oiSOyHrdxEMQ5xZTBojLLlz0/wVActXVtqz28vX4akIeF1wjjedTYHMzxM92AeeTuyH+IYeUGbiB7A3ayFi7dn+4MTNjtQ8zOKSKHHqvcuI5EsWsRU4gDMq9QwNtozM3zureEOl/K8QiqOitfbBf3Ky3RyW7LZxTn+nDk54uzwCSwMNEMYB8uqNHEdoV3LASjsy7KXbOk9ZJ7jBJbqjAS3zVlMva55L57FE4v7ZygScqRvZwdF9/enBn/vksIwASRF/iRk2+5JdviKOYanUEq/eTL7CEXsDsEsSlPgAh3ceRvH8rakIfHUH5PDr28qnq/cuwI9cY3tDHtnMhbHFkcm9VKIr2anj941/2RfNJK1PFMArXg/DGKi1YBTyvrB/CleuD6VbtcpsYtBPXnfXAfEn20Klg==; 5:1wpVeMg7A5NdgfZkZq9Pfh2KZfhoGhq79khc2XTNESnNk6hpOx123MtVUIHyeMQMaLOQ2GU8QdSiNHN1EbRNBqO9X+kFZICgoU+7pvhN96xhTPknuk8oKHv3bRp+HRyK47ww+1pg0YFUiVDzuOEIquu0vFfcHTre9B5/+g+rs4c=; 7:I9ghjhSPyWTJtL+z80c02uXg3Ux9RQSqVW5RoKxsx1vIN9logeZq6kWhCiWj3K7fYdRTYCpjnhkImvlJNjMVXVNd0OkJKli3EYOy63ghCOJR4kE3mzBJOzhaEVxcDC85ZoFKVh6KcynN5AzXfvmkfAHIp4kuDu2oGesWQtMY3OBilYfz/GSGZuZBbkaLU19YoD0CzGqlnKth+Wt4qU2RkaPxRUvQTJfgfm3cnm9aNtnv7DBlgi7cFwMS5DOorEne x-ms-office365-filtering-correlation-id: d05cd000-a0e0-4558-7016-08d61f9be1de x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7193020); SRVR:DM5PR2101MB0727; x-ms-traffictypediagnostic: DM5PR2101MB0727: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(28532068793085)(89211679590171)(12401385986421)(228905959029699); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3231355)(2280164)(944501410)(52105095)(2018427008)(93006095)(93001095)(3002001)(10201501046)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123560045)(20161123564045)(20161123558120)(201708071742011)(7699051)(76991041); SRVR:DM5PR2101MB0727; BCL:0; PCL:0; RULEID:; SRVR:DM5PR2101MB0727; x-forefront-prvs: 0802ADD973 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(1496009)(39860400002)(396003)(136003)(376002)(366004)(346002)(199004)(189003)(8676002)(81156014)(25786009)(446003)(2900100001)(102836004)(46003)(52116002)(6346003)(81166006)(11346002)(105586002)(2351001)(8936002)(386003)(4326008)(76176011)(6506007)(10090500001)(5250100002)(7736002)(2616005)(486006)(305945005)(53376002)(6116002)(186003)(16799955002)(1076002)(2501003)(476003)(6916009)(99286004)(22452003)(97736004)(45954006)(71200400001)(71190400001)(72206003)(478600001)(966005)(6306002)(10290500003)(5640700003)(14454004)(36756003)(86362001)(19627235002)(6436002)(15188155005)(2906002)(86612001)(106356001)(54906003)(316002)(6486002)(256004)(6512007)(14444005)(68736007)(5660300001)(53936002)(60540400001); DIR:OUT; SFP:1102; SCL:1; SRVR:DM5PR2101MB0727; H:DM5PR2101MB1128.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) authentication-results: spf=none (sender IP is ) smtp.mailfrom=Christopher.Co@microsoft.com; x-microsoft-antispam-message-info: FJvDlAhRd+UQ+2SMTwvmCzm6eUVdPW0ZvxFsZOyJ6oZVcOcUElogxYcCalR2zK8dCkJJ5RfsqPab0qioNLG0jn96CIEz4Bt5arRZITD9MHMymaMcmnGzV/ifC/anfYjcTSxr7rYhduzHuU6zmuNdRXVY4yYUg5KyMKkEcGczLc7GCSSoo8oyu7XF6fxGuCBl4LzcqujQKnSRkY+v+tZhouYskDw7sLO3nNTta+dxw5HQ8GVD86ayA5heZwAuIrXCOKyUsDYwYwJsZE6pvBn+fmW2RyDM7vPR1hi9UrrgKoY0gBOHycLQmlgG7FahI1Igo5GP5gP/b+nLCyuV4aGbySPr+p8bajk4dFrpySEUZVDXBX51w5P55jV6R3DL0Wa9RvTccGaJwtyFYR2cTB/SslYpZWwfAURVls8JxsKPZS/F8pRsqVnW2vL8NNNum93zNVQwGDIL5uYXhPUUkhKmY6uNUO0ujX/aHobsJRbrjqObHwuAePxRF4gynP4swqeuJqjHCtnX0aHi05fFsq4s021Cy+doV9zkUUFpwF8hIEZpNAw8tI+rAraxKIYyyYhO spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: d05cd000-a0e0-4558-7016-08d61f9be1de X-MS-Exchange-CrossTenant-originalarrivaltime: 21 Sep 2018 08:26:09.3878 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR2101MB0727 Subject: [PATCH edk2-platforms 17/27] Silicon/NXP: Add i.MX6 USB Phy Library X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Sep 2018 08:26:11 -0000 Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable This adds support for configuring the USB EHCI PHY 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/Include/iMX6UsbPhy.h | 20 ++ Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c | 328 ++++++++= ++++++++++++ Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf | 43 +++ 3 files changed, 391 insertions(+) diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h b/Silicon/NXP/iMX6Pkg= /Include/iMX6UsbPhy.h new file mode 100644 index 000000000000..153c5461a6ad --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h @@ -0,0 +1,20 @@ +/** @file +* +* Copyright (c) 2018 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. +* +**/ + +#ifndef _IMX6_USB_PHY_H_ +#define _IMX6_USB_PHY_H_ + +EFI_STATUS ImxUsbPhyInit (IMX_USBPHY_ID ImxUsbPhyId); + +#endif // _IMX6_USB_PHY_H_ diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c b/Silic= on/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c new file mode 100644 index 000000000000..317d17d14844 --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c @@ -0,0 +1,328 @@ +/** @file +* +* Copyright (c) 2018 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 + +#define USB_PHY_PLL_LOCK_TIMEOUT_USEC (UINT32)(1000*1000) +#define USB_EHCI_STOP_RESET_TIMEOUT_USEC (UINT32)(1000*1000) + +#define IMX_CCM_ANALOG_PLL_USB1_REG_LOCK 0x80000000 +#define IMX_USB_CMD_REG_RUN 0x00000001 +#define IMX_USB_CMD_REG_RESET 0x00000002 + +/** + Wait for a register bit to be on/off +**/ +EFI_STATUS +RegisterWaitBit ( + IN volatile VOID *RegisterAddr, + IN UINT32 Mask, + IN BOOLEAN IsWaitOn, + IN UINT32 TimeOutUsec + ) +{ + UINT32 RegisterValue; + UINT32 TimeUsec; + + TimeUsec =3D 0; + do { + RegisterValue =3D MmioRead32 ((UINTN)RegisterAddr) & Mask; + if (((RegisterValue =3D=3D Mask) && IsWaitOn) || ((RegisterValue =3D= =3D 0) + && !IsWaitOn)) { + return EFI_SUCCESS; + } + + MicroSecondDelay (10); + TimeUsec +=3D 10; + } while (TimeUsec < TimeOutUsec); + + return EFI_TIMEOUT; +} + +/** + Turn on the 480Mhz PLL +**/ +EFI_STATUS +ImxUsbPhyEnablePll ( + IN IMX_USBPHY_ID ImxUsbPhyId + ) +{ + volatile IMX_CCM_ANALOG_REGISTERS *CcmAnaRegsPtr; + volatile IMX_CCM_ANALOG_PLL_USB1_REG *PllUsbClrRegPtr; + volatile IMX_CCM_ANALOG_PLL_USB1_REG *PllUsbSetRegPtr; + IMX_CCM_ANALOG_PLL_USB1_REG PllUsbClrReg; + IMX_CCM_ANALOG_PLL_USB1_REG PllUsbSetReg; + EFI_STATUS Status; + + CcmAnaRegsPtr =3D (IMX_CCM_ANALOG_REGISTERS *)IMX_CCM_ANALOG_BASE; + + switch (ImxUsbPhyId) { + case IMX_USBPHY0: + PllUsbClrRegPtr =3D (IMX_CCM_ANALOG_PLL_USB1_REG *)&CcmAnaRegsPtr->PLL= _USB1_CLR; + PllUsbSetRegPtr =3D (IMX_CCM_ANALOG_PLL_USB1_REG *)&CcmAnaRegsPtr->PLL= _USB1_SET; + break; + case IMX_USBPHY1: + PllUsbClrRegPtr =3D (IMX_CCM_ANALOG_PLL_USB1_REG *)&CcmAnaRegsPtr->PLL= _USB2_CLR; + PllUsbSetRegPtr =3D (IMX_CCM_ANALOG_PLL_USB1_REG *)&CcmAnaRegsPtr->PLL= _USB2_SET; + break; + default: + return EFI_INVALID_PARAMETER; + } + + PllUsbClrReg.AsUint32 =3D 0; + PllUsbClrReg.BYPASS =3D 1; + MmioWrite32 ((UINTN)PllUsbClrRegPtr, PllUsbClrReg.AsUint32); + + PllUsbSetReg.AsUint32 =3D 0; + PllUsbSetReg.EN_USB_CLKS =3D 1; + PllUsbSetReg.POWER =3D 1; + PllUsbSetReg.ENABLE =3D 1; + MmioWrite32 ((UINTN)PllUsbSetRegPtr, PllUsbSetReg.AsUint32); + + // Wait for PLL to lock + Status =3D RegisterWaitBit ( + PllUsbSetRegPtr, + IMX_CCM_ANALOG_PLL_USB1_REG_LOCK, + TRUE, + USB_PHY_PLL_LOCK_TIMEOUT_USEC); + + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "PLL 480Mhz failed to lock for PHY %d\n", + (UINT32)ImxUsbPhyId)); + // On failure disable the PHY + PllUsbClrReg.AsUint32 =3D 0; + PllUsbSetReg.EN_USB_CLKS =3D 1; + PllUsbSetReg.POWER =3D 1; + PllUsbSetReg.ENABLE =3D 1; + MmioWrite32 ((UINTN)PllUsbClrRegPtr, PllUsbSetReg.AsUint32); + return Status; + } + + return EFI_SUCCESS; +} + +/** + Reset the EHCI controller associated with the given PHY. +**/ +EFI_STATUS +ImxUsbEhciResetController ( + IN IMX_USBPHY_ID ImxUsbPhyId + ) +{ + volatile USB_USBCMD_REG *UsbCmdRegPtr; + volatile USB_USBMODE_REG *UsbModeRegPtr; + EFI_STATUS Status; + USB_USBCMD_REG UsbCmdReg; + USB_USBMODE_REG UsbModeReg; + + switch (ImxUsbPhyId) { + case IMX_USBPHY0: + UsbCmdRegPtr =3D (USB_USBCMD_REG *) (IMX_USBCORE_BASE + IMX_USBCORE_LE= NGTH * 0 + + IMX_USBCMD_OFFSET); + break; + case IMX_USBPHY1: + UsbCmdRegPtr =3D (USB_USBCMD_REG *) (IMX_USBCORE_BASE + IMX_USBCORE_LE= NGTH * 1 + + IMX_USBCMD_OFFSET); + break; + default: + return EFI_INVALID_PARAMETER; + } + + // The host controller can only be reset when it is stopped. + UsbCmdReg.AsUint32 =3D MmioRead32 ((UINTN)UsbCmdRegPtr); + UsbCmdReg.RS =3D 0; + MmioWrite32 ((UINTN)UsbCmdRegPtr, UsbCmdReg.AsUint32); + + // Wait for controller to stop + Status =3D RegisterWaitBit ( + UsbCmdRegPtr, + IMX_USB_CMD_REG_RUN, + FALSE, + USB_EHCI_STOP_RESET_TIMEOUT_USEC); + if (Status !=3D EFI_SUCCESS) { + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_ERROR, "Failed to stop EHCI controller (PHY %d)\n", + (UINT32)ImxUsbPhyId)); + return Status; + } + + // Reset the controller + UsbCmdReg.AsUint32 =3D MmioRead32 ((UINTN)UsbCmdRegPtr); + UsbCmdReg.RST =3D 1; + MmioWrite32 ((UINTN)UsbCmdRegPtr, UsbCmdReg.AsUint32); + + // Wait for controller reset to complete + Status =3D RegisterWaitBit ( + UsbCmdRegPtr, + IMX_USB_CMD_REG_RESET, + FALSE, + USB_EHCI_STOP_RESET_TIMEOUT_USEC); + + if (Status !=3D EFI_SUCCESS) { + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_ERROR, "Failed to reset EHCI controller (PHY %d)\n", + (UINT32)ImxUsbPhyId)); + return Status; + } + + // Force OTG port into Host mode. We have seen that ID_PIN can be + // unreliable in some board designs (e.g. SABRESED). + // If the OTG port is not forced into Host mode, the USB stack fails to + // start. + if (ImxUsbPhyId =3D=3D IMX_USBPHY0) { + DEBUG ((DEBUG_INFO, "Switching USB OTG Port to Host\n")); + + UsbModeRegPtr =3D (USB_USBMODE_REG *) (IMX_USBCORE_BASE + IMX_USBMODE_= OFFSET); + UsbModeReg.AsUint32 =3D MmioRead32 ((UINTN)UsbModeRegPtr); + UsbModeReg.CM =3D IMX_USBMODE_HOST; + MmioWrite32 ((UINTN)UsbModeRegPtr, UsbModeReg.AsUint32); + + UsbModeReg.AsUint32 =3D MmioRead32 ((UINTN)UsbModeRegPtr); + ASSERT (UsbModeReg.CM =3D=3D IMX_USBMODE_HOST); + } + + return EFI_SUCCESS; +} + +/** + Initialize a USB PHY +**/ +EFI_STATUS +ImxUsbPhyInit ( + IN IMX_USBPHY_ID ImxUsbPhyId + ) +{ + volatile IMX_USBANA_REGISTERS *UsbAnaRegsPtr; + volatile IMX_USBANA_USB_REGISTERS *UsbAnaUsbRegsPtr; + volatile USBNC_USB_UH_CTRL_REG *UsbNcUhCtrlRegPtr; + volatile IMX_USBNONCORE_REGISTERS *UsbNonCoreRegPtr; + volatile IMX_USBPHY_REGISTERS *UsbPhyRegsPtr; + EFI_STATUS Status; + USB_ANALOG_USB_CHRG_DETECT_REG UsbAnaChrgDetReg; + USB_ANALOG_USB_MISC_REG UsbAnaMicReg; + USBNC_USB_UH_CTRL_REG UsbNcHcCtrlReg; + USBPHYx_CTRL_REG UsbPhyCtrlReg; + + UsbAnaRegsPtr =3D (IMX_USBANA_REGISTERS *)IMX_USBANA_BASE; + UsbNonCoreRegPtr =3D (IMX_USBNONCORE_REGISTERS *)IMX_USBNONCORE_BASE; + + switch (ImxUsbPhyId) { + case IMX_USBPHY0: + UsbPhyRegsPtr =3D (IMX_USBPHY_REGISTERS *)IMX_USBPHY1_BASE; + UsbAnaUsbRegsPtr =3D &UsbAnaRegsPtr->USBANA[0]; + UsbNcUhCtrlRegPtr =3D (USBNC_USB_UH_CTRL_REG *) + &UsbNonCoreRegPtr->USBNC_USB_OTG_CTRL; + break; + case IMX_USBPHY1: + UsbPhyRegsPtr =3D (IMX_USBPHY_REGISTERS *)IMX_USBPHY2_BASE; + UsbAnaUsbRegsPtr =3D &UsbAnaRegsPtr->USBANA[1]; + UsbNcUhCtrlRegPtr =3D (USBNC_USB_UH_CTRL_REG *) + &UsbNonCoreRegPtr->USBNC_USB_UH1_CTRL; + break; + default: + return EFI_INVALID_PARAMETER; + } + + // USB power configuration: + // Set power polarity + UsbNcHcCtrlReg.AsUint32 =3D MmioRead32 ((UINTN)UsbNcUhCtrlRegPtr); + UsbNcHcCtrlReg.PWR_POL =3D 1; + UsbNcHcCtrlReg.AsUint32 |=3D 0x2; // Reserved bit + MmioWrite32 ((UINTN)UsbNcUhCtrlRegPtr, UsbNcHcCtrlReg.AsUint32); + + // Disable external USB charger detector + UsbAnaChrgDetReg.AsUint32 =3D 0; + UsbAnaChrgDetReg.EN_B =3D 1; + UsbAnaChrgDetReg.CHK_CHRG_B =3D 1; + MmioWrite32 ((UINTN)&UsbAnaUsbRegsPtr->USB_ANALOG_USB_CHRG_DETECT_SET, + UsbAnaChrgDetReg.AsUint32); + + // Enable the 480Mhz PLL + Status =3D ImxUsbPhyEnablePll (ImxUsbPhyId); + if (Status !=3D EFI_SUCCESS) { + ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_ERROR, "Failed to enable PLL 480Mhz failed for PHY %d\n"= , + (UINT32)ImxUsbPhyId)); + return Status; + } + + // Configure Over Current + UsbNcHcCtrlReg.AsUint32 =3D MmioRead32 ((UINTN)UsbNcUhCtrlRegPtr); + UsbNcHcCtrlReg.OVER_CUR_POL =3D 0; + UsbNcHcCtrlReg.OVER_CUR_DIS =3D 1; + MmioWrite32 ((UINTN)UsbNcUhCtrlRegPtr, UsbNcHcCtrlReg.AsUint32); + + // Enable USBH PHY clock + UsbPhyCtrlReg.AsUint32 =3D 0; + UsbPhyCtrlReg.CLKGATE =3D 1; + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_CLR, UsbPhyCtrlReg.AsUin= t32); + MicroSecondDelay (10); + + // Enable clock to UTMI block + UsbAnaMicReg.AsUint32 =3D 0; + UsbAnaMicReg.EN_CLK_UTMI =3D 1; + MmioWrite32 ((UINTN)&UsbAnaUsbRegsPtr->USB_ANALOG_USB_MISC_SET, + UsbAnaMicReg.AsUint32); + MicroSecondDelay (10); + + // Enable USBH PHY + // Reset the associated EHCI controller + Status =3D ImxUsbEhciResetController (ImxUsbPhyId); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + // Reset the PHY + UsbPhyCtrlReg.AsUint32 =3D 0; + UsbPhyCtrlReg.SFTRST =3D 1; + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_SET, UsbPhyCtrlReg.AsUin= t32); + MicroSecondDelay (10); + + UsbPhyCtrlReg.AsUint32 =3D 0; + UsbPhyCtrlReg.SFTRST =3D 1; + UsbPhyCtrlReg.CLKGATE =3D 1; + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_CLR, UsbPhyCtrlReg.AsUin= t32); + MicroSecondDelay (10); + + // Power UP the PHY + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_PWD, 0); + + // Apply PHY configuration: + // - Enable low/full speed devices. + UsbPhyCtrlReg.AsUint32 =3D 0; +#if defined(CPU_IMX6DQ) + UsbPhyCtrlReg.ENAUTOSET_USBCLKS =3D 1; + UsbPhyCtrlReg.ENAUTOCLR_USBCLKGATE =3D 1; + UsbPhyCtrlReg.ENAUTO_PWRON_PLL =3D 1; +#endif + UsbPhyCtrlReg.ENAUTOCLR_PHY_PWD =3D 1; + UsbPhyCtrlReg.ENAUTOCLR_CLKGATE =3D 1; + UsbPhyCtrlReg.ENUTMILEVEL2 =3D 1; + UsbPhyCtrlReg.ENUTMILEVEL3 =3D 1; + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_SET, UsbPhyCtrlReg.AsUin= t32); +#if defined(CPU_IMX6DQ) + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_IP_SET, IMX_USBPHY_IP_FIX); +#endif + + return EFI_SUCCESS; +} diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf b/= Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf new file mode 100644 index 000000000000..30f9f1862747 --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf @@ -0,0 +1,43 @@ +## @file +# +# Copyright (c) 2018 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. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D iMX6UsbPhyLib + FILE_GUID =3D 463989D1-27DC-4AE7-92AE-C7E28C1C605D + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D iMX6UsbPhyLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + Silicon/NXP/iMXPlatformPkg/iMXPlatformPkg.dec + Silicon/NXP/iMX6Pkg/iMX6Pkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + IoLib + TimerLib + iMXIoMuxLib + +[Sources.common] + iMX6UsbPhy.c + +[FixedPcd] + giMXPlatformTokenSpaceGuid.PcdGpioBankMemoryRange --=20 2.16.2.gvfs.1.33.gf5370f1