summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c
blob: 0735fd678af484a2f919410b93cd395f32def053 (plain)
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
/** @file

  PCH USB precondition feature support in PEI phase

@copyright
  Copyright (c) 2012 Intel Corporation. All rights reserved
  This software and associated documentation (if any) is furnished
  under a license and may only be used or copied in accordance
  with the terms of the license. Except as permitted by such
  license, no part of this software or documentation may be
  reproduced, stored in a retrieval system, or transmitted in any
  form or by any means without the express written consent of
  Intel Corporation.

  This file contains an 'Intel Peripheral Driver' and uniquely
  identified as "Intel Reference Module" and is
  licensed for Intel CPUs and chipsets under the terms of your
  license agreement with Intel or your vendor.  This file may
  be modified by the user, subject to additional terms of the
  license agreement
**/
#include "PchInitPeim.h"

#ifdef USB_PRECONDITION_ENABLE_FLAG

extern USB_CONTROLLER EhciControllersMap[];

/**
  Perform USB precondition on EHCI, it is the HC on USB HC in PEI phase

  @param[in]  Device              The device number of the EHCI
  @param[in]  EhciMmioBase        Memory base address of EHCI Controller

  @retval     None
**/
VOID
EhciPrecondition (
  IN  UINT8                       Device,
  IN  UINT32                      EhciMmioBase
  )
{
  UINTN                     HcResetTimeout;

  HcResetTimeout = 0;
  while ((HcResetTimeout < 200) &&
    (MmioRead32 (EhciMmioBase + R_PCH_EHCI_USB2CMD) & B_PCH_EHCI_USB2CMD_HCRESET)) {
    PchPmTimerStall (100);
    HcResetTimeout++;
  }

  if ((MmioRead32 (EhciMmioBase + R_PCH_EHCI_USB2CMD) & B_PCH_EHCI_USB2CMD_HCRESET) == 0) {
    //
    // Route all ports to this EHCI
    //
    MmioWrite32 ((EhciMmioBase + R_PCH_EHCI_CONFIGFLAG), BIT0);
  }
}

/**
  Perform USB precondition on XHCI, it is the HC on USB HC in PEI phase

  @param[in]  BusNumber           The Bus number of the XHCI
  @param[in]  Device              The device number of the XHCI
  @param[in]  Function            The function number of the XHCI
  @param[in]  XhciMmioBase        Memory base address of XHCI Controller
  @param[in]  XhciUSB2Ptr         Pointer to USB2 protocol port register
  @param[in]  HsPortCount         The number of USB2 protocol port supported by this XHCI

  @retval     None
**/
VOID
XhciPrecondition (
  IN  UINT8                       BusNumber,
  IN  UINT8                       Device,
  IN  UINT8                       Function,
  IN  UINT32                      XhciMmioBase,
  IN  UINTN                       *XhciUSB2Ptr,
  IN  UINTN                       HsPortCount,
  IN  UINTN                       *XhciUSB3Ptr,
  IN  UINTN                       SsPortCount
  )
{
  UINT32                    Data32;
  UINTN                     HcHaltTimeout;

  //
  // Set the XHC to halt state before reset
  //
  HcHaltTimeout = 0;
  if (!(MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBSTS) & BIT0)) {
    Data32 = MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBCMD);
    MmioWrite32 ((XhciMmioBase + R_PCH_XHCI_USBCMD), (Data32 &~B_PCH_XHCI_USBCMD_RS));
    while ((HcHaltTimeout < 200) &&
           (!(MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBSTS) & BIT0))) {
      PchPmTimerStall (100);
      HcHaltTimeout++;
    }
  }

  if (MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBSTS) & BIT0) {
    MmioOr16 ((XhciMmioBase + R_PCH_XHCI_USBCMD), BIT1);
  }
}

#endif  // USB_PRECONDITION_ENABLE_FLAG