From nobody Thu Mar 28 18:12:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+83642+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+83642+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1636631972; cv=none; d=zohomail.com; s=zohoarc; b=P4HItoVzpefQ432RlxMOOiicwUGB5GKHSURSP76YK+8kmLeTQ0Xw3uGaqqlc/Z+czcYBqFTmvv0Z4ikORxv0Teh7retaBkFY+US65umfSzzL9WnNO6nk7BTZMEgTNl1D4mXqVQvy/dXXD2AjD4eJs8r/ml3VZDjO2sZgscwv2BI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1636631972; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=mHayJiAaQu37tT1UP98TgNjNQAMzOTBip/zuksYKgI4=; b=A4YyI0xyDvPRT6H2yvOyCTE+4UrbZ34Mrwt3ZTHkGhdh2YpTA8JNSnH9BA8K+05gZa+F8rutV9niAeQzVrxvAdZyqqWM3UzuMxfHDwx/uWyTiB3Lwc3jI7N2+COG8QafjObRbSsWDo+xNjBci+49x45tG5mmaXfP103hN5SMu5Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+83642+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1636631972076417.2786229444122; Thu, 11 Nov 2021 03:59:32 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id kJvyYY1788612xwde7j3H3WL; Thu, 11 Nov 2021 03:59:31 -0800 X-Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) by mx.groups.io with SMTP id smtpd.web10.9625.1636631970493471968 for ; Thu, 11 Nov 2021 03:59:30 -0800 X-Received: by mail-ed1-f52.google.com with SMTP id w1so23212819edd.10 for ; Thu, 11 Nov 2021 03:59:30 -0800 (PST) X-Gm-Message-State: 0yLdpwlIaYvYF4HsfPUqOzbax1787277AA= X-Google-Smtp-Source: ABdhPJwoRCLLtpEeOHXvCkhsYPkSXqFIn+NSR+PJeQKpwFn0L3zNB9zy7f7cx8PJa9OUz46rEytWqg== X-Received: by 2002:a17:906:12d0:: with SMTP id l16mr8337051ejb.415.1636631968719; Thu, 11 Nov 2021 03:59:28 -0800 (PST) X-Received: from qc-i7.qualcomm.com (cpc92314-cmbg19-2-0-cust559.5-4.cable.virginm.net. [82.11.186.48]) by smtp.gmail.com with ESMTPSA id j21sm833442edp.21.2021.11.11.03.59.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Nov 2021 03:59:28 -0800 (PST) From: "Leif Lindholm" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Masami Hiramatsu Subject: [edk2-devel] [PATCH edk2-platforms 1/2] Maintainers.txt: add Masami as Socionext reviewer Date: Thu, 11 Nov 2021 11:59:25 +0000 Message-Id: <20211111115926.2317981-2-leif@nuviainc.com> In-Reply-To: <20211111115926.2317981-1-leif@nuviainc.com> References: <20211111115926.2317981-1-leif@nuviainc.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,leif@nuviainc.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1636631971; bh=p6rLtHrE29Tfu0vGqUbIPTyz+Vst4UXCya1Vrss+CdE=; h=Cc:Date:From:Reply-To:Subject:To; b=bxQCD/Hc6d+7fzg17urSUrb6oaevLQSCB7ocQ2anATGBo+feH0S3N0W7yF4INP+ywjm e69O7aBuJfF9xIM+YETLFsyX/jrZRx0adXYSqHY6zvL4mhKgEI4XbkdOt9m81nF88IDgN nI3FJwevMqr9olGj3ftSrn0hVt0PbfnLrGM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1636631972615100003 Content-Type: text/plain; charset="utf-8" Masami is the main contributor to these platforms, and would be useful to have listed as a reviewer. Signed-off-by: Leif Lindholm Cc: Masami Hiramatsu Acked-by: Ard BIesheuvel Acked-by: Masami Hiramatsu --- Maintainers.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Maintainers.txt b/Maintainers.txt index c839c71b2262..093d36e4088d 100644 --- a/Maintainers.txt +++ b/Maintainers.txt @@ -359,6 +359,7 @@ F: Silicon/NXP/Library/Pcf8563RealTimeClockLib/ F: Silicon/Socionext/ M: Ard Biesheuvel M: Leif Lindholm +R: Masami Hiramatsu =20 Silicon/RISC-V/ProcessorPkg F: Silicon/RISC-V/ProcessorPkg/ --=20 2.30.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#83642): https://edk2.groups.io/g/devel/message/83642 Mute This Topic: https://groups.io/mt/86979608/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Thu Mar 28 18:12:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+83643+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+83643+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1636631973; cv=none; d=zohomail.com; s=zohoarc; b=NJUgKDJ4nQ39QW7HpxRFYZMDBVK2itHt+UehtY5CqWszcpQbby30GFuCgrK36L2bAyXG/KlS8jtAG8i00kKNhKMhxVvBRkTb3LXLPFB5PbKvC0jwlH16Ry5a0rfkOu1L+84yMYDE4U62Ep2Dzg+y/T/LOWEHVXE0KXFLXomleUw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1636631973; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=CvriSwCL3KmbDJuQKE0Lmae7mOZ8aEJ3qZM+gnklJx0=; b=FOkBY4F4Ee70VJgoBiiJ27P/Ahzo/q83ykgUnTV90HbCFcvcvygsRx1WdiLyAfigQ9djabqhZGFE2EtmCDkz7Q62XKHgwRklzIOHvC1T6chJ0Uvm2+RW4YsZa4fChprvvOqQrHDn7wggHdmt7Qkk/X3EUnOw2akGuOvlxmvqTXI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+83643+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 16366319736036.671079903214377; Thu, 11 Nov 2021 03:59:33 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8z9PYY1788612xWFhaSJNioE; Thu, 11 Nov 2021 03:59:33 -0800 X-Received: from mail-ed1-f42.google.com (mail-ed1-f42.google.com [209.85.208.42]) by mx.groups.io with SMTP id smtpd.web09.9535.1636631972256755271 for ; Thu, 11 Nov 2021 03:59:32 -0800 X-Received: by mail-ed1-f42.google.com with SMTP id o8so23082022edc.3 for ; Thu, 11 Nov 2021 03:59:32 -0800 (PST) X-Gm-Message-State: YMjdULsBqBqhPPh7sE3WHRyZx1787277AA= X-Google-Smtp-Source: ABdhPJyUNgNZoYLW1cA4o2NgtnEbs3nUFcK5rQEwCxCEefzghpKax3gtN2HnbamAtKSoOXR5D62/ig== X-Received: by 2002:a05:6402:4396:: with SMTP id o22mr9085471edc.353.1636631969801; Thu, 11 Nov 2021 03:59:29 -0800 (PST) X-Received: from qc-i7.qualcomm.com (cpc92314-cmbg19-2-0-cust559.5-4.cable.virginm.net. [82.11.186.48]) by smtp.gmail.com with ESMTPSA id j21sm833442edp.21.2021.11.11.03.59.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Nov 2021 03:59:29 -0800 (PST) From: "Leif Lindholm" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Masami Hiramatsu Subject: [edk2-devel] [PATCH edk2-platforms 2/2] Silicon/Socionext: fix line endings Date: Thu, 11 Nov 2021 11:59:26 +0000 Message-Id: <20211111115926.2317981-3-leif@nuviainc.com> In-Reply-To: <20211111115926.2317981-1-leif@nuviainc.com> References: <20211111115926.2317981-1-leif@nuviainc.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,leif@nuviainc.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1636631973; bh=yXsy0FNBcjUMcwMqvF/KnSWvM7t07ib+8q6Uag0VL64=; h=Cc:Date:From:Reply-To:Subject:To; b=Eb4LP9Hxvxa5TVMVfmNOWGdYajk5Uxc1rtXG2XeBOr1Lnm2p2aAeLZvvZ49OoND9vbW QQ2fS8KScJ7wPo+wCso3xQWS8vbIH+aaPnWM/e0LiXvSvInabPKqOZH9STADXfXLFxlnS wqWARLq01zlXlive2FNoY0Nqvcupur9TZsw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1636631975294100001 Content-Type: text/plain; charset="utf-8" SynQuacerI2cDxe.c (and no other Socionext source files) has LF instead of CRLF line endings, so fix that. Signed-off-by: Leif Lindholm Cc: Masami Hiramatsu Acked-by: Ard BIesheuvel Acked-by: Masami Hiramatsu --- Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c | 11= 62 ++++++++++---------- 1 file changed, 581 insertions(+), 581 deletions(-) diff --git a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI= 2cDxe.c b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cD= xe.c index 31f6e3072f4d..8aa979901837 100644 --- a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c +++ b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerI2cDxe/SynQuacerI2cDxe.c @@ -1,581 +1,581 @@ -/** @file - - Copyright (c) 2017, Linaro, Ltd. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include "SynQuacerI2cDxe.h" - -// -// We cannot use Stall () or timer events at runtime, so we need to busy-w= ait -// for the controller to signal the completion interrupts. This value was -// arbitrarily chosen, and does not appear to produce any premature timeou= ts -// nor does it result in noticeable stalls in case of bus errors. -// -#define WAIT_FOR_INTERRUPT_TIMEOUT 50000 - -/** - Set the frequency for the I2C clock line. - - This routine must be called at or below TPL_NOTIFY. - - The software and controller do a best case effort of using the specified - frequency for the I2C bus. If the frequency does not match exactly then - the I2C master protocol selects the next lower frequency to avoid - exceeding the operating conditions for any of the I2C devices on the bus. - For example if 400 KHz was specified and the controller's divide network - only supports 402 KHz or 398 KHz then the I2C master protocol selects 398 - KHz. If there are not lower frequencies available, then return - EFI_UNSUPPORTED. - - @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structure - @param[in] BusClockHertz Pointer to the requested I2C bus clock frequen= cy - in Hertz. Upon return this value contains the - actual frequency in use by the I2C controller. - - @retval EFI_SUCCESS The bus frequency was set successfully. - @retval EFI_ALREADY_STARTED The controller is busy with another transa= ction. - @retval EFI_INVALID_PARAMETER BusClockHertz is NULL - @retval EFI_UNSUPPORTED The controller does not support this frequ= ency. - -**/ -STATIC -EFI_STATUS -EFIAPI -SynQuacerI2cSetBusFrequency ( - IN CONST EFI_I2C_MASTER_PROTOCOL *This, - IN OUT UINTN *BusClockHertz - ) -{ - SYNQUACER_I2C_MASTER *I2c; - UINT8 Ccr, Csr; - - I2c =3D SYNQUACER_I2C_FROM_THIS (This); - - if (BusClockHertz =3D=3D NULL) { - return EFI_INVALID_PARAMETER; - } - - if (*BusClockHertz >=3D F_I2C_SPEED_FM) { - if (REFCLK_RATE <=3D F_I2C_CLK_RATE_18M) { - Ccr =3D F_I2C_CCR_CS_FAST_MAX_18M (REFCLK_RATE); - Csr =3D F_I2C_CSR_CS_FAST_MAX_18M (REFCLK_RATE); - } else { - Ccr =3D F_I2C_CCR_CS_FAST_MIN_18M (REFCLK_RATE); - Csr =3D F_I2C_CSR_CS_FAST_MIN_18M (REFCLK_RATE); - } - - // Set Clock and enable, Set fast mode - MmioWrite8 (I2c->MmioBase + F_I2C_REG_CCR, - Ccr | F_I2C_CCR_FM | F_I2C_CCR_EN); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_CSR, Csr); - - *BusClockHertz =3D F_I2C_SPEED_FM; - - } else if (*BusClockHertz >=3D F_I2C_SPEED_SM) { - if (REFCLK_RATE <=3D F_I2C_CLK_RATE_18M) { - Ccr =3D F_I2C_CCR_CS_STANDARD_MAX_18M (REFCLK_RATE); - Csr =3D F_I2C_CSR_CS_STANDARD_MAX_18M (REFCLK_RATE); - } else { - Ccr =3D F_I2C_CCR_CS_STANDARD_MIN_18M (REFCLK_RATE); - Csr =3D F_I2C_CSR_CS_STANDARD_MIN_18M (REFCLK_RATE); - } - - // Set Clock and enable, Set standard mode - MmioWrite8 (I2c->MmioBase + F_I2C_REG_CCR, Ccr | F_I2C_CCR_EN); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_CSR, Csr); - - *BusClockHertz =3D F_I2C_SPEED_SM; - } else { - return EFI_UNSUPPORTED; - } - - MemoryFence (); - - return EFI_SUCCESS; -} - -/** - Reset the I2C controller and configure it for use - - This routine must be called at or below TPL_NOTIFY. - - The I2C controller is reset. The caller must call SetBusFrequench() aft= er - calling Reset(). - - @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structur= e. - - @retval EFI_SUCCESS The reset completed successfully. - @retval EFI_ALREADY_STARTED The controller is busy with another transact= ion. - @retval EFI_DEVICE_ERROR The reset operation failed. - -**/ -STATIC -EFI_STATUS -EFIAPI -SynQuacerI2cReset ( - IN CONST EFI_I2C_MASTER_PROTOCOL *This - ) -{ - SYNQUACER_I2C_MASTER *I2c; - - I2c =3D SYNQUACER_I2C_FROM_THIS (This); - - // Disable the clock - MmioWrite8 (I2c->MmioBase + F_I2C_REG_CCR, 0); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_CSR, 0); - - MemoryFence (); - - // Set own Address - MmioWrite8 (I2c->MmioBase + F_I2C_REG_ADR, 0); - - // Set PCLK frequency - MmioWrite8 (I2c->MmioBase + F_I2C_REG_FSR, F_I2C_BUS_CLK_FR (REFCLK_RATE= )); - - // clear IRQ (INT=3D0, BER=3D0), Interrupt Disable - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, 0); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BC2R, 0); - - MemoryFence (); - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -SynQuacerI2cMasterStart ( - IN SYNQUACER_I2C_MASTER *I2c, - IN UINTN SlaveAddress, - IN EFI_I2C_OPERATION *Op - ) -{ - UINT8 Bsr; - UINT8 Bcr; - - if (Op->Flags & I2C_FLAG_READ) { - MmioWrite8 (I2c->MmioBase + F_I2C_REG_DAR, (SlaveAddress << 1) | 1); - } else { - MmioWrite8 (I2c->MmioBase + F_I2C_REG_DAR, SlaveAddress << 1); - } - - DEBUG ((DEBUG_INFO, "%a: slave:0x%02x\n", __FUNCTION__, - SlaveAddress)); - - Bsr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR); - Bcr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BCR); - - if ((Bsr & F_I2C_BSR_BB) && !(Bcr & F_I2C_BCR_MSS)) { - DEBUG ((DEBUG_INFO, "%a: bus is busy\n", __FUNCTION__)); - return EFI_ALREADY_STARTED; - } - - if (Bsr & F_I2C_BSR_BB) { // Bus is busy - DEBUG ((DEBUG_INFO, "%a: Continuous Start\n", __FUNCTION__)); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, Bcr | F_I2C_BCR_SCC); - } else { - if (Bcr & F_I2C_BCR_MSS) { - DEBUG ((DEBUG_WARN, - "%a: is not in master mode\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - DEBUG ((DEBUG_INFO, "%a: Start Condition\n", __FUNCTION__)); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, - Bcr | F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE); - } - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -WaitForInterrupt ( - IN SYNQUACER_I2C_MASTER *I2c - ) -{ - UINT8 Bsr; - UINTN Timeout =3D WAIT_FOR_INTERRUPT_TIMEOUT; - - do { - MemoryFence (); - - Bsr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BCR); - if (Bsr & F_I2C_BCR_INT) { - return EFI_SUCCESS; - } - } while (Timeout--); - - return EFI_DEVICE_ERROR; -} - -/** - Start an I2C transaction on the host controller. - - This routine must be called at or below TPL_NOTIFY. For synchronous - requests this routine must be called at or below TPL_CALLBACK. - - This function initiates an I2C transaction on the controller. To - enable proper error handling by the I2C protocol stack, the I2C - master protocol does not support queuing but instead only manages - one I2C transaction at a time. This API requires that the I2C bus - is in the correct configuration for the I2C transaction. - - The transaction is performed by sending a start-bit and selecting the - I2C device with the specified I2C slave address and then performing - the specified I2C operations. When multiple operations are requested - they are separated with a repeated start bit and the slave address. - The transaction is terminated with a stop bit. - - When Event is NULL, StartRequest operates synchronously and returns - the I2C completion status as its return value. - - When Event is not NULL, StartRequest synchronously returns EFI_SUCCESS - indicating that the I2C transaction was started asynchronously. The - transaction status value is returned in the buffer pointed to by - I2cStatus upon the completion of the I2C transaction when I2cStatus - is not NULL. After the transaction status is returned the Event is - signaled. - - Note: The typical consumer of this API is the I2C host protocol. - Extreme care must be taken by other consumers of this API to prevent - confusing the third party I2C drivers due to a state change at the - I2C device which the third party I2C drivers did not initiate. I2C - platform specific code may use this API within these guidelines. - - @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structur= e. - @param[in] SlaveAddress Address of the device on the I2C bus. Set the - I2C_ADDRESSING_10_BIT when using 10-bit addres= ses, - clear this bit for 7-bit addressing. Bits 0-6 - are used for 7-bit I2C slave addresses and bits - 0-9 are used for 10-bit I2C slave addresses. - @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET - structure describing the I2C transaction. - @param[in] Event Event to signal for asynchronous transactions, - NULL for synchronous transactions - @param[out] I2cStatus Optional buffer to receive the I2C transaction - completion status - - @retval EFI_SUCCESS The asynchronous transaction was successfu= lly - started when Event is not NULL. - @retval EFI_SUCCESS The transaction completed successfully when - Event is NULL. - @retval EFI_ALREADY_STARTED The controller is busy with another transa= ction. - @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is = too - large. - @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the - transaction. - @retval EFI_INVALID_PARAMETER RequestPacket is NULL - @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress param= eter - @retval EFI_NO_RESPONSE The I2C device is not responding to the sl= ave - address. EFI_DEVICE_ERROR will be returne= d if - the controller cannot distinguish when the= NACK - occurred. - @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction - @retval EFI_UNSUPPORTED The controller does not support the reques= ted - transaction. - -**/ -STATIC -EFI_STATUS -EFIAPI -SynQuacerI2cStartRequest ( - IN CONST EFI_I2C_MASTER_PROTOCOL *This, - IN UINTN SlaveAddress, - IN EFI_I2C_REQUEST_PACKET *RequestPacket, - IN EFI_EVENT Event OPTIONAL, - OUT EFI_STATUS *I2cStatus OPTIONAL - ) -{ - SYNQUACER_I2C_MASTER *I2c; - UINTN Idx; - EFI_I2C_OPERATION *Op; - UINTN BufIdx; - EFI_STATUS Status; - EFI_TPL Tpl; - BOOLEAN AtRuntime; - UINT8 Bsr; - UINT8 Bcr; - - I2c =3D SYNQUACER_I2C_FROM_THIS (This); - - // - // We can only do synchronous operations at runtime - // - AtRuntime =3D EfiAtRuntime (); - if (AtRuntime && Event !=3D NULL) { - return EFI_UNSUPPORTED; - } - - if (!AtRuntime) { - Tpl =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); - } - - for (Idx =3D 0, Op =3D RequestPacket->Operation, Status =3D EFI_SUCCESS; - Idx < RequestPacket->OperationCount && !EFI_ERROR (Status); - Idx++, Op++) { - - Status =3D SynQuacerI2cMasterStart (I2c, SlaveAddress, Op); - if (EFI_ERROR (Status)) { - break; - } - - Status =3D WaitForInterrupt (I2c); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "%a: Timeout waiting for interrupt - %r\n", - __FUNCTION__, Status)); - break; - } - - if (MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR) & F_I2C_BSR_LRB) { - DEBUG ((DEBUG_WARN, "%a: No ack received\n", __FUNCTION__)); - Status =3D EFI_DEVICE_ERROR; - break; - } - - BufIdx =3D 0; - do { - Bsr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR); - Bcr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BCR); - - if (Bcr & F_I2C_BCR_BER) { - DEBUG ((DEBUG_WARN, "%a: Bus error detected\n", __FUNCTION__)); - Status =3D EFI_DEVICE_ERROR; - break; - } - - if ((Bsr & F_I2C_BSR_AL) || !(Bcr & F_I2C_BCR_MSS)) { - DEBUG ((DEBUG_WARN, "%a: Arbitration lost\n", __FUNCTION__)); - Status =3D EFI_DEVICE_ERROR; - break; - } - - if (Op->Flags & I2C_FLAG_READ) { - if (BufIdx =3D=3D Op->LengthInBytes - 1) { - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, - F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE); - } else { - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, - F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE | F_I2C_BCR_AC= K); - } - - Status =3D WaitForInterrupt (I2c); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, - "%a: Timeout waiting for interrupt - %r\n", __FUNCTION__, Stat= us)); - break; - } - - if (!(MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR) & F_I2C_BSR_FBT)) { - Op->Buffer [BufIdx++] =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_D= AR); - } - } else { - MmioWrite8 (I2c->MmioBase + F_I2C_REG_DAR, Op->Buffer [BufIdx++]); - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, - F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE); - - Status =3D WaitForInterrupt (I2c); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, - "%a: Timeout waiting for interrupt - %r\n", __FUNCTION__, Stat= us)); - break; - } - - if (MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR) & F_I2C_BSR_LRB) { - DEBUG ((DEBUG_WARN, "%a: No ack received\n", __FUNCTION__)); - Status =3D EFI_DEVICE_ERROR; - break; - } - } - } while (BufIdx < Op->LengthInBytes); - } - - // Force bus state to idle, terminating any ongoing transfer - MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, 0); - - if (!AtRuntime) { - gBS->RestoreTPL (Tpl); - } - - if (Event) { - *I2cStatus =3D Status; - gBS->SignalEvent (Event); - } - return Status; -} - -STATIC CONST EFI_I2C_CONTROLLER_CAPABILITIES mI2cControllerCapabilities = =3D { - sizeof (EFI_I2C_CONTROLLER_CAPABILITIES), // StructureSizeInBytes - MAX_UINT32, // MaximumReceiveBytes - MAX_UINT32, // MaximumTransmitBytes - MAX_UINT32, // MaximumTotalBytes -}; - -STATIC -VOID -EFIAPI -SynQuacerI2cVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - SYNQUACER_I2C_MASTER *I2c =3D Context; - - EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.SetBusFrequency); - EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.Reset); - EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.StartRequest); - EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.I2cControllerCapabiliti= es); - EfiConvertPointer (0x0, (VOID **)&I2c->MmioBase); -} - -EFI_STATUS -SynQuacerI2cInit ( - IN EFI_HANDLE DriverBindingHandle, - IN EFI_HANDLE ControllerHandle - ) -{ - EFI_STATUS Status; - NON_DISCOVERABLE_DEVICE *Dev; - SYNQUACER_I2C_MASTER *I2c; - BOOLEAN Runtime; - - Status =3D gBS->OpenProtocol (ControllerHandle, - &gEdkiiNonDiscoverableDeviceProtocolGuid, - (VOID **)&Dev, DriverBindingHandle, - ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVE= R); - if (EFI_ERROR (Status)) { - return Status; - } - - Runtime =3D CompareGuid (Dev->Type, - &gSynQuacerNonDiscoverableRuntimeI2cMasterGuid); - - // Allocate Resources - if (Runtime) { - I2c =3D AllocateRuntimeZeroPool (sizeof (SYNQUACER_I2C_MASTER)); - } else { - I2c =3D AllocateZeroPool (sizeof (SYNQUACER_I2C_MASTER)); - } - if (I2c =3D=3D NULL) { - Status =3D EFI_OUT_OF_RESOURCES; - goto CloseProtocol; - } - - I2c->Signature =3D SYNQUACER_I2C_SIGNATURE; - I2c->I2cMaster.SetBusFrequency =3D SynQuacerI2cSetBusFrequenc= y; - I2c->I2cMaster.Reset =3D SynQuacerI2cReset; - I2c->I2cMaster.StartRequest =3D SynQuacerI2cStartRequest; - I2c->I2cMaster.I2cControllerCapabilities =3D &mI2cControllerCapabilitie= s; - I2c->MmioBase =3D Dev->Resources[0].AddrRang= eMin; - I2c->Dev =3D Dev; - - if (Runtime) { - I2c->Runtime =3D TRUE; - - // Declare the controller as EFI_MEMORY_RUNTIME - Status =3D gDS->AddMemorySpace ( - EfiGcdMemoryTypeMemoryMappedIo, - Dev->Resources[0].AddrRangeMin, - Dev->Resources[0].AddrLen, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "%a: failed to add memory space - %r\n", - __FUNCTION__, Status)); - } - - Status =3D gDS->SetMemorySpaceAttributes ( - Dev->Resources[0].AddrRangeMin, - Dev->Resources[0].AddrLen, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); - if (EFI_ERROR (Status)) { - goto FreeDevice; - } - - // - // Register for the virtual address change event - // - Status =3D gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, - SynQuacerI2cVirtualNotifyEvent, I2c, - &gEfiEventVirtualAddressChangeGuid, - &I2c->VirtualAddressChangeEvent); - if (EFI_ERROR (Status)) { - goto FreeDevice; - } - } - - CopyGuid (&I2c->DevicePath.Vendor.Guid, &gEfiCallerIdGuid); - I2c->DevicePath.MmioBase =3D I2c->MmioBase; - SetDevicePathNodeLength (&I2c->DevicePath.Vendor, - sizeof (I2c->DevicePath) - sizeof (I2c->DevicePath.End)); - SetDevicePathEndNode (&I2c->DevicePath.End); - - Status =3D gBS->InstallMultipleProtocolInterfaces (&ControllerHandle, - &gEfiI2cMasterProtocolGuid, &I2c->I2cMaster, - &gEfiDevicePathProtocolGuid, &I2c->DevicePath, - NULL); - if (EFI_ERROR (Status)) { - goto CloseEvent; - } - return EFI_SUCCESS; - -CloseEvent: - if (Runtime) { - gBS->CloseEvent (I2c->VirtualAddressChangeEvent); - } - -FreeDevice: - FreePool (I2c); - -CloseProtocol: - gBS->CloseProtocol (ControllerHandle, - &gEdkiiNonDiscoverableDeviceProtocolGuid, - DriverBindingHandle, - ControllerHandle); - return Status; -} - -EFI_STATUS -SynQuacerI2cRelease ( - IN EFI_HANDLE DriverBindingHandle, - IN EFI_HANDLE ControllerHandle - ) -{ - EFI_I2C_MASTER_PROTOCOL *I2cMaster; - SYNQUACER_I2C_MASTER *I2c; - EFI_STATUS Status; - - Status =3D gBS->HandleProtocol (ControllerHandle, - &gEfiI2cMasterProtocolGuid, - (VOID **)&I2cMaster); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return Status; - } - - I2c =3D SYNQUACER_I2C_FROM_THIS (I2cMaster); - - Status =3D gBS->UninstallMultipleProtocolInterfaces (ControllerHandle, - &gEfiI2cMasterProtocolGuid, I2cMaster, - &gEfiDevicePathProtocolGuid, &I2c->DevicePath, - NULL); - if (EFI_ERROR (Status)) { - return Status; - } - - if (I2c->Runtime) { - gBS->CloseEvent (I2c->VirtualAddressChangeEvent); - } - - Status =3D gBS->CloseProtocol (ControllerHandle, - &gEdkiiNonDiscoverableDeviceProtocolGuid, - DriverBindingHandle, - ControllerHandle); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return Status; - } - - gBS->FreePool (I2c); - - return EFI_SUCCESS; -} +/** @file + + Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SynQuacerI2cDxe.h" + +// +// We cannot use Stall () or timer events at runtime, so we need to busy-w= ait +// for the controller to signal the completion interrupts. This value was +// arbitrarily chosen, and does not appear to produce any premature timeou= ts +// nor does it result in noticeable stalls in case of bus errors. +// +#define WAIT_FOR_INTERRUPT_TIMEOUT 50000 + +/** + Set the frequency for the I2C clock line. + + This routine must be called at or below TPL_NOTIFY. + + The software and controller do a best case effort of using the specified + frequency for the I2C bus. If the frequency does not match exactly then + the I2C master protocol selects the next lower frequency to avoid + exceeding the operating conditions for any of the I2C devices on the bus. + For example if 400 KHz was specified and the controller's divide network + only supports 402 KHz or 398 KHz then the I2C master protocol selects 398 + KHz. If there are not lower frequencies available, then return + EFI_UNSUPPORTED. + + @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structure + @param[in] BusClockHertz Pointer to the requested I2C bus clock frequen= cy + in Hertz. Upon return this value contains the + actual frequency in use by the I2C controller. + + @retval EFI_SUCCESS The bus frequency was set successfully. + @retval EFI_ALREADY_STARTED The controller is busy with another transa= ction. + @retval EFI_INVALID_PARAMETER BusClockHertz is NULL + @retval EFI_UNSUPPORTED The controller does not support this frequ= ency. + +**/ +STATIC +EFI_STATUS +EFIAPI +SynQuacerI2cSetBusFrequency ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This, + IN OUT UINTN *BusClockHertz + ) +{ + SYNQUACER_I2C_MASTER *I2c; + UINT8 Ccr, Csr; + + I2c =3D SYNQUACER_I2C_FROM_THIS (This); + + if (BusClockHertz =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + if (*BusClockHertz >=3D F_I2C_SPEED_FM) { + if (REFCLK_RATE <=3D F_I2C_CLK_RATE_18M) { + Ccr =3D F_I2C_CCR_CS_FAST_MAX_18M (REFCLK_RATE); + Csr =3D F_I2C_CSR_CS_FAST_MAX_18M (REFCLK_RATE); + } else { + Ccr =3D F_I2C_CCR_CS_FAST_MIN_18M (REFCLK_RATE); + Csr =3D F_I2C_CSR_CS_FAST_MIN_18M (REFCLK_RATE); + } + + // Set Clock and enable, Set fast mode + MmioWrite8 (I2c->MmioBase + F_I2C_REG_CCR, + Ccr | F_I2C_CCR_FM | F_I2C_CCR_EN); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_CSR, Csr); + + *BusClockHertz =3D F_I2C_SPEED_FM; + + } else if (*BusClockHertz >=3D F_I2C_SPEED_SM) { + if (REFCLK_RATE <=3D F_I2C_CLK_RATE_18M) { + Ccr =3D F_I2C_CCR_CS_STANDARD_MAX_18M (REFCLK_RATE); + Csr =3D F_I2C_CSR_CS_STANDARD_MAX_18M (REFCLK_RATE); + } else { + Ccr =3D F_I2C_CCR_CS_STANDARD_MIN_18M (REFCLK_RATE); + Csr =3D F_I2C_CSR_CS_STANDARD_MIN_18M (REFCLK_RATE); + } + + // Set Clock and enable, Set standard mode + MmioWrite8 (I2c->MmioBase + F_I2C_REG_CCR, Ccr | F_I2C_CCR_EN); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_CSR, Csr); + + *BusClockHertz =3D F_I2C_SPEED_SM; + } else { + return EFI_UNSUPPORTED; + } + + MemoryFence (); + + return EFI_SUCCESS; +} + +/** + Reset the I2C controller and configure it for use + + This routine must be called at or below TPL_NOTIFY. + + The I2C controller is reset. The caller must call SetBusFrequench() aft= er + calling Reset(). + + @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structur= e. + + @retval EFI_SUCCESS The reset completed successfully. + @retval EFI_ALREADY_STARTED The controller is busy with another transact= ion. + @retval EFI_DEVICE_ERROR The reset operation failed. + +**/ +STATIC +EFI_STATUS +EFIAPI +SynQuacerI2cReset ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This + ) +{ + SYNQUACER_I2C_MASTER *I2c; + + I2c =3D SYNQUACER_I2C_FROM_THIS (This); + + // Disable the clock + MmioWrite8 (I2c->MmioBase + F_I2C_REG_CCR, 0); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_CSR, 0); + + MemoryFence (); + + // Set own Address + MmioWrite8 (I2c->MmioBase + F_I2C_REG_ADR, 0); + + // Set PCLK frequency + MmioWrite8 (I2c->MmioBase + F_I2C_REG_FSR, F_I2C_BUS_CLK_FR (REFCLK_RATE= )); + + // clear IRQ (INT=3D0, BER=3D0), Interrupt Disable + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, 0); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BC2R, 0); + + MemoryFence (); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SynQuacerI2cMasterStart ( + IN SYNQUACER_I2C_MASTER *I2c, + IN UINTN SlaveAddress, + IN EFI_I2C_OPERATION *Op + ) +{ + UINT8 Bsr; + UINT8 Bcr; + + if (Op->Flags & I2C_FLAG_READ) { + MmioWrite8 (I2c->MmioBase + F_I2C_REG_DAR, (SlaveAddress << 1) | 1); + } else { + MmioWrite8 (I2c->MmioBase + F_I2C_REG_DAR, SlaveAddress << 1); + } + + DEBUG ((DEBUG_INFO, "%a: slave:0x%02x\n", __FUNCTION__, + SlaveAddress)); + + Bsr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR); + Bcr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BCR); + + if ((Bsr & F_I2C_BSR_BB) && !(Bcr & F_I2C_BCR_MSS)) { + DEBUG ((DEBUG_INFO, "%a: bus is busy\n", __FUNCTION__)); + return EFI_ALREADY_STARTED; + } + + if (Bsr & F_I2C_BSR_BB) { // Bus is busy + DEBUG ((DEBUG_INFO, "%a: Continuous Start\n", __FUNCTION__)); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, Bcr | F_I2C_BCR_SCC); + } else { + if (Bcr & F_I2C_BCR_MSS) { + DEBUG ((DEBUG_WARN, + "%a: is not in master mode\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + DEBUG ((DEBUG_INFO, "%a: Start Condition\n", __FUNCTION__)); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, + Bcr | F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE); + } + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +WaitForInterrupt ( + IN SYNQUACER_I2C_MASTER *I2c + ) +{ + UINT8 Bsr; + UINTN Timeout =3D WAIT_FOR_INTERRUPT_TIMEOUT; + + do { + MemoryFence (); + + Bsr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BCR); + if (Bsr & F_I2C_BCR_INT) { + return EFI_SUCCESS; + } + } while (Timeout--); + + return EFI_DEVICE_ERROR; +} + +/** + Start an I2C transaction on the host controller. + + This routine must be called at or below TPL_NOTIFY. For synchronous + requests this routine must be called at or below TPL_CALLBACK. + + This function initiates an I2C transaction on the controller. To + enable proper error handling by the I2C protocol stack, the I2C + master protocol does not support queuing but instead only manages + one I2C transaction at a time. This API requires that the I2C bus + is in the correct configuration for the I2C transaction. + + The transaction is performed by sending a start-bit and selecting the + I2C device with the specified I2C slave address and then performing + the specified I2C operations. When multiple operations are requested + they are separated with a repeated start bit and the slave address. + The transaction is terminated with a stop bit. + + When Event is NULL, StartRequest operates synchronously and returns + the I2C completion status as its return value. + + When Event is not NULL, StartRequest synchronously returns EFI_SUCCESS + indicating that the I2C transaction was started asynchronously. The + transaction status value is returned in the buffer pointed to by + I2cStatus upon the completion of the I2C transaction when I2cStatus + is not NULL. After the transaction status is returned the Event is + signaled. + + Note: The typical consumer of this API is the I2C host protocol. + Extreme care must be taken by other consumers of this API to prevent + confusing the third party I2C drivers due to a state change at the + I2C device which the third party I2C drivers did not initiate. I2C + platform specific code may use this API within these guidelines. + + @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structur= e. + @param[in] SlaveAddress Address of the device on the I2C bus. Set the + I2C_ADDRESSING_10_BIT when using 10-bit addres= ses, + clear this bit for 7-bit addressing. Bits 0-6 + are used for 7-bit I2C slave addresses and bits + 0-9 are used for 10-bit I2C slave addresses. + @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET + structure describing the I2C transaction. + @param[in] Event Event to signal for asynchronous transactions, + NULL for synchronous transactions + @param[out] I2cStatus Optional buffer to receive the I2C transaction + completion status + + @retval EFI_SUCCESS The asynchronous transaction was successfu= lly + started when Event is not NULL. + @retval EFI_SUCCESS The transaction completed successfully when + Event is NULL. + @retval EFI_ALREADY_STARTED The controller is busy with another transa= ction. + @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is = too + large. + @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the + transaction. + @retval EFI_INVALID_PARAMETER RequestPacket is NULL + @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress param= eter + @retval EFI_NO_RESPONSE The I2C device is not responding to the sl= ave + address. EFI_DEVICE_ERROR will be returne= d if + the controller cannot distinguish when the= NACK + occurred. + @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction + @retval EFI_UNSUPPORTED The controller does not support the reques= ted + transaction. + +**/ +STATIC +EFI_STATUS +EFIAPI +SynQuacerI2cStartRequest ( + IN CONST EFI_I2C_MASTER_PROTOCOL *This, + IN UINTN SlaveAddress, + IN EFI_I2C_REQUEST_PACKET *RequestPacket, + IN EFI_EVENT Event OPTIONAL, + OUT EFI_STATUS *I2cStatus OPTIONAL + ) +{ + SYNQUACER_I2C_MASTER *I2c; + UINTN Idx; + EFI_I2C_OPERATION *Op; + UINTN BufIdx; + EFI_STATUS Status; + EFI_TPL Tpl; + BOOLEAN AtRuntime; + UINT8 Bsr; + UINT8 Bcr; + + I2c =3D SYNQUACER_I2C_FROM_THIS (This); + + // + // We can only do synchronous operations at runtime + // + AtRuntime =3D EfiAtRuntime (); + if (AtRuntime && Event !=3D NULL) { + return EFI_UNSUPPORTED; + } + + if (!AtRuntime) { + Tpl =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); + } + + for (Idx =3D 0, Op =3D RequestPacket->Operation, Status =3D EFI_SUCCESS; + Idx < RequestPacket->OperationCount && !EFI_ERROR (Status); + Idx++, Op++) { + + Status =3D SynQuacerI2cMasterStart (I2c, SlaveAddress, Op); + if (EFI_ERROR (Status)) { + break; + } + + Status =3D WaitForInterrupt (I2c); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "%a: Timeout waiting for interrupt - %r\n", + __FUNCTION__, Status)); + break; + } + + if (MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR) & F_I2C_BSR_LRB) { + DEBUG ((DEBUG_WARN, "%a: No ack received\n", __FUNCTION__)); + Status =3D EFI_DEVICE_ERROR; + break; + } + + BufIdx =3D 0; + do { + Bsr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR); + Bcr =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_BCR); + + if (Bcr & F_I2C_BCR_BER) { + DEBUG ((DEBUG_WARN, "%a: Bus error detected\n", __FUNCTION__)); + Status =3D EFI_DEVICE_ERROR; + break; + } + + if ((Bsr & F_I2C_BSR_AL) || !(Bcr & F_I2C_BCR_MSS)) { + DEBUG ((DEBUG_WARN, "%a: Arbitration lost\n", __FUNCTION__)); + Status =3D EFI_DEVICE_ERROR; + break; + } + + if (Op->Flags & I2C_FLAG_READ) { + if (BufIdx =3D=3D Op->LengthInBytes - 1) { + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, + F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE); + } else { + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, + F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE | F_I2C_BCR_AC= K); + } + + Status =3D WaitForInterrupt (I2c); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: Timeout waiting for interrupt - %r\n", __FUNCTION__, Stat= us)); + break; + } + + if (!(MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR) & F_I2C_BSR_FBT)) { + Op->Buffer [BufIdx++] =3D MmioRead8 (I2c->MmioBase + F_I2C_REG_D= AR); + } + } else { + MmioWrite8 (I2c->MmioBase + F_I2C_REG_DAR, Op->Buffer [BufIdx++]); + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, + F_I2C_BCR_MSS | F_I2C_BCR_INTE | F_I2C_BCR_BEIE); + + Status =3D WaitForInterrupt (I2c); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, + "%a: Timeout waiting for interrupt - %r\n", __FUNCTION__, Stat= us)); + break; + } + + if (MmioRead8 (I2c->MmioBase + F_I2C_REG_BSR) & F_I2C_BSR_LRB) { + DEBUG ((DEBUG_WARN, "%a: No ack received\n", __FUNCTION__)); + Status =3D EFI_DEVICE_ERROR; + break; + } + } + } while (BufIdx < Op->LengthInBytes); + } + + // Force bus state to idle, terminating any ongoing transfer + MmioWrite8 (I2c->MmioBase + F_I2C_REG_BCR, 0); + + if (!AtRuntime) { + gBS->RestoreTPL (Tpl); + } + + if (Event) { + *I2cStatus =3D Status; + gBS->SignalEvent (Event); + } + return Status; +} + +STATIC CONST EFI_I2C_CONTROLLER_CAPABILITIES mI2cControllerCapabilities = =3D { + sizeof (EFI_I2C_CONTROLLER_CAPABILITIES), // StructureSizeInBytes + MAX_UINT32, // MaximumReceiveBytes + MAX_UINT32, // MaximumTransmitBytes + MAX_UINT32, // MaximumTotalBytes +}; + +STATIC +VOID +EFIAPI +SynQuacerI2cVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + SYNQUACER_I2C_MASTER *I2c =3D Context; + + EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.SetBusFrequency); + EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.Reset); + EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.StartRequest); + EfiConvertPointer (0x0, (VOID **)&I2c->I2cMaster.I2cControllerCapabiliti= es); + EfiConvertPointer (0x0, (VOID **)&I2c->MmioBase); +} + +EFI_STATUS +SynQuacerI2cInit ( + IN EFI_HANDLE DriverBindingHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + EFI_STATUS Status; + NON_DISCOVERABLE_DEVICE *Dev; + SYNQUACER_I2C_MASTER *I2c; + BOOLEAN Runtime; + + Status =3D gBS->OpenProtocol (ControllerHandle, + &gEdkiiNonDiscoverableDeviceProtocolGuid, + (VOID **)&Dev, DriverBindingHandle, + ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVE= R); + if (EFI_ERROR (Status)) { + return Status; + } + + Runtime =3D CompareGuid (Dev->Type, + &gSynQuacerNonDiscoverableRuntimeI2cMasterGuid); + + // Allocate Resources + if (Runtime) { + I2c =3D AllocateRuntimeZeroPool (sizeof (SYNQUACER_I2C_MASTER)); + } else { + I2c =3D AllocateZeroPool (sizeof (SYNQUACER_I2C_MASTER)); + } + if (I2c =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto CloseProtocol; + } + + I2c->Signature =3D SYNQUACER_I2C_SIGNATURE; + I2c->I2cMaster.SetBusFrequency =3D SynQuacerI2cSetBusFrequenc= y; + I2c->I2cMaster.Reset =3D SynQuacerI2cReset; + I2c->I2cMaster.StartRequest =3D SynQuacerI2cStartRequest; + I2c->I2cMaster.I2cControllerCapabilities =3D &mI2cControllerCapabilitie= s; + I2c->MmioBase =3D Dev->Resources[0].AddrRang= eMin; + I2c->Dev =3D Dev; + + if (Runtime) { + I2c->Runtime =3D TRUE; + + // Declare the controller as EFI_MEMORY_RUNTIME + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Dev->Resources[0].AddrRangeMin, + Dev->Resources[0].AddrLen, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "%a: failed to add memory space - %r\n", + __FUNCTION__, Status)); + } + + Status =3D gDS->SetMemorySpaceAttributes ( + Dev->Resources[0].AddrRangeMin, + Dev->Resources[0].AddrLen, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); + if (EFI_ERROR (Status)) { + goto FreeDevice; + } + + // + // Register for the virtual address change event + // + Status =3D gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, + SynQuacerI2cVirtualNotifyEvent, I2c, + &gEfiEventVirtualAddressChangeGuid, + &I2c->VirtualAddressChangeEvent); + if (EFI_ERROR (Status)) { + goto FreeDevice; + } + } + + CopyGuid (&I2c->DevicePath.Vendor.Guid, &gEfiCallerIdGuid); + I2c->DevicePath.MmioBase =3D I2c->MmioBase; + SetDevicePathNodeLength (&I2c->DevicePath.Vendor, + sizeof (I2c->DevicePath) - sizeof (I2c->DevicePath.End)); + SetDevicePathEndNode (&I2c->DevicePath.End); + + Status =3D gBS->InstallMultipleProtocolInterfaces (&ControllerHandle, + &gEfiI2cMasterProtocolGuid, &I2c->I2cMaster, + &gEfiDevicePathProtocolGuid, &I2c->DevicePath, + NULL); + if (EFI_ERROR (Status)) { + goto CloseEvent; + } + return EFI_SUCCESS; + +CloseEvent: + if (Runtime) { + gBS->CloseEvent (I2c->VirtualAddressChangeEvent); + } + +FreeDevice: + FreePool (I2c); + +CloseProtocol: + gBS->CloseProtocol (ControllerHandle, + &gEdkiiNonDiscoverableDeviceProtocolGuid, + DriverBindingHandle, + ControllerHandle); + return Status; +} + +EFI_STATUS +SynQuacerI2cRelease ( + IN EFI_HANDLE DriverBindingHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + EFI_I2C_MASTER_PROTOCOL *I2cMaster; + SYNQUACER_I2C_MASTER *I2c; + EFI_STATUS Status; + + Status =3D gBS->HandleProtocol (ControllerHandle, + &gEfiI2cMasterProtocolGuid, + (VOID **)&I2cMaster); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + I2c =3D SYNQUACER_I2C_FROM_THIS (I2cMaster); + + Status =3D gBS->UninstallMultipleProtocolInterfaces (ControllerHandle, + &gEfiI2cMasterProtocolGuid, I2cMaster, + &gEfiDevicePathProtocolGuid, &I2c->DevicePath, + NULL); + if (EFI_ERROR (Status)) { + return Status; + } + + if (I2c->Runtime) { + gBS->CloseEvent (I2c->VirtualAddressChangeEvent); + } + + Status =3D gBS->CloseProtocol (ControllerHandle, + &gEdkiiNonDiscoverableDeviceProtocolGuid, + DriverBindingHandle, + ControllerHandle); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->FreePool (I2c); + + return EFI_SUCCESS; +} --=20 2.30.2 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#83643): https://edk2.groups.io/g/devel/message/83643 Mute This Topic: https://groups.io/mt/86979609/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-