Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions Silicon/NVIDIA/Drivers/EepromDxe/Eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
#include <Library/PlatformResourceLib.h>
#include <Library/PrintLib.h>
#include <Library/Crc8Lib.h>
#include <libfdt.h>

#include <Protocol/DriverBinding.h>
#include <Protocol/I2cIo.h>
#include <Protocol/Eeprom.h>
#include <Protocol/Rng.h>
#include <Protocol/KernelCmdLineUpdate.h>
#include <Protocol/TegraI2cSlaveDeviceTreeNode.h>

#define SERIAL_NUM_CMD_MAX_LEN 64
#define EEPROM_DATA_SIZE 256
Expand Down Expand Up @@ -315,6 +317,11 @@ EepromDxeDriverBindingStart (
TEGRA_EEPROM_BOARD_INFO *CvmBoardInfo;
TEGRA_EEPROM_BOARD_INFO *IdBoardInfo;
BOOLEAN SkipEepromCRC;
INT32 DeviceTreePathLen;

NVIDIA_TEGRA_I2C_SLAVE_DEVICE_TREE_NODE_PROTOCOL *I2cSlaveDeviceTreeNode = NULL;
NVIDIA_DEVICE_TREE_NODE_PROTOCOL EepromDeviceTreeNode;


RawData = NULL;
CvmBoardInfo = NULL;
Expand All @@ -338,6 +345,36 @@ EepromDxeDriverBindingStart (
goto ErrorExit;
}

EFI_HANDLE Handle[10]; // Usually only 8 Tegra I2C buses to choose from
UINTN HandleSize = sizeof(Handle);
Status = gBS->LocateHandle(ByProtocol, &gNVIDIAI2cSlaveDeviceTreeNodeProtocolGuid, NULL, &HandleSize, &Handle[0]);

if ((EFI_ERROR (Status))) {
DEBUG ((DEBUG_ERROR, "%a: Unable to LocateHandle for I2cSlaveDeviceTreeNode Protocol (Status: %d)\n", __FUNCTION__, Status));
return Status;
}


INT32 NumHandles = HandleSize/sizeof(Handle[0]);
for (INT32 i = 0; i < NumHandles; i++) {
Status = gBS->HandleProtocol (Handle[i], &gNVIDIAI2cSlaveDeviceTreeNodeProtocolGuid, (VOID **)&I2cSlaveDeviceTreeNode);
if ((EFI_ERROR (Status))) {
DEBUG ((DEBUG_ERROR, "%a: Unable to HandleProtocol for index %d I2cSlaveDeviceTreeNode Protocol (Status: %d)\n", __FUNCTION__, i, Status));
return Status;
}

Status = I2cSlaveDeviceTreeNode->LookupNode(I2cSlaveDeviceTreeNode, I2cIo->DeviceGuid, I2cIo->DeviceIndex, &EepromDeviceTreeNode);
if (!(EFI_ERROR (Status))) {
// found
break;
}
}

if ((EFI_ERROR (Status))) {
DEBUG ((DEBUG_ERROR, "%a: Unable to LookupNode using any of the %d I2cSlaveDeviceTreeNode Protocols (device index %x, Status: %d)\n", __FUNCTION__, NumHandles, I2cIo->DeviceIndex, Status));
return Status;
}

// Allocate EEPROM Data
RawData = (UINT8 *)AllocateZeroPool (EEPROM_DATA_SIZE);
if (RawData == NULL) {
Expand Down Expand Up @@ -366,8 +403,8 @@ EepromDxeDriverBindingStart (

FreePool (Request);
Request = NULL;

if (0 == AsciiStrnCmp (
if (fdt_get_property(EepromDeviceTreeNode.DeviceTreeBase, EepromDeviceTreeNode.NodeOffset, "uefi-skip-crc", NULL) != NULL ||
0 == AsciiStrnCmp (
(CHAR8 *)&RawData[CAMERA_EEPROM_PART_OFFSET],
CAMERA_EEPROM_PART_NAME,
AsciiStrLen (CAMERA_EEPROM_PART_NAME)
Expand All @@ -388,6 +425,14 @@ EepromDxeDriverBindingStart (
goto ErrorExit;
}

DeviceTreePathLen = fdt_get_path(EepromDeviceTreeNode.DeviceTreeBase, EepromDeviceTreeNode.NodeOffset, IdBoardInfo->EepromDeviceTreePath, MAX_I2C_DEVICE_DT_PATH);

if (DeviceTreePathLen != 0) {
DEBUG((DEBUG_ERROR, "%a: Failed to get device tree path length for I2c sub-device 0x%lx on I2c Bus 0x%lx (error: %d).\n", __FUNCTION__, I2cIo->DeviceIndex >> 16, I2cIo->DeviceIndex & 0xFFFF, DeviceTreePathLen));
} else {
DEBUG ((DEBUG_INFO, "%a: Starting (TEGRA_PLATFORM_SILICON) Bus %x Device %x %a\r\n", __FUNCTION__, I2cIo->DeviceIndex >> 16, I2cIo->DeviceIndex & 0xFFFF, IdBoardInfo->EepromDeviceTreePath));
}

Status = PopulateEepromData (RawData, IdBoardInfo);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Eeprom data population failed(%r)\r\n", Status));
Expand Down
2 changes: 2 additions & 0 deletions Silicon/NVIDIA/Drivers/EepromDxe/Eeprom.inf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
PlatformResourceLib
Crc8Lib
PrintLib
FdtLib

[Pcd]
gNVIDIATokenSpaceGuid.PcdBootAndroidImage
Expand All @@ -53,6 +54,7 @@
gNVIDIACvmEepromProtocolGuid ## SOMETIMES_PRODUCES
gNVIDIACvbEepromProtocolGuid ## SOMETIMES_PRODUCES
gNVIDIAEepromProtocolGuid ## SOMETIMES_PRODUCES
gNVIDIAI2cSlaveDeviceTreeNodeProtocolGuid ## CONSUMES

[Depex]
TRUE
31 changes: 28 additions & 3 deletions Silicon/NVIDIA/Drivers/TegraI2c/TegraI2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@
#define MAX_I2C_DEVICES 16
#define MAX_SLAVES_PER_DEVICE 1

enum MuxType {
MUX = 0,
SWITCH = 1,
GPIO_CONTROLLED = 2, // Not supported yet, but will leave it here as bait
};

typedef struct {
enum MuxType MuxType :8;
UINT8 MuxAddress :8; // Only 7 bit addressing supported for now
UINT8 EnableBitNumber :8; // either 0, 2 or 3
UINT8 Channel :8; // 0-7
} BUS_CONFIGURATION_FIELDS;

// This approach of encoding all mux configuration into a UINT32 isn't strictly compliant with the UEFI spec,
// which suggests that configurations should be sequential indices rather than packed data
typedef union {
BUS_CONFIGURATION_FIELDS Fields;
UINT32 Value;
} NVIDIA_TEGRA_I2C_BUS_CONFIGURATION;


typedef struct {
//
// Standard signature used to identify TegraI2c private data
Expand All @@ -37,6 +58,8 @@ typedef struct {
EFI_I2C_ENUMERATE_PROTOCOL I2cEnumerate;
EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL I2CConfiguration;

NVIDIA_TEGRA_I2C_SLAVE_DEVICE_TREE_NODE_PROTOCOL I2cSlaveDeviceTreeNode;

//
// Indicates if the protocols are installed
//
Expand All @@ -55,7 +78,6 @@ typedef struct {
UINT32 ControllerId;
UINTN BusClockHertz;

UINT32 BusId;
VOID *DeviceTreeBase;
INT32 DeviceTreeNodeOffset;

Expand All @@ -64,15 +86,18 @@ typedef struct {
//
EFI_I2C_DEVICE I2cDevices[MAX_I2C_DEVICES];
UINT32 SlaveAddressArray[MAX_I2C_DEVICES*MAX_SLAVES_PER_DEVICE];
UINT32 SlaveDeviceTreeNodeOffsets[MAX_I2C_DEVICES];
UINTN NumberOfI2cDevices;

UINT32 PinControlId;
BOOLEAN PinControlConfigured;
BOOLEAN SkipOnExitDisabled;
} NVIDIA_TEGRA_I2C_PRIVATE_DATA;

#define TEGRA_I2C_PRIVATE_DATA_FROM_MASTER(a) CR(a, NVIDIA_TEGRA_I2C_PRIVATE_DATA, I2cMaster, TEGRA_I2C_SIGNATURE)
#define TEGRA_I2C_PRIVATE_DATA_FROM_ENUMERATE(a) CR(a, NVIDIA_TEGRA_I2C_PRIVATE_DATA, I2cEnumerate, TEGRA_I2C_SIGNATURE)
#define TEGRA_I2C_PRIVATE_DATA_FROM_MASTER(a) CR(a, NVIDIA_TEGRA_I2C_PRIVATE_DATA, I2cMaster, TEGRA_I2C_SIGNATURE)
#define TEGRA_I2C_PRIVATE_DATA_FROM_ENUMERATE(a) CR(a, NVIDIA_TEGRA_I2C_PRIVATE_DATA, I2cEnumerate, TEGRA_I2C_SIGNATURE)
#define TEGRA_I2C_PRIVATE_DATA_FROM_BUS_CONFIGURATION(a) CR(a, NVIDIA_TEGRA_I2C_PRIVATE_DATA, I2CConfiguration, TEGRA_I2C_SIGNATURE)
#define TEGRA_I2C_PRIVATE_DATA_FROM_SLAVE_DEVICE_TREE_NODE(a) CR(a, NVIDIA_TEGRA_I2C_PRIVATE_DATA, I2cSlaveDeviceTreeNode, TEGRA_I2C_SIGNATURE)

/**
* @addtogroup SPEED_MODES I2C Mode frequencies
Expand Down
Loading