From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-x231.google.com (mail-wr0-x231.google.com [IPv6:2a00:1450:400c:c0c::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3507321C943CF for ; Thu, 22 Jun 2017 08:00:44 -0700 (PDT) Received: by mail-wr0-x231.google.com with SMTP id c11so27039054wrc.3 for ; Thu, 22 Jun 2017 08:02:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=xo5aljb7olJKgzntdQFKd247eJdg2oB9h0tmVPXoBeA=; b=j4lz2QXd4mZlSbzL9Em3i4lolFIqEtm+gnHcebtw8D+s4NjVXcd7P0bTWU8R65NqbO A7ho0YmDlqogJ8iMLYx4V06eNwh7Vndr13+0G33ewzrsAVBTA1C+xxC9+9eFKcASwMZg 4SZZ1JpC/cEc0DLJ7LbLkRKRsDx4hP5nI3Ey4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=xo5aljb7olJKgzntdQFKd247eJdg2oB9h0tmVPXoBeA=; b=QmnvseB5TezTDXbmFgKFRa6Ecg1/93ZcSqijZKPGpxO3aQOe/tOtnEktmykpGSor1a k5pnhOO9xioqPETMfWyrLkVTfbI6leWNPaz5vqjfU4LEM/MzlQTzXP1NLSV6nHwm+jvj ROOrUyOeVsCP+WVasqR/Eh3o+X23v+OnreqmmoXsLYFUBnLJbACRO7V8kjXhQlLDWvT6 ahAY3j7LbsoBZNgqqCUc7DsjebkKVKjFNjOmdnXGFjK8+rFkFC3/nfQbru7jO3BgZ+lq O0sO6+knLYkvL7XOkj6da4KBs9y25pT5Yxz30ondgAgKOfuG06QfqpCA+9J2bVKj7rK+ gQYA== X-Gm-Message-State: AKS2vOybLTr90jNhdOmUydEC8ik537z4JqCsWPkp8E3O8rQ1Th+5HxCY pmG/5W/CC0+a8kwJ X-Received: by 10.28.7.18 with SMTP id 18mr1099398wmh.20.1498143727345; Thu, 22 Jun 2017 08:02:07 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id 94sm675732wrp.63.2017.06.22.08.02.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 22 Jun 2017 08:02:05 -0700 (PDT) Date: Thu, 22 Jun 2017 16:02:04 +0100 From: Leif Lindholm To: Scott Telford Cc: edk2-devel@ml01.01.org, ard.biesheuvel@linaro.org, graeme.gregory@linaro.org, afish@apple.com, michael.d.kinney@intel.com Message-ID: <20170622150204.GL26676@bivouac.eciton.net> References: <1498123921-4638-1-git-send-email-stelford@cadence.com> <1498123921-4638-3-git-send-email-stelford@cadence.com> MIME-Version: 1.0 In-Reply-To: <1498123921-4638-3-git-send-email-stelford@cadence.com> User-Agent: Mutt/1.5.23 (2014-03-12) Subject: Re: [staging/cadence-aarch64 PATCH v3 2/6] CadencePkg: Add library for Cadence UART. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Jun 2017 15:00:44 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 Reviewed-by: Leif Lindholm > --- > 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.
> + 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > + > +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.
> +# 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 z1)<2^-PxHpZ{Cda 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 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 >