From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from EUR04-VI1-obe.outbound.protection.outlook.com (EUR04-VI1-obe.outbound.protection.outlook.com [40.107.8.71]) by mx.groups.io with SMTP id smtpd.web12.1330.1581060240337512135 for ; Thu, 06 Feb 2020 23:24:01 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@nxp.com header.s=selector2 header.b=IdBRQImc; spf=pass (domain: nxp.com, ip: 40.107.8.71, mailfrom: pankaj.bansal@nxp.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ky/M6RUJja7Micraz3sR5fhCyh0fErIgCbQREeEXjTHLqYe9NY7RZ9AbB/Ig7EfUd33T286Cr7oHYmQhiS6wwt0EOc3ZRC45/amV/uDWo7M3tR2gNEPFCMwIIDNtAR5On7NLmZS5EmShigf9RucLXt7K8wPS4ebL+5SknJLMBLccL7MNGgVLS8/RbLbA2BedOcBTdBkEZaV3Q/ol2mJ9gcH/JdnVNxp1d+6mPNPRYRXf+HG0WZtuOmGUcwMqsIkjriZ7ephfjFb+eYa5JmYkMS8o2pLBatPupESu+Ec5318ORmQO4tvq055p6e2MJmu72vZs9Tp7LiDmoeVqCfREWQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=QomWWu9PmeEY5LV+gw8yo2T8p1D2hJA6M5Ud5N8p30I=; b=NFPzzWtNkxYc1Kn6iD86NxCEJvTbYq81qyddDckpjuoVcjCmD9jft7D7Mx0KHfZa+fGx0yeLrWXZfrGM4vQAOT98w3FUY1SGWVpl3CcoZE1gsQFHK0X0CTV0TSoFL7V9leXxvv+Dv7yg5CSBSlhwt/4yZiDyEepRegkOzT2IBzCoPOD79LryFzU4qPONdyaej/M9wBISie7w9G5AGH6VxMRcCPPpX22ms9b7gDIC81SO37hfutKw90O9TN9QbuPbv3dmoMPdSDVjhbwVoIIdK0N8rEdk4SMBVZ92ird3CdRXDQwFrDKw9vCN1KwSY+BTsxgod5dcaicYzX1dee2kyQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com; dkim=pass header.d=nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=QomWWu9PmeEY5LV+gw8yo2T8p1D2hJA6M5Ud5N8p30I=; b=IdBRQImcN8c/sgIoyKI62ZZIxg2THZ9spqGIUAXi2Xxpr49acnct5bgmoQh5xw3yECKs2ZFTLRWXO38EkpU+QDfVTEnH78uFI2XcxQ5bFsfOiGXI1a6Fmlz6BwOJUYr5e22NOjRrUQ07jdBGmyWNZhFQZ7h2AZYahH1ShTR9j6k= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pankaj.bansal@nxp.com; Received: from VI1PR0401MB2496.eurprd04.prod.outlook.com (10.168.65.10) by VI1PR0401MB2686.eurprd04.prod.outlook.com (10.168.67.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2707.21; Fri, 7 Feb 2020 07:23:57 +0000 Received: from VI1PR0401MB2496.eurprd04.prod.outlook.com ([fe80::8823:663d:c6ed:cbd6]) by VI1PR0401MB2496.eurprd04.prod.outlook.com ([fe80::8823:663d:c6ed:cbd6%12]) with mapi id 15.20.2686.036; Fri, 7 Feb 2020 07:23:57 +0000 From: "Pankaj Bansal" To: Leif Lindholm , Meenakshi Aggarwal , Michael D Kinney , Varun Sethi Cc: devel@edk2.groups.io, Pankaj Bansal Subject: [PATCH 04/19] Silicon/NXP: Remove DuartLib and use BaseSerialPortLib16550 Date: Fri, 7 Feb 2020 18:13:13 +0530 Message-Id: <20200207124328.8723-5-pankaj.bansal@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200207124328.8723-1-pankaj.bansal@nxp.com> References: <20200207124328.8723-1-pankaj.bansal@nxp.com> X-ClientProxiedBy: PN1PR01CA0103.INDPRD01.PROD.OUTLOOK.COM (2603:1096:c00::19) To VI1PR0401MB2496.eurprd04.prod.outlook.com (2603:10a6:800:56::10) Return-Path: pankaj.bansal@nxp.com MIME-Version: 1.0 Received: from uefi-workstation.ap.freescale.net (92.120.1.69) by PN1PR01CA0103.INDPRD01.PROD.OUTLOOK.COM (2603:1096:c00::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2707.21 via Frontend Transport; Fri, 7 Feb 2020 07:23:55 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [92.120.1.69] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 3a052b5a-f94a-4ac1-2938-08d7ab9eb1a5 X-MS-TrafficTypeDiagnostic: VI1PR0401MB2686:|VI1PR0401MB2686: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-Forefront-PRVS: 0306EE2ED4 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4636009)(136003)(376002)(346002)(39860400002)(366004)(396003)(199004)(189003)(316002)(66556008)(66476007)(66946007)(5660300002)(44832011)(478600001)(2616005)(956004)(30864003)(4326008)(52116002)(110136005)(26005)(6506007)(16526019)(186003)(1076003)(36756003)(8676002)(6512007)(6636002)(6666004)(19627235002)(81166006)(6486002)(81156014)(2906002)(86362001)(8936002)(326664003)(579004);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0401MB2686;H:VI1PR0401MB2496.eurprd04.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; Received-SPF: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +P31yoU7D21M/qVh1KLm75ICQmSK+9If8PFs2IIfSAFqJcsDqjmgdZDEMBX6Bo3CdBu/Tiejeftpre1Q3MtB6Yplf3HZ5eTIMHAF5cmgZS8otWOXHvXa39uoqG8OJvoARW+mJUHmoMsZzVghvZ8pGfAyfMWXoezrwyDYxY/MH53r4aFkrYeCPTaedFLXm0n1/vojeX0xveLHMrag2MLvVa2bEVVsxuw6+GrZWz2qlp7ZvHNpeWZDAxMRHrhFq5ip4GLcGhFeXRMf0wPyw7ptrEgIinJHIyEfikUCv3lgye7UopauFc8ZgBFIJ9S/V7Nb/XtNC2lEjsKytcIMRkS+yMFxYDJ0/7OVDz/yR7U9dR4foLz+SPR76yd7b07QP2SgjN7YS85EikEt4S/LNk+mNBOQBSNw5ZTpx+7q3XqaLtKFaS8ETgDj1w1CZQEknyriL6DHTjynJyABUrAT1UAZc5HztomW71SAqgMfV94J1L30Ep8pD/9vf+1GRGBBJswa X-MS-Exchange-AntiSpam-MessageData: Hpry9LYQ51A590Xa76gE8J+6lwQuyPyX7i/q6mWj4mIl3XzGgZxJBVHKX39da2um+2TYG3Q3rDkeKY6/MntRZHLnQnrC069vzdeEBBkeZi80ZoGRD0gI26KVyTVqBfWqC2cdvnTZtndwkPx1xs2XOA== X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3a052b5a-f94a-4ac1-2938-08d7ab9eb1a5 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Feb 2020 07:23:57.2776 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: khi3I2bz+AY8jYEoTbicBaeTG0DSr02RYnYqUsmrTCJvqqwuuiJyLOvrgoFbp3BbAwapzKhDrsZdAHHfW8+gGQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2686 Content-Type: text/plain UART in LS1043A conforms to ns16550 register set. so we can use the SerialPortLib16550 from MdeModulePkg. We have removed the PCIe specific part from the library and also added the APIs to get the UART clock from SOC lib instead of using the fixed PCD. Signed-off-by: Pankaj Bansal --- Silicon/NXP/LS1043A/LS1043A.dsc.inc | 2 +- .../BaseSerialPortLib16550.c | 804 ++++++++++++++++++ .../BaseSerialPortLib16550.inf | 39 + .../BaseSerialPortLib16550.uni | 17 + Silicon/NXP/Library/DUartPortLib/DUart.h | 122 --- .../NXP/Library/DUartPortLib/DUartPortLib.c | 364 -------- .../NXP/Library/DUartPortLib/DUartPortLib.inf | 34 - 7 files changed, 861 insertions(+), 521 deletions(-) create mode 100644 Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c create mode 100644 Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf create mode 100644 Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni delete mode 100644 Silicon/NXP/Library/DUartPortLib/DUart.h delete mode 100644 Silicon/NXP/Library/DUartPortLib/DUartPortLib.c delete mode 100644 Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf diff --git a/Silicon/NXP/LS1043A/LS1043A.dsc.inc b/Silicon/NXP/LS1043A/LS1043A.dsc.inc index 8790db6ff8..754eff396a 100644 --- a/Silicon/NXP/LS1043A/LS1043A.dsc.inc +++ b/Silicon/NXP/LS1043A/LS1043A.dsc.inc @@ -9,7 +9,7 @@ [LibraryClasses.common] SocLib|Silicon/NXP/Library/SocLib/LS1043aSocLib.inf - SerialPortLib|Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf + SerialPortLib|Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf ################################################################################ # diff --git a/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c new file mode 100644 index 0000000000..2c5c54ac7d --- /dev/null +++ b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c @@ -0,0 +1,804 @@ +/** @file + 16550 UART Serial Port library functions + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2018, AMD Incorporated. All rights reserved.
+ Copyright 2020 NXP + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +// +// 16550 UART register offsets and bitfields +// +#define R_UART_RXBUF 0 // LCR_DLAB = 0 +#define R_UART_TXBUF 0 // LCR_DLAB = 0 +#define R_UART_BAUD_LOW 0 // LCR_DLAB = 1 +#define R_UART_BAUD_HIGH 1 // LCR_DLAB = 1 +#define R_UART_IER 1 // LCR_DLAB = 0 +#define R_UART_FCR 2 +#define B_UART_FCR_FIFOE BIT0 +#define B_UART_FCR_FIFO64 BIT5 +#define R_UART_LCR 3 +#define B_UART_LCR_DLAB BIT7 +#define R_UART_MCR 4 +#define B_UART_MCR_DTRC BIT0 +#define B_UART_MCR_RTS BIT1 +#define R_UART_LSR 5 +#define B_UART_LSR_RXRDY BIT0 +#define B_UART_LSR_TXRDY BIT5 +#define B_UART_LSR_TEMT BIT6 +#define R_UART_MSR 6 +#define B_UART_MSR_CTS BIT4 +#define B_UART_MSR_DSR BIT5 +#define B_UART_MSR_RI BIT6 +#define B_UART_MSR_DCD BIT7 + +extern +UINT64 +GetBusFrequency ( + VOID + ); + +/** + Read an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is read from + MMIO space. If PcdSerialUseMmio is FALSE, then the value is read from I/O space. The + parameter Offset is added to the base address of the 16550 registers that is specified + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the MMIO space access + width and defaults to 8 bit access, and supports 8 or 32 bit access. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to read. + + @return The value read from the 16550 register. + +**/ +UINT8 +SerialPortReadRegister ( + UINTN Base, + UINTN Offset + ) +{ + return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); +} + +/** + Write an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is written to + MMIO space. If PcdSerialUseMmio is FALSE, then the value is written to I/O space. The + parameter Offset is added to the base address of the 16550 registers that is specified + by PcdSerialRegisterBase. PcdSerialRegisterAccessWidth specifies the MMIO space access + width and defaults to 8 bit access, and supports 8 or 32 bit access. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to write. + @param Value The value to write to the 16550 register specified by Offset. + + @return The value written to the 16550 register. + +**/ +UINT8 +SerialPortWriteRegister ( + UINTN Base, + UINTN Offset, + UINT8 Value + ) +{ + return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); +} + +/** + Retrieve the I/O or MMIO base address register for the PCI UART device. + + This function assumes Root Bus Numer is Zero, and enables I/O and MMIO in PCI UART + Device if they are not already enabled. + + @return The base address register of the UART device. + +**/ +UINTN +GetSerialRegisterBase ( + VOID + ) +{ + return (UINTN)PcdGet64 (PcdSerialRegisterBase); +} + +/** + Return whether the hardware flow control signal allows writing. + + @param SerialRegisterBase The base address register of UART device. + + @retval TRUE The serial port is writable. + @retval FALSE The serial port is not writable. +**/ +BOOLEAN +SerialPortWritable ( + UINTN SerialRegisterBase + ) +{ + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + if (PcdGetBool (PcdSerialDetectCable)) { + // + // Wait for both DSR and CTS to be set + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // === === ======================================== ======== + // 0 0 No cable connected. Wait + // 0 1 No cable connected. Wait + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clear to send. Transmit + // + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS)); + } else { + // + // Wait for both DSR and CTS to be set OR for DSR to be clear. + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // === === ======================================== ======== + // 0 0 No cable connected. Transmit + // 0 1 No cable connected. Transmit + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clar to send. Transmit + // + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR)); + } + } + + return TRUE; +} + +/** + 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 + ) +{ + UINTN SerialRegisterBase; + UINT32 Divisor; + UINT32 CurrentDivisor; + BOOLEAN Initialized; + UINT64 SerialClock; + + // + // Perform platform specific initialization required to enable use of the 16550 device + // at the location specified by PcdSerialUseMmio and PcdSerialRegisterBase. + // + SerialClock = GetBusFrequency (); + if (SerialClock == 0) { + return EFI_DEVICE_ERROR; + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor = SerialClock / (PcdGet32 (PcdSerialBaudRate) * 16); + if ((SerialClock % (PcdGet32 (PcdSerialBaudRate) * 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) { + Divisor++; + } + + // + // Get the base address of the serial port in either I/O or MMIO space + // + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase == 0) { + return RETURN_DEVICE_ERROR; + } + + // + // See if the serial port is already initialized + // + Initialized = TRUE; + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) { + Initialized = FALSE; + } + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB)); + CurrentDivisor = SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH) << 8; + CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB)); + if (CurrentDivisor != Divisor) { + Initialized = FALSE; + } + if (Initialized) { + return RETURN_SUCCESS; + } + + // + // Wait for the serial port to be ready. + // Verify that both the transmit FIFO and the shift register are empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from PcdSerialLineControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F)); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); + + // + // Set FIFO Polled Mode by clearing IER after setting FCR + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_IER, 0x00); + + // + // Put Modem Control Register(MCR) into its reset state of 0x00. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00); + + return RETURN_SUCCESS; +} + +/** + 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 Pointer to the data buffer to be written. + @param NumberOfBytes 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 write operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINTN Index; + UINTN FifoSize; + + if (Buffer == NULL) { + return 0; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return 0; + } + + if (NumberOfBytes == 0) { + // + // Flush the hardware + // + + // + // Wait for both the transmit FIFO and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); + + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)); + return 0; + } + + // + // Compute the maximum size of the Tx FIFO + // + FifoSize = 1; + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) { + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) { + FifoSize = 16; + } else { + FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize); + } + } + + Result = NumberOfBytes; + while (NumberOfBytes != 0) { + // + // Wait for the serial port to be ready, to make sure both the transmit FIFO + // and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); + + // + // Fill then entire Tx FIFO + // + for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) { + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)); + + // + // Write byte to the transmit buffer. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer); + } + } + return Result; +} + +/** + Reads data from a serial device into a buffer. + + @param Buffer Pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes Number of bytes to read from the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes read from the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINT8 Mcr; + + if (NULL == Buffer) { + return 0; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return 0; + } + + Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS); + + for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) { + // + // Wait for the serial port to have some data. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) == 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr | B_UART_MCR_RTS)); + } + } + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + } + + // + // Read byte from the receive buffer. + // + *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF); + } + + return Result; +} + + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls aserial 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 + ) +{ + UINTN SerialRegisterBase; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return FALSE; + } + + // + // Read the serial port status + // + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) != 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS)); + } + return TRUE; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS)); + } + + return FALSE; +} + +/** + Sets the control bits on a serial device. + + @param Control Sets the bits of Control that are settable. + + @retval RETURN_SUCCESS The new control bits were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Mcr; + + // + // First determine the parameter is invalid. + // + if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY | + EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) { + return RETURN_UNSUPPORTED; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_UNSUPPORTED; + } + + // + // Read the Modem Control Register. + // + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS)); + + if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) { + Mcr |= B_UART_MCR_DTRC; + } + + if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) { + Mcr |= B_UART_MCR_RTS; + } + + // + // Write the Modem Control Register. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + + return RETURN_SUCCESS; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control signals from the serial device. + + @retval RETURN_SUCCESS The control bits were read from the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Msr; + UINT8 Mcr; + UINT8 Lsr; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_UNSUPPORTED; + } + + *Control = 0; + + // + // Read the Modem Status Register. + // + Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR); + + if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) { + *Control |= EFI_SERIAL_CLEAR_TO_SEND; + } + + if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) { + *Control |= EFI_SERIAL_DATA_SET_READY; + } + + if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) { + *Control |= EFI_SERIAL_RING_INDICATE; + } + + if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) { + *Control |= EFI_SERIAL_CARRIER_DETECT; + } + + // + // Read the Modem Control Register. + // + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + + if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) { + *Control |= EFI_SERIAL_DATA_TERMINAL_READY; + } + + if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) { + *Control |= EFI_SERIAL_REQUEST_TO_SEND; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + + // + // Read the Line Status Register. + // + Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR); + + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + + if ((Lsr & B_UART_LSR_RXRDY) == 0) { + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + On output, the value actually set. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + On output, the value actually set. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + On output, the value actually set. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + On output, the value actually set. + + @retval RETURN_SUCCESS The new attributes were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +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 + ) +{ + UINTN SerialRegisterBase; + UINT32 SerialBaudRate; + UINTN Divisor; + UINT8 Lcr; + UINT8 LcrData; + UINT8 LcrParity; + UINT8 LcrStop; + UINT64 SerialClock; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_UNSUPPORTED; + } + + SerialClock = GetBusFrequency (); + if (SerialClock == 0) { + return EFI_DEVICE_ERROR; + } + + // + // Check for default settings and fill in actual values. + // + if (*BaudRate == 0) { + *BaudRate = PcdGet32 (PcdSerialBaudRate); + } + SerialBaudRate = (UINT32) *BaudRate; + + if (*DataBits == 0) { + LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3); + *DataBits = LcrData + 5; + } else { + if ((*DataBits < 5) || (*DataBits > 8)) { + return RETURN_INVALID_PARAMETER; + } + // + // Map 5..8 to 0..3 + // + LcrData = (UINT8) (*DataBits - (UINT8) 5); + } + + if (*Parity == DefaultParity) { + LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); + switch (LcrParity) { + case 0: + *Parity = NoParity; + break; + + case 3: + *Parity = EvenParity; + break; + + case 1: + *Parity = OddParity; + break; + + case 7: + *Parity = SpaceParity; + break; + + case 5: + *Parity = MarkParity; + break; + + default: + break; + } + } else { + switch (*Parity) { + case NoParity: + LcrParity = 0; + break; + + case EvenParity: + LcrParity = 3; + break; + + case OddParity: + LcrParity = 1; + break; + + case SpaceParity: + LcrParity = 7; + break; + + case MarkParity: + LcrParity = 5; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + if (*StopBits == DefaultStopBits) { + LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); + switch (LcrStop) { + case 0: + *StopBits = OneStopBit; + break; + + case 1: + if (*DataBits == 5) { + *StopBits = OneFiveStopBits; + } else { + *StopBits = TwoStopBits; + } + break; + + default: + break; + } + } else { + switch (*StopBits) { + case OneStopBit: + LcrStop = 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + LcrStop = 1; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor = SerialClock / (SerialBaudRate * 16); + if ((SerialClock % (SerialBaudRate * 16)) >= SerialBaudRate * 8) { + Divisor++; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from line control value + // + Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr & 0x3F)); + + return RETURN_SUCCESS; +} + diff --git a/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf new file mode 100644 index 0000000000..45ae9dc0af --- /dev/null +++ b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf @@ -0,0 +1,39 @@ +## @file +# SerialPortLib instance for 16550 UART. +# +# Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+# Copyright 2020 NXP +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseSerialPortLib16550 + MODULE_UNI_FILE = BaseSerialPortLib16550.uni + FILE_GUID = 9E7C00CF-355A-4d4e-BF60-0428CFF95540 + MODULE_TYPE = BASE + VERSION_STRING = 1.1 + LIBRARY_CLASS = SerialPortLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + PcdLib + IoLib + SocLib + +[Sources] + BaseSerialPortLib16550.c + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES diff --git a/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni new file mode 100644 index 0000000000..2fefe85cf8 --- /dev/null +++ b/Silicon/NXP/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.uni @@ -0,0 +1,17 @@ +// /** @file +// SerialPortLib instance for 16550 UART. +// +// SerialPortLib instance for 16550 UART. +// +// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+// Copyright 2020 NXP +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "SerialPortLib instance for 16550 UART" + +#string STR_MODULE_DESCRIPTION #language en-US "SerialPortLib instance for 16550 UART." + diff --git a/Silicon/NXP/Library/DUartPortLib/DUart.h b/Silicon/NXP/Library/DUartPortLib/DUart.h deleted file mode 100644 index c71e2ce55d..0000000000 --- a/Silicon/NXP/Library/DUartPortLib/DUart.h +++ /dev/null @@ -1,122 +0,0 @@ -/** DUart.h -* Header defining the DUART constants (Base addresses, sizes, flags) -* -* Based on Serial I/O Port library headers available in PL011Uart.h -* -* Copyright (c) 2011-2012, ARM Limited. All rights reserved. -* Copyright (c) 2016, Freescale Semiconductor, Inc. All rights reserved. -* Copyright 2017 NXP -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#ifndef DUART_H_ -#define DUART_H_ - -// FIFO Control Register -#define DUART_FCR_FIFO_EN 0x01 /* Fifo enable */ -#define DUART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ -#define DUART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ -#define DUART_FCR_DMA_SELECT 0x08 /* For DMA applications */ -#define DUART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ -#define DUART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ -#define DUART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */ -#define DUART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */ -#define DUART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */ -#define DUART_FCR_RXSR 0x02 /* Receiver soft reset */ -#define DUART_FCR_TXSR 0x04 /* Transmitter soft reset */ - -// Modem Control Register -#define DUART_MCR_DTR 0x01 /* Reserved */ -#define DUART_MCR_RTS 0x02 /* RTS */ -#define DUART_MCR_OUT1 0x04 /* Reserved */ -#define DUART_MCR_OUT2 0x08 /* Reserved */ -#define DUART_MCR_LOOP 0x10 /* Enable loopback test mode */ -#define DUART_MCR_AFE 0x20 /* AFE (Auto Flow Control) */ -#define DUART_MCR_DMA_EN 0x04 -#define DUART_MCR_TX_DFR 0x08 - -// Line Control Register -/* -* Note: if the word length is 5 bits (DUART_LCR_WLEN5), then setting -* DUART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. -*/ -#define DUART_LCR_WLS_MSK 0x03 /* character length select mask */ -#define DUART_LCR_WLS_5 0x00 /* 5 bit character length */ -#define DUART_LCR_WLS_6 0x01 /* 6 bit character length */ -#define DUART_LCR_WLS_7 0x02 /* 7 bit character length */ -#define DUART_LCR_WLS_8 0x03 /* 8 bit character length */ -#define DUART_LCR_STB 0x04 /* # stop Bits, off=1, on=1.5 or 2) */ -#define DUART_LCR_PEN 0x08 /* Parity eneble */ -#define DUART_LCR_EPS 0x10 /* Even Parity Select */ -#define DUART_LCR_STKP 0x20 /* Stick Parity */ -#define DUART_LCR_SBRK 0x40 /* Set Break */ -#define DUART_LCR_BKSE 0x80 /* Bank select enable */ -#define DUART_LCR_DLAB 0x80 /* Divisor latch access bit */ - -// Line Status Register -#define DUART_LSR_DR 0x01 /* Data ready */ -#define DUART_LSR_OE 0x02 /* Overrun */ -#define DUART_LSR_PE 0x04 /* Parity error */ -#define DUART_LSR_FE 0x08 /* Framing error */ -#define DUART_LSR_BI 0x10 /* Break */ -#define DUART_LSR_THRE 0x20 /* Xmit holding register empty */ -#define DUART_LSR_TEMT 0x40 /* Xmitter empty */ -#define DUART_LSR_ERR 0x80 /* Error */ - -// Modem Status Register -#define DUART_MSR_DCTS 0x01 /* Delta CTS */ -#define DUART_MSR_DDSR 0x02 /* Reserved */ -#define DUART_MSR_TERI 0x04 /* Reserved */ -#define DUART_MSR_DDCD 0x08 /* Reserved */ -#define DUART_MSR_CTS 0x10 /* Clear to Send */ -#define DUART_MSR_DSR 0x20 /* Reserved */ -#define DUART_MSR_RI 0x40 /* Reserved */ -#define DUART_MSR_DCD 0x80 /* Reserved */ - -// Interrupt Identification Register -#define DUART_IIR_NO_INT 0x01 /* No interrupts pending */ -#define DUART_IIR_ID 0x06 /* Mask for the interrupt ID */ -#define DUART_IIR_MSI 0x00 /* Modem status interrupt */ -#define DUART_IIR_THRI 0x02 /* Transmitter holding register empty */ -#define DUART_IIR_RDI 0x04 /* Receiver data interrupt */ -#define DUART_IIR_RLSI 0x06 /* Receiver line status interrupt */ - -// Interrupt Enable Register -#define DUART_IER_MSI 0x08 /* Enable Modem status interrupt */ -#define DUART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ -#define DUART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ -#define DUART_IER_RDI 0x01 /* Enable receiver data interrupt */ - -// LCR defaults -#define DUART_LCR_8N1 0x03 -#define DUART_LCRVAL DUART_LCR_8N1 /* 8 data, 1 stop, no parity */ -#define DUART_MCRVAL (DUART_MCR_DTR | \ - DUART_MCR_RTS) /* RTS/DTR */ -#define DUART_FCRVAL (DUART_FCR_FIFO_EN | \ - DUART_FCR_RXSR | \ - DUART_FCR_TXSR) /* Clear & enable FIFOs */ - -#define URBR 0x0 -#define UTHR 0x0 -#define UDLB 0x0 -#define UDMB 0x1 -#define UIER 0x1 -#define UIIR 0x2 -#define UFCR 0x2 -#define UAFR 0x2 -#define ULCR 0x3 -#define UMCR 0x4 -#define ULSR 0x5 -#define UMSR 0x6 -#define USCR 0x7 -#define UDSR 0x10 - -extern -UINT64 -GetBusFrequency ( - VOID - ); - -#endif /* DUART_H_ */ diff --git a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.c b/Silicon/NXP/Library/DUartPortLib/DUartPortLib.c deleted file mode 100644 index c3c738d3cc..0000000000 --- a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.c +++ /dev/null @@ -1,364 +0,0 @@ -/** DuartPortLib.c - DUART (NS16550) library functions - - Based on Serial I/O Port library functions available in PL011SerialPortLib.c - - Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
- Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.
- Copyright (c) 2016, Freescale Semiconductor, Inc. All rights reserved. - Copyright 2017 NXP - - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include - -#include "DUart.h" - -STATIC CONST UINT32 mInvalidControlBits = (EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \ - EFI_SERIAL_DATA_TERMINAL_READY); - -/** - 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 EFI_SUCCESS The new control bits were set on the device. - @retval EFI_UNSUPPORTED The device does not support this operation. - -**/ -EFI_STATUS -EFIAPI -SerialPortSetControl ( - IN UINT32 Control - ) -{ - UINT32 McrBits; - UINTN UartBase; - - UartBase = (UINTN)PcdGet64 (PcdSerialRegisterBase); - - if (Control & (mInvalidControlBits)) { - return EFI_UNSUPPORTED; - } - - McrBits = MmioRead8 (UartBase + UMCR); - - if (Control & EFI_SERIAL_REQUEST_TO_SEND) { - McrBits |= DUART_MCR_RTS; - } else { - McrBits &= ~DUART_MCR_RTS; - } - - if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) { - McrBits |= DUART_MCR_LOOP; - } else { - McrBits &= ~DUART_MCR_LOOP; - } - - if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) { - McrBits |= DUART_MCR_AFE; - } else { - McrBits &= ~DUART_MCR_AFE; - } - - MmioWrite32 (UartBase + UMCR, McrBits); - - return EFI_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 ouput feeds the - receive buffer), 0 otherwise. - . EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE : equal to one if - a loopback is accomplished by software, 0 otherwise. - . 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 EFI_SUCCESS The control bits were read from the serial device. - -**/ -EFI_STATUS -EFIAPI -SerialPortGetControl ( - OUT UINT32 *Control - ) -{ - UINT32 MsrRegister; - UINT32 McrRegister; - UINT32 LsrRegister; - UINTN UartBase; - - UartBase = (UINTN)PcdGet64 (PcdSerialRegisterBase); - - MsrRegister = MmioRead8 (UartBase + UMSR); - McrRegister = MmioRead8 (UartBase + UMCR); - LsrRegister = MmioRead8 (UartBase + ULSR); - - *Control = 0; - - if ((MsrRegister & DUART_MSR_CTS) == DUART_MSR_CTS) { - *Control |= EFI_SERIAL_CLEAR_TO_SEND; - } - - if ((McrRegister & DUART_MCR_RTS) == DUART_MCR_RTS) { - *Control |= EFI_SERIAL_REQUEST_TO_SEND; - } - - if ((LsrRegister & DUART_LSR_TEMT) == DUART_LSR_TEMT) { - *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; - } - - if ((McrRegister & DUART_MCR_AFE) == DUART_MCR_AFE) { - *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; - } - - if ((McrRegister & DUART_MCR_LOOP) == DUART_MCR_LOOP) { - *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE; - } - - return EFI_SUCCESS; -} - -/* - * Return Baud divisor on basis of Baudrate - */ -UINT32 -CalculateBaudDivisor ( - IN UINT64 BaudRate - ) -{ - UINTN DUartClk; - UINTN FreqSystemBus; - - FreqSystemBus = GetBusFrequency (); - DUartClk = FreqSystemBus/PcdGet32(PcdPlatformFreqDiv); - - return ((DUartClk)/(BaudRate * 16)); -} - -/* - Initialise the serial port to the specified settings. - All unspecified settings will be set to the default values. - - @return Always return EFI_SUCCESS or EFI_INVALID_PARAMETER. - - **/ -VOID -EFIAPI -DuartInitializePort ( - IN UINT64 BaudRate - ) -{ - UINTN UartBase; - UINT32 BaudDivisor; - - UartBase = (UINTN)PcdGet64 (PcdSerialRegisterBase); - BaudDivisor = CalculateBaudDivisor (BaudRate); - - - while (!(MmioRead8 (UartBase + ULSR) & DUART_LSR_TEMT)); - - // - // Enable and assert interrupt when new data is available on - // external device, - // setup data format, setup baud divisor - // - MmioWrite8 (UartBase + UIER, 0x1); - MmioWrite8 (UartBase + ULCR, DUART_LCR_BKSE | DUART_LCRVAL); - MmioWrite8 (UartBase + UDLB, 0); - MmioWrite8 (UartBase + UDMB, 0); - MmioWrite8 (UartBase + ULCR, DUART_LCRVAL); - MmioWrite8 (UartBase + UMCR, DUART_MCRVAL); - MmioWrite8 (UartBase + UFCR, DUART_FCRVAL); - MmioWrite8 (UartBase + ULCR, DUART_LCR_BKSE | DUART_LCRVAL); - MmioWrite8 (UartBase + UDLB, BaudDivisor & 0xff); - MmioWrite8 (UartBase + UDMB, (BaudDivisor >> 8) & 0xff); - MmioWrite8 (UartBase + ULCR, DUART_LCRVAL); - - return; -} - -/** - Programmed hardware of Serial port. - - @return Always return EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -SerialPortInitialize ( - VOID - ) -{ - UINT64 BaudRate; - BaudRate = (UINTN)PcdGet64 (PcdUartDefaultBaudRate); - - - DuartInitializePort (BaudRate); - - return EFI_SUCCESS; -} - -/** - Write data to serial device. - - @param Buffer Point of data buffer which need to be written. - @param NumberOfBytes Number of output bytes which are cached in Buffer. - - @retval 0 Write data failed. - @retval !0 Actual number of bytes written to serial device. - -**/ -UINTN -EFIAPI -SerialPortWrite ( - IN UINT8 *Buffer, - IN UINTN NumberOfBytes - ) -{ - UINT8 *Final; - UINTN UartBase; - - Final = &Buffer[NumberOfBytes]; - UartBase = (UINTN)PcdGet64 (PcdSerialRegisterBase); - - while (Buffer < Final) { - while ((MmioRead8 (UartBase + ULSR) & DUART_LSR_THRE) == 0); - MmioWrite8 (UartBase + UTHR, *Buffer++); - } - - return NumberOfBytes; -} - -/** - Read data from serial device and save the data in buffer. - - @param Buffer Point of data buffer which need to be written. - @param NumberOfBytes Number of output bytes which are cached in Buffer. - - @retval 0 Read data failed. - @retval !0 Actual number of bytes read from serial device. - -**/ -UINTN -EFIAPI -SerialPortRead ( - OUT UINT8 *Buffer, - IN UINTN NumberOfBytes - ) -{ - UINTN Count; - UINTN UartBase; - - UartBase = (UINTN)PcdGet64 (PcdSerialRegisterBase); - - for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) { - // Loop while waiting for a new char(s) to arrive in the - // RxFIFO - while ((MmioRead8 (UartBase + ULSR) & DUART_LSR_DR) == 0); - - *Buffer = MmioRead8 (UartBase + URBR); - } - - return NumberOfBytes; -} - -/** - Check to see if any data is available to be read from the debug device. - - @retval EFI_SUCCESS At least one byte of data is available to be read - @retval EFI_NOT_READY No data is available to be read - @retval EFI_DEVICE_ERROR The serial device is not functioning properly - -**/ -BOOLEAN -EFIAPI -SerialPortPoll ( - VOID - ) -{ - UINTN UartBase; - - UartBase = (UINTN)PcdGet64 (PcdSerialRegisterBase); - - return ((MmioRead8 (UartBase + ULSR) & DUART_LSR_DR) != 0); -} - -/** - Set new attributes to LS1043a. - - @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 on the serial device. - -**/ -EFI_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 - ) -{ - DuartInitializePort (*BaudRate); - - return EFI_SUCCESS; -} diff --git a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf b/Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf deleted file mode 100644 index 7a2fa619b0..0000000000 --- a/Silicon/NXP/Library/DUartPortLib/DUartPortLib.inf +++ /dev/null @@ -1,34 +0,0 @@ -# DUartPortLib.inf -# -# Component description file for DUartPortLib module -# -# Copyright (c) 2013, Freescale Ltd. All rights reserved. -# Copyright 2017 NXP -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# - -[Defines] - INF_VERSION = 0x0001001A - BASE_NAME = DUartPortLib - FILE_GUID = c42dfe79-8de5-429e-a055-2d0a58591498 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = SerialPortLib - -[Sources.common] - DUartPortLib.c - -[LibraryClasses] - PcdLib - SocLib - -[Packages] - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - Silicon/NXP/NxpQoriqLs.dec - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate - gNxpQoriqLsTokenSpaceGuid.PcdPlatformFreqDiv -- 2.17.1