hc
2024-03-22 a0752693d998599af469473b8dc239ef973a012f
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
/** SerDes.c
  Provides SoC specific SerDes interface
 
  Copyright 2020 NXP
 
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include <Library/DebugLib.h>
#include <Library/SerDesHelperLib.h>
 
/**
  Function to get SerDes Lane protocol corresponding to
  SerDes protocol.
 
  @param  SerDes              SerDes number.
  @param  SerDesProtocol      SerDes protocol number.
  @param  Lane                SerDes Lane number.
  @param  SerDesMaxProtocol   Max SerDes protocol number.
  @param  Config              SerDes Configuration.
 
  @return SerDes Lane protocol.
 
**/
UINT32
GetSerDesProtocol (
  IN  INTN            SerDes,
  IN  INTN            SerDesProtocol,
  IN  INTN            Lane,
  IN  UINT32          SerDesMaxProtocol,
  IN  SERDES_CONFIG   *Config
  )
{
  while (Config->Protocol) {
    if (Config->Protocol == SerDesProtocol) {
      return Config->SerDesLane[Lane];
    }
    Config++;
  }
 
  return SerDesMaxProtocol;
}
 
/**
  Function to validate input SerDes protocol.
 
  @param  SerDes              SerDes number.
  @param  SerDesProtocol      SerDes protocol number.
  @param  SerDesNumLanes      Number of SerDes Lanes.
  @param  Config              SerDes Configuration.
 
  @return EFI_NOT_FOUND     SerDes Protocol not a valid protocol.
  @return EFI_SUCCESS       SerDes Protocol is a valid protocol.
 
**/
EFI_STATUS
IsSerDesProtocolValid (
  IN  INTN           SerDes,
  IN  UINT32         SerDesProtocol,
  IN  UINT8          SerDesNumLanes,
  IN  SERDES_CONFIG  *Config
  )
{
  UINT8 Count;
 
  while (Config->Protocol) {
    if (Config->Protocol == SerDesProtocol) {
      DEBUG ((DEBUG_INFO, "Protocol: 0x%x Matched with the one in Table\n", SerDesProtocol));
      break;
    }
    Config++;
  }
 
  if (!Config->Protocol) {
    return EFI_NOT_FOUND;
  }
 
  for (Count = 0; Count < SerDesNumLanes; Count++) {
    if (Config->SerDesLane[Count] != 0) {
      return EFI_SUCCESS;
    }
  }
 
  return EFI_NOT_FOUND;
}
 
/**
  Get Lane protocol on provided SerDes Lane and execute callback function.
 
  @param  SerDes                  SerDes number.
  @param  SerDesProtocol          SerDes protocol number.
  @param  SerDesNumLanes          Number of SerDes Lanes.
  @param  SerDesMaxProtocol       Max SerDes protocol number.
  @param  Config                  SerDes Configuration.
  @param  SerDesLaneProbeCallback Pointer Callback function to be called for Lane protocol
  @param  Arg                     Pointer to Arguments to be passed to callback function.
**/
VOID
SerDesInstanceProbeLanes (
  IN  UINT32                      SerDes,
  IN  UINT32                      SerDesProtocol,
  IN  UINT8                       SerDesNumLanes,
  IN  UINT32                      SerDesMaxProtocol,
  IN  SERDES_CONFIG               *Config,
  IN  SERDES_PROBE_LANES_CALLBACK SerDesLaneProbeCallback,
  IN  VOID                        *Arg
  )
{
  INT8    Lane;
  UINT32  LaneProtocol;
 
  // Invoke callback for all lanes in the SerDes instance:
  for (Lane = 0; Lane < SerDesNumLanes; Lane++) {
    LaneProtocol = GetSerDesProtocol (SerDes, SerDesProtocol, Lane, SerDesMaxProtocol, Config);
    ASSERT (LaneProtocol < SerDesMaxProtocol);
    if (LaneProtocol != 0x0) {
      SerDesLaneProbeCallback (LaneProtocol, Arg);
    }
  }
}
 
/**
  Function to fill SerDes map information.
 
  @param  SerDes              SerDes number.
  @param  SerDesProtocol      SerDes protocol number.
  @param  SerDesNumLanes      Number of SerDes Lanes.
  @param  SerDesMaxProtocol   Max SerDes protocol number.
  @param  Config              SerDes Configuration.
  @param  SerDesProtocolMap   Output SerDes protocol map of enabled devices.
 
**/
EFI_STATUS
GetSerDesMap (
  IN  UINT32                    SerDes,
  IN  UINT32                    SerDesProtocol,
  IN  UINT8                     SerDesNumLanes,
  IN  UINT32                    SerDesMaxProtocol,
  IN  SERDES_CONFIG             *Config,
  OUT UINT64                    *SerDesProtocolMap
  )
{
  INTN                   Lane;
  EFI_STATUS             Status;
  UINT32                 LaneProtocol;
 
  Status = IsSerDesProtocolValid (SerDes, SerDesProtocol, SerDesNumLanes, Config);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a: SERDES%d[PRTCL] = 0x%x is not valid, Status = %r \n",
            __FUNCTION__, SerDes + 1, SerDesProtocol, Status));
    return Status;
  }
 
  for (Lane = 0; Lane < SerDesNumLanes; Lane++) {
    LaneProtocol = GetSerDesProtocol (SerDes, SerDesProtocol, Lane, SerDesMaxProtocol, Config);
    if (LaneProtocol >= SerDesMaxProtocol) {
      DEBUG ((DEBUG_ERROR, "Unknown SerDes lane protocol %d\n", LaneProtocol));
      return EFI_NO_MAPPING;
    }
    *SerDesProtocolMap |= (BIT0 << (LaneProtocol));
  }
 
  return EFI_SUCCESS;
}