From 0e125c3e6d2fafd6c2460e1859c29b9ece8b5eed Mon Sep 17 00:00:00 2001 From: Marcin Chrzanowski Date: Sat, 26 May 2018 21:01:28 +0200 Subject: Fix synchronization --- harddoomdev.c | 199 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 129 insertions(+), 70 deletions(-) (limited to 'harddoomdev.c') 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); -- cgit v1.2.3