1 /********************************************************************************
2 Copyright (C) 2016 Marvell International Ltd.
3
4 Marvell BSD License Option
5
6 If you received this File from Marvell, you may opt to use, redistribute and/or
7 modify this File under the following licensing terms.
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
10
11 * Redistributions of source code must Retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13
14 * Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 * Neither the name of Marvell nor the names of its contributors may be
19 used to endorse or promote products derived from this software without
20 specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 *******************************************************************************/
34
35 #include "ComPhyLib.h"
36
37 #define SD_LANE_ADDR_WIDTH 0x1000
38 #define HPIPE_ADDR_OFFSET 0x800
39 #define COMPHY_ADDR_LANE_WIDTH 0x28
40 #define SD_ADDR(base, Lane) (base + SD_LANE_ADDR_WIDTH * Lane)
41 #define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + HPIPE_ADDR_OFFSET)
42 #define COMPHY_ADDR(base, Lane) (base + COMPHY_ADDR_LANE_WIDTH * Lane)
43
44 /*
45 * For CP-110 we have 2 Selector registers "PHY Selectors"
46 * and " PIPE Selectors".
47 * PIPE selector include USB and PCIe options.
48 * PHY selector include the Ethernet and SATA options, every Ethernet option
49 * has different options, for example: serdes Lane2 had option Eth_port_0
50 * that include (SGMII0, XAUI0, RXAUI0, KR)
51 */
52 COMPHY_MUX_DATA Cp110ComPhyMuxData[] = {
53 /* Lane 0 */
54 {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII2, 0x1},
55 {PHY_TYPE_XAUI2, 0x1}, {PHY_TYPE_SATA1, 0x4} } },
56 /* Lane 1 */
57 {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII3, 0x1},
58 {PHY_TYPE_XAUI3, 0x1}, {PHY_TYPE_SATA1, 0x4} } },
59 /* Lane 2 */
60 {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1},
61 {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1},
62 {PHY_TYPE_SATA0, 0x4} } },
63 /* Lane 3 */
64 {8, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1},
65 {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1},
66 {PHY_TYPE_XAUI1, 0x1}, {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SATA1, 0x4} } },
67 /* Lane 4 */
68 {7, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x2},
69 {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1},
70 {PHY_TYPE_SGMII2, 0x1}, {PHY_TYPE_XAUI2, 0x1} } },
71 /* Lane 5 */
72 {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_XAUI1, 0x1},
73 {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SGMII3, 0x1}, {PHY_TYPE_XAUI3, 0x1},
74 {PHY_TYPE_SATA1, 0x4} } },
75 };
76
77 COMPHY_MUX_DATA Cp110ComPhyPipeMuxData[] = {
78 /* Lane 0 */
79 {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PCIE0, 0x4} } },
80 /* Lane 1 */
81 {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST0, 0x1},
82 {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PCIE0, 0x4} } },
83 /* Lane 2 */
84 {3, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST0, 0x1},
85 {PHY_TYPE_PCIE0, 0x4} } },
86 /* Lane 3 */
87 {3, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST1, 0x1},
88 {PHY_TYPE_PCIE0, 0x4} } },
89 /* Lane 4 */
90 {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST1, 0x1},
91 {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PCIE1, 0x4} } },
92 /* Lane 5 */
93 {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PCIE2, 0x4} } },
94 };
95
96 STATIC
97 VOID
ComPhyPcieRFUConfiguration(IN EFI_PHYSICAL_ADDRESS ComPhyAddr)98 ComPhyPcieRFUConfiguration (
99 IN EFI_PHYSICAL_ADDRESS ComPhyAddr
100 )
101 {
102 UINT32 Mask, Data;
103
104 /* RFU configurations - hard reset ComPhy */
105 Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
106 Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
107 Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
108 Data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
109 Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
110 Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
111 Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
112 Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
113 Mask |= COMMON_PHY_PHY_MODE_MASK;
114 Data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
115 RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
116
117 /* Release from hard reset */
118 Mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
119 Data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
120 Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
121 Data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
122 RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
123
124 /* Wait 1ms - until band gap and ref clock ready */
125 MicroSecondDelay (1000);
126 MemoryFence ();
127 }
128
129 STATIC
130 VOID
ComPhyPciePhyConfiguration(IN EFI_PHYSICAL_ADDRESS ComPhyAddr,IN EFI_PHYSICAL_ADDRESS HpipeAddr)131 ComPhyPciePhyConfiguration (
132 IN EFI_PHYSICAL_ADDRESS ComPhyAddr,
133 IN EFI_PHYSICAL_ADDRESS HpipeAddr
134 )
135 {
136 UINT32 Mask, Data, PcieClk = 0;
137
138 /* Set PIPE soft reset */
139 Mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
140 Data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
141
142 /* Set PHY Datapath width mode for V0 */
143 Mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
144 Data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
145
146 /* Set Data bus width USB mode for V0 */
147 Mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
148 Data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
149
150 /* Set CORE_CLK output frequency for 250Mhz */
151 Mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
152 Data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
153 RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, Data, Mask);
154
155 /* Set PLL ready delay for 0x2 */
156 RegSet (HpipeAddr + HPIPE_CLK_SRC_LO_REG,
157 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
158 HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
159
160 /* Set PIPE mode interface to PCIe3 - 0x1 */
161 RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
162 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET, HPIPE_CLK_SRC_HI_MODE_PIPE_MASK);
163
164 /* Config update polarity equalization */
165 RegSet (HpipeAddr + HPIPE_LANE_EQ_CFG1_REG,
166 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET, HPIPE_CFG_UPDATE_POLARITY_MASK);
167
168 /* Set PIPE version 4 to mode enable */
169 RegSet (HpipeAddr + HPIPE_DFE_CTRL_28_REG,
170 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET, HPIPE_DFE_CTRL_28_PIPE4_MASK);
171
172 /* Enable PIN clock 100M_125M */
173 Mask = HPIPE_MISC_CLK100M_125M_MASK;
174 Data = 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
175
176 /* Set PIN_TXDCLK_2X Clock Frequency Selection for outputs 500MHz clock */
177 Mask |= HPIPE_MISC_TXDCLK_2X_MASK;
178 Data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
179
180 /* Enable 500MHz Clock */
181 Mask |= HPIPE_MISC_CLK500_EN_MASK;
182 Data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
183
184 if (PcieClk) {
185 /* Set reference clock comes from group 1 */
186 Mask |= HPIPE_MISC_REFCLK_SEL_MASK;
187 Data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
188 } else {
189 /* Set reference clock comes from group 2 */
190 Mask |= HPIPE_MISC_REFCLK_SEL_MASK;
191 Data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
192 }
193 RegSet (HpipeAddr + HPIPE_MISC_REG, Data, Mask);
194
195 if (PcieClk) {
196 /* Set reference frequcency select - 0x2 for 25MHz*/
197 Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
198 Data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
199 } else {
200 /* Set reference frequcency select - 0x0 for 100MHz*/
201 Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
202 Data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
203 }
204
205 /* Set PHY mode to PCIe */
206 Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
207 Data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
208 RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
209
210 /*
211 * Set the amount of time spent in the LoZ state - set
212 * for 0x7 only if the PCIe clock is output
213 */
214 if (PcieClk)
215 RegSet (HpipeAddr + HPIPE_GLOBAL_PM_CTRL,
216 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
217 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
218
219 /* Set Maximal PHY Generation Setting (8Gbps) */
220 Mask = HPIPE_INTERFACE_GEN_MAX_MASK;
221 Data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
222
223 /* Set Link Train Mode (Tx training control pins are used) */
224 Mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
225 Data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
226 RegSet (HpipeAddr + HPIPE_INTERFACE_REG, Data, Mask);
227
228 /* Set Idle_sync enable */
229 Mask = HPIPE_PCIE_IDLE_SYNC_MASK;
230 Data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
231
232 /* Select bits for PCIE Gen3(32bit) */
233 Mask |= HPIPE_PCIE_SEL_BITS_MASK;
234 Data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
235 RegSet (HpipeAddr + HPIPE_PCIE_REG0, Data, Mask);
236
237 /* Enable Tx_adapt_g1 */
238 Mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
239 Data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
240
241 /* Enable Tx_adapt_gn1 */
242 Mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
243 Data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
244
245 /* Disable Tx_adapt_g0 */
246 Mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
247 Data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
248 RegSet (HpipeAddr + HPIPE_TX_TRAIN_CTRL_REG, Data, Mask);
249
250 /* Set reg_tx_train_chk_init */
251 Mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
252 Data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
253
254 /* Enable TX_COE_FM_PIN_PCIE3_EN */
255 Mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
256 Data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
257 RegSet (HpipeAddr + HPIPE_TX_TRAIN_REG, Data, Mask);
258 }
259
260 STATIC
261 VOID
ComPhyPciePhyPowerUp(IN EFI_PHYSICAL_ADDRESS HpipeAddr)262 ComPhyPciePhyPowerUp (
263 IN EFI_PHYSICAL_ADDRESS HpipeAddr
264 )
265 {
266 /* Release from PIPE soft reset */
267 RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
268 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
269 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
270
271 /* Wait 15ms - for ComPhy calibration done */
272 MicroSecondDelay (15000);
273 MemoryFence ();
274 }
275
276 STATIC
277 EFI_STATUS
ComPhyPcieCheckPll(IN EFI_PHYSICAL_ADDRESS HpipeAddr)278 ComPhyPcieCheckPll (
279 IN EFI_PHYSICAL_ADDRESS HpipeAddr
280 )
281 {
282 EFI_STATUS Status = EFI_SUCCESS;
283 UINT32 Data;
284
285 /* Read Lane status */
286 Data = MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG);
287 if ((Data & HPIPE_LANE_STATUS0_PCLK_EN_MASK) == 0) {
288 DEBUG((DEBUG_INFO, "ComPhy: Read from reg = %p - value = 0x%x\n",
289 HpipeAddr + HPIPE_LANE_STATUS0_REG, Data));
290 DEBUG((DEBUG_INFO, "ComPhy: HPIPE_LANE_STATUS0_PCLK_EN_MASK is 0\n"));
291 Status = EFI_D_ERROR;
292 }
293
294 return Status;
295 }
296
297 STATIC
298 EFI_STATUS
ComPhyPciePowerUp(IN UINT32 Lane,IN UINT32 PcieBy4,IN EFI_PHYSICAL_ADDRESS HpipeBase,IN EFI_PHYSICAL_ADDRESS ComPhyBase)299 ComPhyPciePowerUp (
300 IN UINT32 Lane,
301 IN UINT32 PcieBy4,
302 IN EFI_PHYSICAL_ADDRESS HpipeBase,
303 IN EFI_PHYSICAL_ADDRESS ComPhyBase
304 )
305 {
306 EFI_STATUS Status = EFI_SUCCESS;
307 EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
308 EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
309
310 DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
311
312 ComPhyPcieRFUConfiguration (ComPhyAddr);
313
314 DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
315
316 ComPhyPciePhyConfiguration (ComPhyAddr, HpipeAddr);
317
318 DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
319
320 ComPhyPciePhyPowerUp (HpipeAddr);
321
322 DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
323
324 Status = ComPhyPcieCheckPll (HpipeAddr);
325
326 return Status;
327 }
328
329 STATIC
330 VOID
ComPhyUsb3RFUConfiguration(IN EFI_PHYSICAL_ADDRESS ComPhyAddr)331 ComPhyUsb3RFUConfiguration (
332 IN EFI_PHYSICAL_ADDRESS ComPhyAddr
333 )
334 {
335 UINT32 Mask, Data;
336
337 /* RFU configurations - hard reset ComPhy */
338 Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
339 Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
340 Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
341 Data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
342 Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
343 Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
344 Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
345 Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
346 Mask |= COMMON_PHY_PHY_MODE_MASK;
347 Data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
348 RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
349
350 /* Release from hard reset */
351 Mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
352 Data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
353 Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
354 Data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
355 RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
356
357 /* Wait 1ms - until band gap and ref clock ready */
358 MicroSecondDelay (1000);
359 MemoryFence ();
360 }
361
362 STATIC
363 VOID
ComPhyUsb3PhyConfiguration(IN EFI_PHYSICAL_ADDRESS HpipeAddr)364 ComPhyUsb3PhyConfiguration (
365 IN EFI_PHYSICAL_ADDRESS HpipeAddr
366 )
367 {
368 UINT32 Mask, Data;
369
370 /* Set PIPE soft reset */
371 Mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
372 Data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
373
374 /* Set PHY Datapath width mode for V0 */
375 Mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
376 Data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
377
378 /* Set Data bus width USB mode for V0 */
379 Mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
380 Data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
381
382 /* Set CORE_CLK output frequency for 250Mhz */
383 Mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
384 Data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
385 RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, Data, Mask);
386
387 /* Set PLL ready delay for 0x2 */
388 RegSet (HpipeAddr + HPIPE_CLK_SRC_LO_REG,
389 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
390 HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
391
392 /* Set reference clock to come from group 1 - 25Mhz */
393 RegSet (HpipeAddr + HPIPE_MISC_REG, 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
394 HPIPE_MISC_REFCLK_SEL_MASK);
395
396 /* Set reference frequcency select - 0x2 */
397 Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
398 Data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
399
400 /* Set PHY mode to USB - 0x5 */
401 Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
402 Data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
403 RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
404
405 /* Set the amount of time spent in the LoZ state - set for 0x7 */
406 RegSet (HpipeAddr + HPIPE_GLOBAL_PM_CTRL,
407 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
408 HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
409
410 /* Set max PHY generation setting - 5Gbps */
411 RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
412 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
413
414 /* Set select Data width 20Bit (SEL_BITS[2:0]) */
415 RegSet (HpipeAddr + HPIPE_LOOPBACK_REG,
416 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
417 }
418
419 STATIC
420 VOID
ComPhyUsb3SetAnalogParameters(IN EFI_PHYSICAL_ADDRESS HpipeAddr)421 ComPhyUsb3SetAnalogParameters (
422 IN EFI_PHYSICAL_ADDRESS HpipeAddr
423 )
424 {
425 UINT32 Data, Mask;
426
427 /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
428 Mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
429 Data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
430
431 /* Set Override PHY DFE control pins for 0x1 */
432 Mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
433 Data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
434
435 /* Set Spread Spectrum Clock Enable fot 0x1 */
436 Mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
437 Data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
438 RegSet (HpipeAddr + HPIPE_LANE_CFG4_REG, Data, Mask);
439 }
440
441 STATIC
442 UINTN
ComphyUsb3PowerUp(UINT32 Lane,EFI_PHYSICAL_ADDRESS HpipeBase,EFI_PHYSICAL_ADDRESS ComPhyBase)443 ComphyUsb3PowerUp (
444 UINT32 Lane,
445 EFI_PHYSICAL_ADDRESS HpipeBase,
446 EFI_PHYSICAL_ADDRESS ComPhyBase
447 )
448 {
449 EFI_STATUS Status = EFI_SUCCESS;
450 UINT32 Data;
451 EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
452 EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
453
454 DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
455
456 ComPhyUsb3RFUConfiguration (ComPhyAddr);
457
458 /* Start ComPhy Configuration */
459 DEBUG((DEBUG_INFO, "stage: Comphy configuration\n"));
460
461 ComPhyUsb3PhyConfiguration (HpipeAddr);
462
463 /* Start analog paramters from ETP(HW) */
464 DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
465
466 ComPhyUsb3SetAnalogParameters (HpipeAddr);
467
468 DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy power up\n"));
469
470 /* Release from PIPE soft reset */
471 RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
472 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
473 HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
474
475 /* Wait 15ms - for ComPhy calibration done */
476 MicroSecondDelay (15000);
477 MemoryFence ();
478
479 DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
480
481 /* Read Lane status */
482 Data = MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG);
483 if ((Data & HPIPE_LANE_STATUS0_PCLK_EN_MASK) == 0) {
484 DEBUG((DEBUG_ERROR, "ComPhy: HPIPE_LANE_STATUS0_PCLK_EN_MASK is 0\n"));
485 Status = EFI_D_ERROR;
486 }
487
488 return Status;
489 }
490
491 STATIC
492 UINT32
PollingWithTimeout(IN EFI_PHYSICAL_ADDRESS Addr,IN UINT32 Val,IN UINT32 Mask,IN UINT64 Usec_timeout)493 PollingWithTimeout (
494 IN EFI_PHYSICAL_ADDRESS Addr,
495 IN UINT32 Val,
496 IN UINT32 Mask,
497 IN UINT64 Usec_timeout
498 )
499 {
500 UINT32 Data;
501
502 do {
503 MicroSecondDelay(1);
504 Data = MmioRead32(Addr) & Mask;
505 } while (Data != Val && --Usec_timeout > 0);
506
507 if (Usec_timeout == 0)
508 return Data;
509 return 0;
510 }
511
512 STATIC
513 VOID
ComPhySataMacPowerDown(IN EFI_PHYSICAL_ADDRESS SataBase)514 ComPhySataMacPowerDown (
515 IN EFI_PHYSICAL_ADDRESS SataBase
516 )
517 {
518 UINT32 Mask, Data;
519
520 /*
521 * MAC configuration - power down ComPhy
522 * Use indirect address for vendor specific SATA control register
523 */
524 RegSet (SataBase + SATA3_VENDOR_ADDRESS,
525 SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, SATA3_VENDOR_ADDR_MASK);
526
527 /* SATA 0 power down */
528 Mask = SATA3_CTRL_SATA0_PD_MASK;
529 Data = 0x1 << SATA3_CTRL_SATA0_PD_OFFSET;
530
531 /* SATA 1 power down */
532 Mask |= SATA3_CTRL_SATA1_PD_MASK;
533 Data |= 0x1 << SATA3_CTRL_SATA1_PD_OFFSET;
534
535 /* SATA SSU disable */
536 Mask |= SATA3_CTRL_SATA1_ENABLE_MASK;
537 Data |= 0x0 << SATA3_CTRL_SATA1_ENABLE_OFFSET;
538
539 /* SATA port 1 disable */
540 Mask |= SATA3_CTRL_SATA_SSU_MASK;
541 Data |= 0x0 << SATA3_CTRL_SATA_SSU_OFFSET;
542 RegSet (SataBase + SATA3_VENDOR_DATA, Data, Mask);
543 }
544
545 STATIC
546 VOID
ComPhySataRFUConfiguration(IN EFI_PHYSICAL_ADDRESS ComPhyAddr,IN EFI_PHYSICAL_ADDRESS SdIpAddr)547 ComPhySataRFUConfiguration (
548 IN EFI_PHYSICAL_ADDRESS ComPhyAddr,
549 IN EFI_PHYSICAL_ADDRESS SdIpAddr
550 )
551 {
552 UINT32 Mask, Data;
553
554 /* RFU configurations - hard reset ComPhy */
555 Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
556 Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
557 Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
558 Data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
559 Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
560 Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
561 Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
562 Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
563 RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
564
565 /* Set select Data width 40Bit - SATA mode only */
566 RegSet (ComPhyAddr + COMMON_PHY_CFG6_REG,
567 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET, COMMON_PHY_CFG6_IF_40_SEL_MASK);
568
569 /* Release from hard reset in SD external */
570 Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
571 Data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
572 Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
573 Data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
574 RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
575
576 /* Wait 1ms - until band gap and ref clock ready */
577 MicroSecondDelay (1000);
578 MemoryFence ();
579 }
580
581 STATIC
582 VOID
ComPhySataPhyConfiguration(IN EFI_PHYSICAL_ADDRESS HpipeAddr)583 ComPhySataPhyConfiguration (
584 IN EFI_PHYSICAL_ADDRESS HpipeAddr
585 )
586 {
587 UINT32 Mask, Data;
588
589 /* Set reference clock to comes from group 1 - choose 25Mhz */
590 RegSet (HpipeAddr + HPIPE_MISC_REG,
591 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, HPIPE_MISC_REFCLK_SEL_MASK);
592
593 /* Reference frequency select set 1 (for SATA = 25Mhz) */
594 Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
595 Data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
596
597 /* PHY mode select (set SATA = 0x0 */
598 Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
599 Data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
600 RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
601
602 /* Set max PHY generation setting - 6Gbps */
603 RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
604 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
605
606 /* Set select Data width 40Bit (SEL_BITS[2:0]) */
607 RegSet (HpipeAddr + HPIPE_LOOPBACK_REG,
608 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
609 }
610
611 STATIC
612 VOID
ComPhySataSetAnalogParameters(IN EFI_PHYSICAL_ADDRESS HpipeAddr)613 ComPhySataSetAnalogParameters (
614 IN EFI_PHYSICAL_ADDRESS HpipeAddr
615 )
616 {
617 /* DFE reset sequence */
618 RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
619 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
620 RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
621 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
622
623 /* SW reset for interupt logic */
624 RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
625 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK);
626 RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
627 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK);
628 }
629
630 STATIC
631 VOID
ComPhySataPhyPowerUp(IN EFI_PHYSICAL_ADDRESS SataBase)632 ComPhySataPhyPowerUp (
633 IN EFI_PHYSICAL_ADDRESS SataBase
634 )
635 {
636 UINT32 Data, Mask;
637
638 /*
639 * MAC configuration - power up ComPhy - power up PLL/TX/RX
640 * Use indirect address for vendor specific SATA control register
641 */
642 RegSet (SataBase + SATA3_VENDOR_ADDRESS,
643 SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, SATA3_VENDOR_ADDR_MASK);
644
645 /* SATA 0 power up */
646 Mask = SATA3_CTRL_SATA0_PD_MASK;
647 Data = 0x0 << SATA3_CTRL_SATA0_PD_OFFSET;
648
649 /* SATA 1 power up */
650 Mask |= SATA3_CTRL_SATA1_PD_MASK;
651 Data |= 0x0 << SATA3_CTRL_SATA1_PD_OFFSET;
652
653 /* SATA SSU enable */
654 Mask |= SATA3_CTRL_SATA1_ENABLE_MASK;
655 Data |= 0x1 << SATA3_CTRL_SATA1_ENABLE_OFFSET;
656
657 /* SATA port 1 enable */
658 Mask |= SATA3_CTRL_SATA_SSU_MASK;
659 Data |= 0x1 << SATA3_CTRL_SATA_SSU_OFFSET;
660 RegSet (SataBase + SATA3_VENDOR_DATA, Data, Mask);
661
662 /* MBUS request size and interface select register */
663 RegSet (SataBase + SATA3_VENDOR_ADDRESS,
664 SATA_MBUS_SIZE_SELECT_REG << SATA3_VENDOR_ADDR_OFSSET,
665 SATA3_VENDOR_ADDR_MASK);
666
667 /* Mbus regret enable */
668 RegSet (SataBase + SATA3_VENDOR_DATA, 0x1 << SATA_MBUS_REGRET_EN_OFFSET,
669 SATA_MBUS_REGRET_EN_MASK);
670 }
671
672 STATIC
673 EFI_STATUS
ComPhySataCheckPll(IN EFI_PHYSICAL_ADDRESS HpipeAddr,IN EFI_PHYSICAL_ADDRESS SdIpAddr)674 ComPhySataCheckPll (
675 IN EFI_PHYSICAL_ADDRESS HpipeAddr,
676 IN EFI_PHYSICAL_ADDRESS SdIpAddr
677 )
678 {
679 EFI_STATUS Status = EFI_SUCCESS;
680 UINT32 Data,Mask;
681 IN EFI_PHYSICAL_ADDRESS Addr;
682
683 Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG;
684 Data = SD_EXTERNAL_STATUS0_PLL_TX_MASK & SD_EXTERNAL_STATUS0_PLL_RX_MASK;
685 Mask = Data;
686 Data = PollingWithTimeout (Addr, Data, Mask, 15000);
687
688 if (Data != 0) {
689 DEBUG((DEBUG_INFO, "ComPhy: Read from reg = %p - value = 0x%x\n",
690 HpipeAddr + HPIPE_LANE_STATUS0_REG, Data));
691 DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_PLL_TX is %d, SD_EXTERNAL_STATUS0_PLL_RX is %d\n",
692 (Data & SD_EXTERNAL_STATUS0_PLL_TX_MASK),
693 (Data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)));
694 Status = EFI_D_ERROR;
695 }
696
697 return Status;
698 }
699
700 STATIC
701 UINTN
ComPhySataPowerUp(IN UINT32 Lane,IN EFI_PHYSICAL_ADDRESS HpipeBase,IN EFI_PHYSICAL_ADDRESS ComPhyBase)702 ComPhySataPowerUp (
703 IN UINT32 Lane,
704 IN EFI_PHYSICAL_ADDRESS HpipeBase,
705 IN EFI_PHYSICAL_ADDRESS ComPhyBase
706 )
707 {
708 EFI_STATUS Status;
709 EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
710 EFI_PHYSICAL_ADDRESS SdIpAddr = SD_ADDR(HpipeBase, Lane);
711 EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
712 EFI_PHYSICAL_ADDRESS SataBase;
713
714 SataBase = PcdGet32 (PcdSataBaseAddress);
715 if (SataBase == 0) {
716 DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n"));
717 return EFI_D_ERROR;
718 }
719
720 DEBUG((DEBUG_INFO, "ComPhySataPowerUp: stage: MAC configuration - power down ComPhy\n"));
721
722 ComPhySataMacPowerDown (SataBase);
723
724 DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
725
726 ComPhySataRFUConfiguration (ComPhyAddr, SdIpAddr);
727
728 DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n"));
729
730 ComPhySataPhyConfiguration (HpipeAddr);
731
732 DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
733
734 ComPhySataSetAnalogParameters (HpipeAddr);
735
736 DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
737
738 ComPhySataPhyPowerUp (SataBase);
739
740 DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
741
742 Status = ComPhySataCheckPll (HpipeAddr, SdIpAddr);
743
744 return Status;
745 }
746
747 STATIC
748 VOID
ComPhySgmiiRFUConfiguration(IN EFI_PHYSICAL_ADDRESS ComPhyAddr,IN EFI_PHYSICAL_ADDRESS SdIpAddr,IN UINT32 SgmiiSpeed)749 ComPhySgmiiRFUConfiguration (
750 IN EFI_PHYSICAL_ADDRESS ComPhyAddr,
751 IN EFI_PHYSICAL_ADDRESS SdIpAddr,
752 IN UINT32 SgmiiSpeed
753 )
754 {
755 UINT32 Mask, Data;
756
757 Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
758 Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
759 Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
760 Data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
761 RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
762
763 /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
764 Mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
765 Data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
766 Mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
767 Mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
768 if (SgmiiSpeed == PHY_SPEED_1_25G) {
769 Data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
770 Data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
771 } else {
772 /* 3.125G */
773 Data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
774 Data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
775 }
776 Mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
777 Data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
778 Mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
779 Data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
780 Mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
781 Data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
782 RegSet (SdIpAddr + SD_EXTERNAL_CONFIG0_REG, Data, Mask);
783
784 /* Release from hard reset */
785 Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
786 Data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
787 Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
788 Data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
789 Mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
790 Data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
791 RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
792
793 /* Release from hard reset */
794 Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
795 Data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
796 Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
797 Data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
798 RegSet (SdIpAddr+ SD_EXTERNAL_CONFIG1_REG, Data, Mask);
799
800 /* Wait 1ms - until band gap and ref clock ready */
801 MicroSecondDelay (1000);
802 MemoryFence ();
803 }
804
805 STATIC
806 VOID
ComPhySgmiiPhyConfiguration(IN EFI_PHYSICAL_ADDRESS HpipeAddr)807 ComPhySgmiiPhyConfiguration (
808 IN EFI_PHYSICAL_ADDRESS HpipeAddr
809 )
810 {
811 UINT32 Mask, Data;
812
813 /* Set reference clock */
814 Mask = HPIPE_MISC_REFCLK_SEL_MASK;
815 Data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
816 RegSet (HpipeAddr + HPIPE_MISC_REG, Data, Mask);
817
818 /* Power and PLL Control */
819 Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
820 Data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
821 Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
822 Data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
823 RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
824
825 /* Loopback register */
826 Mask = HPIPE_LOOPBACK_SEL_MASK;
827 Data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
828 RegSet (HpipeAddr + HPIPE_LOOPBACK_REG, Data, Mask);
829
830 /* Rx control 1 */
831 Mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
832 Data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
833 Mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
834 Data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
835 RegSet (HpipeAddr + HPIPE_RX_CONTROL_1_REG, Data, Mask);
836
837 /* DTL Control */
838 Mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
839 Data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
840 RegSet (HpipeAddr + HPIPE_PWR_CTR_DTL_REG, Data, Mask);
841 }
842
843 STATIC
844 EFI_STATUS
ComPhySgmiiRFUPowerUp(IN EFI_PHYSICAL_ADDRESS SdIpAddr)845 ComPhySgmiiRFUPowerUp (
846 IN EFI_PHYSICAL_ADDRESS SdIpAddr
847 )
848 {
849 EFI_STATUS Status = EFI_SUCCESS;
850 UINT32 Mask, Data;
851 EFI_PHYSICAL_ADDRESS Addr;
852
853 /* SerDes External Configuration */
854 Mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
855 Data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
856 Mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
857 Data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
858 Mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
859 Data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
860 RegSet (SdIpAddr + SD_EXTERNAL_CONFIG0_REG, Data, Mask);
861
862 /* Check PLL rx & tx ready */
863 Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG;
864 Data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | SD_EXTERNAL_STATUS0_PLL_TX_MASK;
865 Mask = Data;
866 Data = PollingWithTimeout (Addr, Data, Mask, 15000);
867 if (Data != 0) {
868 DEBUG((DEBUG_ERROR, "ComPhy: Read from reg = %p - value = 0x%x\n",
869 SdIpAddr + SD_EXTERNAL_STATUS0_REG, Data));
870 DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n",
871 (Data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
872 (Data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)));
873 Status = EFI_D_ERROR;
874 }
875
876 /* RX init */
877 Mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
878 Data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
879 RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
880
881 /* Check that RX init done */
882 Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG;
883 Data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
884 Mask = Data;
885 Data = PollingWithTimeout (Addr, Data, Mask, 100);
886 if (Data != 0) {
887 DEBUG((DEBUG_ERROR, "ComPhy: Read from reg = %p - value = 0x%x\n",
888 SdIpAddr + SD_EXTERNAL_STATUS0_REG, Data));
889 DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_RX_INIT is 0\n"));
890 Status = EFI_D_ERROR;
891 }
892 Mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
893 Data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
894 Mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
895 Data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
896 RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
897
898 return Status;
899 }
900
901 STATIC
902 UINTN
ComPhySgmiiPowerUp(IN UINT32 Lane,IN UINT32 SgmiiSpeed,IN EFI_PHYSICAL_ADDRESS HpipeBase,IN EFI_PHYSICAL_ADDRESS ComPhyBase)903 ComPhySgmiiPowerUp (
904 IN UINT32 Lane,
905 IN UINT32 SgmiiSpeed,
906 IN EFI_PHYSICAL_ADDRESS HpipeBase,
907 IN EFI_PHYSICAL_ADDRESS ComPhyBase
908 )
909 {
910 EFI_STATUS Status = EFI_SUCCESS;
911 EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
912 EFI_PHYSICAL_ADDRESS SdIpAddr = SD_ADDR(HpipeBase, Lane);
913 EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
914
915 DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
916
917 ComPhySgmiiRFUConfiguration (ComPhyAddr, SdIpAddr, SgmiiSpeed);
918
919 DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
920
921 ComPhySgmiiPhyConfiguration (HpipeAddr);
922
923 /* Set analog paramters from ETP(HW) - for now use the default data */
924 DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
925
926 RegSet (HpipeAddr + HPIPE_G1_SET_0_REG,
927 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
928
929 DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - Power Up PLL,Tx,Rx\n"));
930
931 Status = ComPhySgmiiRFUPowerUp (SdIpAddr);
932
933 return Status;
934 }
935
936 STATIC
937 VOID
ComPhyMuxCp110(IN CHIP_COMPHY_CONFIG * PtrChipCfg,IN COMPHY_MAP * SerdesMap)938 ComPhyMuxCp110 (
939 IN CHIP_COMPHY_CONFIG *PtrChipCfg,
940 IN COMPHY_MAP *SerdesMap
941 )
942 {
943 EFI_PHYSICAL_ADDRESS ComPhyBaseAddr;
944 COMPHY_MAP ComPhyMapPipeData[MAX_LANE_OPTIONS];
945 COMPHY_MAP ComPhyMapPhyData[MAX_LANE_OPTIONS];
946 UINT32 Lane, ComPhyMaxCount;
947
948 ComPhyMaxCount = PtrChipCfg->LanesCount;
949 ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr;
950
951 /*
952 * Copy the SerDes map configuration for PIPE map and PHY map.
953 * The ComPhyMuxInit modifies the Type of the Lane if the Type is not valid.
954 * Because we have 2 selectors, run the ComPhyMuxInit twice and after
955 * that, update the original SerdesMap.
956 */
957 for (Lane = 0; Lane < ComPhyMaxCount; Lane++) {
958 ComPhyMapPipeData[Lane].Type = SerdesMap[Lane].Type;
959 ComPhyMapPipeData[Lane].Speed = SerdesMap[Lane].Speed;
960 ComPhyMapPhyData[Lane].Type = SerdesMap[Lane].Type;
961 ComPhyMapPhyData[Lane].Speed = SerdesMap[Lane].Speed;
962 }
963 PtrChipCfg->MuxData = Cp110ComPhyMuxData;
964 ComPhyMuxInit(PtrChipCfg, ComPhyMapPhyData, ComPhyBaseAddr +
965 COMMON_SELECTOR_PHY_OFFSET);
966
967 PtrChipCfg->MuxData = Cp110ComPhyPipeMuxData;
968 ComPhyMuxInit(PtrChipCfg, ComPhyMapPipeData, ComPhyBaseAddr +
969 COMMON_SELECTOR_PIPE_OFFSET);
970
971 /* Fix the Type after check the PHY and PIPE configuration */
972 for (Lane = 0; Lane < ComPhyMaxCount; Lane++)
973 if ((ComPhyMapPipeData[Lane].Type == PHY_TYPE_UNCONNECTED) &&
974 (ComPhyMapPhyData[Lane].Type == PHY_TYPE_UNCONNECTED))
975 SerdesMap[Lane].Type = PHY_TYPE_UNCONNECTED;
976 }
977
978 EFI_STATUS
ComPhyCp110Init(IN CHIP_COMPHY_CONFIG * PtrChipCfg)979 ComPhyCp110Init (
980 IN CHIP_COMPHY_CONFIG *PtrChipCfg
981 )
982 {
983 EFI_STATUS Status;
984 COMPHY_MAP *PtrComPhyMap, *SerdesMap;
985 EFI_PHYSICAL_ADDRESS ComPhyBaseAddr, HpipeBaseAddr;
986 UINT32 ComPhyMaxCount, Lane;
987 UINT32 PcieBy4 = 1; // Indicating if first 4 lanes set to PCIE
988
989 ComPhyMaxCount = PtrChipCfg->LanesCount;
990 ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr;
991 HpipeBaseAddr = PtrChipCfg->Hpipe3BaseAddr;
992 SerdesMap = PtrChipCfg->MapData;
993
994 /* Config Comphy mux configuration */
995 ComPhyMuxCp110(PtrChipCfg, SerdesMap);
996
997 /* Check if the first 4 Lanes configured as By-4 */
998 for (Lane = 0, PtrComPhyMap = SerdesMap; Lane < 4; Lane++, PtrComPhyMap++) {
999 if (PtrComPhyMap->Type != PHY_TYPE_PCIE0) {
1000 PcieBy4 = 0;
1001 break;
1002 }
1003 }
1004
1005 for (Lane = 0, PtrComPhyMap = SerdesMap; Lane < ComPhyMaxCount;
1006 Lane++, PtrComPhyMap++) {
1007 DEBUG((DEBUG_INFO, "ComPhy: Initialize serdes number %d\n", Lane));
1008 DEBUG((DEBUG_INFO, "ComPhy: Serdes Type = 0x%x\n", PtrComPhyMap->Type));
1009 switch (PtrComPhyMap->Type) {
1010 case PHY_TYPE_UNCONNECTED:
1011 continue;
1012 break;
1013 case PHY_TYPE_PCIE0:
1014 case PHY_TYPE_PCIE1:
1015 case PHY_TYPE_PCIE2:
1016 case PHY_TYPE_PCIE3:
1017 Status = ComPhyPciePowerUp(Lane, PcieBy4, HpipeBaseAddr, ComPhyBaseAddr);
1018 break;
1019 case PHY_TYPE_SATA0:
1020 case PHY_TYPE_SATA1:
1021 case PHY_TYPE_SATA2:
1022 case PHY_TYPE_SATA3:
1023 Status = ComPhySataPowerUp(Lane, HpipeBaseAddr, ComPhyBaseAddr);
1024 break;
1025 case PHY_TYPE_USB3_HOST0:
1026 case PHY_TYPE_USB3_HOST1:
1027 Status = ComphyUsb3PowerUp(Lane, HpipeBaseAddr, ComPhyBaseAddr);
1028 break;
1029 case PHY_TYPE_SGMII0:
1030 case PHY_TYPE_SGMII1:
1031 case PHY_TYPE_SGMII2:
1032 case PHY_TYPE_SGMII3:
1033 Status = ComPhySgmiiPowerUp(Lane, PtrComPhyMap->Speed, HpipeBaseAddr,
1034 ComPhyBaseAddr);
1035 break;
1036 default:
1037 DEBUG((DEBUG_ERROR, "Unknown SerDes Type, skip initialize SerDes %d\n",
1038 Lane));
1039 break;
1040 }
1041 if (EFI_ERROR(Status))
1042 DEBUG((DEBUG_ERROR, "PLL is not locked - Failed to initialize Lane %d\n",
1043 Lane));
1044 }
1045
1046 return EFI_SUCCESS;
1047 }
1048