1 /** @file
2   PCH Serial IO Lib implementation Cannon Lake specific.
3   All function in this library is available for PEI, DXE, and SMM,
4   But do not support UEFI RUNTIME environment call.
5 
6   Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
7 
8   SPDX-License-Identifier: BSD-2-Clause-Patent
9 **/
10 
11 #include <Base.h>
12 #include <Uefi/UefiBaseType.h>
13 #include <Library/IoLib.h>
14 #include <Library/BaseLib.h>
15 #include <IndustryStandard/Pci30.h>
16 #include <Library/PchPcrLib.h>
17 #include <Library/PchInfoLib.h>
18 #include <Library/PciSegmentLib.h>
19 #include <Library/PcdLib.h>
20 #include <Private/Library/GpioPrivateLib.h>
21 #include <Library/PchSerialIoLib.h>
22 #include <Private/Library/PchPsfPrivateLib.h>
23 
24 #include <PchLimits.h>
25 #include <Register/PchRegsSerialIoCnl.h>
26 #include "PchSerialIoLibInternal.h"
27 
28 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mCnlAcpiHid[PCH_MAX_SERIALIO_CONTROLLERS][SERIALIO_HID_LENGTH] =
29 {
30   "INT34B2",
31   "INT34B3",
32   "INT34B4",
33   "INT34B5",
34   "INT34B6",
35   "INT34B7",
36   "INT34B0",
37   "INT34B1",
38   "INT34BC",
39   "INT34B8",
40   "INT34B9",
41   "INT34BA"
42 };
43 
44 GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchLpSerialIoId [PCH_MAX_SERIALIO_CONTROLLERS] =
45 {
46   V_CNL_PCH_LP_SERIAL_IO_CFG_I2C0_DEVICE_ID,
47   V_CNL_PCH_LP_SERIAL_IO_CFG_I2C1_DEVICE_ID,
48   V_CNL_PCH_LP_SERIAL_IO_CFG_I2C2_DEVICE_ID,
49   V_CNL_PCH_LP_SERIAL_IO_CFG_I2C3_DEVICE_ID,
50   V_CNL_PCH_LP_SERIAL_IO_CFG_I2C4_DEVICE_ID,
51   V_CNL_PCH_LP_SERIAL_IO_CFG_I2C5_DEVICE_ID,
52   V_CNL_PCH_LP_SERIAL_IO_CFG_SPI0_DEVICE_ID,
53   V_CNL_PCH_LP_SERIAL_IO_CFG_SPI1_DEVICE_ID,
54   V_CNL_PCH_LP_SERIAL_IO_CFG_UART0_DEVICE_ID,
55   V_CNL_PCH_LP_SERIAL_IO_CFG_UART1_DEVICE_ID,
56   V_CNL_PCH_LP_SERIAL_IO_CFG_UART2_DEVICE_ID
57 };
58 
59 GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mCnlPchHSerialIoId [PCH_MAX_SERIALIO_CONTROLLERS] =
60 {
61   V_CNL_PCH_H_SERIAL_IO_CFG_I2C0_DEVICE_ID,
62   V_CNL_PCH_H_SERIAL_IO_CFG_I2C1_DEVICE_ID,
group_tracks(tracks)63   V_CNL_PCH_H_SERIAL_IO_CFG_I2C2_DEVICE_ID,
64   V_CNL_PCH_H_SERIAL_IO_CFG_I2C3_DEVICE_ID,
65                                          0,
66                                          0,
67   V_CNL_PCH_H_SERIAL_IO_CFG_SPI0_DEVICE_ID,
68   V_CNL_PCH_H_SERIAL_IO_CFG_SPI1_DEVICE_ID,
69   V_CNL_PCH_H_SERIAL_IO_CFG_UART0_DEVICE_ID,
70   V_CNL_PCH_H_SERIAL_IO_CFG_UART1_DEVICE_ID,
71   V_CNL_PCH_H_SERIAL_IO_CFG_UART2_DEVICE_ID
72 };
73 
74 GLOBAL_REMOVE_IF_UNREFERENCED SERIAL_IO_BDF_NUMBERS mSerialIoBdf [PCH_MAX_SERIALIO_CONTROLLERS] =
75 {
76   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C0,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C0},
77   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C1,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C1},
78   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C2,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C2},
79   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C3,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C3},
80   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C4,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C4},
81   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_I2C5,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_I2C5},
82   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI0,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI0},
83   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_SPI1,  PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_SPI1},
84   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART0, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART0},
85   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART1, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART1},
86   {PCI_DEVICE_NUMBER_PCH_SERIAL_IO_UART2, PCI_FUNCTION_NUMBER_PCH_SERIAL_IO_UART2}
87 };
88 
89 
90 /**
91   Returns index of the last i2c controller
92 
93   @param[in] Number                     Number of SerialIo controller
94 
95   @retval                               Index of I2C controller
96 **/
97 PCH_SERIAL_IO_CONTROLLER
98 GetMaxI2cNumber (
99   VOID
100   )
101 {
102   if (IsPchH ()) {
103     return PchSerialIoIndexI2C3;
104   } else {
105     return PchSerialIoIndexI2C5;
106   }
107 }
108 
109 /**
110   Checks if Device with given PciDeviceId is one of SerialIo controllers
111   If yes, its number is returned through Number parameter, otherwise Number is not updated
112 
113   @param[in]  PciDevId                  Device ID
114   @param[out] Number                    Number of SerialIo controller
115 
116   @retval TRUE                          Yes it is a SerialIo controller
117   @retval FALSE                         No it isn't a SerialIo controller
118 **/
119 BOOLEAN
120 IsSerialIoPciDevId (
121   IN  UINT16                    PciDevId,
122   OUT PCH_SERIAL_IO_CONTROLLER  *Number
123   )
124 {
125   PCH_SERIAL_IO_CONTROLLER Controller;
126 
127   for (Controller = 0; Controller < GetPchMaxSerialIoControllersNum (); Controller++) {
128     if ((IsPchLp () && (PciDevId == mCnlPchLpSerialIoId[Controller])) ||
129         (IsPchH () && (PciDevId == mCnlPchHSerialIoId[Controller])))
130     {
131       *Number = Controller;
132       return TRUE;
133     }
134   }
135   return FALSE;
136 }
137 
138 /**
139   Finds PCI Device Number of SerialIo devices.
140 
141   @param[in] SerialIoNumber             Serial IO device
142 
143   @retval                               SerialIo device number
144 **/
145 UINT8
146 GetSerialIoDeviceNumber (
147   IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
148   )
149 {
150   return mSerialIoBdf[SerialIoNumber].DevNum;
151 }
152 
153 /**
154   Finds PCI Function Number of SerialIo devices.
155 
156   @param[in] SerialIoNumber             Serial IO device
157 
158   @retval                               SerialIo funciton number
159 **/
160 UINT8
161 GetSerialIoFunctionNumber (
162   IN PCH_SERIAL_IO_CONTROLLER  SerialIoNumber
163   )
164 {
165   return mSerialIoBdf[SerialIoNumber].FuncNum;
166 }
167 
168 /**
169   Returns string with AcpiHid assigned to selected SerialIo controller
170 
171   @param[in] Number                     Number of SerialIo controller
172 
173   @retval                               pointer to 8-byte string
174 **/
175 CHAR8*
176 GetSerialIoAcpiHid (
177   IN PCH_SERIAL_IO_CONTROLLER Number
178   )
179 {
180   return mCnlAcpiHid[Number];
181 }
182