Commit 425635c0 authored by Jaco Hofmann's avatar Jaco Hofmann
Browse files

Modularize DMA detection

parent 35d0646e
Pipeline #556 passed with stage
in 8 minutes and 55 seconds
......@@ -26,10 +26,16 @@
#define REG_FPGA_ADDR 0x08 /* slv_reg1 = FPGA addr */
#define REG_BTT 0x10 /* slv_reg2 = bytes to transfer */
#define REG_CMD 0x20 /* slv_reg3 = CMD */
#define REG_ID 0x18
#define REG_READ_REQUESTS 0x48
#define REG_WRITE_REQUESTS 0x56
#define CMD_READ 0x10001000 /* from m64 fpga memory to m64 host memory */
#define CMD_WRITE 0x10000001 /* from m64 host memory to m64 fpga memory */
#define BLUE_DMA_ID 0xE5A0023
irqreturn_t blue_dma_intr_handler_read(int irq, void * dev_id)
{
struct dma_engine *dma = (struct dma_engine *)dev_id;
......@@ -46,11 +52,26 @@ irqreturn_t blue_dma_intr_handler_write(int irq, void * dev_id)
return IRQ_HANDLED;
}
int blue_dma_init(struct dma_engine *dma) {
u64 id = *(u64 *)(dma->regs + REG_ID);
if ((id & 0xFFFFFFFF) == BLUE_DMA_ID) {
DEVLOG(dma->dev_id, TLKM_LF_DMA, "detected BlueDMA");
DEVLOG(dma->dev_id, TLKM_LF_DMA, "PCIe beats per burst: %u", (uint8_t)(id >> 32));
DEVLOG(dma->dev_id, TLKM_LF_DMA, "FPGA beats per burst: %u", (uint8_t)(id >> 40));
DEVLOG(dma->dev_id, TLKM_LF_DMA, "smallest alignment: %u", (uint8_t)(id >> 48));
dma->alignment = (uint8_t)(id >> 48);
return 1;
} else {
return 0;
}
}
ssize_t blue_dma_copy_from(struct dma_engine *dma, void *dma_handle, dev_addr_t dev_addr, size_t len)
{
dma_addr_t handle = (dma_addr_t)dma_handle;
DEVLOG(dma->dev_id, TLKM_LF_DMA, "dev_addr = 0x%px, dma_handle = 0x%llx, len: %zu bytes", (void *)dev_addr, handle, len);
if(mutex_lock_interruptible(&dma->regs_mutex)) {
if (mutex_lock_interruptible(&dma->regs_mutex)) {
WRN("got killed while aquiring the mutex");
return len;
}
......@@ -68,7 +89,7 @@ ssize_t blue_dma_copy_to(struct dma_engine *dma, dev_addr_t dev_addr, const void
{
dma_addr_t handle = (dma_addr_t)dma_handle;
DEVLOG(dma->dev_id, TLKM_LF_DMA, "dev_addr = 0x%px, dma_handle = 0x%llx, len: %zu bytes", (void *)dev_addr, handle, len);
if(mutex_lock_interruptible(&dma->regs_mutex)) {
if (mutex_lock_interruptible(&dma->regs_mutex)) {
WRN("got killed while aquiring the mutex");
return len;
}
......
......@@ -23,7 +23,7 @@
#include "tlkm_dma.h"
#include "tlkm_types.h"
#define BLUE_DMA_ID 0xE5A0023
int blue_dma_init(struct dma_engine *dma);
irqreturn_t blue_dma_intr_handler_read(int irq, void * dev_id);
irqreturn_t blue_dma_intr_handler_write(int irq, void * dev_id);
ssize_t blue_dma_copy_from(struct dma_engine *dma, void *krn_addr, dev_addr_t dev_addr, size_t len);
......
......@@ -8,7 +8,6 @@
#include "blue_dma.h"
#include "pcie/pcie_device.h"
#define REG_ID 0x18
#define DMA_SZ 0x10000
typedef struct {
......@@ -18,7 +17,8 @@ typedef struct {
} chunk_data_t;
static const struct dma_operations tlkm_dma_ops[] = {
[DMA_USED_BLUE] = {
{
.init = blue_dma_init,
.intr_read = blue_dma_intr_handler_read,
.intr_write = blue_dma_intr_handler_write,
.copy_from = blue_dma_copy_from,
......@@ -28,18 +28,37 @@ static const struct dma_operations tlkm_dma_ops[] = {
.buffer_cpu = pcie_device_dma_sync_buffer_cpu,
.buffer_dev = pcie_device_dma_sync_buffer_dev,
},
{
.init = 0,
.intr_read = 0,
.intr_write = 0,
.copy_from = 0,
.copy_to = 0,
.allocate_buffer = 0,
.free_buffer = 0,
.buffer_cpu = 0,
.buffer_dev = 0,
}
};
int tlkm_dma_init(struct tlkm_device *dev, struct dma_engine *dma, u64 dbase)
{
dev_id_t dev_id = dev->dev_id;
uint64_t id;
int i = 0;
int ret = 0;
void *base = (void *)((uintptr_t)dbase);
BUG_ON(! dma);
DEVLOG(dev_id, TLKM_LF_DMA, "initializing DMA engine @ 0x%px ...", base);
init_waitqueue_head(&dma->rq);
init_waitqueue_head(&dma->wq);
mutex_init(&dma->regs_mutex);
mutex_init(&dma->rq_mutex);
mutex_init(&dma->wq_mutex);
dma->dev_id = dev_id;
dma->base = base;
dma->dev = dev;
DEVLOG(dev_id, TLKM_LF_DMA, "I/O remapping 0x%px - 0x%px...", base, base + DMA_SZ - 1);
dma->regs = ioremap_nocache((resource_size_t)base, DMA_SZ);
if (dma->regs == 0 || IS_ERR(dma->regs)) {
......@@ -49,21 +68,21 @@ int tlkm_dma_init(struct tlkm_device *dev, struct dma_engine *dma, u64 dbase)
}
DEVLOG(dev_id, TLKM_LF_DMA, "detecting DMA engine type ...");
id = *(u64 *)(dma->regs + REG_ID);
if ((id & 0xFFFFFFFF) == BLUE_DMA_ID) {
dma->dma_used = DMA_USED_BLUE;
DEVLOG(dev_id, TLKM_LF_DMA, "detected BlueDMA");
DEVLOG(dev_id, TLKM_LF_DMA, "PCIe beats per burst: %u", (uint8_t)(id >> 32));
DEVLOG(dev_id, TLKM_LF_DMA, "FPGA beats per burst: %u", (uint8_t)(id >> 40));
DEVLOG(dev_id, TLKM_LF_DMA, "smallest alignment: %u", (uint8_t)(id >> 48));
dma->alignment = (uint8_t)(id >> 48);
} else {
goto err_unknown_dma;
while (tlkm_dma_ops[i].init != 0) {
int r = tlkm_dma_ops[i].init(dma);
if (r) {
dma->ops = tlkm_dma_ops[i];
break;
}
++i;
}
if (tlkm_dma_ops[i].init == 0) {
DEVLOG(dev_id, TLKM_LF_DMA, "unknown DMA engine");
goto err_unknown_dma;
}
dma->ops = tlkm_dma_ops[dma->dma_used];
DEVLOG(dev_id, TLKM_LF_DMA, "allocating DMA buffers of %d x %zd bytes ...", TLKM_DMA_CHUNKS, TLKM_DMA_CHUNK_SZ);
DEVLOG(dev_id, TLKM_LF_DMA, "allocating DMA buffers of 2 x %d x %zd bytes ...", TLKM_DMA_CHUNKS, TLKM_DMA_CHUNK_SZ);
for (i = 0; i < TLKM_DMA_CHUNKS; ++i) {
ret = dma->ops.allocate_buffer(dev->dev_id, dev, &dma->dma_buf_read[i], &dma->dma_buf_read_dev[i], FROM_DEV, TLKM_DMA_CHUNK_SZ);
......@@ -83,18 +102,6 @@ int tlkm_dma_init(struct tlkm_device *dev, struct dma_engine *dma, u64 dbase)
}
}
init_waitqueue_head(&dma->rq);
init_waitqueue_head(&dma->wq);
mutex_init(&dma->regs_mutex);
mutex_init(&dma->rq_mutex);
mutex_init(&dma->wq_mutex);
dma->dev_id = dev_id;
dma->base = base;
dma->dev = dev;
atomic64_set(&dma->rq_enqueued, 0);
atomic64_set(&dma->rq_processed, 0);
atomic64_set(&dma->wq_enqueued, 0);
atomic64_set(&dma->wq_processed, 0);
DEVLOG(dev_id, TLKM_LF_DMA, "DMA engine initialized");
return 0;
......
......@@ -11,6 +11,7 @@
struct dma_engine;
struct tlkm_device;
typedef int (*dma_init_fun)(struct dma_engine *);
typedef irqreturn_t (*dma_intr_handler)(int , void *);
typedef ssize_t (*dma_copy_to_func_t)(struct dma_engine *, dev_addr_t, const void *, size_t);
typedef ssize_t (*dma_copy_from_func_t)(struct dma_engine *, void *, dev_addr_t, size_t);
......@@ -26,12 +27,8 @@ typedef void (*dma_free_buffer_func_t)(dev_id_t dev_id, struct tlkm_device *dev,
typedef int (*dma_buffer_cpu_func_t)(dev_id_t dev_id, struct tlkm_device *dev, void** buffer, void **dev_handle, dma_direction_t direction, size_t size);
typedef int (*dma_buffer_dev_func_t)(dev_id_t dev_id, struct tlkm_device *dev, void** buffer, void **dev_handle, dma_direction_t direction, size_t size);
typedef enum {
DMA_USED_DUAL = 0,
DMA_USED_BLUE,
} dma_used_t;
struct dma_operations {
dma_init_fun init;
dma_allocate_buffer_func_t allocate_buffer;
dma_free_buffer_func_t free_buffer;
dma_buffer_cpu_func_t buffer_cpu;
......@@ -52,7 +49,6 @@ struct dma_engine {
void __iomem *regs;
struct mutex regs_mutex;
struct dma_operations ops;
dma_used_t dma_used;
wait_queue_head_t rq;
struct mutex rq_mutex;
atomic64_t rq_enqueued;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment