/** @file
 *
 *  Copyright (c) 2018 Andrei Warkentin <andrey.warkentin@gmail.com>
 *  Copyright (c) 2020, ARM Limited. All rights reserved.
 *  Copyright (c) 2023, Mario Bălănică <mariobalanica02@gmail.com>
 *
 *  SPDX-License-Identifier: BSD-2-Clause-Patent
 *
 **/

#include <Guid/HiiPlatformSetupFormset.h>
#include <VarStoreData.h>

#include "RK3588DxeFormSetGuid.h"

#define VFR_FILE_INCLUDE
#include "CpuPerformance.h"
#include "FanControl.h"
#include "DebugSerialPort.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      = RK3588DXE_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 CPU_PERF_CLUSTER_CLOCK_PRESET_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPULClusterClockPreset,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_CLOCK_CUSTOM_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPULClusterClockCustom,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_CLOCK_PRESET_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB01ClusterClockPreset,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_CLOCK_CUSTOM_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB01ClusterClockCustom,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_CLOCK_PRESET_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB23ClusterClockPreset,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_CLOCK_CUSTOM_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB23ClusterClockCustom,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_VOLTAGE_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPULClusterVoltageMode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_VOLTAGE_CUSTOM_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPULClusterVoltageCustom,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_VOLTAGE_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB01ClusterVoltageMode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_VOLTAGE_CUSTOM_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB01ClusterVoltageCustom,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_VOLTAGE_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB23ClusterVoltageMode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CPU_PERF_CLUSTER_VOLTAGE_CUSTOM_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CpuPerf_CPUB23ClusterVoltageCustom,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore COMBO_PHY_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = ComboPhy0Mode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore COMBO_PHY_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = ComboPhy1Mode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore COMBO_PHY_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = ComboPhy2Mode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore USBDP_PHY_USB3_STATE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = UsbDpPhy0Usb3State,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore USBDP_PHY_USB3_STATE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = UsbDpPhy1Usb3State,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore PCIE30_STATE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = Pcie30State,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore PCIE30_PHY_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = Pcie30PhyMode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore CONFIG_TABLE_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = ConfigTableMode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore ACPI_PCIE_ECAM_COMPAT_MODE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = AcpiPcieEcamCompatMode,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore FDT_SUPPORT_OVERRIDES_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = FdtSupportOverrides,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore COOLING_FAN_STATE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CoolingFanState,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore COOLING_FAN_SPEED_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = CoolingFanSpeed,
      guid  = RK3588DXE_FORMSET_GUID;

    efivarstore DEBUG_SERIAL_PORT_BAUD_RATE_VARSTORE_DATA,
      attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
      name  = DebugSerialPortBaudRate,
      guid  = RK3588DXE_FORMSET_GUID;

    form formid = 1,
      title  = STRING_TOKEN(STR_FORM_SET_TITLE);
      subtitle text = STRING_TOKEN(STR_FORM_SET_TITLE_SUBTITLE);

      subtitle text = STRING_TOKEN(STR_NULL_STRING);

      goto 0x1000,
        prompt = STRING_TOKEN(STR_CPU_PERF_FORM_TITLE),
        help = STRING_TOKEN(STR_CPU_PERF_FORM_HELP);

      goto 0x1001,
        prompt = STRING_TOKEN(STR_COMBO_PHY_FORM_TITLE),
        help = STRING_TOKEN(STR_COMBO_PHY_FORM_HELP);

#if FixedPcdGetBool (PcdUsbDpPhy0Supported) || FixedPcdGetBool (PcdUsbDpPhy1Supported)
      goto 0x1002,
        prompt = STRING_TOKEN(STR_USBDP_PHY_FORM_TITLE),
        help = STRING_TOKEN(STR_USBDP_PHY_FORM_HELP);
#endif

#if FixedPcdGetBool (PcdPcie30Supported)
      goto 0x1003,
        prompt = STRING_TOKEN(STR_PCIE30_FORM_TITLE),
        help = STRING_TOKEN(STR_PCIE30_FORM_HELP);
#endif

      goto 0x1004,
        prompt = STRING_TOKEN(STR_CONFIG_TABLE_FORM_TITLE),
        help = STRING_TOKEN(STR_CONFIG_TABLE_FORM_HELP);

#if FixedPcdGetBool (PcdHasOnBoardFanOutput)
      goto 0x1005,
        prompt = STRING_TOKEN(STR_COOLING_FAN_FORM_TITLE),
        help = STRING_TOKEN(STR_COOLING_FAN_FORM_HELP);
#endif

      goto 0x1006,
        prompt = STRING_TOKEN(STR_DEBUG_SERIAL_PORT_FORM_TITLE),
        help = STRING_TOKEN(STR_DEBUG_SERIAL_PORT_FORM_HELP);
    endform;

    form formid = 0x1000,
        title  = STRING_TOKEN(STR_CPU_PERF_FORM_TITLE);
        subtitle text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCKS_SUBTITLE);

        oneof varid = CpuPerf_CPULClusterClockPreset.Preset,
          prompt      = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_CLOCK_PRESET_PROMPT),
          help        = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_CLOCK_PRESET_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = FixedPcdGet32 (PcdCPULClusterClockPresetDefault),
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_BOOTDEF), value = CPU_PERF_CLUSTER_CLOCK_PRESET_BOOTDEFAULT, flags = 0;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_MIN), value = CPU_PERF_CLUSTER_CLOCK_PRESET_MIN, flags = 0;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_MAX), value = CPU_PERF_CLUSTER_CLOCK_PRESET_MAX, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM), value = CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM, flags = 0;
        endoneof;

        grayoutif NOT ideqval CpuPerf_CPULClusterClockPreset.Preset == CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM;
          oneof varid = CpuPerf_CPULClusterClockCustom.Mhz,
            prompt      = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_CLOCK_CUSTOM_PROMPT),
            help        = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_CLOCK_CUSTOM_HELP),
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_408), value = 408, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_600), value = 600, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_816), value = 816, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1008), value = 1008, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1200), value = 1200, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1416), value = 1416, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1608), value = 1608, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1800), value = 1800, flags = DEFAULT;
          endoneof;
        endif;

        oneof varid = CpuPerf_CPUB01ClusterClockPreset.Preset,
          prompt      = STRING_TOKEN(STR_CPU_PERF_CPUB01_CLUSTER_CLOCK_PRESET_PROMPT),
          help        = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_CLOCK_PRESET_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = FixedPcdGet32 (PcdCPUB01ClusterClockPresetDefault),
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_BOOTDEF), value = CPU_PERF_CLUSTER_CLOCK_PRESET_BOOTDEFAULT, flags = 0;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_MIN), value = CPU_PERF_CLUSTER_CLOCK_PRESET_MIN, flags = 0;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_MAX), value = CPU_PERF_CLUSTER_CLOCK_PRESET_MAX, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM), value = CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM, flags = 0;
        endoneof;

        grayoutif NOT ideqval CpuPerf_CPUB01ClusterClockPreset.Preset == CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM;
          oneof varid = CpuPerf_CPUB01ClusterClockCustom.Mhz,
            prompt      = STRING_TOKEN(STR_CPU_PERF_CPUB01_CLUSTER_CLOCK_CUSTOM_PROMPT),
            help        = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_CLOCK_CUSTOM_HELP),
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_408), value = 408, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_600), value = 600, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_816), value = 816, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1008), value = 1008, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1200), value = 1200, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1416), value = 1416, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1608), value = 1608, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1800), value = 1800, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2016), value = 2016, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2208), value = 2208, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2256), value = 2256, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2304), value = 2304, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2352), value = 2352, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2400), value = 2400, flags = DEFAULT;
          endoneof;
        endif;

        oneof varid = CpuPerf_CPUB23ClusterClockPreset.Preset,
          prompt      = STRING_TOKEN(STR_CPU_PERF_CPUB23_CLUSTER_CLOCK_PRESET_PROMPT),
          help        = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_CLOCK_PRESET_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = FixedPcdGet32 (PcdCPUB23ClusterClockPresetDefault),
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_BOOTDEF), value = CPU_PERF_CLUSTER_CLOCK_PRESET_BOOTDEFAULT, flags = 0;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_MIN), value = CPU_PERF_CLUSTER_CLOCK_PRESET_MIN, flags = 0;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_MAX), value = CPU_PERF_CLUSTER_CLOCK_PRESET_MAX, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM), value = CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM, flags = 0;
        endoneof;

        grayoutif NOT ideqval CpuPerf_CPUB23ClusterClockPreset.Preset == CPU_PERF_CLUSTER_CLOCK_PRESET_CUSTOM;
          oneof varid = CpuPerf_CPUB23ClusterClockCustom.Mhz,
            prompt      = STRING_TOKEN(STR_CPU_PERF_CPUB23_CLUSTER_CLOCK_CUSTOM_PROMPT),
            help        = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_CLOCK_CUSTOM_HELP),
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_408), value = 408, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_600), value = 600, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_816), value = 816, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1008), value = 1008, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1200), value = 1200, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1416), value = 1416, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1608), value = 1608, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_1800), value = 1800, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2016), value = 2016, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2208), value = 2208, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2256), value = 2256, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2304), value = 2304, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2352), value = 2352, flags = 0;
            option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_CLOCK_CUSTOM_2400), value = 2400, flags = DEFAULT;
          endoneof;
        endif;

        subtitle text = STRING_TOKEN(STR_NULL_STRING);
        subtitle text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGES_SUBTITLE);

        oneof varid = CpuPerf_CPULClusterVoltageMode.Mode,
          prompt      = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_VOLTAGE_MODE_PROMPT),
          help        = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_VOLTAGE_MODE_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGE_MODE_AUTO), value = CPU_PERF_CLUSTER_VOLTAGE_MODE_AUTO, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM), value = CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM, flags = 0;
        endoneof;

        grayoutif NOT ideqval CpuPerf_CPULClusterVoltageMode.Mode == CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM;
          numeric varid = CpuPerf_CPULClusterVoltageCustom.Microvolts,
            prompt  = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_VOLTAGE_CUSTOM_PROMPT),
            help    = STRING_TOKEN(STR_CPU_PERF_CPUL_CLUSTER_VOLTAGE_CUSTOM_HELP),
            flags   = DISPLAY_UINT_DEC | NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            minimum = CLUSTER_MICROVOLTS_MIN,
            maximum = CLUSTER_MICROVOLTS_MAX,
            step = CLUSTER_MICROVOLTS_STEP,
            default = CPUL_CLUSTER_MICROVOLTS_DEFAULT,
          endnumeric;
        endif;

        oneof varid = CpuPerf_CPUB01ClusterVoltageMode.Mode,
          prompt      = STRING_TOKEN(STR_CPU_PERF_CPUB01_CLUSTER_VOLTAGE_MODE_PROMPT),
          help        = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_VOLTAGE_MODE_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGE_MODE_AUTO), value = CPU_PERF_CLUSTER_VOLTAGE_MODE_AUTO, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM), value = CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM, flags = 0;
        endoneof;

        grayoutif NOT ideqval CpuPerf_CPUB01ClusterVoltageMode.Mode == CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM;
          numeric varid = CpuPerf_CPUB01ClusterVoltageCustom.Microvolts,
            prompt  = STRING_TOKEN(STR_CPU_PERF_CPUB01_CLUSTER_VOLTAGE_CUSTOM_PROMPT),
            help    = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_VOLTAGE_CUSTOM_HELP),
            flags   = DISPLAY_UINT_DEC | NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            minimum = CLUSTER_MICROVOLTS_MIN,
            maximum = CLUSTER_MICROVOLTS_MAX,
            step = CLUSTER_MICROVOLTS_STEP,
            default = CPUB_CLUSTER_MICROVOLTS_DEFAULT,
          endnumeric;
        endif;

        oneof varid = CpuPerf_CPUB23ClusterVoltageMode.Mode,
          prompt      = STRING_TOKEN(STR_CPU_PERF_CPUB23_CLUSTER_VOLTAGE_MODE_PROMPT),
          help        = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_VOLTAGE_MODE_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGE_MODE_AUTO), value = CPU_PERF_CLUSTER_VOLTAGE_MODE_AUTO, flags = DEFAULT;
          option text = STRING_TOKEN(STR_CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM), value = CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM, flags = 0;
        endoneof;

        grayoutif NOT ideqval CpuPerf_CPUB23ClusterVoltageMode.Mode == CPU_PERF_CLUSTER_VOLTAGE_MODE_CUSTOM;
          numeric varid = CpuPerf_CPUB23ClusterVoltageCustom.Microvolts,
            prompt  = STRING_TOKEN(STR_CPU_PERF_CPUB23_CLUSTER_VOLTAGE_CUSTOM_PROMPT),
            help    = STRING_TOKEN(STR_CPU_PERF_CPUB_CLUSTER_VOLTAGE_CUSTOM_HELP),
            flags   = DISPLAY_UINT_DEC | NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            minimum = CLUSTER_MICROVOLTS_MIN,
            maximum = CLUSTER_MICROVOLTS_MAX,
            step = CLUSTER_MICROVOLTS_STEP,
            default = CPUB_CLUSTER_MICROVOLTS_DEFAULT,
          endnumeric;
        endif;

        subtitle text = STRING_TOKEN(STR_NULL_STRING);
        subtitle text = STRING_TOKEN(STR_CPU_PERF_FORM_SUBTITLE);
    endform;

    form formid = 0x1001,
        title  = STRING_TOKEN(STR_COMBO_PHY_FORM_TITLE);

        grayoutif FixedPcdGetBool (PcdComboPhy0Switchable) == 0;
          oneof varid = ComboPhy0Mode.Mode,
            prompt      = STRING_TOKEN(STR_COMBO_PHY0_MODE_PROMPT),
#if   FixedPcdGet32 (PcdComboPhy0ModeDefault) == COMBO_PHY_MODE_PCIE
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_PCIE_HELP),
#elif FixedPcdGet32 (PcdComboPhy0ModeDefault) == COMBO_PHY_MODE_SATA
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_SATA_HELP),
#elif FixedPcdGet32 (PcdComboPhy0ModeDefault) == COMBO_PHY_MODE_USB3
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_USB3_HELP),
#else
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_UNCONNECTED_HELP),
#endif
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            default     = FixedPcdGet32 (PcdComboPhy0ModeDefault),
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_UNCONNECTED), value = COMBO_PHY_MODE_UNCONNECTED, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_PCIE), value = COMBO_PHY_MODE_PCIE, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_SATA), value = COMBO_PHY_MODE_SATA, flags = 0;
          endoneof;
        endif;

        grayoutif FixedPcdGetBool (PcdComboPhy1Switchable) == 0;
          oneof varid = ComboPhy1Mode.Mode,
            prompt      = STRING_TOKEN(STR_COMBO_PHY1_MODE_PROMPT),
#if   FixedPcdGet32 (PcdComboPhy1ModeDefault) == COMBO_PHY_MODE_PCIE
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_PCIE_HELP),
#elif FixedPcdGet32 (PcdComboPhy1ModeDefault) == COMBO_PHY_MODE_SATA
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_SATA_HELP),
#elif FixedPcdGet32 (PcdComboPhy1ModeDefault) == COMBO_PHY_MODE_USB3
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_USB3_HELP),
#else
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_UNCONNECTED_HELP),
#endif
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            default     = FixedPcdGet32 (PcdComboPhy1ModeDefault),
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_UNCONNECTED), value = COMBO_PHY_MODE_UNCONNECTED, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_PCIE), value = COMBO_PHY_MODE_PCIE, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_SATA), value = COMBO_PHY_MODE_SATA, flags = 0;
          endoneof;
        endif;

        grayoutif FixedPcdGetBool (PcdComboPhy2Switchable) == 0;
          oneof varid = ComboPhy2Mode.Mode,
            prompt      = STRING_TOKEN(STR_COMBO_PHY2_MODE_PROMPT),
#if   FixedPcdGet32 (PcdComboPhy2ModeDefault) == COMBO_PHY_MODE_PCIE
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_PCIE_HELP),
#elif FixedPcdGet32 (PcdComboPhy2ModeDefault) == COMBO_PHY_MODE_SATA
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_SATA_HELP),
#elif FixedPcdGet32 (PcdComboPhy2ModeDefault) == COMBO_PHY_MODE_USB3
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_USB3_HELP),
#else
            help        = STRING_TOKEN(STR_COMBO_PHY_MODE_DEFAULT_UNCONNECTED_HELP),
#endif
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            default     = FixedPcdGet32 (PcdComboPhy2ModeDefault),
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_UNCONNECTED), value = COMBO_PHY_MODE_UNCONNECTED, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_PCIE), value = COMBO_PHY_MODE_PCIE, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_SATA), value = COMBO_PHY_MODE_SATA, flags = 0;
            option text = STRING_TOKEN(STR_COMBO_PHY_MODE_USB3), value = COMBO_PHY_MODE_USB3, flags = 0;
          endoneof;
        endif;

        subtitle text = STRING_TOKEN(STR_NULL_STRING);
        subtitle text = STRING_TOKEN(STR_COMBO_PHY_FORM_SUBTITLE);
    endform;

    form formid = 0x1002,
        title  = STRING_TOKEN(STR_USBDP_PHY_FORM_TITLE);

#if FixedPcdGetBool (PcdUsbDpPhy0Supported)
        oneof varid = UsbDpPhy0Usb3State.State,
          prompt      = STRING_TOKEN(STR_USBDP_PHY0_USB3_STATE_PROMPT),
          help        = STRING_TOKEN(STR_USBDP_PHY_USB3_STATE_PROMPT),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = USBDP_PHY_USB3_STATE_ENABLED,
          option text = STRING_TOKEN(STR_ENABLED), value = USBDP_PHY_USB3_STATE_ENABLED, flags = 0;
          option text = STRING_TOKEN(STR_DISABLED), value = USBDP_PHY_USB3_STATE_DISABLED, flags = 0;
        endoneof;
#endif

#if FixedPcdGetBool (PcdUsbDpPhy1Supported)
        oneof varid = UsbDpPhy1Usb3State.State,
          prompt      = STRING_TOKEN(STR_USBDP_PHY1_USB3_STATE_PROMPT),
          help        = STRING_TOKEN(STR_USBDP_PHY_USB3_STATE_PROMPT),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = USBDP_PHY_USB3_STATE_ENABLED,
          option text = STRING_TOKEN(STR_ENABLED), value = USBDP_PHY_USB3_STATE_ENABLED, flags = 0;
          option text = STRING_TOKEN(STR_DISABLED), value = USBDP_PHY_USB3_STATE_DISABLED, flags = 0;
        endoneof;
#endif
    endform;

#if FixedPcdGetBool (PcdPcie30Supported)
    form formid = 0x1003,
        title  = STRING_TOKEN(STR_PCIE30_FORM_TITLE);

        oneof varid = Pcie30State.State,
          prompt      = STRING_TOKEN(STR_PCIE30_STATE_PROMPT),
          help        = STRING_TOKEN(STR_PCIE30_STATE_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = PCIE30_STATE_ENABLED,
          option text = STRING_TOKEN(STR_DISABLED), value = PCIE30_STATE_DISABLED, flags = 0;
          option text = STRING_TOKEN(STR_ENABLED), value = PCIE30_STATE_ENABLED, flags = 0;
        endoneof;

        /* shoule we move this to single PHY settings form */
        oneof varid = Pcie30PhyMode.Mode,
          prompt      = STRING_TOKEN(STR_PCIE30_PHY_MODE_PROMPT),
          help        = STRING_TOKEN(STR_PCIE30_PHY_MODE_HELP),
          flags       = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
          default     = FixedPcdGet8 (PcdPcie30PhyModeDefault),
          option text = STRING_TOKEN(STR_PCIE30_PHY_MODE_AGGREGATION), value = PCIE30_PHY_MODE_AGGREGATION, flags = 0;
          option text = STRING_TOKEN(STR_PCIE30_PHY_MODE_NANBNB), value = PCIE30_PHY_MODE_NANBNB, flags = 0;
          option text = STRING_TOKEN(STR_PCIE30_PHY_MODE_NANBBI), value = PCIE30_PHY_MODE_NANBBI, flags = 0;
          option text = STRING_TOKEN(STR_PCIE30_PHY_MODE_NABINB), value = PCIE30_PHY_MODE_NABINB, flags = 0;
          option text = STRING_TOKEN(STR_PCIE30_PHY_MODE_NABIBI), value = PCIE30_PHY_MODE_NABIBI, flags = 0;
        endoneof;
    endform;
#endif

    form formid = 0x1004,
        title  = STRING_TOKEN(STR_CONFIG_TABLE_FORM_TITLE);

        oneof varid = ConfigTableMode.Mode,
          prompt      = STRING_TOKEN(STR_CONFIG_TABLE_MODE_PROMPT),
          help        = STRING_TOKEN(STR_CONFIG_TABLE_MODE_HELP),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = CONFIG_TABLE_MODE_ACPI,
          option text = STRING_TOKEN(STR_CONFIG_TABLE_MODE_ACPI), value = CONFIG_TABLE_MODE_ACPI, flags = 0;
          option text = STRING_TOKEN(STR_CONFIG_TABLE_MODE_FDT), value = CONFIG_TABLE_MODE_FDT, flags = 0;
          option text = STRING_TOKEN(STR_CONFIG_TABLE_MODE_ACPI_FDT), value = CONFIG_TABLE_MODE_ACPI_FDT, flags = 0;
        endoneof;

        suppressif (get(ConfigTableMode.Mode) & CONFIG_TABLE_MODE_ACPI) == 0;
          subtitle text = STRING_TOKEN(STR_NULL_STRING);
          subtitle text = STRING_TOKEN(STR_CONFIG_TABLE_ACPI_SUBTITLE);

          oneof varid = AcpiPcieEcamCompatMode.Mode,
            prompt      = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_PROMPT),
            help        = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_HELP),
            flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            default     = FixedPcdGet32 (PcdAcpiPcieEcamCompatModeDefault),
            option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV), value = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_SINGLE_DEV, flags = 0;
            option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON), value = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6_GRAVITON, flags = 0;
            option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV), value = ACPI_PCIE_ECAM_COMPAT_MODE_SINGLE_DEV, flags = 0;
            option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6), value = ACPI_PCIE_ECAM_COMPAT_MODE_NXPMX6, flags = 0;
            option text = STRING_TOKEN(STR_ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON), value = ACPI_PCIE_ECAM_COMPAT_MODE_GRAVITON, flags = 0;
          endoneof;
        endif;

        suppressif (get(ConfigTableMode.Mode) & CONFIG_TABLE_MODE_FDT) == 0;
          subtitle text = STRING_TOKEN(STR_NULL_STRING);
          subtitle text = STRING_TOKEN(STR_CONFIG_TABLE_FDT_SUBTITLE);

          oneof varid = FdtSupportOverrides.State,
            prompt      = STRING_TOKEN(STR_FDT_SUPPORT_OVERRIDES_PROMPT),
            help        = STRING_TOKEN(STR_FDT_SUPPORT_OVERRIDES_HELP),
            flags       = NUMERIC_SIZE_1 | INTERACTIVE | RESET_REQUIRED,
            default     = FALSE,
            option text = STRING_TOKEN(STR_DISABLED), value = FALSE, flags = 0;
            option text = STRING_TOKEN(STR_ENABLED), value = TRUE, flags = 0;
          endoneof;
        endif;
    endform;

#if FixedPcdGetBool (PcdHasOnBoardFanOutput)
    form formid = 0x1005,
        title  = STRING_TOKEN(STR_COOLING_FAN_FORM_TITLE);

        oneof varid = CoolingFanState.State,
          prompt      = STRING_TOKEN(STR_COOLING_FAN_STATE_PROMPT),
          help        = STRING_TOKEN(STR_COOLING_FAN_STATE_PROMPT),
          flags       = NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
          default     = COOLING_FAN_STATE_ENABLED,
          option text = STRING_TOKEN(STR_DISABLED), value = COOLING_FAN_STATE_DISABLED, flags = 0;
          option text = STRING_TOKEN(STR_ENABLED), value = COOLING_FAN_STATE_ENABLED, flags = 0;
        endoneof;

        grayoutif NOT ideqval CoolingFanState.State == COOLING_FAN_STATE_ENABLED;
          numeric varid = CoolingFanSpeed.Percentage,
            prompt  = STRING_TOKEN(STR_COOLING_FAN_SPEED_PROMPT),
            help    = STRING_TOKEN(STR_COOLING_FAN_SPEED_PROMPT),
            flags   = DISPLAY_UINT_DEC | NUMERIC_SIZE_4 | INTERACTIVE | RESET_REQUIRED,
            minimum = FAN_PERCENTAGE_MIN,
            maximum = FAN_PERCENTAGE_MAX,
            step = FAN_PERCENTAGE_STEP,
            default = FAN_PERCENTAGE_DEFAULT,
          endnumeric;
        endif;
    endform;
#endif

    form formid = 0x1006,
        title  = STRING_TOKEN(STR_DEBUG_SERIAL_PORT_FORM_TITLE);

        numeric varid = DebugSerialPortBaudRate.Value,
          prompt  = STRING_TOKEN(STR_DEBUG_SERIAL_PORT_BAUD_RATE_PROMPT),
          help    = STRING_TOKEN(STR_NULL_STRING),
          flags   = DISPLAY_UINT_DEC | NUMERIC_SIZE_8 | INTERACTIVE | RESET_REQUIRED,
          minimum = DEBUG_SERIAL_PORT_BAUD_RATE_MIN,
          maximum = DEBUG_SERIAL_PORT_BAUD_RATE_MAX,
          step    = 0,
          default = DEBUG_SERIAL_PORT_BAUD_RATE_DEFAULT,
        endnumeric;

        subtitle text = STRING_TOKEN(STR_NULL_STRING);
        subtitle text = STRING_TOKEN(STR_DEBUG_SERIAL_PORT_SUBTITLE);
    endform;

endformset;
