Tue Jan 17 19:13:23 2012 UTC ()
support DDC2, pick an appropriate video mode if a data are found


(macallan)
diff -r1.30 -r1.31 src/sys/dev/pci/voodoofb.c

cvs diff -r1.30 -r1.31 src/sys/dev/pci/voodoofb.c (switch to unified diff)

--- src/sys/dev/pci/voodoofb.c 2012/01/17 07:48:48 1.30
+++ src/sys/dev/pci/voodoofb.c 2012/01/17 19:13:22 1.31
@@ -1,1414 +1,1596 @@ @@ -1,1414 +1,1596 @@
1/* $NetBSD: voodoofb.c,v 1.30 2012/01/17 07:48:48 macallan Exp $ */ 1/* $NetBSD: voodoofb.c,v 1.31 2012/01/17 19:13:22 macallan Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, 2006 Michael Lorenz 4 * Copyright (c) 2005, 2006 Michael Lorenz
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 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28/*  28/*
29 * A console driver for 3Dfx Voodoo3 graphics boards  29 * A console driver for 3Dfx Voodoo3 graphics boards
30 * Thanks to Andreas Drewke (andreas_dr@gmx.de) for his Voodoo3 driver for BeOS  30 * Thanks to Andreas Drewke (andreas_dr@gmx.de) for his Voodoo3 driver for BeOS
31 * which I used as reference / documentation 31 * which I used as reference / documentation
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: voodoofb.c,v 1.30 2012/01/17 07:48:48 macallan Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: voodoofb.c,v 1.31 2012/01/17 19:13:22 macallan Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/malloc.h> 41#include <sys/malloc.h>
42#include <sys/callout.h> 42#include <sys/callout.h>
43#include <sys/kauth.h> 43#include <sys/kauth.h>
44 44
45#include <dev/videomode/videomode.h> 
46 
47#include <dev/pci/pcivar.h> 45#include <dev/pci/pcivar.h>
48#include <dev/pci/pcireg.h> 46#include <dev/pci/pcireg.h>
49#include <dev/pci/pcidevs.h> 47#include <dev/pci/pcidevs.h>
50#include <dev/pci/pciio.h> 48#include <dev/pci/pciio.h>
51#include <dev/pci/voodoofbreg.h> 49#include <dev/pci/voodoofbreg.h>
52 50
53#include <dev/wscons/wsdisplayvar.h> 51#include <dev/wscons/wsdisplayvar.h>
54#include <dev/wscons/wsconsio.h> 52#include <dev/wscons/wsconsio.h>
55#include <dev/wsfont/wsfont.h> 53#include <dev/wsfont/wsfont.h>
56#include <dev/rasops/rasops.h> 54#include <dev/rasops/rasops.h>
57#include <dev/wscons/wsdisplay_vconsvar.h> 55#include <dev/wscons/wsdisplay_vconsvar.h>
58#include <dev/pci/wsdisplay_pci.h> 56#include <dev/pci/wsdisplay_pci.h>
59 57
 58#include <dev/i2c/i2cvar.h>
 59#include <dev/i2c/i2c_bitbang.h>
 60#include <dev/i2c/ddcvar.h>
 61#include <dev/videomode/videomode.h>
 62#include <dev/videomode/edidvar.h>
 63#include <dev/videomode/edidreg.h>
 64
60#include "opt_wsemul.h" 65#include "opt_wsemul.h"
61 66
62struct voodoofb_softc { 67struct voodoofb_softc {
63 device_t sc_dev; 68 device_t sc_dev;
64 pci_chipset_tag_t sc_pc; 69 pci_chipset_tag_t sc_pc;
65 pcitag_t sc_pcitag; 70 pcitag_t sc_pcitag;
66 struct pci_attach_args sc_pa; 71 struct pci_attach_args sc_pa;
67 72
68 bus_space_tag_t sc_memt; 73 bus_space_tag_t sc_memt;
69 bus_space_tag_t sc_iot; 74 bus_space_tag_t sc_iot;
70 bus_space_handle_t sc_memh;  75 bus_space_handle_t sc_memh;
71 76
72 bus_space_tag_t sc_regt; 77 bus_space_tag_t sc_regt;
73 bus_space_tag_t sc_fbt; 78 bus_space_tag_t sc_fbt;
74 bus_space_tag_t sc_ioregt; 79 bus_space_tag_t sc_ioregt;
75 bus_space_handle_t sc_regh; 80 bus_space_handle_t sc_regh;
76 bus_space_handle_t sc_fbh;  81 bus_space_handle_t sc_fbh;
77 bus_space_handle_t sc_ioregh;  82 bus_space_handle_t sc_ioregh;
78 bus_addr_t sc_regs, sc_fb, sc_ioreg; 83 bus_addr_t sc_regs, sc_fb, sc_ioreg;
79 bus_size_t sc_regsize, sc_fbsize, sc_ioregsize; 84 bus_size_t sc_regsize, sc_fbsize, sc_ioregsize;
80 85
81 void *sc_ih; 86 void *sc_ih;
82  87
83 size_t memsize; 88 size_t memsize;
84 int memtype; 89 int memtype;
85 90
86 int bits_per_pixel; 91 int bits_per_pixel;
87 int width, height, linebytes; 92 int width, height, linebytes;
88 const struct videomode *sc_videomode; 93 const struct videomode *sc_videomode;
89 94
 95 /* i2c stuff */
 96 struct i2c_controller sc_i2c;
 97 uint8_t sc_edid_data[128];
 98 struct edid_info sc_edid_info;
 99 uint32_t sc_i2creg;
 100
90 int sc_mode; 101 int sc_mode;
91 uint32_t sc_bg; 102 uint32_t sc_bg;
92  103
93 u_char sc_cmap_red[256]; 104 u_char sc_cmap_red[256];
94 u_char sc_cmap_green[256]; 105 u_char sc_cmap_green[256];
95 u_char sc_cmap_blue[256];  106 u_char sc_cmap_blue[256];
96 int sc_dacw; 107 int sc_dacw;
97 108
98 struct vcons_data vd; 109 struct vcons_data vd;
99}; 110};
100 111
101struct voodoo_regs { 112struct voodoo_regs {
102 uint8_t vr_crtc[31]; 113 uint8_t vr_crtc[31];
103 uint8_t vr_graph[9]; 114 uint8_t vr_graph[9];
104 uint8_t vr_attr[21]; 115 uint8_t vr_attr[21];
105 uint8_t vr_seq[5]; 116 uint8_t vr_seq[5];
106}; 117};
107  118
108static struct vcons_screen voodoofb_console_screen; 119static struct vcons_screen voodoofb_console_screen;
109 120
110extern const u_char rasops_cmap[768]; 121extern const u_char rasops_cmap[768];
111 122
112static int voodoofb_match(device_t, cfdata_t, void *); 123static int voodoofb_match(device_t, cfdata_t, void *);
113static void voodoofb_attach(device_t, device_t, void *); 124static void voodoofb_attach(device_t, device_t, void *);
114 125
115static int voodoofb_drm_print(void *, const char *); 126static int voodoofb_drm_print(void *, const char *);
116static int voodoofb_drm_unmap(struct voodoofb_softc *); 127static int voodoofb_drm_unmap(struct voodoofb_softc *);
117static int voodoofb_drm_map(struct voodoofb_softc *); 128static int voodoofb_drm_map(struct voodoofb_softc *);
118 129
119CFATTACH_DECL_NEW(voodoofb, sizeof(struct voodoofb_softc), voodoofb_match,  130CFATTACH_DECL_NEW(voodoofb, sizeof(struct voodoofb_softc), voodoofb_match,
120 voodoofb_attach, NULL, NULL); 131 voodoofb_attach, NULL, NULL);
121 132
122static bool voodoofb_is_console(struct voodoofb_softc *); 133static bool voodoofb_is_console(struct voodoofb_softc *);
123static void voodoofb_init(struct voodoofb_softc *);  134static void voodoofb_init(struct voodoofb_softc *);
124 135
125static void voodoofb_cursor(void *, int, int, int); 136static void voodoofb_cursor(void *, int, int, int);
126static void voodoofb_putchar(void *, int, int, u_int, long); 137static void voodoofb_putchar(void *, int, int, u_int, long);
127static void voodoofb_copycols(void *, int, int, int, int); 138static void voodoofb_copycols(void *, int, int, int, int);
128static void voodoofb_erasecols(void *, int, int, int, long); 139static void voodoofb_erasecols(void *, int, int, int, long);
129static void voodoofb_copyrows(void *, int, int, int); 140static void voodoofb_copyrows(void *, int, int, int);
130static void voodoofb_eraserows(void *, int, int, long); 141static void voodoofb_eraserows(void *, int, int, long);
131 142
132#if 0 143#if 0
133static int voodoofb_allocattr(void *, int, int, int, long *); 144static int voodoofb_allocattr(void *, int, int, int, long *);
134static void voodoofb_scroll(void *, void *, int); 145static void voodoofb_scroll(void *, void *, int);
135static int voodoofb_load_font(void *, void *, struct wsdisplay_font *); 146static int voodoofb_load_font(void *, void *, struct wsdisplay_font *);
136#endif 147#endif
137 148
138static int voodoofb_putcmap(struct voodoofb_softc *, 149static int voodoofb_putcmap(struct voodoofb_softc *,
139 struct wsdisplay_cmap *); 150 struct wsdisplay_cmap *);
140static int voodoofb_getcmap(struct voodoofb_softc *, 151static int voodoofb_getcmap(struct voodoofb_softc *,
141 struct wsdisplay_cmap *); 152 struct wsdisplay_cmap *);
142static int voodoofb_putpalreg(struct voodoofb_softc *, uint8_t, uint8_t, 153static int voodoofb_putpalreg(struct voodoofb_softc *, uint8_t, uint8_t,
143 uint8_t, uint8_t); 154 uint8_t, uint8_t);
144static void voodoofb_bitblt(struct voodoofb_softc *, int, int, int, int, 155static void voodoofb_bitblt(struct voodoofb_softc *, int, int, int, int,
145 int, int); 156 int, int);
146static void voodoofb_rectfill(struct voodoofb_softc *, int, int, int, int, 157static void voodoofb_rectfill(struct voodoofb_softc *, int, int, int, int,
147 int); 158 int);
148static void voodoofb_rectinvert(struct voodoofb_softc *, int, int, int, 159static void voodoofb_rectinvert(struct voodoofb_softc *, int, int, int,
149 int);  160 int);
150static void voodoofb_setup_mono(struct voodoofb_softc *, int, int, int, 161static void voodoofb_setup_mono(struct voodoofb_softc *, int, int, int,
151 int, uint32_t, uint32_t);  162 int, uint32_t, uint32_t);
152static void voodoofb_feed_line(struct voodoofb_softc *, int, uint8_t *); 163static void voodoofb_feed_line(struct voodoofb_softc *, int, uint8_t *);
153 164
154static void voodoofb_wait_idle(struct voodoofb_softc *); 165static void voodoofb_wait_idle(struct voodoofb_softc *);
155 166
156#ifdef VOODOOFB_ENABLE_INTR 167#ifdef VOODOOFB_ENABLE_INTR
157static int voodoofb_intr(void *); 168static int voodoofb_intr(void *);
158#endif 169#endif
159 170
160static void voodoofb_set_videomode(struct voodoofb_softc *, 171static void voodoofb_set_videomode(struct voodoofb_softc *,
161 const struct videomode *); 172 const struct videomode *);
162 173
163struct wsscreen_descr voodoofb_defaultscreen = { 174struct wsscreen_descr voodoofb_defaultscreen = {
164 "default", 175 "default",
165 0, 0, 176 0, 0,
166 NULL, 177 NULL,
167 8, 16, 178 8, 16,
168 WSSCREEN_WSCOLORS | WSSCREEN_HILIT, 179 WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
169 NULL, 180 NULL,
170}; 181};
171 182
172const struct wsscreen_descr *_voodoofb_scrlist[] = { 183const struct wsscreen_descr *_voodoofb_scrlist[] = {
173 &voodoofb_defaultscreen, 184 &voodoofb_defaultscreen,
174 /* XXX other formats, graphics screen? */ 185 /* XXX other formats, graphics screen? */
175}; 186};
176 187
177struct wsscreen_list voodoofb_screenlist = { 188struct wsscreen_list voodoofb_screenlist = {
178 sizeof(_voodoofb_scrlist) / sizeof(struct wsscreen_descr *), _voodoofb_scrlist 189 sizeof(_voodoofb_scrlist) / sizeof(struct wsscreen_descr *), _voodoofb_scrlist
179}; 190};
180 191
181static int voodoofb_ioctl(void *, void *, u_long, void *, int, 192static int voodoofb_ioctl(void *, void *, u_long, void *, int,
182 struct lwp *); 193 struct lwp *);
183static paddr_t voodoofb_mmap(void *, void *, off_t, int); 194static paddr_t voodoofb_mmap(void *, void *, off_t, int);
184 195
185static void voodoofb_clearscreen(struct voodoofb_softc *); 196static void voodoofb_clearscreen(struct voodoofb_softc *);
186static void voodoofb_init_screen(void *, struct vcons_screen *, int, 197static void voodoofb_init_screen(void *, struct vcons_screen *, int,
187 long *); 198 long *);
188 199
189 200
190struct wsdisplay_accessops voodoofb_accessops = { 201struct wsdisplay_accessops voodoofb_accessops = {
191 voodoofb_ioctl, 202 voodoofb_ioctl,
192 voodoofb_mmap, 203 voodoofb_mmap,
193 NULL, 204 NULL,
194 NULL, 205 NULL,
195 NULL, 206 NULL,
196 NULL, /* load_font */ 207 NULL, /* load_font */
197 NULL, /* polls */ 208 NULL, /* polls */
198 NULL, /* scroll */ 209 NULL, /* scroll */
199}; 210};
200 211
 212/* I2C glue */
 213static int voodoofb_i2c_acquire_bus(void *, int);
 214static void voodoofb_i2c_release_bus(void *, int);
 215static int voodoofb_i2c_send_start(void *, int);
 216static int voodoofb_i2c_send_stop(void *, int);
 217static int voodoofb_i2c_initiate_xfer(void *, i2c_addr_t, int);
 218static int voodoofb_i2c_read_byte(void *, uint8_t *, int);
 219static int voodoofb_i2c_write_byte(void *, uint8_t, int);
 220
 221/* I2C bitbang glue */
 222static void voodoofb_i2cbb_set_bits(void *, uint32_t);
 223static void voodoofb_i2cbb_set_dir(void *, uint32_t);
 224static uint32_t voodoofb_i2cbb_read(void *);
 225
 226static void voodoofb_setup_i2c(struct voodoofb_softc *);
 227
 228static const struct i2c_bitbang_ops voodoofb_i2cbb_ops = {
 229 voodoofb_i2cbb_set_bits,
 230 voodoofb_i2cbb_set_dir,
 231 voodoofb_i2cbb_read,
 232 {
 233 VSP_SDA0_IN,
 234 VSP_SCL0_IN,
 235 0,
 236 0
 237 }
 238};
 239
201/* 240/*
202 * Inline functions for getting access to register aperture. 241 * Inline functions for getting access to register aperture.
203 */ 242 */
204static inline void 243static inline void
205voodoo3_write32(struct voodoofb_softc *sc, uint32_t reg, uint32_t val) 244voodoo3_write32(struct voodoofb_softc *sc, uint32_t reg, uint32_t val)
206{ 245{
207 bus_space_write_4(sc->sc_regt, sc->sc_regh, reg, val); 246 bus_space_write_4(sc->sc_regt, sc->sc_regh, reg, val);
208} 247}
209 248
210static inline uint32_t 249static inline uint32_t
211voodoo3_read32(struct voodoofb_softc *sc, uint32_t reg)  250voodoo3_read32(struct voodoofb_softc *sc, uint32_t reg)
212{ 251{
213 return bus_space_read_4(sc->sc_regt, sc->sc_regh, reg); 252 return bus_space_read_4(sc->sc_regt, sc->sc_regh, reg);
214} 253}
215 254
216static inline void 255static inline void
217voodoo3_write_crtc(struct voodoofb_softc *sc, uint8_t reg, uint8_t val) 256voodoo3_write_crtc(struct voodoofb_softc *sc, uint8_t reg, uint8_t val)
218{ 257{
219 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, CRTC_INDEX - 0x300, reg); 258 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, CRTC_INDEX - 0x300, reg);
220 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, CRTC_DATA - 0x300, val); 259 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, CRTC_DATA - 0x300, val);
221} 260}
222 261
223static inline void 262static inline void
224voodoo3_write_seq(struct voodoofb_softc *sc, uint8_t reg, uint8_t val) 263voodoo3_write_seq(struct voodoofb_softc *sc, uint8_t reg, uint8_t val)
225{ 264{
226 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, SEQ_INDEX - 0x300, reg); 265 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, SEQ_INDEX - 0x300, reg);
227 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, SEQ_DATA - 0x300, val); 266 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, SEQ_DATA - 0x300, val);
228} 267}
229 268
230static inline void 269static inline void
231voodoo3_write_gra(struct voodoofb_softc *sc, uint8_t reg, uint8_t val) 270voodoo3_write_gra(struct voodoofb_softc *sc, uint8_t reg, uint8_t val)
232{ 271{
233 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, GRA_INDEX - 0x300, reg); 272 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, GRA_INDEX - 0x300, reg);
234 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, GRA_DATA - 0x300, val); 273 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, GRA_DATA - 0x300, val);
235} 274}
236 275
237static inline void 276static inline void
238voodoo3_write_attr(struct voodoofb_softc *sc, uint8_t reg, uint8_t val) 277voodoo3_write_attr(struct voodoofb_softc *sc, uint8_t reg, uint8_t val)
239{ 278{
240 volatile uint8_t junk; 279 volatile uint8_t junk;
241 uint8_t index; 280 uint8_t index;
242  281
243 junk = bus_space_read_1(sc->sc_ioregt, sc->sc_ioregh, IS1_R - 0x300); 282 junk = bus_space_read_1(sc->sc_ioregt, sc->sc_ioregh, IS1_R - 0x300);
244 index = bus_space_read_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300); 283 index = bus_space_read_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300);
245 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300, reg); 284 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300, reg);
246 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300, val); 285 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300, val);
247 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300, index); 286 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, ATT_IW - 0x300, index);
248} 287}
249 288
250static inline void 289static inline void
251vga_outb(struct voodoofb_softc *sc, uint32_t reg, uint8_t val) 290vga_outb(struct voodoofb_softc *sc, uint32_t reg, uint8_t val)
252{  291{
253 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, reg - 0x300, val);  292 bus_space_write_1(sc->sc_ioregt, sc->sc_ioregh, reg - 0x300, val);
254} 293}
255 294
256/* wait until there's room for len bytes in the FIFO */ 295/* wait until there's room for len bytes in the FIFO */
257static inline void 296static inline void
258voodoo3_make_room(struct voodoofb_softc *sc, int len)  297voodoo3_make_room(struct voodoofb_softc *sc, int len)
259{ 298{
260 while ((voodoo3_read32(sc, STATUS) & 0x1f) < len); 299 while ((voodoo3_read32(sc, STATUS) & 0x1f) < len);
261} 300}
262 301
263static void 302static void
264voodoofb_wait_idle(struct voodoofb_softc *sc) 303voodoofb_wait_idle(struct voodoofb_softc *sc)
265{ 304{
266 int i = 0; 305 int i = 0;
267 306
268 voodoo3_make_room(sc, 1); 307 voodoo3_make_room(sc, 1);
269 voodoo3_write32(sc, COMMAND_3D, COMMAND_3D_NOP); 308 voodoo3_write32(sc, COMMAND_3D, COMMAND_3D_NOP);
270 309
271 while (1) { 310 while (1) {
272 i = (voodoo3_read32(sc, STATUS) & STATUS_BUSY) ? 0 : i + 1; 311 i = (voodoo3_read32(sc, STATUS) & STATUS_BUSY) ? 0 : i + 1;
273 if(i == 3) break; 312 if(i == 3) break;
274 } 313 }
275} 314}
276 315
277static int 316static int
278voodoofb_match(device_t parent, cfdata_t match, void *aux) 317voodoofb_match(device_t parent, cfdata_t match, void *aux)
279{ 318{
280 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 319 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
281 320
282 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || 321 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY ||
283 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) 322 PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA)
284 return 0; 323 return 0;
285 if ((PCI_VENDOR(pa->pa_id)==PCI_VENDOR_3DFX) &&  324 if ((PCI_VENDOR(pa->pa_id)==PCI_VENDOR_3DFX) &&
286 (PCI_PRODUCT(pa->pa_id)>=PCI_PRODUCT_3DFX_VOODOO3)) 325 (PCI_PRODUCT(pa->pa_id)>=PCI_PRODUCT_3DFX_VOODOO3))
287 return 100; 326 return 100;
288 return 0; 327 return 0;
289} 328}
290 329
291static void 330static void
292voodoofb_attach(device_t parent, device_t self, void *aux) 331voodoofb_attach(device_t parent, device_t self, void *aux)
293{ 332{
294 struct voodoofb_softc *sc = device_private(self);  333 struct voodoofb_softc *sc = device_private(self);
295 struct pci_attach_args *pa = aux; 334 struct pci_attach_args *pa = aux;
296 char devinfo[256]; 335 char devinfo[256];
297 struct wsemuldisplaydev_attach_args aa; 336 struct wsemuldisplaydev_attach_args aa;
298 struct rasops_info *ri; 337 struct rasops_info *ri;
299#ifdef VOODOOFB_ENABLE_INTR 338#ifdef VOODOOFB_ENABLE_INTR
300 pci_intr_handle_t ih; 339 pci_intr_handle_t ih;
301 const char *intrstr; 340 const char *intrstr;
302#endif 341#endif
303 ulong defattr; 342 ulong defattr;
304 int console, width, height, i, j; 343 int console, width, height, i, j;
305 prop_dictionary_t dict; 344 prop_dictionary_t dict;
306 int linebytes, depth; 345 int linebytes, depth;
307 uint32_t bg, fg, ul; 346 uint32_t bg, fg, ul;
308 347
309 sc->sc_dev = self; 348 sc->sc_dev = self;
310 349
311 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 350 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
312 sc->sc_pc = pa->pa_pc; 351 sc->sc_pc = pa->pa_pc;
313 sc->sc_pcitag = pa->pa_tag; 352 sc->sc_pcitag = pa->pa_tag;
314 sc->sc_dacw = -1; 353 sc->sc_dacw = -1;
315 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 354 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
316 printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class)); 355 printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
317 356
318 sc->sc_memt = pa->pa_memt; 357 sc->sc_memt = pa->pa_memt;
319 sc->sc_iot = pa->pa_iot; 358 sc->sc_iot = pa->pa_iot;
320 sc->sc_pa = *pa; 359 sc->sc_pa = *pa;
321 360
322 /* the framebuffer */ 361 /* the framebuffer */
323 if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_MEM, 362 if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_MEM,
324 BUS_SPACE_MAP_CACHEABLE | BUS_SPACE_MAP_PREFETCHABLE |  363 BUS_SPACE_MAP_CACHEABLE | BUS_SPACE_MAP_PREFETCHABLE |
325 BUS_SPACE_MAP_LINEAR,  364 BUS_SPACE_MAP_LINEAR,
326 &sc->sc_fbt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) { 365 &sc->sc_fbt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) {
327 aprint_error_dev(self, "failed to map the frame buffer.\n"); 366 aprint_error_dev(self, "failed to map the frame buffer.\n");
328 } 367 }
329 368
330 /* memory-mapped registers */ 369 /* memory-mapped registers */
331 if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0, 370 if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0,
332 &sc->sc_regt, &sc->sc_regh, &sc->sc_regs, &sc->sc_regsize)) { 371 &sc->sc_regt, &sc->sc_regh, &sc->sc_regs, &sc->sc_regsize)) {
333 aprint_error_dev(self, "failed to map memory-mapped registers.\n"); 372 aprint_error_dev(self, "failed to map memory-mapped registers.\n");
334 } 373 }
335 374
336 /* IO-mapped registers */ 375 /* IO-mapped registers */
337 if (pci_mapreg_map(pa, 0x18, PCI_MAPREG_TYPE_IO, 0, 376 if (pci_mapreg_map(pa, 0x18, PCI_MAPREG_TYPE_IO, 0,
338 &sc->sc_ioregt, &sc->sc_ioregh, &sc->sc_ioreg, 377 &sc->sc_ioregt, &sc->sc_ioregh, &sc->sc_ioreg,
339 &sc->sc_ioregsize)) { 378 &sc->sc_ioregsize)) {
340 aprint_error_dev(self, "failed to map IO-mapped registers.\n"); 379 aprint_error_dev(self, "failed to map IO-mapped registers.\n");
341 } 380 }
342 voodoofb_init(sc); 381 voodoofb_init(sc);
343  382
344 /* we should read these from the chip instead of depending on OF */ 383 /* we should read these from the chip instead of depending on OF */
345 width = height = -1; 384 width = height = -1;
346  385
347 dict = device_properties(self); 386 dict = device_properties(self);
348 if (!prop_dictionary_get_uint32(dict, "width", &width)) { 387 if (!prop_dictionary_get_uint32(dict, "width", &width)) {
349 aprint_error_dev(self, "no width property\n"); 388 aprint_error_dev(self, "no width property\n");
350 return; 389 return;
351 } 390 }
352 if (!prop_dictionary_get_uint32(dict, "height", &height)) { 391 if (!prop_dictionary_get_uint32(dict, "height", &height)) {
353 aprint_error_dev(self, "no height property\n"); 392 aprint_error_dev(self, "no height property\n");
354 return; 393 return;
355 } 394 }
356 if (!prop_dictionary_get_uint32(dict, "depth", &depth)) { 395 if (!prop_dictionary_get_uint32(dict, "depth", &depth)) {
357 aprint_error_dev(self, "no depth property\n"); 396 aprint_error_dev(self, "no depth property\n");
358 return; 397 return;
359 } 398 }
360 linebytes = width; /* XXX */ 399 linebytes = width; /* XXX */
361 400
362 if (width == -1 || height == -1) 401 if (width == -1 || height == -1)
363 return; 402 return;
364 403
365 sc->width = width; 404 sc->width = width;
366 sc->height = height; 405 sc->height = height;
367 sc->bits_per_pixel = depth; 406 sc->bits_per_pixel = depth;
368 sc->linebytes = linebytes; 407 sc->linebytes = linebytes;
369 printf("%s: initial resolution %dx%d, %d bit\n", device_xname(self), 408 printf("%s: initial resolution %dx%d, %d bit\n", device_xname(self),
370 sc->width, sc->height, sc->bits_per_pixel); 409 sc->width, sc->height, sc->bits_per_pixel);
371 410
 411 sc->sc_videomode = NULL;
 412 voodoofb_setup_i2c(sc);
 413
372 /* XXX this should at least be configurable via kernel config */ 414 /* XXX this should at least be configurable via kernel config */
373 if ((sc->sc_videomode = pick_mode_by_ref(1024, 768, 60)) != NULL) 415 if (sc->sc_videomode == NULL) {
374 voodoofb_set_videomode(sc, sc->sc_videomode); 416 sc->sc_videomode = pick_mode_by_ref(width, height, 60);
 417 }
 418
 419 voodoofb_set_videomode(sc, sc->sc_videomode);
375 420
376 vcons_init(&sc->vd, sc, &voodoofb_defaultscreen, &voodoofb_accessops); 421 vcons_init(&sc->vd, sc, &voodoofb_defaultscreen, &voodoofb_accessops);
377 sc->vd.init_screen = voodoofb_init_screen; 422 sc->vd.init_screen = voodoofb_init_screen;
378 423
379 console = voodoofb_is_console(sc); 424 console = voodoofb_is_console(sc);
380 425
381 ri = &voodoofb_console_screen.scr_ri; 426 ri = &voodoofb_console_screen.scr_ri;
382 if (console) { 427 if (console) {
383 vcons_init_screen(&sc->vd, &voodoofb_console_screen, 1, 428 vcons_init_screen(&sc->vd, &voodoofb_console_screen, 1,
384 &defattr); 429 &defattr);
385 voodoofb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 430 voodoofb_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
386 431
387 voodoofb_defaultscreen.textops = &ri->ri_ops; 432 voodoofb_defaultscreen.textops = &ri->ri_ops;
388 voodoofb_defaultscreen.capabilities = ri->ri_caps; 433 voodoofb_defaultscreen.capabilities = ri->ri_caps;
389 voodoofb_defaultscreen.nrows = ri->ri_rows; 434 voodoofb_defaultscreen.nrows = ri->ri_rows;
390 voodoofb_defaultscreen.ncols = ri->ri_cols; 435 voodoofb_defaultscreen.ncols = ri->ri_cols;
391 wsdisplay_cnattach(&voodoofb_defaultscreen, ri, 0, 0, defattr); 436 wsdisplay_cnattach(&voodoofb_defaultscreen, ri, 0, 0, defattr);
392 } else { 437 } else {
393 /* 438 /*
394 * since we're not the console we can postpone the rest 439 * since we're not the console we can postpone the rest
395 * until someone actually allocates a screen for us 440 * until someone actually allocates a screen for us
396 */ 441 */
397 voodoofb_set_videomode(sc, sc->sc_videomode);  442 voodoofb_set_videomode(sc, sc->sc_videomode);
398 } 443 }
399 444
400 printf("%s: %d MB aperture at 0x%08x, %d MB registers at 0x%08x\n", 445 printf("%s: %d MB aperture at 0x%08x, %d MB registers at 0x%08x\n",
401 device_xname(self), (u_int)(sc->sc_fbsize >> 20), 446 device_xname(self), (u_int)(sc->sc_fbsize >> 20),
402 (u_int)sc->sc_fb, (u_int)(sc->sc_regsize >> 20),  447 (u_int)sc->sc_fb, (u_int)(sc->sc_regsize >> 20),
403 (u_int)sc->sc_regs); 448 (u_int)sc->sc_regs);
404#ifdef VOODOOFB_DEBUG 449#ifdef VOODOOFB_DEBUG
405 printf("fb: %08lx\n", (ulong)ri->ri_bits); 450 printf("fb: %08lx\n", (ulong)ri->ri_bits);
406#endif 451#endif
407  452
408 j = 0; 453 j = 0;
409 for (i = 0; i < 256; i++) { 454 for (i = 0; i < 256; i++) {
410 voodoofb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1],  455 voodoofb_putpalreg(sc, i, rasops_cmap[j], rasops_cmap[j + 1],
411 rasops_cmap[j + 2]); 456 rasops_cmap[j + 2]);
412 j += 3; 457 j += 3;
413 } 458 }
414 459
415#ifdef VOODOOFB_ENABLE_INTR 460#ifdef VOODOOFB_ENABLE_INTR
416 /* Interrupt. We don't use it for anything yet */ 461 /* Interrupt. We don't use it for anything yet */
417 if (pci_intr_map(pa, &ih)) { 462 if (pci_intr_map(pa, &ih)) {
418 aprint_error_dev(self, "failed to map interrupt\n"); 463 aprint_error_dev(self, "failed to map interrupt\n");
419 return; 464 return;
420 } 465 }
421 466
422 intrstr = pci_intr_string(sc->sc_pc, ih); 467 intrstr = pci_intr_string(sc->sc_pc, ih);
423 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_NET, voodoofb_intr,  468 sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_NET, voodoofb_intr,
424 sc); 469 sc);
425 if (sc->sc_ih == NULL) { 470 if (sc->sc_ih == NULL) {
426 aprint_error_dev(self, "failed to establish interrupt"); 471 aprint_error_dev(self, "failed to establish interrupt");
427 if (intrstr != NULL) 472 if (intrstr != NULL)
428 aprint_error(" at %s", intrstr); 473 aprint_error(" at %s", intrstr);
429 aprint_error("\n"); 474 aprint_error("\n");
430 return; 475 return;
431 } 476 }
432 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 477 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
433#endif 478#endif
434 479
435 rasops_unpack_attr(defattr, &fg, &bg, &ul); 480 rasops_unpack_attr(defattr, &fg, &bg, &ul);
436 sc->sc_bg = ri->ri_devcmap[bg]; 481 sc->sc_bg = ri->ri_devcmap[bg];
437 voodoofb_clearscreen(sc); 482 voodoofb_clearscreen(sc);
438 483
439 if (console) 484 if (console)
440 vcons_replay_msgbuf(&voodoofb_console_screen); 485 vcons_replay_msgbuf(&voodoofb_console_screen);
441 aa.console = console; 486 aa.console = console;
442 aa.scrdata = &voodoofb_screenlist; 487 aa.scrdata = &voodoofb_screenlist;
443 aa.accessops = &voodoofb_accessops; 488 aa.accessops = &voodoofb_accessops;
444 aa.accesscookie = &sc->vd; 489 aa.accesscookie = &sc->vd;
445 490
446 config_found(self, &aa, wsemuldisplaydevprint); 491 config_found(self, &aa, wsemuldisplaydevprint);
447 config_found_ia(self, "drm", aux, voodoofb_drm_print); 492 config_found_ia(self, "drm", aux, voodoofb_drm_print);
448} 493}
449 494
450static int 495static int
451voodoofb_drm_print(void *opaque, const char *pnp) 496voodoofb_drm_print(void *opaque, const char *pnp)
452{ 497{
453 if (pnp) 498 if (pnp)
454 aprint_normal("drm at %s", pnp); 499 aprint_normal("drm at %s", pnp);
455 500
456 return UNCONF; 501 return UNCONF;
457} 502}
458 503
459static int 504static int
460voodoofb_drm_unmap(struct voodoofb_softc *sc) 505voodoofb_drm_unmap(struct voodoofb_softc *sc)
461{ 506{
462 printf("%s: releasing bus resources\n", device_xname(sc->sc_dev)); 507 printf("%s: releasing bus resources\n", device_xname(sc->sc_dev));
463 508
464 bus_space_unmap(sc->sc_ioregt, sc->sc_ioregh, sc->sc_ioregsize); 509 bus_space_unmap(sc->sc_ioregt, sc->sc_ioregh, sc->sc_ioregsize);
465 bus_space_unmap(sc->sc_regt, sc->sc_regh, sc->sc_regsize); 510 bus_space_unmap(sc->sc_regt, sc->sc_regh, sc->sc_regsize);
466 bus_space_unmap(sc->sc_fbt, sc->sc_fbh, sc->sc_fbsize); 511 bus_space_unmap(sc->sc_fbt, sc->sc_fbh, sc->sc_fbsize);
467 512
468 return 0; 513 return 0;
469} 514}
470 515
471static int 516static int
472voodoofb_drm_map(struct voodoofb_softc *sc) 517voodoofb_drm_map(struct voodoofb_softc *sc)
473{ 518{
474 if (pci_mapreg_map(&sc->sc_pa, 0x14, PCI_MAPREG_TYPE_MEM, 519 if (pci_mapreg_map(&sc->sc_pa, 0x14, PCI_MAPREG_TYPE_MEM,
475 BUS_SPACE_MAP_CACHEABLE | BUS_SPACE_MAP_PREFETCHABLE |  520 BUS_SPACE_MAP_CACHEABLE | BUS_SPACE_MAP_PREFETCHABLE |
476 BUS_SPACE_MAP_LINEAR,  521 BUS_SPACE_MAP_LINEAR,
477 &sc->sc_fbt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) { 522 &sc->sc_fbt, &sc->sc_fbh, &sc->sc_fb, &sc->sc_fbsize)) {
478 aprint_error_dev(sc->sc_dev, "failed to map the frame buffer.\n"); 523 aprint_error_dev(sc->sc_dev, "failed to map the frame buffer.\n");
479 } 524 }
480 525
481 /* memory-mapped registers */ 526 /* memory-mapped registers */
482 if (pci_mapreg_map(&sc->sc_pa, 0x10, PCI_MAPREG_TYPE_MEM, 0, 527 if (pci_mapreg_map(&sc->sc_pa, 0x10, PCI_MAPREG_TYPE_MEM, 0,
483 &sc->sc_regt, &sc->sc_regh, &sc->sc_regs, &sc->sc_regsize)) { 528 &sc->sc_regt, &sc->sc_regh, &sc->sc_regs, &sc->sc_regsize)) {
484 aprint_error_dev(sc->sc_dev, "failed to map memory-mapped registers.\n"); 529 aprint_error_dev(sc->sc_dev, "failed to map memory-mapped registers.\n");
485 } 530 }
486 531
487 /* IO-mapped registers */ 532 /* IO-mapped registers */
488 if (pci_mapreg_map(&sc->sc_pa, 0x18, PCI_MAPREG_TYPE_IO, 0, 533 if (pci_mapreg_map(&sc->sc_pa, 0x18, PCI_MAPREG_TYPE_IO, 0,
489 &sc->sc_ioregt, &sc->sc_ioregh, &sc->sc_ioreg, 534 &sc->sc_ioregt, &sc->sc_ioregh, &sc->sc_ioreg,
490 &sc->sc_ioregsize)) { 535 &sc->sc_ioregsize)) {
491 aprint_error_dev(sc->sc_dev, "failed to map IO-mapped registers.\n"); 536 aprint_error_dev(sc->sc_dev, "failed to map IO-mapped registers.\n");
492 } 537 }
493 538
494 voodoofb_init(sc); 539 voodoofb_init(sc);
495 /* XXX this should at least be configurable via kernel config */ 540 /* XXX this should at least be configurable via kernel config */
496 voodoofb_set_videomode(sc, sc->sc_videomode); 541 voodoofb_set_videomode(sc, sc->sc_videomode);
497 542
498 return 0; 543 return 0;
499} 544}
500 545
501static int 546static int
502voodoofb_putpalreg(struct voodoofb_softc *sc, uint8_t index, uint8_t r,  547voodoofb_putpalreg(struct voodoofb_softc *sc, uint8_t index, uint8_t r,
503 uint8_t g, uint8_t b) 548 uint8_t g, uint8_t b)
504{ 549{
505 uint32_t color; 550 uint32_t color;
506  551
507 sc->sc_cmap_red[index] = r; 552 sc->sc_cmap_red[index] = r;
508 sc->sc_cmap_green[index] = g; 553 sc->sc_cmap_green[index] = g;
509 sc->sc_cmap_blue[index] = b; 554 sc->sc_cmap_blue[index] = b;
510 555
511 color = (r << 16) | (g << 8) | b; 556 color = (r << 16) | (g << 8) | b;
512 voodoo3_make_room(sc, 2); 557 voodoo3_make_room(sc, 2);
513 voodoo3_write32(sc, DACADDR, index); 558 voodoo3_write32(sc, DACADDR, index);
514 voodoo3_write32(sc, DACDATA, color); 559 voodoo3_write32(sc, DACDATA, color);
515 560
516 return 0; 561 return 0;
517} 562}
518 563
519static int 564static int
520voodoofb_putcmap(struct voodoofb_softc *sc, struct wsdisplay_cmap *cm) 565voodoofb_putcmap(struct voodoofb_softc *sc, struct wsdisplay_cmap *cm)
521{ 566{
522 u_char *r, *g, *b; 567 u_char *r, *g, *b;
523 u_int index = cm->index; 568 u_int index = cm->index;
524 u_int count = cm->count; 569 u_int count = cm->count;
525 int i, error; 570 int i, error;
526 u_char rbuf[256], gbuf[256], bbuf[256]; 571 u_char rbuf[256], gbuf[256], bbuf[256];
527 572
528#ifdef VOODOOFB_DEBUG 573#ifdef VOODOOFB_DEBUG
529 printf("putcmap: %d %d\n",index, count); 574 printf("putcmap: %d %d\n",index, count);
530#endif  575#endif
531 if (cm->index >= 256 || cm->count > 256 || 576 if (cm->index >= 256 || cm->count > 256 ||
532 (cm->index + cm->count) > 256) 577 (cm->index + cm->count) > 256)
533 return EINVAL; 578 return EINVAL;
534 error = copyin(cm->red, &rbuf[index], count); 579 error = copyin(cm->red, &rbuf[index], count);
535 if (error) 580 if (error)
536 return error; 581 return error;
537 error = copyin(cm->green, &gbuf[index], count); 582 error = copyin(cm->green, &gbuf[index], count);
538 if (error) 583 if (error)
539 return error; 584 return error;
540 error = copyin(cm->blue, &bbuf[index], count); 585 error = copyin(cm->blue, &bbuf[index], count);
541 if (error) 586 if (error)
542 return error; 587 return error;
543 588
544 memcpy(&sc->sc_cmap_red[index], &rbuf[index], count); 589 memcpy(&sc->sc_cmap_red[index], &rbuf[index], count);
545 memcpy(&sc->sc_cmap_green[index], &gbuf[index], count); 590 memcpy(&sc->sc_cmap_green[index], &gbuf[index], count);
546 memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count); 591 memcpy(&sc->sc_cmap_blue[index], &bbuf[index], count);
547 592
548 r = &sc->sc_cmap_red[index]; 593 r = &sc->sc_cmap_red[index];
549 g = &sc->sc_cmap_green[index]; 594 g = &sc->sc_cmap_green[index];
550 b = &sc->sc_cmap_blue[index]; 595 b = &sc->sc_cmap_blue[index];
551  596
552 for (i = 0; i < count; i++) { 597 for (i = 0; i < count; i++) {
553 voodoofb_putpalreg(sc, index, *r, *g, *b); 598 voodoofb_putpalreg(sc, index, *r, *g, *b);
554 index++; 599 index++;
555 r++, g++, b++; 600 r++, g++, b++;
556 } 601 }
557 return 0; 602 return 0;
558} 603}
559 604
560static int 605static int
561voodoofb_getcmap(struct voodoofb_softc *sc, struct wsdisplay_cmap *cm) 606voodoofb_getcmap(struct voodoofb_softc *sc, struct wsdisplay_cmap *cm)
562{ 607{
563 u_int index = cm->index; 608 u_int index = cm->index;
564 u_int count = cm->count; 609 u_int count = cm->count;
565 int error; 610 int error;
566 611
567 if (index >= 255 || count > 256 || index + count > 256) 612 if (index >= 255 || count > 256 || index + count > 256)
568 return EINVAL; 613 return EINVAL;
569  614
570 error = copyout(&sc->sc_cmap_red[index], cm->red, count); 615 error = copyout(&sc->sc_cmap_red[index], cm->red, count);
571 if (error) 616 if (error)
572 return error; 617 return error;
573 error = copyout(&sc->sc_cmap_green[index], cm->green, count); 618 error = copyout(&sc->sc_cmap_green[index], cm->green, count);
574 if (error) 619 if (error)
575 return error; 620 return error;
576 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count); 621 error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
577 if (error) 622 if (error)
578 return error; 623 return error;
579 624
580 return 0; 625 return 0;
581} 626}
582 627
583static bool 628static bool
584voodoofb_is_console(struct voodoofb_softc *sc) 629voodoofb_is_console(struct voodoofb_softc *sc)
585{ 630{
586 prop_dictionary_t dict; 631 prop_dictionary_t dict;
587 bool console; 632 bool console;
588 633
589 dict = device_properties(sc->sc_dev); 634 dict = device_properties(sc->sc_dev);
590 prop_dictionary_get_bool(dict, "is_console", &console); 635 prop_dictionary_get_bool(dict, "is_console", &console);
591 return console; 636 return console;
592} 637}
593 638
594static void 639static void
595voodoofb_clearscreen(struct voodoofb_softc *sc) 640voodoofb_clearscreen(struct voodoofb_softc *sc)
596{ 641{
597 voodoofb_rectfill(sc, 0, 0, sc->width, sc->height, sc->sc_bg); 642 voodoofb_rectfill(sc, 0, 0, sc->width, sc->height, sc->sc_bg);
598} 643}
599 644
600/* 645/*
601 * wsdisplay_emulops 646 * wsdisplay_emulops
602 */ 647 */
603 648
604static void 649static void
605voodoofb_cursor(void *cookie, int on, int row, int col) 650voodoofb_cursor(void *cookie, int on, int row, int col)
606{ 651{
607 struct rasops_info *ri = cookie; 652 struct rasops_info *ri = cookie;
608 struct vcons_screen *scr = ri->ri_hw; 653 struct vcons_screen *scr = ri->ri_hw;
609 struct voodoofb_softc *sc = scr->scr_cookie; 654 struct voodoofb_softc *sc = scr->scr_cookie;
610 int x, y, wi, he; 655 int x, y, wi, he;
611  656
612 wi = ri->ri_font->fontwidth; 657 wi = ri->ri_font->fontwidth;
613 he = ri->ri_font->fontheight; 658 he = ri->ri_font->fontheight;
614  659
615 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 660 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
616 x = ri->ri_ccol * wi + ri->ri_xorigin; 661 x = ri->ri_ccol * wi + ri->ri_xorigin;
617 y = ri->ri_crow * he + ri->ri_yorigin; 662 y = ri->ri_crow * he + ri->ri_yorigin;
618 if (ri->ri_flg & RI_CURSOR) { 663 if (ri->ri_flg & RI_CURSOR) {
619 voodoofb_rectinvert(sc, x, y, wi, he); 664 voodoofb_rectinvert(sc, x, y, wi, he);
620 ri->ri_flg &= ~RI_CURSOR; 665 ri->ri_flg &= ~RI_CURSOR;
621 } 666 }
622 ri->ri_crow = row; 667 ri->ri_crow = row;
623 ri->ri_ccol = col; 668 ri->ri_ccol = col;
624 if (on) 669 if (on)
625 { 670 {
626 x = ri->ri_ccol * wi + ri->ri_xorigin; 671 x = ri->ri_ccol * wi + ri->ri_xorigin;
627 y = ri->ri_crow * he + ri->ri_yorigin; 672 y = ri->ri_crow * he + ri->ri_yorigin;
628 voodoofb_rectinvert(sc, x, y, wi, he); 673 voodoofb_rectinvert(sc, x, y, wi, he);
629 ri->ri_flg |= RI_CURSOR; 674 ri->ri_flg |= RI_CURSOR;
630 } 675 }
631 } else { 676 } else {
632 ri->ri_flg &= ~RI_CURSOR; 677 ri->ri_flg &= ~RI_CURSOR;
633 ri->ri_crow = row; 678 ri->ri_crow = row;
634 ri->ri_ccol = col; 679 ri->ri_ccol = col;
635 } 680 }
636} 681}
637 682
638#if 0 683#if 0
639int 684int
640voodoofb_mapchar(void *cookie, int uni, u_int *index) 685voodoofb_mapchar(void *cookie, int uni, u_int *index)
641{ 686{
642 return 0; 687 return 0;
643} 688}
644#endif 689#endif
645 690
646static void 691static void
647voodoofb_putchar(void *cookie, int row, int col, u_int c, long attr) 692voodoofb_putchar(void *cookie, int row, int col, u_int c, long attr)
648{ 693{
649 struct rasops_info *ri = cookie; 694 struct rasops_info *ri = cookie;
650 struct wsdisplay_font *font = PICK_FONT(ri, c); 695 struct wsdisplay_font *font = PICK_FONT(ri, c);
651 struct vcons_screen *scr = ri->ri_hw; 696 struct vcons_screen *scr = ri->ri_hw;
652 struct voodoofb_softc *sc = scr->scr_cookie; 697 struct voodoofb_softc *sc = scr->scr_cookie;
653 698
654 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 699 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
655 uint8_t *data; 700 uint8_t *data;
656 int fg, bg, uc, i; 701 int fg, bg, uc, i;
657 int x, y, wi, he; 702 int x, y, wi, he;
658 703
659 wi = font->fontwidth; 704 wi = font->fontwidth;
660 he = font->fontheight; 705 he = font->fontheight;
661 706
662 if (!CHAR_IN_FONT(c, font)) 707 if (!CHAR_IN_FONT(c, font))
663 return; 708 return;
664 bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf]; 709 bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
665 fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf]; 710 fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
666 x = ri->ri_xorigin + col * wi; 711 x = ri->ri_xorigin + col * wi;
667 y = ri->ri_yorigin + row * he; 712 y = ri->ri_yorigin + row * he;
668 if (c == 0x20) { 713 if (c == 0x20) {
669 voodoofb_rectfill(sc, x, y, wi, he, bg); 714 voodoofb_rectfill(sc, x, y, wi, he, bg);
670 } else { 715 } else {
671 uc = c - font->firstchar; 716 uc = c - font->firstchar;
672 data = (uint8_t *)font->data + uc *  717 data = (uint8_t *)font->data + uc *
673 ri->ri_fontscale; 718 ri->ri_fontscale;
674 voodoofb_setup_mono(sc, x, y, wi, he, fg, bg);  719 voodoofb_setup_mono(sc, x, y, wi, he, fg, bg);
675 for (i = 0; i < he; i++) { 720 for (i = 0; i < he; i++) {
676 voodoofb_feed_line(sc, font->stride, data); 721 voodoofb_feed_line(sc, font->stride, data);
677 data += font->stride; 722 data += font->stride;
678 } 723 }
679 } 724 }
680 } 725 }
681} 726}
682 727
683static void 728static void
684voodoofb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 729voodoofb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
685{ 730{
686 struct rasops_info *ri = cookie; 731 struct rasops_info *ri = cookie;
687 struct vcons_screen *scr = ri->ri_hw; 732 struct vcons_screen *scr = ri->ri_hw;
688 struct voodoofb_softc *sc = scr->scr_cookie; 733 struct voodoofb_softc *sc = scr->scr_cookie;
689 int32_t xs, xd, y, width, height; 734 int32_t xs, xd, y, width, height;
690  735
691 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 736 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
692 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 737 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
693 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 738 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
694 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 739 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
695 width = ri->ri_font->fontwidth * ncols; 740 width = ri->ri_font->fontwidth * ncols;
696 height = ri->ri_font->fontheight;  741 height = ri->ri_font->fontheight;
697 voodoofb_bitblt(sc, xs, y, xd, y, width, height); 742 voodoofb_bitblt(sc, xs, y, xd, y, width, height);
698 } 743 }
699} 744}
700 745
701static void 746static void
702voodoofb_erasecols(void *cookie, int row, int startcol, int ncols,  747voodoofb_erasecols(void *cookie, int row, int startcol, int ncols,
703 long fillattr) 748 long fillattr)
704{ 749{
705 struct rasops_info *ri = cookie; 750 struct rasops_info *ri = cookie;
706 struct vcons_screen *scr = ri->ri_hw; 751 struct vcons_screen *scr = ri->ri_hw;
707 struct voodoofb_softc *sc = scr->scr_cookie; 752 struct voodoofb_softc *sc = scr->scr_cookie;
708 int32_t x, y, width, height, fg, bg, ul; 753 int32_t x, y, width, height, fg, bg, ul;
709  754
710 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 755 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
711 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 756 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
712 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 757 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
713 width = ri->ri_font->fontwidth * ncols; 758 width = ri->ri_font->fontwidth * ncols;
714 height = ri->ri_font->fontheight;  759 height = ri->ri_font->fontheight;
715 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 760 rasops_unpack_attr(fillattr, &fg, &bg, &ul);
716  761
717 voodoofb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 762 voodoofb_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
718 } 763 }
719} 764}
720 765
721static void 766static void
722voodoofb_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 767voodoofb_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
723{ 768{
724 struct rasops_info *ri = cookie; 769 struct rasops_info *ri = cookie;
725 struct vcons_screen *scr = ri->ri_hw; 770 struct vcons_screen *scr = ri->ri_hw;
726 struct voodoofb_softc *sc = scr->scr_cookie; 771 struct voodoofb_softc *sc = scr->scr_cookie;
727 int32_t x, ys, yd, width, height; 772 int32_t x, ys, yd, width, height;
728 773
729 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 774 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
730 x = ri->ri_xorigin; 775 x = ri->ri_xorigin;
731 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 776 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
732 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 777 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
733 width = ri->ri_emuwidth; 778 width = ri->ri_emuwidth;
734 height = ri->ri_font->fontheight * nrows;  779 height = ri->ri_font->fontheight * nrows;
735 voodoofb_bitblt(sc, x, ys, x, yd, width, height); 780 voodoofb_bitblt(sc, x, ys, x, yd, width, height);
736 } 781 }
737} 782}
738 783
739static void 784static void
740voodoofb_eraserows(void *cookie, int row, int nrows, long fillattr) 785voodoofb_eraserows(void *cookie, int row, int nrows, long fillattr)
741{ 786{
742 struct rasops_info *ri = cookie; 787 struct rasops_info *ri = cookie;
743 struct vcons_screen *scr = ri->ri_hw; 788 struct vcons_screen *scr = ri->ri_hw;
744 struct voodoofb_softc *sc = scr->scr_cookie; 789 struct voodoofb_softc *sc = scr->scr_cookie;
745 int32_t x, y, width, height, fg, bg, ul; 790 int32_t x, y, width, height, fg, bg, ul;
746 791
747 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 792 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
748 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 793 rasops_unpack_attr(fillattr, &fg, &bg, &ul);
749 if ((row == 0) && (nrows == ri->ri_rows)) { 794 if ((row == 0) && (nrows == ri->ri_rows)) {
750 /* clear the whole screen */ 795 /* clear the whole screen */
751 voodoofb_rectfill(sc, 0, 0, ri->ri_width, 796 voodoofb_rectfill(sc, 0, 0, ri->ri_width,
752 ri->ri_height, ri->ri_devcmap[bg]); 797 ri->ri_height, ri->ri_devcmap[bg]);
753 } else { 798 } else {
754 x = ri->ri_xorigin; 799 x = ri->ri_xorigin;
755 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 800 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
756 width = ri->ri_emuwidth; 801 width = ri->ri_emuwidth;
757 height = ri->ri_font->fontheight * nrows;  802 height = ri->ri_font->fontheight * nrows;
758 voodoofb_rectfill(sc, x, y, width, height, 803 voodoofb_rectfill(sc, x, y, width, height,
759 ri->ri_devcmap[bg]); 804 ri->ri_devcmap[bg]);
760 } 805 }
761 } 806 }
762} 807}
763 808
764static void 809static void
765voodoofb_bitblt(struct voodoofb_softc *sc, int xs, int ys, int xd, int yd, int width, int height)  810voodoofb_bitblt(struct voodoofb_softc *sc, int xs, int ys, int xd, int yd, int width, int height)
766{ 811{
767 uint32_t fmt, blitcmd; 812 uint32_t fmt, blitcmd;
768  813
769 fmt = sc->linebytes | ((sc->bits_per_pixel +  814 fmt = sc->linebytes | ((sc->bits_per_pixel +
770 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13); 815 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13);
771 blitcmd = COMMAND_2D_S2S_BITBLT | (ROP_COPY << 24); 816 blitcmd = COMMAND_2D_S2S_BITBLT | (ROP_COPY << 24);
772 817
773 if (xs <= xd) { 818 if (xs <= xd) {
774 blitcmd |= BIT(14); 819 blitcmd |= BIT(14);
775 xs += (width - 1);  820 xs += (width - 1);
776 xd += (width - 1);  821 xd += (width - 1);
777 } 822 }
778 if (ys <= yd) { 823 if (ys <= yd) {
779 blitcmd |= BIT(15); 824 blitcmd |= BIT(15);
780 ys += (height - 1); 825 ys += (height - 1);
781 yd += (height - 1); 826 yd += (height - 1);
782 } 827 }
783 voodoo3_make_room(sc, 6); 828 voodoo3_make_room(sc, 6);
784  829
785 voodoo3_write32(sc, SRCFORMAT, fmt); 830 voodoo3_write32(sc, SRCFORMAT, fmt);
786 voodoo3_write32(sc, DSTFORMAT, fmt); 831 voodoo3_write32(sc, DSTFORMAT, fmt);
787 voodoo3_write32(sc, DSTSIZE, width | (height << 16)); 832 voodoo3_write32(sc, DSTSIZE, width | (height << 16));
788 voodoo3_write32(sc, DSTXY, xd | (yd << 16)); 833 voodoo3_write32(sc, DSTXY, xd | (yd << 16));
789 voodoo3_write32(sc, SRCXY, xs | (ys << 16));  834 voodoo3_write32(sc, SRCXY, xs | (ys << 16));
790 voodoo3_write32(sc, COMMAND_2D, blitcmd | SST_2D_GO);  835 voodoo3_write32(sc, COMMAND_2D, blitcmd | SST_2D_GO);
791} 836}
792  837
793static void 838static void
794voodoofb_rectfill(struct voodoofb_softc *sc, int x, int y, int width,  839voodoofb_rectfill(struct voodoofb_softc *sc, int x, int y, int width,
795 int height, int colour)  840 int height, int colour)
796{ 841{
797 uint32_t fmt, col; 842 uint32_t fmt, col;
798  843
799 col = (colour << 24) | (colour << 16) | (colour << 8) | colour; 844 col = (colour << 24) | (colour << 16) | (colour << 8) | colour;
800 fmt = sc->linebytes | ((sc->bits_per_pixel +  845 fmt = sc->linebytes | ((sc->bits_per_pixel +
801 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13); 846 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13);
802 847
803 voodoo3_make_room(sc, 6); 848 voodoo3_make_room(sc, 6);
804 voodoo3_write32(sc, DSTFORMAT, fmt); 849 voodoo3_write32(sc, DSTFORMAT, fmt);
805 voodoo3_write32(sc, COLORFORE, colour); 850 voodoo3_write32(sc, COLORFORE, colour);
806 voodoo3_write32(sc, COLORBACK, colour); 851 voodoo3_write32(sc, COLORBACK, colour);
807 voodoo3_write32(sc, COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24)); 852 voodoo3_write32(sc, COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24));
808 voodoo3_write32(sc, DSTSIZE, width | (height << 16)); 853 voodoo3_write32(sc, DSTSIZE, width | (height << 16));
809 voodoo3_write32(sc, LAUNCH_2D, x | (y << 16)); 854 voodoo3_write32(sc, LAUNCH_2D, x | (y << 16));
810} 855}
811 856
812static void 857static void
813voodoofb_rectinvert(struct voodoofb_softc *sc, int x, int y, int width,  858voodoofb_rectinvert(struct voodoofb_softc *sc, int x, int y, int width,
814 int height)  859 int height)
815{ 860{
816 uint32_t fmt; 861 uint32_t fmt;
817  862
818 fmt = sc->linebytes | ((sc->bits_per_pixel +  863 fmt = sc->linebytes | ((sc->bits_per_pixel +
819 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13); 864 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13);
820 865
821 voodoo3_make_room(sc, 6); 866 voodoo3_make_room(sc, 6);
822 voodoo3_write32(sc, DSTFORMAT, fmt); 867 voodoo3_write32(sc, DSTFORMAT, fmt);
823 voodoo3_write32(sc, COMMAND_2D, COMMAND_2D_FILLRECT |  868 voodoo3_write32(sc, COMMAND_2D, COMMAND_2D_FILLRECT |
824 (ROP_INVERT << 24)); 869 (ROP_INVERT << 24));
825 voodoo3_write32(sc, DSTSIZE, width | (height << 16)); 870 voodoo3_write32(sc, DSTSIZE, width | (height << 16));
826 voodoo3_write32(sc, DSTXY, x | (y << 16)); 871 voodoo3_write32(sc, DSTXY, x | (y << 16));
827 voodoo3_write32(sc, LAUNCH_2D, x | (y << 16)); 872 voodoo3_write32(sc, LAUNCH_2D, x | (y << 16));
828} 873}
829 874
830static void  875static void
831voodoofb_setup_mono(struct voodoofb_softc *sc, int xd, int yd, int width, int height, uint32_t fg, 876voodoofb_setup_mono(struct voodoofb_softc *sc, int xd, int yd, int width, int height, uint32_t fg,
832 uint32_t bg)  877 uint32_t bg)
833{ 878{
834 uint32_t dfmt, sfmt = sc->linebytes; 879 uint32_t dfmt, sfmt = sc->linebytes;
835  880
836 dfmt = sc->linebytes | ((sc->bits_per_pixel +  881 dfmt = sc->linebytes | ((sc->bits_per_pixel +
837 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13); 882 ((sc->bits_per_pixel == 8) ? 0 : 8)) << 13);
838 883
839 voodoo3_make_room(sc, 9); 884 voodoo3_make_room(sc, 9);
840 voodoo3_write32(sc, SRCFORMAT, sfmt); 885 voodoo3_write32(sc, SRCFORMAT, sfmt);
841 voodoo3_write32(sc, DSTFORMAT, dfmt); 886 voodoo3_write32(sc, DSTFORMAT, dfmt);
842 voodoo3_write32(sc, COLORFORE, fg); 887 voodoo3_write32(sc, COLORFORE, fg);
843 voodoo3_write32(sc, COLORBACK, bg); 888 voodoo3_write32(sc, COLORBACK, bg);
844 voodoo3_write32(sc, DSTSIZE, width | (height << 16)); 889 voodoo3_write32(sc, DSTSIZE, width | (height << 16));
845 voodoo3_write32(sc, DSTXY, xd | (yd << 16)); 890 voodoo3_write32(sc, DSTXY, xd | (yd << 16));
846 voodoo3_write32(sc, SRCXY, 0); 891 voodoo3_write32(sc, SRCXY, 0);
847 voodoo3_write32(sc, COMMAND_2D, COMMAND_2D_H2S_BITBLT |  892 voodoo3_write32(sc, COMMAND_2D, COMMAND_2D_H2S_BITBLT |
848 (ROP_COPY << 24) | SST_2D_GO); 893 (ROP_COPY << 24) | SST_2D_GO);
849  894
850 /* now feed the data into the chip */ 895 /* now feed the data into the chip */
851} 896}
852 897
853static void  898static void
854voodoofb_feed_line(struct voodoofb_softc *sc, int count, uint8_t *data) 899voodoofb_feed_line(struct voodoofb_softc *sc, int count, uint8_t *data)
855{ 900{
856 int i; 901 int i;
857 uint32_t latch = 0, bork; 902 uint32_t latch = 0, bork;
858 int shift = 0; 903 int shift = 0;
859  904
860 voodoo3_make_room(sc, count); 905 voodoo3_make_room(sc, count);
861 for (i = 0; i < count; i++) { 906 for (i = 0; i < count; i++) {
862 bork = data[i]; 907 bork = data[i];
863 latch |= (bork << shift); 908 latch |= (bork << shift);
864 if (shift == 24) { 909 if (shift == 24) {
865 voodoo3_write32(sc, LAUNCH_2D, latch); 910 voodoo3_write32(sc, LAUNCH_2D, latch);
866 latch = 0; 911 latch = 0;
867 shift = 0; 912 shift = 0;
868 } else 913 } else
869 shift += 8; 914 shift += 8;
870 } 915 }
871 if (shift != 24) 916 if (shift != 24)
872 voodoo3_write32(sc, LAUNCH_2D, latch); 917 voodoo3_write32(sc, LAUNCH_2D, latch);
873}  918}
874 919
875#if 0 920#if 0
876static int 921static int
877voodoofb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp) 922voodoofb_allocattr(void *cookie, int fg, int bg, int flags, long *attrp)
878{ 923{
879 924
880 return 0; 925 return 0;
881} 926}
882#endif 927#endif
883 928
884/* 929/*
885 * wsdisplay_accessops 930 * wsdisplay_accessops
886 */ 931 */
887 932
888static int 933static int
889voodoofb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 934voodoofb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
890 struct lwp *l) 935 struct lwp *l)
891{ 936{
892 struct vcons_data *vd = v; 937 struct vcons_data *vd = v;
893 struct voodoofb_softc *sc = vd->cookie; 938 struct voodoofb_softc *sc = vd->cookie;
894 struct wsdisplay_fbinfo *wdf; 939 struct wsdisplay_fbinfo *wdf;
895 struct vcons_screen *ms = vd->active; 940 struct vcons_screen *ms = vd->active;
896 941
897 switch (cmd) { 942 switch (cmd) {
898 case WSDISPLAYIO_GTYPE: 943 case WSDISPLAYIO_GTYPE:
899 *(u_int *)data = WSDISPLAY_TYPE_PCIMISC; 944 *(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
900 return 0; 945 return 0;
901 946
902 case WSDISPLAYIO_GINFO: 947 case WSDISPLAYIO_GINFO:
903 wdf = (void *)data; 948 wdf = (void *)data;
904 wdf->height = ms->scr_ri.ri_height; 949 wdf->height = ms->scr_ri.ri_height;
905 wdf->width = ms->scr_ri.ri_width; 950 wdf->width = ms->scr_ri.ri_width;
906 wdf->depth = ms->scr_ri.ri_depth; 951 wdf->depth = ms->scr_ri.ri_depth;
907 wdf->cmsize = 256; 952 wdf->cmsize = 256;
908 return 0; 953 return 0;
909  954
910 case WSDISPLAYIO_GETCMAP: 955 case WSDISPLAYIO_GETCMAP:
911 return voodoofb_getcmap(sc, 956 return voodoofb_getcmap(sc,
912 (struct wsdisplay_cmap *)data); 957 (struct wsdisplay_cmap *)data);
913 958
914 case WSDISPLAYIO_PUTCMAP: 959 case WSDISPLAYIO_PUTCMAP:
915 return voodoofb_putcmap(sc, 960 return voodoofb_putcmap(sc,
916 (struct wsdisplay_cmap *)data); 961 (struct wsdisplay_cmap *)data);
917 962
918 /* PCI config read/write passthrough. */ 963 /* PCI config read/write passthrough. */
919 case PCI_IOC_CFGREAD: 964 case PCI_IOC_CFGREAD:
920 case PCI_IOC_CFGWRITE: 965 case PCI_IOC_CFGWRITE:
921 return pci_devioctl(sc->sc_pc, sc->sc_pcitag, 966 return pci_devioctl(sc->sc_pc, sc->sc_pcitag,
922 cmd, data, flag, l); 967 cmd, data, flag, l);
923 968
924 case WSDISPLAYIO_GET_BUSID: 969 case WSDISPLAYIO_GET_BUSID:
925 return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc, 970 return wsdisplayio_busid_pci(sc->sc_dev, sc->sc_pc,
926 sc->sc_pcitag, data); 971 sc->sc_pcitag, data);
927 972
928 case WSDISPLAYIO_SMODE: { 973 case WSDISPLAYIO_SMODE: {
929 int new_mode = *(int*)data; 974 int new_mode = *(int*)data;
930 if (new_mode != sc->sc_mode) { 975 if (new_mode != sc->sc_mode) {
931 sc->sc_mode = new_mode; 976 sc->sc_mode = new_mode;
932 if (new_mode == WSDISPLAYIO_MODE_EMUL) { 977 if (new_mode == WSDISPLAYIO_MODE_EMUL) {
933 voodoofb_drm_map(sc); 978 voodoofb_drm_map(sc);
934 int i; 979 int i;
935  980
936 /* restore the palette */ 981 /* restore the palette */
937 for (i = 0; i < 256; i++) { 982 for (i = 0; i < 256; i++) {
938 voodoofb_putpalreg(sc,  983 voodoofb_putpalreg(sc,
939 i,  984 i,
940 sc->sc_cmap_red[i],  985 sc->sc_cmap_red[i],
941 sc->sc_cmap_green[i], 986 sc->sc_cmap_green[i],
942 sc->sc_cmap_blue[i]); 987 sc->sc_cmap_blue[i]);
943 } 988 }
944 vcons_redraw_screen(ms); 989 vcons_redraw_screen(ms);
945 } else 990 } else
946 voodoofb_drm_unmap(sc); 991 voodoofb_drm_unmap(sc);
947 } 992 }
948 } 993 }
949 return 0; 994 return 0;
950 } 995 }
951 return EPASSTHROUGH; 996 return EPASSTHROUGH;
952} 997}
953 998
954static paddr_t 999static paddr_t
955voodoofb_mmap(void *v, void *vs, off_t offset, int prot) 1000voodoofb_mmap(void *v, void *vs, off_t offset, int prot)
956{ 1001{
957 struct vcons_data *vd = v; 1002 struct vcons_data *vd = v;
958 struct voodoofb_softc *sc = vd->cookie; 1003 struct voodoofb_softc *sc = vd->cookie;
959 paddr_t pa; 1004 paddr_t pa;
960  1005
961 /* 'regular' framebuffer mmap()ing */ 1006 /* 'regular' framebuffer mmap()ing */
962 if (offset < sc->sc_fbsize) { 1007 if (offset < sc->sc_fbsize) {
963 pa = bus_space_mmap(sc->sc_fbt, offset, 0, prot,  1008 pa = bus_space_mmap(sc->sc_fbt, offset, 0, prot,
964 BUS_SPACE_MAP_LINEAR);  1009 BUS_SPACE_MAP_LINEAR);
965 return pa; 1010 return pa;
966 } 1011 }
967 1012
968 /* 1013 /*
969 * restrict all other mappings to processes with superuser privileges 1014 * restrict all other mappings to processes with superuser privileges
970 * or the kernel itself 1015 * or the kernel itself
971 */ 1016 */
972 if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER, 1017 if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER,
973 NULL) != 0) { 1018 NULL) != 0) {
974 aprint_error_dev(sc->sc_dev, "mmap() rejected.\n"); 1019 aprint_error_dev(sc->sc_dev, "mmap() rejected.\n");
975 return -1; 1020 return -1;
976 } 1021 }
977 1022
978 if ((offset >= sc->sc_fb) && (offset < (sc->sc_fb + sc->sc_fbsize))) { 1023 if ((offset >= sc->sc_fb) && (offset < (sc->sc_fb + sc->sc_fbsize))) {
979 pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,  1024 pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
980 BUS_SPACE_MAP_LINEAR);  1025 BUS_SPACE_MAP_LINEAR);
981 return pa; 1026 return pa;
982 } 1027 }
983 1028
984 if ((offset >= sc->sc_regs) && (offset < (sc->sc_regs +  1029 if ((offset >= sc->sc_regs) && (offset < (sc->sc_regs +
985 sc->sc_regsize))) { 1030 sc->sc_regsize))) {
986 pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,  1031 pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
987 BUS_SPACE_MAP_LINEAR);  1032 BUS_SPACE_MAP_LINEAR);
988 return pa; 1033 return pa;
989 } 1034 }
990 1035
991#ifdef PCI_MAGIC_IO_RANGE 1036#ifdef PCI_MAGIC_IO_RANGE
992 /* allow mapping of IO space */ 1037 /* allow mapping of IO space */
993 if ((offset >= PCI_MAGIC_IO_RANGE) &&\ 1038 if ((offset >= PCI_MAGIC_IO_RANGE) &&\
994 (offset < PCI_MAGIC_IO_RANGE + 0x10000)) { 1039 (offset < PCI_MAGIC_IO_RANGE + 0x10000)) {
995 pa = bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE, 1040 pa = bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE,
996 0, prot, BUS_SPACE_MAP_LINEAR);  1041 0, prot, BUS_SPACE_MAP_LINEAR);
997 return pa; 1042 return pa;
998 }  1043 }
999#endif 1044#endif
1000 1045
1001#ifdef OFB_ALLOW_OTHERS 1046#ifdef OFB_ALLOW_OTHERS
1002 if (offset >= 0x80000000) { 1047 if (offset >= 0x80000000) {
1003 pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,  1048 pa = bus_space_mmap(sc->sc_memt, offset, 0, prot,
1004 BUS_SPACE_MAP_LINEAR);  1049 BUS_SPACE_MAP_LINEAR);
1005 return pa; 1050 return pa;
1006 }  1051 }
1007#endif 1052#endif
1008 return -1; 1053 return -1;
1009} 1054}
1010 1055
1011static void 1056static void
1012voodoofb_init_screen(void *cookie, struct vcons_screen *scr, 1057voodoofb_init_screen(void *cookie, struct vcons_screen *scr,
1013 int existing, long *defattr) 1058 int existing, long *defattr)
1014{ 1059{
1015 struct voodoofb_softc *sc = cookie; 1060 struct voodoofb_softc *sc = cookie;
1016 struct rasops_info *ri = &scr->scr_ri; 1061 struct rasops_info *ri = &scr->scr_ri;
1017  1062
1018 ri->ri_depth = sc->bits_per_pixel; 1063 ri->ri_depth = sc->bits_per_pixel;
1019 ri->ri_width = sc->width; 1064 ri->ri_width = sc->width;
1020 ri->ri_height = sc->height; 1065 ri->ri_height = sc->height;
1021 ri->ri_stride = sc->width; 1066 ri->ri_stride = sc->width;
1022 ri->ri_flg = RI_CENTER | RI_FULLCLEAR; 1067 ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
1023 1068
1024 ri->ri_bits = bus_space_vaddr(sc->sc_fbt, sc->sc_fbh); 1069 ri->ri_bits = bus_space_vaddr(sc->sc_fbt, sc->sc_fbh);
1025 1070
1026#ifdef VOODOOFB_DEBUG 1071#ifdef VOODOOFB_DEBUG
1027 printf("addr: %08lx\n", (ulong)ri->ri_bits); 1072 printf("addr: %08lx\n", (ulong)ri->ri_bits);
1028#endif 1073#endif
1029 if (existing) { 1074 if (existing) {
1030 ri->ri_flg |= RI_CLEAR; 1075 ri->ri_flg |= RI_CLEAR;
1031 } 1076 }
1032  1077
1033 rasops_init(ri, 0, 0); 1078 rasops_init(ri, 0, 0);
1034 ri->ri_caps = WSSCREEN_WSCOLORS; 1079 ri->ri_caps = WSSCREEN_WSCOLORS;
1035 1080
1036 rasops_reconfig(ri, sc->height / ri->ri_font->fontheight, 1081 rasops_reconfig(ri, sc->height / ri->ri_font->fontheight,
1037 sc->width / ri->ri_font->fontwidth); 1082 sc->width / ri->ri_font->fontwidth);
1038 1083
1039 ri->ri_hw = scr; 1084 ri->ri_hw = scr;
1040 ri->ri_ops.copyrows = voodoofb_copyrows; 1085 ri->ri_ops.copyrows = voodoofb_copyrows;
1041 ri->ri_ops.copycols = voodoofb_copycols; 1086 ri->ri_ops.copycols = voodoofb_copycols;
1042 ri->ri_ops.eraserows = voodoofb_eraserows; 1087 ri->ri_ops.eraserows = voodoofb_eraserows;
1043 ri->ri_ops.erasecols = voodoofb_erasecols; 1088 ri->ri_ops.erasecols = voodoofb_erasecols;
1044 ri->ri_ops.cursor = voodoofb_cursor; 1089 ri->ri_ops.cursor = voodoofb_cursor;
1045 ri->ri_ops.putchar = voodoofb_putchar; 1090 ri->ri_ops.putchar = voodoofb_putchar;
1046} 1091}
1047 1092
1048#if 0 1093#if 0
1049int 1094int
1050voodoofb_load_font(void *v, void *cookie, struct wsdisplay_font *data) 1095voodoofb_load_font(void *v, void *cookie, struct wsdisplay_font *data)
1051{ 1096{
1052 1097
1053 return 0; 1098 return 0;
1054} 1099}
1055#endif 1100#endif
1056 1101
1057#ifdef VOODOOFB_ENABLE_INTR 1102#ifdef VOODOOFB_ENABLE_INTR
1058static int 1103static int
1059voodoofb_intr(void *arg) 1104voodoofb_intr(void *arg)
1060{ 1105{
1061 struct voodoofb_softc *sc = arg; 1106 struct voodoofb_softc *sc = arg;
1062 1107
1063 voodoo3_write32(sc, V3_STATUS, 0); /* clear interrupts */ 1108 voodoo3_write32(sc, V3_STATUS, 0); /* clear interrupts */
1064 return 1; 1109 return 1;
1065} 1110}
1066#endif 1111#endif
1067 1112
1068/* video mode stuff */ 1113/* video mode stuff */
1069 1114
1070#define REFFREQ 14318 /* .18 */ 1115#define REFFREQ 14318 /* .18 */
1071 1116
1072#define ABS(a) ((a < 0) ? -a : a) 1117#define ABS(a) ((a < 0) ? -a : a)
1073 1118
1074static int 1119static int
1075voodoofb_calc_pll(int freq, int *f_out, int isBanshee) 1120voodoofb_calc_pll(int freq, int *f_out, int isBanshee)
1076{ 1121{
1077 int m, n, k, best_m, best_n, best_k, f_cur, best_error; 1122 int m, n, k, best_m, best_n, best_k, f_cur, best_error;
1078 int minm, maxm; 1123 int minm, maxm;
1079 1124
1080 best_error = freq; 1125 best_error = freq;
1081 best_n = best_m = best_k = 0; 1126 best_n = best_m = best_k = 0;
1082 1127
1083 if (isBanshee) { 1128 if (isBanshee) {
1084 minm = 24; 1129 minm = 24;
1085 maxm = 24; 1130 maxm = 24;
1086 } else { 1131 } else {
1087 minm = 1; 1132 minm = 1;
1088 maxm = 57;  1133 maxm = 57;
1089 /* This used to be 64, alas it seems the last 8 (funny that ?) 1134 /* This used to be 64, alas it seems the last 8 (funny that ?)
1090 * values cause jittering at lower resolutions. I've not done 1135 * values cause jittering at lower resolutions. I've not done
1091 * any calculations to what the adjustment affects clock ranges, 1136 * any calculations to what the adjustment affects clock ranges,
1092 * but I can still run at 1600x1200@75Hz */ 1137 * but I can still run at 1600x1200@75Hz */
1093 } 1138 }
1094 for (n = 1; n < 256; n++) { 1139 for (n = 1; n < 256; n++) {
1095 f_cur = REFFREQ * (n + 2); 1140 f_cur = REFFREQ * (n + 2);
1096 if (f_cur < freq) { 1141 if (f_cur < freq) {
1097 f_cur = f_cur / 3; 1142 f_cur = f_cur / 3;
1098 if (freq - f_cur < best_error) { 1143 if (freq - f_cur < best_error) {
1099 best_error = freq - f_cur; 1144 best_error = freq - f_cur;
1100 best_n = n; 1145 best_n = n;
1101 best_m = 1; 1146 best_m = 1;
1102 best_k = 0; 1147 best_k = 0;
1103 continue; 1148 continue;
1104 } 1149 }
1105 } 1150 }
1106 for (m = minm; m < maxm; m++) { 1151 for (m = minm; m < maxm; m++) {
1107 for (k = 0; k < 4; k++) { 1152 for (k = 0; k < 4; k++) {
1108 f_cur = REFFREQ * (n + 2) / (m + 2) / (1 << k); 1153 f_cur = REFFREQ * (n + 2) / (m + 2) / (1 << k);
1109 if (ABS(f_cur - freq) < best_error) { 1154 if (ABS(f_cur - freq) < best_error) {
1110 best_error = ABS(f_cur - freq); 1155 best_error = ABS(f_cur - freq);
1111 best_n = n; 1156 best_n = n;
1112 best_m = m; 1157 best_m = m;
1113 best_k = k; 1158 best_k = k;
1114 } 1159 }
1115 } 1160 }
1116 } 1161 }
1117 } 1162 }
1118 n = best_n; 1163 n = best_n;
1119 m = best_m; 1164 m = best_m;
1120 k = best_k; 1165 k = best_k;
1121 *f_out = REFFREQ * (n + 2) / (m + 2) / (1 << k); 1166 *f_out = REFFREQ * (n + 2) / (m + 2) / (1 << k);
1122 return ( n << 8) | (m << 2) | k; 1167 return ( n << 8) | (m << 2) | k;
1123} 1168}
1124 1169
1125static void 1170static void
1126voodoofb_setup_monitor(struct voodoofb_softc *sc, const struct videomode *vm) 1171voodoofb_setup_monitor(struct voodoofb_softc *sc, const struct videomode *vm)
1127{ 1172{
1128 struct voodoo_regs mod; 1173 struct voodoo_regs mod;
1129 struct voodoo_regs *mode; 1174 struct voodoo_regs *mode;
1130 uint32_t horizontal_display_end, horizontal_sync_start, 1175 uint32_t horizontal_display_end, horizontal_sync_start,
1131 horizontal_sync_end, horizontal_total, 1176 horizontal_sync_end, horizontal_total,
1132 horizontal_blanking_start, horizontal_blanking_end; 1177 horizontal_blanking_start, horizontal_blanking_end;
1133  1178
1134 uint32_t vertical_display_enable_end, vertical_sync_start, 1179 uint32_t vertical_display_enable_end, vertical_sync_start,
1135 vertical_sync_end, vertical_total, vertical_blanking_start, 1180 vertical_sync_end, vertical_total, vertical_blanking_start,
1136 vertical_blanking_end; 1181 vertical_blanking_end;
1137  1182
1138 uint32_t wd; // CRTC offset 1183 uint32_t wd; // CRTC offset
1139 1184
1140 int i; 1185 int i;
1141 1186
1142 uint8_t misc; 1187 uint8_t misc;
1143 1188
1144 memset(&mod, 0, sizeof(mode)); 1189 memset(&mod, 0, sizeof(mode));
1145  1190
1146 mode = &mod; 1191 mode = &mod;
1147  1192
1148 wd = (vm->hdisplay >> 3) - 1; 1193 wd = (vm->hdisplay >> 3) - 1;
1149 horizontal_display_end = (vm->hdisplay >> 3) - 1; 1194 horizontal_display_end = (vm->hdisplay >> 3) - 1;
1150 horizontal_sync_start = (vm->hsync_start >> 3) - 1; 1195 horizontal_sync_start = (vm->hsync_start >> 3) - 1;
1151 horizontal_sync_end = (vm->hsync_end >> 3) - 1; 1196 horizontal_sync_end = (vm->hsync_end >> 3) - 1;
1152 horizontal_total = (vm->htotal >> 3) - 1; 1197 horizontal_total = (vm->htotal >> 3) - 1;
1153 horizontal_blanking_start = horizontal_display_end; 1198 horizontal_blanking_start = horizontal_display_end;
1154 horizontal_blanking_end = horizontal_total; 1199 horizontal_blanking_end = horizontal_total;
1155 1200
1156 vertical_display_enable_end = vm->vdisplay - 1; 1201 vertical_display_enable_end = vm->vdisplay - 1;
1157 vertical_sync_start = vm->vsync_start; // - 1; 1202 vertical_sync_start = vm->vsync_start; // - 1;
1158 vertical_sync_end = vm->vsync_end; // - 1; 1203 vertical_sync_end = vm->vsync_end; // - 1;
1159 vertical_total = vm->vtotal - 2; 1204 vertical_total = vm->vtotal - 2;
1160 vertical_blanking_start = vertical_display_enable_end; 1205 vertical_blanking_start = vertical_display_enable_end;
1161 vertical_blanking_end = vertical_total; 1206 vertical_blanking_end = vertical_total;
1162  1207
1163 misc = 0x0f | 1208 misc = 0x0f |
1164 (vm->hdisplay < 400 ? 0xa0 : 1209 (vm->hdisplay < 400 ? 0xa0 :
1165 vm->hdisplay < 480 ? 0x60 : 1210 vm->hdisplay < 480 ? 0x60 :
1166 vm->hdisplay < 768 ? 0xe0 : 0x20); 1211 vm->hdisplay < 768 ? 0xe0 : 0x20);
1167  1212
1168 mode->vr_seq[0] = 3; 1213 mode->vr_seq[0] = 3;
1169 mode->vr_seq[1] = 1; 1214 mode->vr_seq[1] = 1;
1170 mode->vr_seq[2] = 8; 1215 mode->vr_seq[2] = 8;
1171 mode->vr_seq[3] = 0; 1216 mode->vr_seq[3] = 0;
1172 mode->vr_seq[4] = 6; 1217 mode->vr_seq[4] = 6;
1173  1218
1174 /* crtc regs start */ 1219 /* crtc regs start */
1175 mode->vr_crtc[0] = horizontal_total - 4; 1220 mode->vr_crtc[0] = horizontal_total - 4;
1176 mode->vr_crtc[1] = horizontal_display_end; 1221 mode->vr_crtc[1] = horizontal_display_end;
1177 mode->vr_crtc[2] = horizontal_blanking_start; 1222 mode->vr_crtc[2] = horizontal_blanking_start;
1178 mode->vr_crtc[3] = 0x80 | (horizontal_blanking_end & 0x1f); 1223 mode->vr_crtc[3] = 0x80 | (horizontal_blanking_end & 0x1f);
1179 mode->vr_crtc[4] = horizontal_sync_start; 1224 mode->vr_crtc[4] = horizontal_sync_start;
1180  1225
1181 mode->vr_crtc[5] = ((horizontal_blanking_end & 0x20) << 2) | 1226 mode->vr_crtc[5] = ((horizontal_blanking_end & 0x20) << 2) |
1182 (horizontal_sync_end & 0x1f); 1227 (horizontal_sync_end & 0x1f);
1183 mode->vr_crtc[6] = vertical_total; 1228 mode->vr_crtc[6] = vertical_total;
1184 mode->vr_crtc[7] = ((vertical_sync_start & 0x200) >> 2) | 1229 mode->vr_crtc[7] = ((vertical_sync_start & 0x200) >> 2) |
1185 ((vertical_display_enable_end & 0x200) >> 3) | 1230 ((vertical_display_enable_end & 0x200) >> 3) |
1186 ((vertical_total & 0x200) >> 4) | 1231 ((vertical_total & 0x200) >> 4) |
1187 0x10 | 1232 0x10 |
1188 ((vertical_blanking_start & 0x100) >> 5) | 1233 ((vertical_blanking_start & 0x100) >> 5) |
1189 ((vertical_sync_start & 0x100) >> 6) | 1234 ((vertical_sync_start & 0x100) >> 6) |
1190 ((vertical_display_enable_end & 0x100) >> 7) | 1235 ((vertical_display_enable_end & 0x100) >> 7) |
1191 ((vertical_total & 0x100) >> 8); 1236 ((vertical_total & 0x100) >> 8);
1192  1237
1193 mode->vr_crtc[8] = 0; 1238 mode->vr_crtc[8] = 0;
1194 mode->vr_crtc[9] = 0x40 | 1239 mode->vr_crtc[9] = 0x40 |
1195 ((vertical_blanking_start & 0x200) >> 4); 1240 ((vertical_blanking_start & 0x200) >> 4);
1196  1241
1197 mode->vr_crtc[10] = 0; 1242 mode->vr_crtc[10] = 0;
1198 mode->vr_crtc[11] = 0; 1243 mode->vr_crtc[11] = 0;
1199 mode->vr_crtc[12] = 0; 1244 mode->vr_crtc[12] = 0;
1200 mode->vr_crtc[13] = 0; 1245 mode->vr_crtc[13] = 0;
1201 mode->vr_crtc[14] = 0; 1246 mode->vr_crtc[14] = 0;
1202 mode->vr_crtc[15] = 0; 1247 mode->vr_crtc[15] = 0;
1203  1248
1204 mode->vr_crtc[16] = vertical_sync_start; 1249 mode->vr_crtc[16] = vertical_sync_start;
1205 mode->vr_crtc[17] = (vertical_sync_end & 0x0f) | 0x20; 1250 mode->vr_crtc[17] = (vertical_sync_end & 0x0f) | 0x20;
1206 mode->vr_crtc[18] = vertical_display_enable_end; 1251 mode->vr_crtc[18] = vertical_display_enable_end;
1207 mode->vr_crtc[19] = wd; // CRTC offset 1252 mode->vr_crtc[19] = wd; // CRTC offset
1208 mode->vr_crtc[20] = 0; 1253 mode->vr_crtc[20] = 0;
1209 mode->vr_crtc[21] = vertical_blanking_start; 1254 mode->vr_crtc[21] = vertical_blanking_start;
1210 mode->vr_crtc[22] = vertical_blanking_end + 1; 1255 mode->vr_crtc[22] = vertical_blanking_end + 1;
1211 mode->vr_crtc[23] = 128; 1256 mode->vr_crtc[23] = 128;
1212 mode->vr_crtc[24] = 255; 1257 mode->vr_crtc[24] = 255;
1213 1258
1214 /* overflow registers */ 1259 /* overflow registers */
1215 mode->vr_crtc[CRTC_HDISP_EXT] = 1260 mode->vr_crtc[CRTC_HDISP_EXT] =
1216 (horizontal_total&0x100) >> 8 | 1261 (horizontal_total&0x100) >> 8 |
1217 (horizontal_display_end & 0x100) >> 6 |  1262 (horizontal_display_end & 0x100) >> 6 |
1218 (horizontal_blanking_start & 0x100) >> 4 | 1263 (horizontal_blanking_start & 0x100) >> 4 |
1219 (horizontal_blanking_end & 0x40) >> 1 | 1264 (horizontal_blanking_end & 0x40) >> 1 |
1220 (horizontal_sync_start & 0x100) >> 2 | 1265 (horizontal_sync_start & 0x100) >> 2 |
1221 (horizontal_sync_end & 0x20) << 2; 1266 (horizontal_sync_end & 0x20) << 2;
1222  1267
1223 mode->vr_crtc[CRTC_VDISP_EXT] = 1268 mode->vr_crtc[CRTC_VDISP_EXT] =
1224 (vertical_total & 0x400) >> 10 | 1269 (vertical_total & 0x400) >> 10 |
1225 (vertical_display_enable_end & 0x400) >> 8 | 1270 (vertical_display_enable_end & 0x400) >> 8 |
1226 (vertical_blanking_start & 0x400) >> 6 | 1271 (vertical_blanking_start & 0x400) >> 6 |
1227 (vertical_blanking_end & 0x400) >> 4; 1272 (vertical_blanking_end & 0x400) >> 4;
1228  1273
1229 /* attr regs start */ 1274 /* attr regs start */
1230 mode->vr_attr[0] = 0; 1275 mode->vr_attr[0] = 0;
1231 mode->vr_attr[1] = 0; 1276 mode->vr_attr[1] = 0;
1232 mode->vr_attr[2] = 0; 1277 mode->vr_attr[2] = 0;
1233 mode->vr_attr[3] = 0; 1278 mode->vr_attr[3] = 0;
1234 mode->vr_attr[4] = 0; 1279 mode->vr_attr[4] = 0;
1235 mode->vr_attr[5] = 0; 1280 mode->vr_attr[5] = 0;
1236 mode->vr_attr[6] = 0; 1281 mode->vr_attr[6] = 0;
1237 mode->vr_attr[7] = 0; 1282 mode->vr_attr[7] = 0;
1238 mode->vr_attr[8] = 0; 1283 mode->vr_attr[8] = 0;
1239 mode->vr_attr[9] = 0; 1284 mode->vr_attr[9] = 0;
1240 mode->vr_attr[10] = 0; 1285 mode->vr_attr[10] = 0;
1241 mode->vr_attr[11] = 0; 1286 mode->vr_attr[11] = 0;
1242 mode->vr_attr[12] = 0; 1287 mode->vr_attr[12] = 0;
1243 mode->vr_attr[13] = 0; 1288 mode->vr_attr[13] = 0;
1244 mode->vr_attr[14] = 0; 1289 mode->vr_attr[14] = 0;
1245 mode->vr_attr[15] = 0; 1290 mode->vr_attr[15] = 0;
1246 mode->vr_attr[16] = 1; 1291 mode->vr_attr[16] = 1;
1247 mode->vr_attr[17] = 0; 1292 mode->vr_attr[17] = 0;
1248 mode->vr_attr[18] = 15; 1293 mode->vr_attr[18] = 15;
1249 mode->vr_attr[19] = 0; 1294 mode->vr_attr[19] = 0;
1250 /* attr regs end */ 1295 /* attr regs end */
1251 1296
1252 /* graph regs start */ 1297 /* graph regs start */
1253 mode->vr_graph[0] = 159; 1298 mode->vr_graph[0] = 159;
1254 mode->vr_graph[1] = 127; 1299 mode->vr_graph[1] = 127;
1255 mode->vr_graph[2] = 127; 1300 mode->vr_graph[2] = 127;
1256 mode->vr_graph[3] = 131; 1301 mode->vr_graph[3] = 131;
1257 mode->vr_graph[4] = 130; 1302 mode->vr_graph[4] = 130;
1258 mode->vr_graph[5] = 142; 1303 mode->vr_graph[5] = 142;
1259 mode->vr_graph[6] = 30; 1304 mode->vr_graph[6] = 30;
1260 mode->vr_graph[7] = 245; 1305 mode->vr_graph[7] = 245;
1261 mode->vr_graph[8] = 0; 1306 mode->vr_graph[8] = 0;
1262 1307
1263 vga_outb(sc, MISC_W, misc | 0x01); 1308 vga_outb(sc, MISC_W, misc | 0x01);
1264  1309
1265 for(i = 0; i < 5; i++) 1310 for(i = 0; i < 5; i++)
1266 voodoo3_write_seq(sc, i, mode->vr_seq[i]); 1311 voodoo3_write_seq(sc, i, mode->vr_seq[i]);
1267 for (i = 0; i < CRTC_PCI_READBACK; i ++) 1312 for (i = 0; i < CRTC_PCI_READBACK; i ++)
1268 voodoo3_write_crtc(sc, i, mode->vr_crtc[i]); 1313 voodoo3_write_crtc(sc, i, mode->vr_crtc[i]);
1269 for (i = 0; i < 0x14; i ++) 1314 for (i = 0; i < 0x14; i ++)
1270 voodoo3_write_attr(sc, i, mode->vr_attr[i]); 1315 voodoo3_write_attr(sc, i, mode->vr_attr[i]);
1271 for (i = 0; i < 0x09; i ++) 1316 for (i = 0; i < 0x09; i ++)
1272 voodoo3_write_gra(sc, i, mode->vr_graph[i]); 1317 voodoo3_write_gra(sc, i, mode->vr_graph[i]);
1273} 1318}
1274 1319
1275static void 1320static void
1276voodoofb_set_videomode(struct voodoofb_softc *sc,  1321voodoofb_set_videomode(struct voodoofb_softc *sc,
1277 const struct videomode *vm) 1322 const struct videomode *vm)
1278{ 1323{
1279 uint32_t miscinit0 = 0; 1324 uint32_t miscinit0 = 0;
1280 int vidpll, fout; 1325 int vidpll, fout;
1281 uint32_t vp, vidproc = VIDPROCDEFAULT; 1326 uint32_t vp, vidproc = VIDPROCDEFAULT;
1282 uint32_t bpp = 1; /* for now */ 1327 uint32_t bpp = 1; /* for now */
1283 uint32_t bytes_per_row = vm->hdisplay * bpp; 1328 uint32_t bytes_per_row = vm->hdisplay * bpp;
1284 1329
1285 sc->bits_per_pixel = bpp << 3; 1330 sc->bits_per_pixel = bpp << 3;
1286 sc->width = vm->hdisplay; 1331 sc->width = vm->hdisplay;
1287 sc->height = vm->vdisplay; 1332 sc->height = vm->vdisplay;
1288 sc->linebytes = bytes_per_row; 1333 sc->linebytes = bytes_per_row;
1289  1334
1290 voodoofb_setup_monitor(sc, vm); 1335 voodoofb_setup_monitor(sc, vm);
1291 vp = voodoo3_read32(sc, VIDPROCCFG); 1336 vp = voodoo3_read32(sc, VIDPROCCFG);
1292  1337
1293 vidproc &= ~(0x1c0000); /* clear bits 18 to 20, bpp in vidproccfg */ 1338 vidproc &= ~(0x1c0000); /* clear bits 18 to 20, bpp in vidproccfg */
1294 /* enable bits 18 to 20 to the required bpp */ 1339 /* enable bits 18 to 20 to the required bpp */
1295 vidproc |= ((bpp - 1) << VIDCFG_PIXFMT_SHIFT); 1340 vidproc |= ((bpp - 1) << VIDCFG_PIXFMT_SHIFT);
1296  1341
1297 vidpll = voodoofb_calc_pll(vm->dot_clock, &fout, 0); 1342 vidpll = voodoofb_calc_pll(vm->dot_clock, &fout, 0);
1298 1343
1299#ifdef VOODOOFB_DEBUG 1344#ifdef VOODOOFB_DEBUG
1300 printf("old vidproc: %08x\n", vp); 1345 printf("old vidproc: %08x\n", vp);
1301 printf("pll: %08x %d\n", vidpll, fout); 1346 printf("pll: %08x %d\n", vidpll, fout);
1302#endif 1347#endif
1303 /* bit 10 of vidproccfg, is enabled or disabled as needed */ 1348 /* bit 10 of vidproccfg, is enabled or disabled as needed */
1304 switch (bpp) {  1349 switch (bpp) {
1305 case 1: 1350 case 1:
1306 /* 1351 /*
1307 * bit 10 off for palettized modes only, off means 1352 * bit 10 off for palettized modes only, off means
1308 * palette is used 1353 * palette is used
1309 */ 1354 */
1310 vidproc &= ~(1 << 10); 1355 vidproc &= ~(1 << 10);
1311 break; 1356 break;
1312#if 0 1357#if 0
1313 case 2: 1358 case 2:
1314 #if __POWERPC__ 1359 #if __POWERPC__
1315 miscinit0 = 0xc0000000; 1360 miscinit0 = 0xc0000000;
1316 #endif 1361 #endif
1317 /* bypass palette for 16bit modes */ 1362 /* bypass palette for 16bit modes */
1318 vidproc |= (1 << 10); 1363 vidproc |= (1 << 10);
1319 break; 1364 break;
1320 case 4: 1365 case 4:
1321 #if __POWERPC__ 1366 #if __POWERPC__
1322 miscinit0 = 0x40000000; 1367 miscinit0 = 0x40000000;
1323 #endif  1368 #endif
1324 vidproc |= (1 << 10); /* Same for 32bit modes */ 1369 vidproc |= (1 << 10); /* Same for 32bit modes */
1325 break; 1370 break;
1326#endif 1371#endif
1327 default: 1372 default:
1328 printf("We support only 8 bit for now\n"); 1373 printf("We support only 8 bit for now\n");
1329 return; 1374 return;
1330 } 1375 }
1331  1376
1332 voodoofb_wait_idle(sc); 1377 voodoofb_wait_idle(sc);
1333  1378
1334 voodoo3_write32(sc, MISCINIT1, voodoo3_read32(sc, MISCINIT1) | 0x01); 1379 voodoo3_write32(sc, MISCINIT1, voodoo3_read32(sc, MISCINIT1) | 0x01);
1335 1380
1336 voodoo3_make_room(sc, 4); 1381 voodoo3_make_room(sc, 4);
1337 voodoo3_write32(sc, VGAINIT0, 4928); 1382 voodoo3_write32(sc, VGAINIT0, 4928);
1338 voodoo3_write32(sc, DACMODE, 0); 1383 voodoo3_write32(sc, DACMODE, 0);
1339 voodoo3_write32(sc, VIDDESKSTRIDE, bytes_per_row); 1384 voodoo3_write32(sc, VIDDESKSTRIDE, bytes_per_row);
1340 voodoo3_write32(sc, PLLCTRL0, vidpll); 1385 voodoo3_write32(sc, PLLCTRL0, vidpll);
1341  1386
1342 voodoo3_make_room(sc, 5); 1387 voodoo3_make_room(sc, 5);
1343 voodoo3_write32(sc, VIDSCREENSIZE, sc->width | (sc->height << 12)); 1388 voodoo3_write32(sc, VIDSCREENSIZE, sc->width | (sc->height << 12));
1344 voodoo3_write32(sc, VIDDESKSTART, 0); 1389 voodoo3_write32(sc, VIDDESKSTART, 0);
1345 1390
1346 vidproc &= ~VIDCFG_HWCURSOR_ENABLE; 1391 vidproc &= ~VIDCFG_HWCURSOR_ENABLE;
1347 voodoo3_write32(sc, VIDPROCCFG, vidproc); 1392 voodoo3_write32(sc, VIDPROCCFG, vidproc);
1348 1393
1349 voodoo3_write32(sc, VGAINIT1, 0); 1394 voodoo3_write32(sc, VGAINIT1, 0);
1350 voodoo3_write32(sc, MISCINIT0, miscinit0); 1395 voodoo3_write32(sc, MISCINIT0, miscinit0);
1351#ifdef VOODOOFB_DEBUG 1396#ifdef VOODOOFB_DEBUG
1352 printf("vidproc: %08x\n", vidproc); 1397 printf("vidproc: %08x\n", vidproc);
1353#endif 1398#endif
1354 voodoo3_make_room(sc, 8); 1399 voodoo3_make_room(sc, 8);
1355 voodoo3_write32(sc, SRCBASE, 0); 1400 voodoo3_write32(sc, SRCBASE, 0);
1356 voodoo3_write32(sc, DSTBASE, 0); 1401 voodoo3_write32(sc, DSTBASE, 0);
1357 voodoo3_write32(sc, COMMANDEXTRA_2D, 0); 1402 voodoo3_write32(sc, COMMANDEXTRA_2D, 0);
1358 voodoo3_write32(sc, CLIP0MIN, 0); 1403 voodoo3_write32(sc, CLIP0MIN, 0);
1359 voodoo3_write32(sc, CLIP0MAX, 0x0fff0fff); 1404 voodoo3_write32(sc, CLIP0MAX, 0x0fff0fff);
1360 voodoo3_write32(sc, CLIP1MIN, 0); 1405 voodoo3_write32(sc, CLIP1MIN, 0);
1361 voodoo3_write32(sc, CLIP1MAX, 0x0fff0fff); 1406 voodoo3_write32(sc, CLIP1MAX, 0x0fff0fff);
1362 voodoo3_write32(sc, SRCXY, 0); 1407 voodoo3_write32(sc, SRCXY, 0);
1363 voodoofb_wait_idle(sc); 1408 voodoofb_wait_idle(sc);
1364 printf("%s: switched to %dx%d, %d bit\n", device_xname(sc->sc_dev), 1409 printf("%s: switched to %dx%d, %d bit\n", device_xname(sc->sc_dev),
1365 sc->width, sc->height, sc->bits_per_pixel); 1410 sc->width, sc->height, sc->bits_per_pixel);
1366} 1411}
1367 1412
1368static void 1413static void
1369voodoofb_init(struct voodoofb_softc *sc) 1414voodoofb_init(struct voodoofb_softc *sc)
1370{ 1415{
1371 /* XXX */ 1416 /* XXX */
1372 uint32_t vgainit0 = 0; 1417 uint32_t vgainit0 = 0;
1373 uint32_t vidcfg = 0; 1418 uint32_t vidcfg = 0;
1374 1419
1375#ifdef VOODOOFB_DEBUG 1420#ifdef VOODOOFB_DEBUG
1376 printf("initializing engine...");  1421 printf("initializing engine...");
1377#endif  1422#endif
1378 vgainit0 = voodoo3_read32(sc, VGAINIT0); 1423 vgainit0 = voodoo3_read32(sc, VGAINIT0);
1379#ifdef VOODOOFB_DEBUG 1424#ifdef VOODOOFB_DEBUG
1380 printf("vga: %08x", vgainit0); 1425 printf("vga: %08x", vgainit0);
1381#endif 1426#endif
1382 vgainit0 |= 1427 vgainit0 |=
1383 VGAINIT0_8BIT_DAC | 1428 VGAINIT0_8BIT_DAC |
1384 VGAINIT0_EXT_ENABLE | 1429 VGAINIT0_EXT_ENABLE |
1385 VGAINIT0_WAKEUP_3C3 | 1430 VGAINIT0_WAKEUP_3C3 |
1386 VGAINIT0_ALT_READBACK | 1431 VGAINIT0_ALT_READBACK |
1387 VGAINIT0_EXTSHIFTOUT; 1432 VGAINIT0_EXTSHIFTOUT;
1388  1433
1389 vidcfg = voodoo3_read32(sc, VIDPROCCFG); 1434 vidcfg = voodoo3_read32(sc, VIDPROCCFG);
1390#ifdef VOODOOFB_DEBUG 1435#ifdef VOODOOFB_DEBUG
1391 printf(" vidcfg: %08x\n", vidcfg); 1436 printf(" vidcfg: %08x\n", vidcfg);
1392#endif 1437#endif
1393 vidcfg |= 1438 vidcfg |=
1394 VIDCFG_VIDPROC_ENABLE | 1439 VIDCFG_VIDPROC_ENABLE |
1395 VIDCFG_DESK_ENABLE; 1440 VIDCFG_DESK_ENABLE;
1396 vidcfg &= ~VIDCFG_HWCURSOR_ENABLE; 1441 vidcfg &= ~VIDCFG_HWCURSOR_ENABLE;
1397  1442
1398 voodoo3_make_room(sc, 2); 1443 voodoo3_make_room(sc, 2);
1399 1444
1400 voodoo3_write32(sc, VGAINIT0, vgainit0); 1445 voodoo3_write32(sc, VGAINIT0, vgainit0);
1401 voodoo3_write32(sc, VIDPROCCFG, vidcfg); 1446 voodoo3_write32(sc, VIDPROCCFG, vidcfg);
1402 1447
1403 voodoo3_make_room(sc, 8); 1448 voodoo3_make_room(sc, 8);
1404 voodoo3_write32(sc, SRCBASE, 0); 1449 voodoo3_write32(sc, SRCBASE, 0);
1405 voodoo3_write32(sc, DSTBASE, 0); 1450 voodoo3_write32(sc, DSTBASE, 0);
1406 voodoo3_write32(sc, COMMANDEXTRA_2D, 0); 1451 voodoo3_write32(sc, COMMANDEXTRA_2D, 0);
1407 voodoo3_write32(sc, CLIP0MIN, 0); 1452 voodoo3_write32(sc, CLIP0MIN, 0);
1408 voodoo3_write32(sc, CLIP0MAX, 0x1fff1fff); 1453 voodoo3_write32(sc, CLIP0MAX, 0x1fff1fff);
1409 voodoo3_write32(sc, CLIP1MIN, 0); 1454 voodoo3_write32(sc, CLIP1MIN, 0);
1410 voodoo3_write32(sc, CLIP1MAX, 0x1fff1fff); 1455 voodoo3_write32(sc, CLIP1MAX, 0x1fff1fff);
1411 voodoo3_write32(sc, SRCXY, 0); 1456 voodoo3_write32(sc, SRCXY, 0);
1412 1457
1413 voodoofb_wait_idle(sc); 1458 voodoofb_wait_idle(sc);
1414} 1459}
 1460
 1461static void
 1462voodoofb_setup_i2c(struct voodoofb_softc *sc)
 1463{
 1464 int i;
 1465
 1466 /* Fill in the i2c tag */
 1467 sc->sc_i2c.ic_cookie = sc;
 1468 sc->sc_i2c.ic_acquire_bus = voodoofb_i2c_acquire_bus;
 1469 sc->sc_i2c.ic_release_bus = voodoofb_i2c_release_bus;
 1470 sc->sc_i2c.ic_send_start = voodoofb_i2c_send_start;
 1471 sc->sc_i2c.ic_send_stop = voodoofb_i2c_send_stop;
 1472 sc->sc_i2c.ic_initiate_xfer = voodoofb_i2c_initiate_xfer;
 1473 sc->sc_i2c.ic_read_byte = voodoofb_i2c_read_byte;
 1474 sc->sc_i2c.ic_write_byte = voodoofb_i2c_write_byte;
 1475 sc->sc_i2c.ic_exec = NULL;
 1476
 1477 sc->sc_i2creg = voodoo3_read32(sc, VIDSERPARPORT);
 1478#ifdef VOODOOFB_DEBUG
 1479 printf("data: %08x\n", sc->sc_i2creg);
 1480#endif
 1481 sc->sc_i2creg |= VSP_ENABLE_IIC0;
 1482 sc->sc_i2creg &= ~(VSP_SDA0_OUT | VSP_SCL0_OUT);
 1483 voodoo3_write32(sc, VIDSERPARPORT, sc->sc_i2creg);
 1484
 1485 /* zero out the EDID buffer */
 1486 memset(sc->sc_edid_data, 0, 128);
 1487
 1488 /* Some monitors don't respond first time */
 1489 i = 0;
 1490 while (sc->sc_edid_data[1] == 0 && i++ < 3)
 1491 ddc_read_edid(&sc->sc_i2c, sc->sc_edid_data, 128);
 1492 if (i < 3) {
 1493 if (edid_parse(sc->sc_edid_data, &sc->sc_edid_info) != -1) {
 1494#ifdef VOODOOFB_DEBUG
 1495 edid_print(&sc->sc_edid_info);
 1496#endif
 1497 /*
 1498 * Now pick a mode.
 1499 * How do we know our max. pixel clock?
 1500 * All Voodoo3 should support at least 250MHz.
 1501 * All Voodoo3 I've seen so far have at least 8MB
 1502 * which we're not going to exhaust either in 8bit.
 1503 */
 1504 if ((sc->sc_edid_info.edid_preferred_mode != NULL)) {
 1505 sc->sc_videomode =
 1506 sc->sc_edid_info.edid_preferred_mode;
 1507 } else {
 1508 int n;
 1509 struct videomode *m = sc->sc_edid_info.edid_modes;
 1510
 1511 sort_modes(sc->sc_edid_info.edid_modes,
 1512 &sc->sc_edid_info.edid_preferred_mode,
 1513 sc->sc_edid_info.edid_nmodes);
 1514 while ((sc->sc_videomode == NULL) &&
 1515 (n < sc->sc_edid_info.edid_nmodes)) {
 1516 if (m[n].dot_clock <= 250000) {
 1517 sc->sc_videomode = &m[n];
 1518 }
 1519 }
 1520 }
 1521 }
 1522 }
 1523}
 1524
 1525/* I2C bitbanging */
 1526static void voodoofb_i2cbb_set_bits(void *cookie, uint32_t bits)
 1527{
 1528 struct voodoofb_softc *sc = cookie;
 1529 uint32_t out;
 1530
 1531 out = bits >> 2; /* bitmasks match the IN bits */
 1532
 1533 voodoo3_write32(sc, VIDSERPARPORT, sc->sc_i2creg | out);
 1534}
 1535
 1536static void voodoofb_i2cbb_set_dir(void *cookie, uint32_t dir)
 1537{
 1538 /* Nothing to do */
 1539}
 1540
 1541static uint32_t voodoofb_i2cbb_read(void *cookie)
 1542{
 1543 struct voodoofb_softc *sc = cookie;
 1544 uint32_t bits;
 1545
 1546 bits = voodoo3_read32(sc, VIDSERPARPORT);
 1547
 1548 return bits;
 1549}
 1550
 1551/* higher level I2C stuff */
 1552static int
 1553voodoofb_i2c_acquire_bus(void *cookie, int flags)
 1554{
 1555 /* private bus */
 1556 return (0);
 1557}
 1558
 1559static void
 1560voodoofb_i2c_release_bus(void *cookie, int flags)
 1561{
 1562 /* private bus */
 1563}
 1564
 1565static int
 1566voodoofb_i2c_send_start(void *cookie, int flags)
 1567{
 1568 return (i2c_bitbang_send_start(cookie, flags, &voodoofb_i2cbb_ops));
 1569}
 1570
 1571static int
 1572voodoofb_i2c_send_stop(void *cookie, int flags)
 1573{
 1574
 1575 return (i2c_bitbang_send_stop(cookie, flags, &voodoofb_i2cbb_ops));
 1576}
 1577
 1578static int
 1579voodoofb_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
 1580{
 1581
 1582 return (i2c_bitbang_initiate_xfer(cookie, addr, flags,
 1583 &voodoofb_i2cbb_ops));
 1584}
 1585
 1586static int
 1587voodoofb_i2c_read_byte(void *cookie, uint8_t *valp, int flags)
 1588{
 1589 return (i2c_bitbang_read_byte(cookie, valp, flags, &voodoofb_i2cbb_ops));
 1590}
 1591
 1592static int
 1593voodoofb_i2c_write_byte(void *cookie, uint8_t val, int flags)
 1594{
 1595 return (i2c_bitbang_write_byte(cookie, val, flags, &voodoofb_i2cbb_ops));
 1596}