hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/** @file
  Install Platform Clocks Config Data.
 
  @copyright
  Copyright 2017 - 2021 Intel Corporation. <BR>
 
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include "PeiCommonBoardInitLib.h"
#include <Library/PlatformClocksLib.h>
#include <Library/UbaClocksConfigLib.h>
#include <Library/SpsPeiLib.h>
#include <Library/PchInfoLib.h>
#include <Ppi/PchPolicy.h>
#include <Ppi/DynamicSiLibraryPpi.h>
 
//
// Table providing details on clocks supported by this library
//
// It is critical that this table be properly constructed.
// The table entries must line up with the clock generatory types
//
CLOCK_GENERATOR_DETAILS mSupportedClockGeneratorTable[] = {
{
    ClockGeneratorCk410,
    CK410_GENERATOR_ID,
    CK410_GENERATOR_SPREAD_SPECTRUM_BYTE,
    CK410_GENERATOR_SPREAD_SPECTRUM_BIT
  },
{
    ClockGeneratorCk420,
    CK420_GENERATOR_ID,
    CK420_GENERATOR_SPREAD_SPECTRUM_BYTE,
    CK420_GENERATOR_SPREAD_SPECTRUM_BIT
  },
{
    ClockGeneratorCk440,
    CK440_GENERATOR_ID,
    CK440_GENERATOR_SPREAD_SPECTRUM_BYTE,
    CK440_GENERATOR_SPREAD_SPECTRUM_BIT
  },
{
    ClockGeneratorCk505,
    CK505_GENERATOR_ID,
    CK505_GENERATOR_SPREAD_SPECTRUM_BYTE,
    CK505_GENERATOR_SPREAD_SPECTRUM_BIT
  }
};
 
/**
 
  Configure the clock generator and enable Spread Spectrum if applicable.
 
  @param None
 
  @retval EFI_SUCCESS      The function completed successfully.
  @retval EFI_UNSUPPORTED  Clock generator configuration is not supported
 
**/
EFI_STATUS
PlatformClocksConfigCallback (
  IN EFI_PEI_SERVICES                   **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR          *NotifyDescriptor,
  IN VOID                               *Ppi
  )
{
  EFI_STATUS                            Status;
  CLOCKING_MODES                        ClockingMode;
  UINT8                                 *ConfigurationTable;
  UINT8                                 ConfigurationTablePlatformSRP[] = CLOCK_GENERATOR_SETTINGS_PLATFORMSRP;
  UINT8                                 ConfigurationTableCK505[] = CLOCK_GENERATOR_SETTINGS_CK505;
  UINTN                                 Length;
  CLOCK_GENERATOR_TYPE                  ClockType;
  BOOLEAN                               SecondarySmbus = FALSE;
  BOOLEAN                               EnableSpreadSpectrum;
  PCH_POLICY_PPI                        *PchPolicyPpi;
  UINT8                                 ClockGeneratorAddress = 0;
  DYNAMIC_SI_LIBARY_PPI                 *DynamicSiLibraryPpi = NULL;
 
  Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
  if (EFI_ERROR(Status)) {
    DEBUG ((DEBUG_ERROR, "ConfigurePlatformClocks. Can not read gDynamicSiLibraryPpiGuid\n"));
    return Status;
  }
 
  ClockGeneratorAddress = PcdGet8 (PcdOemSkuClockGeneratorAddress);
 
  ClockingMode = InternalAlternate;
  Status = EFI_SUCCESS;
  if (EFI_ERROR (Status)) {
    if (Status != EFI_UNSUPPORTED) {
      DEBUG ((DEBUG_ERROR, "ConfigurePlatformClocks. Can't read clock mode! EFI_STATUS = %r\n", Status));
    }
    return Status;
  }
 
  if (External == ClockingMode)
  {
    DEBUG ((DEBUG_INFO, "ConfigurePlatformClocks. Clock Mode: External\n"));
 
    //
    // If the clocking mode is external and CPX is present, then no further configuration of the
    // clock is supported at this time.
    //
    if (DynamicSiLibraryPpi->IsCpuAndRevision (CPU_CPX, REV_ALL)) {
      return EFI_UNSUPPORTED;
    }
 
    if (DynamicSiLibraryPpi->IsSimicsEnvironment()) {
      //
      // Simics implements CK505 model
      //
      ConfigurationTable = ConfigurationTableCK505;
      Length = sizeof (ConfigurationTableCK505);
      ClockType = ClockGeneratorCk505;
    }
    else {
      //
      // SRP/DVP configuration
      //
      ConfigurationTable = ConfigurationTablePlatformSRP;
      Length = sizeof (ConfigurationTablePlatformSRP);
      ClockType = ClockGeneratorCk420;
    }
    Status = (*PeiServices)->LocatePpi (PeiServices,
                                        &gPchPlatformPolicyPpiGuid,
                                        0,
                                        NULL,
                                        (VOID **)&PchPolicyPpi
                                       );
    ASSERT_EFI_ERROR (Status);
    EnableSpreadSpectrum = (BOOLEAN) PchPolicyPpi->PchConfig.EnableClockSpreadSpec;
    if (1 == EnableSpreadSpectrum) {
      ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] |= mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset;
    } else {
      ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] &= ~(mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset);
    }
    Status = ConfigureClockGenerator (PeiServices,
                                      ClockType,
                                      ClockGeneratorAddress,
                                      Length,
                                      ConfigurationTable,
                                      EnableSpreadSpectrum,
                                      &mSupportedClockGeneratorTable[ClockType],
                                      SecondarySmbus
                                     );
    ASSERT_EFI_ERROR (Status);
  }
 
  return EFI_SUCCESS;
}
 
PLATFORM_CLOCKS_CONFIG_TABLE    PlatformClocksConfigTable =
{
  PLATFORM_CLOCKS_CONFIG_SIGNATURE,
  PLATFORM_CLOCKS_CONFIG_VERSION,
  PlatformClocksConfigCallback
};
 
EFI_STATUS
InstallPlatformClocksConfigData (
  IN UBA_CONFIG_DATABASE_PPI    *UbaConfigPpi
)
{
  EFI_STATUS                            Status = EFI_SUCCESS;
 
   Status = UbaConfigPpi->AddData (
                                  UbaConfigPpi,
                                  &gPlatformClocksConfigDataGuid,
                                  &PlatformClocksConfigTable,
                                  sizeof(PlatformClocksConfigTable)
                                  );
 
  return Status;
}