1 /** @file 2 Serial I/O Port library functions with no library constructor/destructor 3 4 Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> 5 Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR> 6 7 This program and the accompanying materials 8 are licensed and made available under the terms and conditions of the BSD License 9 which accompanies this distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15 **/ 16 17 #include <Library/DebugLib.h> 18 #include <Library/IoLib.h> 19 #include <Library/PcdLib.h> 20 21 #include <Drivers/PL011Uart.h> 22 23 // 24 // EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE is the only 25 // control bit that is not supported. 26 // 27 STATIC CONST UINT32 mInvalidControlBits = EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; 28 29 /* 30 31 Initialise the serial port to the specified settings. 32 All unspecified settings will be set to the default values. 33 34 @return Always return EFI_SUCCESS or EFI_INVALID_PARAMETER. 35 36 **/ 37 RETURN_STATUS 38 EFIAPI 39 PL011UartInitializePort ( 40 IN OUT UINTN UartBase, 41 IN OUT UINT64 *BaudRate, 42 IN OUT UINT32 *ReceiveFifoDepth, 43 IN OUT EFI_PARITY_TYPE *Parity, 44 IN OUT UINT8 *DataBits, 45 IN OUT EFI_STOP_BITS_TYPE *StopBits 46 ) 47 { 48 UINT32 LineControl; 49 UINT32 Divisor; 50 51 LineControl = 0; 52 53 // The PL011 supports a buffer of 1, 16 or 32 chars. Therefore we can accept 54 // 1 char buffer as the minimum fifo size. Because everything can be rounded down, 55 // there is no maximum fifo size. 56 if ((*ReceiveFifoDepth == 0) || (*ReceiveFifoDepth >= 32)) { 57 LineControl |= PL011_UARTLCR_H_FEN; 58 if (PL011_UARTPID2_VER (MmioRead32 (UartBase + UARTPID2)) > PL011_VER_R1P4) 59 *ReceiveFifoDepth = 32; 60 else 61 *ReceiveFifoDepth = 16; 62 } else { 63 ASSERT (*ReceiveFifoDepth < 32); 64 // Nothing else to do. 1 byte fifo is default. 65 *ReceiveFifoDepth = 1; 66 } 67 68 // 69 // Parity 70 // 71 switch (*Parity) { 72 case DefaultParity: 73 *Parity = NoParity; 74 case NoParity: 75 // Nothing to do. Parity is disabled by default. 76 break; 77 case EvenParity: 78 LineControl |= (PL011_UARTLCR_H_PEN | PL011_UARTLCR_H_EPS); 79 break; 80 case OddParity: 81 LineControl |= PL011_UARTLCR_H_PEN; 82 break; 83 case MarkParity: 84 LineControl |= (PL011_UARTLCR_H_PEN | PL011_UARTLCR_H_SPS | PL011_UARTLCR_H_EPS); 85 break; 86 case SpaceParity: 87 LineControl |= (PL011_UARTLCR_H_PEN | PL011_UARTLCR_H_SPS); 88 break; 89 default: 90 return RETURN_INVALID_PARAMETER; 91 } 92 93 // 94 // Data Bits 95 // 96 switch (*DataBits) { 97 case 0: 98 *DataBits = 8; 99 case 8: 100 LineControl |= PL011_UARTLCR_H_WLEN_8; 101 break; 102 case 7: 103 LineControl |= PL011_UARTLCR_H_WLEN_7; 104 break; 105 case 6: 106 LineControl |= PL011_UARTLCR_H_WLEN_6; 107 break; 108 case 5: 109 LineControl |= PL011_UARTLCR_H_WLEN_5; 110 break; 111 default: 112 return RETURN_INVALID_PARAMETER; 113 } 114 115 // 116 // Stop Bits 117 // 118 switch (*StopBits) { 119 case DefaultStopBits: 120 *StopBits = OneStopBit; 121 case OneStopBit: 122 // Nothing to do. One stop bit is enabled by default. 123 break; 124 case TwoStopBits: 125 LineControl |= PL011_UARTLCR_H_STP2; 126 break; 127 case OneFiveStopBits: 128 // Only 1 or 2 stops bits are supported 129 default: 130 return RETURN_INVALID_PARAMETER; 131 } 132 133 // Don't send the LineControl value to the PL011 yet, 134 // wait until after the Baud Rate setting. 135 // This ensures we do not mess up the UART settings halfway through 136 // in the rare case when there is an error with the Baud Rate. 137 138 // 139 // Baud Rate 140 // 141 142 // If PL011 Integral value has been defined then always ignore the BAUD rate 143 if (PcdGet32 (PL011UartInteger) != 0) { 144 MmioWrite32 (UartBase + UARTIBRD, PcdGet32 (PL011UartInteger)); 145 MmioWrite32 (UartBase + UARTFBRD, PcdGet32 (PL011UartFractional)); 146 } else { 147 // If BAUD rate is zero then replace it with the system default value 148 if (*BaudRate == 0) { 149 *BaudRate = PcdGet32 (PcdSerialBaudRate); 150 ASSERT (*BaudRate != 0); 151 } 152 153 Divisor = (PcdGet32 (PL011UartClkInHz) * 4) / *BaudRate; 154 MmioWrite32 (UartBase + UARTIBRD, Divisor >> 6); 155 MmioWrite32 (UartBase + UARTFBRD, Divisor & 0x3F); 156 } 157 158 // No parity, 1 stop, no fifo, 8 data bits 159 MmioWrite32 (UartBase + UARTLCR_H, LineControl); 160 161 // Clear any pending errors 162 MmioWrite32 (UartBase + UARTECR, 0); 163 164 // Enable tx, rx, and uart overall 165 MmioWrite32 (UartBase + UARTCR, PL011_UARTCR_RXE | PL011_UARTCR_TXE | PL011_UARTCR_UARTEN); 166 167 return RETURN_SUCCESS; 168 } 169 170 /** 171 172 Assert or deassert the control signals on a serial port. 173 The following control signals are set according their bit settings : 174 . Request to Send 175 . Data Terminal Ready 176 177 @param[in] UartBase UART registers base address 178 @param[in] Control The following bits are taken into account : 179 . EFI_SERIAL_REQUEST_TO_SEND : assert/deassert the 180 "Request To Send" control signal if this bit is 181 equal to one/zero. 182 . EFI_SERIAL_DATA_TERMINAL_READY : assert/deassert 183 the "Data Terminal Ready" control signal if this 184 bit is equal to one/zero. 185 . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : enable/disable 186 the hardware loopback if this bit is equal to 187 one/zero. 188 . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : not supported. 189 . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : enable/ 190 disable the hardware flow control based on CTS (Clear 191 To Send) and RTS (Ready To Send) control signals. 192 193 @retval RETURN_SUCCESS The new control bits were set on the serial device. 194 @retval RETURN_UNSUPPORTED The serial device does not support this operation. 195 196 **/ 197 RETURN_STATUS 198 EFIAPI 199 PL011UartSetControl ( 200 IN UINTN UartBase, 201 IN UINT32 Control 202 ) 203 { 204 UINT32 Bits; 205 206 if (Control & (mInvalidControlBits)) { 207 return RETURN_UNSUPPORTED; 208 } 209 210 Bits = MmioRead32 (UartBase + UARTCR); 211 212 if (Control & EFI_SERIAL_REQUEST_TO_SEND) { 213 Bits |= PL011_UARTCR_RTS; 214 } else { 215 Bits &= ~PL011_UARTCR_RTS; 216 } 217 218 if (Control & EFI_SERIAL_DATA_TERMINAL_READY) { 219 Bits |= PL011_UARTCR_DTR; 220 } else { 221 Bits &= ~PL011_UARTCR_DTR; 222 } 223 224 if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) { 225 Bits |= PL011_UARTCR_LBE; 226 } else { 227 Bits &= ~PL011_UARTCR_LBE; 228 } 229 230 if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) { 231 Bits |= (PL011_UARTCR_CTSEN | PL011_UARTCR_RTSEN); 232 } else { 233 Bits &= ~(PL011_UARTCR_CTSEN | PL011_UARTCR_RTSEN); 234 } 235 236 MmioWrite32 (UartBase + UARTCR, Bits); 237 238 return RETURN_SUCCESS; 239 } 240 241 /** 242 243 Retrieve the status of the control bits on a serial device. 244 245 @param[in] UartBase UART registers base address 246 @param[out] Control Status of the control bits on a serial device : 247 248 . EFI_SERIAL_DATA_CLEAR_TO_SEND, EFI_SERIAL_DATA_SET_READY, 249 EFI_SERIAL_RING_INDICATE, EFI_SERIAL_CARRIER_DETECT, 250 EFI_SERIAL_REQUEST_TO_SEND, EFI_SERIAL_DATA_TERMINAL_READY 251 are all related to the DTE (Data Terminal Equipment) and 252 DCE (Data Communication Equipment) modes of operation of 253 the serial device. 254 . EFI_SERIAL_INPUT_BUFFER_EMPTY : equal to one if the receive 255 buffer is empty, 0 otherwise. 256 . EFI_SERIAL_OUTPUT_BUFFER_EMPTY : equal to one if the transmit 257 buffer is empty, 0 otherwise. 258 . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : equal to one if the 259 hardware loopback is enabled (the ouput feeds the receive 260 buffer), 0 otherwise. 261 . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal to one if a 262 loopback is accomplished by software, 0 otherwise. 263 . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : equal to one if the 264 hardware flow control based on CTS (Clear To Send) and RTS 265 (Ready To Send) control signals is enabled, 0 otherwise. 266 267 @retval RETURN_SUCCESS The control bits were read from the serial device. 268 269 **/ 270 RETURN_STATUS 271 EFIAPI 272 PL011UartGetControl ( 273 IN UINTN UartBase, 274 OUT UINT32 *Control 275 ) 276 { 277 UINT32 FlagRegister; 278 UINT32 ControlRegister; 279 280 281 FlagRegister = MmioRead32 (UartBase + UARTFR); 282 ControlRegister = MmioRead32 (UartBase + UARTCR); 283 284 *Control = 0; 285 286 if ((FlagRegister & PL011_UARTFR_CTS) == PL011_UARTFR_CTS) { 287 *Control |= EFI_SERIAL_CLEAR_TO_SEND; 288 } 289 290 if ((FlagRegister & PL011_UARTFR_DSR) == PL011_UARTFR_DSR) { 291 *Control |= EFI_SERIAL_DATA_SET_READY; 292 } 293 294 if ((FlagRegister & PL011_UARTFR_RI) == PL011_UARTFR_RI) { 295 *Control |= EFI_SERIAL_RING_INDICATE; 296 } 297 298 if ((FlagRegister & PL011_UARTFR_DCD) == PL011_UARTFR_DCD) { 299 *Control |= EFI_SERIAL_CARRIER_DETECT; 300 } 301 302 if ((ControlRegister & PL011_UARTCR_RTS) == PL011_UARTCR_RTS) { 303 *Control |= EFI_SERIAL_REQUEST_TO_SEND; 304 } 305 306 if ((ControlRegister & PL011_UARTCR_DTR) == PL011_UARTCR_DTR) { 307 *Control |= EFI_SERIAL_DATA_TERMINAL_READY; 308 } 309 310 if ((FlagRegister & PL011_UARTFR_RXFE) == PL011_UARTFR_RXFE) { 311 *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; 312 } 313 314 if ((FlagRegister & PL011_UARTFR_TXFE) == PL011_UARTFR_TXFE) { 315 *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; 316 } 317 318 if ((ControlRegister & (PL011_UARTCR_CTSEN | PL011_UARTCR_RTSEN)) 319 == (PL011_UARTCR_CTSEN | PL011_UARTCR_RTSEN)) { 320 *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; 321 } 322 323 if ((ControlRegister & PL011_UARTCR_LBE) == PL011_UARTCR_LBE) { 324 *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE; 325 } 326 327 return RETURN_SUCCESS; 328 } 329 330 /** 331 Write data to serial device. 332 333 @param Buffer Point of data buffer which need to be written. 334 @param NumberOfBytes Number of output bytes which are cached in Buffer. 335 336 @retval 0 Write data failed. 337 @retval !0 Actual number of bytes written to serial device. 338 339 **/ 340 UINTN 341 EFIAPI 342 PL011UartWrite ( 343 IN UINTN UartBase, 344 IN UINT8 *Buffer, 345 IN UINTN NumberOfBytes 346 ) 347 { 348 UINT8* CONST Final = &Buffer[NumberOfBytes]; 349 350 while (Buffer < Final) { 351 // Wait until UART able to accept another char 352 while ((MmioRead32 (UartBase + UARTFR) & UART_TX_FULL_FLAG_MASK)); 353 354 MmioWrite8 (UartBase + UARTDR, *Buffer++); 355 } 356 357 return NumberOfBytes; 358 } 359 360 /** 361 Read data from serial device and save the data in buffer. 362 363 @param Buffer Point of data buffer which need to be written. 364 @param NumberOfBytes Number of output bytes which are cached in Buffer. 365 366 @retval 0 Read data failed. 367 @retval !0 Actual number of bytes read from serial device. 368 369 **/ 370 UINTN 371 EFIAPI 372 PL011UartRead ( 373 IN UINTN UartBase, 374 OUT UINT8 *Buffer, 375 IN UINTN NumberOfBytes 376 ) 377 { 378 UINTN Count; 379 380 for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) { 381 while ((MmioRead32 (UartBase + UARTFR) & UART_RX_EMPTY_FLAG_MASK) != 0); 382 *Buffer = MmioRead8 (UartBase + UARTDR); 383 } 384 385 return NumberOfBytes; 386 } 387 388 /** 389 Check to see if any data is available to be read from the debug device. 390 391 @retval EFI_SUCCESS At least one byte of data is available to be read 392 @retval EFI_NOT_READY No data is available to be read 393 @retval EFI_DEVICE_ERROR The serial device is not functioning properly 394 395 **/ 396 BOOLEAN 397 EFIAPI 398 PL011UartPoll ( 399 IN UINTN UartBase 400 ) 401 { 402 return ((MmioRead32 (UartBase + UARTFR) & UART_RX_EMPTY_FLAG_MASK) == 0); 403 } 404