diff --git a/common/driver/gpu_async.c b/common/driver/gpu_async.c index aa45862..ef50074 100755 --- a/common/driver/gpu_async.c +++ b/common/driver/gpu_async.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ void Gpu_Init(struct DmaDevice *dev, uint32_t offset) { gpuData->base = dev->base + offset; gpuData->writeBuffers.count = 0; gpuData->readBuffers.count = 0; + gpuData->offset = offset; } /** @@ -186,13 +188,13 @@ int32_t Gpu_AddNvidia(struct DmaDevice *dev, uint64_t arg) { x = 0; if (data->writeBuffers.count > 0) { - x |= 0x00000100; - x |= (data->writeBuffers.count-1); + x |= 0x00000100; // Set write-enable bit + x |= (data->writeBuffers.count-1); // Set the 0-based write buffer count } if (data->readBuffers.count > 0) { - x |= 0x01000000; - x |= (data->readBuffers.count-1) << 16; + x |= 0x01000000; // Set read-enable bit + x |= (data->readBuffers.count-1) << 16; // Set the 0-based read buffer count } writel(x, data->base+0x008); @@ -299,3 +301,45 @@ int32_t Gpu_SetWriteEn(struct DmaDevice *dev, uint64_t arg) { return 0; } +/** + * Gpu_Show - Show information about DataGpu internal state + * @s: Sequence file pointer to write to + * @dev: Device to read from + */ +void Gpu_Show(struct seq_file *s, struct DmaDevice *dev) { + int i; + struct GpuData* data = (struct GpuData*)dev->utilData; + + const u32 readBuffCnt = readGpuAsyncReg(data->base, &GpuAsyncReg_ReadCount)+1; + const u32 writeBuffCnt = readGpuAsyncReg(data->base, &GpuAsyncReg_WriteCount)+1; + const u32 writeEnable = readGpuAsyncReg(data->base, &GpuAsyncReg_WriteEnable); + const u32 readEnable = readGpuAsyncReg(data->base, &GpuAsyncReg_ReadEnable); + + seq_printf(s, "\n---------------- DataGPU State ----------------\n"); + seq_printf(s, " GpuAsyncCore Offset : 0x%X\n", data->offset); + seq_printf(s, " Max Buffers : %d\n", readGpuAsyncReg(data->base, &GpuAsyncReg_MaxBuffers)); + seq_printf(s, " Write Buffer Count : %d\n", writeBuffCnt); + seq_printf(s, " Write Enable : %d\n", writeEnable); + seq_printf(s, " Read Buffer Count : %d\n", readBuffCnt); + seq_printf(s, " Read Enable : %d\n", readEnable); + seq_printf(s, " RX Frame Count : %d\n", readGpuAsyncReg(data->base, &GpuAsyncReg_RxFrameCnt)); + seq_printf(s, " TX Frame Count : %d\n", readGpuAsyncReg(data->base, &GpuAsyncReg_TxFrameCnt)); + seq_printf(s, " AXI Write Error Count : %d\n", readGpuAsyncReg(data->base, &GpuAsyncReg_AxiWriteErrorCnt)); + seq_printf(s, " AXI Read Error Count : %d\n", readGpuAsyncReg(data->base, &GpuAsyncReg_AxiReadErrorCnt)); + + for (i = 0; i < writeBuffCnt && writeEnable; ++i) { + u32 wal = readl(data->base + GPU_ASYNC_REG_WRITE_ADDR_L_OFFSET(i)); + u32 wah = readl(data->base + GPU_ASYNC_REG_WRITE_ADDR_H_OFFSET(i)); + seq_printf(s, "\n-------- Write Buffer %d --------\n", i); + seq_printf(s, " Write Address : 0x%llX\n", ((u64)wah << 32) | wal); + seq_printf(s, " Write Size : 0x%X\n", readl(data->base + GPU_ASYNC_REG_WRITE_SIZE_OFFSET(i))); + } + + for (i = 0; i < readBuffCnt && readEnable; ++i) { + u32 ral = readl(data->base + GPU_ASYNC_REG_READ_ADDR_L_OFFSET(i)); + u32 rah = readl(data->base + GPU_ASYNC_REG_READ_ADDR_H_OFFSET(i)); + seq_printf(s, "\n-------- Read Buffer %d --------\n", i); + seq_printf(s, " Read Address : 0x%llX\n", ((u64)rah << 32) | ral); + seq_printf(s, " Read Size : 0x%X\n", readl(data->base + GPU_ASYNC_REG_REMOTE_READ_SIZE_OFFSET(i))); + } +} diff --git a/common/driver/gpu_async.h b/common/driver/gpu_async.h index 027ad30..f070fbd 100755 --- a/common/driver/gpu_async.h +++ b/common/driver/gpu_async.h @@ -92,6 +92,7 @@ struct GpuBuffers { */ struct GpuData { uint8_t * base; + uint32_t offset; struct GpuBuffers writeBuffers; struct GpuBuffers readBuffers; }; @@ -103,5 +104,7 @@ int32_t Gpu_AddNvidia(struct DmaDevice *dev, uint64_t arg); int32_t Gpu_RemNvidia(struct DmaDevice *dev, uint64_t arg); void Gpu_FreeNvidia(void * data); int32_t Gpu_SetWriteEn(struct DmaDevice *dev, uint64_t arg); +void Gpu_Show(struct seq_file *s, struct DmaDevice *dev); + #endif // __GPU_ASYNC_2_H__ diff --git a/data_gpu/driver/src/GpuAsyncRegs.h b/data_gpu/driver/src/GpuAsyncRegs.h new file mode 120000 index 0000000..9c142ca --- /dev/null +++ b/data_gpu/driver/src/GpuAsyncRegs.h @@ -0,0 +1 @@ +../../../include/GpuAsyncRegs.h \ No newline at end of file diff --git a/data_gpu/driver/src/data_gpu_top.c b/data_gpu/driver/src/data_gpu_top.c index 9114d5f..8aef980 100755 --- a/data_gpu/driver/src/data_gpu_top.c +++ b/data_gpu/driver/src/data_gpu_top.c @@ -32,6 +32,7 @@ #include #include #include +#include #include /* @@ -225,7 +226,7 @@ int DataGpu_Probe(struct pci_dev *pcidev, const struct pci_device_id *dev_id) { dev->rwSize = (2*USER_SIZE) - PHY_OFF; // Read/Write region size // GPU Init - Gpu_Init(dev, GPU_OFF); + Gpu_Init(dev, GPU_ASYNC_CORE_OFFSET); // Manage device reset cycle dev_info(dev->device, "Init: Setting user reset\n"); @@ -384,6 +385,9 @@ void DataGpu_SeqShow(struct seq_file *s, struct DmaDevice *dev) { /* Display additional device-specific information. */ AxisG2_SeqShow(s, dev); + + /* Display DataGPU-specific state information */ + Gpu_Show(s, dev); } /** diff --git a/data_gpu/driver/src/data_gpu_top.h b/data_gpu/driver/src/data_gpu_top.h index 68e0f58..fee5822 100755 --- a/data_gpu/driver/src/data_gpu_top.h +++ b/data_gpu/driver/src/data_gpu_top.h @@ -42,7 +42,6 @@ #define PROM_SIZE 0x00050000 #define USER_OFF 0x00800000 #define USER_SIZE 0x00800000 -#define GPU_OFF 0x00028000 /* Function prototypes */ int32_t DataGpu_Init(void); diff --git a/include/GpuAsyncRegs.h b/include/GpuAsyncRegs.h new file mode 100755 index 0000000..c16df1c --- /dev/null +++ b/include/GpuAsyncRegs.h @@ -0,0 +1,242 @@ +/** + * ---------------------------------------------------------------------------- + * Company : SLAC National Accelerator Laboratory + * ---------------------------------------------------------------------------- + * Description: + * Defines register locations and bit offsets into AxiPcieGpuAsyncCore + * ---------------------------------------------------------------------------- + * This file is part of the aes_stream_drivers package. It is subject to + * the license terms in the LICENSE.txt file found in the top-level directory + * of this distribution and at: + * https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. + * No part of the aes_stream_drivers package, including this file, may be + * copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE.txt file. + * ---------------------------------------------------------------------------- +**/ + +#ifndef __GPU_ASYNC_REGS_H__ +#define __GPU_ASYNC_REGS_H__ + +#include + +#ifdef DMA_IN_KERNEL +#include +#endif + +// Offset of AxiPcieGpuAsyncCore. Must match the value within the firmware +#define GPU_ASYNC_CORE_OFFSET 0x00028000 + +struct GpuAsyncRegister { + uint32_t offset; + uint32_t bitOffset; + uint32_t bitMask; +}; + +static inline uint32_t readGpuAsyncReg(const volatile void* baseptr, const struct GpuAsyncRegister* reg) { +#ifdef DMA_IN_KERNEL + return (readl((uint8_t*)baseptr + reg->offset) & reg->bitMask) >> reg->bitOffset; +#else + uint32_t val = reg->bitMask & *(const volatile uint32_t*)(((const volatile uint8_t*)baseptr) + reg->offset); + return val >> reg->bitOffset; +#endif +} + +static inline void writeGpuAsyncReg(volatile void* baseptr, const struct GpuAsyncRegister* reg, uint32_t value) { + volatile uint32_t* regp = (volatile uint32_t*)(volatile uint8_t*)baseptr + reg->offset; +#ifdef DMA_IN_KERNEL + writel((readl(regp) & ~reg->bitMask) | ((value << reg->bitOffset) & reg->bitMask), regp); +#else + *regp = (*regp & ~reg->bitMask) | ((value << reg->bitOffset) & reg->bitMask); +#endif +} + +#define GPU_ASYNC_DEF_REG(_name, _off, _bitOff, _bitMask) \ +static const struct GpuAsyncRegister GpuAsyncReg_ ## _name = { \ + .offset = _off, \ + .bitOffset = _bitOff, \ + .bitMask = _bitMask \ +}; + +GPU_ASYNC_DEF_REG(ArCache, 0x4, 0, 0xFF); +GPU_ASYNC_DEF_REG(AwCache, 0x4, 8, 0xFF00); +GPU_ASYNC_DEF_REG(DmaDataBytes, 0x4, 16, 0xFF0000); +GPU_ASYNC_DEF_REG(MaxBuffers, 0x4, 24, 0x1F000000); + +GPU_ASYNC_DEF_REG(WriteCount, 0x8, 0, 0xFF); +GPU_ASYNC_DEF_REG(WriteEnable, 0x8, 8, 0xFF00); +GPU_ASYNC_DEF_REG(ReadCount, 0x8, 16, 0xFF0000); +GPU_ASYNC_DEF_REG(ReadEnable, 0x8, 24, 0xFF000000); + +GPU_ASYNC_DEF_REG(RxFrameCnt, 0x10, 0, 0xFFFFFFFF); +GPU_ASYNC_DEF_REG(TxFrameCnt, 0x14, 0, 0xFFFFFFFF); +GPU_ASYNC_DEF_REG(AxiWriteErrorCnt, 0x18, 0, 0xFFFFFFFF); +GPU_ASYNC_DEF_REG(AxiReadErrorCnt, 0x1C, 0, 0xFFFFFFFF); + +GPU_ASYNC_DEF_REG(CntRst, 0x20, 0, 0xFFFFFFFF); +GPU_ASYNC_DEF_REG(AxiWriteErrorVal, 0x24, 0, 0xFFFFFFFF); +GPU_ASYNC_DEF_REG(AxiReadErrorVal, 0x28, 0, 0xFFFFFFFF); + +GPU_ASYNC_DEF_REG(DynamicRouteMasks0, 0x2C, 0, 0xFF); +GPU_ASYNC_DEF_REG(DynamicRouteDests0, 0x2C, 8, 0xFF00); +GPU_ASYNC_DEF_REG(DynamicRouteMasks1, 0x2C, 16, 0xFF0000); +GPU_ASYNC_DEF_REG(DynamicRouteDests1, 0x2C, 24, 0xFF000000); + +// The following register defintiions are firmware specific. GpuAsyncCore can have up to 16 buffers, but defaults to 4. +// You must check the MaxBuffers register for the true value + +/*********************** Write Buffers ************************/ + +#define GPU_ASYNC_REG_WRITE_BASE 256 + +#define GPU_ASYNC_REG_WRITE_ADDR_L_OFFSET(_i) (GPU_ASYNC_REG_WRITE_BASE + _i * 16 + 0) +#define GPU_ASYNC_REG_WRITE_ADDR_H_OFFSET(_i) (GPU_ASYNC_REG_WRITE_BASE + _i * 16 + 4) +#define GPU_ASYNC_REG_WRITE_SIZE_OFFSET(_i) (GPU_ASYNC_REG_WRITE_BASE + _i * 16 + 8) + +#define GPU_ASYNC_DEF_WRITE_REGISTER(_i) \ + GPU_ASYNC_DEF_REG(WriteBuffer ## _i ## _WriteAddrL, GPU_ASYNC_REG_WRITE_ADDR_L_OFFSET(_i), 0, 0xFFFFFFFF) \ + GPU_ASYNC_DEF_REG(WriteBuffer ## _i ## _WriteAddrH, GPU_ASYNC_REG_WRITE_ADDR_H_OFFSET(_i), 0, 0xFFFFFFFF) \ + GPU_ASYNC_DEF_REG(WriteBuffer ## _i ## _WriteSize, GPU_ASYNC_REG_WRITE_SIZE_OFFSET(_i), 0, 0xFFFFFFFF) + +GPU_ASYNC_DEF_WRITE_REGISTER(0) +GPU_ASYNC_DEF_WRITE_REGISTER(1) +GPU_ASYNC_DEF_WRITE_REGISTER(2) +GPU_ASYNC_DEF_WRITE_REGISTER(3) +GPU_ASYNC_DEF_WRITE_REGISTER(4) +GPU_ASYNC_DEF_WRITE_REGISTER(5) +GPU_ASYNC_DEF_WRITE_REGISTER(6) +GPU_ASYNC_DEF_WRITE_REGISTER(7) +GPU_ASYNC_DEF_WRITE_REGISTER(8) +GPU_ASYNC_DEF_WRITE_REGISTER(9) +GPU_ASYNC_DEF_WRITE_REGISTER(10) +GPU_ASYNC_DEF_WRITE_REGISTER(11) +GPU_ASYNC_DEF_WRITE_REGISTER(12) +GPU_ASYNC_DEF_WRITE_REGISTER(13) +GPU_ASYNC_DEF_WRITE_REGISTER(14) +GPU_ASYNC_DEF_WRITE_REGISTER(15) + +#undef GPU_ASYNC_DEF_WRITE_REGISTER + +/*********************** Read Buffers ************************/ + +#define GPU_ASYNC_REG_READ_BASE 512 + +#define GPU_ASYNC_REG_READ_ADDR_L_OFFSET(_i) (GPU_ASYNC_REG_READ_BASE + _i * 16 + 0) +#define GPU_ASYNC_REG_READ_ADDR_H_OFFSET(_i) (GPU_ASYNC_REG_READ_BASE + _i * 16 + 4) + +#define GPU_ASYNC_DEF_READ_REGISTER(_i) \ + GPU_ASYNC_DEF_REG(ReadBuffer ## _i ## _ReadAddrL, GPU_ASYNC_REG_READ_ADDR_L_OFFSET(_i), 0, 0xFFFFFFFF) \ + GPU_ASYNC_DEF_REG(ReadBuffer ## _i ## _ReadAddrH, GPU_ASYNC_REG_READ_ADDR_H_OFFSET(_i), 0, 0xFFFFFFFF) + +GPU_ASYNC_DEF_READ_REGISTER(0) +GPU_ASYNC_DEF_READ_REGISTER(1) +GPU_ASYNC_DEF_READ_REGISTER(2) +GPU_ASYNC_DEF_READ_REGISTER(3) +GPU_ASYNC_DEF_READ_REGISTER(4) +GPU_ASYNC_DEF_READ_REGISTER(5) +GPU_ASYNC_DEF_READ_REGISTER(6) +GPU_ASYNC_DEF_READ_REGISTER(7) +GPU_ASYNC_DEF_READ_REGISTER(8) +GPU_ASYNC_DEF_READ_REGISTER(9) +GPU_ASYNC_DEF_READ_REGISTER(10) +GPU_ASYNC_DEF_READ_REGISTER(11) +GPU_ASYNC_DEF_READ_REGISTER(12) +GPU_ASYNC_DEF_READ_REGISTER(13) +GPU_ASYNC_DEF_READ_REGISTER(14) +GPU_ASYNC_DEF_READ_REGISTER(15) + +#undef GPU_ASYNC_DEF_READ_REGISTER + +/*********************** Write Detect ************************/ + +#define GPU_ASYNC_REG_WRITE_DETECT_BASE 768 + +#define GPU_ASYNC_REG_WRITE_DETECT_OFFSET(_i) (GPU_ASYNC_REG_WRITE_DETECT_BASE + _i * 4) + +#define GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(_i) \ + GPU_ASYNC_DEF_REG(WriteBuffer ## _i ## _WriteEn, GPU_ASYNC_REG_WRITE_DETECT_OFFSET(_i), 0, 0xFFFFFFFF) + +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(0) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(1) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(2) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(3) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(4) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(5) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(6) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(7) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(8) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(9) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(10) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(11) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(12) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(13) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(14) +GPU_ASYNC_DEF_WRITE_DETECT_REGISTER(15) + +#undef GPU_ASYNC_DEF_WRITE_DETECT_REGISTER + +/*********************** Read Detect ************************/ + +#define GPU_ASYNC_REG_READ_DETECT_BASE 1024 + +#define GPU_ASYNC_REG_REMOTE_READ_SIZE_OFFSET(_i) (GPU_ASYNC_REG_READ_DETECT_BASE + _i * 4 + 0) +#define GPU_ASYNC_REG_REMOTE_READ_DETECT_OFFSET(_i) (GPU_ASYNC_REG_READ_DETECT_BASE + _i * 4 + 4) + +#define GPU_ASYNC_DEF_READ_DETECT_REGISTER(_i) \ + GPU_ASYNC_DEF_REG(ReadBuffer ## _i ## _RemoteReadSize, GPU_ASYNC_REG_REMOTE_READ_SIZE_OFFSET(_i), 0, 0xFFFFFFFF) \ + GPU_ASYNC_DEF_REG(ReadBuffer ## _i ## _RemoteReadEn, GPU_ASYNC_REG_REMOTE_READ_DETECT_OFFSET(_i), 0, 0xFFFFFFFF) + +GPU_ASYNC_DEF_READ_DETECT_REGISTER(0) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(1) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(2) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(3) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(4) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(5) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(6) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(7) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(8) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(9) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(10) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(11) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(12) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(13) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(14) +GPU_ASYNC_DEF_READ_DETECT_REGISTER(15) + +#undef GPU_ASYNC_DEF_READ_DETECT_REGISTER + +/*********************** Buffer Latencies ************************/ + +#define GPU_ASYNC_REG_LATENCY_BASE 1280 + +#define GPU_ASYNC_REG_LATENCY_TOTAL_OFFSET(_i) (GPU_ASYNC_REG_LATENCY_BASE + _i * 16 + 0) +#define GPU_ASYNC_REG_LATENCY_GPU_OFFSET(_i) (GPU_ASYNC_REG_LATENCY_BASE + _i * 16 + 4) +#define GPU_ASYNC_REG_LATENCY_WRITE_OFFSET(_i) (GPU_ASYNC_REG_LATENCY_BASE + _i * 16 + 8) + +#define GPU_ASYNC_DEF_LATENCY_REGISTER(_i) \ + GPU_ASYNC_DEF_REG(Latency ## _i ## _Total, GPU_ASYNC_REG_LATENCY_TOTAL_OFFSET(_i), 0, 0xFFFFFFFF) \ + GPU_ASYNC_DEF_REG(Latency ## _i ## _Gpu, GPU_ASYNC_REG_LATENCY_GPU_OFFSET(_i), 0, 0xFFFFFFFF) \ + GPU_ASYNC_DEF_REG(Latency ## _i ## _Write, GPU_ASYNC_REG_LATENCY_WRITE_OFFSET(_i), 0, 0xFFFFFFFF) + +GPU_ASYNC_DEF_LATENCY_REGISTER(0) +GPU_ASYNC_DEF_LATENCY_REGISTER(1) +GPU_ASYNC_DEF_LATENCY_REGISTER(2) +GPU_ASYNC_DEF_LATENCY_REGISTER(3) +GPU_ASYNC_DEF_LATENCY_REGISTER(4) +GPU_ASYNC_DEF_LATENCY_REGISTER(5) +GPU_ASYNC_DEF_LATENCY_REGISTER(6) +GPU_ASYNC_DEF_LATENCY_REGISTER(7) +GPU_ASYNC_DEF_LATENCY_REGISTER(8) +GPU_ASYNC_DEF_LATENCY_REGISTER(9) +GPU_ASYNC_DEF_LATENCY_REGISTER(10) +GPU_ASYNC_DEF_LATENCY_REGISTER(11) +GPU_ASYNC_DEF_LATENCY_REGISTER(12) +GPU_ASYNC_DEF_LATENCY_REGISTER(13) +GPU_ASYNC_DEF_LATENCY_REGISTER(14) +GPU_ASYNC_DEF_LATENCY_REGISTER(15) + +#undef GPU_ASYNC_DEF_LATENCY_REGISTER + +#undef GPU_ASYNC_DEF_REG + +#endif // __GPU_ASYNC_REGS_H__