Wed Jan 25 16:11:54 2017 UTC ()
Map coprocessor registers before igsfb_hw_setup(), they are needed for
setting up the video mode.


(jakllsch)
diff -r1.54 -r1.55 src/sys/dev/ic/igsfb.c

cvs diff -r1.54 -r1.55 src/sys/dev/ic/igsfb.c (switch to unified diff)

--- src/sys/dev/ic/igsfb.c 2017/01/25 15:51:07 1.54
+++ src/sys/dev/ic/igsfb.c 2017/01/25 16:11:54 1.55
@@ -1,1349 +1,1360 @@ @@ -1,1349 +1,1360 @@
1/* $NetBSD: igsfb.c,v 1.54 2017/01/25 15:51:07 jakllsch Exp $ */ 1/* $NetBSD: igsfb.c,v 1.55 2017/01/25 16:11:54 jakllsch Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2002, 2003 Valeriy E. Ushakov 4 * Copyright (c) 2002, 2003 Valeriy E. Ushakov
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products 15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission 16 * derived from this software without specific prior written permission
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29 29
30/* 30/*
31 * Integraphics Systems IGA 168x and CyberPro series. 31 * Integraphics Systems IGA 168x and CyberPro series.
32 */ 32 */
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: igsfb.c,v 1.54 2017/01/25 15:51:07 jakllsch Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: igsfb.c,v 1.55 2017/01/25 16:11:54 jakllsch Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/malloc.h> 40#include <sys/malloc.h>
41#include <sys/ioctl.h> 41#include <sys/ioctl.h>
42 42
43#include <sys/bus.h> 43#include <sys/bus.h>
44 44
45#include <dev/wscons/wsdisplayvar.h> 45#include <dev/wscons/wsdisplayvar.h>
46#include <dev/wscons/wsconsio.h> 46#include <dev/wscons/wsconsio.h>
47#include <dev/wsfont/wsfont.h> 47#include <dev/wsfont/wsfont.h>
48#include <dev/rasops/rasops.h> 48#include <dev/rasops/rasops.h>
49 49
50#include <dev/wscons/wsdisplay_vconsvar.h> 50#include <dev/wscons/wsdisplay_vconsvar.h>
51 51
52#include <dev/ic/igsfbreg.h> 52#include <dev/ic/igsfbreg.h>
53#include <dev/ic/igsfbvar.h> 53#include <dev/ic/igsfbvar.h>
54 54
55 55
56struct igsfb_devconfig igsfb_console_dc = { 56struct igsfb_devconfig igsfb_console_dc = {
57 .dc_mmap = NULL, 57 .dc_mmap = NULL,
58 .dc_modestring = "", 58 .dc_modestring = "",
59}; 59};
60 60
61/* 61/*
62 * wsscreen 62 * wsscreen
63 */ 63 */
64 64
65/* filled from rasops_info in igsfb_init_wsdisplay */ 65/* filled from rasops_info in igsfb_init_wsdisplay */
66static struct wsscreen_descr igsfb_stdscreen = { 66static struct wsscreen_descr igsfb_stdscreen = {
67 .name = "std", 67 .name = "std",
68}; 68};
69 69
70static const struct wsscreen_descr *_igsfb_scrlist[] = { 70static const struct wsscreen_descr *_igsfb_scrlist[] = {
71 &igsfb_stdscreen, 71 &igsfb_stdscreen,
72}; 72};
73 73
74static const struct wsscreen_list igsfb_screenlist = { 74static const struct wsscreen_list igsfb_screenlist = {
75 .nscreens = sizeof(_igsfb_scrlist) / sizeof(_igsfb_scrlist[0]), 75 .nscreens = sizeof(_igsfb_scrlist) / sizeof(_igsfb_scrlist[0]),
76 .screens = _igsfb_scrlist, 76 .screens = _igsfb_scrlist,
77}; 77};
78 78
79 79
80/* 80/*
81 * wsdisplay_accessops 81 * wsdisplay_accessops
82 */ 82 */
83 83
84static int igsfb_ioctl(void *, void *, u_long, void *, int, struct lwp *); 84static int igsfb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
85static paddr_t igsfb_mmap(void *, void *, off_t, int); 85static paddr_t igsfb_mmap(void *, void *, off_t, int);
86 86
87static struct wsdisplay_accessops igsfb_accessops = { 87static struct wsdisplay_accessops igsfb_accessops = {
88 .ioctl = igsfb_ioctl, 88 .ioctl = igsfb_ioctl,
89 .mmap = igsfb_mmap, 89 .mmap = igsfb_mmap,
90}; 90};
91 91
92 92
93/* 93/*
94 * acceleration 94 * acceleration
95 */ 95 */
96static int igsfb_make_text_cursor(struct igsfb_devconfig *, 96static int igsfb_make_text_cursor(struct igsfb_devconfig *,
97 struct vcons_screen *); 97 struct vcons_screen *);
98static void igsfb_accel_cursor(void *, int, int, int); 98static void igsfb_accel_cursor(void *, int, int, int);
99 99
100static int igsfb_accel_wait(struct igsfb_devconfig *); 100static int igsfb_accel_wait(struct igsfb_devconfig *);
101static void igsfb_accel_fill(struct igsfb_devconfig *, 101static void igsfb_accel_fill(struct igsfb_devconfig *,
102 uint32_t, uint32_t, uint16_t, uint16_t); 102 uint32_t, uint32_t, uint16_t, uint16_t);
103static void igsfb_accel_copy(struct igsfb_devconfig *, 103static void igsfb_accel_copy(struct igsfb_devconfig *,
104 uint32_t, uint32_t, uint16_t, uint16_t); 104 uint32_t, uint32_t, uint16_t, uint16_t);
105 105
106static void igsfb_accel_copycols(void *, int, int, int, int); 106static void igsfb_accel_copycols(void *, int, int, int, int);
107static void igsfb_accel_erasecols(void *, int, int, int, long); 107static void igsfb_accel_erasecols(void *, int, int, int, long);
108static void igsfb_accel_copyrows(void *, int, int, int); 108static void igsfb_accel_copyrows(void *, int, int, int);
109static void igsfb_accel_eraserows(void *, int, int, long); 109static void igsfb_accel_eraserows(void *, int, int, long);
110static void igsfb_accel_putchar(void *, int, int, u_int, long); 110static void igsfb_accel_putchar(void *, int, int, u_int, long);
111 111
112 112
113/* 113/*
114 * internal functions 114 * internal functions
115 */ 115 */
116static int igsfb_init_video(struct igsfb_devconfig *); 116static int igsfb_init_video(struct igsfb_devconfig *);
117static void igsfb_init_cmap(struct igsfb_devconfig *); 117static void igsfb_init_cmap(struct igsfb_devconfig *);
118static uint16_t igsfb_spread_bits_8(uint8_t); 118static uint16_t igsfb_spread_bits_8(uint8_t);
119static void igsfb_init_bit_table(struct igsfb_devconfig *); 119static void igsfb_init_bit_table(struct igsfb_devconfig *);
120static void igsfb_init_wsdisplay(void *, struct vcons_screen *, int, 120static void igsfb_init_wsdisplay(void *, struct vcons_screen *, int,
121 long *); 121 long *);
122 122
123 123
124static void igsfb_blank_screen(struct igsfb_devconfig *, int); 124static void igsfb_blank_screen(struct igsfb_devconfig *, int);
125static int igsfb_get_cmap(struct igsfb_devconfig *, 125static int igsfb_get_cmap(struct igsfb_devconfig *,
126 struct wsdisplay_cmap *); 126 struct wsdisplay_cmap *);
127static int igsfb_set_cmap(struct igsfb_devconfig *, 127static int igsfb_set_cmap(struct igsfb_devconfig *,
128 const struct wsdisplay_cmap *); 128 const struct wsdisplay_cmap *);
129static void igsfb_update_cmap(struct igsfb_devconfig *, u_int, u_int); 129static void igsfb_update_cmap(struct igsfb_devconfig *, u_int, u_int);
130static void igsfb_set_curpos(struct igsfb_devconfig *, 130static void igsfb_set_curpos(struct igsfb_devconfig *,
131 const struct wsdisplay_curpos *); 131 const struct wsdisplay_curpos *);
132static void igsfb_update_curpos(struct igsfb_devconfig *); 132static void igsfb_update_curpos(struct igsfb_devconfig *);
133static int igsfb_get_cursor(struct igsfb_devconfig *, 133static int igsfb_get_cursor(struct igsfb_devconfig *,
134 struct wsdisplay_cursor *); 134 struct wsdisplay_cursor *);
135static int igsfb_set_cursor(struct igsfb_devconfig *, 135static int igsfb_set_cursor(struct igsfb_devconfig *,
136 const struct wsdisplay_cursor *); 136 const struct wsdisplay_cursor *);
137static void igsfb_update_cursor(struct igsfb_devconfig *, u_int); 137static void igsfb_update_cursor(struct igsfb_devconfig *, u_int);
138static void igsfb_convert_cursor_data(struct igsfb_devconfig *, 138static void igsfb_convert_cursor_data(struct igsfb_devconfig *,
139 u_int, u_int); 139 u_int, u_int);
140 140
141 141
142int 142int
143igsfb_cnattach_subr(struct igsfb_devconfig *dc) 143igsfb_cnattach_subr(struct igsfb_devconfig *dc)
144{ 144{
145 struct rasops_info *ri; 145 struct rasops_info *ri;
146 long defattr; 146 long defattr;
147 147
148 KASSERT(dc == &igsfb_console_dc); 148 KASSERT(dc == &igsfb_console_dc);
149 149
150 igsfb_init_video(dc); 150 igsfb_init_video(dc);
151 dc->dc_vd.active = NULL; 151 dc->dc_vd.active = NULL;
152 igsfb_init_wsdisplay(dc, &dc->dc_console, 1, &defattr); 152 igsfb_init_wsdisplay(dc, &dc->dc_console, 1, &defattr);
153 153
154 ri = &dc->dc_console.scr_ri; 154 ri = &dc->dc_console.scr_ri;
155 ri->ri_hw = &dc->dc_console; 155 ri->ri_hw = &dc->dc_console;
156 dc->dc_console.scr_cookie = dc; 156 dc->dc_console.scr_cookie = dc;
157 157
158 (*ri->ri_ops.allocattr)(ri, 158 (*ri->ri_ops.allocattr)(ri,
159 WS_DEFAULT_FG, /* fg */ 159 WS_DEFAULT_FG, /* fg */
160 WS_DEFAULT_BG, /* bg */ 160 WS_DEFAULT_BG, /* bg */
161 0, /* wsattrs */ 161 0, /* wsattrs */
162 &defattr); 162 &defattr);
163 163
164 wsdisplay_cnattach(&igsfb_stdscreen, 164 wsdisplay_cnattach(&igsfb_stdscreen,
165 ri, /* emulcookie */ 165 ri, /* emulcookie */
166 0, 0, /* cursor position */ 166 0, 0, /* cursor position */
167 defattr); 167 defattr);
168 return 0; 168 return 0;
169} 169}
170 170
171 171
172/* 172/*
173 * Finish off the attach. Bus specific attach method should have 173 * Finish off the attach. Bus specific attach method should have
174 * enabled io and memory accesses and mapped io (and cop?) registers. 174 * enabled io and memory accesses and mapped io (and cop?) registers.
175 */ 175 */
176void 176void
177igsfb_attach_subr(struct igsfb_softc *sc, int isconsole) 177igsfb_attach_subr(struct igsfb_softc *sc, int isconsole)
178{ 178{
179 struct igsfb_devconfig *dc = sc->sc_dc; 179 struct igsfb_devconfig *dc = sc->sc_dc;
180 struct wsemuldisplaydev_attach_args waa; 180 struct wsemuldisplaydev_attach_args waa;
181 struct rasops_info *ri; 181 struct rasops_info *ri;
182 long defattr; 182 long defattr;
183 183
184 KASSERT(dc != NULL); 184 KASSERT(dc != NULL);
185 185
186 if (!isconsole) { 186 if (!isconsole) {
187 igsfb_init_video(dc); 187 igsfb_init_video(dc);
188 } 188 }
189 189
190 vcons_init(&dc->dc_vd, dc, &igsfb_stdscreen, &igsfb_accessops); 190 vcons_init(&dc->dc_vd, dc, &igsfb_stdscreen, &igsfb_accessops);
191 dc->dc_vd.init_screen = igsfb_init_wsdisplay; 191 dc->dc_vd.init_screen = igsfb_init_wsdisplay;
192 192
193 vcons_init_screen(&dc->dc_vd, &dc->dc_console, 1, &defattr); 193 vcons_init_screen(&dc->dc_vd, &dc->dc_console, 1, &defattr);
194 dc->dc_console.scr_flags |= VCONS_SCREEN_IS_STATIC; 194 dc->dc_console.scr_flags |= VCONS_SCREEN_IS_STATIC;
195 195
196 aprint_normal("%s: %dMB, %s%dx%d, %dbpp\n", 196 aprint_normal("%s: %dMB, %s%dx%d, %dbpp\n",
197 device_xname(sc->sc_dev), 197 device_xname(sc->sc_dev),
198 (uint32_t)(dc->dc_vmemsz >> 20), 198 (uint32_t)(dc->dc_vmemsz >> 20),
199 (dc->dc_hwflags & IGSFB_HW_BSWAP) 199 (dc->dc_hwflags & IGSFB_HW_BSWAP)
200 ? (dc->dc_hwflags & IGSFB_HW_BE_SELECT) 200 ? (dc->dc_hwflags & IGSFB_HW_BE_SELECT)
201 ? "hardware bswap, " : "software bswap, " 201 ? "hardware bswap, " : "software bswap, "
202 : "", 202 : "",
203 dc->dc_width, dc->dc_height, dc->dc_depth); 203 dc->dc_width, dc->dc_height, dc->dc_depth);
204 aprint_normal("%s: using %dbpp for X\n", device_xname(sc->sc_dev), 204 aprint_normal("%s: using %dbpp for X\n", device_xname(sc->sc_dev),
205 dc->dc_maxdepth); 205 dc->dc_maxdepth);
206 ri = &dc->dc_console.scr_ri; 206 ri = &dc->dc_console.scr_ri;
207 ri->ri_ops.eraserows(ri, 0, ri->ri_rows, defattr); 207 ri->ri_ops.eraserows(ri, 0, ri->ri_rows, defattr);
208 208
209 if (isconsole) 209 if (isconsole)
210 vcons_replay_msgbuf(&dc->dc_console); 210 vcons_replay_msgbuf(&dc->dc_console);
211 211
212 /* attach wsdisplay */ 212 /* attach wsdisplay */
213 waa.console = isconsole; 213 waa.console = isconsole;
214 waa.scrdata = &igsfb_screenlist; 214 waa.scrdata = &igsfb_screenlist;
215 waa.accessops = &igsfb_accessops; 215 waa.accessops = &igsfb_accessops;
216 waa.accesscookie = &dc->dc_vd; 216 waa.accesscookie = &dc->dc_vd;
217 217
218 config_found(sc->sc_dev, &waa, wsemuldisplaydevprint); 218 config_found(sc->sc_dev, &waa, wsemuldisplaydevprint);
219} 219}
220 220
221 221
222static int 222static int
223igsfb_init_video(struct igsfb_devconfig *dc) 223igsfb_init_video(struct igsfb_devconfig *dc)
224{ 224{
225 bus_space_handle_t tmph; 225 bus_space_handle_t tmph;
226 uint8_t *p; 226 uint8_t *p;
227 int need_bswap; 227 int need_bswap;
228 bus_addr_t fbaddr, craddr; 228 bus_addr_t fbaddr, craddr;
229 off_t croffset; 229 off_t croffset;
230 uint8_t busctl, curctl; 230 uint8_t busctl, curctl;
231 void *va; 231 void *va;
232 232
233 /* Total amount of video memory. */ 233 /* Total amount of video memory. */
234 busctl = igs_ext_read(dc->dc_iot, dc->dc_ioh, IGS_EXT_BUS_CTL); 234 busctl = igs_ext_read(dc->dc_iot, dc->dc_ioh, IGS_EXT_BUS_CTL);
235 if (busctl & 0x2) 235 if (busctl & 0x2)
236 dc->dc_vmemsz = 4; 236 dc->dc_vmemsz = 4;
237 else if (busctl & 0x1) 237 else if (busctl & 0x1)
238 dc->dc_vmemsz = 2; 238 dc->dc_vmemsz = 2;
239 else 239 else
240 dc->dc_vmemsz = 1; 240 dc->dc_vmemsz = 1;
241 dc->dc_vmemsz <<= 20; /* megabytes -> bytes */ 241 dc->dc_vmemsz <<= 20; /* megabytes -> bytes */
242 242
243 /* 243 /*
244 * Check for endianness mismatch by writing a word at the end of 244 * Check for endianness mismatch by writing a word at the end of
245 * the video memory (off-screen) and reading it back byte-by-byte. 245 * the video memory (off-screen) and reading it back byte-by-byte.
246 */ 246 */
247 if (bus_space_map(dc->dc_memt, 247 if (bus_space_map(dc->dc_memt,
248 dc->dc_memaddr + dc->dc_vmemsz - sizeof(uint32_t), 248 dc->dc_memaddr + dc->dc_vmemsz - sizeof(uint32_t),
249 sizeof(uint32_t), 249 sizeof(uint32_t),
250 dc->dc_memflags | BUS_SPACE_MAP_LINEAR, 250 dc->dc_memflags | BUS_SPACE_MAP_LINEAR,
251 &tmph) != 0) 251 &tmph) != 0)
252 { 252 {
253 printf("unable to map video memory for endianness test\n"); 253 printf("unable to map video memory for endianness test\n");
254 return 1; 254 return 1;
255 } 255 }
256 256
257 p = bus_space_vaddr(dc->dc_memt, tmph); 257 p = bus_space_vaddr(dc->dc_memt, tmph);
258#if BYTE_ORDER == BIG_ENDIAN 258#if BYTE_ORDER == BIG_ENDIAN
259 *((uint32_t *)p) = 0x12345678; 259 *((uint32_t *)p) = 0x12345678;
260#else 260#else
261 *((uint32_t *)p) = 0x78563412; 261 *((uint32_t *)p) = 0x78563412;
262#endif 262#endif
263 if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78) 263 if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78)
264 need_bswap = 0; 264 need_bswap = 0;
265 else 265 else
266 need_bswap = 1; 266 need_bswap = 1;
267 267
268 bus_space_unmap(dc->dc_memt, tmph, sizeof(uint32_t)); 268 bus_space_unmap(dc->dc_memt, tmph, sizeof(uint32_t));
269 269
270 /* 270 /*
271 * On CyberPro we can use magic bswap bit in linear address. 271 * On CyberPro we can use magic bswap bit in linear address.
272 */ 272 */
273 fbaddr = dc->dc_memaddr; 273 fbaddr = dc->dc_memaddr;
274 if (need_bswap) { 274 if (need_bswap) {
275 dc->dc_hwflags |= IGSFB_HW_BSWAP; 275 dc->dc_hwflags |= IGSFB_HW_BSWAP;
276 if (dc->dc_id >= 0x2000) { 276 if (dc->dc_id >= 0x2000) {
277 dc->dc_hwflags |= IGSFB_HW_BE_SELECT; 277 dc->dc_hwflags |= IGSFB_HW_BE_SELECT;
278 fbaddr |= IGS_MEM_BE_SELECT; 278 fbaddr |= IGS_MEM_BE_SELECT;
279 } 279 }
280 } 280 }
281 281
 282 /*
 283 * Map graphic coprocessor for mode setting and accelerated rasops.
 284 */
 285 if (dc->dc_id >= 0x2000) { /* XXX */
 286 if (bus_space_map(dc->dc_iot,
 287 dc->dc_iobase + IGS_COP_BASE_B, IGS_COP_SIZE,
 288 dc->dc_ioflags,
 289 &dc->dc_coph) != 0)
 290 {
 291 printf("unable to map COP registers\n");
 292 return 1;
 293 }
 294 }
 295
282 igsfb_hw_setup(dc); 296 igsfb_hw_setup(dc);
283 297
284 /* 298 /*
285 * Don't map in all N megs, just the amount we need for the wsscreen. 299 * Don't map in all N megs, just the amount we need for the wsscreen.
286 */ 300 */
287 dc->dc_fbsz = dc->dc_stride * dc->dc_height; 301 dc->dc_fbsz = dc->dc_stride * dc->dc_height;
288 if (bus_space_map(dc->dc_memt, fbaddr, dc->dc_fbsz, 302 if (bus_space_map(dc->dc_memt, fbaddr, dc->dc_fbsz,
289 dc->dc_memflags | BUS_SPACE_MAP_LINEAR, 303 dc->dc_memflags | BUS_SPACE_MAP_LINEAR,
290 &dc->dc_fbh) != 0) 304 &dc->dc_fbh) != 0)
291 { 305 {
 306 if (dc->dc_id >= 0x2000) { /* XXX */
 307 bus_space_unmap(dc->dc_iot, dc->dc_coph, IGS_COP_SIZE);
 308 }
292 bus_space_unmap(dc->dc_iot, dc->dc_ioh, IGS_REG_SIZE); 309 bus_space_unmap(dc->dc_iot, dc->dc_ioh, IGS_REG_SIZE);
293 printf("unable to map framebuffer\n"); 310 printf("unable to map framebuffer\n");
294 return 1; 311 return 1;
295 } 312 }
296 313
297 igsfb_init_cmap(dc); 314 igsfb_init_cmap(dc);
298 315
299 /* 316 /*
300 * 1KB for cursor sprite data at the very end of the video memory. 317 * 1KB for cursor sprite data at the very end of the video memory.
301 */ 318 */
302 croffset = dc->dc_vmemsz - IGS_CURSOR_DATA_SIZE; 319 croffset = dc->dc_vmemsz - IGS_CURSOR_DATA_SIZE;
303 craddr = fbaddr + croffset; 320 craddr = fbaddr + croffset;
304 if (bus_space_map(dc->dc_memt, craddr, IGS_CURSOR_DATA_SIZE, 321 if (bus_space_map(dc->dc_memt, craddr, IGS_CURSOR_DATA_SIZE,
305 dc->dc_memflags | BUS_SPACE_MAP_LINEAR, 322 dc->dc_memflags | BUS_SPACE_MAP_LINEAR,
306 &dc->dc_crh) != 0) 323 &dc->dc_crh) != 0)
307 { 324 {
 325 if (dc->dc_id >= 0x2000) { /* XXX */
 326 bus_space_unmap(dc->dc_iot, dc->dc_coph, IGS_COP_SIZE);
 327 }
308 bus_space_unmap(dc->dc_iot, dc->dc_ioh, IGS_REG_SIZE); 328 bus_space_unmap(dc->dc_iot, dc->dc_ioh, IGS_REG_SIZE);
309 bus_space_unmap(dc->dc_memt, dc->dc_fbh, dc->dc_fbsz); 329 bus_space_unmap(dc->dc_memt, dc->dc_fbh, dc->dc_fbsz);
310 printf("unable to map cursor sprite region\n"); 330 printf("unable to map cursor sprite region\n");
311 return 1; 331 return 1;
312 } 332 }
313 333
314 /* 334 /*
315 * Tell the device where cursor sprite data are located in the 335 * Tell the device where cursor sprite data are located in the
316 * linear space (it takes data offset in 1KB units). 336 * linear space (it takes data offset in 1KB units).
317 */ 337 */
318 croffset >>= 10; /* bytes -> kilobytes */ 338 croffset >>= 10; /* bytes -> kilobytes */
319 igs_ext_write(dc->dc_iot, dc->dc_ioh, 339 igs_ext_write(dc->dc_iot, dc->dc_ioh,
320 IGS_EXT_SPRITE_DATA_LO, croffset & 0xff); 340 IGS_EXT_SPRITE_DATA_LO, croffset & 0xff);
321 igs_ext_write(dc->dc_iot, dc->dc_ioh, 341 igs_ext_write(dc->dc_iot, dc->dc_ioh,
322 IGS_EXT_SPRITE_DATA_HI, (croffset >> 8) & 0xf); 342 IGS_EXT_SPRITE_DATA_HI, (croffset >> 8) & 0xf);
323 343
324 /* init the bit expansion table for cursor sprite data conversion */ 344 /* init the bit expansion table for cursor sprite data conversion */
325 igsfb_init_bit_table(dc); 345 igsfb_init_bit_table(dc);
326 346
327 /* XXX: fill dc_cursor and use igsfb_update_cursor() instead? */ 347 /* XXX: fill dc_cursor and use igsfb_update_cursor() instead? */
328 memset(&dc->dc_cursor, 0, sizeof(struct igs_hwcursor)); 348 memset(&dc->dc_cursor, 0, sizeof(struct igs_hwcursor));
329 va = bus_space_vaddr(dc->dc_memt, dc->dc_crh); 349 va = bus_space_vaddr(dc->dc_memt, dc->dc_crh);
330 memset(va, /* transparent */ 0xaa, IGS_CURSOR_DATA_SIZE); 350 memset(va, /* transparent */ 0xaa, IGS_CURSOR_DATA_SIZE);
331 351
332 curctl = igs_ext_read(dc->dc_iot, dc->dc_ioh, IGS_EXT_SPRITE_CTL); 352 curctl = igs_ext_read(dc->dc_iot, dc->dc_ioh, IGS_EXT_SPRITE_CTL);
333 curctl |= IGS_EXT_SPRITE_64x64; 353 curctl |= IGS_EXT_SPRITE_64x64;
334 curctl &= ~IGS_EXT_SPRITE_VISIBLE; 354 curctl &= ~IGS_EXT_SPRITE_VISIBLE;
335 igs_ext_write(dc->dc_iot, dc->dc_ioh, IGS_EXT_SPRITE_CTL, curctl); 355 igs_ext_write(dc->dc_iot, dc->dc_ioh, IGS_EXT_SPRITE_CTL, curctl);
336 dc->dc_curenb = 0; 356 dc->dc_curenb = 0;
337 357
338 /* 358 /*
339 * Map and init graphic coprocessor for accelerated rasops. 359 * Init graphic coprocessor for accelerated rasops.
340 */ 360 */
341 if (dc->dc_id >= 0x2000) { /* XXX */ 361 if (dc->dc_id >= 0x2000) { /* XXX */
342 if (bus_space_map(dc->dc_iot, 
343 dc->dc_iobase + IGS_COP_BASE_B, IGS_COP_SIZE, 
344 dc->dc_ioflags, 
345 &dc->dc_coph) != 0) 
346 { 
347 printf("unable to map COP registers\n"); 
348 return 1; 
349 } 
350 
351 /* XXX: hardcoded 8bpp */ 362 /* XXX: hardcoded 8bpp */
352 bus_space_write_2(dc->dc_iot, dc->dc_coph, 363 bus_space_write_2(dc->dc_iot, dc->dc_coph,
353 IGS_COP_SRC_MAP_WIDTH_REG, 364 IGS_COP_SRC_MAP_WIDTH_REG,
354 dc->dc_width - 1); 365 dc->dc_width - 1);
355 bus_space_write_2(dc->dc_iot, dc->dc_coph, 366 bus_space_write_2(dc->dc_iot, dc->dc_coph,
356 IGS_COP_DST_MAP_WIDTH_REG, 367 IGS_COP_DST_MAP_WIDTH_REG,
357 dc->dc_width - 1); 368 dc->dc_width - 1);
358 369
359 bus_space_write_1(dc->dc_iot, dc->dc_coph, 370 bus_space_write_1(dc->dc_iot, dc->dc_coph,
360 IGS_COP_MAP_FMT_REG, 371 IGS_COP_MAP_FMT_REG,
361 IGS_COP_MAP_8BPP); 372 IGS_COP_MAP_8BPP);
362 } 373 }
363 374
364 /* make sure screen is not blanked */ 375 /* make sure screen is not blanked */
365 dc->dc_blanked = 0; 376 dc->dc_blanked = 0;
366 igsfb_blank_screen(dc, dc->dc_blanked); 377 igsfb_blank_screen(dc, dc->dc_blanked);
367 378
368 return 0; 379 return 0;
369} 380}
370 381
371 382
372static void 383static void
373igsfb_init_cmap(struct igsfb_devconfig *dc) 384igsfb_init_cmap(struct igsfb_devconfig *dc)
374{ 385{
375 bus_space_tag_t iot = dc->dc_iot; 386 bus_space_tag_t iot = dc->dc_iot;
376 bus_space_handle_t ioh = dc->dc_ioh; 387 bus_space_handle_t ioh = dc->dc_ioh;
377 const uint8_t *p; 388 const uint8_t *p;
378 int i; 389 int i;
379 390
380 p = rasops_cmap; /* "ANSI" color map */ 391 p = rasops_cmap; /* "ANSI" color map */
381 392
382 /* init software copy */ 393 /* init software copy */
383 for (i = 0; i < IGS_CMAP_SIZE; ++i, p += 3) { 394 for (i = 0; i < IGS_CMAP_SIZE; ++i, p += 3) {
384 dc->dc_cmap.r[i] = p[0]; 395 dc->dc_cmap.r[i] = p[0];
385 dc->dc_cmap.g[i] = p[1]; 396 dc->dc_cmap.g[i] = p[1];
386 dc->dc_cmap.b[i] = p[2]; 397 dc->dc_cmap.b[i] = p[2];
387 } 398 }
388 399
389 /* propagate to the device */ 400 /* propagate to the device */
390 igsfb_update_cmap(dc, 0, IGS_CMAP_SIZE); 401 igsfb_update_cmap(dc, 0, IGS_CMAP_SIZE);
391 402
392 /* set overscan color */ 403 /* set overscan color */
393 p = &rasops_cmap[WSDISPLAY_BORDER_COLOR * 3]; 404 p = &rasops_cmap[WSDISPLAY_BORDER_COLOR * 3];
394 igs_ext_write(iot, ioh, IGS_EXT_OVERSCAN_RED, p[0]); 405 igs_ext_write(iot, ioh, IGS_EXT_OVERSCAN_RED, p[0]);
395 igs_ext_write(iot, ioh, IGS_EXT_OVERSCAN_GREEN, p[1]); 406 igs_ext_write(iot, ioh, IGS_EXT_OVERSCAN_GREEN, p[1]);
396 igs_ext_write(iot, ioh, IGS_EXT_OVERSCAN_BLUE, p[2]); 407 igs_ext_write(iot, ioh, IGS_EXT_OVERSCAN_BLUE, p[2]);
397} 408}
398 409
399 410
400static void 411static void
401igsfb_init_wsdisplay(void *cookie, struct vcons_screen *scr, int existing, 412igsfb_init_wsdisplay(void *cookie, struct vcons_screen *scr, int existing,
402 long *defattr) 413 long *defattr)
403{ 414{
404 struct igsfb_devconfig *dc = cookie; 415 struct igsfb_devconfig *dc = cookie;
405 struct rasops_info *ri = &scr->scr_ri; 416 struct rasops_info *ri = &scr->scr_ri;
406 int wsfcookie; 417 int wsfcookie;
407 418
408 if (scr == &dc->dc_console) { 419 if (scr == &dc->dc_console) {
409 if (ri->ri_flg == 0) { 420 if (ri->ri_flg == 0) {
410 /* first time, need to set RI_NO_AUTO */ 421 /* first time, need to set RI_NO_AUTO */
411 ri->ri_flg |= RI_NO_AUTO; 422 ri->ri_flg |= RI_NO_AUTO;
412 } else { 423 } else {
413 /* clear it on 2nd run */ 424 /* clear it on 2nd run */
414 ri->ri_flg &= ~RI_NO_AUTO; 425 ri->ri_flg &= ~RI_NO_AUTO;
415 } 426 }
416 } 427 }
417 ri->ri_flg |= RI_CENTER | RI_FULLCLEAR; 428 ri->ri_flg |= RI_CENTER | RI_FULLCLEAR;
418 429
419 if (IGSFB_HW_SOFT_BSWAP(dc)) 430 if (IGSFB_HW_SOFT_BSWAP(dc))
420 ri->ri_flg |= RI_BSWAP; 431 ri->ri_flg |= RI_BSWAP;
421 432
422 ri->ri_depth = dc->dc_depth; 433 ri->ri_depth = dc->dc_depth;
423 ri->ri_width = dc->dc_width; 434 ri->ri_width = dc->dc_width;
424 ri->ri_height = dc->dc_height; 435 ri->ri_height = dc->dc_height;
425 ri->ri_stride = dc->dc_stride; 436 ri->ri_stride = dc->dc_stride;
426 ri->ri_bits = bus_space_vaddr(dc->dc_memt, dc->dc_fbh); 437 ri->ri_bits = bus_space_vaddr(dc->dc_memt, dc->dc_fbh);
427 438
428 /* 439 /*
429 * Initialize wsfont related stuff. 440 * Initialize wsfont related stuff.
430 */ 441 */
431 wsfont_init(); 442 wsfont_init();
432 443
433 /* prefer gallant that is identical to the one the prom uses */ 444 /* prefer gallant that is identical to the one the prom uses */
434 wsfcookie = wsfont_find("Gallant", 12, 22, 0, 445 wsfcookie = wsfont_find("Gallant", 12, 22, 0,
435 WSDISPLAY_FONTORDER_L2R, 446 WSDISPLAY_FONTORDER_L2R,
436 WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP); 447 WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP);
437 if (wsfcookie <= 0) { 448 if (wsfcookie <= 0) {
438#ifdef DIAGNOSTIC 449#ifdef DIAGNOSTIC
439 printf("unable to find font Gallant 12x22\n"); 450 printf("unable to find font Gallant 12x22\n");
440#endif 451#endif
441 wsfcookie = wsfont_find(NULL, 0, 0, 0, /* any font at all? */ 452 wsfcookie = wsfont_find(NULL, 0, 0, 0, /* any font at all? */
442 WSDISPLAY_FONTORDER_L2R, 453 WSDISPLAY_FONTORDER_L2R,
443 WSDISPLAY_FONTORDER_L2R, 454 WSDISPLAY_FONTORDER_L2R,
444 WSFONT_FIND_BITMAP); 455 WSFONT_FIND_BITMAP);
445 } 456 }
446 457
447 if (wsfcookie <= 0) { 458 if (wsfcookie <= 0) {
448 printf("unable to find any fonts\n"); 459 printf("unable to find any fonts\n");
449 return; 460 return;
450 } 461 }
451 462
452 if (wsfont_lock(wsfcookie, &ri->ri_font) != 0) { 463 if (wsfont_lock(wsfcookie, &ri->ri_font) != 0) {
453 printf("unable to lock font\n"); 464 printf("unable to lock font\n");
454 return; 465 return;
455 } 466 }
456 ri->ri_wsfcookie = wsfcookie; 467 ri->ri_wsfcookie = wsfcookie;
457 468
458 469
459 /* XXX: TODO: compute term size based on font dimensions? */ 470 /* XXX: TODO: compute term size based on font dimensions? */
460 rasops_init(ri, 0, 0); 471 rasops_init(ri, 0, 0);
461 rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight, 472 rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
462 ri->ri_width / ri->ri_font->fontwidth); 473 ri->ri_width / ri->ri_font->fontwidth);
463 474
464 475
465 /* use the sprite for the text mode cursor */ 476 /* use the sprite for the text mode cursor */
466 igsfb_make_text_cursor(dc, scr); 477 igsfb_make_text_cursor(dc, scr);
467 478
468 /* the cursor is "busy" while we are in the text mode */ 479 /* the cursor is "busy" while we are in the text mode */
469 dc->dc_hwflags |= IGSFB_HW_TEXT_CURSOR; 480 dc->dc_hwflags |= IGSFB_HW_TEXT_CURSOR;
470 481
471 /* propagate sprite data to the device */ 482 /* propagate sprite data to the device */
472 igsfb_update_cursor(dc, WSDISPLAY_CURSOR_DOSHAPE); 483 igsfb_update_cursor(dc, WSDISPLAY_CURSOR_DOSHAPE);
473 484
474 /* accelerated text cursor */ 485 /* accelerated text cursor */
475 ri->ri_ops.cursor = igsfb_accel_cursor; 486 ri->ri_ops.cursor = igsfb_accel_cursor;
476 487
477 if (dc->dc_id >= 0x2000) { /* XXX */ 488 if (dc->dc_id >= 0x2000) { /* XXX */
478 /* accelerated erase/copy */ 489 /* accelerated erase/copy */
479 ri->ri_ops.copycols = igsfb_accel_copycols; 490 ri->ri_ops.copycols = igsfb_accel_copycols;
480 ri->ri_ops.erasecols = igsfb_accel_erasecols; 491 ri->ri_ops.erasecols = igsfb_accel_erasecols;
481 ri->ri_ops.copyrows = igsfb_accel_copyrows; 492 ri->ri_ops.copyrows = igsfb_accel_copyrows;
482 ri->ri_ops.eraserows = igsfb_accel_eraserows; 493 ri->ri_ops.eraserows = igsfb_accel_eraserows;
483 494
484 /* putchar hook to sync with the cop */ 495 /* putchar hook to sync with the cop */
485 dc->dc_ri_putchar = ri->ri_ops.putchar; 496 dc->dc_ri_putchar = ri->ri_ops.putchar;
486 ri->ri_ops.putchar = igsfb_accel_putchar; 497 ri->ri_ops.putchar = igsfb_accel_putchar;
487 } 498 }
488 499
489 igsfb_stdscreen.nrows = ri->ri_rows; 500 igsfb_stdscreen.nrows = ri->ri_rows;
490 igsfb_stdscreen.ncols = ri->ri_cols; 501 igsfb_stdscreen.ncols = ri->ri_cols;
491 igsfb_stdscreen.textops = &ri->ri_ops; 502 igsfb_stdscreen.textops = &ri->ri_ops;
492 igsfb_stdscreen.capabilities = ri->ri_caps; 503 igsfb_stdscreen.capabilities = ri->ri_caps;
493} 504}
494 505
495 506
496/* 507/*
497 * Init cursor data in dc_cursor for the accelerated text cursor. 508 * Init cursor data in dc_cursor for the accelerated text cursor.
498 */ 509 */
499static int 510static int
500igsfb_make_text_cursor(struct igsfb_devconfig *dc, struct vcons_screen *scr) 511igsfb_make_text_cursor(struct igsfb_devconfig *dc, struct vcons_screen *scr)
501{ 512{
502 struct rasops_info *ri = &scr->scr_ri; 513 struct rasops_info *ri = &scr->scr_ri;
503 struct wsdisplay_font *f = ri->ri_font; 514 struct wsdisplay_font *f = ri->ri_font;
504 uint16_t cc_scan[8]; /* one sprite scanline */ 515 uint16_t cc_scan[8]; /* one sprite scanline */
505 uint16_t s; 516 uint16_t s;
506 int w, i; 517 int w, i;
507 518
508 KASSERT(f->fontwidth <= IGS_CURSOR_MAX_SIZE); 519 KASSERT(f->fontwidth <= IGS_CURSOR_MAX_SIZE);
509 KASSERT(f->fontheight <= IGS_CURSOR_MAX_SIZE); 520 KASSERT(f->fontheight <= IGS_CURSOR_MAX_SIZE);
510 521
511 w = f->fontwidth; 522 w = f->fontwidth;
512 for (i = 0; i < f->stride; ++i) { 523 for (i = 0; i < f->stride; ++i) {
513 if (w >= 8) { 524 if (w >= 8) {
514 s = 0xffff; /* all inverted */ 525 s = 0xffff; /* all inverted */
515 w -= 8; 526 w -= 8;
516 } else { 527 } else {
517 /* first w pixels inverted, the rest is transparent */ 528 /* first w pixels inverted, the rest is transparent */
518 s = ~(0x5555 << (w * 2)); 529 s = ~(0x5555 << (w * 2));
519 s = htole16(s); 530 s = htole16(s);
520 w = 0; 531 w = 0;
521 } 532 }
522 cc_scan[i] = s; 533 cc_scan[i] = s;
523 } 534 }
524 535
525 dc->dc_cursor.cc_size.x = f->fontwidth; 536 dc->dc_cursor.cc_size.x = f->fontwidth;
526 dc->dc_cursor.cc_size.y = f->fontheight; 537 dc->dc_cursor.cc_size.y = f->fontheight;
527 538
528 dc->dc_cursor.cc_hot.x = 0; 539 dc->dc_cursor.cc_hot.x = 0;
529 dc->dc_cursor.cc_hot.y = 0; 540 dc->dc_cursor.cc_hot.y = 0;
530 541
531 /* init sprite array to be all transparent */ 542 /* init sprite array to be all transparent */
532 memset(dc->dc_cursor.cc_sprite, 0xaa, IGS_CURSOR_DATA_SIZE); 543 memset(dc->dc_cursor.cc_sprite, 0xaa, IGS_CURSOR_DATA_SIZE);
533 544
534 for (i = 0; i < f->fontheight; ++i) 545 for (i = 0; i < f->fontheight; ++i)
535 memcpy(&dc->dc_cursor.cc_sprite[i * 8], 546 memcpy(&dc->dc_cursor.cc_sprite[i * 8],
536 cc_scan, f->stride * sizeof(uint16_t)); 547 cc_scan, f->stride * sizeof(uint16_t));
537 548
538 return 0; 549 return 0;
539} 550}
540 551
541 552
542/* 553/*
543 * Spread a byte (abcd.efgh) into two (0a0b.0c0d 0e0f.0g0h). 554 * Spread a byte (abcd.efgh) into two (0a0b.0c0d 0e0f.0g0h).
544 * Helper function for igsfb_init_bit_table(). 555 * Helper function for igsfb_init_bit_table().
545 */ 556 */
546static uint16_t 557static uint16_t
547igsfb_spread_bits_8(uint8_t b) 558igsfb_spread_bits_8(uint8_t b)
548{ 559{
549 uint16_t s = b; 560 uint16_t s = b;
550 561
551 s = ((s & 0x00f0) << 4) | (s & 0x000f); 562 s = ((s & 0x00f0) << 4) | (s & 0x000f);
552 s = ((s & 0x0c0c) << 2) | (s & 0x0303); 563 s = ((s & 0x0c0c) << 2) | (s & 0x0303);
553 s = ((s & 0x2222) << 1) | (s & 0x1111); 564 s = ((s & 0x2222) << 1) | (s & 0x1111);
554 return s; 565 return s;
555} 566}
556 567
557 568
558/* 569/*
559 * Cursor sprite data are in 2bpp. Incoming image/mask are in 1bpp. 570 * Cursor sprite data are in 2bpp. Incoming image/mask are in 1bpp.
560 * Prebuild the table to expand 1bpp->2bpp, with bswapping if necessary. 571 * Prebuild the table to expand 1bpp->2bpp, with bswapping if necessary.
561 */ 572 */
562static void 573static void
563igsfb_init_bit_table(struct igsfb_devconfig *dc) 574igsfb_init_bit_table(struct igsfb_devconfig *dc)
564{ 575{
565 uint16_t *expand = dc->dc_bexpand; 576 uint16_t *expand = dc->dc_bexpand;
566 uint16_t s; 577 uint16_t s;
567 u_int i; 578 u_int i;
568 579
569 for (i = 0; i < 256; ++i) { 580 for (i = 0; i < 256; ++i) {
570 s = igsfb_spread_bits_8(i); 581 s = igsfb_spread_bits_8(i);
571 expand[i] = htole16(s); 582 expand[i] = htole16(s);
572 } 583 }
573} 584}
574 585
575 586
576/* 587/*
577 * wsdisplay_accessops: mmap() 588 * wsdisplay_accessops: mmap()
578 * XXX: security considerations for allowing mmapping i/o mapped i/o regs? 589 * XXX: security considerations for allowing mmapping i/o mapped i/o regs?
579 */ 590 */
580static paddr_t 591static paddr_t
581igsfb_mmap(void *v, void *vs, off_t offset, int prot) 592igsfb_mmap(void *v, void *vs, off_t offset, int prot)
582{ 593{
583 struct vcons_data *vd = v; 594 struct vcons_data *vd = v;
584 struct igsfb_devconfig *dc = vd->cookie; 595 struct igsfb_devconfig *dc = vd->cookie;
585 596
586 if (offset < dc->dc_memsz && offset >= 0) 597 if (offset < dc->dc_memsz && offset >= 0)
587 return bus_space_mmap(dc->dc_memt, dc->dc_memaddr, offset, 598 return bus_space_mmap(dc->dc_memt, dc->dc_memaddr, offset,
588 prot, dc->dc_memflags | BUS_SPACE_MAP_LINEAR); 599 prot, dc->dc_memflags | BUS_SPACE_MAP_LINEAR);
589 if (dc->dc_mmap) 600 if (dc->dc_mmap)
590 return dc->dc_mmap(v, vs, offset, prot); 601 return dc->dc_mmap(v, vs, offset, prot);
591 return -1; 602 return -1;
592} 603}
593 604
594 605
595/* 606/*
596 * wsdisplay_accessops: ioctl() 607 * wsdisplay_accessops: ioctl()
597 */ 608 */
598static int 609static int
599igsfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 610igsfb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
600 struct lwp *l) 611 struct lwp *l)
601{ 612{
602 struct vcons_data *vd = v; 613 struct vcons_data *vd = v;
603 struct igsfb_devconfig *dc = vd->cookie; 614 struct igsfb_devconfig *dc = vd->cookie;
604 int cursor_busy; 615 int cursor_busy;
605 int turnoff; 616 int turnoff;
606 617
607 /* don't permit cursor ioctls if we use sprite for text cursor */ 618 /* don't permit cursor ioctls if we use sprite for text cursor */
608 cursor_busy = !dc->dc_mapped 619 cursor_busy = !dc->dc_mapped
609 && (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR); 620 && (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR);
610 621
611 switch (cmd) { 622 switch (cmd) {
612 623
613 case WSDISPLAYIO_GTYPE: 624 case WSDISPLAYIO_GTYPE:
614 *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; 625 *(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
615 return 0; 626 return 0;
616 627
617 case WSDISPLAYIO_GINFO: 628 case WSDISPLAYIO_GINFO:
618#define wsd_fbip ((struct wsdisplay_fbinfo *)data) 629#define wsd_fbip ((struct wsdisplay_fbinfo *)data)
619 wsd_fbip->height = dc->dc_height; 630 wsd_fbip->height = dc->dc_height;
620 wsd_fbip->width = dc->dc_width; 631 wsd_fbip->width = dc->dc_width;
621 wsd_fbip->depth = dc->dc_maxdepth; 632 wsd_fbip->depth = dc->dc_maxdepth;
622 wsd_fbip->cmsize = IGS_CMAP_SIZE; 633 wsd_fbip->cmsize = IGS_CMAP_SIZE;
623#undef wsd_fbip 634#undef wsd_fbip
624 return 0; 635 return 0;
625 636
626 case WSDISPLAYIO_LINEBYTES: 637 case WSDISPLAYIO_LINEBYTES:
627 *(int *)data = dc->dc_width * (dc->dc_maxdepth >> 3); 638 *(int *)data = dc->dc_width * (dc->dc_maxdepth >> 3);
628 return 0; 639 return 0;
629 640
630 case WSDISPLAYIO_SMODE: 641 case WSDISPLAYIO_SMODE:
631#define d (*(int *)data) 642#define d (*(int *)data)
632 if (d != WSDISPLAYIO_MODE_EMUL) { 643 if (d != WSDISPLAYIO_MODE_EMUL) {
633 dc->dc_mapped = 1; 644 dc->dc_mapped = 1;
634 /* turn off hardware cursor */ 645 /* turn off hardware cursor */
635 if (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR) { 646 if (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR) {
636 dc->dc_curenb = 0; 647 dc->dc_curenb = 0;
637 igsfb_update_cursor(dc, 648 igsfb_update_cursor(dc,
638 WSDISPLAY_CURSOR_DOCUR); 649 WSDISPLAY_CURSOR_DOCUR);
639 } 650 }
640 if ((dc->dc_mode != NULL) && (dc->dc_maxdepth != 8)) 651 if ((dc->dc_mode != NULL) && (dc->dc_maxdepth != 8))
641 igsfb_set_mode(dc, dc->dc_mode, 652 igsfb_set_mode(dc, dc->dc_mode,
642 dc->dc_maxdepth); 653 dc->dc_maxdepth);
643 } else { 654 } else {
644 dc->dc_mapped = 0; 655 dc->dc_mapped = 0;
645 if ((dc->dc_mode != NULL) && (dc->dc_maxdepth != 8)) 656 if ((dc->dc_mode != NULL) && (dc->dc_maxdepth != 8))
646 igsfb_set_mode(dc, dc->dc_mode, 8); 657 igsfb_set_mode(dc, dc->dc_mode, 8);
647 igsfb_init_cmap(dc); 658 igsfb_init_cmap(dc);
648 /* reinit sprite for text cursor */ 659 /* reinit sprite for text cursor */
649 if (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR) { 660 if (dc->dc_hwflags & IGSFB_HW_TEXT_CURSOR) {
650 igsfb_make_text_cursor(dc, dc->dc_vd.active); 661 igsfb_make_text_cursor(dc, dc->dc_vd.active);
651 dc->dc_curenb = 0; 662 dc->dc_curenb = 0;
652 igsfb_update_cursor(dc, 663 igsfb_update_cursor(dc,
653 WSDISPLAY_CURSOR_DOSHAPE 664 WSDISPLAY_CURSOR_DOSHAPE
654 | WSDISPLAY_CURSOR_DOCUR); 665 | WSDISPLAY_CURSOR_DOCUR);
655 } 666 }
656 vcons_redraw_screen(vd->active); 667 vcons_redraw_screen(vd->active);
657 } 668 }
658 return 0; 669 return 0;
659 670
660 case WSDISPLAYIO_GVIDEO: 671 case WSDISPLAYIO_GVIDEO:
661 *(u_int *)data = dc->dc_blanked ? 672 *(u_int *)data = dc->dc_blanked ?
662 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON; 673 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
663 return 0; 674 return 0;
664 675
665 case WSDISPLAYIO_SVIDEO: 676 case WSDISPLAYIO_SVIDEO:
666 turnoff = (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF); 677 turnoff = (*(u_int *)data == WSDISPLAYIO_VIDEO_OFF);
667 if (dc->dc_blanked != turnoff) { 678 if (dc->dc_blanked != turnoff) {
668 dc->dc_blanked = turnoff; 679 dc->dc_blanked = turnoff;
669 igsfb_blank_screen(dc, dc->dc_blanked); 680 igsfb_blank_screen(dc, dc->dc_blanked);
670 } 681 }
671 return 0; 682 return 0;
672 683
673 case WSDISPLAYIO_GETCMAP: 684 case WSDISPLAYIO_GETCMAP:
674 return igsfb_get_cmap(dc, (struct wsdisplay_cmap *)data); 685 return igsfb_get_cmap(dc, (struct wsdisplay_cmap *)data);
675 686
676 case WSDISPLAYIO_PUTCMAP: 687 case WSDISPLAYIO_PUTCMAP:
677 return igsfb_set_cmap(dc, (struct wsdisplay_cmap *)data); 688 return igsfb_set_cmap(dc, (struct wsdisplay_cmap *)data);
678 689
679 case WSDISPLAYIO_GCURMAX: 690 case WSDISPLAYIO_GCURMAX:
680 ((struct wsdisplay_curpos *)data)->x = IGS_CURSOR_MAX_SIZE; 691 ((struct wsdisplay_curpos *)data)->x = IGS_CURSOR_MAX_SIZE;
681 ((struct wsdisplay_curpos *)data)->y = IGS_CURSOR_MAX_SIZE; 692 ((struct wsdisplay_curpos *)data)->y = IGS_CURSOR_MAX_SIZE;
682 return 0; 693 return 0;
683 694
684 case WSDISPLAYIO_GCURPOS: 695 case WSDISPLAYIO_GCURPOS:
685 if (cursor_busy) 696 if (cursor_busy)
686 return EBUSY; 697 return EBUSY;
687 *(struct wsdisplay_curpos *)data = dc->dc_cursor.cc_pos; 698 *(struct wsdisplay_curpos *)data = dc->dc_cursor.cc_pos;
688 return 0; 699 return 0;
689 700
690 case WSDISPLAYIO_SCURPOS: 701 case WSDISPLAYIO_SCURPOS:
691 if (cursor_busy) 702 if (cursor_busy)
692 return EBUSY; 703 return EBUSY;
693 igsfb_set_curpos(dc, (struct wsdisplay_curpos *)data); 704 igsfb_set_curpos(dc, (struct wsdisplay_curpos *)data);
694 return 0; 705 return 0;
695 706
696 case WSDISPLAYIO_GCURSOR: 707 case WSDISPLAYIO_GCURSOR:
697 if (cursor_busy) 708 if (cursor_busy)
698 return EBUSY; 709 return EBUSY;
699 return igsfb_get_cursor(dc, (struct wsdisplay_cursor *)data); 710 return igsfb_get_cursor(dc, (struct wsdisplay_cursor *)data);
700 711
701 case WSDISPLAYIO_SCURSOR: 712 case WSDISPLAYIO_SCURSOR:
702 if (cursor_busy) 713 if (cursor_busy)
703 return EBUSY; 714 return EBUSY;
704 return igsfb_set_cursor(dc, (struct wsdisplay_cursor *)data); 715 return igsfb_set_cursor(dc, (struct wsdisplay_cursor *)data);
705 } 716 }
706 717
707 return EPASSTHROUGH; 718 return EPASSTHROUGH;
708} 719}
709 720
710 721
711/* 722/*
712 * wsdisplay_accessops: ioctl(WSDISPLAYIO_SVIDEO) 723 * wsdisplay_accessops: ioctl(WSDISPLAYIO_SVIDEO)
713 */ 724 */
714static void 725static void
715igsfb_blank_screen(struct igsfb_devconfig *dc, int blank) 726igsfb_blank_screen(struct igsfb_devconfig *dc, int blank)
716{ 727{
717 728
718 igs_ext_write(dc->dc_iot, dc->dc_ioh, 729 igs_ext_write(dc->dc_iot, dc->dc_ioh,
719 IGS_EXT_SYNC_CTL, 730 IGS_EXT_SYNC_CTL,
720 blank ? IGS_EXT_SYNC_H0 | IGS_EXT_SYNC_V0 731 blank ? IGS_EXT_SYNC_H0 | IGS_EXT_SYNC_V0
721 : 0); 732 : 0);
722} 733}
723 734
724 735
725/* 736/*
726 * wsdisplay_accessops: ioctl(WSDISPLAYIO_GETCMAP) 737 * wsdisplay_accessops: ioctl(WSDISPLAYIO_GETCMAP)
727 * Served from the software cmap copy. 738 * Served from the software cmap copy.
728 */ 739 */
729static int 740static int
730igsfb_get_cmap(struct igsfb_devconfig *dc, struct wsdisplay_cmap *p) 741igsfb_get_cmap(struct igsfb_devconfig *dc, struct wsdisplay_cmap *p)
731{ 742{
732 u_int index, count; 743 u_int index, count;
733 int err; 744 int err;
734 745
735 index = p->index; 746 index = p->index;
736 count = p->count; 747 count = p->count;
737 748
738 if (index >= IGS_CMAP_SIZE || count > IGS_CMAP_SIZE - index) 749 if (index >= IGS_CMAP_SIZE || count > IGS_CMAP_SIZE - index)
739 return EINVAL; 750 return EINVAL;
740 751
741 err = copyout(&dc->dc_cmap.r[index], p->red, count); 752 err = copyout(&dc->dc_cmap.r[index], p->red, count);
742 if (err) 753 if (err)
743 return err; 754 return err;
744 err = copyout(&dc->dc_cmap.g[index], p->green, count); 755 err = copyout(&dc->dc_cmap.g[index], p->green, count);
745 if (err) 756 if (err)
746 return err; 757 return err;
747 err = copyout(&dc->dc_cmap.b[index], p->blue, count); 758 err = copyout(&dc->dc_cmap.b[index], p->blue, count);
748 if (err) 759 if (err)
749 return err; 760 return err;
750 761
751 return 0; 762 return 0;
752} 763}
753 764
754 765
755/* 766/*
756 * wsdisplay_accessops: ioctl(WSDISPLAYIO_PUTCMAP) 767 * wsdisplay_accessops: ioctl(WSDISPLAYIO_PUTCMAP)
757 * Set the software cmap copy and propagate changed range to the device. 768 * Set the software cmap copy and propagate changed range to the device.
758 */ 769 */
759static int 770static int
760igsfb_set_cmap(struct igsfb_devconfig *dc, const struct wsdisplay_cmap *p) 771igsfb_set_cmap(struct igsfb_devconfig *dc, const struct wsdisplay_cmap *p)
761{ 772{
762 u_int index, count; 773 u_int index, count;
763 uint8_t r[IGS_CMAP_SIZE]; 774 uint8_t r[IGS_CMAP_SIZE];
764 uint8_t g[IGS_CMAP_SIZE]; 775 uint8_t g[IGS_CMAP_SIZE];
765 uint8_t b[IGS_CMAP_SIZE]; 776 uint8_t b[IGS_CMAP_SIZE];
766 int error; 777 int error;
767 778
768 index = p->index; 779 index = p->index;
769 count = p->count; 780 count = p->count;
770 if (index >= IGS_CMAP_SIZE || count > IGS_CMAP_SIZE - index) 781 if (index >= IGS_CMAP_SIZE || count > IGS_CMAP_SIZE - index)
771 return EINVAL; 782 return EINVAL;
772 error = copyin(p->red, &r[index], count); 783 error = copyin(p->red, &r[index], count);
773 if (error) 784 if (error)
774 return error; 785 return error;
775 error = copyin(p->green, &g[index], count); 786 error = copyin(p->green, &g[index], count);
776 if (error) 787 if (error)
777 return error; 788 return error;
778 error = copyin(p->blue, &b[index], count); 789 error = copyin(p->blue, &b[index], count);
779 if (error) 790 if (error)
780 return error; 791 return error;
781 792
782 memcpy(&dc->dc_cmap.r[index], &r[index], count); 793 memcpy(&dc->dc_cmap.r[index], &r[index], count);
783 memcpy(&dc->dc_cmap.g[index], &g[index], count); 794 memcpy(&dc->dc_cmap.g[index], &g[index], count);
784 memcpy(&dc->dc_cmap.b[index], &b[index], count); 795 memcpy(&dc->dc_cmap.b[index], &b[index], count);
785 796
786 /* propagate changes to the device */ 797 /* propagate changes to the device */
787 igsfb_update_cmap(dc, index, count); 798 igsfb_update_cmap(dc, index, count);
788 return 0; 799 return 0;
789} 800}
790 801
791 802
792/* 803/*
793 * Propagate specified part of the software cmap copy to the device. 804 * Propagate specified part of the software cmap copy to the device.
794 */ 805 */
795static void 806static void
796igsfb_update_cmap(struct igsfb_devconfig *dc, u_int index, u_int count) 807igsfb_update_cmap(struct igsfb_devconfig *dc, u_int index, u_int count)
797{ 808{
798 bus_space_tag_t t; 809 bus_space_tag_t t;
799 bus_space_handle_t h; 810 bus_space_handle_t h;
800 u_int last, i; 811 u_int last, i;
801 812
802 if (index >= IGS_CMAP_SIZE) 813 if (index >= IGS_CMAP_SIZE)
803 return; 814 return;
804 815
805 last = index + count; 816 last = index + count;
806 if (last > IGS_CMAP_SIZE) 817 if (last > IGS_CMAP_SIZE)
807 last = IGS_CMAP_SIZE; 818 last = IGS_CMAP_SIZE;
808 819
809 t = dc->dc_iot; 820 t = dc->dc_iot;
810 h = dc->dc_ioh; 821 h = dc->dc_ioh;
811 822
812 /* start palette writing, index is autoincremented by hardware */ 823 /* start palette writing, index is autoincremented by hardware */
813 bus_space_write_1(t, h, IGS_DAC_PEL_WRITE_IDX, index); 824 bus_space_write_1(t, h, IGS_DAC_PEL_WRITE_IDX, index);
814 825
815 for (i = index; i < last; ++i) { 826 for (i = index; i < last; ++i) {
816 bus_space_write_1(t, h, IGS_DAC_PEL_DATA, dc->dc_cmap.r[i]); 827 bus_space_write_1(t, h, IGS_DAC_PEL_DATA, dc->dc_cmap.r[i]);
817 bus_space_write_1(t, h, IGS_DAC_PEL_DATA, dc->dc_cmap.g[i]); 828 bus_space_write_1(t, h, IGS_DAC_PEL_DATA, dc->dc_cmap.g[i]);
818 bus_space_write_1(t, h, IGS_DAC_PEL_DATA, dc->dc_cmap.b[i]); 829 bus_space_write_1(t, h, IGS_DAC_PEL_DATA, dc->dc_cmap.b[i]);
819 } 830 }
820} 831}
821 832
822 833
823/* 834/*
824 * wsdisplay_accessops: ioctl(WSDISPLAYIO_SCURPOS) 835 * wsdisplay_accessops: ioctl(WSDISPLAYIO_SCURPOS)
825 */ 836 */
826static void 837static void
827igsfb_set_curpos(struct igsfb_devconfig *dc, 838igsfb_set_curpos(struct igsfb_devconfig *dc,
828 const struct wsdisplay_curpos *curpos) 839 const struct wsdisplay_curpos *curpos)
829{ 840{
830 struct rasops_info *ri = &dc->dc_vd.active->scr_ri; 841 struct rasops_info *ri = &dc->dc_vd.active->scr_ri;
831 u_int x = curpos->x, y = curpos->y; 842 u_int x = curpos->x, y = curpos->y;
832 843
833 if (x >= ri->ri_width) 844 if (x >= ri->ri_width)
834 x = ri->ri_width - 1; 845 x = ri->ri_width - 1;
835 if (y >= ri->ri_height) 846 if (y >= ri->ri_height)
836 y = ri->ri_height - 1; 847 y = ri->ri_height - 1;
837 848
838 dc->dc_cursor.cc_pos.x = x; 849 dc->dc_cursor.cc_pos.x = x;
839 dc->dc_cursor.cc_pos.y = y; 850 dc->dc_cursor.cc_pos.y = y;
840 851
841 /* propagate changes to the device */ 852 /* propagate changes to the device */
842 igsfb_update_curpos(dc); 853 igsfb_update_curpos(dc);
843} 854}
844 855
845 856
846static void 857static void
847igsfb_update_curpos(struct igsfb_devconfig *dc) 858igsfb_update_curpos(struct igsfb_devconfig *dc)
848{ 859{
849 bus_space_tag_t t; 860 bus_space_tag_t t;
850 bus_space_handle_t h; 861 bus_space_handle_t h;
851 int x, xoff, y, yoff; 862 int x, xoff, y, yoff;
852 863
853 xoff = 0; 864 xoff = 0;
854 x = dc->dc_cursor.cc_pos.x - dc->dc_cursor.cc_hot.x; 865 x = dc->dc_cursor.cc_pos.x - dc->dc_cursor.cc_hot.x;
855 if (x < 0) { 866 if (x < 0) {
856 xoff = -x; 867 xoff = -x;
857 x = 0; 868 x = 0;
858 } 869 }
859 870
860 yoff = 0; 871 yoff = 0;
861 y = dc->dc_cursor.cc_pos.y - dc->dc_cursor.cc_hot.y; 872 y = dc->dc_cursor.cc_pos.y - dc->dc_cursor.cc_hot.y;
862 if (y < 0) { 873 if (y < 0) {
863 yoff = -y; 874 yoff = -y;
864 y = 0; 875 y = 0;
865 } 876 }
866 877
867 t = dc->dc_iot; 878 t = dc->dc_iot;
868 h = dc->dc_ioh; 879 h = dc->dc_ioh;
869 880
870 igs_ext_write(t, h, IGS_EXT_SPRITE_HSTART_LO, x & 0xff); 881 igs_ext_write(t, h, IGS_EXT_SPRITE_HSTART_LO, x & 0xff);
871 igs_ext_write(t, h, IGS_EXT_SPRITE_HSTART_HI, (x >> 8) & 0x07); 882 igs_ext_write(t, h, IGS_EXT_SPRITE_HSTART_HI, (x >> 8) & 0x07);
872 igs_ext_write(t, h, IGS_EXT_SPRITE_HPRESET, xoff & 0x3f); 883 igs_ext_write(t, h, IGS_EXT_SPRITE_HPRESET, xoff & 0x3f);
873 884
874 igs_ext_write(t, h, IGS_EXT_SPRITE_VSTART_LO, y & 0xff); 885 igs_ext_write(t, h, IGS_EXT_SPRITE_VSTART_LO, y & 0xff);
875 igs_ext_write(t, h, IGS_EXT_SPRITE_VSTART_HI, (y >> 8) & 0x07); 886 igs_ext_write(t, h, IGS_EXT_SPRITE_VSTART_HI, (y >> 8) & 0x07);
876 igs_ext_write(t, h, IGS_EXT_SPRITE_VPRESET, yoff & 0x3f); 887 igs_ext_write(t, h, IGS_EXT_SPRITE_VPRESET, yoff & 0x3f);
877} 888}
878 889
879 890
880/* 891/*
881 * wsdisplay_accessops: ioctl(WSDISPLAYIO_GCURSOR) 892 * wsdisplay_accessops: ioctl(WSDISPLAYIO_GCURSOR)
882 */ 893 */
883static int 894static int
884igsfb_get_cursor(struct igsfb_devconfig *dc, struct wsdisplay_cursor *p) 895igsfb_get_cursor(struct igsfb_devconfig *dc, struct wsdisplay_cursor *p)
885{ 896{
886 897
887 /* XXX: TODO */ 898 /* XXX: TODO */
888 return 0; 899 return 0;
889} 900}
890 901
891 902
892/* 903/*
893 * wsdisplay_accessops: ioctl(WSDISPLAYIO_SCURSOR) 904 * wsdisplay_accessops: ioctl(WSDISPLAYIO_SCURSOR)
894 */ 905 */
895static int 906static int
896igsfb_set_cursor(struct igsfb_devconfig *dc, const struct wsdisplay_cursor *p) 907igsfb_set_cursor(struct igsfb_devconfig *dc, const struct wsdisplay_cursor *p)
897{ 908{
898 struct igs_hwcursor *cc; 909 struct igs_hwcursor *cc;
899 struct wsdisplay_curpos pos, hot; 910 struct wsdisplay_curpos pos, hot;
900 u_int v, index, count, icount, iwidth; 911 u_int v, index, count, icount, iwidth;
901 uint8_t r[2], g[2], b[2], image[512], mask[512]; 912 uint8_t r[2], g[2], b[2], image[512], mask[512];
902 int error; 913 int error;
903 914
904 cc = &dc->dc_cursor; 915 cc = &dc->dc_cursor;
905 v = p->which; 916 v = p->which;
906 index = count = icount = iwidth = 0; /* XXX: gcc */ 917 index = count = icount = iwidth = 0; /* XXX: gcc */
907 pos.x = pos.y = 0; /* XXX: gcc */ 918 pos.x = pos.y = 0; /* XXX: gcc */
908 919
909 /* copy in the new cursor colormap */ 920 /* copy in the new cursor colormap */
910 if (v & WSDISPLAY_CURSOR_DOCMAP) { 921 if (v & WSDISPLAY_CURSOR_DOCMAP) {
911 index = p->cmap.index; 922 index = p->cmap.index;
912 count = p->cmap.count; 923 count = p->cmap.count;
913 if (index >= 2 || (index + count) > 2) 924 if (index >= 2 || (index + count) > 2)
914 return EINVAL; 925 return EINVAL;
915 error = copyin(p->cmap.red, &r[index], count); 926 error = copyin(p->cmap.red, &r[index], count);
916 if (error) 927 if (error)
917 return error; 928 return error;
918 error = copyin(p->cmap.green, &g[index], count); 929 error = copyin(p->cmap.green, &g[index], count);
919 if (error) 930 if (error)
920 return error; 931 return error;
921 error = copyin(p->cmap.blue, &b[index], count); 932 error = copyin(p->cmap.blue, &b[index], count);
922 if (error) 933 if (error)
923 return error; 934 return error;
924 } 935 }
925 936
926 /* verify that the new cursor data are valid */ 937 /* verify that the new cursor data are valid */
927 if (v & WSDISPLAY_CURSOR_DOSHAPE) { 938 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
928 if (p->size.x > IGS_CURSOR_MAX_SIZE 939 if (p->size.x > IGS_CURSOR_MAX_SIZE
929 || p->size.y > IGS_CURSOR_MAX_SIZE) 940 || p->size.y > IGS_CURSOR_MAX_SIZE)
930 return EINVAL; 941 return EINVAL;
931 942
932 iwidth = (p->size.x + 7) >> 3; /* bytes per scan line */ 943 iwidth = (p->size.x + 7) >> 3; /* bytes per scan line */
933 icount = iwidth * p->size.y; 944 icount = iwidth * p->size.y;
934 error = copyin(p->image, image, icount); 945 error = copyin(p->image, image, icount);
935 if (error) 946 if (error)
936 return error; 947 return error;
937 error = copyin(p->mask, mask, icount); 948 error = copyin(p->mask, mask, icount);
938 if (error) 949 if (error)
939 return error; 950 return error;
940 } 951 }
941 952
942 /* enforce that the position is within screen bounds */ 953 /* enforce that the position is within screen bounds */
943 if (v & WSDISPLAY_CURSOR_DOPOS) { 954 if (v & WSDISPLAY_CURSOR_DOPOS) {
944 struct rasops_info *ri = &dc->dc_vd.active->scr_ri; 955 struct rasops_info *ri = &dc->dc_vd.active->scr_ri;
945 956
946 pos = p->pos; /* local copy we can write to */ 957 pos = p->pos; /* local copy we can write to */
947 if (pos.x >= ri->ri_width) 958 if (pos.x >= ri->ri_width)
948 pos.x = ri->ri_width - 1; 959 pos.x = ri->ri_width - 1;
949 if (pos.y >= ri->ri_height) 960 if (pos.y >= ri->ri_height)
950 pos.y = ri->ri_height - 1; 961 pos.y = ri->ri_height - 1;
951 } 962 }
952 963
953 /* enforce that the hot spot is within sprite bounds */ 964 /* enforce that the hot spot is within sprite bounds */
954 if (v & WSDISPLAY_CURSOR_DOHOT) 965 if (v & WSDISPLAY_CURSOR_DOHOT)
955 hot = p->hot; /* local copy we can write to */ 966 hot = p->hot; /* local copy we can write to */
956 967
957 if (v & (WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOSHAPE)) { 968 if (v & (WSDISPLAY_CURSOR_DOHOT | WSDISPLAY_CURSOR_DOSHAPE)) {
958 const struct wsdisplay_curpos *nsize; 969 const struct wsdisplay_curpos *nsize;
959 struct wsdisplay_curpos *nhot; 970 struct wsdisplay_curpos *nhot;
960 971
961 nsize = (v & WSDISPLAY_CURSOR_DOSHAPE) ? 972 nsize = (v & WSDISPLAY_CURSOR_DOSHAPE) ?
962 &p->size : &cc->cc_size; 973 &p->size : &cc->cc_size;
963 nhot = (v & WSDISPLAY_CURSOR_DOHOT) ? &hot : &cc->cc_hot; 974 nhot = (v & WSDISPLAY_CURSOR_DOHOT) ? &hot : &cc->cc_hot;
964 975
965 if (nhot->x >= nsize->x) 976 if (nhot->x >= nsize->x)
966 nhot->x = nsize->x - 1; 977 nhot->x = nsize->x - 1;
967 if (nhot->y >= nsize->y) 978 if (nhot->y >= nsize->y)
968 nhot->y = nsize->y - 1; 979 nhot->y = nsize->y - 1;
969 } 980 }
970 981
971 /* copy data to the driver's cursor info */ 982 /* copy data to the driver's cursor info */
972 if (v & WSDISPLAY_CURSOR_DOCUR) 983 if (v & WSDISPLAY_CURSOR_DOCUR)
973 dc->dc_curenb = p->enable; 984 dc->dc_curenb = p->enable;
974 if (v & WSDISPLAY_CURSOR_DOPOS) 985 if (v & WSDISPLAY_CURSOR_DOPOS)
975 cc->cc_pos = pos; /* local copy, possibly corrected */ 986 cc->cc_pos = pos; /* local copy, possibly corrected */
976 if (v & WSDISPLAY_CURSOR_DOHOT) 987 if (v & WSDISPLAY_CURSOR_DOHOT)
977 cc->cc_hot = hot; /* local copy, possibly corrected */ 988 cc->cc_hot = hot; /* local copy, possibly corrected */
978 if (v & WSDISPLAY_CURSOR_DOCMAP) { 989 if (v & WSDISPLAY_CURSOR_DOCMAP) {
979 memcpy(&cc->cc_color[index], &r[index], count); 990 memcpy(&cc->cc_color[index], &r[index], count);
980 memcpy(&cc->cc_color[index + 2], &g[index], count); 991 memcpy(&cc->cc_color[index + 2], &g[index], count);
981 memcpy(&cc->cc_color[index + 4], &b[index], count); 992 memcpy(&cc->cc_color[index + 4], &b[index], count);
982 } 993 }
983 if (v & WSDISPLAY_CURSOR_DOSHAPE) { 994 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
984 u_int trailing_bits; 995 u_int trailing_bits;
985 996
986 memcpy(cc->cc_image, image, icount); 997 memcpy(cc->cc_image, image, icount);
987 memcpy(cc->cc_mask, mask, icount); 998 memcpy(cc->cc_mask, mask, icount);
988 cc->cc_size = p->size; 999 cc->cc_size = p->size;
989 1000
990 /* clear trailing bits in the "partial" mask bytes */ 1001 /* clear trailing bits in the "partial" mask bytes */
991 trailing_bits = p->size.x & 0x07; 1002 trailing_bits = p->size.x & 0x07;
992 if (trailing_bits != 0) { 1003 if (trailing_bits != 0) {
993 const u_int cutmask = ~((~0) << trailing_bits); 1004 const u_int cutmask = ~((~0) << trailing_bits);
994 u_char *mp; 1005 u_char *mp;
995 u_int i; 1006 u_int i;
996 1007
997 mp = cc->cc_mask + iwidth - 1; 1008 mp = cc->cc_mask + iwidth - 1;
998 for (i = 0; i < p->size.y; ++i) { 1009 for (i = 0; i < p->size.y; ++i) {
999 *mp &= cutmask; 1010 *mp &= cutmask;
1000 mp += iwidth; 1011 mp += iwidth;
1001 } 1012 }
1002 } 1013 }
1003 igsfb_convert_cursor_data(dc, iwidth, p->size.y); 1014 igsfb_convert_cursor_data(dc, iwidth, p->size.y);
1004 } 1015 }
1005 1016
1006 /* propagate changes to the device */ 1017 /* propagate changes to the device */
1007 igsfb_update_cursor(dc, v); 1018 igsfb_update_cursor(dc, v);
1008 1019
1009 return 0; 1020 return 0;
1010} 1021}
1011 1022
1012 1023
1013/* 1024/*
1014 * Convert incoming 1bpp cursor image/mask into native 2bpp format. 1025 * Convert incoming 1bpp cursor image/mask into native 2bpp format.
1015 */ 1026 */
1016static void 1027static void
1017igsfb_convert_cursor_data(struct igsfb_devconfig *dc, 1028igsfb_convert_cursor_data(struct igsfb_devconfig *dc,
1018 u_int width, u_int height) 1029 u_int width, u_int height)
1019{ 1030{
1020 struct igs_hwcursor *cc = &dc->dc_cursor; 1031 struct igs_hwcursor *cc = &dc->dc_cursor;
1021 uint16_t *expand = dc->dc_bexpand; 1032 uint16_t *expand = dc->dc_bexpand;
1022 uint8_t *ip, *mp; 1033 uint8_t *ip, *mp;
1023 uint16_t is, ms, *dp; 1034 uint16_t is, ms, *dp;
1024 u_int line, i; 1035 u_int line, i;
1025 1036
1026 /* init sprite to be all transparent */ 1037 /* init sprite to be all transparent */
1027 memset(cc->cc_sprite, 0xaa, IGS_CURSOR_DATA_SIZE); 1038 memset(cc->cc_sprite, 0xaa, IGS_CURSOR_DATA_SIZE);
1028 1039
1029 /* first scanline */ 1040 /* first scanline */
1030 ip = cc->cc_image; 1041 ip = cc->cc_image;
1031 mp = cc->cc_mask; 1042 mp = cc->cc_mask;
1032 dp = cc->cc_sprite; 1043 dp = cc->cc_sprite;
1033 1044
1034 for (line = 0; line < height; ++line) { 1045 for (line = 0; line < height; ++line) {
1035 for (i = 0; i < width; ++i) { 1046 for (i = 0; i < width; ++i) {
1036 is = expand[ip[i]]; /* image: 0 -> 00, 1 -> 01 */ 1047 is = expand[ip[i]]; /* image: 0 -> 00, 1 -> 01 */
1037 ms = expand[mp[i]]; /* mask: 0 -> 00, 1 -> 11 */ 1048 ms = expand[mp[i]]; /* mask: 0 -> 00, 1 -> 11 */
1038 ms |= (ms << 1); 1049 ms |= (ms << 1);
1039 dp[i] = (0xaaaa & ~ms) | (is & ms); 1050 dp[i] = (0xaaaa & ~ms) | (is & ms);
1040 } 1051 }
1041 1052
1042 /* next scanline */ 1053 /* next scanline */
1043 ip += width; 1054 ip += width;
1044 mp += width; 1055 mp += width;
1045 dp += 8; /* 64 pixels, 2bpp, 8 pixels per short = 8 shorts */ 1056 dp += 8; /* 64 pixels, 2bpp, 8 pixels per short = 8 shorts */
1046 } 1057 }
1047} 1058}
1048 1059
1049 1060
1050/* 1061/*
1051 * Propagate cursor changes to the device. 1062 * Propagate cursor changes to the device.
1052 * "which" is composed of WSDISPLAY_CURSOR_DO* bits. 1063 * "which" is composed of WSDISPLAY_CURSOR_DO* bits.
1053 */ 1064 */
1054static void 1065static void
1055igsfb_update_cursor(struct igsfb_devconfig *dc, u_int which) 1066igsfb_update_cursor(struct igsfb_devconfig *dc, u_int which)
1056{ 1067{
1057 bus_space_tag_t iot = dc->dc_iot; 1068 bus_space_tag_t iot = dc->dc_iot;
1058 bus_space_handle_t ioh = dc->dc_ioh; 1069 bus_space_handle_t ioh = dc->dc_ioh;
1059 uint8_t curctl; 1070 uint8_t curctl;
1060 1071
1061 curctl = 0; /* XXX: gcc */ 1072 curctl = 0; /* XXX: gcc */
1062 1073
1063 /* 1074 /*
1064 * We will need to tweak sprite control register for cursor 1075 * We will need to tweak sprite control register for cursor
1065 * visibility and cursor color map manipulation. 1076 * visibility and cursor color map manipulation.
1066 */ 1077 */
1067 if (which & (WSDISPLAY_CURSOR_DOCUR | WSDISPLAY_CURSOR_DOCMAP)) { 1078 if (which & (WSDISPLAY_CURSOR_DOCUR | WSDISPLAY_CURSOR_DOCMAP)) {
1068 curctl = igs_ext_read(iot, ioh, IGS_EXT_SPRITE_CTL); 1079 curctl = igs_ext_read(iot, ioh, IGS_EXT_SPRITE_CTL);
1069 } 1080 }
1070 1081
1071 if (which & WSDISPLAY_CURSOR_DOSHAPE) { 1082 if (which & WSDISPLAY_CURSOR_DOSHAPE) {
1072 uint8_t *dst = bus_space_vaddr(dc->dc_memt, dc->dc_crh); 1083 uint8_t *dst = bus_space_vaddr(dc->dc_memt, dc->dc_crh);
1073 1084
1074 /* 1085 /*
1075 * memcpy between spaces of different endianness would 1086 * memcpy between spaces of different endianness would
1076 * be ... special. We cannot be sure if memcpy gonna 1087 * be ... special. We cannot be sure if memcpy gonna
1077 * push data in 4-byte chunks, we can't pre-bswap it, 1088 * push data in 4-byte chunks, we can't pre-bswap it,
1078 * so do it byte-by-byte to preserve byte ordering. 1089 * so do it byte-by-byte to preserve byte ordering.
1079 */ 1090 */
1080 if (IGSFB_HW_SOFT_BSWAP(dc)) { 1091 if (IGSFB_HW_SOFT_BSWAP(dc)) {
1081 uint8_t *src = (uint8_t *)dc->dc_cursor.cc_sprite; 1092 uint8_t *src = (uint8_t *)dc->dc_cursor.cc_sprite;
1082 int i; 1093 int i;
1083 1094
1084 for (i = 0; i < IGS_CURSOR_DATA_SIZE; ++i) 1095 for (i = 0; i < IGS_CURSOR_DATA_SIZE; ++i)
1085 *dst++ = *src++; 1096 *dst++ = *src++;
1086 } else { 1097 } else {
1087 memcpy(dst, dc->dc_cursor.cc_sprite, 1098 memcpy(dst, dc->dc_cursor.cc_sprite,
1088 IGS_CURSOR_DATA_SIZE); 1099 IGS_CURSOR_DATA_SIZE);
1089 } 1100 }
1090 } 1101 }
1091 1102
1092 if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) { 1103 if (which & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
1093 /* code shared with WSDISPLAYIO_SCURPOS */ 1104 /* code shared with WSDISPLAYIO_SCURPOS */
1094 igsfb_update_curpos(dc); 1105 igsfb_update_curpos(dc);
1095 } 1106 }
1096 1107
1097 if (which & WSDISPLAY_CURSOR_DOCMAP) { 1108 if (which & WSDISPLAY_CURSOR_DOCMAP) {
1098 uint8_t *p; 1109 uint8_t *p;
1099 1110
1100 /* tell DAC we want access to the cursor palette */ 1111 /* tell DAC we want access to the cursor palette */
1101 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, 1112 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL,
1102 curctl | IGS_EXT_SPRITE_DAC_PEL); 1113 curctl | IGS_EXT_SPRITE_DAC_PEL);
1103 1114
1104 p = dc->dc_cursor.cc_color; 1115 p = dc->dc_cursor.cc_color;
1105 1116
1106 bus_space_write_1(iot, ioh, IGS_DAC_PEL_WRITE_IDX, 0); 1117 bus_space_write_1(iot, ioh, IGS_DAC_PEL_WRITE_IDX, 0);
1107 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[0]); 1118 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[0]);
1108 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[2]); 1119 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[2]);
1109 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[4]); 1120 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[4]);
1110 1121
1111 bus_space_write_1(iot, ioh, IGS_DAC_PEL_WRITE_IDX, 1); 1122 bus_space_write_1(iot, ioh, IGS_DAC_PEL_WRITE_IDX, 1);
1112 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[1]); 1123 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[1]);
1113 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[3]); 1124 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[3]);
1114 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[5]); 1125 bus_space_write_1(iot, ioh, IGS_DAC_PEL_DATA, p[5]);
1115 1126
1116 /* restore access to the normal palette */ 1127 /* restore access to the normal palette */
1117 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, curctl); 1128 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, curctl);
1118 } 1129 }
1119 1130
1120 if (which & WSDISPLAY_CURSOR_DOCUR) { 1131 if (which & WSDISPLAY_CURSOR_DOCUR) {
1121 if ((curctl & IGS_EXT_SPRITE_VISIBLE) == 0 1132 if ((curctl & IGS_EXT_SPRITE_VISIBLE) == 0
1122 && dc->dc_curenb) 1133 && dc->dc_curenb)
1123 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, 1134 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL,
1124 curctl | IGS_EXT_SPRITE_VISIBLE); 1135 curctl | IGS_EXT_SPRITE_VISIBLE);
1125 else if ((curctl & IGS_EXT_SPRITE_VISIBLE) != 0 1136 else if ((curctl & IGS_EXT_SPRITE_VISIBLE) != 0
1126 && !dc->dc_curenb) 1137 && !dc->dc_curenb)
1127 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL, 1138 igs_ext_write(iot, ioh, IGS_EXT_SPRITE_CTL,
1128 curctl & ~IGS_EXT_SPRITE_VISIBLE); 1139 curctl & ~IGS_EXT_SPRITE_VISIBLE);
1129 } 1140 }
1130} 1141}
1131 1142
1132 1143
1133/* 1144/*
1134 * Accelerated text mode cursor that uses hardware sprite. 1145 * Accelerated text mode cursor that uses hardware sprite.
1135 */ 1146 */
1136static void 1147static void
1137igsfb_accel_cursor(void *cookie, int on, int row, int col) 1148igsfb_accel_cursor(void *cookie, int on, int row, int col)
1138{ 1149{
1139 struct rasops_info *ri = (struct rasops_info *)cookie; 1150 struct rasops_info *ri = (struct rasops_info *)cookie;
1140 struct vcons_screen *scr = ri->ri_hw; 1151 struct vcons_screen *scr = ri->ri_hw;
1141 struct igsfb_devconfig *dc = scr->scr_cookie; 1152 struct igsfb_devconfig *dc = scr->scr_cookie;
1142 struct igs_hwcursor *cc = &dc->dc_cursor; 1153 struct igs_hwcursor *cc = &dc->dc_cursor;
1143 u_int which; 1154 u_int which;
1144 1155
1145 ri->ri_crow = row; 1156 ri->ri_crow = row;
1146 ri->ri_ccol = col; 1157 ri->ri_ccol = col;
1147 1158
1148 which = 0; 1159 which = 0;
1149 if (on) { 1160 if (on) {
1150 ri->ri_flg |= RI_CURSOR; 1161 ri->ri_flg |= RI_CURSOR;
1151 1162
1152 /* only bother to move the cursor if it's visible */ 1163 /* only bother to move the cursor if it's visible */
1153 cc->cc_pos.x = ri->ri_xorigin 1164 cc->cc_pos.x = ri->ri_xorigin
1154 + ri->ri_ccol * ri->ri_font->fontwidth; 1165 + ri->ri_ccol * ri->ri_font->fontwidth;
1155 cc->cc_pos.y = ri->ri_yorigin 1166 cc->cc_pos.y = ri->ri_yorigin
1156 + ri->ri_crow * ri->ri_font->fontheight; 1167 + ri->ri_crow * ri->ri_font->fontheight;
1157 which |= WSDISPLAY_CURSOR_DOPOS; 1168 which |= WSDISPLAY_CURSOR_DOPOS;
1158 } else 1169 } else
1159 ri->ri_flg &= ~RI_CURSOR; 1170 ri->ri_flg &= ~RI_CURSOR;
1160 1171
1161 if (dc->dc_curenb != on) { 1172 if (dc->dc_curenb != on) {
1162 dc->dc_curenb = on; 1173 dc->dc_curenb = on;
1163 which |= WSDISPLAY_CURSOR_DOCUR; 1174 which |= WSDISPLAY_CURSOR_DOCUR;
1164 } 1175 }
1165 1176
1166 /* propagate changes to the device */ 1177 /* propagate changes to the device */
1167 igsfb_update_cursor(dc, which); 1178 igsfb_update_cursor(dc, which);
1168} 1179}
1169 1180
1170 1181
1171 1182
1172/* 1183/*
1173 * Accelerated raster ops that use graphic coprocessor. 1184 * Accelerated raster ops that use graphic coprocessor.
1174 */ 1185 */
1175 1186
1176static int 1187static int
1177igsfb_accel_wait(struct igsfb_devconfig *dc) 1188igsfb_accel_wait(struct igsfb_devconfig *dc)
1178{ 1189{
1179 bus_space_tag_t t = dc->dc_iot; 1190 bus_space_tag_t t = dc->dc_iot;
1180 bus_space_handle_t h = dc->dc_coph; 1191 bus_space_handle_t h = dc->dc_coph;
1181 int timo = 100000; 1192 int timo = 100000;
1182 uint8_t reg; 1193 uint8_t reg;
1183 1194
1184 bus_space_write_1(t, h, IGS_COP_MAP_FMT_REG, (dc->dc_depth >> 3) - 1); 1195 bus_space_write_1(t, h, IGS_COP_MAP_FMT_REG, (dc->dc_depth >> 3) - 1);
1185 while (timo--) { 1196 while (timo--) {
1186 reg = bus_space_read_1(t, h, IGS_COP_CTL_REG); 1197 reg = bus_space_read_1(t, h, IGS_COP_CTL_REG);
1187 if ((reg & IGS_COP_CTL_BUSY) == 0) 1198 if ((reg & IGS_COP_CTL_BUSY) == 0)
1188 return 0; 1199 return 0;
1189 } 1200 }
1190 1201
1191 return 1; 1202 return 1;
1192} 1203}
1193 1204
1194 1205
1195static void 1206static void
1196igsfb_accel_copy(struct igsfb_devconfig *dc, uint32_t src, uint32_t dst, 1207igsfb_accel_copy(struct igsfb_devconfig *dc, uint32_t src, uint32_t dst,
1197 uint16_t width, uint16_t height) 1208 uint16_t width, uint16_t height)
1198{ 1209{
1199 bus_space_tag_t t = dc->dc_iot; 1210 bus_space_tag_t t = dc->dc_iot;
1200 bus_space_handle_t h = dc->dc_coph; 1211 bus_space_handle_t h = dc->dc_coph;
1201 uint32_t toend; 1212 uint32_t toend;
1202 uint8_t drawcmd; 1213 uint8_t drawcmd;
1203 1214
1204 drawcmd = IGS_COP_DRAW_ALL; 1215 drawcmd = IGS_COP_DRAW_ALL;
1205 if (dst > src) { 1216 if (dst > src) {
1206 toend = dc->dc_vd.active->scr_ri.ri_width * (height - 1) + (width - 1); 1217 toend = dc->dc_vd.active->scr_ri.ri_width * (height - 1) + (width - 1);
1207 src += toend; 1218 src += toend;
1208 dst += toend; 1219 dst += toend;
1209 drawcmd |= IGS_COP_OCTANT_X_NEG | IGS_COP_OCTANT_Y_NEG; 1220 drawcmd |= IGS_COP_OCTANT_X_NEG | IGS_COP_OCTANT_Y_NEG;
1210 } 1221 }
1211 1222
1212 igsfb_accel_wait(dc); 1223 igsfb_accel_wait(dc);
1213 bus_space_write_1(t, h, IGS_COP_CTL_REG, 0); 1224 bus_space_write_1(t, h, IGS_COP_CTL_REG, 0);
1214 1225
1215 bus_space_write_1(t, h, IGS_COP_FG_MIX_REG, IGS_COP_MIX_S); 1226 bus_space_write_1(t, h, IGS_COP_FG_MIX_REG, IGS_COP_MIX_S);
1216 1227
1217 bus_space_write_2(t, h, IGS_COP_WIDTH_REG, width - 1); 1228 bus_space_write_2(t, h, IGS_COP_WIDTH_REG, width - 1);
1218 bus_space_write_2(t, h, IGS_COP_HEIGHT_REG, height - 1); 1229 bus_space_write_2(t, h, IGS_COP_HEIGHT_REG, height - 1);
1219 1230
1220 bus_space_write_4(t, h, IGS_COP_SRC_START_REG, src); 1231 bus_space_write_4(t, h, IGS_COP_SRC_START_REG, src);
1221 bus_space_write_4(t, h, IGS_COP_DST_START_REG, dst); 1232 bus_space_write_4(t, h, IGS_COP_DST_START_REG, dst);
1222 1233
1223 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_0_REG, drawcmd); 1234 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_0_REG, drawcmd);
1224 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_1_REG, IGS_COP_PPM_FIXED_FG); 1235 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_1_REG, IGS_COP_PPM_FIXED_FG);
1225 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_2_REG, 0); 1236 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_2_REG, 0);
1226 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_3_REG, 1237 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_3_REG,
1227 IGS_COP_OP_PXBLT | IGS_COP_OP_FG_FROM_SRC); 1238 IGS_COP_OP_PXBLT | IGS_COP_OP_FG_FROM_SRC);
1228} 1239}
1229 1240
1230 1241
1231static void 1242static void
1232igsfb_accel_fill(struct igsfb_devconfig *dc, uint32_t color, uint32_t dst, 1243igsfb_accel_fill(struct igsfb_devconfig *dc, uint32_t color, uint32_t dst,
1233 uint16_t width, uint16_t height) 1244 uint16_t width, uint16_t height)
1234{ 1245{
1235 bus_space_tag_t t = dc->dc_iot; 1246 bus_space_tag_t t = dc->dc_iot;
1236 bus_space_handle_t h = dc->dc_coph; 1247 bus_space_handle_t h = dc->dc_coph;
1237 1248
1238 igsfb_accel_wait(dc); 1249 igsfb_accel_wait(dc);
1239 bus_space_write_1(t, h, IGS_COP_CTL_REG, 0); 1250 bus_space_write_1(t, h, IGS_COP_CTL_REG, 0);
1240 1251
1241 bus_space_write_1(t, h, IGS_COP_FG_MIX_REG, IGS_COP_MIX_S); 1252 bus_space_write_1(t, h, IGS_COP_FG_MIX_REG, IGS_COP_MIX_S);
1242 1253
1243 bus_space_write_2(t, h, IGS_COP_WIDTH_REG, width - 1); 1254 bus_space_write_2(t, h, IGS_COP_WIDTH_REG, width - 1);
1244 bus_space_write_2(t, h, IGS_COP_HEIGHT_REG, height - 1); 1255 bus_space_write_2(t, h, IGS_COP_HEIGHT_REG, height - 1);
1245 1256
1246 bus_space_write_4(t, h, IGS_COP_DST_START_REG, dst); 1257 bus_space_write_4(t, h, IGS_COP_DST_START_REG, dst);
1247 bus_space_write_4(t, h, IGS_COP_FG_REG, color); 1258 bus_space_write_4(t, h, IGS_COP_FG_REG, color);
1248 1259
1249 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_0_REG, IGS_COP_DRAW_ALL); 1260 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_0_REG, IGS_COP_DRAW_ALL);
1250 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_1_REG, IGS_COP_PPM_FIXED_FG); 1261 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_1_REG, IGS_COP_PPM_FIXED_FG);
1251 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_2_REG, 0); 1262 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_2_REG, 0);
1252 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_3_REG, IGS_COP_OP_PXBLT); 1263 bus_space_write_1(t, h, IGS_COP_PIXEL_OP_3_REG, IGS_COP_OP_PXBLT);
1253} 1264}
1254 1265
1255 1266
1256static void 1267static void
1257igsfb_accel_copyrows(void *cookie, int src, int dst, int num) 1268igsfb_accel_copyrows(void *cookie, int src, int dst, int num)
1258{ 1269{
1259 struct rasops_info *ri = (struct rasops_info *)cookie; 1270 struct rasops_info *ri = (struct rasops_info *)cookie;
1260 struct vcons_screen *scr = ri->ri_hw; 1271 struct vcons_screen *scr = ri->ri_hw;
1261 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie; 1272 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie;
1262 uint32_t srp, dsp; 1273 uint32_t srp, dsp;
1263 uint16_t width, height; 1274 uint16_t width, height;
1264 1275
1265 width = ri->ri_emuwidth; 1276 width = ri->ri_emuwidth;
1266 height = num * ri->ri_font->fontheight; 1277 height = num * ri->ri_font->fontheight;
1267 1278
1268 srp = ri->ri_xorigin 1279 srp = ri->ri_xorigin
1269 + ri->ri_width * (ri->ri_yorigin 1280 + ri->ri_width * (ri->ri_yorigin
1270 + src * ri->ri_font->fontheight); 1281 + src * ri->ri_font->fontheight);
1271 dsp = ri->ri_xorigin 1282 dsp = ri->ri_xorigin
1272 + ri->ri_width * (ri->ri_yorigin 1283 + ri->ri_width * (ri->ri_yorigin
1273 + dst * ri->ri_font->fontheight); 1284 + dst * ri->ri_font->fontheight);
1274 1285
1275 igsfb_accel_copy(dc, srp, dsp, width, height); 1286 igsfb_accel_copy(dc, srp, dsp, width, height);
1276} 1287}
1277 1288
1278 1289
1279static void 1290static void
1280igsfb_accel_copycols(void *cookie, int row, int src, int dst, int num) 1291igsfb_accel_copycols(void *cookie, int row, int src, int dst, int num)
1281{ 1292{
1282 struct rasops_info *ri = (struct rasops_info *)cookie; 1293 struct rasops_info *ri = (struct rasops_info *)cookie;
1283 struct vcons_screen *scr = ri->ri_hw; 1294 struct vcons_screen *scr = ri->ri_hw;
1284 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie; 1295 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie;
1285 uint32_t rowp, srp, dsp; 1296 uint32_t rowp, srp, dsp;
1286 uint16_t width, height; 1297 uint16_t width, height;
1287 1298
1288 width = num * ri->ri_font->fontwidth; 1299 width = num * ri->ri_font->fontwidth;
1289 height = ri->ri_font->fontheight; 1300 height = ri->ri_font->fontheight;
1290 1301
1291 rowp = ri->ri_xorigin 1302 rowp = ri->ri_xorigin
1292 + ri->ri_width * (ri->ri_yorigin 1303 + ri->ri_width * (ri->ri_yorigin
1293 + row * ri->ri_font->fontheight); 1304 + row * ri->ri_font->fontheight);
1294 1305
1295 srp = rowp + src * ri->ri_font->fontwidth; 1306 srp = rowp + src * ri->ri_font->fontwidth;
1296 dsp = rowp + dst * ri->ri_font->fontwidth; 1307 dsp = rowp + dst * ri->ri_font->fontwidth;
1297 1308
1298 igsfb_accel_copy(dc, srp, dsp, width, height); 1309 igsfb_accel_copy(dc, srp, dsp, width, height);
1299} 1310}
1300 1311
1301 1312
1302static void 1313static void
1303igsfb_accel_eraserows(void *cookie, int row, int num, long attr) 1314igsfb_accel_eraserows(void *cookie, int row, int num, long attr)
1304{ 1315{
1305 struct rasops_info *ri = (struct rasops_info *)cookie; 1316 struct rasops_info *ri = (struct rasops_info *)cookie;
1306 struct vcons_screen *scr = ri->ri_hw; 1317 struct vcons_screen *scr = ri->ri_hw;
1307 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie; 1318 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie;
1308 uint32_t color; 1319 uint32_t color;
1309 uint32_t dsp; 1320 uint32_t dsp;
1310 uint16_t width, height; 1321 uint16_t width, height;
1311 1322
1312 if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) { 1323 if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
1313 width = ri->ri_width; 1324 width = ri->ri_width;
1314 height = ri->ri_height; 1325 height = ri->ri_height;
1315 dsp = 0; 1326 dsp = 0;
1316 } else { 1327 } else {
1317 width = ri->ri_emuwidth; 1328 width = ri->ri_emuwidth;
1318 height = num * ri->ri_font->fontheight; 1329 height = num * ri->ri_font->fontheight;
1319 1330
1320 dsp = ri->ri_xorigin 1331 dsp = ri->ri_xorigin
1321 + ri->ri_width * (ri->ri_yorigin 1332 + ri->ri_width * (ri->ri_yorigin
1322 + row * ri->ri_font->fontheight); 1333 + row * ri->ri_font->fontheight);
1323 } 1334 }
1324 1335
1325 /* XXX: we "know" the encoding that rasops' allocattr uses */ 1336 /* XXX: we "know" the encoding that rasops' allocattr uses */
1326 color = (attr >> 16) & 0xff; 1337 color = (attr >> 16) & 0xff;
1327 1338
1328 igsfb_accel_fill(dc, color, dsp, width, height); 1339 igsfb_accel_fill(dc, color, dsp, width, height);
1329} 1340}
1330 1341
1331 1342
1332static void 1343static void
1333igsfb_accel_erasecols(void *cookie, int row, int col, int num, long attr) 1344igsfb_accel_erasecols(void *cookie, int row, int col, int num, long attr)
1334{ 1345{
1335 struct rasops_info *ri = (struct rasops_info *)cookie; 1346 struct rasops_info *ri = (struct rasops_info *)cookie;
1336 struct vcons_screen *scr = ri->ri_hw; 1347 struct vcons_screen *scr = ri->ri_hw;
1337 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie; 1348 struct igsfb_devconfig *dc = (struct igsfb_devconfig *)scr->scr_cookie;
1338 uint32_t color; 1349 uint32_t color;
1339 uint32_t rowp, dsp; 1350 uint32_t rowp, dsp;
1340 uint16_t width, height; 1351 uint16_t width, height;
1341 1352
1342 width = num * ri->ri_font->fontwidth; 1353 width = num * ri->ri_font->fontwidth;
1343 height = ri->ri_font->fontheight; 1354 height = ri->ri_font->fontheight;
1344 1355
1345 rowp = ri->ri_xorigin 1356 rowp = ri->ri_xorigin
1346 + ri->ri_width * (ri->ri_yorigin 1357 + ri->ri_width * (ri->ri_yorigin
1347 + row * ri->ri_font->fontheight); 1358 + row * ri->ri_font->fontheight);
1348 1359
1349 dsp = rowp + col * ri->ri_font->fontwidth; 1360 dsp = rowp + col * ri->ri_font->fontwidth;