From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=40.107.71.124; helo=nam05-by2-obe.outbound.protection.outlook.com; envelope-from=christopher.co@microsoft.com; receiver=edk2-devel@lists.01.org Received: from NAM05-BY2-obe.outbound.protection.outlook.com (mail-eopbgr710124.outbound.protection.outlook.com [40.107.71.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 9DC302098EACC for ; Thu, 19 Jul 2018 23:33:55 -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=LTPxRh0he2GWIYECLwB+dhlioIVLK9Vs66BJ3gM6cp4=; b=lz/EnlLyxZW0vIl/q7/qKZwX0lV3KoLw9LkPg0wUmksvp8HR1eWbJo2wLq+wzsNB+eSSWVqQQsCZdOUx1XADSBUvihbb05WTBJLW7AdyQiT2ScC8fvPTJANsNTPoAByjLQqvWaqb9fEXFl6YoRHXfMfwRjyuWTWCVTpVqbHKIIw= Received: from SN6PR2101MB1136.namprd21.prod.outlook.com (52.132.114.25) by SN6PR2101MB1133.namprd21.prod.outlook.com (52.132.114.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.995.0; Fri, 20 Jul 2018 06:33:53 +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:53 +0000 From: Chris Co To: "edk2-devel@lists.01.org" CC: Ard Biesheuvel , Leif Lindholm , Michael D Kinney Thread-Topic: [PATCH edk2-platforms 06/13] Silicon/NXP: Add i.MX6 USB Phy Library Thread-Index: AQHUH/OgpONBPuPMgESbYhWhMXrzLg== Date: Fri, 20 Jul 2018 06:33:53 +0000 Message-ID: <20180720063328.26856-7-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; SN6PR2101MB1133; 6:NRJCg83+OGsYXZQ9VqgJavLLAmVrrvPCeVuLrZjDt4dt//666/sfYUj6R1L13uYyLwOLVf8I2x1ndpp0nCCLdJAbvl3LaQlt0Z44opfeeHAjhS2Aheso96ityvUR/J3yAYljyoRlRn7YeSulX5V6tcKRmssULV18HYkP8+tEVDZA+YtzNDFlmn5/ndkv+eiPWlZluH755hMpf3GUIRq71z3TnqmJHHUvFlmG6DbdfWaspG9uIGN2zPlc6neBS3BGxwuv0126zgZRJZE/UK5T3h0zi/BM5HzYcbO90Cq35FR1MR2vwV6FEwZe+ML95WruE5JmYfw4oYmRVSxbsjuNGs4/AdmrWrE7MFdqGFPfjYdch8Q23pdJKiz9VE97IdWkh9qIfzXXpw6KKZgctEBbhn8heVhCrnlkTkP5ZYwi1Y8ZB1JJKwv6uC2QtH72pmlYkOpokg1aQu6Y3Q5hLpCmmg==; 5:+Q8c4T7iLeKC8gH/G6Mz4f9FqEOrAs/qlN+U1K5W7ioQvkKMwO2kRrkAIms4f93/We0Aaj/8TWk+a4PWc9FVngU/VUl86fh5Jphsnwq85/bs8QURdJajGTdX/1OPqbiQIDQgdUPliMt+cZKS6vka+qD+/82LrsplLHp/RJFGLyk=; 7:7C/3yfEazJ6hB8dCACmBo7tbboB/6rh57vqeKAOHkuQuT12xPor9NoyIKIZgSrXu0QWDMUia6iqTS/5In2G7GEKhm6WTZrPqUtW3LdGcaTgW93TmTtxGIGVfkh9Mc2E/gCSuD7MjrUVjrVBOo6xWrR0U6aOFnTjMbhjeD3bUv7Swt1sy7d376mgNPKI/pygqxR/HUNNLRklFqypb9EG6M3Jg4cDdxwv3Ks9Z26h4vckzmWoYgB1waX4qJvnaZLFT x-ms-office365-filtering-correlation-id: b31206da-2d52-4626-fe06-08d5ee0ac2be 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:SN6PR2101MB1133; x-ms-traffictypediagnostic: SN6PR2101MB1133: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Christopher.Co@microsoft.com; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(28532068793085)(89211679590171)(228905959029699); x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3002001)(3231311)(944501410)(52105095)(2018427008)(93006095)(93001095)(6055026)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123560045)(20161123564045)(6072148)(201708071742011)(7699016); SRVR:SN6PR2101MB1133; BCL:0; PCL:0; RULEID:; SRVR:SN6PR2101MB1133; x-forefront-prvs: 073966E86B x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(396003)(376002)(366004)(346002)(136003)(39860400002)(189003)(199004)(52116002)(16799955002)(46003)(2906002)(2900100001)(15188155005)(36756003)(97736004)(386003)(256004)(99286004)(19627235002)(86612001)(6506007)(14444005)(86362001)(186003)(76176011)(10090500001)(102836004)(1076002)(6306002)(6512007)(8936002)(6486002)(2616005)(476003)(5660300001)(486006)(478600001)(8676002)(6116002)(81156014)(81166006)(25786009)(4326008)(5640700003)(53376002)(53936002)(68736007)(6436002)(2501003)(10290500003)(22452003)(2351001)(7736002)(305945005)(5250100002)(6916009)(54906003)(14454004)(11346002)(72206003)(106356001)(966005)(316002)(446003)(105586002); DIR:OUT; SFP:1102; SCL:1; SRVR:SN6PR2101MB1133; H:SN6PR2101MB1136.namprd21.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: /JhkS4HutuEu8tr9swOZMgy9oLZb/CgORvp8boVajsGCE4UnEGnBuGP/K/jerX24fzE1OaM207qqVVqvtC0Jt+Lp9H17s+uz93NKwE0oizm5Ss0mbGV+PCtxAU7mNkAXxZvxm69gIn2LlGzqevwULNNn+CXCYwZJ3FmmsS1lZPBtwbwJd1S4LWE+4H5oZOuCXocPn7eSC7S2NyX9ajnHUexQpJjE+KPh2isQa5lJjRwoCv5LzfElaBIq/27/XxYFSt71wMyxB+t5ZUcJgoqaJAuH3KSGS7lBGaH731Z6EuzMATA4pSt0cjDWd+iPat07n68R1tjbSjBoLA6ry3ueNGXDASIq7TxJNyGgZ7J3g/E= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: b31206da-2d52-4626-fe06-08d5ee0ac2be X-MS-Exchange-CrossTenant-originalarrivaltime: 20 Jul 2018 06:33:53.2642 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR2101MB1133 Subject: [PATCH edk2-platforms 06/13] Silicon/NXP: Add i.MX6 USB Phy Library 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:55 -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/Library/iMX6UsbPhyLib/iMX6UsbPhy.c | 364 ++++++++= ++++++++++++ Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf | 43 +++ 2 files changed, 407 insertions(+) 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..967fa0620242 --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c @@ -0,0 +1,364 @@ +/** @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 + +/** + Timeout constants +**/ + +#define USB_PHY_PLL_LOCK_TIMEOUT_USEC (UINT32)(1000*1000) +#define USB_EHCI_STOP_RESET_TIMEOUT_USEC (UINT32)(1000*1000) + +/** + Required register bit masks +**/ + +#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 ( + volatile VOID* RegisterAddr, + UINT32 Mask, + BOOLEAN IsWaitOn, + UINT32 TimeOutUsec) +{ + UINT32 TimeUsec =3D 0; + do { + UINT32 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 (IMX_USBPHY_ID ImxUsbPhyId) +{ + volatile IMX_CCM_ANALOG_REGISTERS* CcmAnaRegsPtr =3D (IMX_CCM_ANALOG_R= EGISTERS*)IMX_CCM_ANALOG_BASE; + volatile IMX_CCM_ANALOG_PLL_USB1_REG* PllUsbClrRegPtr; + volatile IMX_CCM_ANALOG_PLL_USB1_REG* PllUsbSetRegPtr; + EFI_STATUS Status; + + 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; + } + + IMX_CCM_ANALOG_PLL_USB1_REG PllUsbClrReg =3D { 0 }; + PllUsbClrReg.BYPASS =3D 1; + MmioWrite32((UINTN)PllUsbClrRegPtr, PllUsbClrReg.AsUint32); + + IMX_CCM_ANALOG_PLL_USB1_REG PllUsbSetReg =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, // On + USB_PHY_PLL_LOCK_TIMEOUT_USEC); + + if (Status !=3D EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "PLL 480Mhz failed to lock for PHY %d\n", (UIN= T32)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 (IMX_USBPHY_ID ImxUsbPhyId) +{ + volatile USB_USBCMD_REG* UsbCmdRegPtr; + EFI_STATUS Status; + + switch (ImxUsbPhyId) { + case IMX_USBPHY0: + UsbCmdRegPtr =3D (USB_USBCMD_REG*)(IMX_USBCORE_BASE + IMX_USBCORE_= LENGTH * 0 + IMX_USBCMD_OFFSET); + break; + + case IMX_USBPHY1: + UsbCmdRegPtr =3D (USB_USBCMD_REG*)(IMX_USBCORE_BASE + IMX_USBCORE_= LENGTH * 1 + IMX_USBCMD_OFFSET); + break; + + default: + return EFI_INVALID_PARAMETER; + } + + // + // The host controller can only be reset when it is stopped. + // + USB_USBCMD_REG UsbCmdReg =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, // Off + 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, // Off + 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. Depending on the ID_PIN tends to be + // unreliable in some board designs such as SABRESED. + // If the OTG port is not forced into Host mode, the USB stack fails t= o + // start. + // + if (ImxUsbPhyId =3D=3D IMX_USBPHY0) { + volatile USB_USBMODE_REG* UsbModeRegPtr; + USB_USBMODE_REG UsbModeReg; + + DEBUG((DEBUG_INFO, "Switching USB OTG Port to Host\n")); + + UsbModeRegPtr =3D (USB_USBMODE_REG*)(IMX_USBCORE_BASE + IMX_USBMOD= E_OFFSET); + UsbModeReg.AsUint32 =3D MmioRead32((UINTN)UsbModeRegPtr); + UsbModeReg.CM =3D IMX_USBMODE_HOST; + MmioWrite32((UINTN)UsbModeRegPtr, UsbModeReg.AsUint32); + + DEBUG_CODE_BEGIN(); + UsbModeReg.AsUint32 =3D MmioRead32((UINTN)UsbModeRegPtr); + ASSERT(UsbModeReg.CM =3D=3D IMX_USBMODE_HOST); + DEBUG_CODE_END(); + } + + return EFI_SUCCESS; +} + +/** + Initialize a USB PHY +**/ +EFI_STATUS ImxUsbPhyInit (IMX_USBPHY_ID ImxUsbPhyId) +{ + volatile IMX_USBNONCORE_REGISTERS* UsbNonCoreRegPtr =3D (IMX_USBNONCOR= E_REGISTERS*)IMX_USBNONCORE_BASE; + volatile IMX_USBANA_REGISTERS* UsbAnaRegsPtr =3D (IMX_USBANA_REGISTERS= *)IMX_USBANA_BASE; + volatile IMX_USBPHY_REGISTERS* UsbPhyRegsPtr; + volatile IMX_USBANA_USB_REGISTERS* UsbAnaUsbRegsPtr; + volatile USBNC_USB_UH_CTRL_REG* UsbNcUhCtrlRegPtr; + EFI_STATUS Status; + + 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->U= SBNC_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->U= SBNC_USB_UH1_CTRL; + break; + + default: + return EFI_INVALID_PARAMETER; + } + + // + // USB power configuration: + // + { + // + // Set power polarity + // + USBNC_USB_UH_CTRL_REG UsbNcHcCtrlReg =3D { MmioRead32((UINTN)UsbNc= UhCtrlRegPtr) }; + UsbNcHcCtrlReg.PWR_POL =3D 1; + UsbNcHcCtrlReg.AsUint32 |=3D 0x2; // Reserved bit + MmioWrite32((UINTN)UsbNcUhCtrlRegPtr, UsbNcHcCtrlReg.AsUint32); + + // + // Disable external USB charger detector + // + USB_ANALOG_USB_CHRG_DETECT_REG UsbAnaChrgDetReg =3D { 0 }; + UsbAnaChrgDetReg.EN_B =3D 1; + UsbAnaChrgDetReg.CHK_CHRG_B =3D 1; + MmioWrite32((UINTN)&UsbAnaUsbRegsPtr->USB_ANALOG_USB_CHRG_DETECT_S= ET, 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 PH= Y %d\n", (UINT32)ImxUsbPhyId)); + return Status; + } + } + + // + // Configure Over Current + // + { + USBNC_USB_UH_CTRL_REG UsbNcHcCtrlReg =3D { MmioRead32((UINTN)UsbNc= UhCtrlRegPtr) }; + UsbNcHcCtrlReg.OVER_CUR_POL =3D 0; + UsbNcHcCtrlReg.OVER_CUR_DIS =3D 1; + MmioWrite32((UINTN)UsbNcUhCtrlRegPtr, UsbNcHcCtrlReg.AsUint32); + } + + // + // Enable USBH PHY clock + // + { + USBPHYx_CTRL_REG UsbPhyCtrlReg =3D { 0 }; + UsbPhyCtrlReg.CLKGATE =3D 1; + MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_CLR, UsbPhyCtrlReg.= AsUint32); + MicroSecondDelay(10); + } + + // + // Enable clock to UTMI block + // + { + USB_ANALOG_USB_MISC_REG UsbAnaMicReg =3D { 0 }; + UsbAnaMicReg.EN_CLK_UTMI =3D 1; + MmioWrite32((UINTN)&UsbAnaUsbRegsPtr->USB_ANALOG_USB_MISC_SET, Usb= AnaMicReg.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 + // + USBPHYx_CTRL_REG UsbPhyCtrl; + { + UsbPhyCtrl.AsUint32 =3D 0; + UsbPhyCtrl.SFTRST =3D 1; + MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_SET, UsbPhyCtrl= .AsUint32); + MicroSecondDelay(10); + + UsbPhyCtrl.AsUint32 =3D 0; + UsbPhyCtrl.SFTRST =3D 1; + UsbPhyCtrl.CLKGATE =3D 1; + MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_CLR, UsbPhyCtrl= .AsUint32); + MicroSecondDelay(10); + } + + // + // Power UP the PHY + // + MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_PWD, 0); + + // + // Apply PHY configuration: + // - Enable low/full speed devices. + // + UsbPhyCtrl.AsUint32 =3D 0; + // iMX6 Solo and DualLite - 66.3.4 USB PHY General Control Registe= r (USBPHYx_CTRLn) +#if !(defined(CPU_IMX6SX) || defined(CPU_IMX6SDL)) + UsbPhyCtrl.ENAUTOSET_USBCLKS =3D 1; + UsbPhyCtrl.ENAUTOCLR_USBCLKGATE =3D 1; +#endif + UsbPhyCtrl.ENAUTOCLR_PHY_PWD =3D 1; + UsbPhyCtrl.ENAUTOCLR_CLKGATE =3D 1; +#if !(defined(CPU_IMX6SX) || defined(CPU_IMX6SDL)) + UsbPhyCtrl.ENAUTO_PWRON_PLL =3D 1; +#endif + UsbPhyCtrl.ENUTMILEVEL2 =3D 1; + UsbPhyCtrl.ENUTMILEVEL3 =3D 1; + MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_SET, UsbPhyCtrl.AsU= int32); +#if !(defined(CPU_IMX6SX) || defined(CPU_IMX6SDL)) + MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_IP_SET, IMX_USBPHY_IP_F= IX); +#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..35b31adf7989 --- /dev/null +++ b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf @@ -0,0 +1,43 @@ +## @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. +# +## + +[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