#include "harddoomdev.h" #include "harddoom.h" #include "doomcode.h" #include "pci.h" #include "private_data.h" #include "util.h" void doomdev_write(void __iomem *iomem, size_t addr, uint32_t data) { iowrite32(data, iomem + addr); } uint32_t doomdev_read(void __iomem *iomem, size_t addr) { return ioread32(iomem + addr); } 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) { while (doomdev_read(iomem, HARDDOOM_FIFO_FREE) == 0) {} write_command(iomem, command); } uint32_t get_interrupts(void __iomem *iomem) { return doomdev_read(iomem, HARDDOOM_INTR); } void deactivate_intr(void __iomem *iomem, uint32_t intr) { doomdev_write(iomem, HARDDOOM_INTR, intr); } void ping_sync(void __iomem *iomem) { send_command(iomem, HARDDOOM_CMD_PING_SYNC); } void set_surf_src_pt(void __iomem *iomem, dma_addr_t page_table) { send_command(iomem, HARDDOOM_CMD_SURF_SRC_PT(page_table)); } void set_surf_dst_pt(void __iomem *iomem, dma_addr_t page_table) { send_command(iomem, HARDDOOM_CMD_SURF_DST_PT(page_table)); } void set_surf_dims(void __iomem *iomem, uint32_t width, uint32_t height) { send_command(iomem, HARDDOOM_CMD_SURF_DIMS(width, height)); } void set_xy_a(void __iomem *iomem, uint16_t x, uint16_t y) { send_command(iomem, HARDDOOM_CMD_XY_A(x, y)); } void set_xy_b(void __iomem *iomem, uint16_t x, uint16_t y) { send_command(iomem, HARDDOOM_CMD_XY_B(x, y)); } void set_fill_color(void __iomem *iomem, uint8_t color) { send_command(iomem, HARDDOOM_CMD_FILL_COLOR(color)); } void set_texture_pt(void __iomem *iomem, dma_addr_t page_table_dev) { send_command(iomem, HARDDOOM_CMD_TEXTURE_PT(page_table_dev)); } void set_texture_dims(void __iomem *iomem, uint32_t size, uint16_t height) { send_command(iomem, HARDDOOM_CMD_TEXTURE_DIMS(size,height)); } void set_ustart(void __iomem *iomem, uint32_t ustart) { send_command(iomem, HARDDOOM_CMD_USTART(ustart)); } void set_ustep(void __iomem *iomem, uint32_t ustep) { send_command(iomem, HARDDOOM_CMD_USTEP(ustep)); } void set_draw_params(void __iomem *iomem, uint8_t flags) { send_command(iomem, HARDDOOM_CMD_DRAW_PARAMS(flags)); } void fill_rect(struct surface_data *surface_data, struct doomdev_fill_rect rect) { 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_xy_a(iomem, rect.pos_dst_x, rect.pos_dst_y); set_fill_color(iomem, rect.color); send_command(iomem, HARDDOOM_CMD_FILL_RECT(rect.width, rect.height)); } void draw_line(struct surface_data *surface_data, struct doomdev_line line) { 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_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); send_command(iomem, 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(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)); } 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); send_command(iomem, HARDDOOM_CMD_DRAW_COLUMN(column.texture_offset)); } uint32_t doomdev_read_stat(void __iomem *iomem, size_t stat) { return doomdev_read(iomem, HARDDOOM_STATS(stat)); } void load_microcode(void __iomem *iomem) { int i; doomdev_write(iomem, HARDDOOM_FE_CODE_ADDR, 0); for (i = 0; i < ARRAY_SIZE(doomcode); i++) { doomdev_write(iomem, HARDDOOM_FE_CODE_WINDOW, doomcode[i]); } } void start_dev(struct pci_dev *dev) { struct doom_data *data; void __iomem *iomem; data = pci_get_drvdata(dev); iomem = data->iomem; load_microcode(iomem); doomdev_write(iomem, HARDDOOM_RESET, 0xffffffe); doomdev_write(iomem, HARDDOOM_INTR, HARDDOOM_INTR_MASK); doomdev_write(iomem, HARDDOOM_INTR_ENABLE, HARDDOOM_INTR_MASK); doomdev_write(iomem, HARDDOOM_ENABLE, HARDDOOM_ENABLE_ALL ^ HARDDOOM_ENABLE_FETCH_CMD); } void shutdown_dev(struct pci_dev *dev) { struct doom_data *data; void __iomem *iomem; data = pci_get_drvdata(dev); iomem = data->iomem; doomdev_write(iomem, HARDDOOM_ENABLE, 0); doomdev_write(iomem, HARDDOOM_INTR_ENABLE, 0); doomdev_read(iomem, 0); }