add Qualcomm GENI SerialPortLib
This commit is contained in:
parent
95968d21ab
commit
798f7cc778
47
sdm845Pkg/Library/QcomGeniSerialPortLib/GeniSerial.h
Normal file
47
sdm845Pkg/Library/QcomGeniSerialPortLib/GeniSerial.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef UARTQUPV3_H
|
||||
#define UARTQUPV3_H
|
||||
#define UART_DEBUG_PORT_BASE 0xA84000
|
||||
#define UART_BASE_ADDR UART_DEBUG_PORT_BASE
|
||||
#define RING_SIZE 256
|
||||
#define MemWrite(off1,off2,val) (*((volatile UINT32*)(UINTN)(UART_BASE_ADDR+(off1)+(off2)))=((UINT32)(val)))
|
||||
#define MemRead(off1,off2,v) ((*((volatile UINT32*)(UINTN)(UART_BASE_ADDR+(off1)+(off2))))&(v))
|
||||
#define MemReadMask(off1,k) MemRead(off1,k##_ADDR,k##_MASK)
|
||||
#define GENI4_CFG 0x0
|
||||
#define GENI4_IMAGE_REGS 0x100
|
||||
#define GENI4_DATA 0x600
|
||||
#define QUPV3_SE_DMA 0xC00
|
||||
#define GENI4_IMAGE 0x1000
|
||||
#define GENI_STATUS_ADDR 0x00000040
|
||||
#define GENI_S_IRQ_STATUS_ADDR 0x00000040
|
||||
#define GENI_RX_FIFO_ADDR 0x00000180
|
||||
#define GENI_TX_FIFO_STATUS_ADDR 0x00000200
|
||||
#define GENI_RX_FIFO_STATUS_ADDR 0x00000204
|
||||
#define SE_HW_PARAM_0_ADDR 0x00000224
|
||||
#define GENI_STATUS_MASK 0x1fffff
|
||||
#define GENI_S_IRQ_STATUS_MASK 0xfc07f3f
|
||||
#define GENI_RX_FIFO_MASK 0xffffffff
|
||||
#define GENI_TX_FIFO_STATUS_MASK 0xffffffff
|
||||
#define GENI_RX_FIFO_STATUS_MASK 0xffffffff
|
||||
#define SE_HW_PARAM_0_MASK 0x3f3f79ff
|
||||
#define GENI_M_CMD0_ADDR 0x00000000
|
||||
#define GENI_M_IRQ_EN_SET_ADDR 0x0000001c
|
||||
#define GENI_M_IRQ_EN_CLEAR_ADDR 0x00000020
|
||||
#define GENI_S_IRQ_CLEAR_ADDR 0x00000048
|
||||
#define GENI_S_IRQ_EN_SET_ADDR 0x0000004c
|
||||
#define GENI_S_IRQ_EN_CLEAR_ADDR 0x00000050
|
||||
#define GENI_TX_FIFO_ADDR 0x00000100
|
||||
#define UART_TX_TRANS_CFG_ADDR 0x0000015c
|
||||
#define GENI_TX_PACKING_CFG0_ADDR 0x00000160
|
||||
#define GENI_TX_PACKING_CFG1_ADDR 0x00000164
|
||||
#define UART_TX_TRANS_LEN_ADDR 0x00000170
|
||||
#define TX_FIFO_WC 0xfffffff
|
||||
#define RX_FIFO_WC 0x1ffffff
|
||||
#define RX_LAST_IRQ 0x8000000
|
||||
#define TX_FIFO_DEPTH_MASK 0x3f0000
|
||||
#define TX_FIFO_DEPTH_SHIFT 0x10
|
||||
#define TX_FIFO_WATERMARK_IRQ 0x40000000
|
||||
#define RX_FIFO_WATERMARK_IRQ 0x4000000
|
||||
#define RX_LAST_VALID_BYTES_MASK 0x70000000
|
||||
#define RX_LAST_VALID_BYTES_SHIFT 0x1c
|
||||
#define M_GENI_CMD_ACTIVE 0x1
|
||||
#endif
|
111
sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.c
Normal file
111
sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.c
Normal file
@ -0,0 +1,111 @@
|
||||
#include <Base.h>
|
||||
#include <PiDxe.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/SerialPortLib.h>
|
||||
#include "GeniSerial.h"
|
||||
STATIC UINT32 ReadIndex=0,WriteIndex=0,TxFIFOSize=0;
|
||||
UINTN EFIAPI SerialPortRead(OUT UINT8*Buffer,IN UINTN Bytes){
|
||||
CHAR8*ReadBuffer;
|
||||
BOOLEAN Status;
|
||||
STATIC UINT8 RxBuffer[255];
|
||||
UINT8*Buff=Buffer;
|
||||
UINT32 Room=Bytes,Copied=0,Avail=0,Num,WriteOffset,BytesRead,WordsRead,Index,FIFOStatus,Word,IRQStatus,AvailBytes;
|
||||
while(1){
|
||||
if(ReadIndex==WriteIndex)ReadIndex=WriteIndex=0;
|
||||
if(sizeof(RxBuffer)-WriteIndex>4){
|
||||
ReadBuffer=(CHAR8*)(RxBuffer+WriteIndex);
|
||||
WriteOffset=0,BytesRead=0,WordsRead=0;
|
||||
MemWrite(GENI4_DATA,GENI_S_IRQ_EN_SET_ADDR,RX_LAST_IRQ|RX_FIFO_WATERMARK_IRQ);
|
||||
IRQStatus=MemReadMask(GENI4_DATA,GENI_S_IRQ_STATUS);
|
||||
FIFOStatus=MemReadMask(GENI4_DATA,GENI_RX_FIFO_STATUS);
|
||||
if(IRQStatus&(RX_LAST_IRQ|RX_FIFO_WATERMARK_IRQ)){
|
||||
BytesRead=(FIFOStatus&RX_LAST_VALID_BYTES_MASK)>>RX_LAST_VALID_BYTES_SHIFT;
|
||||
WordsRead=FIFOStatus&RX_FIFO_WC;
|
||||
if(BytesRead!=0&&BytesRead!=4)WordsRead-=1;
|
||||
else BytesRead=0;
|
||||
}
|
||||
AvailBytes=WordsRead*4+BytesRead;
|
||||
if(WriteOffset+AvailBytes>sizeof(RxBuffer)-WriteIndex){
|
||||
if(sizeof(RxBuffer)-WriteIndex-WriteOffset<4){
|
||||
MemWrite(GENI4_DATA,GENI_S_IRQ_CLEAR_ADDR,IRQStatus);
|
||||
MemWrite(GENI4_DATA,GENI_S_IRQ_EN_CLEAR_ADDR,RX_LAST_IRQ|RX_FIFO_WATERMARK_IRQ);
|
||||
goto ok;
|
||||
}else{
|
||||
WordsRead=((sizeof(RxBuffer)-WriteIndex-WriteOffset)&0x3)>>2;
|
||||
BytesRead=0,AvailBytes=WordsRead*4;
|
||||
}
|
||||
}else MemWrite(GENI4_DATA,GENI_S_IRQ_CLEAR_ADDR,(IRQStatus&RX_LAST_IRQ));
|
||||
ReadBuffer+=WriteOffset;
|
||||
Status=(ReadBuffer-(CHAR8*)NULL)&0x03;
|
||||
for(Index=0;Index<WordsRead;Index++){
|
||||
Word=MemReadMask(GENI4_DATA,GENI_RX_FIFO);
|
||||
if(Status){
|
||||
ReadBuffer[0]=(UINT8)(Word>>0),ReadBuffer[1]=(UINT8)(Word>>8);
|
||||
ReadBuffer[2]=(UINT8)(Word>>16),ReadBuffer[3]=(UINT8)(Word>>24);
|
||||
}else *(UINT32*)ReadBuffer=Word;
|
||||
ReadBuffer+=4;
|
||||
}
|
||||
if(BytesRead){
|
||||
Word=MemReadMask(GENI4_DATA,GENI_RX_FIFO);
|
||||
for(Index=0;Index<BytesRead;Index++)ReadBuffer[Index]=(UINT8)(Word>>Index*8);
|
||||
}
|
||||
WriteOffset+=AvailBytes;
|
||||
MemWrite(GENI4_DATA,GENI_S_IRQ_CLEAR_ADDR,(IRQStatus&RX_FIFO_WATERMARK_IRQ));
|
||||
ok:WriteIndex+=WriteOffset;
|
||||
}
|
||||
Avail=ReadIndex<WriteIndex?WriteIndex-ReadIndex:0;
|
||||
Num=Room<Avail?Room:Avail;
|
||||
if(Num==0)break;
|
||||
for(Index=0;Index<Num;Index++)*Buff++=RxBuffer[ReadIndex++&(sizeof(RxBuffer)-1)];
|
||||
Copied+=Num,Room-=Num;
|
||||
}
|
||||
return Copied;
|
||||
}
|
||||
UINTN EFIAPI SerialPortWrite(IN UINT8*Buffer,IN UINTN Bytes){
|
||||
UINT8*MsgBuff=Buffer;
|
||||
UINT32 Slots,FIFOSize,WordValue,Index,WordsSend,BytesSend,Full,Partial;
|
||||
UINTN BytesRemain=Bytes,Send;
|
||||
FIFOSize=(MemReadMask(QUPV3_SE_DMA,SE_HW_PARAM_0)&TX_FIFO_DEPTH_MASK)>>TX_FIFO_DEPTH_SHIFT;
|
||||
if(TxFIFOSize==0)TxFIFOSize=FIFOSize<<2;
|
||||
while(BytesRemain>0){
|
||||
Send=(BytesRemain>TxFIFOSize)?TxFIFOSize:BytesRemain;
|
||||
if(MemReadMask(GENI4_CFG,GENI_STATUS)&M_GENI_CMD_ACTIVE)continue;
|
||||
MemWrite(GENI4_IMAGE_REGS,UART_TX_TRANS_LEN_ADDR,Send);
|
||||
MemWrite(GENI4_DATA,GENI_M_CMD0_ADDR,0x08000000);
|
||||
if(Send){
|
||||
Full=Send>>2,Partial=Send&0x03;
|
||||
Slots=FIFOSize-(MemReadMask(GENI4_DATA,GENI_TX_FIFO_STATUS)&TX_FIFO_WC);
|
||||
WordsSend=Full>Slots?Slots:Full,BytesSend=Full>=Slots?0:Partial;
|
||||
BOOLEAN k=((CHAR8*)Buffer-(CHAR8*)NULL)&0x03;
|
||||
for(Index=0;Index<WordsSend;Index++){
|
||||
MemWrite(
|
||||
GENI4_DATA,GENI_TX_FIFO_ADDR,(k?(
|
||||
Buffer[0]<<0|Buffer[1]<<8|
|
||||
Buffer[2]<<16|Buffer[3]<<24
|
||||
):(*(UINT32*)Buffer))
|
||||
);
|
||||
Buffer+=4;
|
||||
}
|
||||
if(BytesSend){
|
||||
WordValue=0;
|
||||
for(Index=0;Index<BytesSend;Index++)WordValue|=Buffer[Index]<<Index*8;
|
||||
MemWrite(GENI4_DATA,GENI_TX_FIFO_ADDR,WordValue);
|
||||
}
|
||||
MemWrite(
|
||||
GENI4_DATA,
|
||||
(Send==WordsSend*4+BytesSend)?
|
||||
GENI_M_IRQ_EN_CLEAR_ADDR:GENI_M_IRQ_EN_SET_ADDR,
|
||||
TX_FIFO_WATERMARK_IRQ
|
||||
);
|
||||
}
|
||||
MsgBuff+=Send,BytesRemain-=Send;
|
||||
}
|
||||
return Bytes;
|
||||
}
|
||||
UINTN EFIAPI SerialPortControl(IN UINTN Arg,IN UINTN Param){return 0;}
|
||||
BOOLEAN EFIAPI SerialPortPoll(VOID){return (MemReadMask(GENI4_DATA,GENI_S_IRQ_STATUS)&(RX_LAST_IRQ|RX_FIFO_WATERMARK_IRQ))||(WriteIndex-ReadIndex>0);}
|
||||
EFI_STATUS EFIAPI SerialPortSetAttributes(IN OUT UINT64*BaudRate,IN OUT UINT32*ReceiveFifoDepth,IN OUT UINT32*Timeout,IN OUT EFI_PARITY_TYPE*Parity,IN OUT UINT8*DataBits,IN OUT EFI_STOP_BITS_TYPE *StopBits){return EFI_UNSUPPORTED;}
|
||||
EFI_STATUS EFIAPI SerialPortGetControl(OUT UINT32*Control){return EFI_UNSUPPORTED;}
|
||||
EFI_STATUS EFIAPI SerialPortSetControl(IN UINT32 Control){return EFI_UNSUPPORTED;}
|
||||
EFI_STATUS EFIAPI SerialPortInitialize(VOID){return EFI_SUCCESS;}
|
@ -0,0 +1,13 @@
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = QcomGeniSerialPortLib
|
||||
MODULE_TYPE = BASE
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = SerialPortLib
|
||||
|
||||
[Sources]
|
||||
GeniSerial.h
|
||||
QcomGeniSerialPortLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
@ -34,7 +34,7 @@
|
||||
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
|
||||
|
||||
!if $(TARGET) != RELEASE
|
||||
SerialPortLib|sdm845Pkg/Library/InMemorySerialPortLib/InMemorySerialPortLib.inf
|
||||
SerialPortLib|sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.inf
|
||||
!else
|
||||
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
|
||||
!endif
|
||||
@ -78,10 +78,6 @@
|
||||
# SimpleFbDxe
|
||||
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
|
||||
|
||||
!if $(TARGET) != RELEASE
|
||||
SerialPortLib|sdm845Pkg/Library/FrameBufferSerialPortLib/FrameBufferSerialPortLib.inf
|
||||
!endif
|
||||
|
||||
PlatformBootManagerLib|sdm845Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
||||
MemoryInitPeiLib|sdm845Pkg/Library/MemoryInitPeiLib/PeiMemoryAllocationLib.inf
|
||||
PlatformPeiLib|sdm845Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
||||
|
Loading…
Reference in New Issue
Block a user