• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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