diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/bt431.h |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/video/bt431.h')
-rw-r--r-- | drivers/video/bt431.h | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/drivers/video/bt431.h b/drivers/video/bt431.h new file mode 100644 index 000000000000..c826f2787bad --- /dev/null +++ b/drivers/video/bt431.h | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/bt431.h | ||
3 | * | ||
4 | * Copyright 2003 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General | ||
7 | * Public License. See the file COPYING in the main directory of this | ||
8 | * archive for more details. | ||
9 | */ | ||
10 | #include <linux/types.h> | ||
11 | #include <asm/system.h> | ||
12 | |||
13 | /* | ||
14 | * Bt431 cursor generator registers, 32-bit aligned. | ||
15 | * Two twin Bt431 are used on the DECstation's PMAG-AA. | ||
16 | */ | ||
17 | struct bt431_regs { | ||
18 | volatile u16 addr_lo; | ||
19 | u16 pad0; | ||
20 | volatile u16 addr_hi; | ||
21 | u16 pad1; | ||
22 | volatile u16 addr_cmap; | ||
23 | u16 pad2; | ||
24 | volatile u16 addr_reg; | ||
25 | u16 pad3; | ||
26 | }; | ||
27 | |||
28 | static inline u16 bt431_set_value(u8 val) | ||
29 | { | ||
30 | return ((val << 8) | (val & 0xff)) & 0xffff; | ||
31 | } | ||
32 | |||
33 | static inline u8 bt431_get_value(u16 val) | ||
34 | { | ||
35 | return val & 0xff; | ||
36 | } | ||
37 | |||
38 | /* | ||
39 | * Additional registers addressed indirectly. | ||
40 | */ | ||
41 | #define BT431_REG_CMD 0x0000 | ||
42 | #define BT431_REG_CXLO 0x0001 | ||
43 | #define BT431_REG_CXHI 0x0002 | ||
44 | #define BT431_REG_CYLO 0x0003 | ||
45 | #define BT431_REG_CYHI 0x0004 | ||
46 | #define BT431_REG_WXLO 0x0005 | ||
47 | #define BT431_REG_WXHI 0x0006 | ||
48 | #define BT431_REG_WYLO 0x0007 | ||
49 | #define BT431_REG_WYHI 0x0008 | ||
50 | #define BT431_REG_WWLO 0x0009 | ||
51 | #define BT431_REG_WWHI 0x000a | ||
52 | #define BT431_REG_WHLO 0x000b | ||
53 | #define BT431_REG_WHHI 0x000c | ||
54 | |||
55 | #define BT431_REG_CRAM_BASE 0x0000 | ||
56 | #define BT431_REG_CRAM_END 0x01ff | ||
57 | |||
58 | /* | ||
59 | * Command register. | ||
60 | */ | ||
61 | #define BT431_CMD_CURS_ENABLE 0x40 | ||
62 | #define BT431_CMD_XHAIR_ENABLE 0x20 | ||
63 | #define BT431_CMD_OR_CURSORS 0x10 | ||
64 | #define BT431_CMD_AND_CURSORS 0x00 | ||
65 | #define BT431_CMD_1_1_MUX 0x00 | ||
66 | #define BT431_CMD_4_1_MUX 0x04 | ||
67 | #define BT431_CMD_5_1_MUX 0x08 | ||
68 | #define BT431_CMD_xxx_MUX 0x0c | ||
69 | #define BT431_CMD_THICK_1 0x00 | ||
70 | #define BT431_CMD_THICK_3 0x01 | ||
71 | #define BT431_CMD_THICK_5 0x02 | ||
72 | #define BT431_CMD_THICK_7 0x03 | ||
73 | |||
74 | static inline void bt431_select_reg(struct bt431_regs *regs, int ir) | ||
75 | { | ||
76 | /* | ||
77 | * The compiler splits the write in two bytes without these | ||
78 | * helper variables. | ||
79 | */ | ||
80 | volatile u16 *lo = &(regs->addr_lo); | ||
81 | volatile u16 *hi = &(regs->addr_hi); | ||
82 | |||
83 | mb(); | ||
84 | *lo = bt431_set_value(ir & 0xff); | ||
85 | wmb(); | ||
86 | *hi = bt431_set_value((ir >> 8) & 0xff); | ||
87 | } | ||
88 | |||
89 | /* Autoincrement read/write. */ | ||
90 | static inline u8 bt431_read_reg_inc(struct bt431_regs *regs) | ||
91 | { | ||
92 | /* | ||
93 | * The compiler splits the write in two bytes without the | ||
94 | * helper variable. | ||
95 | */ | ||
96 | volatile u16 *r = &(regs->addr_reg); | ||
97 | |||
98 | mb(); | ||
99 | return bt431_get_value(*r); | ||
100 | } | ||
101 | |||
102 | static inline void bt431_write_reg_inc(struct bt431_regs *regs, u8 value) | ||
103 | { | ||
104 | /* | ||
105 | * The compiler splits the write in two bytes without the | ||
106 | * helper variable. | ||
107 | */ | ||
108 | volatile u16 *r = &(regs->addr_reg); | ||
109 | |||
110 | mb(); | ||
111 | *r = bt431_set_value(value); | ||
112 | } | ||
113 | |||
114 | static inline u8 bt431_read_reg(struct bt431_regs *regs, int ir) | ||
115 | { | ||
116 | bt431_select_reg(regs, ir); | ||
117 | return bt431_read_reg_inc(regs); | ||
118 | } | ||
119 | |||
120 | static inline void bt431_write_reg(struct bt431_regs *regs, int ir, u8 value) | ||
121 | { | ||
122 | bt431_select_reg(regs, ir); | ||
123 | bt431_write_reg_inc(regs, value); | ||
124 | } | ||
125 | |||
126 | /* Autoincremented read/write for the cursor map. */ | ||
127 | static inline u16 bt431_read_cmap_inc(struct bt431_regs *regs) | ||
128 | { | ||
129 | /* | ||
130 | * The compiler splits the write in two bytes without the | ||
131 | * helper variable. | ||
132 | */ | ||
133 | volatile u16 *r = &(regs->addr_cmap); | ||
134 | |||
135 | mb(); | ||
136 | return *r; | ||
137 | } | ||
138 | |||
139 | static inline void bt431_write_cmap_inc(struct bt431_regs *regs, u16 value) | ||
140 | { | ||
141 | /* | ||
142 | * The compiler splits the write in two bytes without the | ||
143 | * helper variable. | ||
144 | */ | ||
145 | volatile u16 *r = &(regs->addr_cmap); | ||
146 | |||
147 | mb(); | ||
148 | *r = value; | ||
149 | } | ||
150 | |||
151 | static inline u16 bt431_read_cmap(struct bt431_regs *regs, int cr) | ||
152 | { | ||
153 | bt431_select_reg(regs, cr); | ||
154 | return bt431_read_cmap_inc(regs); | ||
155 | } | ||
156 | |||
157 | static inline void bt431_write_cmap(struct bt431_regs *regs, int cr, u16 value) | ||
158 | { | ||
159 | bt431_select_reg(regs, cr); | ||
160 | bt431_write_cmap_inc(regs, value); | ||
161 | } | ||
162 | |||
163 | static inline void bt431_enable_cursor(struct bt431_regs *regs) | ||
164 | { | ||
165 | bt431_write_reg(regs, BT431_REG_CMD, | ||
166 | BT431_CMD_CURS_ENABLE | BT431_CMD_OR_CURSORS | ||
167 | | BT431_CMD_4_1_MUX | BT431_CMD_THICK_1); | ||
168 | } | ||
169 | |||
170 | static inline void bt431_erase_cursor(struct bt431_regs *regs) | ||
171 | { | ||
172 | bt431_write_reg(regs, BT431_REG_CMD, BT431_CMD_4_1_MUX); | ||
173 | } | ||
174 | |||
175 | static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y) | ||
176 | { | ||
177 | /* | ||
178 | * Magic from the MACH sources. | ||
179 | * | ||
180 | * Cx = x + D + H - P | ||
181 | * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 | ||
182 | * D = pixel skew between outdata and external data | ||
183 | * H = pixels between HSYNCH falling and active video | ||
184 | * | ||
185 | * Cy = y + V - 32 | ||
186 | * V = scanlines between HSYNCH falling, two or more | ||
187 | * clocks after VSYNCH falling, and active video | ||
188 | */ | ||
189 | x += 412 - 52; | ||
190 | y += 68 - 32; | ||
191 | |||
192 | /* Use autoincrement. */ | ||
193 | bt431_select_reg(regs, BT431_REG_CXLO); | ||
194 | bt431_write_reg_inc(regs, x & 0xff); /* BT431_REG_CXLO */ | ||
195 | bt431_write_reg_inc(regs, (x >> 8) & 0x0f); /* BT431_REG_CXHI */ | ||
196 | bt431_write_reg_inc(regs, y & 0xff); /* BT431_REG_CYLO */ | ||
197 | bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */ | ||
198 | } | ||
199 | |||
200 | static inline void bt431_set_font(struct bt431_regs *regs, u8 fgc, | ||
201 | u16 width, u16 height) | ||
202 | { | ||
203 | int i; | ||
204 | u16 fgp = fgc ? 0xffff : 0x0000; | ||
205 | u16 bgp = fgc ? 0x0000 : 0xffff; | ||
206 | |||
207 | bt431_select_reg(regs, BT431_REG_CRAM_BASE); | ||
208 | for (i = BT431_REG_CRAM_BASE; i <= BT431_REG_CRAM_END; i++) { | ||
209 | u16 value; | ||
210 | |||
211 | if (height << 6 <= i << 3) | ||
212 | value = bgp; | ||
213 | else if (width <= i % 8 << 3) | ||
214 | value = bgp; | ||
215 | else if (((width >> 3) & 0xffff) > i % 8) | ||
216 | value = fgp; | ||
217 | else | ||
218 | value = fgp & ~(bgp << (width % 8 << 1)); | ||
219 | |||
220 | bt431_write_cmap_inc(regs, value); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | static inline void bt431_init_cursor(struct bt431_regs *regs) | ||
225 | { | ||
226 | /* no crosshair window */ | ||
227 | bt431_select_reg(regs, BT431_REG_WXLO); | ||
228 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXLO */ | ||
229 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXHI */ | ||
230 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYLO */ | ||
231 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYHI */ | ||
232 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWLO */ | ||
233 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWHI */ | ||
234 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHLO */ | ||
235 | bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHHI */ | ||
236 | } | ||