summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-03-11 09:04:44 -0800
committerGary King <gking@nvidia.com>2010-03-11 20:28:30 -0800
commitd7410ca658ea62a51163655f000cf20c640c76f9 (patch)
treecb3821cc28bd1df23ec18a98d8cc05a430ad6df8 /arch
parent01ba7d51e2e9456c1a99b2454553259edd09d373 (diff)
serial: delete tegra DDK serial driver
this driver is no longer being used, and its continued existence just causes confusion. Change-Id: Ia5b4a350b6590bbd0e8914625e9e81951096fb8c Reviewed-on: http://git-master/r/843 Reviewed-by: John Davis <jodavis@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/nvddk/Makefile3
-rw-r--r--arch/arm/mach-tegra/nvddk/ap15ddk_uart_hw_private.c965
-rw-r--r--arch/arm/mach-tegra/nvddk/ddkuart_hw_private.h390
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_uart.c2834
4 files changed, 0 insertions, 4192 deletions
diff --git a/arch/arm/mach-tegra/nvddk/Makefile b/arch/arm/mach-tegra/nvddk/Makefile
index 15a897de16bf..347675bb74cb 100644
--- a/arch/arm/mach-tegra/nvddk/Makefile
+++ b/arch/arm/mach-tegra/nvddk/Makefile
@@ -19,8 +19,5 @@ endif
obj-$(CONFIG_KEYBOARD_TEGRA) += nvddk_kbc.o
obj-$(CONFIG_MTD_NAND_TEGRA) += nvddk_nand.o
-obj-$(CONFIG_SERIAL_TEGRA_DDK) += nvddk_uart.o
-obj-$(CONFIG_SERIAL_TEGRA_DDK) += ap15ddk_uart_hw_private.o
-
obj-$(CONFIG_MMC_TEGRA_SDIO) += nvddk_sdio.o
obj-$(CONFIG_TEGRA_SNOR) += nvsnor_controller.o
diff --git a/arch/arm/mach-tegra/nvddk/ap15ddk_uart_hw_private.c b/arch/arm/mach-tegra/nvddk/ap15ddk_uart_hw_private.c
deleted file mode 100644
index 8d4320ec94f9..000000000000
--- a/arch/arm/mach-tegra/nvddk/ap15ddk_uart_hw_private.c
+++ /dev/null
@@ -1,965 +0,0 @@
-/*
- * Copyright (c) 2007-2009 NVIDIA Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NVIDIA Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * @file
- * @brief <b>nVIDIA Driver Development Kit:
- * Private functions for the uart hw access</b>
- *
- * @b Description: Implements the private interfacing functions for the uart
- * hw interface.
- *
- */
-
-#include "nvrm_drf.h"
-#include "ddkuart_hw_private.h"
-#include "nvrm_hardware_access.h"
-#include "nvassert.h"
-
-// hardware includes
-#include "ap15/aruart.h"
-
-// Allowed uart baud rate accuracy in percent. As per theory, it should be 5%
-enum {UART_BAUDRATE_ACCURACY = 5};
-
-#define UART_REG_READ32(pUartHwRegsVirtBaseAdd, reg) \
- NV_READ32((pUartHwRegsVirtBaseAdd) + ((UART_##reg##_0)/4))
-
-#define UART_REG_WRITE32(pUartHwRegsVirtBaseAdd, reg, val) \
- do { \
- NV_WRITE32((((pUartHwRegsVirtBaseAdd) + ((UART_##reg##_0)/4))), (val)); \
- } while (0)
-
-#define IS_POSSIBLE_RX_ERROR (NV_DRF_DEF(UART, LSR, BRK, BREAK) | \
- NV_DRF_DEF(UART, LSR, FIFOE, ERR) | \
- NV_DRF_DEF(UART, LSR, FERR, FRAME_ERR) | \
- NV_DRF_DEF(UART, LSR, OVRF, OVERRUN_ERROR) | \
- NV_DRF_DEF(UART, LSR, PERR, PARITY_ERR))
-
-#define IS_DATA_IN_FIFO NV_DRF_DEF(UART, LSR, RDR, DATA_IN_FIFO)
-
-#define TX_EMPTY_STATUS (NV_DRF_DEF(UART, LSR, TMTY, EMPTY) | \
- NV_DRF_DEF(UART, LSR, THRE, EMPTY))
-
-/**
- * Initialize the uart register.
- */
-void NvDdkPrivUartHwRegisterInitialize(NvU32 CommChannelId, UartHwRegisters *pUartHwRegs)
-{
- // Initialize the member of Uart hw register structure.
- pUartHwRegs->ModemSignalSatus = 0;
- pUartHwRegs->IsRtsHwFlowSupported = NV_FALSE;
- pUartHwRegs->IsEndOfDataIntSupport = NV_FALSE;
-
- pUartHwRegs->FcrRegister = 0;
- pUartHwRegs->IerRegister = 0;
- pUartHwRegs->LcrRegister = 0;
- pUartHwRegs->McrRegister = 0;
- pUartHwRegs->DllRegister = 0;
- pUartHwRegs->DlmRegister = 0;
-
- pUartHwRegs->IsDmaMode = NV_TRUE;
- pUartHwRegs->pRegsVirtBaseAdd = NULL;
- pUartHwRegs->ChannelId = CommChannelId;
- pUartHwRegs->RegsPhyBaseAdd = 0;
- pUartHwRegs->BankSize = 0;
- pUartHwRegs->TransmitTrigLevel = 1;
- pUartHwRegs->IsRtsActive = NV_FALSE;
- pUartHwRegs->IsDtrActive = NV_FALSE;
-}
-
-/**
- * Initialize the uart fifos.
- */
-void NvDdkPrivUartHwInitFifo(UartHwRegisters *pUartHwRegs)
-{
- pUartHwRegs->FcrRegister = NV_DRF_DEF(UART, IIR_FCR, FCR_EN_FIFO, ENABLE);
- NvDdkPrivUartHwResetFifo(pUartHwRegs, UartDataDirection_Both);
- NvDdkPrivUartHwSetFifoTriggerLevel(pUartHwRegs, UartDataDirection_Both, 4);
- NvDdkPrivUartHwUpdateModemSignal(pUartHwRegs);
- NvDdkPrivUartHwSetModemSignal(pUartHwRegs, NvDdkUartSignalName_Rts, NV_FALSE);
- }
-
-/**
- * Get the clock frequency required related to the baud rate.
- */
-void
-NvDdkPrivUartHwGetReqdClockSourceFreq(
- NvU32 BaudRate,
- NvU32 *pMinClockFreqReqd,
- NvU32 *pClockFreqReqd,
- NvU32 *pMaxClockFreqReqd)
-{
- NvU32 MaxClockFreqReq = 0;
- NvU32 MinClockFreqReq = 0;
- NvU32 ClockFreqReqd = 0;
-
- *pMinClockFreqReqd = 1;
- *pClockFreqReqd = 1;
- *pMaxClockFreqReqd = 1;
-
- // Required clock frequency in KHz.
- // Required clock freq is 16 times of the required baudrate.
- ClockFreqReqd = (BaudRate *16)/1000;
- if (!ClockFreqReqd)
- ClockFreqReqd = 1;
-
- // Minimum clock frequency required, -5%
- MinClockFreqReq = (NvU32)NvDiv64(((100 - UART_BAUDRATE_ACCURACY)* (NvU64)BaudRate *16), (1000*100));
- if (!MinClockFreqReq)
- MinClockFreqReq = 1;
-
- // Maximum clock frequency required, +5%
- MaxClockFreqReq = (NvU32)NvDiv64(((100 + UART_BAUDRATE_ACCURACY)* (NvU64)BaudRate *16),(1000*100));
- if (MaxClockFreqReq <= ClockFreqReqd)
- MaxClockFreqReq = ClockFreqReqd + 1;
-
- *pMinClockFreqReqd = MinClockFreqReq;
- *pClockFreqReqd = ClockFreqReqd;
- *pMaxClockFreqReqd = MaxClockFreqReq;
-}
-
-/**
- * Set the baud rate of uart communication.
- */
-NvError
-NvDdkPrivUartHwSetBaudRate(
- UartHwRegisters *pUartHwRegs,
- NvU32 BaudRate,
- NvU32 ClockSourceFreq)
-{
- NvU32 BaudRateConstant;
-
- // Calculated baud rate constant for 5% boundary.
- NvU32 CalcBRL;
- NvU32 CalcBRH;
-
- // boundary of the baudrate.
- NvU32 BR_Dev_L;
- NvU32 BR_Dev_H;
-
- NvU32 ClockFreq;
-
- // Final baud rate constant.
- NvU32 FinalBaudRateConstant = 0;
- NvU32 BaudrateDll;
- NvU32 BaudrateDlm;
- NvU32 LcrValue;
-
- // Get the upper and lower baud rate constant calculation.
- BR_Dev_L = (BaudRate - (BaudRate * UART_BAUDRATE_ACCURACY)/100);
- BR_Dev_H = (BaudRate + (BaudRate * UART_BAUDRATE_ACCURACY)/100);
-
- // Search the clock source which gives the proper baud rate constant
- // for given baud rate.
- // Get the baud rate constant for given clock frequency.
- ClockFreq = ClockSourceFreq*1000;
- BaudRateConstant = (ClockFreq /(BaudRate*16));
-
- // If baud rate constant is becoming 0 then it will not be possible to set
- // the baud rate.
- if (!BaudRateConstant)
- return NvError_NotSupported;
-
- // Get the baud rate with calculated baud rate constant and +1.
- CalcBRH = (ClockFreq)/(BaudRateConstant *16);
- CalcBRL = (ClockFreq)/((BaudRateConstant+1) *16);
-
- // If calculated low baud rate is in up/down 5 percent baudrates then
- // we have got the correct clock source.
- if ((CalcBRL >= BR_Dev_L) && (CalcBRL <= BR_Dev_H))
- FinalBaudRateConstant = BaudRateConstant+1;
- else if ((CalcBRH >= BR_Dev_L) && (CalcBRH <= BR_Dev_H))
- FinalBaudRateConstant = BaudRateConstant;
- else
- return NvError_NotSupported;
-
- // Get the lower byte and upper byte of the baud rate constant.
- BaudrateDll = FinalBaudRateConstant & 0xFF;
- BaudrateDlm = (FinalBaudRateConstant >> 8) & 0xFF;
-
- pUartHwRegs->DllRegister = BaudrateDll;
- pUartHwRegs->DlmRegister = BaudrateDlm;
-
- // Enable the LCR-DLAB.
- LcrValue = pUartHwRegs->LcrRegister;
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, DLAB, ENABLE, LcrValue);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
-
- // Program the lower and upper bytes of the baud rate constant.
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, THR_DLAB_0, BaudrateDll);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, BaudrateDlm);
-
- // Disable the DLAB.
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, DLAB, DISABLE, LcrValue);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
- return NvSuccess;
-}
-
-/**
- * Set the parity of uart communication.
- */
-NvError
-NvDdkPrivUartHwSetParityBit(
- UartHwRegisters *pUartHwRegs,
- NvDdkUartParity ParityBit)
-{
- NvU32 LcrValue;
-
- // Get the Lcr register value and set the parity as per per requirement.
- LcrValue = pUartHwRegs->LcrRegister;
- switch (ParityBit)
- {
- case NvDdkUartParity_None:
- // No parity
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, PAR, NO_PARITY, LcrValue);
- break;
-
- case NvDdkUartParity_Odd:
- // Odd parity
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, PAR, PARITY, LcrValue);
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, EVEN, DISABLE, LcrValue);
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, SET_P, NO_PARITY, LcrValue);
- break;
-
- case NvDdkUartParity_Even:
- // Even parity.
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, PAR, PARITY, LcrValue);
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, EVEN, ENABLE, LcrValue);
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, SET_P, NO_PARITY, LcrValue);
- break;
-
- default:
- // Unknown type of parameter.
- return NvError_NotSupported;
- }
-
- pUartHwRegs->LcrRegister = LcrValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
- return NvSuccess;
-}
-
-/**
- * Set the data length of uart communication.
- */
-NvError
-NvDdkPrivUartHwSetDataLength(
- UartHwRegisters *pUartHwRegs,
- NvU32 DataLength)
-{
- NvU32 LcrValue;
-
- // Get the lcr register value.
- LcrValue = pUartHwRegs->LcrRegister;
- if (DataLength == 5)
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, WD_SIZE, WORD_LENGTH_5, LcrValue);
- else if (DataLength == 6)
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, WD_SIZE, WORD_LENGTH_6, LcrValue);
- else if (DataLength == 7)
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, WD_SIZE, WORD_LENGTH_7, LcrValue);
- else if (DataLength == 8)
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, WD_SIZE, WORD_LENGTH_8, LcrValue);
- else
- return NvError_NotSupported;
-
- pUartHwRegs->LcrRegister = LcrValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
- return NvSuccess;
-}
-
-/**
- * Set the stop bit of uart communication.
- */
-NvError NvDdkPrivUartHwSetStopBit(
- UartHwRegisters *pUartHwRegs,
- NvDdkUartStopBit StopBit)
-{
- NvU32 LcrValue;
-
- // Get the lcr register value and configured for the stop bit.
- LcrValue = pUartHwRegs->LcrRegister;
- if (StopBit == NvDdkUartStopBit_1)
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, STOP, DISABLE, LcrValue);
- else if ((StopBit == NvDdkUartStopBit_1_5) || (StopBit == NvDdkUartStopBit_2))
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, STOP, ENABLE, LcrValue);
- else
- return NvError_NotSupported;
- pUartHwRegs->LcrRegister = LcrValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
- return NvSuccess;
-}
-
-/**
- * Start/stop sending the break control signal.
- */
-void NvDdkPrivUartHwSetBreakControlSignal(
- UartHwRegisters *pUartHwRegs,
- NvBool IsStart)
-{
- NvU32 LcrValue;
- // Get the lcr register value and configured the break send control bit.
- LcrValue = pUartHwRegs->LcrRegister;
- if (IsStart)
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, SET_B, BREAK, LcrValue);
- else
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, SET_B, NO_BREAK, LcrValue);
- pUartHwRegs->LcrRegister = LcrValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
-}
-
-/**
- * Reset the uart fifo register.
- */
-void
-NvDdkPrivUartHwResetFifo(
- UartHwRegisters *pUartHwRegs,
- UartDataDirection FifoType)
-{
- NvU32 FcrValue;
-
- // Get the Fcr register value.
- FcrValue = pUartHwRegs->FcrRegister;
-
- // Get the fifo type whether receive and transmit fifo.
- // Reset the rx or tx fifo.
- if (FifoType & UartDataDirection_Receive)
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, RX_CLR, CLEAR, FcrValue);
-
- if (FifoType & UartDataDirection_Transmit)
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, TX_CLR, CLEAR, FcrValue);
-
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IIR_FCR, FcrValue);
-}
-
-/**
- * Set the fifo trigger level of uart fifo.
- */
-void
-NvDdkPrivUartHwSetFifoTriggerLevel(
- UartHwRegisters *pUartHwRegs,
- UartDataDirection FifoType,
- NvU32 TriggerLevel)
-{
- NvU32 FcrValue;
-
- // Get the fcr register value and configured for the receive and transmit
- // fifo trigger level.
- FcrValue = pUartHwRegs->FcrRegister;
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, FCR_EN_FIFO, ENABLE, FcrValue);
-
- // If it is receive fifo then configure the rx trigger value.
- if (FifoType & UartDataDirection_Receive)
- {
- switch (TriggerLevel)
- {
- case 1:
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, RX_TRIG,
- FIFO_COUNT_GREATER_1, FcrValue);
- break;
-
- case 4:
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, RX_TRIG,
- FIFO_COUNT_GREATER_4, FcrValue);
- break;
-
- case 8:
- // Fix me ar issue
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, RX_TRIG,
- FIFO_COUNT_GREATER_8, FcrValue);
- break;
-
- default:
- // Fix me ar issue
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, RX_TRIG,
- FIFO_COUNT_GREATER_12, FcrValue);
- break;
- }
- }
- if (FifoType & UartDataDirection_Transmit)
- {
- // It is for transmit fifo, configure for tx fifo trigger level.
- switch (TriggerLevel)
- {
- case 1:
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, TX_TRIG,
- FIFO_COUNT_GREATER_1, FcrValue);
- pUartHwRegs->TransmitTrigLevel = 1;
- break;
-
- case 4:
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, TX_TRIG,
- FIFO_COUNT_GREATER_4, FcrValue);
- pUartHwRegs->TransmitTrigLevel = 4;
- break;
-
- case 8:
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, TX_TRIG,
- FIFO_COUNT_GREATER_8, FcrValue);
- pUartHwRegs->TransmitTrigLevel = 8;
- break;
-
- default:
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, TX_TRIG,
- FIFO_COUNT_GREATER_12, FcrValue);
-
- pUartHwRegs->TransmitTrigLevel = 12;
- break;
- }
- }
-
- // If no error then write into the uart register. Also update the soft copy
- // of fcr register.
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IIR_FCR, FcrValue);
- pUartHwRegs->FcrRegister = FcrValue;
-}
-
-/**
- * Set the dma mode operation of uart
- */
-void NvDdkPrivUartHwSetDmaMode(UartHwRegisters *pUartHwRegs, NvBool IsEnable)
-{
- NvU32 FcrValue;
-
- // Get the fcr register value and enable/disable the dma bit and write into
- // the register.
- FcrValue = pUartHwRegs->FcrRegister;
- if (IsEnable)
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, DMA, CHANGE, FcrValue);
- else
- FcrValue = NV_FLD_SET_DRF_DEF(UART, IIR_FCR, DMA, NO_CHANGE, FcrValue);
-
- pUartHwRegs->IsDmaMode = IsEnable;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IIR_FCR, FcrValue);
- pUartHwRegs->FcrRegister = FcrValue;
-}
-
-/**
- * Write into the transmit fifo register.
- * Returns the number of bytes written.
- */
-NvU32
-NvDdkPrivUartHwWriteInTransmitFifo(
- UartHwRegisters *pUartHwRegs,
- NvU8 *pTxBuff,
- NvU32 BytesRequested)
-{
- NvU32 BytesToWrite;
- NvU32 TransmitChar;
- NvU32 DataWritten = 0;
-
- // This function is called once the trigger level interrupt is reach.
- // Write the data same as the trigger level without checking the fifo status.
- BytesToWrite = NV_MIN(BytesRequested, pUartHwRegs->TransmitTrigLevel);
-
- while (BytesToWrite)
- {
- TransmitChar = (NvU32)(*pTxBuff);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, THR_DLAB_0, TransmitChar);
- pTxBuff++;
- BytesToWrite--;
- DataWritten++;
- }
- return DataWritten;
-}
-
-/**
- * Write into the transmit fifo register.
- * Returns the number of bytes written.
- */
-NvU32
-NvDdkPrivUartHwPollingWriteInTransmitFifo(
- UartHwRegisters *pUartHwRegs,
- NvU8 *pTxBuff,
- NvU32 BytesRequested)
-{
- NvU32 BytesToWrite = BytesRequested;
- NvU32 TransmitChar;
- NvU32 LsrValue;
-
- while (BytesToWrite)
- {
- LsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, LSR);
- if (!(LsrValue & (NV_DRF_DEF(UART, LSR, TMTY, EMPTY))))
- break;
- TransmitChar = (NvU32)(*pTxBuff);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, THR_DLAB_0, TransmitChar);
- pTxBuff++;
- BytesToWrite--;
- }
- return (BytesRequested - BytesToWrite);
-}
-
-/**
- * Check whether the Transmit fifo is empty or not.
- * Returns TRUE if the Tx fifo is empty otherwise returns FALSE.
- */
-NvBool NvDdkPrivUartHwIsTransmitFifoEmpty(UartHwRegisters *pUartHwRegs)
-{
- NvU32 LsrValue;
- LsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, LSR);
- if ((LsrValue & TX_EMPTY_STATUS) == TX_EMPTY_STATUS)
- return NV_TRUE;
- else
- return NV_FALSE;
-}
-
-NvBool NvDdkPrivUartHwIsBreakSignalDetected(UartHwRegisters *pUartHwRegs)
-{
- NvBool IsBreakDetected = NV_FALSE;
- NvU32 LsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, LSR);
- if (LsrValue & NV_DRF_DEF(UART, LSR, BRK, BREAK))
- {
- IsBreakDetected = NV_TRUE;
-
- // Again read the LSR and if there is fifo error with data then reset
- // here
- LsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, LSR);
- if (LsrValue & NV_DRF_DEF(UART, LSR, FIFOE, ERR))
- {
- if (LsrValue & NV_DRF_DEF(UART, LSR, RDR, DATA_IN_FIFO))
- return IsBreakDetected;
-
- // Fifo error without rx data
- NvDdkPrivUartHwResetFifo(pUartHwRegs, UartDataDirection_Receive);
- }
- }
-
- return IsBreakDetected;
-}
-
-/**
- * Read the data from the receive fifo.
- */
-NvBool NvDdkPrivUartHwIsDataAvailableInFifo(UartHwRegisters *pUartHwRegs)
-{
- NvU32 LsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, LSR);
- if (LsrValue & NV_DRF_DEF(UART, LSR, RDR, DATA_IN_FIFO))
- return NV_TRUE;
- return NV_FALSE;
-}
-
-/**
- * Read the data from the receive fifo.
- */
-NvError
-NvDdkPrivUartHwReadFromReceiveFifo(
- UartHwRegisters *pUartHwRegs,
- NvU8 *pRxBuff,
- NvU32 MaxByteRequested,
- NvU32 *pBytesRead)
-{
- NvError Error = NvSuccess;
- NvU32 BytesToRead;
- NvU32 LsrValue = 0;
- NvU8 ReadChar;
- NvU32 DataRead = 0;
-
- // Get how many bytes to be read.
- BytesToRead = MaxByteRequested;
-
- // Read till bytes required to be read is there.
- while (BytesToRead)
- {
- // Get the Line status register and check for the error.
- LsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, LSR);
-
- // Check if any type of error occurred.
- if (LsrValue & IS_POSSIBLE_RX_ERROR)
- {
- if (LsrValue & NV_DRF_DEF(UART, LSR, OVRF, OVERRUN_ERROR))
- {
- // Overrun error
- Error = NvError_UartOverrun;
- }
- else if (LsrValue & NV_DRF_DEF(UART, LSR, PERR, PARITY_ERR))
- {
- // Parity error
- Error = NvError_UartParity;
- }
- else if (LsrValue & NV_DRF_DEF(UART, LSR, FERR, FRAME_ERR))
- {
- // Framing error
- Error = NvError_UartFraming;
- }
- else if (LsrValue & NV_DRF_DEF(UART, LSR, FIFOE, ERR))
- {
- // Fifo error
- Error = NvSuccess;
- NvDdkPrivUartHwResetFifo(pUartHwRegs, UartDataDirection_Receive);
- *pBytesRead = 0;
- }
- else if (LsrValue & NV_DRF_DEF(UART, LSR, BRK, BREAK))
- {
- // Break signal received.
- Error = NvError_UartBreakReceived;
- }
- break;
- }
-
- // No error in fifo, check if data is available and if then read from
- // receive fifo.
- if (LsrValue & IS_DATA_IN_FIFO)
- {
- ReadChar = (NvU8)((UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, THR_DLAB_0)) & 0xFF);
- *pRxBuff++ = ReadChar;
- BytesToRead--;
- DataRead++;
- }
- else
- {
- // Fifo is empty so exit from loop.
- break;
- }
- }
-
- *pBytesRead = DataRead;
- return Error;
-}
-
-void NvDdkPrivUartHwClearAllInt(UartHwRegisters *pUartHwRegs)
-{
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, 0);
- pUartHwRegs->IerRegister = 0;
-}
-
-void NvDdkPrivUartHwSetReceiveInterrupt(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable,
- NvBool IsRxUsingApbDma)
-{
- NvU32 IerValue;
-
- // Get the IER register value.
- IerValue = pUartHwRegs->IerRegister;
-
- // Enable/disable the interrupt bit for the receive fifo ready and
- // receive line status error.
- if (IsEnable)
- {
- if (IsRxUsingApbDma)
- {
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RXS, ENABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RX_TIMEOUT, ENABLE, IerValue);
- if (pUartHwRegs->IsEndOfDataIntSupport)
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_EORD, ENABLE, IerValue);
- }
- else
- {
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RHR, ENABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RXS, ENABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RX_TIMEOUT, ENABLE, IerValue);
- }
- }
- else
- {
- if (IsRxUsingApbDma)
- {
- // Sw workaround to disable the rx timeout interrupt.
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RHR, ENABLE, IerValue);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, IerValue);
-
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RHR, DISABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RXS, DISABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RX_TIMEOUT, DISABLE, IerValue);
- if (pUartHwRegs->IsEndOfDataIntSupport)
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_EORD, DISABLE, IerValue);
- }
- else
- {
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RHR, DISABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RXS, DISABLE, IerValue);
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_RX_TIMEOUT, DISABLE, IerValue);
- }
- }
- pUartHwRegs->IerRegister = IerValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, IerValue);
-}
-
-void NvDdkPrivUartHwSetTransmitInterrupt(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable)
-{
- NvU32 IerValue;
- // Get the IER register value.
- IerValue = pUartHwRegs->IerRegister;
-
- // Enable/disable the transmit fifo empty
- if (IsEnable)
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_THR, ENABLE, IerValue);
- else
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_THR, DISABLE, IerValue);
- pUartHwRegs->IerRegister = IerValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, IerValue);
-}
-
-void NvDdkPrivUartHwSetModemControlInterrupt(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable)
-{
- NvU32 IerValue;
-
- // Get the IER register value.
- IerValue = pUartHwRegs->IerRegister;
-
- // Enable/disable the modem control signal.
- if (IsEnable)
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_MSI, ENABLE, IerValue);
- else
- IerValue = NV_FLD_SET_DRF_DEF(UART, IER_DLAB_0, IE_MSI, DISABLE, IerValue);
- pUartHwRegs->IerRegister = IerValue;
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, IerValue);
-}
-
-/**
- * Get the interrupt reason.
- */
-UartHwInterruptSource
-NvDdkPrivUartHwGetInterruptReason(
- UartHwRegisters *pUartHwRegs)
-{
- NvU32 IirValue;
- NvU32 P0;
- NvU32 P1;
- NvU32 P2;
- NvU32 InterruptValue = 0;
- NvU32 InterruptSource[8] =
- {
- UartHwInterruptSource_ModemControl, // Modem signal change interrupt
- UartHwInterruptSource_Transmit, // Transmit fifo trigger level interrupt
- UartHwInterruptSource_Receive, // Rx fifo data ready interrupt
- UartHwInterruptSource_ReceiveError, // Line status interrupt
- UartHwInterruptSource_EndOfData, // End of data interrupt
- UartHwInterruptSource_None, // Unused interrupt
- UartHwInterruptSource_RxTimeout, // Rx timeout interrupt
- UartHwInterruptSource_None // Unused interrupt
- };
-
- // Read the Iir register value.
- IirValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, IIR_FCR);
-
- // Check whether all the interrupt is served or not. If there is no
- // pending interrupt then return none.
- if (IirValue & NV_DRF_DEF(UART, IIR_FCR, IS_STA, NO_INTR_PEND))
- return UartHwInterruptSource_None;
-
- // Valid interrupt is there, identify the interrupt.
- P0 = NV_DRF_VAL(UART, IIR_FCR, IS_PRI0, IirValue);
- P1 = NV_DRF_VAL(UART, IIR_FCR, IS_PRI1, IirValue);
- P2 = NV_DRF_VAL(UART, IIR_FCR, IS_PRI2, IirValue);
- InterruptValue = ((P2 << 2) | (P1 <<1) | (P0)) & 0x7;
- return InterruptSource[InterruptValue];
-}
-
-/**
- * Enable/disable the Irda coding.
- */
-void
-NvDdkPrivUartHwSetIrdaCoding(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable)
-{
- NvU32 IrdaCsrValue;
-
- // Read data from the irda csr register.
- IrdaCsrValue = pUartHwRegs->IrdaCsrRegister;
-
- // Enable/disable the sir modulation bit.
- if (IsEnable)
- IrdaCsrValue = NV_FLD_SET_DRF_DEF(UART, IRDA_CSR, SIR_A, ENABLE, IrdaCsrValue);
- else
- IrdaCsrValue = NV_FLD_SET_DRF_DEF(UART, IRDA_CSR, SIR_A, DISABLE, IrdaCsrValue);
-
- pUartHwRegs->IrdaCsrRegister = IrdaCsrValue;
- // Write into the irda csr register.
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IRDA_CSR, IrdaCsrValue);
-}
-
-/**
- * Set the output modem signal to active or inactive state.
- */
-void
-NvDdkPrivUartHwSetModemSignal(
- UartHwRegisters *pUartHwRegs,
- NvDdkUartSignalName SignalName,
- NvBool IsActive)
-{
- NvU32 McrValue= pUartHwRegs->McrRegister;
-
- if (SignalName & NvDdkUartSignalName_Rts)
- {
- if (IsActive != pUartHwRegs->IsRtsActive)
- {
- if (IsActive)
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, RTS, FORCE_RTS_LOW, McrValue);
- else
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, RTS, FORCE_RTS_HI, McrValue);
- pUartHwRegs->IsRtsActive = IsActive;
- }
- }
-
- if (SignalName & NvDdkUartSignalName_Dtr)
- {
- if (IsActive != pUartHwRegs->IsDtrActive)
- {
- if (IsActive)
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, DTR, FORCE_DTR_LOW, McrValue);
- else
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, DTR, FORCE_DTR_HI, McrValue);
- pUartHwRegs->IsDtrActive = IsActive;
- }
- }
-
- // Write the updated value into the register.
- if (pUartHwRegs->McrRegister != McrValue)
- {
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, MCR, McrValue);
- pUartHwRegs->McrRegister = McrValue;
- }
- return;
-}
-
-/**
- * Read the modem signal level and update the state of the signal in the uart hw
- * register structure.
- */
-void NvDdkPrivUartHwUpdateModemSignal(UartHwRegisters *pUartHwRegs)
-{
- NvU32 MsrValue;
-
- // Read the modem status register.
- MsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, MSR);
-
- // If change in CTS then update the CTS value.
- if (MsrValue & (NV_DRF_DEF(UART, MSR, CTS, ENABLE)))
- pUartHwRegs->ModemSignalSatus |= NvDdkUartSignalName_Cts;
- else
- pUartHwRegs->ModemSignalSatus &= ~NvDdkUartSignalName_Cts;
-
- // If change in DSR then update the DSR value.
- if (MsrValue & (NV_DRF_DEF(UART, MSR, DSR, ENABLE)))
- pUartHwRegs->ModemSignalSatus |= NvDdkUartSignalName_Dsr;
- else
- pUartHwRegs->ModemSignalSatus &= ~NvDdkUartSignalName_Dsr;
-
- // If change in RI then update the RI value.
- if (MsrValue & (NV_DRF_DEF(UART, MSR, RI, ENABLE)))
- pUartHwRegs->ModemSignalSatus |= NvDdkUartSignalName_Ri;
- else
- pUartHwRegs->ModemSignalSatus &= ~NvDdkUartSignalName_Ri;
-
- // If change in CD then update the CD value.
- if (MsrValue & (NV_DRF_DEF(UART, MSR, CD, ENABLE)))
- pUartHwRegs->ModemSignalSatus |= NvDdkUartSignalName_Cd;
- else
- pUartHwRegs->ModemSignalSatus &= ~NvDdkUartSignalName_Cd;
-}
-
-// NV_TRUE Active: Uart can send the data
-// NV_FALSE InActive: Uart can not send the data as other terminal have not
-// activated its RTS line
-NvBool NvDdkPrivUartHwIsCtsActive(UartHwRegisters *pUartHwRegs)
-{
- NvU32 MsrValue = UART_REG_READ32(pUartHwRegs->pRegsVirtBaseAdd, MSR);
- if (MsrValue & (NV_DRF_DEF(UART, MSR, CTS, ENABLE)))
- return NV_TRUE;
- else
- return NV_FALSE;
-}
-/**
-* Enable/disable the hw flow control for transmitting the signal. If it is
-* enabled then it will only transmit the data if CTS line is Low. If the CTS
-* line is high then it will not transmit the data. The controller reads the
-* inverted state of the signal state from pin.
-*/
-void
-NvDdkPrivUartHwSetHWFlowControl(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable)
-{
- NvU32 McrValue;
-
- // Read the modem control register and configured for the CTS hw flow
- // bit for the enabling/disabling the hw flow for transmit.
- McrValue = pUartHwRegs->McrRegister;
-
- // Configired the CTS Hw flow bit.
- if (IsEnable)
- {
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, CTS_EN, ENABLE, McrValue);
-
- if (pUartHwRegs->IsRtsHwFlowSupported)
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, RTS_EN, ENABLE, McrValue);
- }
- else
- {
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, CTS_EN, DISABLE, McrValue);
- if (pUartHwRegs->IsRtsHwFlowSupported)
- McrValue = NV_FLD_SET_DRF_DEF(UART, MCR, RTS_EN, DISABLE, McrValue);
- }
-
- pUartHwRegs->McrRegister = McrValue;
-
- // Write into the register.
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, MCR, McrValue);
-}
-
-void NvDdkPrivUartHwReconfigureRegisters(UartHwRegisters *pUartHwRegs)
-{
- NvU32 LcrValue;
-
- // Fcr Register
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IIR_FCR, pUartHwRegs->FcrRegister);
-
- // Lcr, DLL and DLAB registers
- // Enable the LCR-DLAB.
- LcrValue = pUartHwRegs->LcrRegister;
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, DLAB, ENABLE, LcrValue);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
-
- // Program the lower and upper bytes of the baud rate constant.
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, THR_DLAB_0, pUartHwRegs->DllRegister);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, pUartHwRegs->DlmRegister);
-
- // Disable the DLAB.
- LcrValue = NV_FLD_SET_DRF_DEF(UART, LCR, DLAB, DISABLE, LcrValue);
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, LCR, LcrValue);
-
- // Mcr register
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, MCR, pUartHwRegs->McrRegister);
-
- // Irda CSR
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IRDA_CSR, pUartHwRegs->IrdaCsrRegister);
-
- // IER register
- UART_REG_WRITE32(pUartHwRegs->pRegsVirtBaseAdd, IER_DLAB_0, pUartHwRegs->IerRegister);
-}
-
diff --git a/arch/arm/mach-tegra/nvddk/ddkuart_hw_private.h b/arch/arm/mach-tegra/nvddk/ddkuart_hw_private.h
deleted file mode 100644
index fe8f58dc683f..000000000000
--- a/arch/arm/mach-tegra/nvddk/ddkuart_hw_private.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (c) 2007-2009 NVIDIA Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NVIDIA Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * @file
- * @brief <b>nVIDIA Driver Development Kit:
- * Private functions for the uart Ddk driver</b>
- *
- * @b Description: Defines the private interfacing functions for the uart
- * hw interface.
- *
- */
-
-#ifndef INCLUDED_DDKUART_HW_PRIVATE_H
-#define INCLUDED_DDKUART_HW_PRIVATE_H
-
-/**
- * @defgroup nvddk_uart Universal Asynchronous Receiver Transmitter (UART)
- * Controller hw interface API
- *
- * This is the Universal Asynchronous Receiver Transmitter (UART) hw interface
- * controller api.
- *
- * @ingroup nvddk_modules
- * @{
- *
- */
-
-#include "nvcommon.h"
-#include "nvddk_uart.h"
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/**
- * Combines the definition of the uart register and modem signals.
- */
-typedef struct UartHwRegistersRec
-{
- // Channel instance Id.
- NvU32 ChannelId;
-
- // Virtual base address of the uart hw register.
- NvU32 *pRegsVirtBaseAdd;
-
- // Physical base address of the uart hw register.
- NvRmPhysAddr RegsPhyBaseAdd;
-
- // Register bank size.
- NvU32 BankSize;
-
- // Uart shadow registers to keep the s/w value of registers
-
- // Currently programmed Fcr register value.
- NvU32 FcrRegister;
-
- // Currently programmed Ier register value.
- NvU32 IerRegister;
-
- // Currently programmed Lcr register value.
- NvU32 LcrRegister;
-
- // Currently programmed Mcr register value.
- NvU32 McrRegister;
-
- // Currently programmed irda csr register value.
- NvU32 IrdaCsrRegister;
-
- // Currently programmed Dlm register value.
- NvU32 DlmRegister;
-
- // Currently programmed Dll register value.
- NvU32 DllRegister;
-
- // Tells whether the dma mode is selected or not.
- NvBool IsDmaMode;
-
- // Modem signal status, 1 on the particular location shows the state to high.
- NvU32 ModemSignalSatus;
-
- // Tells whether the Rts hw flow control is supported or not
- NvBool IsRtsHwFlowSupported;
-
- // Tells whether the end of data interrupt is supported or not
- NvBool IsEndOfDataIntSupport;
-
- // Store the RTS line status
- NvBool IsRtsActive;
-
- NvBool IsDtrActive;
-
- NvU32 TransmitTrigLevel;
-} UartHwRegisters;
-
-/**
- * Combines the uart interrupt sources.
- */
-typedef enum
-{
- // No Uart interrupt source.
- UartHwInterruptSource_None = 0x0,
-
- // Receive Uart interrupt source.
- UartHwInterruptSource_Receive,
-
- // Receive error Uart interrupt source.
- UartHwInterruptSource_ReceiveError,
-
- // Rx timeout interrupt source.
- UartHwInterruptSource_RxTimeout,
-
- // End of data interrupt source.
- UartHwInterruptSource_EndOfData,
-
- // Transmit interrupt source.
- UartHwInterruptSource_Transmit,
-
- // Modem control interrupt source.
- UartHwInterruptSource_ModemControl,
-
- UartHwInterruptSource_Force32 = 0x7FFFFFFF
-} UartHwInterruptSource;
-
-/**
- * Combines the uart hw data direction.
- */
-typedef enum
-{
- // Invalid fifo type.
- UartDataDirection_Invalid = 0x0,
-
- // Receive direction.
- UartDataDirection_Receive = 0x1,
-
- // Transmit direction.
- UartDataDirection_Transmit = 0x2,
-
- // Both, receive and transmit data direction.
- UartDataDirection_Both = 0x3,
-
- UartDataDirection_Force32 = 0x7FFFFFFF
-} UartDataDirection;
-
-/**
- * Initialize the uart hw registers parameters. It does not write anything on
- * the controller register.
- */
-void
-NvDdkPrivUartHwRegisterInitialize(
- NvU32 CommChannelId,
- UartHwRegisters *pUartHwRegs);
-/**
- * Initialize the uart fifos.
- */
-void NvDdkPrivUartHwInitFifo(UartHwRegisters *pUartHwRegs);
-
-/**
- * Get the clock source frequency required for the given baud rate.
- */
-void
-NvDdkPrivUartHwGetReqdClockSourceFreq(
- NvU32 BaudRate,
- NvU32 *pMinClockFreqReqd,
- NvU32 *pClockFreqReqd,
- NvU32 *pMaxClockFreqReqd);
-
-/**
- * Set the baud rate of uart communication.
- */
-NvError
-NvDdkPrivUartHwSetBaudRate(
- UartHwRegisters *pUartHwRegs,
- NvU32 BaudRate,
- NvU32 ClockSourceFreq);
-/**
- * Set the parity of uart communication.
- */
-NvError
-NvDdkPrivUartHwSetParityBit(
- UartHwRegisters *pUartHwRegs,
- NvDdkUartParity ParityBit);
-
-/**
- * Set the data length of uart communication.
- */
-NvError
-NvDdkPrivUartHwSetDataLength(
- UartHwRegisters *pUartHwRegs,
- NvU32 DataLength);
-
-/**
- * Set the stop bit of uart communication.
- */
-NvError NvDdkPrivUartHwSetStopBit(
- UartHwRegisters *pUartHwRegs,
- NvDdkUartStopBit StopBit);
-
-/**
- * Start/stop sending the break control signal.
- */
-void NvDdkPrivUartHwSetBreakControlSignal(
- UartHwRegisters *pUartHwRegs,
- NvBool IsStart);
-
-/**
- * Reset the uart fifos.
- */
-void
-NvDdkPrivUartHwResetFifo(
- UartHwRegisters *pUartHwRegs,
- UartDataDirection FifoType);
-
-/**
- * Set the fifo trigger level of uart fifo.
- */
-void
-NvDdkPrivUartHwSetFifoTriggerLevel(
- UartHwRegisters *pUartHwRegs,
- UartDataDirection FifoType,
- NvU32 TriggerLevel);
-
-/**
- * Set the dma mode operation of uart
- */
-void
-NvDdkPrivUartHwSetDmaMode(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable);
-
-/**
- * Write into the transmit fifo register with the trigger level.
- * This function should be call when tx trigger level is reached.
- */
-NvU32
-NvDdkPrivUartHwWriteInTransmitFifo(
- UartHwRegisters *pUartHwRegs,
- NvU8 *pTxBuff,
- NvU32 BytesRequested);
-
-/**
- * Write into the transmit fifo register and check the fifo status before writing
- * into the tx fifo.
- * With every write, the fifo status will be checked.
- */
-NvU32
-NvDdkPrivUartHwPollingWriteInTransmitFifo(
- UartHwRegisters *pUartHwRegs,
- NvU8 *pTxBuff,
- NvU32 BytesRequested);
-
-/**
- * Check whether the Transmit fiof is empty or not.
- * Returns TRUE if the Tx fifo is empty otherwise returns FALSE.
- */
-NvBool NvDdkPrivUartHwIsTransmitFifoEmpty(UartHwRegisters *pUartHwRegs);
-
-/**
- * Check whether break condition is received or not.
- */
-NvBool NvDdkPrivUartHwIsBreakSignalDetected(UartHwRegisters *pUartHwRegs);
-
-/**
- * Get the Rx fifo status whether data is available in the rx fifo or not.
- */
-NvBool NvDdkPrivUartHwIsDataAvailableInFifo(UartHwRegisters *pUartHwRegs);
-
-/**
- * Read the data from the receive fifo.
- */
-NvError
-NvDdkPrivUartHwReadFromReceiveFifo(
- UartHwRegisters *pUartHwRegs,
- NvU8 *pRxBuff,
- NvU32 MaxBytesRequested,
- NvU32 *bytesRead);
-
-/**
- * Clear all the uart interrupt.
- */
-void NvDdkPrivUartHwClearAllInt(UartHwRegisters *pUartHwRegs);
-
-/**
- * Configure the receive interrupt.
- */
-void NvDdkPrivUartHwSetReceiveInterrupt(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable,
- NvBool IsRxUsingApbDma);
-
-/**
- * Configure the transmit interrupt.
- */
-void NvDdkPrivUartHwSetTransmitInterrupt(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable);
-
-/**
- * Configure the modem control interrupt.
- */
-void NvDdkPrivUartHwSetModemControlInterrupt(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable);
-
-/**
- * Get the interrupt reason.
- */
-UartHwInterruptSource
-NvDdkPrivUartHwGetInterruptReason(
- UartHwRegisters *pUartHwRegs);
-
-/**
- * Enable/disable the Irda coding.
- */
-void
-NvDdkPrivUartHwSetIrdaCoding(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable);
-
-/**
- * Set the output modem signals to high or low.
- */
-void
-NvDdkPrivUartHwSetModemSignal(
- UartHwRegisters *pUartHwRegs,
- NvDdkUartSignalName SignalName,
- NvBool IsActive);
-
-/**
- * Get the CTS status from the line.
- */
-NvBool NvDdkPrivUartHwIsCtsActive(UartHwRegisters *pUartHwRegs);
-
-/**
- * Read the modem signal level and update the state of the signal in the uart hw
- * register structure.
- */
-void NvDdkPrivUartHwUpdateModemSignal(UartHwRegisters *pUartHwRegs);
-
-/**
- * Enable/disable the hw flow control for transmitting the signal. If it is
- * enabled then it wil only transmit the data if CTS line is high.
- */
-void
-NvDdkPrivUartHwSetHWFlowControl(
- UartHwRegisters *pUartHwRegs,
- NvBool IsEnable);
-
-/**
- * Reconfigure the uart controller register. The shadow register content is
- * written into the uart controller register.
- */
-void NvDdkPrivUartHwReconfigureRegisters(UartHwRegisters *pUartHwRegs);
-
-/** @}*/
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif // INCLUDED_DDKUART_HW_PRIVATE_H
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_uart.c b/arch/arm/mach-tegra/nvddk/nvddk_uart.c
deleted file mode 100644
index c3f498b3a26d..000000000000
--- a/arch/arm/mach-tegra/nvddk/nvddk_uart.c
+++ /dev/null
@@ -1,2834 +0,0 @@
-/*
- * Copyright (c) 2007-2009 NVIDIA Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NVIDIA Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * @file
- * @brief <b>NVIDIA Driver Development Kit:
- * Uart ddk Driver implementation</b>
- *
- * @b Description: Implementation of the NvDdk UART API.
- *
- * Some constrains and designs details of the uart driver:
- *
- * We use the continuous double buffering mechanims for the uart receive.
- * In this method, the apb dma is programmed for the receive in contunous mode*
- * and generte the interrupt after half of the buffer completion.
- * Currently the buffer size is 64KB and so dma generate the interrupt after
- * every 32 K transfer. So the uart ddk clinet need to copy this dma buffer
- * to local buffer before next 32K bytes received. For 4.5Mbps rate, the 32 K
- * transfer takes around 70ms and we have the only latency of 70ms to copy this
- * buffer. For lower baudrate, the latency is more.
- *
- * In the receive path, there are three possible errors:
- * - FIFO overrun error: If there is no space in the Rx FIFO (16 bytes in uart
- * controller) and if data arrives then we get this error.
- * As we are using the apb dma in double continuous mode
- * with the trigger level of 4 bytes so whenever there
- * is 4 bytes in the fifo, the apb dma transfers this to
- * memory. This is done by hw and sw does not get involved.
- * This transfer is continuous. As hw is transferring the
- * data from the fifo to memory, there is very less
- * chances of getting the overrun error. We may get only
- * when system bus is too much loaded, or
- * ahb/apb/cpu/memory frequencies are too low or any
- * system bandwidth issue. We have verified 4.5Mbps baud
- * rate maximum and not seen any such issue.
-
- * - Dma buffer overwrite: There is 64KB of dma buffer on which data is filled
- * from fifo. This is continuous mode filling and dma
- * generates the interrupt after every 32Kbyte of transfers.
- * So we have to respond this interrupt till next 32K data
- * receive and copy this data to local buffer so that dma
- * can fill again on this dma buffer. if we don't copy the
- * data in a given time, the dma will overwrite this data
- * with the new arriving data and so lose the old data. So
- * responding the interrupt in a given time line is necessary
- * and it defines the maximum interrupt latency for the
- * uart communication. If system does not respond in the
- * given time, the system will not perform as expected.
-
- * - Local buffer full: As ddk copies the incoming data from dma buffer to
- * local buffer so that it can be supplied to client when
- * client calls the read. If data are arriving continuously
- * and data is not being read then buffer will get filled.
- * If we have the hw flow control then sw deassert the RTS
- * so that no more data can be send from other end. It will
- * again assert when the client calls the read and there
- * is some threshold level of the space. Currently in ddk
- * it is set to 48K minimum so if there is data available
- * less than 48K in the local buffer then only RTS will be
- * enabled otherwise it will be deasserted. This RTS control
- * is done through sw (driver) and so system should
- * response the IST/high priority thread in a given time.
- *
- * Moreover in the cuttent design, the DMA IST/UART IST priorities are high on
- * the system as these are ISR. The Rx thread priority in the uart shim driver
- * should be the IST priority level.
- *
- * If the system responds the threads in a given time then we will not see any
- * data loss/overrun type of error.
- *
- * What happen if operating system is unable to schedule the Nvidia UART driver
- * routines in a timely fashion or is mishandling hardware handshaking.
- * Specifically, it is necessary for the driver to de-assert RTS when it is in
- * danger of a FIFO overrun, 16 bytes max, to inform the sender that it should
- * hold off on further transmissions.
- *
- * Answer:
- * If OS is unable to respond the IST/higher priority thread on a given time
- * line then system is too loaded and need to redesign the application/system
- * because it is not meeting the real time requirements for the device (even it
- * is soft real time system).
- * We don't have the RTS control enable from the hw and so sw control the RTS
- * based on the driver buffer state/internal state. For this the thread should
- * be scheduled properly so that proper flow control can be controlled.
- * Even in double buffering mechanism, the hw control of RTS is also not useful
- * as the hw does not know your buffer overwrite issue.
- * We are setting the RTS activation/deactivation control to the size of half
- * local buffer (minimum local buffer size is 96K). So if there is data in the
- * local buffer more than half the local buffer, the RTS will be deactivated
- * and if it's less, then only it's activated. This water level mechanism saves
- * the 'out of local buffer issue'.
- */
-
-#include "nvddk_uart.h"
-#include "ddkuart_hw_private.h"
-#include "nvrm_power.h"
-#include "nvrm_memmgr.h"
-#include "nvrm_dma.h"
-#include "nvodm_query.h"
-#include "nvrm_interrupt.h"
-#include "nvassert.h"
-#include "nvrm_hardware_access.h"
-#include "nvodm_query_pinmux.h"
-#include "nvrm_pinmux.h"
-#include "nvodm_uart.h"
-
-// Some important debug print to debug the flow
-#define DEBUG_WRITE_TIMEOUT 0
-#define DEBUG_READ_RXERROR 0
-#define ENABLE_WRITE_PROFILE 0
-#define ENABLE_READ_PROFILE 0
-// Constants used to size arrays. Must be >= the max of all chips.
-enum {MAX_UART_CONTROLLERS = 5};
-
-// Assuming 50 ms data size for the 4.5Mbps
-// Assuming the 50 ms will be the time taken to copy the recv data into the
-// Passed buffer.
-enum {UART_RX_DMA_PING_BUFFER_SIZE = 0x8000};
-
-// Minimum size of the local buffering of the data to avoid any data loss.
-enum {UART_RX_LOCAL_BUFFER_SIZE_MIN = UART_RX_DMA_PING_BUFFER_SIZE*3};
-
-// Local buffer threshold for disabling the rts line.
-// This is the 2/3rd of the local buffer size.
-enum {UART_RX_LOCAL_BUFFER_THRESOLD_MIN = UART_RX_DMA_PING_BUFFER_SIZE << 1};
-
-// maximum frequency boost list
-enum {MAX_FREQ_REQ_LIST = 3};
-
-// Time from last operation on read/write complete on uart port.
-// If the time is more than the limit then uart will request for the
-// frequency down.
-enum {HIGH_FREQUENCY_HOLD_TIMEOUT = 3000}; // 3 seconds
-
-// Mutex definition which are used for the locking the read/write/channel
-// register access.
-#define DeclareReadFlowLock NvOsIntrMutexHandle hReadMutex
-#define CreateReadFlowLock(hUart) NvOsIntrMutexCreate(&hUart->hReadMutex)
-#define LockReadFlow(hUart) NvOsIntrMutexLock(hUart->hReadMutex)
-#define UnlockReadFlow(hUart) NvOsIntrMutexUnlock(hUart->hReadMutex)
-#define DestroyReadFlowLock(hUart) NvOsIntrMutexDestroy(hUart->hReadMutex)
-
-#define DeclareWriteFlowLock NvOsIntrMutexHandle hWriteMutex
-#define CreateWriteFlowLock(hUart) NvOsIntrMutexCreate(&hUart->hWriteMutex)
-#define LockWriteFlow(hUart) NvOsIntrMutexLock(hUart->hWriteMutex)
-#define UnlockWriteFlow(hUart) NvOsIntrMutexUnlock(hUart->hWriteMutex)
-#define DestroyWriteFlowLock(hUart) NvOsIntrMutexDestroy(hUart->hWriteMutex)
-
-#define DeclareRegisterAccessLock NvOsIntrMutexHandle hRegisterAccessMutex
-#define CreateRegisterAccessLock(hUart) NvOsIntrMutexCreate(&hUart->hRegisterAccessMutex)
-#define LockRegisterAccess(hUart) NvOsIntrMutexLock(hUart->hRegisterAccessMutex)
-#define UnlockRegisterAccess(hUart) NvOsIntrMutexUnlock(hUart->hRegisterAccessMutex)
-#define DestroyRegisterAccessLock(hUart) NvOsIntrMutexDestroy(hUart->hRegisterAccessMutex)
-
-// Way to reset the semaphore count.
-#define ResetSemaphoreCount(hSema) \
- while(NvOsSemaphoreWaitTimeout(hSema, 0) != NvError_Timeout)
-
-#if DEBUG_READ_RXERROR
-#define DEBUG_PRINT_RX_ERR(Expr, Format) \
- do { \
- if (Expr) \
- { \
- NvOsDebugPrintf Format; \
- } \
- } while(0)
-#else
-#define DEBUG_PRINT_RX_ERR(Expr, Format)
-#endif
-
-#if DEBUG_WRITE_TIMEOUT
-#define DEBUG_PRINT_TX_ERR(Expr, Format) \
- do { \
- if (Expr) \
- { \
- NvOsDebugPrintf Format; \
- } \
- } while(0)
-#else
-#define DEBUG_PRINT_TX_ERR(Expr, Format)
-#endif
-
-/**
- * Combines the SOC uart capability structure.
- */
-typedef struct SocUartCapabilityRec
-{
- // Tells whether the end of data interrupt is supported or not.
- NvBool IsEndOfDataIntSupported;
-
- // Tells whether the RTS hw flow control is supported or not.
- NvBool IsRtsHwFlowControlSupported;
-
- // Fifo depth of the uart controller.
- NvU32 FifoDepth;
-} SocUartCapability;
-
-/**
- * Combines the uart channel information.
- */
-typedef struct
-{
- // Nv Rm device handles.
- NvRmDeviceHandle hRmDevice;
-
- // List of the uart handle exist in the ddk.
- NvDdkUartHandle hUartList[MAX_UART_CONTROLLERS];
-
- // Mutex for uart channel information.
- NvOsMutexHandle hUartOpenMutex;
-} DdkUartChannelInfo;
-
-/**
- * Combines the Uart transfer information for receive and transmit for the given
- * uart channel.
- */
-typedef struct
-{
- // Tells whether transfer is going on or not?
- NvBool IsBusy;
-
- NvU8 *pReqBuffer;
-
- // Pointer to the current transfer.
- NvU8 *pCurrTransBuf;
-
- NvU32 BytesRequested;
-
- NvU32 BytesTransferred;
-
- // Bytes remaining to transfer.
- NvU32 BytesRemaining;
-
- // Current transfer status.
- NvError TransferStatus;
-
- // On complete semaphore Id which need to be signal after transfer
- // completion or abort on the transfer.
- NvOsSemaphoreHandle hOnCompleteSema;
-
- NvBool IsStopReq;
-} UartTransferReqInfo;
-
-/**
- * Uart local buffer information.
- */
-typedef struct
-{
- // Pointer to the local buffer.
- NvU8 *pBuffPtr;
-
- // Read Index
- NvU32 ReadIndex;
-
- // Write index.
- NvU32 WriteIndex;
-
- // Total size of the buffer.
- NvU32 TotalBufferSize;
-
- // Higher buffer level from where the RTS is deactivated to stop the sender
- // as ddk is not able to receive more data.
- NvU32 BufferLevelHigh;
-
- // Total data available in the buffer.
- NvU32 DataAvailable;
-
- // Semaphore which will be signalled once the data is available in the
- // fifo/dma buffer. Client passed this semaphore Id.
- NvOsSemaphoreHandle hDataAvailableSema;
-
- // Semaphore which will be signalled when there is any error or break receive
- // in the Rx line. Client passed this semaphore Id.
- NvOsSemaphoreHandle hLineStatusSema;
-} UartLocalBuffer;
-
-/**
- * Uart handle which combines all the information related to the given uart
- * channels
- */
-typedef struct NvDdkUartRec
-{
- // Nv Rm device handles.
- NvRmDeviceHandle hRmDevice;
-
- // Instance Id of the uart channels.
- NvU32 InstanceId;
-
- // Number of open count.
- NvU32 OpenCount;
-
- // The uart capability for this uart channel only.
- SocUartCapability SocUartCaps;
-
- // Number of uart interface lines physically available on board.
- NvU32 NumberOfInterfaceLine;
-
- // Uart configuration parameter.
- NvDdkUartConfiguarations UartConfig;
-
- // Uart hw register information.
- UartHwRegisters UartHwRegs;
-
- // Uart write transfer request information.
- UartTransferReqInfo WriteReq;
-
- // Read transfer request information.
- UartTransferReqInfo ReadReq;
-
- // Local buffer information which is used for receive.
- UartLocalBuffer LocalRxBuff;
-
- // Tells whether the dma support is available for this channel.
- // This can be false if the dma allocation or the dma buffer creation fails.
- NvBool IsDmaSupport;
-
- // Is receive is dma based transfer or not.
- NvBool IsRxApbDmaBased;
-
- // Is read started or not.
- NvBool IsDmaReadStarted;
-
- // Rx dma handles.
- NvRmDmaHandle hRxRmDma;
-
- // Tx dma handles.
- NvRmDmaHandle hTxRmDma;
-
- // Memory handle to create the uncache memory for dma transfer.
- NvRmMemHandle hRmMemory;
-
- // Rx Dma buffer address.
- NvRmPhysAddr RxDmaBuffPhysAdd;
-
- // Tx Dma buffer address.
- NvRmPhysAddr TxDmaBuffPhysAdd;
-
- NvU32 RxDmaBufferSize;
- NvU32 HalfRxDmaBufferSize;
-
- NvU32 TxDmaBufferSize;
-
- // Virtual pointer to the Rx dma buffer.
- NvU8 *pRxDmaBuffer;
-
- // Virtual pointer to the Tx dma buffer.
- NvU8 *pTxDmaBuffer;
-
- // Write dma request
- NvRmDmaClientBuffer WDmaReq;
-
- // Read dma request
- NvRmDmaClientBuffer RDmaReq;
-
- // The last read index from dma buffer to the local buffer.
- NvU32 LastReadIndex;
-
- // Is current write is polling
- NvBool IsWritePolling;
-
- // Maximum transmit bytes which can be send by polling.
- NvU32 MaxTxBytesPolling;
-
- // 4 character time in microseconds, the write will wait for this much of
- // time when it founds that Tx fifo is full.
- NvU32 Char4TimeUs;
-
- // Receive Synchronous semaphore Id which need to be signalled.
- NvOsSemaphoreHandle hRxSynchSema;
-
- // Transmit Synchronous semaphore Id which need to be signalled.
- NvOsSemaphoreHandle hTxSynchSema;
-
- // Mutex to access the read flow.
- DeclareReadFlowLock;
-
- // Mutex to access the write flow.
- DeclareWriteFlowLock;
-
- // Mutex to access the register which are common for read/write/configuration.
- DeclareRegisterAccessLock;
-
- // Callback for signal change notification.
- NvDdkUartSignalChangeCallback hModemSigChngCallback;
-
- // Arguments to the signal change callback function.
- void *ModemSigChngHandlerArgs;
-
- // Clinet wants the notification on the signal change.
- NvU32 ModemSignalName;
-
- NvBool IsRtsFlowEnable;
-
- NvBool IsCtsFlowEnable;
-
- // Pointer to the uart information.
- DdkUartChannelInfo *pUartInfo;
-
- // Semaphore for registering the client with the power manager.
- NvOsSemaphoreHandle hRmPowerEventSema;
-
- // Power client Id.
- NvU32 RmPowerClientId;
-
- // Interrupt handle
- NvOsInterruptHandle InterruptHandle;
-
- // Odm uart handle
- NvOdmUartHandle hOdmUart;
-
- // Busy hints for setting the required frequency of the system/cpu.
- NvRmDfsBusyHint UpFreq[MAX_FREQ_REQ_LIST];
- NvRmDfsBusyHint DownFreq[MAX_FREQ_REQ_LIST];
-
- // Thread to keep the power/frequency requirement on the channel.
- NvOsThreadHandle hUartPowerMgrThread;
-
- NvOsSemaphoreHandle hUartPowerMgrSema;
-
- NvBool IsStopPowerThread;
-
- NvBool IsFreqBoosted;
-
- NvBool IsSuspendedState;
-
- NvBool OldRtsState;
-
- NvBool OldDtrState;
-} NvDdkUart;
-
-static DdkUartChannelInfo *s_pUartInfo = NULL;
-
-/**
- * Get the uart soc capability.
- *
- */
-static NvError
-UartGetSocCapabilities(
- NvRmDeviceHandle hRmDevice,
- NvU32 UartInstanceId,
- SocUartCapability *pUartSocCaps)
-{
- NvRmModuleID ModuleId;
- static SocUartCapability s_SocUartCapsList[3];
- NvRmModuleCapability UartCapsList[] =
- {
- { 1, 0, 0, &s_SocUartCapsList[0] }, // Major.Minor = 1.0
- { 1, 1, 0, &s_SocUartCapsList[1] }, // Major.Minor = 1.1
- { 1, 2, 0, &s_SocUartCapsList[2] }, // Major.Minor = 1.2
- };
- SocUartCapability *pUartCaps = NULL;
-
- ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, UartInstanceId);
-
- s_SocUartCapsList[0].IsEndOfDataIntSupported = NV_FALSE;
- s_SocUartCapsList[0].IsRtsHwFlowControlSupported = NV_FALSE;
- s_SocUartCapsList[0].FifoDepth = 16;
-
- s_SocUartCapsList[1].IsEndOfDataIntSupported = NV_TRUE;
- s_SocUartCapsList[1].FifoDepth = 16;
-
- s_SocUartCapsList[2].IsEndOfDataIntSupported = NV_TRUE;
- s_SocUartCapsList[2].FifoDepth = 32;
-
- // FIXEME!! HW Bug: The RTS hw flow control is not working when enabling
- // EORD interrupt.
- // As the EORD is more important feature then the Rts hw flow control,
- // disabling this feature.
- s_SocUartCapsList[1].IsRtsHwFlowControlSupported = NV_FALSE;
- s_SocUartCapsList[2].IsRtsHwFlowControlSupported = NV_FALSE;
-
- // Get the capability from modules files.
- NV_ASSERT_SUCCESS(NvRmModuleGetCapabilities(hRmDevice, ModuleId,
- UartCapsList, NV_ARRAY_SIZE(UartCapsList),
- (void **)&pUartCaps));
- pUartSocCaps->IsEndOfDataIntSupported = pUartCaps->IsEndOfDataIntSupported;
- pUartSocCaps->IsRtsHwFlowControlSupported = pUartCaps->IsRtsHwFlowControlSupported;
- pUartSocCaps->FifoDepth = pUartCaps->FifoDepth;
- return NvSuccess;
-}
-
-/**
- * Initialize the uart information.
- * Thread safety: Caller responsibility.
- */
-static NvError InitUartInformation(NvRmDeviceHandle hRmDevice)
-{
- NvError Error = NvSuccess;
- DdkUartChannelInfo *pUartInfo = NULL;
-
- NV_ASSERT(NvRmModuleGetNumInstances(hRmDevice, NvRmModuleID_Uart) <= MAX_UART_CONTROLLERS);
- if (!s_pUartInfo)
- {
- // Allocate the memory for the uart information.
- pUartInfo = NvOsAlloc(sizeof(*pUartInfo));
- if (!pUartInfo)
- return NvError_InsufficientMemory;
- NvOsMemset(pUartInfo, 0, sizeof(*pUartInfo));
-
- // Initialize all the parameters.
- pUartInfo->hRmDevice = hRmDevice;
-
- // Create the mutex to accss the uart information.
- Error = NvOsMutexCreate(&pUartInfo->hUartOpenMutex);
- // If error exit till then destroy all allocations.
- if (Error)
- {
- NvOsFree(pUartInfo);
- pUartInfo = NULL;
- return Error;
- }
-
- if (NvOsAtomicCompareExchange32((NvS32*)&s_pUartInfo, 0, (NvS32)pUartInfo)!=0)
- {
- NvOsMutexDestroy(pUartInfo->hUartOpenMutex);
- NvOsFree(pUartInfo);
- }
- }
- return NvSuccess;
-}
-
-/**
- * Create the dma buffer memory handle.
- */
-static NvError
-CreateDmaBufferMemoryHandle(
- NvRmDeviceHandle hRmDevice,
- NvRmMemHandle *phMemHandle,
- NvRmPhysAddr *pMemPhyAddr,
- NvU32 BufferSize)
-{
- NvError Error = NvSuccess;
- NvRmMemHandle hNewMemHandle = NULL;
-
- // Initialize the memory handle with NULL
- *phMemHandle = NULL;
-
- /// Create memory handle
- Error = NvRmMemHandleCreate(hRmDevice, &hNewMemHandle, BufferSize);
-
- // Allocates the memory from the sdram
- if (!Error)
- Error = NvRmMemAlloc(hNewMemHandle, NULL, 0, 0x4, NvOsMemAttribute_Uncached);
-
- // Pin the memory allocation so that it should not move by memory manager.
- // Also get the physical address.
- if (!Error)
- *pMemPhyAddr = NvRmMemPin(hNewMemHandle);
-
- // If error then free the memory allocation and memory handle.
- if (Error)
- {
- NvRmMemHandleFree(hNewMemHandle);
- hNewMemHandle = NULL;
- }
-
- *phMemHandle = hNewMemHandle;
- return Error;
-}
-
- /**
- * Destroy the dma buffer memory handle.
- * Thread safety: Caller responsibility.
- */
-static void DestroyDmaBufferMemoryHandle(NvRmMemHandle hMemHandle)
-{
- // Can accept the null parameter. If it is not null then only destroy.
- if (hMemHandle)
- {
- // Unpin the memory allocation.
- NvRmMemUnpin(hMemHandle);
-
- // Free the memory handle.
- NvRmMemHandleFree(hMemHandle);
- }
-}
-
-/**
- * Create the dma transfer buffer for the given handles.
- * Thread safety: Caller responsibility.
- */
-static NvError
-CreateDmaTransferBuffer(
- NvRmDeviceHandle hRmDevice,
- NvRmMemHandle *phRmMemory,
- NvRmPhysAddr *pBuff1PhysAddr,
- void **pBuff1Ptr,
- NvRmPhysAddr *pBuff2PhysAddr,
- void **pBuff2Ptr,
- NvU32 OneBufferSize)
-{
- NvError Error = NvSuccess;
- NvRmMemHandle hRmMemory = NULL;
- NvRmPhysAddr BuffPhysAddr;
-
- // Reset all the members related to the dma buffer.
- BuffPhysAddr = 0;
-
- *phRmMemory = NULL;
- *pBuff1Ptr = (void *)NULL;
- *pBuff1PhysAddr = 0;
- *pBuff2Ptr = (void *)NULL;
- *pBuff2PhysAddr = 0;
-
- // Create the dma buffer memory for receive and transmit.
- // It will be double of the OneBufferSize
- Error = CreateDmaBufferMemoryHandle(hRmDevice, &hRmMemory, &BuffPhysAddr,
- (OneBufferSize << 1));
- if (!Error)
- {
- // 0 to OneBufferSize-1 is buffer 1 and OneBufferSize to 2*OneBufferSize
- // is second buffer.
- Error = NvRmMemMap(hRmMemory, 0, OneBufferSize,
- NVOS_MEM_READ_WRITE, pBuff1Ptr);
- if (!Error)
- {
- Error = NvRmMemMap(hRmMemory, OneBufferSize, OneBufferSize,
- NVOS_MEM_READ_WRITE, pBuff2Ptr);
- if (Error)
- NvRmMemUnmap(hRmMemory, pBuff1Ptr, OneBufferSize);
- }
- // If error then free the allocation and reset all changed value.
- if (Error)
- {
- DestroyDmaBufferMemoryHandle(hRmMemory);
- hRmMemory = NULL;
- *pBuff1Ptr = (void *)NULL;
- *pBuff2Ptr = (void *)NULL;
- return Error;
- }
- *phRmMemory = hRmMemory;
- *pBuff1PhysAddr = BuffPhysAddr;
- *pBuff2PhysAddr = BuffPhysAddr + OneBufferSize;
- }
- return Error;
-}
-
-/**
- * Destroy the dma transfer buffer.
- * Thread safety: Caller responsibility.
- */
-static void
-DestroyDmaTransferBuffer(
- NvRmMemHandle hRmMemory,
- void *pBuff1Ptr,
- void *pBuff2Ptr,
- NvU32 OneBufferSize)
-{
- NvRmMemUnmap(hRmMemory, pBuff1Ptr, OneBufferSize);
- NvRmMemUnmap(hRmMemory, pBuff2Ptr, OneBufferSize);
- DestroyDmaBufferMemoryHandle(hRmMemory);
-}
-
-/**
- * Initialize the transfer information for the given handles.
- * Thread safety: Caller /responsibility.
- */
-static void
-InitTransferInfo(
- NvRmDeviceHandle hRmDevice,
- UartTransferReqInfo *pTransferInfo)
-{
- NvOsMemset(pTransferInfo, 0, sizeof(UartTransferReqInfo));
- pTransferInfo->IsBusy = NV_FALSE;
- pTransferInfo->pReqBuffer = NULL;
- pTransferInfo->BytesRequested = 0;
- pTransferInfo->BytesTransferred = 0;
- pTransferInfo->pCurrTransBuf = NULL;
- pTransferInfo->BytesRemaining = 0;
- pTransferInfo->TransferStatus = NvSuccess;
- pTransferInfo->hOnCompleteSema = NULL;
-}
-
-
-/**
- * Create the local buffer.
- * Thread safety: Caller responsibility.
- */
-static NvError CreateLocalRxBuff(NvDdkUartHandle hUart, NvU32 BufferSize)
-{
- NvError Error = NvSuccess;
-
- hUart->LocalRxBuff.pBuffPtr = NULL;
- hUart->LocalRxBuff.ReadIndex = 0;
- hUart->LocalRxBuff.WriteIndex = 0;
- hUart->LocalRxBuff.DataAvailable = 0;
- hUart->LocalRxBuff.hDataAvailableSema = NULL;
- hUart->LocalRxBuff.TotalBufferSize = BufferSize;
- // Setting the RTS activation/deactivation thresold level to the half of the
- // buffer size.
- hUart->LocalRxBuff.BufferLevelHigh = (BufferSize >> 1);
- if (BufferSize)
- {
- hUart->LocalRxBuff.pBuffPtr = NvOsAlloc(BufferSize);
- if (!hUart->LocalRxBuff.pBuffPtr)
- Error = NvError_InsufficientMemory;
- }
- return Error;
-}
-
-/**
- * Destroy the local buffer.
- * Thread safety: Caller responsibility.
- */
-static void DestroyLocalRxBuff(NvDdkUartHandle hUart)
-{
- NvOsFree(hUart->LocalRxBuff.pBuffPtr);
- hUart->LocalRxBuff.pBuffPtr = NULL;
- hUart->LocalRxBuff.ReadIndex = 0;
- hUart->LocalRxBuff.DataAvailable = 0;
- hUart->LocalRxBuff.WriteIndex = 0;
- hUart->LocalRxBuff.hDataAvailableSema = NULL;
- hUart->LocalRxBuff.hLineStatusSema = NULL;
- hUart->LocalRxBuff.TotalBufferSize = 0;
- hUart->LocalRxBuff.BufferLevelHigh = 0;
-}
-
-/**
- * Handle the uart receive interrupt.
- * Thread safety: Caller responsibility.
- */
-static void
-HandleUartRxInterrupt(
- NvDdkUartHandle hUart,
- UartHwInterruptSource InterruptReason)
-{
- NvError Error = NvSuccess;
- NvU32 SpaceFromWriteIndex;
- NvU32 SpaceFromStartIndex;
- NvU32 BytesRead;
- NvU32 IsNextRead = NV_TRUE;
-
-
- if (hUart->IsRxApbDmaBased)
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetReceiveInterrupt(&hUart->UartHwRegs, NV_FALSE, NV_TRUE);
- UnlockRegisterAccess(hUart);
- NvOsSemaphoreSignal(hUart->LocalRxBuff.hDataAvailableSema);
- }
- else
- {
- LockReadFlow(hUart);
- if (hUart->LocalRxBuff.ReadIndex > hUart->LocalRxBuff.WriteIndex)
- {
- // 0.....w....r...(n-1)
- SpaceFromWriteIndex = hUart->LocalRxBuff.ReadIndex -
- hUart->LocalRxBuff.WriteIndex;
- SpaceFromStartIndex = 0;
- }
- else
- {
- // 0.....r....w...(n-1)
- SpaceFromWriteIndex = hUart->LocalRxBuff.TotalBufferSize -
- hUart->LocalRxBuff.WriteIndex;
- SpaceFromStartIndex = hUart->LocalRxBuff.ReadIndex;
- }
-
- if (SpaceFromWriteIndex)
- {
- Error = NvDdkPrivUartHwReadFromReceiveFifo(&hUart->UartHwRegs,
- &hUart->LocalRxBuff.pBuffPtr[hUart->LocalRxBuff.WriteIndex],
- SpaceFromWriteIndex, &BytesRead);
- if (BytesRead)
- {
- hUart->LocalRxBuff.WriteIndex += BytesRead;
- if (hUart->LocalRxBuff.WriteIndex >= hUart->LocalRxBuff.TotalBufferSize)
- hUart->LocalRxBuff.WriteIndex = 0;
- hUart->LocalRxBuff.DataAvailable += BytesRead;
- }
- if (BytesRead < SpaceFromWriteIndex)
- IsNextRead = NV_FALSE;
- }
- if ((!Error) && (IsNextRead) && (SpaceFromStartIndex))
- {
- Error = NvDdkPrivUartHwReadFromReceiveFifo(&hUart->UartHwRegs,
- &hUart->LocalRxBuff.pBuffPtr[hUart->LocalRxBuff.WriteIndex],
- SpaceFromStartIndex, &BytesRead);
- if (BytesRead)
- {
- hUart->LocalRxBuff.WriteIndex += BytesRead;
- if (hUart->LocalRxBuff.WriteIndex >= hUart->LocalRxBuff.TotalBufferSize)
- hUart->LocalRxBuff.WriteIndex = 0;
- hUart->LocalRxBuff.DataAvailable += BytesRead;
- }
- }
-
- // If flow control is enabled and data available is crossed the thresold
- // level then disable the rts so there will not be any incoming data.
- if (hUart->LocalRxBuff.DataAvailable >= hUart->LocalRxBuff.BufferLevelHigh)
- {
- if (hUart->IsRtsFlowEnable)
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs,
- NvDdkUartSignalName_Rts, NV_FALSE);
- UnlockRegisterAccess(hUart);
- }
- }
- UnlockReadFlow(hUart);
-
- // Update the transfer status.
- hUart->ReadReq.TransferStatus = Error;
- NvOsSemaphoreSignal(hUart->LocalRxBuff.hDataAvailableSema);
- }
-}
-
-/**
- * Handle the uart transmit interrupt.
- * Thread safety: Caller responsibility.
- */
-static void HandleUartTxInterrupt(NvDdkUartHandle hUart)
-{
- NvU32 BytesWritten;
-
- if (hUart->IsWritePolling)
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_FALSE);
- UnlockRegisterAccess(hUart);
-
- if (hUart->WriteReq.hOnCompleteSema)
- NvOsSemaphoreSignal(hUart->WriteReq.hOnCompleteSema);
- hUart->WriteReq.hOnCompleteSema = NULL;
- return;
- }
- // Write into the transmit fifo.
- BytesWritten = NvDdkPrivUartHwWriteInTransmitFifo(&hUart->UartHwRegs,
- hUart->WriteReq.pCurrTransBuf, hUart->WriteReq.BytesRemaining);
- if (BytesWritten)
- {
- hUart->WriteReq.BytesRemaining -= BytesWritten;
- hUart->WriteReq.BytesTransferred += BytesWritten;
- hUart->WriteReq.pCurrTransBuf += BytesWritten;
- }
-
- // If there is error or the bytes remaining to write is 0 then inform the
- // client.
- if (!hUart->WriteReq.BytesRemaining)
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_FALSE);
- UnlockRegisterAccess(hUart);
- NvOsSemaphoreSignal(hUart->WriteReq.hOnCompleteSema);
- }
-}
-
-/**
- * Handle the uart modem interrupt.
- * Thread safety: Caller responsibility.
- */
-static void HandleUartModemInterrupt(NvDdkUartHandle hUart)
-{
- NvU32 OldState = (hUart->UartHwRegs.ModemSignalSatus & hUart->ModemSignalName);
- NvU32 NewState;
-
- // Update the modem signal status.
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwUpdateModemSignal(&hUart->UartHwRegs);
- NewState = (hUart->UartHwRegs.ModemSignalSatus & hUart->ModemSignalName);
- UnlockRegisterAccess(hUart);
-
- if (OldState != NewState)
- {
- // Inform client that there is changes in the modem control signal.
- if (hUart->hModemSigChngCallback)
- (*(hUart->hModemSigChngCallback))
- (hUart->ModemSigChngHandlerArgs);
- }
-}
-
-/**
- * Handle all types of the uart interrupts.
- * Thread safety: Caller responsibility.
- */
-static void HandleUartInterrupt(void *args)
-{
- UartHwInterruptSource InterruptReason;
- NvDdkUartHandle hUart;
-
- hUart = (NvDdkUartHandle)args;
-
- // Some action on this channel, so boost frequency
- if (!hUart->IsFreqBoosted)
- NvOsSemaphoreSignal(hUart->hUartPowerMgrSema);
-
- // The interrupt status is provided from high priority till no pending
- // interrupt so do in the loop to handle all interrupts.
- while (1)
- {
- // Get the interrupt reason for this uart channel.
- InterruptReason = NvDdkPrivUartHwGetInterruptReason(&hUart->UartHwRegs);
-
- // No pending interrupt or error then break the loop and exit the error.
- if (UartHwInterruptSource_None == InterruptReason)
- break;
-
- // there is a valid interrupt reason so call appropriate function.
- switch (InterruptReason)
- {
- case UartHwInterruptSource_ReceiveError:
- NvDdkPrivUartHwSetReceiveInterrupt(&hUart->UartHwRegs, NV_FALSE, hUart->IsRxApbDmaBased);
- NvOsSemaphoreSignal(hUart->LocalRxBuff.hLineStatusSema);
- DEBUG_PRINT_RX_ERR(1, ("HandleUartInterrupt(): RX Error interrupt occured\n"));
- break;
-
- case UartHwInterruptSource_Receive:
- case UartHwInterruptSource_RxTimeout:
- case UartHwInterruptSource_EndOfData:
- HandleUartRxInterrupt(hUart, InterruptReason);
- break;
-
- case UartHwInterruptSource_Transmit:
- HandleUartTxInterrupt(hUart);
- break;
-
- case UartHwInterruptSource_ModemControl:
- HandleUartModemInterrupt(hUart);
- break;
-
- default:
- break;
- }
- }
-
- NvRmInterruptDone(hUart->InterruptHandle);
- return;
-}
-
-static NvError
-RegisterUartInterrupt(
- NvRmDeviceHandle hRmDevice,
- NvDdkUartHandle hDdkUart)
-{
- NvU32 IrqList;
- NvOsInterruptHandler IntHandlers;
- if (hDdkUart->InterruptHandle)
- {
- return NvSuccess;
- }
- IrqList = NvRmGetIrqForLogicalInterrupt(hRmDevice,
- NVRM_MODULE_ID(NvRmModuleID_Uart, hDdkUart->InstanceId), 0);
- IntHandlers = HandleUartInterrupt;
- return(NvRmInterruptRegister(hRmDevice, 1, &IrqList, &IntHandlers, hDdkUart,
- &hDdkUart->InterruptHandle, NV_TRUE));
-}
-
-/**
- * Uart power manager thread which manages the frequency requirement for the
- * channel. If there is no transaction in the channel for some time then it
- * reduces the frequency request otherwise it will keep the request for
- * higher frequency.
- */
-static void UartPowerManagerThread(void *args)
-{
- NvDdkUartHandle hUart = (NvDdkUartHandle)args;
- NvError Error = NvSuccess;
- NvU32 TimeOut = NV_WAIT_INFINITE;
- NvU32 TimeoutErrCount = 0;
- NvBool IsFreqDown = NV_TRUE;
- for (;;)
- {
- // Wait till any event occurs for the transmit thread to take any action.
- Error = NvOsSemaphoreWaitTimeout(hUart->hUartPowerMgrSema, TimeOut);
- if (!Error) // Got the signal from client.
- {
- // If need to stop the thread the return
- if (hUart->IsStopPowerThread)
- {
- // Bringdown the frequency before returning
- if (!IsFreqDown)
- NvRmPowerBusyHintMulti(hUart->hRmDevice, hUart->RmPowerClientId,
- hUart->DownFreq, MAX_FREQ_REQ_LIST,
- NvRmDfsBusyHintSyncMode_Async);
- hUart->IsFreqBoosted = NV_FALSE;
- break;
- }
-
- TimeoutErrCount = 0;
-
- // If the new state is suspended state then bringdown the freq
- if (hUart->IsSuspendedState)
- {
- if (!IsFreqDown)
- NvRmPowerBusyHintMulti(hUart->hRmDevice, hUart->RmPowerClientId,
- hUart->DownFreq, MAX_FREQ_REQ_LIST,
- NvRmDfsBusyHintSyncMode_Async);
- hUart->IsFreqBoosted = NV_FALSE;
- IsFreqDown = NV_TRUE;
- // Now boost the freq only when resume is called.
- TimeOut = NV_WAIT_INFINITE;
- continue;
- }
-
- // If frequency is already boosted then no need to increase the
- // frequency
- if (IsFreqDown)
- NvRmPowerBusyHintMulti(hUart->hRmDevice, hUart->RmPowerClientId,
- hUart->UpFreq, MAX_FREQ_REQ_LIST,
- NvRmDfsBusyHintSyncMode_Async);
- hUart->IsFreqBoosted = NV_TRUE;
- IsFreqDown = NV_FALSE;
- // Wait for the high freq hold timeout.
- TimeOut = HIGH_FREQUENCY_HOLD_TIMEOUT;
- continue;
- }
-
- // Dont down the freq in first timeout, do in next timeout.
- if (!TimeoutErrCount)
- {
- // Assume the freq is reduced but actually reduce in next timeout.
- hUart->IsFreqBoosted = NV_FALSE;
- TimeoutErrCount++;
- TimeOut = HIGH_FREQUENCY_HOLD_TIMEOUT;
- }
- else
- {
- // No signal from client and second time, timeout happen and so it
- // may bringdown the frequency
- if (!IsFreqDown)
- NvRmPowerBusyHintMulti(hUart->hRmDevice, hUart->RmPowerClientId,
- hUart->DownFreq, MAX_FREQ_REQ_LIST,
- NvRmDfsBusyHintSyncMode_Async);
- hUart->IsFreqBoosted = NV_FALSE;
- IsFreqDown = NV_TRUE;
-
- // Now wait for the signal for freq boosting request.
- TimeOut = NV_WAIT_INFINITE;
- }
- }
-}
-
-static void
-SetBaudRateDependentParameter(
- NvDdkUartHandle hUart,
- NvU32 BaudRate)
-{
- NvU32 CpuFreqReqd;
- CpuFreqReqd = (BaudRate >= 900000)? 450000: ((BaudRate >= 250000)? 400000: 350000);
-
- hUart->UpFreq[0].ClockId = NvRmDfsClockId_Cpu;
- hUart->UpFreq[0].BoostDurationMs = NV_WAIT_INFINITE;
- hUart->UpFreq[0].BoostKHz = CpuFreqReqd;
- hUart->UpFreq[0].BusyAttribute = NV_TRUE;
-
- hUart->UpFreq[1].ClockId = NvRmDfsClockId_Ahb;
- hUart->UpFreq[1].BoostDurationMs = NV_WAIT_INFINITE;
- hUart->UpFreq[1].BoostKHz = 144000;
- hUart->UpFreq[1].BusyAttribute = NV_TRUE;
-
- hUart->UpFreq[2].ClockId = NvRmDfsClockId_Emc;
- hUart->UpFreq[2].BoostDurationMs = NV_WAIT_INFINITE;
- hUart->UpFreq[2].BoostKHz = 166000;
- hUart->UpFreq[2].BusyAttribute = NV_TRUE;
-
- hUart->DownFreq[0].ClockId = NvRmDfsClockId_Cpu;
- hUart->DownFreq[0].BoostDurationMs = NV_WAIT_INFINITE;
- hUart->DownFreq[0].BoostKHz = 0;
- hUart->DownFreq[0].BusyAttribute = NV_TRUE;
-
- hUart->DownFreq[1].ClockId = NvRmDfsClockId_Ahb;
- hUart->DownFreq[1].BoostDurationMs = NV_WAIT_INFINITE;
- hUart->DownFreq[1].BoostKHz = 0;
- hUart->DownFreq[1].BusyAttribute = NV_TRUE;
-
- hUart->DownFreq[2].ClockId = NvRmDfsClockId_Emc;
- hUart->DownFreq[2].BoostDurationMs = NV_WAIT_INFINITE;
- hUart->DownFreq[2].BoostKHz = 0;
- hUart->DownFreq[2].BusyAttribute = NV_TRUE;
-
- // Selected 400 microsecond for polling
- hUart->MaxTxBytesPolling = (BaudRate >= 2000000)? 0x40 : ((BaudRate >= 900000)? 0x30: 0x10);
- hUart->Char4TimeUs = (40000000 + BaudRate - 1)/(BaudRate); // 4 char*1000000us*10bitperchar
-}
-
-/**
- * Destroy the handle of uart channel and free all the allocation done for it.
- * Thread safety: Caller responsibility.
- */
-static void DestroyUartChannelHandle(NvDdkUartHandle hUart)
-{
- NvRmModuleID ModuleId;
-
- // If null pointer for uart handle then return error.
- if (!hUart)
- return;
-
- // Close the uart odm handle
- if (hUart->hOdmUart)
- NvOdmUartClose(hUart->hOdmUart);
-
- ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, hUart->InstanceId);
-
- if (hUart->RmPowerClientId)
- {
- // Disable the clocks.
- NV_ASSERT_SUCCESS(NvRmPowerModuleClockControl(
- hUart->hRmDevice,
- ModuleId, hUart->RmPowerClientId,
- NV_FALSE));
-
- // Disable the power to the controller.
- NV_ASSERT_SUCCESS(NvRmPowerVoltageControl(
- hUart->hRmDevice,
- ModuleId,
- hUart->RmPowerClientId,
- NvRmVoltsOff,
- NvRmVoltsOff,
- NULL,
- 0,
- NULL));
-
- // Unregister for the power manager.
- NvRmPowerUnRegister(hUart->hRmDevice, hUart->RmPowerClientId);
- NvOsSemaphoreDestroy(hUart->hRmPowerEventSema);
- }
- NvDdkPrivUartHwClearAllInt(&hUart->UartHwRegs);
-
- if (hUart->InterruptHandle)
- {
- NvRmInterruptUnregister(hUart->hRmDevice, hUart->InterruptHandle);
- hUart->InterruptHandle = NULL;
- }
-
- // Kill the power manager thread.
- if (hUart->hUartPowerMgrThread)
- {
- hUart->IsStopPowerThread = NV_TRUE;
- NvOsSemaphoreSignal(hUart->hUartPowerMgrSema);
- NvOsThreadJoin(hUart->hUartPowerMgrThread);
- }
-
- NvOsSemaphoreDestroy(hUart->hUartPowerMgrSema);
-
- // Unmap the virtual mapping of the uart hw register.
- NvRmPhysicalMemUnmap(hUart->UartHwRegs.pRegsVirtBaseAdd,
- hUart->UartHwRegs.BankSize);
-
- DestroyLocalRxBuff(hUart);
-
- if (hUart->IsDmaSupport)
- {
- // Free the dma handles if it is allocated.
- NvRmDmaAbort(hUart->hRxRmDma);
- NvRmDmaFree(hUart->hRxRmDma);
-
- NvRmDmaAbort(hUart->hTxRmDma);
- NvRmDmaFree(hUart->hTxRmDma);
-
- // Destroy Dma Buffers
- DestroyDmaTransferBuffer(hUart->hRmMemory, hUart->pRxDmaBuffer,
- hUart->pTxDmaBuffer, UART_RX_DMA_PING_BUFFER_SIZE << 1);
- }
-
- // Tri-State the pin-mux pins
- NV_ASSERT_SUCCESS(NvRmSetModuleTristate(hUart->hRmDevice, ModuleId, NV_TRUE));
-
- // Destroy the mutex allocated for the uart read/write/register/channel access.
- DestroyReadFlowLock(hUart);
- DestroyWriteFlowLock(hUart);
- DestroyRegisterAccessLock(hUart);
-
-
- // Destroy the sync sempahores.
- NvOsSemaphoreDestroy(hUart->hRxSynchSema);
- NvOsSemaphoreDestroy(hUart->hTxSynchSema);
-
- // Free the memory of the uart handles.
- NvOsFree(hUart);
-}
-
-/**
- * Create the handle for the uart channel.
- * Thread safety: Caller responsibility.
- */
-static NvError CreateUartChannelHandle(
- NvRmDeviceHandle hRmDevice,
- NvU32 ChannelId,
- NvDdkUartHandle *phUart)
-{
- NvError Error = NvSuccess;
- NvDdkUartHandle hNewUart = NULL;
- NvRmModuleID ModuleId;
- NvRmModuleUartInterfaceCaps InterfaceCap;
-
- ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, ChannelId);
-
- *phUart = NULL;
-
- if (NvRmSetModuleTristate(hRmDevice,ModuleId,NV_FALSE)!=NvSuccess)
- return NvError_NotSupported;
-
- Error = NvRmGetModuleInterfaceCapabilities(hRmDevice, ModuleId,
- sizeof(InterfaceCap), &InterfaceCap);
- if (Error)
- return Error;
-
- // If the number of lines available in platform is 0 then return error
- // as the uart is not supported on the given platform.
- if (InterfaceCap.NumberOfInterfaceLines == 0)
- return NvError_NotSupported;
-
- // Allocoate the memory for the uart handle.
- hNewUart = NvOsAlloc(sizeof(NvDdkUart));
- if (!hNewUart)
- {
- return NvError_InsufficientMemory;
- }
-
- // Reset the memory allocated for the uart handle.
- NvOsMemset(hNewUart, 0, sizeof(*hNewUart));
-
- // Set the uart handle parameters.
- hNewUart->hRmDevice = hRmDevice;
- hNewUart->InstanceId = ChannelId;
- hNewUart->OpenCount = 0;
- hNewUart->NumberOfInterfaceLine = InterfaceCap.NumberOfInterfaceLines;
-
- hNewUart->WriteReq.hOnCompleteSema = NULL;
- hNewUart->WriteReq.pCurrTransBuf = NULL;
-
- hNewUart->ReadReq.hOnCompleteSema = NULL;
- hNewUart->ReadReq.pCurrTransBuf = NULL;
-
- hNewUart->hRxSynchSema = NULL;
- hNewUart->hTxSynchSema = NULL;
-
- hNewUart->IsRtsFlowEnable = NV_FALSE;
- hNewUart->IsCtsFlowEnable = NV_FALSE;
-
- hNewUart->hRmMemory = NULL;
- hNewUart->RxDmaBuffPhysAdd = 0;
- hNewUart->pRxDmaBuffer = NULL;
- hNewUart->hRxRmDma = NULL;
-
- hNewUart->TxDmaBuffPhysAdd = 0;
- hNewUart->pTxDmaBuffer = NULL;
- hNewUart->hTxRmDma = NULL;
-
- hNewUart->hWriteMutex = NULL;
- hNewUart->hReadMutex = NULL;
- hNewUart->hRegisterAccessMutex = NULL;
-
- hNewUart->hModemSigChngCallback = NULL;
- hNewUart->pUartInfo = s_pUartInfo;
- hNewUart->hRmPowerEventSema = NULL;
- hNewUart->RmPowerClientId = 0;
- hNewUart->hOdmUart = NULL;
-
- hNewUart->IsRxApbDmaBased = NV_FALSE;
- hNewUart->IsDmaReadStarted = NV_FALSE;
-
- hNewUart->IsStopPowerThread = NV_FALSE;
- hNewUart->IsFreqBoosted = NV_FALSE;
- hNewUart->IsSuspendedState = NV_FALSE;
-
- hNewUart->hUartPowerMgrThread = NULL;
- hNewUart->hUartPowerMgrSema = NULL;
-
- // Initialize the uart configuration parameters.
- hNewUart->UartConfig.UartBaudRate = 0;
- hNewUart->UartConfig.UartDataLength = 5;
- hNewUart->UartConfig.UartParityBit = NvDdkUartParity_None;
- hNewUart->UartConfig.UartStopBit = NvDdkUartStopBit_1;
- hNewUart->UartConfig.IsEnableIrdaModulation = NV_FALSE;
-
- NvDdkPrivUartHwRegisterInitialize(ChannelId, &hNewUart->UartHwRegs);
- hNewUart->OldRtsState = hNewUart->UartHwRegs.IsRtsActive;
- hNewUart->OldDtrState = hNewUart->UartHwRegs.IsDtrActive;
-
- // Initialize the baudrate dependent parameter.
- SetBaudRateDependentParameter(hNewUart, 9600);
-
- // Get the soc capabilities and if error return here now.
- Error = UartGetSocCapabilities(hRmDevice, ChannelId, &hNewUart->SocUartCaps);
- if (!Error)
- {
- hNewUart->UartHwRegs.IsEndOfDataIntSupport =
- hNewUart->SocUartCaps.IsEndOfDataIntSupported;
- hNewUart->UartHwRegs.IsRtsHwFlowSupported =
- hNewUart->SocUartCaps.IsRtsHwFlowControlSupported;
- }
-
- // If error the return now.
- if (Error)
- {
- NvOsFree(hNewUart);
- return Error;
- }
-
- // Create the odm uart handle
- hNewUart->hOdmUart = NvOdmUartOpen(ChannelId);
-
- // Create the local buffer information.
- Error = CreateLocalRxBuff(hNewUart, UART_RX_LOCAL_BUFFER_SIZE_MIN);
-
- // Create all mutex required for the channel.
- if (!Error)
- Error = CreateReadFlowLock(hNewUart);
- if (!Error)
- Error = CreateWriteFlowLock(hNewUart);
- if (!Error)
- Error = CreateRegisterAccessLock(hNewUart);
-
- // Create the synchronous semaphores.
- if (!Error)
- Error = NvOsSemaphoreCreate(&hNewUart->hRxSynchSema, 0);
-
- if (!Error)
- Error = NvOsSemaphoreCreate(&hNewUart->hTxSynchSema, 0);
-
- // Create the read/write transfer information.
- if (!Error)
- {
- InitTransferInfo(hNewUart->hRmDevice, &hNewUart->WriteReq);
- InitTransferInfo(hNewUart->hRmDevice, &hNewUart->ReadReq);
-
- NvRmModuleGetBaseAddress(hRmDevice, ModuleId,
- &hNewUart->UartHwRegs.RegsPhyBaseAdd, &hNewUart->UartHwRegs.BankSize);
-
- Error = NvRmPhysicalMemMap(hNewUart->UartHwRegs.RegsPhyBaseAdd,
- hNewUart->UartHwRegs.BankSize, NVOS_MEM_READ_WRITE,
- NvOsMemAttribute_Uncached,
- (void **)&hNewUart->UartHwRegs.pRegsVirtBaseAdd);
- }
-
- // Create the dma transfer buffer, allocate the dma and initialize the
- // request structure.
- if (!Error)
- {
- Error = CreateDmaTransferBuffer(hNewUart->hRmDevice, &hNewUart->hRmMemory,
- &hNewUart->RxDmaBuffPhysAdd, (void **)&hNewUart->pRxDmaBuffer,
- &hNewUart->TxDmaBuffPhysAdd, (void **)&hNewUart->pTxDmaBuffer,
- UART_RX_DMA_PING_BUFFER_SIZE << 1);
-
- // Allocate the two dma (one for Rx and One for Tx) with high priority
- if (!Error)
- Error = NvRmDmaAllocate(hNewUart->hRmDevice, &hNewUart->hRxRmDma,
- NV_FALSE, NvRmDmaPriority_High, NvRmDmaModuleID_Uart,
- hNewUart->InstanceId);
- if (!Error)
- {
- Error = NvRmDmaAllocate(hNewUart->hRmDevice, &hNewUart->hTxRmDma,
- NV_FALSE, NvRmDmaPriority_High, NvRmDmaModuleID_Uart,
- hNewUart->InstanceId);
- }
- if (Error)
- {
- hNewUart->IsDmaSupport = NV_FALSE;
- DestroyDmaTransferBuffer(hNewUart->hRmMemory, hNewUart->pRxDmaBuffer,
- hNewUart->pTxDmaBuffer, UART_RX_DMA_PING_BUFFER_SIZE << 1);
-
- NvRmDmaFree(hNewUart->hRxRmDma);
- NvRmDmaFree(hNewUart->hTxRmDma);
- hNewUart->hRmMemory = NULL;
- hNewUart->pRxDmaBuffer = NULL;
- hNewUart->pTxDmaBuffer = NULL;
- hNewUart->hRxRmDma = NULL;
- hNewUart->hTxRmDma = NULL;
- Error = NvSuccess;
-
- }
- else
- {
- hNewUart->IsDmaSupport = NV_TRUE;
- hNewUart->WDmaReq.SourceBufferPhyAddress = hNewUart->TxDmaBuffPhysAdd;
- hNewUart->WDmaReq.DestinationBufferPhyAddress = hNewUart->UartHwRegs.RegsPhyBaseAdd;
- hNewUart->WDmaReq.SourceAddressWrapSize = 0;
- hNewUart->WDmaReq.DestinationAddressWrapSize = 4;
- hNewUart->TxDmaBufferSize = UART_RX_DMA_PING_BUFFER_SIZE << 1;
-
- hNewUart->RDmaReq.SourceBufferPhyAddress = hNewUart->UartHwRegs.RegsPhyBaseAdd;
- hNewUart->RDmaReq.DestinationBufferPhyAddress = hNewUart->RxDmaBuffPhysAdd;
- hNewUart->RDmaReq.SourceAddressWrapSize = 4;
- hNewUart->RDmaReq.DestinationAddressWrapSize = 0;
- hNewUart->RxDmaBufferSize = UART_RX_DMA_PING_BUFFER_SIZE << 1;
- hNewUart->HalfRxDmaBufferSize = UART_RX_DMA_PING_BUFFER_SIZE;
-
- }
- }
-
- // Register as the Rm power client
- if (!Error)
- {
- Error = NvOsSemaphoreCreate(&hNewUart->hRmPowerEventSema, 0);
- if (!Error)
- Error = NvRmPowerRegister(hNewUart->hRmDevice, hNewUart->hRmPowerEventSema,
- &hNewUart->RmPowerClientId);
- }
-
- // Enable power for uart module
- if (!Error)
- Error = NvRmPowerVoltageControl(hNewUart->hRmDevice, ModuleId,
- hNewUart->RmPowerClientId,
- NvRmVoltsUnspecified, NvRmVoltsUnspecified,
- NULL, 0, NULL);
-
- // Enable the clock.
- if (!Error)
- Error = NvRmPowerModuleClockControl(hRmDevice, ModuleId, hNewUart->RmPowerClientId,
- NV_TRUE);
-
- // Create the thread which keep the power/frequency requirement of the
- // uart channel.
- if (!Error)
- {
- Error = NvOsSemaphoreCreate(&hNewUart->hUartPowerMgrSema, 0);
- if (!Error)
- Error = NvOsThreadCreate(UartPowerManagerThread, hNewUart, &hNewUart->hUartPowerMgrThread);
- }
-
- // Reset the uart controller.
- if (!Error)
- NvRmModuleReset(hRmDevice, ModuleId);
-
- if (!Error)
- Error = RegisterUartInterrupt(hRmDevice, hNewUart);
-
- // Configure the uart handle for the non dma mode transfer as basic transfer.
- if (!Error)
- {
- // Enable the fifo mode of the uart and reset the fifo
- NvDdkPrivUartHwInitFifo(&hNewUart->UartHwRegs);
- NvDdkPrivUartHwSetDmaMode(&hNewUart->UartHwRegs, hNewUart->IsDmaSupport);
- }
- // If error then destroy all the allocation done here.
- if (Error)
- {
- DestroyUartChannelHandle(hNewUart);
- hNewUart = NULL;
- }
- *phUart = hNewUart;
- return Error;
-}
-
-/**
- * Read from the local buffer.
- * Thread safety: Caller responsibility.
- */
-static NvU32 ReadFromLocalBuffer(
- NvU8 *pReceiveBuffer,
- NvU32 BytesRequested,
- UartLocalBuffer *pRxLocalBuffer)
-{
- NvU32 DataToBeRead;
- NvU32 DataRead = 0;
-
- // Get the current write index and then read based on this index.
- DataToBeRead = NV_MIN(BytesRequested, pRxLocalBuffer->DataAvailable);
- while (DataToBeRead)
- {
- *pReceiveBuffer++ = pRxLocalBuffer->pBuffPtr[pRxLocalBuffer->ReadIndex++];
- if (pRxLocalBuffer->ReadIndex >= pRxLocalBuffer->TotalBufferSize)
- pRxLocalBuffer->ReadIndex = 0;
-
- DataToBeRead--;
- DataRead++;
- }
- pRxLocalBuffer->DataAvailable = pRxLocalBuffer->DataAvailable - DataRead;
- return DataRead;
-}
-
-
-/**
- * Stop the write operation.
- * Thread protection: By caller
- */
-static void UartStopWrite(NvDdkUartHandle hUart, NvBool IsResetTxFifoIfNotBusy)
-{
- // If write transfer state is not busy then invalid state error.
- if (hUart->WriteReq.IsBusy)
- {
- hUart->WriteReq.IsStopReq = NV_TRUE;
- NvOsSemaphoreSignal(hUart->WriteReq.hOnCompleteSema);
- if (!hUart->IsDmaSupport)
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_FALSE);
- UnlockRegisterAccess(hUart);
- }
- }
- else
- {
- if (IsResetTxFifoIfNotBusy)
- NvDdkPrivUartHwResetFifo(&hUart->UartHwRegs,
- UartDataDirection_Transmit);
- }
-}
-
-
-/**
- * Wait till tx fifo become empty. This is required when either we change the
- * baudrate or we go for suspend.
- * Thread protection: By caller
- */
-static void WaitTillTxFifoEmpty(NvDdkUartHandle hUart)
-{
- NvDdkUartConfiguarations *pUartCurrConfig = NULL;
-
- NvBool IsTxFifoEmpty;
- NvU32 CharacterWaitTimeInUs;
- NvU32 WaitTimeInMs;
- NvU32 RemainingWaitTimeoutUs;
-
- // Get the uart configuration pointers.
- pUartCurrConfig = &hUart->UartConfig;
-
- // Wait for the Tx fifo to be empty if the current baudrate is non zero.
- // Wait time is maximum of (fifo depth + 4) character time, and if it
- // does not get flushed then reset the fifo.
- // Here + 4 is for the safer side.
- if (pUartCurrConfig->UartBaudRate)
- {
- // 1 char time in microsecond: 1 char*1000000us*10 bitperchar
- CharacterWaitTimeInUs = (10000000 + pUartCurrConfig->UartBaudRate - 1)/
- (pUartCurrConfig->UartBaudRate);
- RemainingWaitTimeoutUs = (hUart->SocUartCaps.FifoDepth + 4)*CharacterWaitTimeInUs;
- WaitTimeInMs = (CharacterWaitTimeInUs + 999)/1000;
- while(1)
- {
- IsTxFifoEmpty = NvDdkPrivUartHwIsTransmitFifoEmpty(&hUart->UartHwRegs);
- if (IsTxFifoEmpty)
- break;
- NvOsSleepMS(WaitTimeInMs);
- if (RemainingWaitTimeoutUs > (WaitTimeInMs * 1000))
- {
- RemainingWaitTimeoutUs -= (WaitTimeInMs * 1000);
- continue;
- }
- break;
- }
-
- // If the tx fifo is not empty then reset the fifo forcefully.
- if (!IsTxFifoEmpty)
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwResetFifo(&hUart->UartHwRegs, UartDataDirection_Transmit);
- UnlockRegisterAccess(hUart);
- }
- }
-
-}
-/**
- * Open the uart handle.
- */
-NvError
-NvDdkUartOpen(
- NvRmDeviceHandle hRmDevice,
- NvU32 ChannelId,
- NvDdkUartHandle *phUart)
-{
- NvError Error = NvSuccess;
- DdkUartChannelInfo *pUartInfo = NULL;
- NvDdkUart *pUartChannel = NULL;
- NvU32 InstanceAvailable;
-
- NV_ASSERT(phUart);
- NV_ASSERT(hRmDevice);
-
- *phUart = NULL;
-
- InstanceAvailable = NvRmModuleGetNumInstances(hRmDevice, NvRmModuleID_Uart);
- if (ChannelId >= InstanceAvailable)
- return NvError_NotSupported;
-
- Error = InitUartInformation(hRmDevice);
- if (Error)
- return Error;
- pUartInfo = s_pUartInfo;
-
- // Lock the uart info mutex access.
- NvOsMutexLock(pUartInfo->hUartOpenMutex);
-
- // Check for the open uart handle to find out whether same instance port
- // name exit or not.
- pUartChannel = pUartInfo->hUartList[ChannelId];
-
- // If the uart handle does not exist then create it.
- if (!pUartChannel)
- {
- Error = CreateUartChannelHandle(hRmDevice, ChannelId, &pUartChannel);
- if (!Error)
- {
- pUartInfo->hUartList[ChannelId] = pUartChannel;
- pUartChannel->OpenCount++;
- }
- }
-
- // Unlock the uart info access.
- NvOsMutexUnlock(pUartInfo->hUartOpenMutex);
-
- // If no error then update the passed pointers.
- if (!Error)
- {
- *phUart = pUartChannel;
- }
- return Error;
-}
-
-/**
- * Close the uart handle.
- */
-void NvDdkUartClose(NvDdkUartHandle hUart)
-{
- DdkUartChannelInfo *pUartInformation = NULL;
-
- // if null parameter then do nothing.
- if (!hUart)
- return;
-
- // Get the uart information pointer.
- pUartInformation = hUart->pUartInfo;
-
- // Lock the uart information access.
- NvOsMutexLock(pUartInformation->hUartOpenMutex);
-
- // decrement the open count and it becomes 0 then release all the allocation
- // done for this handle.
- hUart->OpenCount--;
-
- // If the open count become zero then remove from the list of handles and
- // free..
- if (hUart->OpenCount == 0)
- {
- // Read/write should not be on this channel.
- NV_ASSERT((!hUart->ReadReq.IsBusy) || (!hUart->WriteReq.IsBusy));
-
- pUartInformation->hUartList[hUart->InstanceId] = NULL;
- // Now destroy the handles.
- DestroyUartChannelHandle(hUart);
- }
-
- // Unlock the uart information access.
- NvOsMutexUnlock(pUartInformation->hUartOpenMutex);
-}
-
-/**
- * Set the uart configuration which is configured currently.
- */
-NvError
-NvDdkUartSetConfiguration(
- NvDdkUartHandle hUart,
- const NvDdkUartConfiguarations* const pUartNewConfig)
-{
- NvError Error = NvSuccess;
- NvDdkUartConfiguarations *pUartCurrConfig = NULL;
- NvU32 ConfiguredClockFreq = 0;
- NvRmModuleID ModuleId;
- NvU32 MinClockFreqReqd;
- NvU32 MaxClockFreqReqd;
- NvU32 ClockFreqReqd = 0;
-
- NV_ASSERT(hUart);
- NV_ASSERT(pUartNewConfig);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- // Stop bit 1.5 is supported only with the data length of 5.
- if ((pUartNewConfig->UartStopBit == NvDdkUartStopBit_1_5) &&
- ((pUartNewConfig->UartDataLength != 5)))
- return NvError_NotSupported;
-
- // Stop bit 2 is not supported with the data length of 5.
- if ((pUartNewConfig->UartStopBit == NvDdkUartStopBit_2) &&
- ((pUartNewConfig->UartDataLength == 5)))
- return NvError_NotSupported;
-
- // Get the uart configuration pointers.
- pUartCurrConfig = &hUart->UartConfig;
-
- // Wait for the Tx fifo to be empty.
- WaitTillTxFifoEmpty(hUart);
-
- LockRegisterAccess(hUart);
- // Set the required baud rate if there is any change.
- if (pUartNewConfig->UartBaudRate != pUartCurrConfig->UartBaudRate)
- {
- // Get the clock frequency related to the baud rate.
- NvDdkPrivUartHwGetReqdClockSourceFreq(pUartNewConfig->UartBaudRate,
- &MinClockFreqReqd, &ClockFreqReqd, &MaxClockFreqReqd);
-
- ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, hUart->InstanceId);
- Error = NvRmPowerModuleClockConfig(hUart->hRmDevice,
- ModuleId, 0, MinClockFreqReqd, MaxClockFreqReqd,
- &ClockFreqReqd, 1, &ConfiguredClockFreq, 0);
-
- // If not error then check for configured clock frequency and verify.
- if (!Error)
- {
- // Set the baudrate and get the required clock frequency.
- Error = NvDdkPrivUartHwSetBaudRate(&hUart->UartHwRegs,
- pUartNewConfig->UartBaudRate, ConfiguredClockFreq);
- if (!Error)
- pUartCurrConfig->UartBaudRate = pUartNewConfig->UartBaudRate;
- }
-
- // If error then return here only.
- if (Error)
- goto ErrorExit;
-
- SetBaudRateDependentParameter(hUart, pUartCurrConfig->UartBaudRate);
- }
-
- // Configured for parity bit.
- if (pUartNewConfig->UartParityBit != pUartCurrConfig->UartParityBit)
- {
- Error = NvDdkPrivUartHwSetParityBit(&hUart->UartHwRegs,
- pUartNewConfig->UartParityBit);
- if (Error)
- goto ErrorExit;
- pUartCurrConfig->UartParityBit = pUartNewConfig->UartParityBit;
- }
-
- // Configured for the data length.
- if (pUartNewConfig->UartDataLength != pUartCurrConfig->UartDataLength)
- {
- Error = NvDdkPrivUartHwSetDataLength(&hUart->UartHwRegs,
- pUartNewConfig->UartDataLength);
- if (Error)
- goto ErrorExit;
- pUartCurrConfig->UartDataLength = pUartNewConfig->UartDataLength;
- }
-
- // Configured for stop bit length.
- if (pUartNewConfig->UartStopBit != pUartCurrConfig->UartStopBit)
- {
- Error = NvDdkPrivUartHwSetStopBit(&hUart->UartHwRegs,
- pUartNewConfig->UartStopBit);
- if (Error)
- goto ErrorExit;
- pUartCurrConfig->UartStopBit = pUartNewConfig->UartStopBit;
- }
-
- // Configured for the Irda modulation.
- if (pUartNewConfig->IsEnableIrdaModulation != pUartCurrConfig->IsEnableIrdaModulation)
- {
- NvDdkPrivUartHwSetIrdaCoding(&hUart->UartHwRegs, pUartNewConfig->IsEnableIrdaModulation);
- pUartCurrConfig->IsEnableIrdaModulation = pUartNewConfig->IsEnableIrdaModulation;
- }
-ErrorExit:
- UnlockRegisterAccess(hUart);
-
- // Boost frequency now.
- if ((!Error) && (!hUart->IsFreqBoosted))
- NvOsSemaphoreSignal(hUart->hUartPowerMgrSema);
-
- return Error;
-}
-
-/**
- * Get the uart configuartion which is configured currently.
- */
-NvError
-NvDdkUartGetConfiguration(
- NvDdkUartHandle hUart,
- NvDdkUartConfiguarations* const pUartDriverConfiguration)
-{
- NV_ASSERT(hUart);
- NV_ASSERT(pUartDriverConfiguration);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- LockRegisterAccess(hUart);
- // Copy the current configured parameter for the uart communication.
- NvOsMemcpy(pUartDriverConfiguration, &hUart->UartConfig,
- sizeof(*pUartDriverConfiguration));
- UnlockRegisterAccess(hUart);
- return NvSuccess;
-}
-
-NvError
-NvDdkUartStartReadOnBuffer(
- NvDdkUartHandle hUart,
- NvOsSemaphoreHandle hRxEventSema,
- NvU32 BufferSize)
-{
- NvError Error = NvSuccess;
- NvU32 NewBufferSize;
- NvU8 *pNewBuff = NULL;
-
- NV_ASSERT(hUart);
- NV_ASSERT(BufferSize);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- // If reading is going on then it is not possible to change the size of the
- // local buffering
- if (hUart->ReadReq.IsBusy)
- return NvError_InvalidState;
-
- // Create the local buffer first.
- LockReadFlow(hUart);
- if (hUart->ReadReq.IsBusy)
- {
- UnlockReadFlow(hUart);
- return NvError_InvalidState;
- }
-
- // Deactivate the RTS line to stop the sender to data send as ddk is not
- // able to read the data.
- LockRegisterAccess(hUart);
- if (hUart->IsRtsFlowEnable)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, NvDdkUartSignalName_Rts, NV_FALSE);
-
- // Disable receive interrupt.
- NvDdkPrivUartHwSetReceiveInterrupt(&hUart->UartHwRegs, NV_TRUE, hUart->IsRxApbDmaBased);
- UnlockRegisterAccess(hUart);
-
- // Abort the dma if it is started.
- if ((hUart->IsDmaReadStarted) && (hUart->IsRxApbDmaBased))
- NvRmDmaAbort(hUart->hRxRmDma);
-
- hUart->IsRxApbDmaBased = NV_FALSE;
- hUart->IsDmaReadStarted = NV_FALSE;
-
- // Reset the Rx fifo.
- NvDdkPrivUartHwResetFifo(&hUart->UartHwRegs, UartDataDirection_Receive);
-
- // Check whether it is same size or not. If not then reallocate it.
- NewBufferSize = NV_MAX(UART_RX_LOCAL_BUFFER_SIZE_MIN, BufferSize);
- if (NewBufferSize != hUart->LocalRxBuff.TotalBufferSize)
- {
- pNewBuff = NvOsAlloc(NewBufferSize);
-
- // If allocated successfully then use this memory for local buffering.
- if(pNewBuff)
- {
- // Free the existing buffer.
- if (hUart->LocalRxBuff.pBuffPtr)
- NvOsFree(hUart->LocalRxBuff.pBuffPtr);
- hUart->LocalRxBuff.pBuffPtr = pNewBuff;
- }
- else
- {
- NewBufferSize = hUart->LocalRxBuff.TotalBufferSize;
- }
- }
- hUart->LocalRxBuff.ReadIndex = 0;
- hUart->LocalRxBuff.WriteIndex = 0;
- hUart->LocalRxBuff.DataAvailable = 0;
- hUart->LocalRxBuff.TotalBufferSize = NewBufferSize;
- hUart->LocalRxBuff.BufferLevelHigh = (NewBufferSize >> 1);
- hUart->LocalRxBuff.hDataAvailableSema = hRxEventSema;
- hUart->LocalRxBuff.hLineStatusSema = hRxEventSema;
-
- // Start the dma to start receiving the data.
- if (hUart->IsDmaSupport)
- {
- hUart->RDmaReq.TransferSize = hUart->RxDmaBufferSize;
- Error = NvRmDmaStartDmaTransfer(hUart->hRxRmDma, &hUart->RDmaReq,
- NvRmDmaDirection_Forward, 0, hUart->LocalRxBuff.hDataAvailableSema);
- if (!Error)
- {
- hUart->IsRxApbDmaBased = NV_TRUE;
- hUart->IsDmaReadStarted = NV_TRUE;
- hUart->LastReadIndex = 0;
- }
- Error = NvSuccess;
- }
-
- LockRegisterAccess(hUart);
- // Enable the receive interrupt.
- NvDdkPrivUartHwSetReceiveInterrupt(&hUart->UartHwRegs, NV_TRUE, hUart->IsRxApbDmaBased);
-
- // Activate the RTS line as ddk is able to receive more data as receive
- // buffer is empty.
- if (hUart->IsRtsFlowEnable)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, NvDdkUartSignalName_Rts,
- NV_TRUE);
-
- UnlockRegisterAccess(hUart);
- UnlockReadFlow(hUart);
- return Error;
-}
-
-NvError NvDdkUartClearReceiveBuffer(NvDdkUartHandle hUart)
-{
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- return NvDdkUartStartReadOnBuffer(hUart, hUart->LocalRxBuff.hDataAvailableSema,
- hUart->LocalRxBuff.TotalBufferSize);
-}
-
-NvError
-NvDdkUartUpdateReceiveBuffer(
- NvDdkUartHandle hUart,
- NvU32 *pAvailableBytes)
-{
- NvU32 SpaceAvailable;
- NvError Error = NvSuccess;
- NvU32 TransferdCount;
- NvU32 DataToBeCopied;
- NvU8 CpuReadBuffer[30];
- NvU32 TempTransCount;
- NvU32 Index;
- NvBool IsDmaIndexTobeReset = NV_FALSE;
- NvU32 BytesRead;
- NvBool IsBreakDetectd;
-
- NV_ASSERT(hUart);
- NV_ASSERT(pAvailableBytes);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- // Lock the transfer status mutex.
- LockReadFlow(hUart);
-
- BytesRead = 0;
- TransferdCount = 0;
- IsBreakDetectd = NvDdkPrivUartHwIsBreakSignalDetected(&hUart->UartHwRegs);
- if (hUart->IsRxApbDmaBased)
- {
- if (NvDdkPrivUartHwIsDataAvailableInFifo(&hUart->UartHwRegs))
- {
- // Disable the rts line as cpu is going to read the fifo.
- if (hUart->IsRtsFlowEnable)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs,
- NvDdkUartSignalName_Rts, NV_FALSE);
-
- // Get the transfer Count transferred by the dma. Also stop the apb
- // dma so that apb dma will not be able to transfer the data.
- Error = NvRmDmaGetTransferredCount(hUart->hRxRmDma, &TransferdCount, NV_TRUE);
- NV_ASSERT(Error == NvSuccess);
- if (Error)
- TransferdCount = 0;
-
- // Now Read the fifo by cpu.
- hUart->ReadReq.TransferStatus =
- NvDdkPrivUartHwReadFromReceiveFifo(&hUart->UartHwRegs,
- CpuReadBuffer, 25, &BytesRead);
- DEBUG_PRINT_RX_ERR(hUart->ReadReq.TransferStatus,
- ("NvDdkUartUpdateReceiveBuffer(): LSR Status shows error Error occured 0x%08x\n", hUart->ReadReq.TransferStatus));
-
- // Now start the dma so that receive data can be transferred again.
- Error = NvRmDmaGetTransferredCount(hUart->hRxRmDma, &TempTransCount, NV_FALSE);
- NV_ASSERT(Error == NvSuccess);
- if (Error)
- TransferdCount = 0;
- IsDmaIndexTobeReset = NV_TRUE;
- }
- else
- {
- // Get the transfer Count transferred by the dma without stopping the dma.
- Error = NvRmDmaGetTransferredCount(hUart->hRxRmDma, &TransferdCount, NV_FALSE);
- NV_ASSERT(Error == NvSuccess);
- if (Error)
- TransferdCount = 0;
- hUart->ReadReq.TransferStatus = NvSuccess;
-
- }
- if (TransferdCount)
- {
- //NvOsDebugPrintf("UartUpdate old TransCount 0x%08x and old Last ReadIndex 0x%08x\n ",
- //TransferdCount, hUart->LastReadIndex);
- if (hUart->LastReadIndex < hUart->HalfRxDmaBufferSize)
- TransferdCount = TransferdCount - hUart->LastReadIndex;
- else
- TransferdCount = TransferdCount - (hUart->LastReadIndex - hUart->HalfRxDmaBufferSize);
- }
-
- // Copy in the circular buffer
- if (TransferdCount)
- {
- SpaceAvailable = hUart->LocalRxBuff.TotalBufferSize - hUart->LocalRxBuff.DataAvailable;
- DataToBeCopied = NV_MIN(SpaceAvailable, TransferdCount);
-
- // For debugging the DataToBeCopied should never be less than
- // the TransferdCount
- NV_ASSERT(DataToBeCopied == TransferdCount);
- for (Index = 0; Index < DataToBeCopied; ++Index)
- {
- hUart->LocalRxBuff.pBuffPtr[hUart->LocalRxBuff.WriteIndex++] =
- hUart->pRxDmaBuffer[hUart->LastReadIndex++];
- if (hUart->LocalRxBuff.WriteIndex >= hUart->LocalRxBuff.TotalBufferSize)
- hUart->LocalRxBuff.WriteIndex = 0;
- if (hUart->LastReadIndex >= hUart->RxDmaBufferSize)
- hUart->LastReadIndex = 0;
- hUart->LocalRxBuff.DataAvailable++;
- }
-// NvOsDebugPrintf("uartUpdate New TransCount 0x%08x and new LastReadIndex 0x%08x\n",
-// TransferdCount, hUart->LastReadIndex);
- }
- if (BytesRead)
- {
- // Get the lcoal buffer pointer.
- SpaceAvailable = hUart->LocalRxBuff.TotalBufferSize - hUart->LocalRxBuff.DataAvailable;
- DataToBeCopied = NV_MIN(BytesRead, SpaceAvailable);
-
- // FixME!! For debugging the DataToBeCopied should never be less than
- // the BytesRead
- NV_ASSERT(DataToBeCopied == BytesRead);
-
- for (Index = 0; Index < DataToBeCopied; ++Index)
- {
- hUart->LocalRxBuff.pBuffPtr[hUart->LocalRxBuff.WriteIndex++] =
- CpuReadBuffer[Index];
- if (hUart->LocalRxBuff.WriteIndex >= hUart->LocalRxBuff.TotalBufferSize)
- hUart->LocalRxBuff.WriteIndex = 0;
- hUart->LocalRxBuff.DataAvailable++;
- }
- }
-
- if (IsDmaIndexTobeReset)
- hUart->LastReadIndex = 0;
-
- NvDdkPrivUartHwSetReceiveInterrupt(&hUart->UartHwRegs, NV_TRUE, NV_TRUE);
- }
-
- // See whether the readcall is waiting for the data or not. If yes then
- // copy on client buffer.
- if (hUart->ReadReq.IsBusy)
- {
- // If transfer status is success then read form local buffer
- // and upate the client information and inform if it
- // request has been completed.
- if ((hUart->ReadReq.TransferStatus == NvSuccess) && (!IsBreakDetectd))
- {
- BytesRead = ReadFromLocalBuffer(hUart->ReadReq.pCurrTransBuf,
- hUart->ReadReq.BytesRemaining, &hUart->LocalRxBuff);
-
- // If bytes read then update the read parameters.
- if (BytesRead)
- {
- hUart->ReadReq.pCurrTransBuf += BytesRead;
- hUart->ReadReq.BytesRemaining -= BytesRead;
- hUart->ReadReq.BytesTransferred += BytesRead;
- }
- }
-
- // If the transfer status is error or bytes remaining for
- // client is 0 then inform the client.
- if ((hUart->ReadReq.TransferStatus) || (!hUart->ReadReq.BytesRemaining)
- || IsBreakDetectd)
- {
- // Break signal status is higher priority than other status.
- if (IsBreakDetectd)
- hUart->ReadReq.TransferStatus = NvError_UartBreakReceived;
-
- // Update the current state.
- hUart->ReadReq.IsBusy = NV_FALSE;
-
- // Inform the client that transfer is complete.
- NvOsSemaphoreSignal(hUart->ReadReq.hOnCompleteSema);
- }
- }
- else
- {
- // Break signal status is higher priority than other status.
- if (IsBreakDetectd)
- hUart->ReadReq.TransferStatus = NvError_UartBreakReceived;
- }
-
- // If flow control is enabled and if the data available is more then the
- // higher water level of the local buffer then disable the rts line.
- if (hUart->IsRtsFlowEnable)
- {
- if (hUart->LocalRxBuff.DataAvailable < hUart->LocalRxBuff.BufferLevelHigh)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs,
- NvDdkUartSignalName_Rts, NV_TRUE);
- else
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs,
- NvDdkUartSignalName_Rts, NV_FALSE);
- }
- UnlockReadFlow(hUart);
-
- *pAvailableBytes = hUart->LocalRxBuff.DataAvailable;
- return hUart->ReadReq.TransferStatus;
-}
-
-/**
- * Read the data from com channel.
- * Thread safety: Provided in the function.
- */
-NvError
-NvDdkUartRead(
- NvDdkUartHandle hUart,
- NvU8 *pReceiveBuffer,
- NvU32 BytesRequested,
- NvU32 *pBytesRead,
- NvU32 WaitTimeoutMs)
-{
- NvError Error = NvSuccess;
- NvU32 BytesRead;
-#if ENABLE_READ_PROFILE
- NvU32 EntryTime = NvOsGetTimeMS();
-#endif
-
- NV_ASSERT(hUart);
- NV_ASSERT(pReceiveBuffer);
- NV_ASSERT(pBytesRead);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- // Check for the status and if it is in busy state then return error.
- if (hUart->ReadReq.IsBusy)
- {
- DEBUG_PRINT_RX_ERR(1, ("NvDdkUartRead(): Error occured Invalid state\n"));
- return NvError_InvalidState;
- }
-
- LockReadFlow(hUart);
- if (hUart->ReadReq.IsBusy)
- {
- UnlockReadFlow(hUart);
- DEBUG_PRINT_RX_ERR(1, ("NvDdkUartRead(): Error occured Invalid state\n"));
- return NvError_InvalidState;
- }
-
- // Get the data from the local buffer and if it has the requested number of
- // bytes then comeout.
- BytesRead = ReadFromLocalBuffer(pReceiveBuffer, BytesRequested, &hUart->LocalRxBuff);
- // If read completely or if wait timeout is 0 (read whatever available
- // in the fifo) or any error then return.
- if ((BytesRead == BytesRequested) || (!WaitTimeoutMs) ||
- (hUart->ReadReq.TransferStatus))
- {
- Error = hUart->ReadReq.TransferStatus;
- hUart->ReadReq.TransferStatus = NvSuccess;
-
- // If flow control is enabled and if the data available is less then the
- // higher water level of the local buffer then enable the rts line.
- if (hUart->IsRtsFlowEnable)
- {
- if (hUart->LocalRxBuff.DataAvailable < hUart->LocalRxBuff.BufferLevelHigh)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs,
- NvDdkUartSignalName_Rts, NV_TRUE);
- }
-
- UnlockReadFlow(hUart);
- *pBytesRead = BytesRead;
- DEBUG_PRINT_RX_ERR(Error, ("NvDdkUartRead(): Error occured 0x%08x\n",Error));
-#if ENABLE_READ_PROFILE
- if (!Error)
- NvOsDebugPrintf("NvDdkUartRead(): EntryTime 0x%08x and ExitTime 0x%08x\n",
- EntryTime, NvOsGetTimeMS());
-#endif
- return Error;
- }
-
- hUart->ReadReq.pReqBuffer = pReceiveBuffer;
- hUart->ReadReq.pCurrTransBuf = pReceiveBuffer + BytesRead;
- hUart->ReadReq.BytesRequested = BytesRequested;
- hUart->ReadReq.BytesRemaining = BytesRequested - BytesRead;
- hUart->ReadReq.BytesTransferred = BytesRead;
- hUart->ReadReq.TransferStatus = NvSuccess;
- hUart->ReadReq.hOnCompleteSema = hUart->hRxSynchSema;
- hUart->ReadReq.IsStopReq = NV_FALSE;
- hUart->ReadReq.IsBusy = NV_TRUE;
-
- // Reset the semaphore count
- ResetSemaphoreCount(hUart->hRxSynchSema);
- UnlockReadFlow(hUart);
- *pBytesRead = 0;
- Error = NvOsSemaphoreWaitTimeout(hUart->ReadReq.hOnCompleteSema, WaitTimeoutMs);
-
- // Check the status
- LockReadFlow(hUart);
- if ((hUart->ReadReq.TransferStatus) || (hUart->ReadReq.IsStopReq) ||
- (Error == NvError_Timeout))
- {
- hUart->ReadReq.IsBusy = NV_FALSE;
- if (!hUart->ReadReq.BytesRemaining)
- Error = NvSuccess;
- else
- Error = (hUart->ReadReq.TransferStatus)? hUart->ReadReq.TransferStatus: NvError_Timeout;
- }
- UnlockReadFlow(hUart);
-
- DEBUG_PRINT_RX_ERR(((Error) && (Error != NvError_Timeout)),
- ("NvDdkUartRead(): Error occured 0x%08x\n",Error));
- *pBytesRead = hUart->ReadReq.BytesTransferred;
-
-#if ENABLE_READ_PROFILE
- if (!Error)
- NvOsDebugPrintf("NvDdkUartRead(): EntryTime 0x%08x and ExitTime 0x%08x\n",
- EntryTime, NvOsGetTimeMS());
-#endif
- return Error;
-}
-
-/**
- * Stop the write opeartion.
- */
-void NvDdkUartStopRead(NvDdkUartHandle hUart)
-{
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return;
-
- // Update the current transfer state and current transfer parameters.
- LockReadFlow(hUart);
- // If read transfer state is not busy then invalid state error.
- if (hUart->ReadReq.IsBusy)
- {
- NvOsSemaphoreSignal(hUart->ReadReq.hOnCompleteSema);
- hUart->ReadReq.IsBusy = NV_FALSE;
- hUart->ReadReq.IsStopReq = NV_TRUE;
- }
- UnlockReadFlow(hUart);
-}
-
-/**
- * Transmit the data from com channel.
- * Thread safety: Provided in the function.
- */
-NvError
-NvDdkUartWrite(
- NvDdkUartHandle hUart,
- NvU8 *pTransmitBuffer,
- NvU32 BytesRequested,
- NvU32 *pBytesWritten,
- NvU32 WaitTimeoutMs)
-{
- NvError Error = NvSuccess;
- NvU32 BytesWritten;
- NvU32 StartTime;
- NvU32 CurrentTime;
- NvU32 TimeElapsed;
- NvU32 DmaBytesRemaining;
- NvU32 TransferSize;
- NvU32 DmaTransferedCount;
- NvU32 Timeout;
- NvBool IsCtsActive;
-#if DEBUG_WRITE_TIMEOUT
- NvBool IsCtsPrevActive = NV_FALSE;
-#endif
-#if ENABLE_WRITE_PROFILE
- NvU32 EntryTime = NvOsGetTimeMS();
-#endif
-
- NV_ASSERT(hUart);
- NV_ASSERT(pTransmitBuffer);
- NV_ASSERT(pBytesWritten);
-
- // We dont support the timeout to be 0. Lets assert for debug.
- NV_ASSERT(WaitTimeoutMs);
- if (!WaitTimeoutMs)
- return NvError_BadParameter;
-
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
-#if DEBUG_WRITE_TIMEOUT
- if (hUart->IsCtsFlowEnable)
- IsCtsPrevActive = NvDdkPrivUartHwIsCtsActive(&hUart->UartHwRegs);
- if (!IsCtsPrevActive)
- NvOsDebugPrintf("The CTS is inactive %d\n", IsCtsPrevActive);
-#endif
-
- if (!hUart->IsFreqBoosted)
- NvOsSemaphoreSignal(hUart->hUartPowerMgrSema);
-
- LockWriteFlow(hUart);
- // If current write transfer state is busy then return error.
- if (hUart->WriteReq.IsBusy)
- {
- UnlockWriteFlow(hUart);
- return NvError_InvalidState;
- }
- hUart->WriteReq.IsBusy = NV_TRUE;
- hUart->WriteReq.pReqBuffer = pTransmitBuffer;
- hUart->WriteReq.pCurrTransBuf = pTransmitBuffer;
- hUart->WriteReq.BytesRequested = BytesRequested;
- hUart->WriteReq.BytesTransferred = 0;
- hUart->WriteReq.BytesRemaining = BytesRequested;
- hUart->WriteReq.IsStopReq = NV_FALSE;
- hUart->IsWritePolling = NV_FALSE;
- UnlockWriteFlow(hUart);
-
- StartTime = NvOsGetTimeMS();
- // Use interrupt/dma based transfer if the number of bytes requested is more
- // than polling limit.
- if (hUart->WriteReq.BytesRemaining > hUart->MaxTxBytesPolling)
- {
- if (hUart->IsDmaSupport)
- {
- // Apb dma based transfer
- hUart->WriteReq.hOnCompleteSema = hUart->hTxSynchSema;
-
- // Reset the semaphore if it is already signalled.
- ResetSemaphoreCount(hUart->WriteReq.hOnCompleteSema);
-
- // APB dma accept multiple of 4 bytes only so transfer the data using the apb dma
- // to nearest of 4 in lower side.
- DmaBytesRemaining = ((hUart->WriteReq.BytesRequested >> 2) << 2);
- while (DmaBytesRemaining)
- {
- TransferSize = NV_MIN(hUart->TxDmaBufferSize, DmaBytesRemaining);
- NvOsMemcpy(hUart->pTxDmaBuffer, hUart->WriteReq.pCurrTransBuf, TransferSize);
- hUart->WDmaReq.TransferSize = TransferSize;
- Error = NvRmDmaStartDmaTransfer(hUart->hTxRmDma, &hUart->WDmaReq,
- NvRmDmaDirection_Forward, 0, hUart->WriteReq.hOnCompleteSema);
- if (Error)
- break;
-
- Error = NvOsSemaphoreWaitTimeout(hUart->WriteReq.hOnCompleteSema, WaitTimeoutMs);
- // The semaphore can be signalled by stopping the transfer or transfer
- // complets.
- if ((hUart->WriteReq.IsStopReq) || (Error == NvError_Timeout))
- {
- Error = NvRmDmaGetTransferredCount(hUart->hTxRmDma, &DmaTransferedCount, NV_TRUE);
-
- // Aborting the dma request if the dma current transaction incomplete
- NvRmDmaAbort(hUart->hTxRmDma);
- if (Error)
- {
- DmaTransferedCount = 0;
- }
- else
- {
- hUart->WriteReq.BytesTransferred += DmaTransferedCount;
- hUart->WriteReq.pCurrTransBuf += DmaTransferedCount;
- DmaBytesRemaining -= DmaTransferedCount;
- // If transfer is not completed the return timeout error
- if (!Error)
- Error = (DmaBytesRemaining)? NvError_Timeout: NvSuccess;
- }
- break;
- }
- hUart->WriteReq.BytesTransferred += TransferSize;
- hUart->WriteReq.pCurrTransBuf += TransferSize;
- DmaBytesRemaining -= TransferSize;
- }
-
- hUart->WriteReq.BytesRemaining = hUart->WriteReq.BytesRequested -
- hUart->WriteReq.BytesTransferred;
- }
- else
- {
- // Interrupt based transfer.
- hUart->WriteReq.hOnCompleteSema = hUart->hTxSynchSema;
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetFifoTriggerLevel(&hUart->UartHwRegs, UartDataDirection_Transmit, 8);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_TRUE);
- UnlockRegisterAccess(hUart);
- Error = NvOsSemaphoreWaitTimeout(hUart->WriteReq.hOnCompleteSema, WaitTimeoutMs);
- if ((hUart->WriteReq.IsStopReq) || (Error == NvError_Timeout))
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_FALSE);
- UnlockRegisterAccess(hUart);
- }
- }
- }
-
- if ((!Error) && (hUart->WriteReq.BytesRemaining) && (!hUart->WriteReq.IsStopReq))
- {
- hUart->IsWritePolling = NV_TRUE;
-
- // Do by polling
- while (hUart->WriteReq.BytesRemaining)
- {
- BytesWritten = NvDdkPrivUartHwPollingWriteInTransmitFifo(&hUart->UartHwRegs,
- hUart->WriteReq.pCurrTransBuf, hUart->WriteReq.BytesRemaining);
- if (BytesWritten)
- {
- hUart->WriteReq.pCurrTransBuf += BytesWritten;
- hUart->WriteReq.BytesRemaining -= BytesWritten;
- hUart->WriteReq.BytesTransferred += BytesWritten;
- continue;
- }
- // Calculate the timeouts.
- if (WaitTimeoutMs == NV_WAIT_INFINITE)
- Timeout = NV_WAIT_INFINITE;
- else
- {
- CurrentTime = NvOsGetTimeMS();
- TimeElapsed = (CurrentTime >= StartTime)? (CurrentTime - StartTime):
- 0xFFFFFFFF-StartTime + CurrentTime;
- if (WaitTimeoutMs <= TimeElapsed)
- break;
- Timeout = (WaitTimeoutMs - TimeElapsed);
- }
-
- // CTS Hw flow disable: As CTS hw flow is disable we will get the
- // fifo empty after transmitting the bytes as there is no stop
- // for transmit data
- // CTS Hw flow enable: If CTS hw flow is enable and If CTS line
- // is inactive then we dont know how much time it will take to
- // get the fifo empty and in this case better to wait for semaphore
- // with the trigger level interrupt.
- if (hUart->IsCtsFlowEnable)
- {
- IsCtsActive = NvDdkPrivUartHwIsCtsActive(&hUart->UartHwRegs);
- if (!IsCtsActive)
- {
- // Wait for fifo get empty
- hUart->WriteReq.hOnCompleteSema = hUart->hTxSynchSema;
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetFifoTriggerLevel(&hUart->UartHwRegs, UartDataDirection_Transmit, 4);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_TRUE);
- UnlockRegisterAccess(hUart);
- Error = NvOsSemaphoreWaitTimeout(hUart->WriteReq.hOnCompleteSema, Timeout);
- if ((hUart->WriteReq.IsStopReq) || (Error == NvError_Timeout))
- {
- LockRegisterAccess(hUart);
- NvDdkPrivUartHwSetTransmitInterrupt(&hUart->UartHwRegs, NV_FALSE);
- UnlockRegisterAccess(hUart);
- break;
- }
- continue;
- }
- }
-
- // Wait for the 4 character time in efficient way.
- // If more than 500 microsecond then wait with the NvOsSleep
- if (hUart->Char4TimeUs > 500)
- NvOsSleepMS((hUart->Char4TimeUs + 999)/1000);
- else
- NvOsWaitUS(hUart->Char4TimeUs);
- }
- }
-
- DEBUG_PRINT_TX_ERR((Error == NvError_Timeout),
- ("NvDdkUartWrite(): BytesRequested 0x%08x and Timeout 0x%08x \n",
- BytesRequested, WaitTimeoutMs));
- DEBUG_PRINT_TX_ERR(((Error == NvError_Timeout) &&(hUart->IsCtsFlowEnable)),
- ("NvDdkUartWrite(): CTS State starting %d and end %d",IsCtsPrevActive, NvDdkPrivUartHwIsCtsActive(&hUart->UartHwRegs)));
-
- // If the write is stopped the reset the Tx fifo.
- // Fixme!! Do we really need to reset the fifo?
- if (hUart->WriteReq.IsStopReq)
- NvDdkPrivUartHwResetFifo(&hUart->UartHwRegs, UartDataDirection_Transmit);
-
- *pBytesWritten = hUart->WriteReq.BytesTransferred;
- hUart->WriteReq.IsBusy = NV_FALSE;
-
-#if ENABLE_WRITE_PROFILE
- if (!Error)
- NvOsDebugPrintf("NvDdkUartWrite(): EntryTime 0x%08x and ExitTime 0x%08x\n",
- EntryTime, NvOsGetTimeMS());
-#endif
- return Error;
-}
-
-/**
- * Stop the write opeartion.
- */
-void NvDdkUartStopWrite(NvDdkUartHandle hUart)
-{
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return;
-
- LockWriteFlow(hUart);
- UartStopWrite(hUart, NV_TRUE);
- UnlockWriteFlow(hUart);
-}
-
-void
-NvDdkUartGetTransferStatus(
- NvDdkUartHandle hUart,
- NvU32 *pTxBytesToRemain,
- NvError *pTxStatus,
- NvU32 *pRxBytesAvailable,
- NvError *pRxStatus)
-{
- NvU32 TxCount = 0;
- NvError TxStatus = NvSuccess;
- NvU32 RxBytesAvailable;
- NvError RxStatus = NvSuccess;
-
- NvError Err = NvSuccess;
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return;
-
- if (hUart->WriteReq.IsBusy)
- {
- if ((hUart->WriteReq.BytesRequested > hUart->MaxTxBytesPolling) &&
- (hUart->IsDmaSupport))
- {
- Err = NvRmDmaGetTransferredCount(hUart->hTxRmDma,&TxCount, NV_FALSE);
- if (!Err)
- TxCount += hUart->WriteReq.BytesTransferred;
- else
- TxCount = hUart->WriteReq.BytesTransferred;
- }
- else
- TxCount = hUart->WriteReq.BytesTransferred;
- TxStatus = hUart->WriteReq.TransferStatus;
- }
-
- RxBytesAvailable = hUart->LocalRxBuff.DataAvailable;
- RxStatus = hUart->ReadReq.TransferStatus;
-
- *pTxBytesToRemain = TxCount;
- *pTxStatus = TxStatus;
- *pRxBytesAvailable = RxBytesAvailable;
- *pRxStatus = RxStatus;
-}
-
-/**
- * Start/Stop sending the break signal.
- */
-NvError NvDdkUartSetBreakSignal(NvDdkUartHandle hUart, NvBool IsStart)
-{
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- // Start sending the break signal.
- LockRegisterAccess(hUart);
- if (IsStart)
- NvDdkPrivUartHwSetBreakControlSignal(&hUart->UartHwRegs, NV_TRUE);
- else
- NvDdkPrivUartHwSetBreakControlSignal(&hUart->UartHwRegs, NV_FALSE);
- UnlockRegisterAccess(hUart);
- return NvSuccess;
-}
-
-/**
- * Set the flow control signal level.
- */
-NvError
-NvDdkUartSetFlowControlSignal(
- NvDdkUartHandle hUart,
- NvDdkUartSignalName SignalName,
- NvDdkUartFlowControl FlowControl)
-{
- NvError Error = NvSuccess;
- NvU32 IsHigh;
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- LockRegisterAccess(hUart);
- if (FlowControl == NvDdkUartFlowControl_Handshake)
- {
- // For RTS/CTS handshake flow control, the number of line should be 4
- // or more.
- if (hUart->NumberOfInterfaceLine < 4)
- {
- Error = NvError_NotSupported;
- goto Exit;
- }
-
- if (SignalName & NvDdkUartSignalName_Rts)
- hUart->IsRtsFlowEnable = NV_TRUE;
-
- if (SignalName & NvDdkUartSignalName_Cts)
- {
- NvDdkPrivUartHwSetHWFlowControl(&hUart->UartHwRegs, NV_TRUE);
- hUart->IsCtsFlowEnable = NV_TRUE;
- }
- Error = NvSuccess;
- goto Exit;
- }
-
- IsHigh = (FlowControl == NvDdkUartFlowControl_Enable)? NV_TRUE: NV_FALSE;
- if (SignalName & NvDdkUartSignalName_Rts)
- hUart->IsRtsFlowEnable = NV_FALSE;
-
- if (SignalName & NvDdkUartSignalName_Cts)
- {
- if (FlowControl == NvDdkUartFlowControl_Enable)
- {
- NvDdkPrivUartHwSetHWFlowControl(&hUart->UartHwRegs, NV_TRUE);
- hUart->IsCtsFlowEnable = NV_TRUE;
- }
- else
- {
- NvDdkPrivUartHwSetHWFlowControl(&hUart->UartHwRegs, NV_FALSE);
- hUart->IsCtsFlowEnable = NV_FALSE;
- }
- }
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, SignalName, IsHigh);
-
-Exit:
- UnlockRegisterAccess(hUart);
- return Error;
-}
-
-/**
- * Get the input modem signal level status.
- */
-NvError
-NvDdkUartGetFlowControlSignalLevel(
- NvDdkUartHandle hUart,
- NvDdkUartSignalName SignalName,
- NvU32 *pSignalState)
-
-{
- NvError Error = NvSuccess;
- NvU32 SignalState = 0;
-
- NV_ASSERT(hUart);
- NV_ASSERT(pSignalState);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- LockRegisterAccess(hUart);
- SignalState = (hUart->UartHwRegs.ModemSignalSatus & SignalName);
- UnlockRegisterAccess(hUart);
- *pSignalState = SignalState;
- return Error;
-}
-
-/**
- * Set semaphore for the modem signal status change. Any signal change in modem
- * line will signal this semaphore.
- */
-NvError
-NvDdkUartRegisterModemSignalChange(
- NvDdkUartHandle hUart,
- NvDdkUartSignalName SignalName,
- NvDdkUartSignalChangeCallback Callback,
- void *args)
-{
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return NvError_InvalidState;
-
- LockRegisterAccess(hUart);
- // Update the semaphore for the modem signal status change.
- if (Callback != NULL)
- {
- hUart->hModemSigChngCallback = Callback;
- hUart->ModemSignalName = SignalName;
- hUart->ModemSigChngHandlerArgs = args;
- // Enable the modem control interrupt only when the number of line are
- // 8 i.e. full modem interface is available.
- if (hUart->NumberOfInterfaceLine == 8)
- NvDdkPrivUartHwSetModemControlInterrupt(&hUart->UartHwRegs, NV_TRUE);
- }
- else
- {
- hUart->hModemSigChngCallback = NULL;
- hUart->ModemSignalName = 0;
- hUart->ModemSigChngHandlerArgs = NULL;
- NvDdkPrivUartHwSetModemControlInterrupt(&hUart->UartHwRegs, NV_FALSE);
- }
- UnlockRegisterAccess(hUart);
- return NvSuccess;
-}
-
-NvError NvDdkUartSuspend(NvDdkUartHandle hUart)
-{
- NvError Error;
- NvRmPowerState PowerState;
- NvRmModuleID ModuleId;
- NvU32 TimeCount = 50; // 100 ms waiting
-
- NV_ASSERT(hUart);
- if (hUart->IsSuspendedState)
- return NvSuccess;
-
- ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, hUart->InstanceId);
-
- // First Declared as suspended state.
- hUart->IsSuspendedState = NV_TRUE;
-
- // Abort write if it is going
- LockWriteFlow(hUart);
- UartStopWrite(hUart, NV_FALSE);
- UnlockWriteFlow(hUart);
-
- // Wait for the write busy to come to non-busy, maximum 50 ms.
- while((hUart->WriteReq.IsBusy) && TimeCount)
- {
- NvOsSleepMS(2);
- TimeCount--;
- }
- // Still write busy then something wrong, so dont enter into suspend state.
- if (hUart->WriteReq.IsBusy)
- {
- hUart->IsSuspendedState = NV_FALSE;
- return NvError_InvalidState;
- }
-
- // Wait for the Tx fifo to be empty.
- WaitTillTxFifoEmpty(hUart);
-
- // Now abort the read flow
- LockReadFlow(hUart);
- LockRegisterAccess(hUart);
-
- hUart->OldRtsState = hUart->UartHwRegs.IsRtsActive;
- hUart->OldDtrState = hUart->UartHwRegs.IsDtrActive;
- if (hUart->UartHwRegs.IsRtsActive)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, NvDdkUartSignalName_Rts, NV_FALSE);
-
- if (hUart->UartHwRegs.IsDtrActive)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, NvDdkUartSignalName_Dtr, NV_FALSE);
-
- // Abort the dma if it is started.
- if ((hUart->IsDmaReadStarted) && (hUart->IsRxApbDmaBased))
- NvRmDmaAbort(hUart->hRxRmDma);
-
- hUart->IsRxApbDmaBased = NV_FALSE;
- hUart->IsDmaReadStarted = NV_FALSE;
- hUart->LastReadIndex = 0;
-
- // Reset the uart controller to clear all status and interrupt request
- // if there is any. This is require because after clock disabling, if we
- // enter into the ISR, we may not be able to clear that.
- NvRmModuleReset(hUart->hRmDevice, ModuleId);
-
- // Disable the clock
- Error = NvRmPowerModuleClockControl(hUart->hRmDevice, ModuleId,
- hUart->RmPowerClientId, NV_FALSE);
-
- // Bring down the freq requirements.
- NvOsSemaphoreSignal(hUart->hUartPowerMgrSema);
-
- // Disable power
- if (!Error)
- Error = NvRmPowerVoltageControl(hUart->hRmDevice, ModuleId,
- hUart->RmPowerClientId, NvRmVoltsOff, NvRmVoltsOff,
- NULL, 0, NULL);
-
- // Tri-State the pin-mux pins
- NV_ASSERT_SUCCESS(NvRmSetModuleTristate(hUart->hRmDevice, ModuleId, NV_TRUE));
-
- // Check whether the power state is idle
- if (!Error)
- {
- Error = NvRmPowerGetState(hUart->hRmDevice, &PowerState);
- // if (!Error)
- // NV_ASSERT(PowerState != NvRmPowerState_Active);
- }
- UnlockRegisterAccess(hUart);
- UnlockReadFlow(hUart);
- return Error;
-}
-
-NvError NvDdkUartResume(NvDdkUartHandle hUart)
-{
- NvError Error;
- NvRmPowerState PowerState;
- NvRmModuleID ModuleId;
-
- NV_ASSERT(hUart);
- if (!hUart->IsSuspendedState)
- return NvSuccess;
-
- ModuleId = NVRM_MODULE_ID(NvRmModuleID_Uart, hUart->InstanceId);
-
- LockReadFlow(hUart);
- LockRegisterAccess(hUart);
-
- // Reenable the pin nmux
- Error = NvRmSetModuleTristate(hUart->hRmDevice, ModuleId, NV_FALSE);
-
- // Enable power for uart module
- if (!Error)
- Error = NvRmPowerVoltageControl(hUart->hRmDevice, ModuleId,
- hUart->RmPowerClientId,
- NvRmVoltsUnspecified, NvRmVoltsUnspecified,
- NULL, 0, NULL);
-
- // Enable the clock.
- if (!Error)
- Error = NvRmPowerModuleClockControl(hUart->hRmDevice, ModuleId,
- hUart->RmPowerClientId, NV_TRUE);
-
- // Reset the module.
- if (!Error)
- NvRmModuleReset(hUart->hRmDevice, ModuleId);
-
- // Check whether the power state is active
- if (!Error)
- {
- Error = NvRmPowerGetState(hUart->hRmDevice, &PowerState);
- if (!Error)
- NV_ASSERT(PowerState == NvRmPowerState_Active);
- }
-
- // Restore the registers.
- if (!Error)
- {
- NvDdkPrivUartHwReconfigureRegisters(&hUart->UartHwRegs);
-
- // Restart the apb dma.
- if (hUart->IsDmaSupport)
- {
- hUart->RDmaReq.TransferSize = hUart->RxDmaBufferSize;
- Error = NvRmDmaStartDmaTransfer(hUart->hRxRmDma, &hUart->RDmaReq,
- NvRmDmaDirection_Forward, 0, hUart->LocalRxBuff.hDataAvailableSema);
- if (!Error)
- {
- hUart->IsRxApbDmaBased = NV_TRUE;
- hUart->IsDmaReadStarted = NV_TRUE;
- hUart->LastReadIndex = 0;
- }
- Error = NvSuccess;
- }
-
- // Enable the receive interrupt.
- NvDdkPrivUartHwSetReceiveInterrupt(&hUart->UartHwRegs, NV_TRUE, hUart->IsRxApbDmaBased);
- if (hUart->OldRtsState)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, NvDdkUartSignalName_Rts, NV_TRUE);
- if (hUart->OldDtrState)
- NvDdkPrivUartHwSetModemSignal(&hUart->UartHwRegs, NvDdkUartSignalName_Dtr, NV_TRUE);
- }
-
- hUart->IsSuspendedState = NV_FALSE;
- NvOsSemaphoreSignal(hUart->hUartPowerMgrSema);
-
- UnlockRegisterAccess(hUart);
- UnlockReadFlow(hUart);
- return Error;
-}