Add serial port library to support the Cadence IP6528 UART used in the
Cadence CSP platform.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Scott Telford <stelford@cadence.com>
---
CadencePkg/Include/Library/CspSerialPortLib.h | 86 ++++
.../CadenceCspSerialPortLib/CspSerialPortLib.c | 523 +++++++++++++++++++++
.../CadenceCspSerialPortLib/CspSerialPortLib.inf | 52 ++
.../CadenceCspSerialPortLib/CspSerialPortLib.uni | Bin 0 -> 1622 bytes
4 files changed, 661 insertions(+)
create mode 100644 CadencePkg/Include/Library/CspSerialPortLib.h
create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni
diff --git a/CadencePkg/Include/Library/CspSerialPortLib.h b/CadencePkg/Include/Library/CspSerialPortLib.h
new file mode 100644
index 0000000..46fa0d8
--- /dev/null
+++ b/CadencePkg/Include/Library/CspSerialPortLib.h
@@ -0,0 +1,86 @@
+/** @file
+* Serial Port Library for Cadence IP6528 UART.
+* Copyright (c) 2017, Cadence Design Systems. All rights reserved.
+*
+* This program and the accompanying materials are licensed and made
+* available under the terms and conditions of the BSD License which
+* accompanies this distribution. The full text of the license may be
+* found at http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __CSP_SERIAL_PORT_LIB_H__
+#define __CSP_SERIAL_PORT_LIB_H__
+
+// Cadence UART register offsets
+#define CSP_UART_CR 0x00 // Control
+#define CSP_UART_MR 0x04 // Mode
+#define CSP_UART_IER 0x08 // Interrupt enable
+#define CSP_UART_IDR 0x0C // Interrupt disable
+#define CSP_UART_IMR 0x10 // Interrupt mask
+#define CSP_UART_CISR 0x14 // Channel interrupt status
+#define CSP_UART_BRGR 0x18 // Baud rate generator
+#define CSP_UART_RTOR 0x1C // Rx Timeout
+#define CSP_UART_RTRIG 0x20 // Rx FIFO trigger level
+#define CSP_UART_MCR 0x24 // Modem control
+#define CSP_UART_MSR 0x28 // Modem status
+#define CSP_UART_CSR 0x2C // Channel status
+#define CSP_UART_FIFO 0x30 // FIFO (Tx/Rx)
+#define CSP_UART_BDIV 0x34 // Baud rate divider
+#define CSP_UART_FDEL 0x38 // Flow delay
+#define CSP_UART_PMIN 0x3C // IR min received pulse width
+#define CSP_UART_PWID 0x40 // IR transmitted pulse Width
+#define CSP_UART_TTRIG 0x44 // Tx FIFO trigger level
+
+
+// Control Register Bit Definitions
+#define CSP_UART_CR_STPBRK 0x00000100 // Stop Tx break
+#define CSP_UART_CR_STTBRK 0x00000080 // Start Tx break
+#define CSP_UART_CR_RSTTO 0x00000040 // Restart Rx timeout Counter
+#define CSP_UART_CR_TXDIS 0x00000020 // Tx disable
+#define CSP_UART_CR_TXEN 0x00000010 // Tx enable
+#define CSP_UART_CR_RXDIS 0x00000008 // Rx disable
+#define CSP_UART_CR_RXEN 0x00000004 // Rx enable
+#define CSP_UART_CR_TXRES 0x00000002 // Tx reset
+#define CSP_UART_CR_RXRES 0x00000001 // Rx reset
+
+
+// Mode register bit definitions
+#define CSP_UART_MR_CLKS 0x00000001 // Baud rate /8 pre-scalar
+#define CSP_UART_MR_CHMODE_LLB 0x00000200 // Local loopback mode
+#define CSP_UART_MR_CHMODE_NML 0x00000000 // Normal mode
+
+#define CSP_UART_MR_CHRL_6 0x00000006 // 6 databits
+#define CSP_UART_MR_CHRL_7 0x00000004 // 7 databits
+#define CSP_UART_MR_CHRL_8 0x00000000 // 8 databits
+
+#define CSP_UART_MR_PAR_NONE 0x00000020 // No parity mode
+#define CSP_UART_MR_PAR_MARK 0x00000018 // Mark parity mode
+#define CSP_UART_MR_PAR_SPACE 0x00000010 // Space parity mode
+#define CSP_UART_MR_PAR_ODD 0x00000008 // Odd parity mode
+#define CSP_UART_MR_PAR_EVEN 0x00000000 // Even parity mode
+
+#define CSP_UART_MR_NBSTOP_1 0x00000000 // 1 stop bit
+#define CSP_UART_MR_NBSTOP_2 0x00000080 // 2 stop bits
+
+// Modem control register bit definitions
+#define CSP_UART_MCR_DTR 0x00000001 // DTR control
+#define CSP_UART_MCR_RTS 0x00000002 // RTS control
+#define CSP_UART_MCR_FCM 0x00000020 // Auto flow control
+
+// Modem status register bit definitions
+#define CSP_UART_MSR_FCMS 0x00000100 // Auto flow control status
+#define CSP_UART_MSR_DCD 0x00000080 // DCD status
+#define CSP_UART_MSR_RI 0x00000040 // RI status
+#define CSP_UART_MSR_DSR 0x00000020 // DSR status
+#define CSP_UART_MSR_CTS 0x00000010 // CTS status
+
+// Channel status register bit definitions
+#define CSP_UART_CSR_REMPTY 0x00000002 // Rx FIFO empty
+#define CSP_UART_CSR_TEMPTY 0x00000008 // Tx FIFO empty
+#define CSP_UART_CSR_TFUL 0x00000010 // Tx FIFO full
+
+#endif
diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
new file mode 100644
index 0000000..9a9e14a
--- /dev/null
+++ b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
@@ -0,0 +1,523 @@
+/** @file
+ Serial Port Library for Cadence IP6528 UART.
+ Copyright (c) 2015-2017, Cadence Design Systems, Inc. All rights reserved.
+
+ Based on:
+
+ Null Serial Port library instance with empty functions.
+
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/CspSerialPortLib.h>
+#include <Library/CspSysReg.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+
+
+RETURN_STATUS
+EFIAPI
+CspUartInitializePort (
+ IN UINTN UartBase,
+ IN OUT UINT64 *BaudRate,
+ IN OUT EFI_PARITY_TYPE *Parity,
+ IN OUT UINT8 *DataBits,
+ IN OUT EFI_STOP_BITS_TYPE *StopBits
+);
+VOID CspUartPutChar (IN UINTN UartBase, IN UINT8 Char);
+UINT8 CspUartGetChar (IN UINTN UartBase);
+
+/**
+ Initialize the serial device hardware.
+
+ If no initialization is required, then return RETURN_SUCCESS.
+ If the serial device was successfully initialized, then return RETURN_SUCCESS.
+ If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
+
+ @retval RETURN_SUCCESS The serial device was initialized.
+ @retval RETURN_DEVICE_ERROR The serial device could not be initialized.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ UINT64 BaudRate;
+ EFI_PARITY_TYPE Parity;
+ UINT8 DataBits;
+ EFI_STOP_BITS_TYPE StopBits;
+
+ BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
+ Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
+ DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
+ StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
+
+ return CspUartInitializePort (
+ (UINTN)FixedPcdGet64 (PcdCspSerialBase),
+ &BaudRate,
+ &Parity,
+ &DataBits,
+ &StopBits
+ );
+}
+
+/**
+ Set new attributes to UART.
+
+ @param BaudRate The baud rate of the serial device. If the
+ baud rate is not supported, the speed will
+ be reduced down to the nearest supported one
+ and the variable's value will be updated
+ accordingly.
+ @param ReceiveFifoDepth The number of characters the device will
+ buffer on input. If the specified value is
+ not supported, the variable's value will
+ be reduced down to the nearest supported one.
+ @param Timeout If applicable, the number of microseconds the
+ device will wait before timing out a Read or
+ a Write operation.
+ @param Parity If applicable, this is the EFI_PARITY_TYPE
+ that is computed or checked as each character
+ is transmitted or received. If the device
+ does not support parity, the value is the
+ default parity value.
+ @param DataBits The number of data bits in each character
+ @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
+ of stop bits per character. If the device
+ does not support stop bits, the value is the
+ default stop bit value.
+
+ @retval EFI_SUCCESS All attributes were set correctly.
+ @retval EFI_INVALID_PARAMETERS One or more attributes has an unsupported
+ value.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+ IN OUT UINT64 *BaudRate,
+ IN OUT UINT32 *ReceiveFifoDepth,
+ IN OUT UINT32 *Timeout,
+ IN OUT EFI_PARITY_TYPE *Parity,
+ IN OUT UINT8 *DataBits,
+ IN OUT EFI_STOP_BITS_TYPE *StopBits
+ )
+{
+ return CspUartInitializePort (
+ (UINTN)FixedPcdGet64 (PcdCspSerialBase),
+ BaudRate,
+ Parity,
+ DataBits,
+ StopBits
+ );
+}
+
+/**
+ Write data from buffer to serial device.
+
+ Writes NumberOfBytes data bytes from Buffer to the serial device.
+ The number of bytes actually written to the serial device is returned.
+ If the return value is less than NumberOfBytes, then the write operation failed.
+ If Buffer is NULL, then ASSERT().
+ If NumberOfBytes is zero, then return 0.
+
+ @param Buffer The pointer to the data buffer to be written.
+ @param NumberOfBytes The number of bytes to written to the serial device.
+
+ @retval 0 NumberOfBytes is 0.
+ @retval >0 The number of bytes written to the serial device.
+ If this value is less than NumberOfBytes, then the read operation failed.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN i;
+ for (i = 0; i < NumberOfBytes; i++) {
+ CspUartPutChar ((UINTN)PcdGet64 (PcdCspSerialBase), Buffer[i]);
+ }
+ return i;
+}
+
+
+/**
+ Read data from serial device and save the datas in buffer.
+
+ Reads NumberOfBytes data bytes from a serial device into the buffer
+ specified by Buffer. The number of bytes actually read is returned.
+ If the return value is less than NumberOfBytes, then the rest operation failed.
+ If Buffer is NULL, then ASSERT().
+ If NumberOfBytes is zero, then return 0.
+
+ @param Buffer The pointer to the data buffer to store the data read from the serial device.
+ @param NumberOfBytes The number of bytes which will be read.
+
+ @retval 0 Read data failed; No data is to be read.
+ @retval >0 The actual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN i;
+ for (i = 0; i < NumberOfBytes; i++) {
+ Buffer[i] = CspUartGetChar ((UINTN)PcdGet64 (PcdCspSerialBase));
+ }
+ return i;
+}
+
+/**
+ Polls a serial device to see if there is any data waiting to be read.
+
+ Polls a serial device to see if there is any data waiting to be read.
+ If there is data waiting to be read from the serial device, then TRUE is returned.
+ If there is no data waiting to be read from the serial device, then FALSE is returned.
+
+ @retval TRUE Data is waiting to be read from the serial device.
+ @retval FALSE There is no data waiting to be read from the serial device.
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+ VOID
+ )
+{
+ return (MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase + CSP_UART_CSR))) &
+ CSP_UART_CSR_REMPTY) ? FALSE : TRUE;
+}
+
+/**
+
+ Assert or deassert the control signals on a serial port.
+ The following control signals are set according their bit settings :
+ . Request to Send
+ . Data Terminal Ready
+
+ @param[in] Control The following bits are taken into account :
+ . EFI_SERIAL_REQUEST_TO_SEND : assert/deassert the
+ "Request To Send" control signal if this bit is
+ equal to one/zero.
+ . EFI_SERIAL_DATA_TERMINAL_READY : assert/deassert
+ the "Data Terminal Ready" control signal if this
+ bit is equal to one/zero.
+ . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : enable/disable
+ the hardware loopback if this bit is equal to
+ one/zero.
+ . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : not supported.
+ . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : enable/
+ disable the hardware flow control based on CTS (Clear
+ To Send) and RTS (Ready To Send) control signals.
+
+ @retval RETURN_SUCCESS The new control bits were set on the device.
+ @retval RETURN_UNSUPPORTED The device does not support this operation.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+ IN UINT32 Control
+ )
+{
+ UINT32 Bits;
+
+ if (Control & (EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
+ EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE )) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ Bits = MmioRead32 (PcdGet64 (PcdCspSerialBase) + CSP_UART_MCR);
+
+ if (Control & EFI_SERIAL_REQUEST_TO_SEND) {
+ Bits |= CSP_UART_MCR_RTS;
+ } else {
+ Bits &= ~CSP_UART_MCR_RTS;
+ }
+
+ if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {
+ Bits |= CSP_UART_MCR_DTR;
+ } else {
+ Bits &= ~CSP_UART_MCR_DTR;
+ }
+
+ if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
+ Bits |= CSP_UART_MCR_FCM;
+ } else {
+ Bits &= CSP_UART_MCR_FCM;
+ }
+
+ MmioWrite32 ((PcdGet64 (PcdCspSerialBase) + CSP_UART_MCR), Bits);
+
+ return RETURN_SUCCESS;
+}
+
+/**
+
+ Retrieve the status of the control bits on a serial device.
+
+ @param[out] Control Status of the control bits on a serial device :
+
+ . EFI_SERIAL_DATA_CLEAR_TO_SEND,
+ EFI_SERIAL_DATA_SET_READY,
+ EFI_SERIAL_RING_INDICATE,
+ EFI_SERIAL_CARRIER_DETECT,
+ EFI_SERIAL_REQUEST_TO_SEND,
+ EFI_SERIAL_DATA_TERMINAL_READY
+ are all related to the DTE (Data Terminal Equipment)
+ and DCE (Data Communication Equipment) modes of
+ operation of the serial device.
+ . EFI_SERIAL_INPUT_BUFFER_EMPTY : equal to one if the
+ receive buffer is empty, 0 otherwise.
+ . EFI_SERIAL_OUTPUT_BUFFER_EMPTY : equal to one if the
+ transmit buffer is empty, 0 otherwise.
+ . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : equal to one if
+ the hardware loopback is enabled (the output feeds
+ the receive buffer), 0 otherwise.
+ . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal to one
+ if a loopback is accomplished by software, else 0.
+ . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : equal to
+ one if the hardware flow control based on CTS (Clear
+ To Send) and RTS (Ready To Send) control signals is
+ enabled, 0 otherwise.
+
+ @retval RETURN_SUCCESS The control bits were read from the device.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+ OUT UINT32 *Control
+ )
+{
+ UINT32 ModemStatusReg;
+ UINT32 ModemCtrlReg;
+ UINT32 ChanStatusReg;
+
+ ModemCtrlReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
+ CSP_UART_MCR));
+ ModemStatusReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
+ CSP_UART_MSR));
+ ChanStatusReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
+ CSP_UART_CSR));
+
+ *Control = 0;
+
+ if ((ModemStatusReg & CSP_UART_MSR_CTS) == CSP_UART_MSR_CTS) {
+ *Control |= EFI_SERIAL_CLEAR_TO_SEND;
+ }
+
+ if ((ModemStatusReg & CSP_UART_MSR_DSR) == CSP_UART_MSR_DSR) {
+ *Control |= EFI_SERIAL_DATA_SET_READY;
+ }
+
+ if ((ModemStatusReg & CSP_UART_MSR_RI) == CSP_UART_MSR_RI) {
+ *Control |= EFI_SERIAL_RING_INDICATE;
+ }
+
+ if ((ModemStatusReg & CSP_UART_MSR_DCD) == CSP_UART_MSR_DCD) {
+ *Control |= EFI_SERIAL_CARRIER_DETECT;
+ }
+
+ if ((ModemCtrlReg & CSP_UART_MCR_RTS) == CSP_UART_MCR_RTS) {
+ *Control |= EFI_SERIAL_REQUEST_TO_SEND;
+ }
+
+ if ((ModemCtrlReg & CSP_UART_MCR_DTR) == CSP_UART_MCR_DTR) {
+ *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
+ }
+
+ if ((ChanStatusReg & CSP_UART_CSR_REMPTY) == CSP_UART_CSR_REMPTY) {
+ *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+ }
+
+ if ((ChanStatusReg & CSP_UART_CSR_TEMPTY) == CSP_UART_CSR_TEMPTY) {
+ *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
+ }
+
+ if ((ModemCtrlReg & CSP_UART_MCR_FCM) == CSP_UART_MCR_FCM) {
+ *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+ }
+
+ return RETURN_SUCCESS;
+}
+
+
+/**
+
+ Initialise the serial port to the specified settings.
+ The serial port is re-configured only if the specified settings
+ are different from the current settings.
+ All unspecified settings will be set to the default values.
+
+ @param UartBase The base address of the serial device.
+ @param BaudRate The baud rate of the serial device. If the
+ baud rate is not supported, the speed will be
+ reduced to the nearest supported one and the
+ variable's value will be updated accordingly.
+ @param Parity If applicable, this is the EFI_PARITY_TYPE
+ that is computed or checked as each character
+ is transmitted or received. If the device
+ does not support parity, the value is the
+ default parity value.
+ @param DataBits The number of data bits in each character.
+ @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
+ of stop bits per character.
+ If the device does not support stop bits, the
+ value is the default stop bit value.
+
+ @retval RETURN_SUCCESS All attributes were set correctly on the
+ serial device.
+ @retval RETURN_INVALID_PARAMETER One or more of the attributes has an
+ unsupported value.
+
+**/
+RETURN_STATUS
+EFIAPI
+CspUartInitializePort (
+ IN UINTN UartBase,
+ IN OUT UINT64 *BaudRate,
+ IN OUT EFI_PARITY_TYPE *Parity,
+ IN OUT UINT8 *DataBits,
+ IN OUT EFI_STOP_BITS_TYPE *StopBits
+ )
+{
+ UINT32 RegVal = 0;
+ UINT32 BaudDivisor = 0;
+
+ // Wait for Tx FIFO to empty before initializing
+ if (!(MmioRead32 (UartBase + CSP_UART_CR) & CSP_UART_CR_TXDIS)) {
+ while (!(MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_TEMPTY))
+ ;
+ }
+
+ // Disable Tx/Rx before setting baud rate
+ RegVal = MmioRead32 (UartBase + CSP_UART_CR);
+ RegVal |= CSP_UART_CR_TXDIS | CSP_UART_CR_RXDIS;
+ MmioWrite32 ((UartBase + CSP_UART_CR), RegVal);
+
+ // Set baud rate
+ UINT32 SelClk = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSysRegBase) +
+ CSP_SYSREG_CPU_FREQ));
+ UINT32 BDiv = 0;
+
+ if (SelClk < 0x1800000) {
+ BaudDivisor = 1;
+ } else {
+ BaudDivisor = 8;
+ }
+ MmioWrite32 ((UartBase + CSP_UART_BRGR), BaudDivisor);
+ BDiv = (SelClk + ((*BaudRate * BaudDivisor) / 2)) / (*BaudRate * BaudDivisor);
+ MmioWrite32 ((UartBase + CSP_UART_BDIV), (BDiv - 1));
+
+ // Reset and enable Tx/Rx
+ RegVal = MmioRead32 (UartBase + CSP_UART_CR);
+ RegVal &= ~(CSP_UART_CR_TXDIS | CSP_UART_CR_RXDIS);
+ RegVal |= CSP_UART_CR_TXEN | CSP_UART_CR_TXRES | \
+ CSP_UART_CR_RXEN | CSP_UART_CR_RXRES;;
+ MmioWrite32 ((UartBase + CSP_UART_CR), RegVal);
+
+ RegVal = MmioRead32 (UartBase + CSP_UART_MR) & 1;
+
+ //
+ // Data Bits
+ //
+ switch (*DataBits) {
+ case 0:
+ *DataBits = 8;
+ case 8:
+ RegVal |= CSP_UART_MR_CHRL_8;
+ break;
+ case 7:
+ RegVal |= CSP_UART_MR_CHRL_7;
+ break;
+ case 6:
+ RegVal |= CSP_UART_MR_CHRL_6;
+ break;
+ default:
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ //
+ // Stop Bits
+ //
+ switch (*StopBits) {
+ case DefaultStopBits:
+ *StopBits = OneStopBit;
+ case OneStopBit:
+ RegVal |= CSP_UART_MR_NBSTOP_1;
+ break;
+ case TwoStopBits:
+ RegVal |= CSP_UART_MR_NBSTOP_2;
+ break;
+ default:
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ //
+ // Parity
+ //
+ switch (*Parity) {
+ case DefaultParity:
+ *Parity = NoParity;
+ case NoParity:
+ RegVal |= CSP_UART_MR_PAR_NONE;
+ break;
+ case EvenParity:
+ RegVal |= CSP_UART_MR_PAR_EVEN;
+ break;
+ case OddParity:
+ RegVal |= CSP_UART_MR_PAR_ODD;
+ break;
+ case MarkParity:
+ RegVal |= CSP_UART_MR_PAR_MARK;
+ break;
+ case SpaceParity:
+ RegVal |= CSP_UART_MR_PAR_SPACE;
+ break;
+ default:
+ return RETURN_INVALID_PARAMETER;
+ }
+
+ MmioWrite32 ((UartBase + CSP_UART_MR), RegVal);
+
+ return RETURN_SUCCESS;
+}
+
+VOID CspUartPutChar (IN UINTN UartBase, IN UINT8 Char)
+{
+ while ((MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_TFUL)
+ == CSP_UART_CSR_TFUL)
+ ;
+ MmioWrite8 (UartBase + CSP_UART_FIFO, Char);
+}
+
+UINT8 CspUartGetChar (IN UINTN UartBase)
+{
+ while ((MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_REMPTY)
+ == CSP_UART_CSR_REMPTY)
+ ;
+ return MmioRead8 (UartBase + CSP_UART_FIFO);
+}
+
diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
new file mode 100644
index 0000000..46ea8f9
--- /dev/null
+++ b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
@@ -0,0 +1,52 @@
+## @file
+# Serial Port Library for Cadence IP6528 UART.
+#
+# Based on:
+#
+# Null instance of Serial Port Library with empty functions.
+#
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+# Copyright (C) 2017 Cadence Design Systems. All rights reserved worldwide.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 1.25
+ BASE_NAME = CspSerialPortLib
+ MODULE_UNI_FILE = CspSerialPortLib.uni
+ FILE_GUID = C456789-8897-411a-91F8-7D7E45837146
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SerialPortLib
+
+[Sources]
+ CspSerialPortLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ CadencePkg/CadenceCspPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ BaseLib
+ PcdLib
+
+[FixedPcd]
+ gCadenceCspTokenSpaceGuid.PcdCspSerialBase
+ gCadenceCspTokenSpaceGuid.PcdCspSysRegBase
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+
diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni
new file mode 100644
index 0000000000000000000000000000000000000000..60434d42366ee99f53da028381deff21250cfda8
GIT binary patch
literal 1622
zcmc(fL2uJQ5QXQA#D7?&7eK88T#z`CGzKi7juJ<OQ{^NjwUj2vP8<5?3*TGE-cW+X
z1)<2^-PxHpZ{Cda<GyQMb3D)ZIeTMYt+1tC+GBf!Rd-`fCDt6fv!SgyZP<OpHf5jl
z+;J{!WfeC$>x>u&mVBL^Vw+=W>=WzR$TExCEFs$|G2g&b#)Vz^Oiw^~3eHP=ZZGWB
z0mK35m5*3)J0@OCF728%!qS7g*ay_gpA@C)Zh6nKY(3*8`z>hVe28NPuYyPi(~^h<
z@0?uD*Djn59#SAji5VW(cuJQ$;#T-OEV*acC|k8!D5~_)OT49|bglUbL->joJNe%7
zsAoCdQ0JW8crVozm`IJ1II(U}#7uYvObWl(?V7%YxIStQIIG)%OX%0uYcb>fd$k2Q
zg(x*@y_8FxQPop;HhI+}saj9X&8}PG{2iZ%oPO1%Rznjw-NmnW3W(8WPghOThEBZp
zldU<cwUvMAtBa_<q(5C4?AKdinZkT-Cl78SP_B5woT!rb7Q<)Al&AKNch5d?PSDb!
zrq&E=Vtt#ii@m}VJ7bNp2ZW%0!Z#4(G4{wQJ59CT9aiBAwZq!?XPu7sYCq>*yi%Xh
z**RV#&+H6)0;(`lpMAth++|bF3}5*uYwh(GUuFNo`hgoUKV~2AveZ??_PNCg=m}a3
znJ48O?CBO}O8-S&&s{b>NA1+qUr(*y1xP6v6VPJ2fRXf)vOUzw;Pa>75na?*u%Pof
rZ_S-%;RGx(?eP9r|9YLavcIcJGcl$f&C9Uu!=cLlXH^lJHQo9N7Zm#w
literal 0
HcmV?d00001
--
2.2.2
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
On Thu, Jun 22, 2017 at 10:31:57AM +0100, Scott Telford wrote:
> Add serial port library to support the Cadence IP6528 UART used in the
> Cadence CSP platform.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Scott Telford <stelford@cadence.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
> ---
> CadencePkg/Include/Library/CspSerialPortLib.h | 86 ++++
> .../CadenceCspSerialPortLib/CspSerialPortLib.c | 523 +++++++++++++++++++++
> .../CadenceCspSerialPortLib/CspSerialPortLib.inf | 52 ++
> .../CadenceCspSerialPortLib/CspSerialPortLib.uni | Bin 0 -> 1622 bytes
> 4 files changed, 661 insertions(+)
> create mode 100644 CadencePkg/Include/Library/CspSerialPortLib.h
> create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
> create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
> create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni
>
> diff --git a/CadencePkg/Include/Library/CspSerialPortLib.h b/CadencePkg/Include/Library/CspSerialPortLib.h
> new file mode 100644
> index 0000000..46fa0d8
> --- /dev/null
> +++ b/CadencePkg/Include/Library/CspSerialPortLib.h
> @@ -0,0 +1,86 @@
> +/** @file
> +* Serial Port Library for Cadence IP6528 UART.
> +* Copyright (c) 2017, Cadence Design Systems. All rights reserved.
> +*
> +* This program and the accompanying materials are licensed and made
> +* available under the terms and conditions of the BSD License which
> +* accompanies this distribution. The full text of the license may be
> +* found at http://opensource.org/licenses/bsd-license.php
> +*
> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +*
> +**/
> +
> +#ifndef __CSP_SERIAL_PORT_LIB_H__
> +#define __CSP_SERIAL_PORT_LIB_H__
> +
> +// Cadence UART register offsets
> +#define CSP_UART_CR 0x00 // Control
> +#define CSP_UART_MR 0x04 // Mode
> +#define CSP_UART_IER 0x08 // Interrupt enable
> +#define CSP_UART_IDR 0x0C // Interrupt disable
> +#define CSP_UART_IMR 0x10 // Interrupt mask
> +#define CSP_UART_CISR 0x14 // Channel interrupt status
> +#define CSP_UART_BRGR 0x18 // Baud rate generator
> +#define CSP_UART_RTOR 0x1C // Rx Timeout
> +#define CSP_UART_RTRIG 0x20 // Rx FIFO trigger level
> +#define CSP_UART_MCR 0x24 // Modem control
> +#define CSP_UART_MSR 0x28 // Modem status
> +#define CSP_UART_CSR 0x2C // Channel status
> +#define CSP_UART_FIFO 0x30 // FIFO (Tx/Rx)
> +#define CSP_UART_BDIV 0x34 // Baud rate divider
> +#define CSP_UART_FDEL 0x38 // Flow delay
> +#define CSP_UART_PMIN 0x3C // IR min received pulse width
> +#define CSP_UART_PWID 0x40 // IR transmitted pulse Width
> +#define CSP_UART_TTRIG 0x44 // Tx FIFO trigger level
> +
> +
> +// Control Register Bit Definitions
> +#define CSP_UART_CR_STPBRK 0x00000100 // Stop Tx break
> +#define CSP_UART_CR_STTBRK 0x00000080 // Start Tx break
> +#define CSP_UART_CR_RSTTO 0x00000040 // Restart Rx timeout Counter
> +#define CSP_UART_CR_TXDIS 0x00000020 // Tx disable
> +#define CSP_UART_CR_TXEN 0x00000010 // Tx enable
> +#define CSP_UART_CR_RXDIS 0x00000008 // Rx disable
> +#define CSP_UART_CR_RXEN 0x00000004 // Rx enable
> +#define CSP_UART_CR_TXRES 0x00000002 // Tx reset
> +#define CSP_UART_CR_RXRES 0x00000001 // Rx reset
> +
> +
> +// Mode register bit definitions
> +#define CSP_UART_MR_CLKS 0x00000001 // Baud rate /8 pre-scalar
> +#define CSP_UART_MR_CHMODE_LLB 0x00000200 // Local loopback mode
> +#define CSP_UART_MR_CHMODE_NML 0x00000000 // Normal mode
> +
> +#define CSP_UART_MR_CHRL_6 0x00000006 // 6 databits
> +#define CSP_UART_MR_CHRL_7 0x00000004 // 7 databits
> +#define CSP_UART_MR_CHRL_8 0x00000000 // 8 databits
> +
> +#define CSP_UART_MR_PAR_NONE 0x00000020 // No parity mode
> +#define CSP_UART_MR_PAR_MARK 0x00000018 // Mark parity mode
> +#define CSP_UART_MR_PAR_SPACE 0x00000010 // Space parity mode
> +#define CSP_UART_MR_PAR_ODD 0x00000008 // Odd parity mode
> +#define CSP_UART_MR_PAR_EVEN 0x00000000 // Even parity mode
> +
> +#define CSP_UART_MR_NBSTOP_1 0x00000000 // 1 stop bit
> +#define CSP_UART_MR_NBSTOP_2 0x00000080 // 2 stop bits
> +
> +// Modem control register bit definitions
> +#define CSP_UART_MCR_DTR 0x00000001 // DTR control
> +#define CSP_UART_MCR_RTS 0x00000002 // RTS control
> +#define CSP_UART_MCR_FCM 0x00000020 // Auto flow control
> +
> +// Modem status register bit definitions
> +#define CSP_UART_MSR_FCMS 0x00000100 // Auto flow control status
> +#define CSP_UART_MSR_DCD 0x00000080 // DCD status
> +#define CSP_UART_MSR_RI 0x00000040 // RI status
> +#define CSP_UART_MSR_DSR 0x00000020 // DSR status
> +#define CSP_UART_MSR_CTS 0x00000010 // CTS status
> +
> +// Channel status register bit definitions
> +#define CSP_UART_CSR_REMPTY 0x00000002 // Rx FIFO empty
> +#define CSP_UART_CSR_TEMPTY 0x00000008 // Tx FIFO empty
> +#define CSP_UART_CSR_TFUL 0x00000010 // Tx FIFO full
> +
> +#endif
> diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
> new file mode 100644
> index 0000000..9a9e14a
> --- /dev/null
> +++ b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
> @@ -0,0 +1,523 @@
> +/** @file
> + Serial Port Library for Cadence IP6528 UART.
> + Copyright (c) 2015-2017, Cadence Design Systems, Inc. All rights reserved.
> +
> + Based on:
> +
> + Null Serial Port library instance with empty functions.
> +
> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD License
> + which accompanies this distribution. The full text of the license may be found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/CspSerialPortLib.h>
> +#include <Library/CspSysReg.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/SerialPortLib.h>
> +
> +
> +RETURN_STATUS
> +EFIAPI
> +CspUartInitializePort (
> + IN UINTN UartBase,
> + IN OUT UINT64 *BaudRate,
> + IN OUT EFI_PARITY_TYPE *Parity,
> + IN OUT UINT8 *DataBits,
> + IN OUT EFI_STOP_BITS_TYPE *StopBits
> +);
> +VOID CspUartPutChar (IN UINTN UartBase, IN UINT8 Char);
> +UINT8 CspUartGetChar (IN UINTN UartBase);
> +
> +/**
> + Initialize the serial device hardware.
> +
> + If no initialization is required, then return RETURN_SUCCESS.
> + If the serial device was successfully initialized, then return RETURN_SUCCESS.
> + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
> +
> + @retval RETURN_SUCCESS The serial device was initialized.
> + @retval RETURN_DEVICE_ERROR The serial device could not be initialized.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortInitialize (
> + VOID
> + )
> +{
> + UINT64 BaudRate;
> + EFI_PARITY_TYPE Parity;
> + UINT8 DataBits;
> + EFI_STOP_BITS_TYPE StopBits;
> +
> + BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
> + Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
> + DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
> + StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
> +
> + return CspUartInitializePort (
> + (UINTN)FixedPcdGet64 (PcdCspSerialBase),
> + &BaudRate,
> + &Parity,
> + &DataBits,
> + &StopBits
> + );
> +}
> +
> +/**
> + Set new attributes to UART.
> +
> + @param BaudRate The baud rate of the serial device. If the
> + baud rate is not supported, the speed will
> + be reduced down to the nearest supported one
> + and the variable's value will be updated
> + accordingly.
> + @param ReceiveFifoDepth The number of characters the device will
> + buffer on input. If the specified value is
> + not supported, the variable's value will
> + be reduced down to the nearest supported one.
> + @param Timeout If applicable, the number of microseconds the
> + device will wait before timing out a Read or
> + a Write operation.
> + @param Parity If applicable, this is the EFI_PARITY_TYPE
> + that is computed or checked as each character
> + is transmitted or received. If the device
> + does not support parity, the value is the
> + default parity value.
> + @param DataBits The number of data bits in each character
> + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
> + of stop bits per character. If the device
> + does not support stop bits, the value is the
> + default stop bit value.
> +
> + @retval EFI_SUCCESS All attributes were set correctly.
> + @retval EFI_INVALID_PARAMETERS One or more attributes has an unsupported
> + value.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortSetAttributes (
> + IN OUT UINT64 *BaudRate,
> + IN OUT UINT32 *ReceiveFifoDepth,
> + IN OUT UINT32 *Timeout,
> + IN OUT EFI_PARITY_TYPE *Parity,
> + IN OUT UINT8 *DataBits,
> + IN OUT EFI_STOP_BITS_TYPE *StopBits
> + )
> +{
> + return CspUartInitializePort (
> + (UINTN)FixedPcdGet64 (PcdCspSerialBase),
> + BaudRate,
> + Parity,
> + DataBits,
> + StopBits
> + );
> +}
> +
> +/**
> + Write data from buffer to serial device.
> +
> + Writes NumberOfBytes data bytes from Buffer to the serial device.
> + The number of bytes actually written to the serial device is returned.
> + If the return value is less than NumberOfBytes, then the write operation failed.
> + If Buffer is NULL, then ASSERT().
> + If NumberOfBytes is zero, then return 0.
> +
> + @param Buffer The pointer to the data buffer to be written.
> + @param NumberOfBytes The number of bytes to written to the serial device.
> +
> + @retval 0 NumberOfBytes is 0.
> + @retval >0 The number of bytes written to the serial device.
> + If this value is less than NumberOfBytes, then the read operation failed.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortWrite (
> + IN UINT8 *Buffer,
> + IN UINTN NumberOfBytes
> +)
> +{
> + UINTN i;
> + for (i = 0; i < NumberOfBytes; i++) {
> + CspUartPutChar ((UINTN)PcdGet64 (PcdCspSerialBase), Buffer[i]);
> + }
> + return i;
> +}
> +
> +
> +/**
> + Read data from serial device and save the datas in buffer.
> +
> + Reads NumberOfBytes data bytes from a serial device into the buffer
> + specified by Buffer. The number of bytes actually read is returned.
> + If the return value is less than NumberOfBytes, then the rest operation failed.
> + If Buffer is NULL, then ASSERT().
> + If NumberOfBytes is zero, then return 0.
> +
> + @param Buffer The pointer to the data buffer to store the data read from the serial device.
> + @param NumberOfBytes The number of bytes which will be read.
> +
> + @retval 0 Read data failed; No data is to be read.
> + @retval >0 The actual number of bytes read from serial device.
> +
> +**/
> +UINTN
> +EFIAPI
> +SerialPortRead (
> + OUT UINT8 *Buffer,
> + IN UINTN NumberOfBytes
> +)
> +{
> + UINTN i;
> + for (i = 0; i < NumberOfBytes; i++) {
> + Buffer[i] = CspUartGetChar ((UINTN)PcdGet64 (PcdCspSerialBase));
> + }
> + return i;
> +}
> +
> +/**
> + Polls a serial device to see if there is any data waiting to be read.
> +
> + Polls a serial device to see if there is any data waiting to be read.
> + If there is data waiting to be read from the serial device, then TRUE is returned.
> + If there is no data waiting to be read from the serial device, then FALSE is returned.
> +
> + @retval TRUE Data is waiting to be read from the serial device.
> + @retval FALSE There is no data waiting to be read from the serial device.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +SerialPortPoll (
> + VOID
> + )
> +{
> + return (MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase + CSP_UART_CSR))) &
> + CSP_UART_CSR_REMPTY) ? FALSE : TRUE;
> +}
> +
> +/**
> +
> + Assert or deassert the control signals on a serial port.
> + The following control signals are set according their bit settings :
> + . Request to Send
> + . Data Terminal Ready
> +
> + @param[in] Control The following bits are taken into account :
> + . EFI_SERIAL_REQUEST_TO_SEND : assert/deassert the
> + "Request To Send" control signal if this bit is
> + equal to one/zero.
> + . EFI_SERIAL_DATA_TERMINAL_READY : assert/deassert
> + the "Data Terminal Ready" control signal if this
> + bit is equal to one/zero.
> + . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : enable/disable
> + the hardware loopback if this bit is equal to
> + one/zero.
> + . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : not supported.
> + . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : enable/
> + disable the hardware flow control based on CTS (Clear
> + To Send) and RTS (Ready To Send) control signals.
> +
> + @retval RETURN_SUCCESS The new control bits were set on the device.
> + @retval RETURN_UNSUPPORTED The device does not support this operation.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortSetControl (
> + IN UINT32 Control
> + )
> +{
> + UINT32 Bits;
> +
> + if (Control & (EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
> + EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE )) {
> + return RETURN_UNSUPPORTED;
> + }
> +
> + Bits = MmioRead32 (PcdGet64 (PcdCspSerialBase) + CSP_UART_MCR);
> +
> + if (Control & EFI_SERIAL_REQUEST_TO_SEND) {
> + Bits |= CSP_UART_MCR_RTS;
> + } else {
> + Bits &= ~CSP_UART_MCR_RTS;
> + }
> +
> + if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {
> + Bits |= CSP_UART_MCR_DTR;
> + } else {
> + Bits &= ~CSP_UART_MCR_DTR;
> + }
> +
> + if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
> + Bits |= CSP_UART_MCR_FCM;
> + } else {
> + Bits &= CSP_UART_MCR_FCM;
> + }
> +
> + MmioWrite32 ((PcdGet64 (PcdCspSerialBase) + CSP_UART_MCR), Bits);
> +
> + return RETURN_SUCCESS;
> +}
> +
> +/**
> +
> + Retrieve the status of the control bits on a serial device.
> +
> + @param[out] Control Status of the control bits on a serial device :
> +
> + . EFI_SERIAL_DATA_CLEAR_TO_SEND,
> + EFI_SERIAL_DATA_SET_READY,
> + EFI_SERIAL_RING_INDICATE,
> + EFI_SERIAL_CARRIER_DETECT,
> + EFI_SERIAL_REQUEST_TO_SEND,
> + EFI_SERIAL_DATA_TERMINAL_READY
> + are all related to the DTE (Data Terminal Equipment)
> + and DCE (Data Communication Equipment) modes of
> + operation of the serial device.
> + . EFI_SERIAL_INPUT_BUFFER_EMPTY : equal to one if the
> + receive buffer is empty, 0 otherwise.
> + . EFI_SERIAL_OUTPUT_BUFFER_EMPTY : equal to one if the
> + transmit buffer is empty, 0 otherwise.
> + . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : equal to one if
> + the hardware loopback is enabled (the output feeds
> + the receive buffer), 0 otherwise.
> + . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal to one
> + if a loopback is accomplished by software, else 0.
> + . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : equal to
> + one if the hardware flow control based on CTS (Clear
> + To Send) and RTS (Ready To Send) control signals is
> + enabled, 0 otherwise.
> +
> + @retval RETURN_SUCCESS The control bits were read from the device.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +SerialPortGetControl (
> + OUT UINT32 *Control
> + )
> +{
> + UINT32 ModemStatusReg;
> + UINT32 ModemCtrlReg;
> + UINT32 ChanStatusReg;
> +
> + ModemCtrlReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
> + CSP_UART_MCR));
> + ModemStatusReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
> + CSP_UART_MSR));
> + ChanStatusReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
> + CSP_UART_CSR));
> +
> + *Control = 0;
> +
> + if ((ModemStatusReg & CSP_UART_MSR_CTS) == CSP_UART_MSR_CTS) {
> + *Control |= EFI_SERIAL_CLEAR_TO_SEND;
> + }
> +
> + if ((ModemStatusReg & CSP_UART_MSR_DSR) == CSP_UART_MSR_DSR) {
> + *Control |= EFI_SERIAL_DATA_SET_READY;
> + }
> +
> + if ((ModemStatusReg & CSP_UART_MSR_RI) == CSP_UART_MSR_RI) {
> + *Control |= EFI_SERIAL_RING_INDICATE;
> + }
> +
> + if ((ModemStatusReg & CSP_UART_MSR_DCD) == CSP_UART_MSR_DCD) {
> + *Control |= EFI_SERIAL_CARRIER_DETECT;
> + }
> +
> + if ((ModemCtrlReg & CSP_UART_MCR_RTS) == CSP_UART_MCR_RTS) {
> + *Control |= EFI_SERIAL_REQUEST_TO_SEND;
> + }
> +
> + if ((ModemCtrlReg & CSP_UART_MCR_DTR) == CSP_UART_MCR_DTR) {
> + *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
> + }
> +
> + if ((ChanStatusReg & CSP_UART_CSR_REMPTY) == CSP_UART_CSR_REMPTY) {
> + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
> + }
> +
> + if ((ChanStatusReg & CSP_UART_CSR_TEMPTY) == CSP_UART_CSR_TEMPTY) {
> + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
> + }
> +
> + if ((ModemCtrlReg & CSP_UART_MCR_FCM) == CSP_UART_MCR_FCM) {
> + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
> + }
> +
> + return RETURN_SUCCESS;
> +}
> +
> +
> +/**
> +
> + Initialise the serial port to the specified settings.
> + The serial port is re-configured only if the specified settings
> + are different from the current settings.
> + All unspecified settings will be set to the default values.
> +
> + @param UartBase The base address of the serial device.
> + @param BaudRate The baud rate of the serial device. If the
> + baud rate is not supported, the speed will be
> + reduced to the nearest supported one and the
> + variable's value will be updated accordingly.
> + @param Parity If applicable, this is the EFI_PARITY_TYPE
> + that is computed or checked as each character
> + is transmitted or received. If the device
> + does not support parity, the value is the
> + default parity value.
> + @param DataBits The number of data bits in each character.
> + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
> + of stop bits per character.
> + If the device does not support stop bits, the
> + value is the default stop bit value.
> +
> + @retval RETURN_SUCCESS All attributes were set correctly on the
> + serial device.
> + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an
> + unsupported value.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +CspUartInitializePort (
> + IN UINTN UartBase,
> + IN OUT UINT64 *BaudRate,
> + IN OUT EFI_PARITY_TYPE *Parity,
> + IN OUT UINT8 *DataBits,
> + IN OUT EFI_STOP_BITS_TYPE *StopBits
> + )
> +{
> + UINT32 RegVal = 0;
> + UINT32 BaudDivisor = 0;
> +
> + // Wait for Tx FIFO to empty before initializing
> + if (!(MmioRead32 (UartBase + CSP_UART_CR) & CSP_UART_CR_TXDIS)) {
> + while (!(MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_TEMPTY))
> + ;
> + }
> +
> + // Disable Tx/Rx before setting baud rate
> + RegVal = MmioRead32 (UartBase + CSP_UART_CR);
> + RegVal |= CSP_UART_CR_TXDIS | CSP_UART_CR_RXDIS;
> + MmioWrite32 ((UartBase + CSP_UART_CR), RegVal);
> +
> + // Set baud rate
> + UINT32 SelClk = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSysRegBase) +
> + CSP_SYSREG_CPU_FREQ));
> + UINT32 BDiv = 0;
> +
> + if (SelClk < 0x1800000) {
> + BaudDivisor = 1;
> + } else {
> + BaudDivisor = 8;
> + }
> + MmioWrite32 ((UartBase + CSP_UART_BRGR), BaudDivisor);
> + BDiv = (SelClk + ((*BaudRate * BaudDivisor) / 2)) / (*BaudRate * BaudDivisor);
> + MmioWrite32 ((UartBase + CSP_UART_BDIV), (BDiv - 1));
> +
> + // Reset and enable Tx/Rx
> + RegVal = MmioRead32 (UartBase + CSP_UART_CR);
> + RegVal &= ~(CSP_UART_CR_TXDIS | CSP_UART_CR_RXDIS);
> + RegVal |= CSP_UART_CR_TXEN | CSP_UART_CR_TXRES | \
> + CSP_UART_CR_RXEN | CSP_UART_CR_RXRES;;
> + MmioWrite32 ((UartBase + CSP_UART_CR), RegVal);
> +
> + RegVal = MmioRead32 (UartBase + CSP_UART_MR) & 1;
> +
> + //
> + // Data Bits
> + //
> + switch (*DataBits) {
> + case 0:
> + *DataBits = 8;
> + case 8:
> + RegVal |= CSP_UART_MR_CHRL_8;
> + break;
> + case 7:
> + RegVal |= CSP_UART_MR_CHRL_7;
> + break;
> + case 6:
> + RegVal |= CSP_UART_MR_CHRL_6;
> + break;
> + default:
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + //
> + // Stop Bits
> + //
> + switch (*StopBits) {
> + case DefaultStopBits:
> + *StopBits = OneStopBit;
> + case OneStopBit:
> + RegVal |= CSP_UART_MR_NBSTOP_1;
> + break;
> + case TwoStopBits:
> + RegVal |= CSP_UART_MR_NBSTOP_2;
> + break;
> + default:
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + //
> + // Parity
> + //
> + switch (*Parity) {
> + case DefaultParity:
> + *Parity = NoParity;
> + case NoParity:
> + RegVal |= CSP_UART_MR_PAR_NONE;
> + break;
> + case EvenParity:
> + RegVal |= CSP_UART_MR_PAR_EVEN;
> + break;
> + case OddParity:
> + RegVal |= CSP_UART_MR_PAR_ODD;
> + break;
> + case MarkParity:
> + RegVal |= CSP_UART_MR_PAR_MARK;
> + break;
> + case SpaceParity:
> + RegVal |= CSP_UART_MR_PAR_SPACE;
> + break;
> + default:
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + MmioWrite32 ((UartBase + CSP_UART_MR), RegVal);
> +
> + return RETURN_SUCCESS;
> +}
> +
> +VOID CspUartPutChar (IN UINTN UartBase, IN UINT8 Char)
> +{
> + while ((MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_TFUL)
> + == CSP_UART_CSR_TFUL)
> + ;
> + MmioWrite8 (UartBase + CSP_UART_FIFO, Char);
> +}
> +
> +UINT8 CspUartGetChar (IN UINTN UartBase)
> +{
> + while ((MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_REMPTY)
> + == CSP_UART_CSR_REMPTY)
> + ;
> + return MmioRead8 (UartBase + CSP_UART_FIFO);
> +}
> +
> diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
> new file mode 100644
> index 0000000..46ea8f9
> --- /dev/null
> +++ b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# Serial Port Library for Cadence IP6528 UART.
> +#
> +# Based on:
> +#
> +# Null instance of Serial Port Library with empty functions.
> +#
> +# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +# Copyright (C) 2017 Cadence Design Systems. All rights reserved worldwide.
> +#
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the BSD License
> +# which accompanies this distribution. The full text of the license may be found at
> +# http://opensource.org/licenses/bsd-license.php.
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 1.25
> + BASE_NAME = CspSerialPortLib
> + MODULE_UNI_FILE = CspSerialPortLib.uni
> + FILE_GUID = C456789-8897-411a-91F8-7D7E45837146
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = SerialPortLib
> +
> +[Sources]
> + CspSerialPortLib.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + CadencePkg/CadenceCspPkg.dec
> + EmbeddedPkg/EmbeddedPkg.dec
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + DebugLib
> + IoLib
> + BaseLib
> + PcdLib
> +
> +[FixedPcd]
> + gCadenceCspTokenSpaceGuid.PcdCspSerialBase
> + gCadenceCspTokenSpaceGuid.PcdCspSysRegBase
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
> +
> diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni
> new file mode 100644
> index 0000000000000000000000000000000000000000..60434d42366ee99f53da028381deff21250cfda8
> GIT binary patch
> literal 1622
> zcmc(fL2uJQ5QXQA#D7?&7eK88T#z`CGzKi7juJ<OQ{^NjwUj2vP8<5?3*TGE-cW+X
> z1)<2^-PxHpZ{Cda<GyQMb3D)ZIeTMYt+1tC+GBf!Rd-`fCDt6fv!SgyZP<OpHf5jl
> z+;J{!WfeC$>x>u&mVBL^Vw+=W>=WzR$TExCEFs$|G2g&b#)Vz^Oiw^~3eHP=ZZGWB
> z0mK35m5*3)J0@OCF728%!qS7g*ay_gpA@C)Zh6nKY(3*8`z>hVe28NPuYyPi(~^h<
> z@0?uD*Djn59#SAji5VW(cuJQ$;#T-OEV*acC|k8!D5~_)OT49|bglUbL->joJNe%7
> zsAoCdQ0JW8crVozm`IJ1II(U}#7uYvObWl(?V7%YxIStQIIG)%OX%0uYcb>fd$k2Q
> zg(x*@y_8FxQPop;HhI+}saj9X&8}PG{2iZ%oPO1%Rznjw-NmnW3W(8WPghOThEBZp
> zldU<cwUvMAtBa_<q(5C4?AKdinZkT-Cl78SP_B5woT!rb7Q<)Al&AKNch5d?PSDb!
> zrq&E=Vtt#ii@m}VJ7bNp2ZW%0!Z#4(G4{wQJ59CT9aiBAwZq!?XPu7sYCq>*yi%Xh
> z**RV#&+H6)0;(`lpMAth++|bF3}5*uYwh(GUuFNo`hgoUKV~2AveZ??_PNCg=m}a3
> znJ48O?CBO}O8-S&&s{b>NA1+qUr(*y1xP6v6VPJ2fRXf)vOUzw;Pa>75na?*u%Pof
> rZ_S-%;RGx(?eP9r|9YLavcIcJGcl$f&C9Uu!=cLlXH^lJHQo9N7Zm#w
>
> literal 0
> HcmV?d00001
>
> --
> 2.2.2
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
On 22 June 2017 at 15:02, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Thu, Jun 22, 2017 at 10:31:57AM +0100, Scott Telford wrote:
>> Add serial port library to support the Cadence IP6528 UART used in the
>> Cadence CSP platform.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Scott Telford <stelford@cadence.com>
>
> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> CadencePkg/Include/Library/CspSerialPortLib.h | 86 ++++
>> .../CadenceCspSerialPortLib/CspSerialPortLib.c | 523 +++++++++++++++++++++
>> .../CadenceCspSerialPortLib/CspSerialPortLib.inf | 52 ++
>> .../CadenceCspSerialPortLib/CspSerialPortLib.uni | Bin 0 -> 1622 bytes
>> 4 files changed, 661 insertions(+)
>> create mode 100644 CadencePkg/Include/Library/CspSerialPortLib.h
>> create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
>> create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
>> create mode 100644 CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni
>>
>> diff --git a/CadencePkg/Include/Library/CspSerialPortLib.h b/CadencePkg/Include/Library/CspSerialPortLib.h
>> new file mode 100644
>> index 0000000..46fa0d8
>> --- /dev/null
>> +++ b/CadencePkg/Include/Library/CspSerialPortLib.h
>> @@ -0,0 +1,86 @@
>> +/** @file
>> +* Serial Port Library for Cadence IP6528 UART.
>> +* Copyright (c) 2017, Cadence Design Systems. All rights reserved.
>> +*
>> +* This program and the accompanying materials are licensed and made
>> +* available under the terms and conditions of the BSD License which
>> +* accompanies this distribution. The full text of the license may be
>> +* found at http://opensource.org/licenses/bsd-license.php
>> +*
>> +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
>> +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +*
>> +**/
>> +
>> +#ifndef __CSP_SERIAL_PORT_LIB_H__
>> +#define __CSP_SERIAL_PORT_LIB_H__
>> +
>> +// Cadence UART register offsets
>> +#define CSP_UART_CR 0x00 // Control
>> +#define CSP_UART_MR 0x04 // Mode
>> +#define CSP_UART_IER 0x08 // Interrupt enable
>> +#define CSP_UART_IDR 0x0C // Interrupt disable
>> +#define CSP_UART_IMR 0x10 // Interrupt mask
>> +#define CSP_UART_CISR 0x14 // Channel interrupt status
>> +#define CSP_UART_BRGR 0x18 // Baud rate generator
>> +#define CSP_UART_RTOR 0x1C // Rx Timeout
>> +#define CSP_UART_RTRIG 0x20 // Rx FIFO trigger level
>> +#define CSP_UART_MCR 0x24 // Modem control
>> +#define CSP_UART_MSR 0x28 // Modem status
>> +#define CSP_UART_CSR 0x2C // Channel status
>> +#define CSP_UART_FIFO 0x30 // FIFO (Tx/Rx)
>> +#define CSP_UART_BDIV 0x34 // Baud rate divider
>> +#define CSP_UART_FDEL 0x38 // Flow delay
>> +#define CSP_UART_PMIN 0x3C // IR min received pulse width
>> +#define CSP_UART_PWID 0x40 // IR transmitted pulse Width
>> +#define CSP_UART_TTRIG 0x44 // Tx FIFO trigger level
>> +
>> +
>> +// Control Register Bit Definitions
>> +#define CSP_UART_CR_STPBRK 0x00000100 // Stop Tx break
>> +#define CSP_UART_CR_STTBRK 0x00000080 // Start Tx break
>> +#define CSP_UART_CR_RSTTO 0x00000040 // Restart Rx timeout Counter
>> +#define CSP_UART_CR_TXDIS 0x00000020 // Tx disable
>> +#define CSP_UART_CR_TXEN 0x00000010 // Tx enable
>> +#define CSP_UART_CR_RXDIS 0x00000008 // Rx disable
>> +#define CSP_UART_CR_RXEN 0x00000004 // Rx enable
>> +#define CSP_UART_CR_TXRES 0x00000002 // Tx reset
>> +#define CSP_UART_CR_RXRES 0x00000001 // Rx reset
>> +
>> +
>> +// Mode register bit definitions
>> +#define CSP_UART_MR_CLKS 0x00000001 // Baud rate /8 pre-scalar
>> +#define CSP_UART_MR_CHMODE_LLB 0x00000200 // Local loopback mode
>> +#define CSP_UART_MR_CHMODE_NML 0x00000000 // Normal mode
>> +
>> +#define CSP_UART_MR_CHRL_6 0x00000006 // 6 databits
>> +#define CSP_UART_MR_CHRL_7 0x00000004 // 7 databits
>> +#define CSP_UART_MR_CHRL_8 0x00000000 // 8 databits
>> +
>> +#define CSP_UART_MR_PAR_NONE 0x00000020 // No parity mode
>> +#define CSP_UART_MR_PAR_MARK 0x00000018 // Mark parity mode
>> +#define CSP_UART_MR_PAR_SPACE 0x00000010 // Space parity mode
>> +#define CSP_UART_MR_PAR_ODD 0x00000008 // Odd parity mode
>> +#define CSP_UART_MR_PAR_EVEN 0x00000000 // Even parity mode
>> +
>> +#define CSP_UART_MR_NBSTOP_1 0x00000000 // 1 stop bit
>> +#define CSP_UART_MR_NBSTOP_2 0x00000080 // 2 stop bits
>> +
>> +// Modem control register bit definitions
>> +#define CSP_UART_MCR_DTR 0x00000001 // DTR control
>> +#define CSP_UART_MCR_RTS 0x00000002 // RTS control
>> +#define CSP_UART_MCR_FCM 0x00000020 // Auto flow control
>> +
>> +// Modem status register bit definitions
>> +#define CSP_UART_MSR_FCMS 0x00000100 // Auto flow control status
>> +#define CSP_UART_MSR_DCD 0x00000080 // DCD status
>> +#define CSP_UART_MSR_RI 0x00000040 // RI status
>> +#define CSP_UART_MSR_DSR 0x00000020 // DSR status
>> +#define CSP_UART_MSR_CTS 0x00000010 // CTS status
>> +
>> +// Channel status register bit definitions
>> +#define CSP_UART_CSR_REMPTY 0x00000002 // Rx FIFO empty
>> +#define CSP_UART_CSR_TEMPTY 0x00000008 // Tx FIFO empty
>> +#define CSP_UART_CSR_TFUL 0x00000010 // Tx FIFO full
>> +
>> +#endif
>> diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
>> new file mode 100644
>> index 0000000..9a9e14a
>> --- /dev/null
>> +++ b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.c
>> @@ -0,0 +1,523 @@
>> +/** @file
>> + Serial Port Library for Cadence IP6528 UART.
>> + Copyright (c) 2015-2017, Cadence Design Systems, Inc. All rights reserved.
>> +
>> + Based on:
>> +
>> + Null Serial Port library instance with empty functions.
>> +
>> + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
>> + This program and the accompanying materials
>> + are licensed and made available under the terms and conditions of the BSD License
>> + which accompanies this distribution. The full text of the license may be found at
>> + http://opensource.org/licenses/bsd-license.php.
>> +
>> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
>> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#include <Base.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/CspSerialPortLib.h>
>> +#include <Library/CspSysReg.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/SerialPortLib.h>
>> +
>> +
>> +RETURN_STATUS
>> +EFIAPI
>> +CspUartInitializePort (
>> + IN UINTN UartBase,
>> + IN OUT UINT64 *BaudRate,
>> + IN OUT EFI_PARITY_TYPE *Parity,
>> + IN OUT UINT8 *DataBits,
>> + IN OUT EFI_STOP_BITS_TYPE *StopBits
>> +);
>> +VOID CspUartPutChar (IN UINTN UartBase, IN UINT8 Char);
>> +UINT8 CspUartGetChar (IN UINTN UartBase);
>> +
>> +/**
>> + Initialize the serial device hardware.
>> +
>> + If no initialization is required, then return RETURN_SUCCESS.
>> + If the serial device was successfully initialized, then return RETURN_SUCCESS.
>> + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR.
>> +
>> + @retval RETURN_SUCCESS The serial device was initialized.
>> + @retval RETURN_DEVICE_ERROR The serial device could not be initialized.
>> +
>> +**/
>> +RETURN_STATUS
>> +EFIAPI
>> +SerialPortInitialize (
>> + VOID
>> + )
>> +{
>> + UINT64 BaudRate;
>> + EFI_PARITY_TYPE Parity;
>> + UINT8 DataBits;
>> + EFI_STOP_BITS_TYPE StopBits;
>> +
>> + BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
>> + Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
>> + DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
>> + StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
>> +
>> + return CspUartInitializePort (
>> + (UINTN)FixedPcdGet64 (PcdCspSerialBase),
>> + &BaudRate,
>> + &Parity,
>> + &DataBits,
>> + &StopBits
>> + );
>> +}
>> +
>> +/**
>> + Set new attributes to UART.
>> +
>> + @param BaudRate The baud rate of the serial device. If the
>> + baud rate is not supported, the speed will
>> + be reduced down to the nearest supported one
>> + and the variable's value will be updated
>> + accordingly.
>> + @param ReceiveFifoDepth The number of characters the device will
>> + buffer on input. If the specified value is
>> + not supported, the variable's value will
>> + be reduced down to the nearest supported one.
>> + @param Timeout If applicable, the number of microseconds the
>> + device will wait before timing out a Read or
>> + a Write operation.
>> + @param Parity If applicable, this is the EFI_PARITY_TYPE
>> + that is computed or checked as each character
>> + is transmitted or received. If the device
>> + does not support parity, the value is the
>> + default parity value.
>> + @param DataBits The number of data bits in each character
>> + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
>> + of stop bits per character. If the device
>> + does not support stop bits, the value is the
>> + default stop bit value.
>> +
>> + @retval EFI_SUCCESS All attributes were set correctly.
>> + @retval EFI_INVALID_PARAMETERS One or more attributes has an unsupported
>> + value.
>> +
>> +**/
>> +RETURN_STATUS
>> +EFIAPI
>> +SerialPortSetAttributes (
>> + IN OUT UINT64 *BaudRate,
>> + IN OUT UINT32 *ReceiveFifoDepth,
>> + IN OUT UINT32 *Timeout,
>> + IN OUT EFI_PARITY_TYPE *Parity,
>> + IN OUT UINT8 *DataBits,
>> + IN OUT EFI_STOP_BITS_TYPE *StopBits
>> + )
>> +{
>> + return CspUartInitializePort (
>> + (UINTN)FixedPcdGet64 (PcdCspSerialBase),
>> + BaudRate,
>> + Parity,
>> + DataBits,
>> + StopBits
>> + );
>> +}
>> +
>> +/**
>> + Write data from buffer to serial device.
>> +
>> + Writes NumberOfBytes data bytes from Buffer to the serial device.
>> + The number of bytes actually written to the serial device is returned.
>> + If the return value is less than NumberOfBytes, then the write operation failed.
>> + If Buffer is NULL, then ASSERT().
>> + If NumberOfBytes is zero, then return 0.
>> +
>> + @param Buffer The pointer to the data buffer to be written.
>> + @param NumberOfBytes The number of bytes to written to the serial device.
>> +
>> + @retval 0 NumberOfBytes is 0.
>> + @retval >0 The number of bytes written to the serial device.
>> + If this value is less than NumberOfBytes, then the read operation failed.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +SerialPortWrite (
>> + IN UINT8 *Buffer,
>> + IN UINTN NumberOfBytes
>> +)
>> +{
>> + UINTN i;
>> + for (i = 0; i < NumberOfBytes; i++) {
>> + CspUartPutChar ((UINTN)PcdGet64 (PcdCspSerialBase), Buffer[i]);
>> + }
>> + return i;
>> +}
>> +
>> +
>> +/**
>> + Read data from serial device and save the datas in buffer.
>> +
>> + Reads NumberOfBytes data bytes from a serial device into the buffer
>> + specified by Buffer. The number of bytes actually read is returned.
>> + If the return value is less than NumberOfBytes, then the rest operation failed.
>> + If Buffer is NULL, then ASSERT().
>> + If NumberOfBytes is zero, then return 0.
>> +
>> + @param Buffer The pointer to the data buffer to store the data read from the serial device.
>> + @param NumberOfBytes The number of bytes which will be read.
>> +
>> + @retval 0 Read data failed; No data is to be read.
>> + @retval >0 The actual number of bytes read from serial device.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +SerialPortRead (
>> + OUT UINT8 *Buffer,
>> + IN UINTN NumberOfBytes
>> +)
>> +{
>> + UINTN i;
>> + for (i = 0; i < NumberOfBytes; i++) {
>> + Buffer[i] = CspUartGetChar ((UINTN)PcdGet64 (PcdCspSerialBase));
>> + }
>> + return i;
>> +}
>> +
>> +/**
>> + Polls a serial device to see if there is any data waiting to be read.
>> +
>> + Polls a serial device to see if there is any data waiting to be read.
>> + If there is data waiting to be read from the serial device, then TRUE is returned.
>> + If there is no data waiting to be read from the serial device, then FALSE is returned.
>> +
>> + @retval TRUE Data is waiting to be read from the serial device.
>> + @retval FALSE There is no data waiting to be read from the serial device.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +SerialPortPoll (
>> + VOID
>> + )
>> +{
>> + return (MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase + CSP_UART_CSR))) &
>> + CSP_UART_CSR_REMPTY) ? FALSE : TRUE;
>> +}
>> +
>> +/**
>> +
>> + Assert or deassert the control signals on a serial port.
>> + The following control signals are set according their bit settings :
>> + . Request to Send
>> + . Data Terminal Ready
>> +
>> + @param[in] Control The following bits are taken into account :
>> + . EFI_SERIAL_REQUEST_TO_SEND : assert/deassert the
>> + "Request To Send" control signal if this bit is
>> + equal to one/zero.
>> + . EFI_SERIAL_DATA_TERMINAL_READY : assert/deassert
>> + the "Data Terminal Ready" control signal if this
>> + bit is equal to one/zero.
>> + . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : enable/disable
>> + the hardware loopback if this bit is equal to
>> + one/zero.
>> + . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : not supported.
>> + . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : enable/
>> + disable the hardware flow control based on CTS (Clear
>> + To Send) and RTS (Ready To Send) control signals.
>> +
>> + @retval RETURN_SUCCESS The new control bits were set on the device.
>> + @retval RETURN_UNSUPPORTED The device does not support this operation.
>> +
>> +**/
>> +RETURN_STATUS
>> +EFIAPI
>> +SerialPortSetControl (
>> + IN UINT32 Control
>> + )
>> +{
>> + UINT32 Bits;
>> +
>> + if (Control & (EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE |
>> + EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE )) {
>> + return RETURN_UNSUPPORTED;
>> + }
>> +
>> + Bits = MmioRead32 (PcdGet64 (PcdCspSerialBase) + CSP_UART_MCR);
>> +
>> + if (Control & EFI_SERIAL_REQUEST_TO_SEND) {
>> + Bits |= CSP_UART_MCR_RTS;
>> + } else {
>> + Bits &= ~CSP_UART_MCR_RTS;
>> + }
>> +
>> + if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {
>> + Bits |= CSP_UART_MCR_DTR;
>> + } else {
>> + Bits &= ~CSP_UART_MCR_DTR;
>> + }
>> +
>> + if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
>> + Bits |= CSP_UART_MCR_FCM;
>> + } else {
>> + Bits &= CSP_UART_MCR_FCM;
>> + }
>> +
>> + MmioWrite32 ((PcdGet64 (PcdCspSerialBase) + CSP_UART_MCR), Bits);
>> +
>> + return RETURN_SUCCESS;
>> +}
>> +
>> +/**
>> +
>> + Retrieve the status of the control bits on a serial device.
>> +
>> + @param[out] Control Status of the control bits on a serial device :
>> +
>> + . EFI_SERIAL_DATA_CLEAR_TO_SEND,
>> + EFI_SERIAL_DATA_SET_READY,
>> + EFI_SERIAL_RING_INDICATE,
>> + EFI_SERIAL_CARRIER_DETECT,
>> + EFI_SERIAL_REQUEST_TO_SEND,
>> + EFI_SERIAL_DATA_TERMINAL_READY
>> + are all related to the DTE (Data Terminal Equipment)
>> + and DCE (Data Communication Equipment) modes of
>> + operation of the serial device.
>> + . EFI_SERIAL_INPUT_BUFFER_EMPTY : equal to one if the
>> + receive buffer is empty, 0 otherwise.
>> + . EFI_SERIAL_OUTPUT_BUFFER_EMPTY : equal to one if the
>> + transmit buffer is empty, 0 otherwise.
>> + . EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE : equal to one if
>> + the hardware loopback is enabled (the output feeds
>> + the receive buffer), 0 otherwise.
>> + . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal to one
>> + if a loopback is accomplished by software, else 0.
>> + . EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE : equal to
>> + one if the hardware flow control based on CTS (Clear
>> + To Send) and RTS (Ready To Send) control signals is
>> + enabled, 0 otherwise.
>> +
>> + @retval RETURN_SUCCESS The control bits were read from the device.
>> +
>> +**/
>> +RETURN_STATUS
>> +EFIAPI
>> +SerialPortGetControl (
>> + OUT UINT32 *Control
>> + )
>> +{
>> + UINT32 ModemStatusReg;
>> + UINT32 ModemCtrlReg;
>> + UINT32 ChanStatusReg;
>> +
>> + ModemCtrlReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
>> + CSP_UART_MCR));
>> + ModemStatusReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
>> + CSP_UART_MSR));
>> + ChanStatusReg = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSerialBase) +
>> + CSP_UART_CSR));
>> +
>> + *Control = 0;
>> +
>> + if ((ModemStatusReg & CSP_UART_MSR_CTS) == CSP_UART_MSR_CTS) {
>> + *Control |= EFI_SERIAL_CLEAR_TO_SEND;
>> + }
>> +
>> + if ((ModemStatusReg & CSP_UART_MSR_DSR) == CSP_UART_MSR_DSR) {
>> + *Control |= EFI_SERIAL_DATA_SET_READY;
>> + }
>> +
>> + if ((ModemStatusReg & CSP_UART_MSR_RI) == CSP_UART_MSR_RI) {
>> + *Control |= EFI_SERIAL_RING_INDICATE;
>> + }
>> +
>> + if ((ModemStatusReg & CSP_UART_MSR_DCD) == CSP_UART_MSR_DCD) {
>> + *Control |= EFI_SERIAL_CARRIER_DETECT;
>> + }
>> +
>> + if ((ModemCtrlReg & CSP_UART_MCR_RTS) == CSP_UART_MCR_RTS) {
>> + *Control |= EFI_SERIAL_REQUEST_TO_SEND;
>> + }
>> +
>> + if ((ModemCtrlReg & CSP_UART_MCR_DTR) == CSP_UART_MCR_DTR) {
>> + *Control |= EFI_SERIAL_DATA_TERMINAL_READY;
>> + }
>> +
>> + if ((ChanStatusReg & CSP_UART_CSR_REMPTY) == CSP_UART_CSR_REMPTY) {
>> + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
>> + }
>> +
>> + if ((ChanStatusReg & CSP_UART_CSR_TEMPTY) == CSP_UART_CSR_TEMPTY) {
>> + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
>> + }
>> +
>> + if ((ModemCtrlReg & CSP_UART_MCR_FCM) == CSP_UART_MCR_FCM) {
>> + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
>> + }
>> +
>> + return RETURN_SUCCESS;
>> +}
>> +
>> +
>> +/**
>> +
>> + Initialise the serial port to the specified settings.
>> + The serial port is re-configured only if the specified settings
>> + are different from the current settings.
>> + All unspecified settings will be set to the default values.
>> +
>> + @param UartBase The base address of the serial device.
>> + @param BaudRate The baud rate of the serial device. If the
>> + baud rate is not supported, the speed will be
>> + reduced to the nearest supported one and the
>> + variable's value will be updated accordingly.
>> + @param Parity If applicable, this is the EFI_PARITY_TYPE
>> + that is computed or checked as each character
>> + is transmitted or received. If the device
>> + does not support parity, the value is the
>> + default parity value.
>> + @param DataBits The number of data bits in each character.
>> + @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
>> + of stop bits per character.
>> + If the device does not support stop bits, the
>> + value is the default stop bit value.
>> +
>> + @retval RETURN_SUCCESS All attributes were set correctly on the
>> + serial device.
>> + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an
>> + unsupported value.
>> +
>> +**/
>> +RETURN_STATUS
>> +EFIAPI
>> +CspUartInitializePort (
>> + IN UINTN UartBase,
>> + IN OUT UINT64 *BaudRate,
>> + IN OUT EFI_PARITY_TYPE *Parity,
>> + IN OUT UINT8 *DataBits,
>> + IN OUT EFI_STOP_BITS_TYPE *StopBits
>> + )
>> +{
>> + UINT32 RegVal = 0;
>> + UINT32 BaudDivisor = 0;
>> +
>> + // Wait for Tx FIFO to empty before initializing
>> + if (!(MmioRead32 (UartBase + CSP_UART_CR) & CSP_UART_CR_TXDIS)) {
>> + while (!(MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_TEMPTY))
>> + ;
>> + }
>> +
>> + // Disable Tx/Rx before setting baud rate
>> + RegVal = MmioRead32 (UartBase + CSP_UART_CR);
>> + RegVal |= CSP_UART_CR_TXDIS | CSP_UART_CR_RXDIS;
>> + MmioWrite32 ((UartBase + CSP_UART_CR), RegVal);
>> +
>> + // Set baud rate
>> + UINT32 SelClk = MmioRead32 ((UINTN)(PcdGet64 (PcdCspSysRegBase) +
>> + CSP_SYSREG_CPU_FREQ));
>> + UINT32 BDiv = 0;
>> +
>> + if (SelClk < 0x1800000) {
>> + BaudDivisor = 1;
>> + } else {
>> + BaudDivisor = 8;
>> + }
>> + MmioWrite32 ((UartBase + CSP_UART_BRGR), BaudDivisor);
>> + BDiv = (SelClk + ((*BaudRate * BaudDivisor) / 2)) / (*BaudRate * BaudDivisor);
>> + MmioWrite32 ((UartBase + CSP_UART_BDIV), (BDiv - 1));
>> +
>> + // Reset and enable Tx/Rx
>> + RegVal = MmioRead32 (UartBase + CSP_UART_CR);
>> + RegVal &= ~(CSP_UART_CR_TXDIS | CSP_UART_CR_RXDIS);
>> + RegVal |= CSP_UART_CR_TXEN | CSP_UART_CR_TXRES | \
>> + CSP_UART_CR_RXEN | CSP_UART_CR_RXRES;;
>> + MmioWrite32 ((UartBase + CSP_UART_CR), RegVal);
>> +
>> + RegVal = MmioRead32 (UartBase + CSP_UART_MR) & 1;
>> +
>> + //
>> + // Data Bits
>> + //
>> + switch (*DataBits) {
>> + case 0:
>> + *DataBits = 8;
>> + case 8:
>> + RegVal |= CSP_UART_MR_CHRL_8;
>> + break;
>> + case 7:
>> + RegVal |= CSP_UART_MR_CHRL_7;
>> + break;
>> + case 6:
>> + RegVal |= CSP_UART_MR_CHRL_6;
>> + break;
>> + default:
>> + return RETURN_INVALID_PARAMETER;
>> + }
>> +
>> + //
>> + // Stop Bits
>> + //
>> + switch (*StopBits) {
>> + case DefaultStopBits:
>> + *StopBits = OneStopBit;
>> + case OneStopBit:
>> + RegVal |= CSP_UART_MR_NBSTOP_1;
>> + break;
>> + case TwoStopBits:
>> + RegVal |= CSP_UART_MR_NBSTOP_2;
>> + break;
>> + default:
>> + return RETURN_INVALID_PARAMETER;
>> + }
>> +
>> + //
>> + // Parity
>> + //
>> + switch (*Parity) {
>> + case DefaultParity:
>> + *Parity = NoParity;
>> + case NoParity:
>> + RegVal |= CSP_UART_MR_PAR_NONE;
>> + break;
>> + case EvenParity:
>> + RegVal |= CSP_UART_MR_PAR_EVEN;
>> + break;
>> + case OddParity:
>> + RegVal |= CSP_UART_MR_PAR_ODD;
>> + break;
>> + case MarkParity:
>> + RegVal |= CSP_UART_MR_PAR_MARK;
>> + break;
>> + case SpaceParity:
>> + RegVal |= CSP_UART_MR_PAR_SPACE;
>> + break;
>> + default:
>> + return RETURN_INVALID_PARAMETER;
>> + }
>> +
>> + MmioWrite32 ((UartBase + CSP_UART_MR), RegVal);
>> +
>> + return RETURN_SUCCESS;
>> +}
>> +
>> +VOID CspUartPutChar (IN UINTN UartBase, IN UINT8 Char)
>> +{
>> + while ((MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_TFUL)
>> + == CSP_UART_CSR_TFUL)
>> + ;
>> + MmioWrite8 (UartBase + CSP_UART_FIFO, Char);
>> +}
>> +
>> +UINT8 CspUartGetChar (IN UINTN UartBase)
>> +{
>> + while ((MmioRead32 (UartBase + CSP_UART_CSR) & CSP_UART_CSR_REMPTY)
>> + == CSP_UART_CSR_REMPTY)
>> + ;
>> + return MmioRead8 (UartBase + CSP_UART_FIFO);
>> +}
>> +
>> diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
>> new file mode 100644
>> index 0000000..46ea8f9
>> --- /dev/null
>> +++ b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.inf
>> @@ -0,0 +1,52 @@
>> +## @file
>> +# Serial Port Library for Cadence IP6528 UART.
>> +#
>> +# Based on:
>> +#
>> +# Null instance of Serial Port Library with empty functions.
>> +#
>> +# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
>> +# Copyright (C) 2017 Cadence Design Systems. All rights reserved worldwide.
>> +#
>> +# This program and the accompanying materials
>> +# are licensed and made available under the terms and conditions of the BSD License
>> +# which accompanies this distribution. The full text of the license may be found at
>> +# http://opensource.org/licenses/bsd-license.php.
>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
>> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +#
>> +#
>> +##
>> +
>> +[Defines]
>> + INF_VERSION = 1.25
>> + BASE_NAME = CspSerialPortLib
>> + MODULE_UNI_FILE = CspSerialPortLib.uni
>> + FILE_GUID = C456789-8897-411a-91F8-7D7E45837146
>> + MODULE_TYPE = BASE
>> + VERSION_STRING = 1.0
>> + LIBRARY_CLASS = SerialPortLib
>> +
>> +[Sources]
>> + CspSerialPortLib.c
>> +
>> +[Packages]
>> + ArmPkg/ArmPkg.dec
>> + CadencePkg/CadenceCspPkg.dec
>> + EmbeddedPkg/EmbeddedPkg.dec
>> + MdePkg/MdePkg.dec
>> +
>> +[LibraryClasses]
>> + DebugLib
>> + IoLib
>> + BaseLib
>> + PcdLib
>> +
>> +[FixedPcd]
>> + gCadenceCspTokenSpaceGuid.PcdCspSerialBase
>> + gCadenceCspTokenSpaceGuid.PcdCspSysRegBase
>> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
>> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
>> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
>> + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
>> +
>> diff --git a/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni b/CadencePkg/Library/CadenceCspSerialPortLib/CspSerialPortLib.uni
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..60434d42366ee99f53da028381deff21250cfda8
>> GIT binary patch
>> literal 1622
>> zcmc(fL2uJQ5QXQA#D7?&7eK88T#z`CGzKi7juJ<OQ{^NjwUj2vP8<5?3*TGE-cW+X
>> z1)<2^-PxHpZ{Cda<GyQMb3D)ZIeTMYt+1tC+GBf!Rd-`fCDt6fv!SgyZP<OpHf5jl
>> z+;J{!WfeC$>x>u&mVBL^Vw+=W>=WzR$TExCEFs$|G2g&b#)Vz^Oiw^~3eHP=ZZGWB
>> z0mK35m5*3)J0@OCF728%!qS7g*ay_gpA@C)Zh6nKY(3*8`z>hVe28NPuYyPi(~^h<
>> z@0?uD*Djn59#SAji5VW(cuJQ$;#T-OEV*acC|k8!D5~_)OT49|bglUbL->joJNe%7
>> zsAoCdQ0JW8crVozm`IJ1II(U}#7uYvObWl(?V7%YxIStQIIG)%OX%0uYcb>fd$k2Q
>> zg(x*@y_8FxQPop;HhI+}saj9X&8}PG{2iZ%oPO1%Rznjw-NmnW3W(8WPghOThEBZp
>> zldU<cwUvMAtBa_<q(5C4?AKdinZkT-Cl78SP_B5woT!rb7Q<)Al&AKNch5d?PSDb!
>> zrq&E=Vtt#ii@m}VJ7bNp2ZW%0!Z#4(G4{wQJ59CT9aiBAwZq!?XPu7sYCq>*yi%Xh
>> z**RV#&+H6)0;(`lpMAth++|bF3}5*uYwh(GUuFNo`hgoUKV~2AveZ??_PNCg=m}a3
>> znJ48O?CBO}O8-S&&s{b>NA1+qUr(*y1xP6v6VPJ2fRXf)vOUzw;Pa>75na?*u%Pof
>> rZ_S-%;RGx(?eP9r|9YLavcIcJGcl$f&C9Uu!=cLlXH^lJHQo9N7Zm#w
>>
>> literal 0
>> HcmV?d00001
>>
>> --
>> 2.2.2
>>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2026 Red Hat, Inc.