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
/** @file
  UbaClkGenUpdateLib implementation.
 
  @copyright
  Copyright 2012 - 2021 Intel Corporation. <BR>
 
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include <PiPei.h>
#include <Uefi/UefiSpec.h>
 
#include <Ppi/UbaCfgDb.h>
#include <Ppi/Smbus2.h>
 
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/PeiServicesTablePointerLib.h>
#include <Library/DebugLib.h>
 
#include <Library/UbaClkGenUpdateLib.h>
 
#define CLOCK_GENERATOR_ADDRESS     0xD2
 
EFI_STATUS
PlatformUpdateClockgen (
  IN  BOOLEAN                           EnableSpreadSpectrum
)
{
  EFI_STATUS                            Status;
 
  UBA_CONFIG_DATABASE_PPI               *UbaConfigPpi = NULL;
  PLATFORM_CLOCKGEN_UPDATE_TABLE        ClockgenTable;
  UINTN                                 TableSize = 0;
 
  EFI_SMBUS_DEVICE_ADDRESS              SlaveAddress;
  UINT8                                 Buffer[PLATFORM_NUMBER_OF_CLOCKGEN_DATA];
  UINTN                                 Length = 0;
  EFI_SMBUS_DEVICE_COMMAND              Command;
  EFI_PEI_SMBUS2_PPI                    *SmbusPpi = NULL;
 
  Status = PeiServicesLocatePpi (
              &gUbaConfigDatabasePpiGuid,
              0,
              NULL,
              &UbaConfigPpi
              );
  if (EFI_ERROR(Status)) {
    return Status;
  }
 
  Status = PeiServicesLocatePpi (
              &gEfiPeiSmbus2PpiGuid,
              0,
              NULL,
              &SmbusPpi
              );
  if (EFI_ERROR(Status)) {
    return Status;
  }
 
  //
  // Read the clock generator
  //
  SlaveAddress.SmbusDeviceAddress = CLOCK_GENERATOR_ADDRESS >> 1;
  Length      = sizeof (Buffer);
  Command     = 0;
  Status = SmbusPpi->Execute (
                      SmbusPpi,
                      SlaveAddress,
                      Command,
                      EfiSmbusReadBlock,
                      FALSE,
                      &Length,
                      Buffer
                      );
 
  if (EFI_ERROR(Status)) {
    return Status;
  }
 
  do {
 
    TableSize = sizeof(ClockgenTable);
    Status = UbaConfigPpi->GetData (
                                  UbaConfigPpi,
                                  &gPlatformClockgenConfigDataGuid,
                                  &ClockgenTable,
                                  &TableSize
                                  );
 
    if (EFI_ERROR(Status)) {
      return Status;
    }
 
    ASSERT (ClockgenTable.Signature == PLATFORM_CLOCKGEN_UPDATE_SIGNATURE);
    ASSERT (ClockgenTable.Version == PLATFORM_CLOCKGEN_UPDATE_VERSION);
 
    if (ClockgenTable.Id != PLATFORM_CLOCKGEN_NO_ID) {
      if (ClockgenTable.Id != Buffer[ClockgenTable.IdOffset]) {
        continue;
      }
    }
 
    if (EnableSpreadSpectrum) {
      ClockgenTable.Data[ClockgenTable.SpreadSpectrumByteOffset] = ClockgenTable.SpreadSpectrumValue;
    }
 
    //
    // Program clock generator
    //
    Command = 0;
    Length  = ClockgenTable.DataLength;
 
    Status = SmbusPpi->Execute (
                        SmbusPpi,
                        SlaveAddress,
                        Command,
                        EfiSmbusWriteBlock,
                        FALSE,
                        &Length,              //&ConfigurationTableLength,
                        &ClockgenTable.Data   //ConfigurationTable
                        );
    if (EFI_ERROR(Status)) {
      return Status;
    } else {
      break;
    }
  }while (!EFI_ERROR(Status));
 
  return Status;
}