From: BigfootACA Date: 星期六, 5 Feb 2022 12:19:32 +0000 (+0800) Subject: add Qualcomm GENI SerialPortLib X-Git-Tag: v2.0rc1~27 X-Git-Url: https://git.renegade-project.org/?a=commitdiff_plain;h=798f7cc77843948692f5336cbbb65d062a5ac795;p=edk2-sdm845.git add Qualcomm GENI SerialPortLib --- diff --git a/sdm845Pkg/Library/QcomGeniSerialPortLib/GeniSerial.h b/sdm845Pkg/Library/QcomGeniSerialPortLib/GeniSerial.h new file mode 100644 index 0000000..f92035a --- /dev/null +++ b/sdm845Pkg/Library/QcomGeniSerialPortLib/GeniSerial.h @@ -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 diff --git a/sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.c b/sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.c new file mode 100644 index 0000000..9ac2fc4 --- /dev/null +++ b/sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#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>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>Index*8); + } + WriteOffset+=AvailBytes; + MemWrite(GENI4_DATA,GENI_S_IRQ_CLEAR_ADDR,(IRQStatus&RX_FIFO_WATERMARK_IRQ)); + ok:WriteIndex+=WriteOffset; + } + Avail=ReadIndex>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;Index0);} +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;} diff --git a/sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.inf b/sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.inf new file mode 100644 index 0000000..0e96c7e --- /dev/null +++ b/sdm845Pkg/Library/QcomGeniSerialPortLib/QcomGeniSerialPortLib.inf @@ -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 diff --git a/sdm845Pkg/sdm845Pkg.dsc b/sdm845Pkg/sdm845Pkg.dsc index 99eb689..dfb2316 100644 --- a/sdm845Pkg/sdm845Pkg.dsc +++ b/sdm845Pkg/sdm845Pkg.dsc @@ -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