From c9973e18879c7608d0d4499230301c8a60755530 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" <w.terpstra@gsi.de> Date: Fri, 4 May 2012 15:24:25 +0000 Subject: [PATCH] Implement the mandatory Etherbone config space registers. Currently hardcode SDWB address as hardware does not support it. --- driver/pcie_wb.c | 28 ++++++++++++++++++++++++---- driver/pcie_wb.h | 2 ++ driver/wishbone.c | 34 +++++++++++++++++++++++++--------- driver/wishbone.h | 1 + 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/driver/pcie_wb.c b/driver/pcie_wb.c index f06aa19..19ad7ed 100644 --- a/driver/pcie_wb.c +++ b/driver/pcie_wb.c @@ -29,7 +29,7 @@ static unsigned int debug = 0; -void wb_cycle(struct wishbone* wb, int on) +static void wb_cycle(struct wishbone* wb, int on) { struct pcie_wb_dev* dev; unsigned char* control; @@ -44,7 +44,7 @@ void wb_cycle(struct wishbone* wb, int on) if (!on) mutex_unlock(&dev->mutex); } -void wb_byteenable(struct wishbone* wb, unsigned char be) +static void wb_byteenable(struct wishbone* wb, unsigned char be) { struct pcie_wb_dev* dev; @@ -92,7 +92,7 @@ void wb_byteenable(struct wishbone* wb, unsigned char be) } } -void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data) +static void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data) { struct pcie_wb_dev* dev; unsigned char* control; @@ -125,7 +125,7 @@ void wb_write(struct wishbone* wb, wb_addr_t addr, wb_data_t data) } } -wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr) +static wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr) { struct pcie_wb_dev* dev; unsigned char* control; @@ -158,11 +158,31 @@ wb_data_t wb_read(struct wishbone* wb, wb_addr_t addr) return 0; } +static wb_data_t wb_read_cfg(struct wishbone *wb, wb_addr_t addr) +{ + struct pcie_wb_dev* dev; + unsigned char* control; + + dev = container_of(wb, struct pcie_wb_dev, wb); + control = dev->pci_res[0].addr; + + rmb(); // has to be executed before reading + + switch (addr) { + case 0: return ioread32(control + ERROR_FLAG_HIGH); + case 4: return ioread32(control + ERROR_FLAG_LOW); + case 8: return 0; // ioread32(control + SDWB_ADDRESS_HIGH); + case 12: return 0x300000; // ioread32(control + SDWB_ADDRESS_LOW); + default: return 0; + } +} + static const struct wishbone_operations wb_ops = { .cycle = wb_cycle, .byteenable = wb_byteenable, .write = wb_write, .read = wb_read, + .read_cfg = wb_read_cfg, }; #if 0 diff --git a/driver/pcie_wb.h b/driver/pcie_wb.h index 84be7d9..0d51eca 100644 --- a/driver/pcie_wb.h +++ b/driver/pcie_wb.h @@ -15,6 +15,8 @@ #define ERROR_FLAG_LOW 12 #define WINDOW_OFFSET_HIGH 16 #define WINDOW_OFFSET_LOW 20 +#define SDWB_ADDRESS_HIGH 24 +#define SDWB_ADDRESS_LOW 28 #define WINDOW_HIGH 0xFFFF0000UL #define WINDOW_LOW 0x0000FFFCUL diff --git a/driver/wishbone.c b/driver/wishbone.c index ab8ba66..2a78c6c 100644 --- a/driver/wishbone.c +++ b/driver/wishbone.c @@ -102,18 +102,26 @@ static void etherbone_process(struct etherbone_context* context) wb_addr_t base_address; unsigned char j; int wff = flags & ETHERBONE_WFF; + int wca = flags & ETHERBONE_WCA; /* Erase the header */ eb_from_cpu(buf+i, 0); i = RING_INDEX(i + sizeof(wb_data_t)); base_address = eb_to_cpu(buf+i); - for (j = wcount; j > 0; --j) { - eb_from_cpu(buf+i, 0); - i = RING_INDEX(i + sizeof(wb_data_t)); - wops->write(wb, base_address, eb_to_cpu(buf+i)); - - if (!wff) base_address += sizeof(wb_data_t); + if (wca) { + for (j = wcount; j > 0; --j) { + eb_from_cpu(buf+i, 0); + i = RING_INDEX(i + sizeof(wb_data_t)); + } + } else { + for (j = wcount; j > 0; --j) { + eb_from_cpu(buf+i, 0); + i = RING_INDEX(i + sizeof(wb_data_t)); + wops->write(wb, base_address, eb_to_cpu(buf+i)); + + if (!wff) base_address += sizeof(wb_data_t); + } } } @@ -126,13 +134,21 @@ static void etherbone_process(struct etherbone_context* context) if (rcount > 0) { unsigned char j; + int rca = flags & ETHERBONE_RCA; /* Move past header, and leave BaseRetAddr intact */ i = RING_INDEX(i + sizeof(wb_data_t) + sizeof(wb_data_t)); - for (j = rcount; j > 0; --j) { - eb_from_cpu(buf+i, wops->read(wb, eb_to_cpu(buf+i))); - i = RING_INDEX(i + sizeof(wb_data_t)); + if (rca) { + for (j = rcount; j > 0; --j) { + eb_from_cpu(buf+i, wops->read_cfg(wb, eb_to_cpu(buf+i))); + i = RING_INDEX(i + sizeof(wb_data_t)); + } + } else { + for (j = rcount; j > 0; --j) { + eb_from_cpu(buf+i, wops->read(wb, eb_to_cpu(buf+i))); + i = RING_INDEX(i + sizeof(wb_data_t)); + } } } diff --git a/driver/wishbone.h b/driver/wishbone.h index f137a29..7ed3da7 100644 --- a/driver/wishbone.h +++ b/driver/wishbone.h @@ -26,6 +26,7 @@ struct wishbone_operations void (*byteenable)(struct wishbone* wb, unsigned char mask); void (*write)(struct wishbone* wb, wb_addr_t addr, wb_data_t); wb_data_t (*read)(struct wishbone* wb, wb_addr_t addr); + wb_data_t (*read_cfg)(struct wishbone* wb, wb_addr_t addr); }; /* One per wishbone backend hardware */ -- GitLab