1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#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_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 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);
}
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);
}
|