m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/harddoomdev.c
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-26 21:01:28 +0200
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-26 21:01:28 +0200
commit0e125c3e6d2fafd6c2460e1859c29b9ece8b5eed (patch)
tree6e531c8c5317f0de19b71fcd7e38dc0235ebf57a /harddoomdev.c
parent911ab1a4ad24fb3c4f6df5c4798a8f2656c09af7 (diff)
Fix synchronization
Diffstat (limited to 'harddoomdev.c')
-rw-r--r--harddoomdev.c199
1 files changed, 129 insertions, 70 deletions
diff --git a/harddoomdev.c b/harddoomdev.c
index 823e868..26eb34e 100644
--- a/harddoomdev.c
+++ b/harddoomdev.c
@@ -6,6 +6,8 @@
#include "private_data.h"
#include "util.h"
+#define PING_FREQUENCY 0x80
+
void doomdev_write(void __iomem *iomem, size_t addr, uint32_t data)
{
iowrite32(data, iomem + addr);
@@ -21,11 +23,44 @@ void write_command(void __iomem *iomem, uint32_t command)
doomdev_write(iomem, HARDDOOM_FIFO_SEND, command);
}
-void send_command(void __iomem *iomem, uint32_t command)
+void enable_intr(void __iomem *iomem, uint32_t intr)
+{
+ uint32_t interrupts;
+
+ interrupts = doomdev_read(iomem, HARDDOOM_INTR_ENABLE);
+ doomdev_write(iomem, HARDDOOM_INTR_ENABLE, interrupts | intr);
+}
+
+void disable_intr(void __iomem *iomem, uint32_t intr)
{
- while (doomdev_read(iomem, HARDDOOM_FIFO_FREE) == 0) {}
+ uint32_t interrupts;
- write_command(iomem, command);
+ interrupts = doomdev_read(iomem, HARDDOOM_INTR_ENABLE);
+ doomdev_write(iomem, HARDDOOM_INTR_ENABLE, interrupts & (~intr));
+}
+
+void send_command(struct doom_data *doom_data, uint32_t command)
+{
+ uint32_t free;
+
+ free = doomdev_read(doom_data->iomem, HARDDOOM_FIFO_FREE);
+ if (free == 0) {
+ deactivate_intr(doom_data->iomem, HARDDOOM_INTR_PONG_ASYNC);
+ }
+
+ if (free == 0) {
+ enable_intr(doom_data->iomem, HARDDOOM_INTR_PONG_ASYNC);
+ down(&doom_data->pong_async_sem);
+ }
+
+ if (doom_data->cmd_counter > PING_FREQUENCY) {
+ doom_data->cmd_counter = 0;
+ write_command(doom_data->iomem, HARDDOOM_CMD_PING_ASYNC);
+ } else {
+ doom_data->cmd_counter++;
+ }
+
+ write_command(doom_data->iomem, command);
}
uint32_t get_interrupts(void __iomem *iomem)
@@ -33,134 +68,157 @@ uint32_t get_interrupts(void __iomem *iomem)
return doomdev_read(iomem, HARDDOOM_INTR);
}
+uint32_t get_enabled_interrupts(void __iomem *iomem)
+{
+ return doomdev_read(iomem, HARDDOOM_INTR_ENABLE);
+}
+
void deactivate_intr(void __iomem *iomem, uint32_t intr)
{
doomdev_write(iomem, HARDDOOM_INTR, intr);
}
-void ping_sync(void __iomem *iomem)
+void ping_sync(struct doom_data *doom_data)
{
- send_command(iomem, HARDDOOM_CMD_PING_SYNC);
+ send_command(doom_data, HARDDOOM_CMD_PING_SYNC);
}
-void set_surf_src_pt(void __iomem *iomem, dma_addr_t page_table)
+void set_surf_src_pt(struct doom_data *doom_data, dma_addr_t page_table)
{
- send_command(iomem, HARDDOOM_CMD_SURF_SRC_PT(page_table));
+ send_command(doom_data, HARDDOOM_CMD_SURF_SRC_PT(page_table));
}
-void set_surf_dst_pt(void __iomem *iomem, dma_addr_t page_table)
+void set_surf_dst_pt(struct doom_data *doom_data, dma_addr_t page_table)
{
- send_command(iomem, HARDDOOM_CMD_SURF_DST_PT(page_table));
+ send_command(doom_data, HARDDOOM_CMD_SURF_DST_PT(page_table));
}
-void set_surf_dims(void __iomem *iomem, uint32_t width, uint32_t height)
+void set_surf_dims(struct doom_data *doom_data, uint32_t width, uint32_t height)
{
- send_command(iomem, HARDDOOM_CMD_SURF_DIMS(width, height));
+ send_command(doom_data, HARDDOOM_CMD_SURF_DIMS(width, height));
}
-void set_xy_a(void __iomem *iomem, uint16_t x, uint16_t y)
+void set_xy_a(struct doom_data *doom_data, uint16_t x, uint16_t y)
{
- send_command(iomem, HARDDOOM_CMD_XY_A(x, y));
+ send_command(doom_data, HARDDOOM_CMD_XY_A(x, y));
}
-void set_xy_b(void __iomem *iomem, uint16_t x, uint16_t y)
+void set_xy_b(struct doom_data *doom_data, uint16_t x, uint16_t y)
{
- send_command(iomem, HARDDOOM_CMD_XY_B(x, y));
+ send_command(doom_data, HARDDOOM_CMD_XY_B(x, y));
}
-void set_fill_color(void __iomem *iomem, uint8_t color)
+void set_fill_color(struct doom_data *doom_data, uint8_t color)
{
- send_command(iomem, HARDDOOM_CMD_FILL_COLOR(color));
+ send_command(doom_data, HARDDOOM_CMD_FILL_COLOR(color));
}
-void set_texture_pt(void __iomem *iomem, dma_addr_t page_table_dev)
+void set_texture_pt(struct doom_data *doom_data, dma_addr_t page_table_dev)
{
- send_command(iomem, HARDDOOM_CMD_TEXTURE_PT(page_table_dev));
+ send_command(doom_data, HARDDOOM_CMD_TEXTURE_PT(page_table_dev));
}
-void set_texture_dims(void __iomem *iomem, uint32_t size, uint16_t height)
+void set_texture_dims(struct doom_data *doom_data, uint32_t size, uint16_t height)
{
- send_command(iomem, HARDDOOM_CMD_TEXTURE_DIMS(size,height));
+ send_command(doom_data, HARDDOOM_CMD_TEXTURE_DIMS(size,height));
}
-void set_ustart(void __iomem *iomem, uint32_t ustart)
+void set_flat(struct doom_data *doom_data, dma_addr_t flat_dev)
{
- send_command(iomem, HARDDOOM_CMD_USTART(ustart));
+ send_command(doom_data, HARDDOOM_CMD_FLAT_ADDR(flat_dev));
}
-void set_ustep(void __iomem *iomem, uint32_t ustep)
+void set_ustart(struct doom_data *doom_data, uint32_t ustart)
{
- send_command(iomem, HARDDOOM_CMD_USTEP(ustep));
+ send_command(doom_data, HARDDOOM_CMD_USTART(ustart));
}
-void set_draw_params(void __iomem *iomem, uint8_t flags)
+void set_ustep(struct doom_data *doom_data, uint32_t ustep)
{
- send_command(iomem, HARDDOOM_CMD_DRAW_PARAMS(flags));
+ send_command(doom_data, HARDDOOM_CMD_USTEP(ustep));
}
-void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect)
+void set_vstart(struct doom_data *doom_data, uint32_t vstart)
{
- void __iomem *iomem;
-
- iomem = surface_data->doom_data->iomem;
+ send_command(doom_data, HARDDOOM_CMD_VSTART(vstart));
+}
- set_surf_dst_pt(iomem, surface_data->page_table_dev);
- set_surf_dims(iomem, surface_data->width, surface_data->height);
- set_xy_a(iomem, rect.pos_dst_x, rect.pos_dst_y);
- set_fill_color(iomem, rect.color);
+void set_vstep(struct doom_data *doom_data, uint32_t vstep)
+{
+ send_command(doom_data, HARDDOOM_CMD_VSTEP(vstep));
+}
- send_command(iomem, HARDDOOM_CMD_FILL_RECT(rect.width, rect.height));
+void set_draw_params(struct doom_data *doom_data, uint8_t flags)
+{
+ send_command(doom_data, HARDDOOM_CMD_DRAW_PARAMS(flags));
}
-void draw_line(struct surface_data *surface_data, struct doomdev_line line)
+void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect)
{
- void __iomem *iomem;
+ set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
+ set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
+ set_xy_a(surface_data->doom_data, rect.pos_dst_x, rect.pos_dst_y);
+ set_fill_color(surface_data->doom_data, rect.color);
- iomem = surface_data->doom_data->iomem;
+ send_command(surface_data->doom_data, HARDDOOM_CMD_FILL_RECT(rect.width, rect.height));
+}
- set_surf_dst_pt(iomem, surface_data->page_table_dev);
- set_surf_dims(iomem, surface_data->width, surface_data->height);
- set_xy_a(iomem, line.pos_a_x, line.pos_a_y);
- set_xy_b(iomem, line.pos_b_x, line.pos_b_y);
- set_fill_color(iomem, line.color);
+void draw_line(struct surface_data *surface_data, struct doomdev_line line)
+{
+ set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
+ set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
+ set_xy_a(surface_data->doom_data, line.pos_a_x, line.pos_a_y);
+ set_xy_b(surface_data->doom_data, line.pos_b_x, line.pos_b_y);
+ set_fill_color(surface_data->doom_data, line.color);
- send_command(iomem, HARDDOOM_CMD_DRAW_LINE);
+ send_command(surface_data->doom_data, HARDDOOM_CMD_DRAW_LINE);
}
void copy_rect(struct surface_data *dst_data, struct surface_data *src_data,
struct doomdev_copy_rect rect)
{
- void __iomem *iomem;
-
- iomem = dst_data->doom_data->iomem;
+ set_surf_dst_pt(dst_data->doom_data, dst_data->page_table_dev);
+ set_surf_src_pt(dst_data->doom_data, src_data->page_table_dev);
+ set_surf_dims(dst_data->doom_data, dst_data->width, dst_data->height);
+ set_xy_a(dst_data->doom_data, rect.pos_dst_x, rect.pos_dst_y);
+ set_xy_b(dst_data->doom_data, rect.pos_src_x, rect.pos_src_y);
- set_surf_dst_pt(iomem, dst_data->page_table_dev);
- set_surf_src_pt(iomem, src_data->page_table_dev);
- set_surf_dims(iomem, dst_data->width, dst_data->height);
- set_xy_a(iomem, rect.pos_dst_x, rect.pos_dst_y);
- set_xy_b(iomem, rect.pos_src_x, rect.pos_src_y);
-
- send_command(iomem, HARDDOOM_CMD_COPY_RECT(rect.width, rect.height));
+ send_command(dst_data->doom_data, HARDDOOM_CMD_COPY_RECT(rect.width, rect.height));
}
void draw_column(struct surface_data *surface_data,
struct texture_data *texture_data, struct doomdev_column column)
{
- void __iomem *iomem;
-
- iomem = surface_data->doom_data->iomem;
-
- set_surf_dst_pt(iomem, surface_data->page_table_dev);
- set_surf_dims(iomem, surface_data->width, surface_data->height);
- set_texture_pt(iomem, texture_data->page_table_dev);
- set_texture_dims(iomem, texture_data->size, texture_data->height);
- set_xy_a(iomem, column.x, column.y1);
- set_xy_b(iomem, column.x, column.y2);
- set_ustart(iomem, column.ustart);
- set_ustep(iomem, column.ustep);
- set_draw_params(iomem, 0);
+ set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
+ set_surf_dims(surface_data->doom_data, surface_data->width, surface_data->height);
+ set_texture_pt(surface_data->doom_data, texture_data->page_table_dev);
+ set_texture_dims(surface_data->doom_data, texture_data->size, texture_data->height);
+ set_xy_a(surface_data->doom_data, column.x, column.y1);
+ set_xy_b(surface_data->doom_data, column.x, column.y2);
+ set_ustart(surface_data->doom_data, column.ustart);
+ set_ustep(surface_data->doom_data, column.ustep);
+ set_draw_params(surface_data->doom_data, 0);
+
+ send_command(surface_data->doom_data,
+ HARDDOOM_CMD_DRAW_COLUMN(column.texture_offset));
+}
- send_command(iomem, HARDDOOM_CMD_DRAW_COLUMN(column.texture_offset));
+void draw_span(struct surface_data *surface_data, struct flat_data *flat_data,
+ struct doomdev_span span)
+{
+ set_surf_dst_pt(surface_data->doom_data, surface_data->page_table_dev);
+ set_surf_dims(surface_data->doom_data, surface_data->width,
+ surface_data->height);
+ set_flat(surface_data->doom_data, flat_data->flat_dev);
+ set_xy_a(surface_data->doom_data, span.x1, span.y);
+ set_xy_b(surface_data->doom_data, span.x2, span.y);
+ set_ustart(surface_data->doom_data, span.ustart);
+ set_ustep(surface_data->doom_data, span.ustep);
+ set_vstart(surface_data->doom_data, span.vstart);
+ set_vstep(surface_data->doom_data, span.vstep);
+ set_draw_params(surface_data->doom_data, 0);
+
+ send_command(surface_data->doom_data, HARDDOOM_CMD_DRAW_SPAN);
}
uint32_t doomdev_read_stat(void __iomem *iomem, size_t stat)
@@ -188,7 +246,8 @@ void start_dev(struct pci_dev *dev)
load_microcode(iomem);
doomdev_write(iomem, HARDDOOM_RESET, 0xffffffe);
- doomdev_write(iomem, HARDDOOM_INTR, HARDDOOM_INTR_MASK);
+ doomdev_write(iomem, HARDDOOM_INTR,
+ HARDDOOM_INTR_MASK ^ HARDDOOM_INTR_PONG_ASYNC);
doomdev_write(iomem, HARDDOOM_INTR_ENABLE, HARDDOOM_INTR_MASK);
doomdev_write(iomem, HARDDOOM_ENABLE,
HARDDOOM_ENABLE_ALL ^ HARDDOOM_ENABLE_FETCH_CMD);