summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Platform/Socionext/DeveloperBox/DeveloperBox.dsc2
-rw-r--r--Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc2
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c35
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c107
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h13
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf11
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni29
-rw-r--r--Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr69
-rw-r--r--Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h23
-rw-r--r--Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h5
-rw-r--r--Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h29
-rw-r--r--Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf2
-rw-r--r--Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c40
-rw-r--r--Silicon/Socionext/SynQuacer/SynQuacer.dec5
14 files changed, 365 insertions, 7 deletions
diff --git a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
index 86685d1dec..2d46b45157 100644
--- a/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
+++ b/Platform/Socionext/DeveloperBox/DeveloperBox.dsc
@@ -405,6 +405,8 @@
[PcdsDynamicHii]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|30
+ gSynQuacerTokenSpaceGuid.PcdPlatformSettings|L"SynQuacerPlatformSettings"|gSynQuacerPlatformFormSetGuid|0x0|0x0|NV,BS
+
[PcdsDynamicDefault]
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0000000000000000
gArmTokenSpaceGuid.PcdSystemMemorySize|0xFFFFFFFFFFFFFFFF
diff --git a/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc b/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
index b4b9239143..263b6454ff 100644
--- a/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
+++ b/Platform/Socionext/SynQuacerEvalBoard/SynQuacerEvalBoard.dsc
@@ -397,6 +397,8 @@
[PcdsDynamicHii]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|30
+ gSynQuacerTokenSpaceGuid.PcdPlatformSettings|L"SynQuacerPlatformSettings"|gSynQuacerPlatformFormSetGuid|0x0|0x0|NV,BS
+
[PcdsDynamicDefault]
gArmTokenSpaceGuid.PcdSystemMemoryBase|0x0000000000000000
gArmTokenSpaceGuid.PcdSystemMemorySize|0xFFFFFFFFFFFFFFFF
diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c
index 9af3dd942c..7c69a8051a 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/Pci.c
@@ -45,6 +45,11 @@ RetrainAsm1184eDownstreamPort (
EFI_STATUS Status;
PCIE_CAP Cap;
PCI_REG_PCIE_LINK_CONTROL LinkControl;
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+ UINT8 MaxSpeed;
//
// The upstream and downstream ports share the same PID/VID, so check
@@ -64,8 +69,34 @@ RetrainAsm1184eDownstreamPort (
return;
}
- DEBUG ((DEBUG_INFO, "%a: retraining ASM118x downstream PCIe port\n",
- __FUNCTION__));
+ Status = PciIo->GetLocation (PciIo, &SegmentNumber, &BusNumber, &DeviceNumber,
+ &FunctionNumber);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Check whether this downstream port is described by any of our 'slot'
+ // definitions, and get the maximum speed if this is the case.
+ //
+ switch (SYNQUACER_PCI_LOCATION (SegmentNumber, BusNumber, DeviceNumber)) {
+ case SYNQUACER_PCI_SLOT0_LOCATION:
+ MaxSpeed = mHiiSettings->PcieSlot0MaxSpeed;
+ break;
+ case SYNQUACER_PCI_SLOT1_LOCATION:
+ MaxSpeed = mHiiSettings->PcieSlot1MaxSpeed;
+ break;
+ case SYNQUACER_PCI_SLOT2_LOCATION:
+ MaxSpeed = mHiiSettings->PcieSlot2MaxSpeed;
+ break;
+ default:
+ MaxSpeed = PCIE_MAX_SPEED_UNLIMITED;
+ }
+ if (MaxSpeed == PCIE_MAX_SPEED_GEN1) {
+ return;
+ }
+
+ DEBUG ((DEBUG_INFO,
+ "%a: retraining ASM118x downstream PCIe port at %04x:%02x:%02x to Gen2\n",
+ __FUNCTION__, SegmentNumber, BusNumber, DeviceNumber));
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
ASM118x_PCIE_LINK_CONTROL_OFFSET, 1, &LinkControl);
diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c
index 91c1b66ea1..b60607d058 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c
+++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.c
@@ -14,6 +14,36 @@
#include "PlatformDxe.h"
+UINT64 mHiiSettingsVal;
+SYNQUACER_PLATFORM_VARSTORE_DATA *mHiiSettings;
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+STATIC HII_VENDOR_DEVICE_PATH mPlatformDxeHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ SYNQUACER_PLATFORM_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
STATIC EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR mNetsecDesc[] = {
{
ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc
@@ -144,6 +174,77 @@ SmmuEnableCoherentDma (
SMMU_SCR0_SHCFG_INNER | SMMU_SCR0_MTCFG | SMMU_SCR0_MEMATTR_INNER_OUTER_WB);
}
+STATIC
+EFI_STATUS
+InstallHiiPages (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HANDLE DriverHandle;
+
+ DriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mPlatformDxeHiiVendorDevicePath,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HiiHandle = HiiAddPackages (&gSynQuacerPlatformFormSetGuid,
+ DriverHandle,
+ PlatformDxeStrings,
+ PlatformDxeHiiBin,
+ NULL);
+
+ if (HiiHandle == NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mPlatformDxeHiiVendorDevicePath,
+ NULL);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EnableSettingsForm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN VarSize;
+ SYNQUACER_PLATFORM_VARSTORE_DATA Settings;
+
+ VarSize = sizeof (Settings);
+ Status = gRT->GetVariable (SYNQUACER_PLATFORM_VARIABLE_NAME,
+ &gSynQuacerPlatformFormSetGuid, NULL, &VarSize, &Settings);
+ if (Status == EFI_NOT_FOUND) {
+ //
+ // Variable does not exist yet - create it
+ //
+ SetMem (&Settings, sizeof (Settings), 0);
+ Status = gRT->SetVariable (SYNQUACER_PLATFORM_VARIABLE_NAME,
+ &gSynQuacerPlatformFormSetGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (Settings), &Settings);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a: EfiSetVariable failed - %r\n", __FUNCTION__,
+ Status));
+ return Status;
+ }
+ } else if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_WARN, "%a: EfiGetVariable failed - %r\n", __FUNCTION__,
+ Status));
+ return Status;
+ }
+
+ return InstallHiiPages ();
+}
+
EFI_STATUS
EFIAPI
PlatformDxeEntryPoint (
@@ -156,6 +257,9 @@ PlatformDxeEntryPoint (
UINTN DtbSize;
EFI_HANDLE Handle;
+ mHiiSettingsVal = PcdGet64 (PcdPlatformSettings);
+ mHiiSettings = (SYNQUACER_PLATFORM_VARSTORE_DATA *)&mHiiSettingsVal;
+
Dtb = NULL;
Status = DtPlatformLoadDtb (&Dtb, &DtbSize);
if (!EFI_ERROR (Status)) {
@@ -197,5 +301,8 @@ PlatformDxeEntryPoint (
Status = RegisterPcieNotifier ();
ASSERT_EFI_ERROR (Status);
+ Status = EnableSettingsForm ();
+ ASSERT_EFI_ERROR (Status);
+
return EFI_SUCCESS;
}
diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h
index d1dad2a3ea..53898b5828 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h
+++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.h
@@ -16,18 +16,31 @@
#define __PLATFORM_DXE_H__
#include <PiDxe.h>
+#include <Guid/SynQuacerPlatformFormSet.h>
#include <IndustryStandard/Pci.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
#include <Library/DtPlatformDtbLoaderLib.h>
+#include <Library/HiiLib.h>
#include <Library/IoLib.h>
#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
#include <Platform/MemoryMap.h>
+#include <Platform/Pcie.h>
+#include <Platform/VarStore.h>
#include <Protocol/NonDiscoverableDevice.h>
#include <Protocol/PciIo.h>
+extern UINT8 PlatformDxeHiiBin[];
+extern UINT8 PlatformDxeStrings[];
+
+extern UINT64 mHiiSettingsVal;
+extern SYNQUACER_PLATFORM_VARSTORE_DATA *mHiiSettings;
+
EFI_STATUS
EFIAPI
RegisterPcieNotifier (
diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf
index f075957d74..de21ba33df 100644
--- a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf
+++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxe.inf
@@ -25,6 +25,8 @@
[Sources]
Pci.c
PlatformDxe.c
+ PlatformDxeHii.uni
+ PlatformDxeHii.vfr
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
@@ -37,18 +39,24 @@
[LibraryClasses]
BaseMemoryLib
DebugLib
+ DevicePathLib
DtPlatformDtbLoaderLib
+ HiiLib
IoLib
MemoryAllocationLib
+ PcdLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiLib
+ UefiRuntimeServicesTableLib
[Guids]
+ gEfiHiiPlatformSetupFormsetGuid
gFdtTableGuid
gNetsecNonDiscoverableDeviceGuid
gSynQuacerNonDiscoverableI2cMasterGuid
gSynQuacerNonDiscoverableRuntimeI2cMasterGuid
+ gSynQuacerPlatformFormSetGuid
[Protocols]
gEdkiiNonDiscoverableDeviceProtocolGuid ## PRODUCES
@@ -59,5 +67,8 @@
gSynQuacerTokenSpaceGuid.PcdNetsecEepromBase
gSynQuacerTokenSpaceGuid.PcdNetsecPhyAddress
+[Pcd]
+ gSynQuacerTokenSpaceGuid.PcdPlatformSettings
+
[Depex]
TRUE
diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni
new file mode 100644
index 0000000000..b274d12ed2
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.uni
@@ -0,0 +1,29 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#langdef en-US "English"
+
+#string STR_FORM_SET_TITLE #language en-US "SynQuacer Platform Settings"
+#string STR_FORM_SET_TITLE_HELP #language en-US "Press <Enter> to set platform specific options."
+
+#string STR_MAIN_FORM_TITLE #language en-US "SynQuacer Platform Settings"
+#string STR_NULL_STRING #language en-US ""
+
+#string STR_PCIE0_MAX_SPEED_PROMPT #language en-US "PCIe x4 slot max speed"
+#string STR_PCIE1_MAX_SPEED_PROMPT #language en-US "PCIe x1 slot 1 max speed"
+#string STR_PCIE2_MAX_SPEED_PROMPT #language en-US "PCIe x1 slot 2 max speed"
+#string STR_PCIE_MAX_SPEED_HELP #language en-US "The maximum speed the PCIe downstream port is allowed to negotiate"
+
+#string STR_PCIE_MAX_SPEED_UNLIMITED #language en-US "Unlimited"
+#string STR_PCIE_MAX_SPEED_GEN1 #language en-US "Gen1 (2.5 GT/s)"
diff --git a/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr
new file mode 100644
index 0000000000..52f554b61e
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Drivers/PlatformDxe/PlatformDxeHii.vfr
@@ -0,0 +1,69 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro, Ltd. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Guid/HiiPlatformSetupFormset.h>
+#include <Guid/SynQuacerPlatformFormSet.h>
+#include <Platform/VarStore.h>
+
+//
+// EFI Variable attributes
+//
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_READ_ONLY 0x00000008
+
+formset
+ guid = SYNQUACER_PLATFORM_FORMSET_GUID,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+ efivarstore SYNQUACER_PLATFORM_VARSTORE_DATA,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attributes
+ name = SynQuacerPlatformSettings,
+ guid = SYNQUACER_PLATFORM_FORMSET_GUID;
+
+ form formid = 0x1000,
+ title = STRING_TOKEN(STR_MAIN_FORM_TITLE);
+
+ oneof varid = SynQuacerPlatformSettings.PcieSlot0MaxSpeed,
+ prompt = STRING_TOKEN(STR_PCIE0_MAX_SPEED_PROMPT),
+ help = STRING_TOKEN(STR_PCIE_MAX_SPEED_HELP),
+ flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
+ option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_UNLIMITED), value = PCIE_MAX_SPEED_UNLIMITED, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_GEN1), value = PCIE_MAX_SPEED_GEN1, flags = 0;
+ endoneof;
+
+ oneof varid = SynQuacerPlatformSettings.PcieSlot1MaxSpeed,
+ prompt = STRING_TOKEN(STR_PCIE1_MAX_SPEED_PROMPT),
+ help = STRING_TOKEN(STR_PCIE_MAX_SPEED_HELP),
+ flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
+ option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_UNLIMITED), value = PCIE_MAX_SPEED_UNLIMITED, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_GEN1), value = PCIE_MAX_SPEED_GEN1, flags = 0;
+ endoneof;
+
+ oneof varid = SynQuacerPlatformSettings.PcieSlot2MaxSpeed,
+ prompt = STRING_TOKEN(STR_PCIE2_MAX_SPEED_PROMPT),
+ help = STRING_TOKEN(STR_PCIE_MAX_SPEED_HELP),
+ flags = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
+ option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_UNLIMITED), value = PCIE_MAX_SPEED_UNLIMITED, flags = DEFAULT;
+ option text = STRING_TOKEN(STR_PCIE_MAX_SPEED_GEN1), value = PCIE_MAX_SPEED_GEN1, flags = 0;
+ endoneof;
+
+ subtitle text = STRING_TOKEN(STR_NULL_STRING);
+
+ endform;
+
+endformset;
diff --git a/Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h b/Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h
new file mode 100644
index 0000000000..9a70bb8730
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Include/Guid/SynQuacerPlatformFormSet.h
@@ -0,0 +1,23 @@
+/** @file
+*
+* Copyright (c) 2017, Linaro Limited. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made available
+* under the terms and conditions of the BSD License which accompanies this
+* distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __SYNQUACER_PLATFORM_FORMSET_H__
+#define __SYNQUACER_PLATFORM_FORMSET_H__
+
+#define SYNQUACER_PLATFORM_FORMSET_GUID \
+ { 0xe9cd576a, 0xaf9a, 0x4d41, { 0xbf, 0x1a, 0x29, 0xe1, 0xbc, 0x99, 0x99, 0x54 } }
+
+extern EFI_GUID gSynQuacerPlatformFormSetGuid;
+
+#endif
diff --git a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
index d2a3f9acbf..ee2357be9a 100644
--- a/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
+++ b/Silicon/Socionext/SynQuacer/Include/Platform/Pcie.h
@@ -60,4 +60,9 @@
#define SYNQUACER_PCI_SEG1_MMIO64_MAX 0x3fffffffff
#define SYNQUACER_PCI_SEG1_MMIO64_SIZE 0x100000000
+#define SYNQUACER_PCI_LOCATION(s,b,d) (((s) << 16) | ((b) << 8) | (d))
+#define SYNQUACER_PCI_SLOT0_LOCATION SYNQUACER_PCI_LOCATION(1, 0, 0)
+#define SYNQUACER_PCI_SLOT1_LOCATION SYNQUACER_PCI_LOCATION(0, 1, 7)
+#define SYNQUACER_PCI_SLOT2_LOCATION SYNQUACER_PCI_LOCATION(0, 1, 3)
+
#endif
diff --git a/Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h b/Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h
new file mode 100644
index 0000000000..5944613e74
--- /dev/null
+++ b/Silicon/Socionext/SynQuacer/Include/Platform/VarStore.h
@@ -0,0 +1,29 @@
+/** @file
+
+ Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __VARSTORE_H__
+#define __VARSTORE_H__
+
+#define SYNQUACER_PLATFORM_VARIABLE_NAME L"SynQuacerPlatformSettings"
+
+#define PCIE_MAX_SPEED_UNLIMITED 0x0
+#define PCIE_MAX_SPEED_GEN1 0x1
+
+typedef struct {
+ UINT8 PcieSlot0MaxSpeed;
+ UINT8 PcieSlot1MaxSpeed;
+ UINT8 PcieSlot2MaxSpeed;
+ UINT8 Reserved[5];
+} SYNQUACER_PLATFORM_VARSTORE_DATA;
+
+#endif
diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf
index 27fcba0344..e475529eaf 100644
--- a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLib.inf
@@ -45,6 +45,7 @@
DebugLib
DevicePathLib
MemoryAllocationLib
+ PcdLib
UefiBootServicesTableLib
[FixedPcd]
@@ -52,3 +53,4 @@
[Pcd]
gSynQuacerTokenSpaceGuid.PcdPcieEnableMask
+ gSynQuacerTokenSpaceGuid.PcdPlatformSettings
diff --git a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
index bea40e3dcf..e4679543cc 100644
--- a/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
+++ b/Silicon/Socionext/SynQuacer/Library/SynQuacerPciHostBridgeLib/SynQuacerPciHostBridgeLibConstructor.c
@@ -18,9 +18,11 @@
#include <Library/ArmLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
#include <Library/PciHostBridgeLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Platform/Pcie.h>
+#include <Platform/VarStore.h>
#include <Protocol/PciHostBridgeResourceAllocation.h>
#define IATU_VIEWPORT_OFF 0x900
@@ -268,7 +270,8 @@ PciInitControllerPost (
IN EFI_PHYSICAL_ADDRESS DbiBase,
IN EFI_PHYSICAL_ADDRESS ConfigBase,
IN EFI_PHYSICAL_ADDRESS IoMemBase,
- IN CONST PCI_ROOT_BRIDGE *RootBridge
+ IN CONST PCI_ROOT_BRIDGE *RootBridge,
+ IN BOOLEAN EnableGen2Speed
)
{
// 4: Set Bifurcation 1=disable 4=able
@@ -312,8 +315,10 @@ PciInitControllerPost (
EFI_PCI_COMMAND_MEMORY_SPACE |
EFI_PCI_COMMAND_BUS_MASTER);
- // Force link speed change to Gen2 at link up
- MmioOr32 (DbiBase + GEN2_CONTROL_OFF, DIRECT_SPEED_CHANGE);
+ if (EnableGen2Speed) {
+ // Force link speed change to Gen2 at link up
+ MmioOr32 (DbiBase + GEN2_CONTROL_OFF, DIRECT_SPEED_CHANGE);
+ }
// Region 0: MMIO32 range
ConfigureWindow (DbiBase, 0,
@@ -392,7 +397,13 @@ SynQuacerPciHostBridgeLibConstructor (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
- UINTN Idx;
+ UINTN Idx;
+ UINT64 SettingsVal;
+ SYNQUACER_PLATFORM_VARSTORE_DATA *Settings;
+ UINT8 MaxSpeed;
+
+ SettingsVal = PcdGet64 (PcdPlatformSettings);
+ Settings = (SYNQUACER_PLATFORM_VARSTORE_DATA *)&SettingsVal;
for (Idx = 0; Idx < ARRAY_SIZE (mBaseAddresses); Idx++) {
if (PcdGet8 (PcdPcieEnableMask) & (1 << Idx)) {
@@ -409,12 +420,31 @@ SynQuacerPciHostBridgeLibConstructor (
gBS->Stall (150 * 1000);
for (Idx = 0; Idx < ARRAY_SIZE (mBaseAddresses); Idx++) {
+ //
+ // Check whether this root port is described by any of our 'slot'
+ // definitions, and get the maximum speed if this is the case.
+ //
+ switch (SYNQUACER_PCI_LOCATION (Idx, 0, 0)) {
+ case SYNQUACER_PCI_SLOT0_LOCATION:
+ MaxSpeed = Settings->PcieSlot0MaxSpeed;
+ break;
+ case SYNQUACER_PCI_SLOT1_LOCATION:
+ MaxSpeed = Settings->PcieSlot1MaxSpeed;
+ break;
+ case SYNQUACER_PCI_SLOT2_LOCATION:
+ MaxSpeed = Settings->PcieSlot2MaxSpeed;
+ break;
+ default:
+ MaxSpeed = PCIE_MAX_SPEED_UNLIMITED;
+ }
+
if (PcdGet8 (PcdPcieEnableMask) & (1 << Idx)) {
PciInitControllerPost (mBaseAddresses[Idx].ExsBase,
mBaseAddresses[Idx].DbiBase,
mBaseAddresses[Idx].ConfigBase,
mBaseAddresses[Idx].IoMemBase,
- &mPciRootBridges[Idx]);
+ &mPciRootBridges[Idx],
+ (MaxSpeed != PCIE_MAX_SPEED_GEN1));
}
}
diff --git a/Silicon/Socionext/SynQuacer/SynQuacer.dec b/Silicon/Socionext/SynQuacer/SynQuacer.dec
index 76529e3c21..eb4fc4ace2 100644
--- a/Silicon/Socionext/SynQuacer/SynQuacer.dec
+++ b/Silicon/Socionext/SynQuacer/SynQuacer.dec
@@ -27,6 +27,8 @@
gSynQuacerPlatformDxeFileGuid = { 0xac422cc1, 0xd916, 0x489a, { 0xb1, 0x65, 0x53, 0x6f, 0xdf, 0xc6, 0x33, 0xc2 } }
+ gSynQuacerPlatformFormSetGuid = { 0xe9cd576a, 0xaf9a, 0x4d41, { 0xbf, 0x1a, 0x29, 0xe1, 0xbc, 0x99, 0x99, 0x54 } }
+
[Ppis]
gSynQuacerDramInfoPpiGuid = { 0x3e1d7356, 0xdda4, 0x4b1a, { 0x93, 0x46, 0xbf, 0x89, 0x1c, 0x86, 0x46, 0xcc } }
@@ -45,3 +47,6 @@
[PcdsPatchableInModule, PcdsDynamic]
# Enable both RC #0 and RC #1 by default
gSynQuacerTokenSpaceGuid.PcdPcieEnableMask|0x3|UINT8|0x00000007
+
+[PcdsDynamic]
+ gSynQuacerTokenSpaceGuid.PcdPlatformSettings|0x0|UINT64|0x00000008