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
|
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
|
||||||
|
|
||||||
!if $(TARGET) != RELEASE
|
!if $(TARGET) != RELEASE
|
||||||
SerialPortLib|sdm845Pkg/Library/InMemorySerialPortLib/InMemorySerialPortLib.inf
|
SerialPortLib|sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.inf
|
||||||
!else
|
!else
|
||||||
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
|
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
|
||||||
!endif
|
!endif
|
||||||
@ -78,10 +78,6 @@
|
|||||||
# SimpleFbDxe
|
# SimpleFbDxe
|
||||||
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
|
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
|
||||||
|
|
||||||
!if $(TARGET) != RELEASE
|
|
||||||
SerialPortLib|sdm845Pkg/Library/FrameBufferSerialPortLib/FrameBufferSerialPortLib.inf
|
|
||||||
!endif
|
|
||||||
|
|
||||||
PlatformBootManagerLib|sdm845Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
PlatformBootManagerLib|sdm845Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
|
||||||
MemoryInitPeiLib|sdm845Pkg/Library/MemoryInitPeiLib/PeiMemoryAllocationLib.inf
|
MemoryInitPeiLib|sdm845Pkg/Library/MemoryInitPeiLib/PeiMemoryAllocationLib.inf
|
||||||
PlatformPeiLib|sdm845Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
PlatformPeiLib|sdm845Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
||||||
|
Loading…
Reference in New Issue
Block a user