From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=40.107.80.121; helo=nam03-dm3-obe.outbound.protection.outlook.com; envelope-from=mike.li@bayhubtech.com; receiver=edk2-devel@lists.01.org Received: from NAM03-DM3-obe.outbound.protection.outlook.com (mail-eopbgr800121.outbound.protection.outlook.com [40.107.80.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 745C32194D387 for ; Wed, 23 Jan 2019 01:29:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=towerbridgetechnology.onmicrosoft.com; s=selector1-bayhubtech-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Pb5nGmQ7QBDF8TpO5c6k2loFipt513tmllexWNXdiQU=; b=krCCv3T80GX6sop7Pf+zRELsToCNJRxS8VWI2H2RCFHkFvINarGG26d6yaYU4cnGvTJc+WL4fheeAa+opAQVBr74roP/OrTJcVlJLhs8+6VhizEI8kMj1A9MZv4aXsrjoqHKRP03sra+b/M3nnFD5J4cEI02BI5FvGyAbIAl2WA= Received: from MWHPR16MB1679.namprd16.prod.outlook.com (10.172.59.149) by MWHPR16MB0111.namprd16.prod.outlook.com (10.172.102.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1537.27; Wed, 23 Jan 2019 09:29:20 +0000 Received: from MWHPR16MB1679.namprd16.prod.outlook.com ([fe80::151:66e0:7431:2f5d]) by MWHPR16MB1679.namprd16.prod.outlook.com ([fe80::151:66e0:7431:2f5d%10]) with mapi id 15.20.1558.016; Wed, 23 Jan 2019 09:29:20 +0000 From: "Mike Li (WH)" To: "Xiaoguang Yu (WH)" , "Ernest Zhang(WH)" , "Andy Dai (WH)" CC: "Shirley Her (SC)" , "edk2-devel@lists.01.org" Thread-Topic: [edk2] [patch_1] make EDK Driver Support BH720+EMMC chip Thread-Index: AdSy/gGCBZ1Vimj1Q1KozDK4Cs6GQw== Date: Wed, 23 Jan 2019 09:29:19 +0000 Message-ID: Accept-Language: en-AU, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=mike.li@bayhubtech.com; x-originating-ip: [58.48.115.170] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; MWHPR16MB0111; 6:LX6K3hAzfgAsFr1z3MkH6YrcVzi+hcAxYvJAtvVdKPXXVZGY7tLLR6AOrQgF+RGBVwkJD67nkSV8XWcm1hEYUEGLgDAKUIYc8537nsRZfvA2SJnVMlEERtxS4ThWeMD5FoVec3fQqz6jayKHtNty+H9M7BYXQ0CgEcKnsPGwGSbmKPmh0gdglUt8/4hHiC4mcP9YQPTqt1uh4ruwteG8N9wrt1EYXoJSTm/fHt2agNw+F8ZKFuLdfAdmSnSPqd4l0vBYYUzZL8CHD/wnBPOtdv79MwkGnmdo/qlORiTerOUK7d84VzBGX5fq94fdkeB+ptWE8+BbsEh4Za09V5RRKoDNoh5O0QOmACgtpvkoykiwUeLl3TzBZLuOUrukIfj1Kw07rh0el/m7vPctcVs+WG8I/2Q6k1wXvFLgYfHS8o4QfU+/sNXBdPuX4Ur7n3x2UpKomJbVgHIvlR9zdS+wlw==; 5:H5MuxmC+AYQa7eOXkFVxzx1h5x8qDOn+oRBATYHWZK1Gx7l4ZrPKFqCUMXeLi+4mgApe6O2ZsCVwG7Fwc+IXpHSh/vIOk1mxwPhwOjDpgwIhBdNbuzrJCZmY7lWJC+evzKwKIj7XOeLLbaNMHdgIPhZgalAN0bGNPliyHrZfojaOGCs04YUtzoUQuFz11VjP40M9zXk9OjY5G6Q2hlwLAA==; 7:9YtnBPONXJWua9nxRj1+8Ef5nXuvL2StZA7uEwycd9jk2EWvr6sbBfPHTEOI/cYbLDq1fFHEiYTOepVYB0NmvRDzPJIzmrONMAm1srCuo19ecoTz/005XE3MdZO+Jrolycb/T4Bev0ZtnKH5p/+nXg== x-ms-office365-filtering-correlation-id: 1e4cecae-4d52-48a8-1076-08d6811540f8 x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(7021145)(8989299)(5600110)(711020)(4605077)(4534185)(7022145)(4603075)(4627221)(201702281549075)(8990200)(2017052603328)(7153060)(7193020); SRVR:MWHPR16MB0111; x-ms-traffictypediagnostic: MWHPR16MB0111: x-microsoft-antispam-prvs: x-forefront-prvs: 0926B0E013 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(136003)(376002)(39830400003)(346002)(396003)(366004)(189003)(199004)(71200400001)(30864003)(71190400001)(53946003)(6436002)(486006)(476003)(53936002)(2906002)(7736002)(66066001)(105586002)(6636002)(68736007)(54896002)(19627235002)(106356001)(9686003)(6306002)(33656002)(14444005)(256004)(3846002)(6116002)(81156014)(81166006)(97736004)(790700001)(4326008)(7696005)(316002)(8936002)(8676002)(55016002)(99286004)(26005)(110136005)(74316002)(14454004)(6506007)(478600001)(102836004)(54906003)(86362001)(186003)(25786009)(559001)(579004)(569006); DIR:OUT; SFP:1102; SCL:1; SRVR:MWHPR16MB0111; H:MWHPR16MB1679.namprd16.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: bayhubtech.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: wMLyekHxeQ1QwMuHATj85G3709u+PM3Pw6Zb01wylhzzQCclG2RSVHecu5lkVvmfIzEjgFAOv7IfiPxuVBi2sejE1zkXeDzMOdlftDAMYWrO7w36CTT1YHXNDI7BjDfZRghlV5Q1UuLXm3weG7ESk+4stZctylFDlxdouPsr0JKQDHDEJkfzxVCCwxe47vf8uGY+RoJdCj/43i1IuxQXV7eLIfOqY4KbfgnD+IDryLxxNwwRXurKaoNaQZgSxBaRdP6lp0a+bU/7C71qAfGAt9upOMU2HI+kvH12aeBG4T2iAZnvqm5Ewdx62YbekqGvk7kFAgpADmVtsX0bYZNQ9b41H6Mm3zAv+TDglDVa2hXRg9XCE1/7Ri3S2mB+swVYm6yg7cywWxdakRhr2XVpXNEJ5UR0zubsPOD81Y59fMo= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: bayhubtech.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1e4cecae-4d52-48a8-1076-08d6811540f8 X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Jan 2019 09:29:20.2157 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 0a7aae2b-8f2e-44df-ba2f-42de7f93c642 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR16MB0111 X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Subject: [patch_1] make EDK Driver Support BH720+EMMC chip 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: Wed, 23 Jan 2019 09:29:26 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi, all The following modifications are made to enable EDK Driver Support BH720 CHI= P. --- /c/MyWorkspace/edk2-vUDK2018/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPc= iHci.c 2019-01-10 14:35:21.342736200 -0800 +++ /c/yx/edk2/MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c 201= 9-01-21 15:36:12.195715300 -0800 @@ -4,6 +4,7 @@ It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use. + Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License @@ -16,8 +17,6 @@ **/ #include "SdMmcPciHcDxe.h" -int g_deviceId =3D 0; - /** Dump the content of SD/MMC host controller's Capability Register. @@ -47,7 +46,8 @@ DumpCapabilityReg ( DEBUG ((DEBUG_INFO, " Voltage 3.3 %a\n", Capability->Voltage33 ?= "TRUE" : "FALSE")); DEBUG ((DEBUG_INFO, " Voltage 3.0 %a\n", Capability->Voltage30 ?= "TRUE" : "FALSE")); DEBUG ((DEBUG_INFO, " Voltage 1.8 %a\n", Capability->Voltage18 ?= "TRUE" : "FALSE")); - DEBUG ((DEBUG_INFO, " 64-bit Sys Bus %a\n", Capability->SysBus64 ? = "TRUE" : "FALSE")); + DEBUG ((DEBUG_INFO, " V4 64-bit Sys Bus %a\n", Capability->SysBus64V4 = ? "TRUE" : "FALSE")); + DEBUG ((DEBUG_INFO, " V3 64-bit Sys Bus %a\n", Capability->SysBus64V3 = ? "TRUE" : "FALSE")); DEBUG ((DEBUG_INFO, " Async Interrupt %a\n", Capability->AsyncInt ? = "TRUE" : "FALSE")); DEBUG ((DEBUG_INFO, " SlotType ")); if (Capability->SlotType =3D=3D 0x00) { @@ -419,9 +419,39 @@ SdMmcHcWaitMmioSet ( } /** + Get the controller version information from the specified slot. + + @param[in] PciIo The PCI IO protocol instance. + @param[in] Slot The slot number of the SD card to send the c= ommand to. + @param[out] Version The buffer to store the version information. + + @retval EFI_SUCCESS The operation executes successfully. + @retval Others The operation fails. + +**/ +EFI_STATUS +SdMmcHcGetControllerVersion ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT8 Slot, + OUT UINT16 *Version + ) +{ + EFI_STATUS Status; + + Status =3D SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof = (UINT16), Version); + if (EFI_ERROR (Status)) { + return Status; + } + + *Version &=3D 0xFF; + + return EFI_SUCCESS; +} + +/** Software reset the specified SD/MMC host controller and enable all inter= rupts. - @param[in] PciIo The PCI IO protocol instance. + @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instan= ce. @param[in] Slot The slot number of the SD card to send the com= mand to. @retval EFI_SUCCESS The software reset executes successfully. @@ -430,18 +460,38 @@ SdMmcHcWaitMmioSet ( **/ EFI_STATUS SdMmcHcReset ( - IN EFI_PCI_IO_PROTOCOL *PciIo, + IN SD_MMC_HC_PRIVATE_DATA *Private, IN UINT8 Slot ) { EFI_STATUS Status; UINT8 SwReset; + EFI_PCI_IO_PROTOCOL *PciIo; + + // + // Notify the SD/MMC override protocol that we are about to reset + // the SD/MMC host controller. + // + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { + Status =3D mOverride->NotifyPhase ( + Private->ControllerHandle, + Slot, + EdkiiSdMmcResetPre, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: SD/MMC pre reset notifier callback failed - %r\n", + __FUNCTION__, Status)); + return Status; + } + } - SwReset =3D 0xFF; - Status =3D SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_SW_RST, FALSE, sizeof = (SwReset), &SwReset); + PciIo =3D Private->PciIo; + SwReset =3D BIT0; + Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_SW_RST, sizeof (SwRese= t), &SwReset); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "SdMmcHcReset: write full 1 fails: %r\n", Status)= ); + DEBUG ((DEBUG_ERROR, "SdMmcHcReset: write SW Reset for All fails: %r\n= ", Status)); return Status; } @@ -450,7 +500,7 @@ SdMmcHcReset ( Slot, SD_MMC_HC_SW_RST, sizeof (SwReset), - 0xFF, + BIT0, 0x00, SD_MMC_HC_GENERIC_TIMEOUT ); @@ -458,10 +508,33 @@ SdMmcHcReset ( DEBUG ((DEBUG_INFO, "SdMmcHcReset: reset done with %r\n", Status)); return Status; } + // // Enable all interrupt after reset all. // Status =3D SdMmcHcEnableInterrupt (PciIo, Slot); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "SdMmcHcReset: SdMmcHcEnableInterrupt done with %r= \n", + Status)); + return Status; + } + + // + // Notify the SD/MMC override protocol that we have just reset + // the SD/MMC host controller. + // + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { + Status =3D mOverride->NotifyPhase ( + Private->ControllerHandle, + Slot, + EdkiiSdMmcResetPost, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: SD/MMC post reset notifier callback failed - %r\n", + __FUNCTION__, Status)); + } + } return Status; } @@ -680,7 +753,8 @@ SdMmcHcStopClock ( @param[in] PciIo The PCI IO protocol instance. @param[in] Slot The slot number of the SD card to send the com= mand to. @param[in] ClockFreq The max clock frequency to be set. The unit is= KHz. - @param[in] Capability The capability of the slot. + @param[in] BaseClkFreq The base clock frequency of host controller in= MHz. + @param[in] ControllerVer The version of host controller. @retval EFI_SUCCESS The clock is supplied successfully. @retval Others The clock isn't supplied successfully. @@ -691,23 +765,21 @@ SdMmcHcClockSupply ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT8 Slot, IN UINT64 ClockFreq, - IN SD_MMC_HC_SLOT_CAP Capability + IN UINT32 BaseClkFreq, + IN UINT16 ControllerVer ) { EFI_STATUS Status; - UINT32 BaseClkFreq; UINT32 SettingFreq; UINT32 Divisor; UINT32 Remainder; - UINT16 ControllerVer; UINT16 ClockCtrl; // // Calculate a divisor for SD clock frequency // - ASSERT (Capability.BaseClkFreq !=3D 0); + ASSERT (BaseClkFreq !=3D 0); - BaseClkFreq =3D Capability.BaseClkFreq; if (ClockFreq =3D=3D 0) { return EFI_INVALID_PARAMETER; } @@ -736,17 +808,15 @@ SdMmcHcClockSupply ( DEBUG ((DEBUG_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", Ba= seClkFreq, Divisor, ClockFreq)); - Status =3D SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof = (ControllerVer), &ControllerVer); - if (EFI_ERROR (Status)) { - return Status; - } // // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock = Control register. // - if (((ControllerVer & 0xFF) =3D=3D 2) || ((ControllerVer & 0xFF) =3D=3D = 3)) { + if ((ControllerVer >=3D SD_MMC_HC_CTRL_VER_300) && + (ControllerVer <=3D SD_MMC_HC_CTRL_VER_420)) { ASSERT (Divisor <=3D 0x3FF); ClockCtrl =3D ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2); - } else if (((ControllerVer & 0xFF) =3D=3D 0) || ((ControllerVer & 0xFF) = =3D=3D 1)) { + } else if ((ControllerVer =3D=3D SD_MMC_HC_CTRL_VER_100) || + (ControllerVer =3D=3D SD_MMC_HC_CTRL_VER_200)) { // // Only the most significant bit can be used as divisor. // @@ -894,11 +964,62 @@ SdMmcHcSetBusWidth ( } /** - Supply SD/MMC card with lowest clock frequency at initialization. + Configure V4 controller enhancements at initialization. @param[in] PciIo The PCI IO protocol instance. @param[in] Slot The slot number of the SD card to send the com= mand to. @param[in] Capability The capability of the slot. + @param[in] ControllerVer The version of host controller. + + @retval EFI_SUCCESS The clock is supplied successfully. + +**/ +EFI_STATUS +SdMmcHcInitV4Enhancements ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT8 Slot, + IN SD_MMC_HC_SLOT_CAP Capability, + IN UINT16 ControllerVer + ) +{ + EFI_STATUS Status; + UINT16 HostCtrl2; + + // + // Check if controller version V4 or higher + // + if (ControllerVer >=3D SD_MMC_HC_CTRL_VER_400) { + HostCtrl2 =3D SD_MMC_HC_V4_EN; + // + // Check if V4 64bit support is available + // + if (Capability.SysBus64V4 !=3D 0) { + HostCtrl2 |=3D SD_MMC_HC_64_ADDR_EN; + DEBUG ((DEBUG_INFO, "Enabled V4 64 bit system bus support\n")); + } + // + // Check if controller version V4.10 or higher + // + if (ControllerVer >=3D SD_MMC_HC_CTRL_VER_410) { + HostCtrl2 |=3D SD_MMC_HC_26_DATA_LEN_ADMA_EN; + DEBUG ((DEBUG_INFO, "Enabled V4 26 bit data length ADMA support\n"))= ; + } + Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (H= ostCtrl2), &HostCtrl2); + if (EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_SUCCESS; +} + +/** + Supply SD/MMC card with lowest clock frequency at initialization. + + @param[in] PciIo The PCI IO protocol instance. + @param[in] Slot The slot number of the SD card to send the com= mand to. + @param[in] BaseClkFreq The base clock frequency of host controller in= MHz. + @param[in] ControllerVer The version of host controller. @retval EFI_SUCCESS The clock is supplied successfully. @retval Others The clock isn't supplied successfully. @@ -908,16 +1029,20 @@ EFI_STATUS SdMmcHcInitClockFreq ( IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT8 Slot, - IN SD_MMC_HC_SLOT_CAP Capability + IN UINT32 BaseClkFreq, + IN UINT16 ControllerVer ) { EFI_STATUS Status; UINT32 InitFreq; // - // Calculate a divisor for SD clock frequency + // According to SDHCI specification ver. 4.2, BaseClkFreq field value of + // the Capability Register 1 can be zero, which means a need for obtaini= ng + // the clock frequency via another method. Fail in case it is not update= d + // by SW at this point. // - if (Capability.BaseClkFreq =3D=3D 0) { + if (BaseClkFreq =3D=3D 0) { // // Don't support get Base Clock Frequency information via another meth= od // @@ -927,7 +1052,7 @@ SdMmcHcInitClockFreq ( // Supply 400KHz clock frequency at initialization phase. // InitFreq =3D 400; - Status =3D SdMmcHcClockSupply (PciIo, Slot, InitFreq, Capability); + Status =3D SdMmcHcClockSupply (PciIo, Slot, InitFreq, BaseClkFreq, Contr= ollerVer); return Status; } @@ -988,15 +1113,6 @@ SdMmcHcInitPowerVoltage ( // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Re= gister // Status =3D SdMmcHcPowerControl (PciIo, Slot, MaxVoltage); - if (BhtHostPciSupport(PciIo)){ - // 1.8V signaling enable - HostCtrl2 =3D BIT3; - Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL= 2, sizeof (HostCtrl2), &HostCtrl2); - gBS->Stall (5000); - if (EFI_ERROR (Status)) { - return Status; - } - } return Status; } @@ -1032,9 +1148,8 @@ SdMmcHcInitTimeoutCtrl ( Initial SD/MMC host controller with lowest clock frequency, max power an= d max timeout value at initialization. - @param[in] PciIo The PCI IO protocol instance. + @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instan= ce. @param[in] Slot The slot number of the SD card to send the com= mand to. - @param[in] Capability The capability of the slot. @retval EFI_SUCCESS The host controller is initialized successfull= y. @retval Others The host controller isn't initialized successf= ully. @@ -1042,96 +1157,164 @@ SdMmcHcInitTimeoutCtrl ( **/ EFI_STATUS SdMmcHcInitHost ( - IN EFI_PCI_IO_PROTOCOL *PciIo, - IN UINT8 Slot, - IN SD_MMC_HC_SLOT_CAP Capability + IN SD_MMC_HC_PRIVATE_DATA *Private, + IN UINT8 Slot ) { - EFI_STATUS Status; - UINT32 value32; - - if (BhtHostPciSupport(PciIo)){ - - DbgMsg(L"find bht emmc chip\n"); - /* FET on */ - PciBhtOr32(PciIo, 0xEC, 0x3); - /* Led on */ - //PciBhtAnd32(PciIo, 0x334, (UINT32)~BIT13); - PciBhtOr32(PciIo, 0xD4, BIT6); - /* Set 1.8v emmc signaling flag */ - PciBhtOr32(PciIo, 0x308, BIT4); - /* Set 200MBaseClock */ - value32 =3D PciBhtRead32(PciIo, 0x304); - value32 &=3D 0x0000FFFF; - value32 |=3D 0x25100000; - PciBhtWrite32(PciIo, 0x304, value32); - PciBhtOr32(PciIo, 0x3E4, BIT22); - PciBhtWrite32(PciIo, 0x300, 0x21400033); - - //enable internal clk - value32 =3D BIT0; - Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MM= C_HC_CLOCK_CTRL,sizeof(value32), &value32); - - //reset pll start - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1CC= , TRUE, sizeof(value32), &value32); - value32 |=3D BIT12; - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1CC= , FALSE, sizeof(value32), &value32); - gBS->Stall(1); - - //reset pll end - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1CC= , TRUE,sizeof(value32), &value32); - value32 &=3D ~BIT12; - value32 |=3D BIT18; - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1CC= , FALSE, sizeof(value32), &value32); - - //wait BaseClk stable 0x1CC bit14 - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1CC= , TRUE, sizeof(value32), &value32); - while(!(value32&BIT14)){ - gBS->Stall(100); - Status =3D SdMmcHcRwMmio (Pc= iIo, Slot, 0x1CC, TRUE, sizeof(value32), &value32); - DbgMsg(L"1CC=3D0x%08x\n", va= lue32); - } - - if (value32 & BIT18) - { - //Wait 2nd Card Detect debounce Finished b= y wait twice of debounce max time - while (1) { - Status =3D SdMmcHcRwMmio (PciIo, Slot, S= D_MMC_HC_PRESENT_STATE, TRUE, sizeof(value32), &value32); - if (((value32 >> 16) & 0x01) =3D=3D ((value32 >> 18) & 0x01)) - break; - } - //force pll active end - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1= CC, TRUE, sizeof(value32), &value32); - value32 &=3D ~BIT18; - Status =3D SdMmcHcRwMmio (PciIo, Slot, 0x1= CC, FALSE, sizeof(value32), &value32); - } - - Status =3D SdMmcHcInitPowerVoltage (PciIo, S= lot, Capability); - if (EFI_ERROR (Status)) { - DbgMsg(L"emmc host init failure\n"); - return Status; - } - - - } - - Status =3D SdMmcHcInitClockFreq (PciIo, Slot, Capability); - if (EFI_ERROR (Status)) { - return Status; - } - - if (!BhtHostPciSupport(PciIo)){ - Status =3D SdMmcHcInitPowerVoltage (PciIo, Slot, Capabilit= y); - if (EFI_ERROR (Status)) { - return Status; - } + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + SD_MMC_HC_SLOT_CAP Capability; + + // + // Notify the SD/MMC override protocol that we are about to initialize + // the SD/MMC host controller. + // + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { + Status =3D mOverride->NotifyPhase ( + Private->ControllerHandle, + Slot, + EdkiiSdMmcInitHostPre, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: SD/MMC pre init notifier callback failed - %r\n", + __FUNCTION__, Status)); + return Status; + } + } + + PciIo =3D Private->PciIo; + Capability =3D Private->Capability[Slot]; + + Status =3D SdMmcHcInitV4Enhancements (PciIo, Slot, Capability, Private->= ControllerVersion[Slot]); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot]= , Private->ControllerVersion[Slot]); + if (EFI_ERROR (Status)) { + return Status; } - + + Status =3D SdMmcHcInitPowerVoltage (PciIo, Slot, Capability); + if (EFI_ERROR (Status)) { + return Status; + } + Status =3D SdMmcHcInitTimeoutCtrl (PciIo, Slot); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Notify the SD/MMC override protocol that we are have just initialized + // the SD/MMC host controller. + // + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { + Status =3D mOverride->NotifyPhase ( + Private->ControllerHandle, + Slot, + EdkiiSdMmcInitHostPost, + NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: SD/MMC post init notifier callback failed - %r\n", + __FUNCTION__, Status)); + } + } return Status; } /** + Set SD Host Controler control 2 registry according to selected speed. + + @param[in] ControllerHandle The handle of the controller. + @param[in] PciIo The PCI IO protocol instance. + @param[in] Slot The slot number of the SD card to send the c= ommand to. + @param[in] Timing The timing to select. + + @retval EFI_SUCCESS The timing is set successfully. + @retval Others The timing isn't set successfully. +**/ +EFI_STATUS +SdMmcHcUhsSignaling ( + IN EFI_HANDLE ControllerHandle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT8 Slot, + IN SD_MMC_BUS_MODE Timing + ) +{ + EFI_STATUS Status; + UINT8 HostCtrl2; + + HostCtrl2 =3D (UINT8)~SD_MMC_HC_CTRL_UHS_MASK; + Status =3D SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (Ho= stCtrl2), &HostCtrl2); + if (EFI_ERROR (Status)) { + return Status; + } + + switch (Timing) { + case SdMmcUhsSdr12: + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR12; + break; + case SdMmcUhsSdr25: + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR25; + break; + case SdMmcUhsSdr50: + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR50; + break; + case SdMmcUhsSdr104: + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_SDR104; + break; + case SdMmcUhsDdr50: + HostCtrl2 =3D SD_MMC_HC_CTRL_UHS_DDR50; + break; + case SdMmcMmcLegacy: + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_LEGACY; + break; + case SdMmcMmcHsSdr: + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_HS_SDR; + break; + case SdMmcMmcHsDdr: + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_HS_DDR; + break; + case SdMmcMmcHs200: + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_HS200; + break; + case SdMmcMmcHs400: + HostCtrl2 =3D SD_MMC_HC_CTRL_MMC_HS400; + break; + default: + HostCtrl2 =3D 0; + break; + } + Status =3D SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (Hos= tCtrl2), &HostCtrl2); + if (EFI_ERROR (Status)) { + return Status; + } + + if (mOverride !=3D NULL && mOverride->NotifyPhase !=3D NULL) { + Status =3D mOverride->NotifyPhase ( + ControllerHandle, + Slot, + EdkiiSdMmcUhsSignaling, + &Timing + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: SD/MMC uhs signaling notifier callback failed - %r\n", + __FUNCTION__, + Status + )); + return Status; + } + } + + return EFI_SUCCESS; +} + +/** Turn on/off LED. @param[in] PciIo The PCI IO protocol instance. @@ -1166,9 +1349,10 @@ SdMmcHcLedOnOff ( /** Build ADMA descriptor table for transfer. - Refer to SD Host Controller Simplified spec 3.0 Section 1.13 for details= . + Refer to SD Host Controller Simplified spec 4.2 Section 1.13 for details= . @param[in] Trb The pointer to the SD_MMC_HC_TRB instance. + @param[in] ControllerVer The version of host controller. @retval EFI_SUCCESS The ADMA descriptor table is created successfu= lly. @retval Others The ADMA descriptor table isn't created succes= sfully. @@ -1176,7 +1360,8 @@ SdMmcHcLedOnOff ( **/ EFI_STATUS BuildAdmaDescTable ( - IN SD_MMC_HC_TRB *Trb + IN SD_MMC_HC_TRB *Trb, + IN UINT16 ControllerVer ) { EFI_PHYSICAL_ADDRESS Data; @@ -1184,49 +1369,93 @@ BuildAdmaDescTable ( UINT64 Entries; UINT32 Index; UINT64 Remaining; - UINT32 Address; + UINT64 Address; UINTN TableSize; EFI_PCI_IO_PROTOCOL *PciIo; EFI_STATUS Status; UINTN Bytes; + BOOLEAN AddressingMode64; + BOOLEAN DataLength26; + UINT32 AdmaMaxDataPerLine; + UINT32 DescSize; + VOID *AdmaDesc; + + AddressingMode64 =3D FALSE; + DataLength26 =3D FALSE; + AdmaMaxDataPerLine =3D ADMA_MAX_DATA_PER_LINE_16B; + DescSize =3D sizeof (SD_MMC_HC_ADMA_32_DESC_LINE); + AdmaDesc =3D NULL; Data =3D Trb->DataPhy; DataLen =3D Trb->DataLen; PciIo =3D Trb->Private->PciIo; + // - // Only support 32bit ADMA Descriptor Table + // Detect whether 64bit addressing is supported. // - if ((Data >=3D 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) { + if (ControllerVer >=3D SD_MMC_HC_CTRL_VER_400) { + Status =3D SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2,= sizeof(UINT16), + SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, SD_= MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN); + if (!EFI_ERROR (Status)) { + AddressingMode64 =3D TRUE; + DescSize =3D sizeof (SD_MMC_HC_ADMA_64_DESC_LINE); + } + } + // + // Check for valid ranges in 32bit ADMA Descriptor Table + // + if (!AddressingMode64 && + ((Data >=3D 0x100000000ul) || ((Data + DataLen) > 0x100000000ul))) { return EFI_INVALID_PARAMETER; } // - // Address field shall be set on 32-bit boundary (Lower 2-bit is always = set to 0) - // for 32-bit address descriptor table. + // Check address field alignment // - if ((Data & (BIT0 | BIT1)) !=3D 0) { - DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not a= ligned to 4 bytes boundary!\n", Data)); + if (AddressingMode64) { + // + // Address field shall be set on 64-bit boundary (Lower 3-bit is alway= s set to 0) + // + if ((Data & (BIT0 | BIT1 | BIT2)) !=3D 0) { + DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not= aligned to 8 bytes boundary!\n", Data)); + } + } else { + // + // Address field shall be set on 32-bit boundary (Lower 2-bit is alway= s set to 0) + // + if ((Data & (BIT0 | BIT1)) !=3D 0) { + DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not= aligned to 4 bytes boundary!\n", Data)); + } + } + // + // Detect whether 26bit data length is supported. + // + Status =3D SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, s= izeof(UINT16), + SD_MMC_HC_26_DATA_LEN_ADMA_EN, SD_MMC_HC_26= _DATA_LEN_ADMA_EN); + if (!EFI_ERROR (Status)) { + DataLength26 =3D TRUE; + AdmaMaxDataPerLine =3D ADMA_MAX_DATA_PER_LINE_26B; } - Entries =3D DivU64x32 ((DataLen + ADMA_MAX_DATA_PER_LINE - 1), ADMA_MA= X_DATA_PER_LINE); - TableSize =3D (UINTN)MultU64x32 (Entries, sizeof (SD_MMC_HC_ADMA_DESC_LI= NE)); + Entries =3D DivU64x32 ((DataLen + AdmaMaxDataPerLine - 1), AdmaMaxData= PerLine); + TableSize =3D (UINTN)MultU64x32 (Entries, DescSize); Trb->AdmaPages =3D (UINT32)EFI_SIZE_TO_PAGES (TableSize); Status =3D PciIo->AllocateBuffer ( PciIo, AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES (TableSize), - (VOID **)&Trb->AdmaDesc, + (VOID **)&AdmaDesc, 0 ); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } - ZeroMem (Trb->AdmaDesc, TableSize); + ZeroMem (AdmaDesc, TableSize); Bytes =3D TableSize; Status =3D PciIo->Map ( PciIo, EfiPciIoOperationBusMasterCommonBuffer, - Trb->AdmaDesc, + AdmaDesc, &Bytes, &Trb->AdmaDescPhy, &Trb->AdmaMap @@ -1239,12 +1468,13 @@ BuildAdmaDescTable ( PciIo->FreeBuffer ( PciIo, EFI_SIZE_TO_PAGES (TableSize), - Trb->AdmaDesc + AdmaDesc ); return EFI_OUT_OF_RESOURCES; } - if ((UINT64)(UINTN)Trb->AdmaDescPhy > 0x100000000ul) { + if ((!AddressingMode64) && + (UINT64)(UINTN)Trb->AdmaDescPhy > 0x100000000ul) { // // The ADMA doesn't support 64bit addressing. // @@ -1255,35 +1485,71 @@ BuildAdmaDescTable ( PciIo->FreeBuffer ( PciIo, EFI_SIZE_TO_PAGES (TableSize), - Trb->AdmaDesc + AdmaDesc ); return EFI_DEVICE_ERROR; } Remaining =3D DataLen; - Address =3D (UINT32)Data; + Address =3D Data; + if (!AddressingMode64) { + Trb->Adma32Desc =3D AdmaDesc; + Trb->Adma64Desc =3D NULL; + } else { + Trb->Adma64Desc =3D AdmaDesc; + Trb->Adma32Desc =3D NULL; + } for (Index =3D 0; Index < Entries; Index++) { - if (Remaining <=3D ADMA_MAX_DATA_PER_LINE) { - Trb->AdmaDesc[Index].Valid =3D 1; - Trb->AdmaDesc[Index].Act =3D 2; - Trb->AdmaDesc[Index].Length =3D (UINT16)Remaining; - Trb->AdmaDesc[Index].Address =3D Address; - break; + if (!AddressingMode64) { + if (Remaining <=3D AdmaMaxDataPerLine) { + Trb->Adma32Desc[Index].Valid =3D 1; + Trb->Adma32Desc[Index].Act =3D 2; + if (DataLength26) { + Trb->Adma32Desc[Index].UpperLength =3D (UINT16)RShiftU64 (Remain= ing, 16); + } + Trb->Adma32Desc[Index].LowerLength =3D (UINT16)(Remaining & MAX_UI= NT16); + Trb->Adma32Desc[Index].Address =3D (UINT32)Address; + break; + } else { + Trb->Adma32Desc[Index].Valid =3D 1; + Trb->Adma32Desc[Index].Act =3D 2; + if (DataLength26) { + Trb->Adma32Desc[Index].UpperLength =3D 0; + } + Trb->Adma32Desc[Index].LowerLength =3D 0; + Trb->Adma32Desc[Index].Address =3D (UINT32)Address; + } } else { - Trb->AdmaDesc[Index].Valid =3D 1; - Trb->AdmaDesc[Index].Act =3D 2; - Trb->AdmaDesc[Index].Length =3D 0; - Trb->AdmaDesc[Index].Address =3D Address; + if (Remaining <=3D AdmaMaxDataPerLine) { + Trb->Adma64Desc[Index].Valid =3D 1; + Trb->Adma64Desc[Index].Act =3D 2; + if (DataLength26) { + Trb->Adma64Desc[Index].UpperLength =3D (UINT16)RShiftU64 (Remai= ning, 16); + } + Trb->Adma64Desc[Index].LowerLength =3D (UINT16)(Remaining & MAX_U= INT16); + Trb->Adma64Desc[Index].LowerAddress =3D (UINT32)Address; + Trb->Adma64Desc[Index].UpperAddress =3D (UINT32)RShiftU64 (Address= , 32); + break; + } else { + Trb->Adma64Desc[Index].Valid =3D 1; + Trb->Adma64Desc[Index].Act =3D 2; + if (DataLength26) { + Trb->Adma64Desc[Index].UpperLength =3D 0; + } + Trb->Adma64Desc[Index].LowerLength =3D 0; + Trb->Adma64Desc[Index].LowerAddress =3D (UINT32)Address; + Trb->Adma64Desc[Index].UpperAddress =3D (UINT32)RShiftU64 (Address= , 32); + } } - Remaining -=3D ADMA_MAX_DATA_PER_LINE; - Address +=3D ADMA_MAX_DATA_PER_LINE; + Remaining -=3D AdmaMaxDataPerLine; + Address +=3D AdmaMaxDataPerLine; } // // Set the last descriptor line as end of descriptor table // - Trb->AdmaDesc[Index].End =3D 1; + AddressingMode64 ? (Trb->Adma64Desc[Index].End =3D 1) : (Trb->Adma32Desc= [Index].End =3D 1); return EFI_SUCCESS; } @@ -1381,7 +1647,7 @@ SdMmcCreateTrb ( Trb->Mode =3D SdMmcNoData; } else if (Private->Capability[Slot].Adma2 !=3D 0) { Trb->Mode =3D SdMmcAdmaMode; - Status =3D BuildAdmaDescTable (Trb); + Status =3D BuildAdmaDescTable (Trb, Private->ControllerVersion[Slot]= ); if (EFI_ERROR (Status)) { PciIo->Unmap (PciIo, Trb->DataMap); goto Error; @@ -1427,11 +1693,18 @@ SdMmcFreeTrb ( Trb->AdmaMap ); } - if (Trb->AdmaDesc !=3D NULL) { + if (Trb->Adma32Desc !=3D NULL) { + PciIo->FreeBuffer ( + PciIo, + Trb->AdmaPages, + Trb->Adma32Desc + ); + } + if (Trb->Adma64Desc !=3D NULL) { PciIo->FreeBuffer ( PciIo, Trb->AdmaPages, - Trb->AdmaDesc + Trb->Adma64Desc ); } if (Trb->DataMap !=3D NULL) { @@ -1571,12 +1844,15 @@ SdMmcExecTrb ( UINT16 Cmd; UINT16 IntStatus; UINT32 Argument; - UINT16 BlkCount; + UINT32 BlkCount; UINT16 BlkSize; UINT16 TransMode; UINT8 HostCtrl1; - UINT32 SdmaAddr; + UINT64 SdmaAddr; UINT64 AdmaAddr; + BOOLEAN AddressingMode64; + + AddressingMode64 =3D FALSE; Packet =3D Trb->Packet; PciIo =3D Trb->Private->PciIo; @@ -1609,13 +1885,28 @@ SdMmcExecTrb ( SdMmcHcLedOnOff (PciIo, Trb->Slot, TRUE); + if (Private->ControllerVersion[Trb->Slot] >=3D SD_MMC_HC_CTRL_VER_400) { + Status =3D SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2,= sizeof(UINT16), + SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, SD_= MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN); + if (!EFI_ERROR (Status)) { + AddressingMode64 =3D TRUE; + } + } + if (Trb->Mode =3D=3D SdMmcSdmaMode) { - if ((UINT64)(UINTN)Trb->DataPhy >=3D 0x100000000ul) { + if ((!AddressingMode64) && + ((UINT64)(UINTN)Trb->DataPhy >=3D 0x100000000ul)) { return EFI_INVALID_PARAMETER; } - SdmaAddr =3D (UINT32)(UINTN)Trb->DataPhy; - Status =3D SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, FAL= SE, sizeof (SdmaAddr), &SdmaAddr); + SdmaAddr =3D (UINT64)(UINTN)Trb->DataPhy; + + if (Private->ControllerVersion[Trb->Slot] >=3D SD_MMC_HC_CTRL_VER_400)= { + Status =3D SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_ADMA_SYS_ADDR,= FALSE, sizeof (UINT64), &SdmaAddr); + } else { + Status =3D SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, FAL= SE, sizeof (UINT32), &SdmaAddr); + } + if (EFI_ERROR (Status)) { return Status; } @@ -1645,9 +1936,13 @@ SdMmcExecTrb ( // // Calcuate Block Count. // - BlkCount =3D (UINT16)(Trb->DataLen / Trb->BlockSize); + BlkCount =3D (Trb->DataLen / Trb->BlockSize); + } + if (Private->ControllerVersion[Trb->Slot] >=3D SD_MMC_HC_CTRL_VER_410) { + Status =3D SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, FALSE= , sizeof (UINT32), &BlkCount); + } else { + Status =3D SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, FALSE= , sizeof (UINT16), &BlkCount); } - Status =3D SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, FALSE= , sizeof (BlkCount), &BlkCount); if (EFI_ERROR (Status)) { return Status; } @@ -1743,7 +2038,7 @@ SdMmcCheckTrbResult ( EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet; UINT16 IntStatus; UINT32 Response[4]; - UINT32 SdmaAddr; + UINT64 SdmaAddr; UINT8 Index; UINT8 SwReset; UINT32 PioLength; @@ -1867,8 +2162,19 @@ SdMmcCheckTrbResult ( // // Update SDMA Address register. // - SdmaAddr =3D SD_MMC_SDMA_ROUND_UP ((UINT32)(UINTN)Trb->DataPhy, SD_MMC= _SDMA_BOUNDARY); - Status =3D SdMmcHcRwMmio ( + SdmaAddr =3D SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, SD_MMC_SDMA_BO= UNDARY); + + if (Private->ControllerVersion[Trb->Slot] >=3D SD_MMC_HC_CTRL_VER_400)= { + Status =3D SdMmcHcRwMmio ( + Private->PciIo, + Trb->Slot, + SD_MMC_HC_ADMA_SYS_ADDR, + FALSE, + sizeof (UINT64), + &SdmaAddr + ); + } else { + Status =3D SdMmcHcRwMmio ( Private->PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, @@ -1876,10 +2182,12 @@ SdMmcCheckTrbResult ( sizeof (UINT32), &SdmaAddr ); + } + if (EFI_ERROR (Status)) { goto Done; } - Trb->DataPhy =3D (UINT32)(UINTN)SdmaAddr; + Trb->DataPhy =3D (UINT64)(UINTN)SdmaAddr; } if ((Packet->SdMmcCmdBlk->CommandType !=3D SdMmcCommandTypeAdtc) && @@ -2000,281 +2308,3 @@ SdMmcWaitTrbResult ( return EFI_TIMEOUT; } -BOOLEAN BhtHostPciSupport(EFI_PCI_IO_PROTOCOL *PciIo) -{ - PCI_TYPE00 Pci; - - PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, - 0, sizeof = Pci / sizeof (UINT32), &Pci); - - DEBUG ((DEBUG_INFO, "check device %04x:%04x\n", Pci.Hdr.Vend= orId, Pci.Hdr.DeviceId)); - - if (Pci.Hdr.VendorId !=3D 0x1217) - goto end; - - switch (Pci.Hdr.DeviceId) - { - case 0x8420: //PCI_DEV_ID_SDS0 - case 0x8421: //PCI_DEV_ID_SDS1 - case 0x8520: //PCI_DEV_ID_FJ2 - case 0x8620: //PCI_DEV_ID_SB0 - case 0x8621: //PCI_DEV_ID_SB1 - g_deviceId =3D Pci.Hdr.Devic= eId; - return 1; - default: - break; - } - - end: - return 0; -} - -void DbgNull(IN CONST CHAR16 * fmt, ...) -{ -} - -UINT32 bht_readl(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 offset) -{ - UINT32 arg; - PciIo->Mem.Read(PciIo,EfiPciIoWidthUint32,1,offset,1,&arg); - return arg; -} - -void bht_writel(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 offset, UINT32 value) -{ - PciIo->Mem.Write(PciIo,EfiPciIoWidthUint32,1,offset,1,&value= ); -} - - -UINT32 PciBhtRead32(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 offset) -{ - UINT32 i =3D 0; - UINT32 tmp[3] =3D {0}; - - if((g_deviceId =3D=3D PCI_DEV_ID_SDS0) || - (g_deviceId =3D=3D PCI_DEV_I= D_SDS1) || - (g_deviceId =3D=3D PCI_DEV_I= D_FJ2) || - (g_deviceId =3D=3D PCI_DEV_I= D_SB0) || - (g_deviceId =3D=3D PCI_DEV_I= D_SB1)) - { - // For Sandstorm, HW implement a mapping met= hod by memory space reg to access PCI reg. - // Enable mapping - - // Check function conflict - if((g_deviceId =3D=3D PCI_DEV_ID_SDS0) || - (g_deviceId = =3D=3D PCI_DEV_ID_FJ2) || - (g_deviceId = =3D=3D PCI_DEV_ID_SB0) || - (g_deviceId = =3D=3D PCI_DEV_ID_SB1)) - { - i =3D 0; - bht_writel(PciIo, BHT_PCIRMa= ppingEn, 0x40000000); - while((bht_readl(PciIo, BHT_= PCIRMappingEn) & 0x40000000) =3D=3D 0) - { - if(i =3D=3D = 5) - { - = //DbgMsg((DRIVERNAME " - %s() function 0 can't lock!\n", __FUNCTION__))= ; - = goto RD_DIS_MAPPING; - } - = gBS->Stall(1000); - i++; - = bht_writel(PciIo, BHT_PCIRMappingEn, 0x40000000); - - } - } - else if(g_deviceId =3D=3D PCI_DEV_ID_SDS1) - { - i =3D 0; - bht_writel(PciIo, BHT_PCIRMa= ppingEn, 0x20000000); - while((bht_readl(PciIo, BHT_= PCIRMappingEn) & 0x20000000) =3D=3D 0) - { - if(i =3D=3D = 5) - { - = //DbgErr((DRIVERNAME " - %s() function 1 can't lock!\n", __FUNCTION__))= ; - = goto RD_DIS_MAPPING; - } - gBS->Stall(1= 000); - i++; - bht_writel(P= ciIo, BHT_PCIRMappingEn, 0x20000000); - } - } - - // Check last operation is complete - i =3D 0; - while(bht_readl(PciIo, BHT_PCIRMappingCtl) &= 0xc0000000) - { - if(i =3D=3D 5) - { - //DbgErr((DR= IVERNAME " - [204] =3D 0x%x\n", RegisterRead32(ELN_dPCIRMappingCtl))); - //DbgErr((DR= IVERNAME " - [208] =3D 0x%x\n", RegisterRead32(ELN_dPCIRMappingEn))); - //DbgErr((DR= IVERNAME " - %s() check last operation complete timeout!!!\n", __FUNCTION__= )); - goto RD_DIS_= MAPPING; - } - gBS->Stall(1000); - i +=3D 1; - } - - // Set register address - tmp[0] |=3D 0x40000000; - tmp[0] |=3D offset; - bht_writel(PciIo, BHT_PCIRMappingCtl, tmp[0]= ); - - // Check read is complete - i =3D 0; - while(bht_readl(PciIo, BHT_PCIRMappingCtl) &= 0x40000000) - { - if(i =3D=3D 5) - { - //DbgErr((DR= IVERNAME " - %s() check read operation complete timeout!!!\n", __FUNCTION__= )); - goto RD_DIS_= MAPPING; - } - gBS->Stall(1000); - i +=3D 1; - } - - // Get PCIR value - tmp[1] =3D bht_readl(PciIo, BHT_PCIRMappingV= al); - -RD_DIS_MAPPING: - // Disable mapping - bht_writel(PciIo, BHT_PCIRMappingEn, 0x80000= 000); - - //DbgDebug(L"%s offset=3D%x Value:%x\n", __F= UNCTION__, offset, tmp[1]); - return tmp[1]; - } - - //DbgDebug(L"%s offset=3D%x Value:%x\n", __FUNCTION__, offse= t, tmp[0]); - return tmp[0]; -} - -void PciBhtWrite32(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 offset, UINT32 value= ) -{ - UINT32 tmp =3D 0; - UINT32 i =3D 0; - - if((g_deviceId =3D=3D PCI_DEV_ID_SDS0) || - (g_deviceId =3D=3D PCI_DEV_I= D_SDS1) || - (g_deviceId =3D=3D PCI_DEV_I= D_FJ2) || - (g_deviceId =3D=3D PCI_DEV_I= D_SB0) || - (g_deviceId =3D=3D PCI_DEV_I= D_SB1)) - { - // For Sandstorm, HW implement a mapping method by memory space re= g to access PCI reg. - // Upper caller doesn't need to set 0xD0. - - // Enable mapping - - // Check function conflict - if((g_deviceId =3D=3D PCI_DEV_ID_SDS0) || - (g_deviceId = =3D=3D PCI_DEV_ID_FJ2) || - (g_deviceId = =3D=3D PCI_DEV_ID_SB0) || - (g_deviceId = =3D=3D PCI_DEV_ID_SB1)) - { - i =3D 0; - bht_writel(PciIo, BHT_PCIRMappingEn, 0x40000000); - while((bht_readl(PciIo, BHT_PCIRMappingEn) & 0x40000000) =3D= =3D 0) - { - if(i =3D=3D 5) - { - //DbgErr((DRIVERNAME " - %s() function 0 can't lock!\n= ", __FUNCTION__)); - goto WR_DIS_MAPPING; - } - - gBS->Stall(1000); - i++; - bht_writel(PciIo, BHT_PCIRMappingEn, 0x40000000); - } - } - else if(g_deviceId =3D=3D PCI_DEV_ID_SDS1) - { - i =3D 0; - bht_writel(PciIo, BHT_PCIRMappingEn, 0x20000000); - - while((bht_readl(PciIo, BHT_PCIRMappingEn) & 0x20000000) =3D= =3D 0) - { - if(i =3D=3D 5) - { - //DbgErr((DRIVERNAME " - %s() function 0 can't lock!\n= ", __FUNCTION__)); - goto WR_DIS_MAPPING; - } - - gBS->Stall(1000); - i++; - bht_writel(PciIo, BHT_PCIRMappingEn, 0x20000000); - } - } - - // Enable MEM access - bht_writel(PciIo, BHT_PCIRMappingVal, 0x80000000); - bht_writel(PciIo, BHT_PCIRMappingCtl, 0x800000D0); - - // Check last operation is complete - i =3D 0; - while(bht_readl(PciIo, BHT_PCIRMappingCtl) & 0xc0000000) - { - if(i =3D=3D 5) - { - //DbgErr((DRIVERNAME " - %s() check last operation complet= e timeout!!!\n", __FUNCTION__)); - goto WR_DIS_MAPPING; - } - gBS->Stall(1000); - i +=3D 1; - } - - // Set write value - bht_writel(PciIo, BHT_PCIRMappingVal, value); - // Set register address - tmp |=3D 0x80000000; - tmp |=3D offset; - bht_writel(PciIo, BHT_PCIRMappingCtl, tmp); - - // Check write is complete - i =3D 0; - while(bht_readl(PciIo, BHT_PCIRMappingCtl) & 0x80000000) - { - if(i =3D=3D 5) - { - //DbgErr((DRIVERNAME " - %s() check write operation comple= te timeout!!!\n", __FUNCTION__)); - goto WR_DIS_MAPPING; - } - gBS->Stall(1000); - i +=3D 1; - } - -WR_DIS_MAPPING: - // Disable MEM access - bht_writel(PciIo, BHT_PCIRMappingVal, 0x80000001); - bht_writel(PciIo, BHT_PCIRMappingCtl, 0x800000D0); - - // Check last operation is complete - i =3D 0; - while(bht_readl(PciIo, BHT_PCIRMappingCtl) & 0xc0000000) - { - if(i =3D=3D 5) - { - //DbgErr((DRIVERNAME " - %s() check last operation complet= e timeout!!!\n", __FUNCTION__)); - break; - } - gBS->Stall(1000); - i +=3D 1; - } - - // Disable function conflict - - // Disable mapping - bht_writel(PciIo, BHT_PCIRMappingEn, 0x80000000); - } -} - -void PciBhtOr32(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 offset, UINT32 value) -{ - UINT32 arg; - arg =3D PciBhtRead32(PciIo, offset); - PciBhtWrite32(PciIo, offset, value | arg); -} - -void PciBhtAnd32(EFI_PCI_IO_PROTOCOL *PciIo, UINT32 offset, UINT32 value) -{ - UINT32 arg; - arg =3D PciBhtRead32(PciIo, offset); - PciBhtWrite32(PciIo, offset, value & arg); -} - Please check it! Br, Mike