123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- /** @file
- I2C Debug Port Protocol Implementation
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Base.h>
- #include <Library/BaseLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/PcdLib.h>
- #include <Library/TimerLib.h>
- #include <IgfxI2c.h>
- #include <Gmbus.h>
- #include <I2cDebugPortProtocol.h>
- /**
- Writes data to the I2C debug port
- @param[in] Buffer - The data to be written to the I2C debug port.
- @param[in] Count - The number of bytes to write to the I2C debug port.
- @retval EFI_SUCCESS - The data was successfully written.
- @retval EFI_INVALID_PARAMETER - One of the following conditions:
- * ByteCount is 0
- * Buffer is NULL
- @retval EFI_TIMEOUT - The I2C controller did not respond within the required timeout period.
- @retval EFI_DEVICE_ERROR - An error occurred while accessing the I2C controller.
- **/
- EFI_STATUS
- I2cDebugPortWrite (
- IN UINT8 *Buffer,
- IN UINT32 Count
- )
- {
- UINT8 WriteBuffer[I2C_DEBUG_PORT_MAX_DATA_SIZE + 1];
- EFI_STATUS Status;
- UINT32 Index;
- UINT32 ImplementationDelayUs;
- UINT8 CurrentSize;
- UINT8 DdcBusPinPair;
- if (Count <= 0) {
- return EFI_INVALID_PARAMETER;
- }
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Status = GetGmbusBusPinPairForI2cDebugPort (&DdcBusPinPair);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- ImplementationDelayUs = FixedPcdGet32 (PcdI2cHdmiDebugPortPacketStallUs); //BP: 3ms stall to catch up
- RaiseTplForI2cDebugPortAccess ();
- for (Index = 0; Index < Count; Index += I2C_DEBUG_PORT_MAX_DATA_SIZE) {
- MicroSecondDelay (ImplementationDelayUs);
- if ((Index + I2C_DEBUG_PORT_MAX_DATA_SIZE) >= Count) {
- CurrentSize = (UINT8) (Count - Index);
- } else {
- CurrentSize = I2C_DEBUG_PORT_MAX_DATA_SIZE;
- }
- WriteBuffer[0] = (I2C_DEBUG_PORT_WRITE_COMMAND << I2C_DEBUG_PORT_COMMAND_BIT_POSITION) |
- (CurrentSize & I2C_DEBUG_PORT_DATA_SIZE_BIT_MASK);
- CopyMem (&(WriteBuffer[1]), &(Buffer[Index]), CurrentSize);
- Status = GmbusWrite (DdcBusPinPair, I2C_DEBUG_PORT_WRITE_DEVICE_ADDRESS, TRUE, CurrentSize + 1, &(WriteBuffer[0]));
- if (EFI_ERROR (Status)) {
- break;
- }
- }
- RestoreTplAfterI2cDebugPortAccess ();
- return Status;
- }
- /**
- Reads data from the I2C debug port
- @param[out] Buffer - The memory buffer to return the read data.
- @param[in, out] Count - The number of bytes to read from the I2C debug port.
- On output, the number of bytes actually read.
- @retval EFI_SUCCESS - The data was successfully read.
- @retval EFI_INVALID_PARAMETER - One of the following conditions:
- * ByteCount is 0
- * Buffer is NULL
- @retval EFI_TIMEOUT - The I2C controller did not respond within the required timeout period.
- @retval EFI_DEVICE_ERROR - An error occurred while accessing the I2C controller.
- **/
- EFI_STATUS
- I2cDebugPortRead (
- OUT UINT8 *Buffer,
- IN OUT UINT32 *Count
- )
- {
- EFI_STATUS Status;
- UINT32 Index;
- UINT32 BytesRead;
- UINT32 ImplementationDelayUs;
- UINT32 CurrentSize;
- UINT8 DdcBusPinPair;
- UINT8 GmbusIndexData;
- BytesRead = 0;
- if ((*Count) <= 0) {
- return EFI_INVALID_PARAMETER;
- }
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Status = GetGmbusBusPinPairForI2cDebugPort (&DdcBusPinPair);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- ImplementationDelayUs = FixedPcdGet32 (PcdI2cHdmiDebugPortPacketStallUs); //BP: 3ms stall to catch up
- RaiseTplForI2cDebugPortAccess ();
- for (Index = 0; Index < (*Count); Index += I2C_DEBUG_PORT_MAX_DATA_SIZE) {
- MicroSecondDelay (ImplementationDelayUs);
- if ((Index + I2C_DEBUG_PORT_MAX_DATA_SIZE) >= (*Count)) {
- CurrentSize = (*Count) - Index;
- } else {
- CurrentSize = I2C_DEBUG_PORT_MAX_DATA_SIZE;
- }
- GmbusIndexData = (I2C_DEBUG_PORT_READ_COMMAND << I2C_DEBUG_PORT_COMMAND_BIT_POSITION) |
- (CurrentSize & I2C_DEBUG_PORT_DATA_SIZE_BIT_MASK);
- Status = GmbusRead (
- DdcBusPinPair,
- I2C_DEBUG_PORT_READ_DEVICE_ADDRESS,
- TRUE,
- TRUE,
- GmbusIndexData,
- &CurrentSize,
- &(Buffer[Index])
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- BytesRead += CurrentSize;
- if (((Index + I2C_DEBUG_PORT_MAX_DATA_SIZE) < (*Count)) && (CurrentSize < I2C_DEBUG_PORT_MAX_DATA_SIZE)) {
- break;
- }
- }
- RestoreTplAfterI2cDebugPortAccess ();
- (*Count) = BytesRead;
- return Status;
- }
- /**
- Queries the I2C debug port to see if there are any data waiting to be read
- @param[out] NumberOfBytesInFifoBuffer - The number of bytes sitting in the I2C debug port's
- FIFO buffer waiting to be read
- @retval EFI_SUCCESS - The I2C debug port was successfully queried
- @retval EFI_INVALID_PARAMETER - One of the following conditions:
- * NumberOfBytesInFifoBuffer is NULL
- @retval EFI_TIMEOUT - The I2C controller did not respond within the required timeout period.
- @retval EFI_DEVICE_ERROR - An error occurred while accessing the I2C controller.
- **/
- EFI_STATUS
- I2cDebugPortReadyToRead (
- OUT UINT8 *NumberOfBytesInFifoBuffer
- )
- {
- EFI_STATUS Status;
- UINT32 BytesRead;
- UINT8 DdcBusPinPair;
- UINT32 ImplementationDelayUs;
- UINT8 GmbusIndexData;
- BytesRead = 1;
- if (NumberOfBytesInFifoBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- Status = GetGmbusBusPinPairForI2cDebugPort (&DdcBusPinPair);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- ImplementationDelayUs = FixedPcdGet32 (PcdI2cHdmiDebugPortPacketStallUs); //BP: 3ms stall to catch up
- MicroSecondDelay (ImplementationDelayUs);
- GmbusIndexData = (I2C_DEBUG_PORT_READY_TO_READ_COMMAND << I2C_DEBUG_PORT_COMMAND_BIT_POSITION) |
- (1 & I2C_DEBUG_PORT_DATA_SIZE_BIT_MASK); //READY_TO_READ always returns 1 byte
- RaiseTplForI2cDebugPortAccess ();
- Status = GmbusRead (DdcBusPinPair, I2C_DEBUG_PORT_READ_DEVICE_ADDRESS, TRUE, TRUE, GmbusIndexData, &BytesRead, NumberOfBytesInFifoBuffer);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- RestoreTplAfterI2cDebugPortAccess ();
- if (BytesRead != 1) {
- Status = EFI_DEVICE_ERROR;
- }
- return Status;
- }
|