1 /* $NetBSD: voodoofb.c,v 1.20 2009/08/20 02:40:57 macallan Exp $ */
4 * Copyright (c) 2005, 2006 Michael Lorenz
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
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
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * A console driver for 3Dfx Voodoo3 graphics boards
30 * Thanks to Andreas Drewke (andreas_dr@gmx.de) for his Voodoo3 driver for BeOS
31 * which I used as reference / documentation
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: voodoofb.c,v 1.20 2009/08/20 02:40:57 macallan Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/device.h>
41 #include <sys/malloc.h>
42 #include <sys/callout.h>
43 #include <sys/kauth.h>
45 #include <uvm/uvm_extern.h>
47 #if defined(macppc) || defined (sparc64) || defined(ofppc)
48 #define HAVE_OPENFIRMWARE
51 /* XXX should be configurable */
52 #define VOODOOFB_VIDEOMODE 15
54 #ifdef HAVE_OPENFIRMWARE
55 #include <dev/ofw/openfirm.h>
56 #include <dev/ofw/ofw_pci.h>
59 #include <dev/videomode/videomode.h>
61 #include <dev/pci/pcivar.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/pci/pcidevs.h>
64 #include <dev/pci/pciio.h>
65 #include <dev/pci/voodoofbreg.h>
67 #include <dev/wscons/wsdisplayvar.h>
68 #include <dev/wscons/wsconsio.h>
69 #include <dev/wsfont/wsfont.h>
70 #include <dev/rasops/rasops.h>
71 #include <dev/wscons/wsdisplay_vconsvar.h>
73 #include "opt_wsemul.h"
75 struct voodoofb_softc
{
77 pci_chipset_tag_t sc_pc
;
79 struct pci_attach_args sc_pa
;
81 bus_space_tag_t sc_memt
;
82 bus_space_tag_t sc_iot
;
83 bus_space_handle_t sc_memh
;
85 bus_space_tag_t sc_regt
;
86 bus_space_tag_t sc_fbt
;
87 bus_space_tag_t sc_ioregt
;
88 bus_space_handle_t sc_regh
;
89 bus_space_handle_t sc_fbh
;
90 bus_space_handle_t sc_ioregh
;
91 bus_addr_t sc_regs
, sc_fb
, sc_ioreg
;
92 bus_size_t sc_regsize
, sc_fbsize
, sc_ioregsize
;
100 int width
, height
, linebytes
;
105 u_char sc_cmap_red
[256];
106 u_char sc_cmap_green
[256];
107 u_char sc_cmap_blue
[256];
110 struct vcons_data vd
;
120 static struct vcons_screen voodoofb_console_screen
;
122 extern const u_char rasops_cmap
[768];
124 static int voodoofb_match(device_t
, cfdata_t
, void *);
125 static void voodoofb_attach(device_t
, device_t
, void *);
127 static int voodoofb_drm_print(void *, const char *);
128 static int voodoofb_drm_unmap(struct voodoofb_softc
*);
129 static int voodoofb_drm_map(struct voodoofb_softc
*);
131 CFATTACH_DECL_NEW(voodoofb
, sizeof(struct voodoofb_softc
), voodoofb_match
,
132 voodoofb_attach
, NULL
, NULL
);
134 static int voodoofb_is_console(struct pci_attach_args
*);
135 static void voodoofb_init(struct voodoofb_softc
*);
137 static void voodoofb_cursor(void *, int, int, int);
138 static void voodoofb_putchar(void *, int, int, u_int
, long);
139 static void voodoofb_copycols(void *, int, int, int, int);
140 static void voodoofb_erasecols(void *, int, int, int, long);
141 static void voodoofb_copyrows(void *, int, int, int);
142 static void voodoofb_eraserows(void *, int, int, long);
145 static int voodoofb_allocattr(void *, int, int, int, long *);
146 static void voodoofb_scroll(void *, void *, int);
147 static int voodoofb_load_font(void *, void *, struct wsdisplay_font
*);
150 static int voodoofb_putcmap(struct voodoofb_softc
*,
151 struct wsdisplay_cmap
*);
152 static int voodoofb_getcmap(struct voodoofb_softc
*,
153 struct wsdisplay_cmap
*);
154 static int voodoofb_putpalreg(struct voodoofb_softc
*, uint8_t, uint8_t,
156 static void voodoofb_bitblt(struct voodoofb_softc
*, int, int, int, int,
158 static void voodoofb_rectfill(struct voodoofb_softc
*, int, int, int, int,
160 static void voodoofb_rectinvert(struct voodoofb_softc
*, int, int, int,
162 static void voodoofb_setup_mono(struct voodoofb_softc
*, int, int, int,
163 int, uint32_t, uint32_t);
164 static void voodoofb_feed_line(struct voodoofb_softc
*, int, uint8_t *);
166 #ifdef VOODOOFB_DEBUG
167 static void voodoofb_showpal(struct voodoofb_softc
*);
170 static void voodoofb_wait_idle(struct voodoofb_softc
*);
172 #ifdef VOODOOFB_ENABLE_INTR
173 static int voodoofb_intr(void *);
176 static void voodoofb_set_videomode(struct voodoofb_softc
*,
177 const struct videomode
*);
179 struct wsscreen_descr voodoofb_defaultscreen
= {
184 WSSCREEN_WSCOLORS
| WSSCREEN_HILIT
,
188 const struct wsscreen_descr
*_voodoofb_scrlist
[] = {
189 &voodoofb_defaultscreen
,
190 /* XXX other formats, graphics screen? */
193 struct wsscreen_list voodoofb_screenlist
= {
194 sizeof(_voodoofb_scrlist
) / sizeof(struct wsscreen_descr
*), _voodoofb_scrlist
197 static int voodoofb_ioctl(void *, void *, u_long
, void *, int,
199 static paddr_t
voodoofb_mmap(void *, void *, off_t
, int);
201 static void voodoofb_clearscreen(struct voodoofb_softc
*);
202 static void voodoofb_init_screen(void *, struct vcons_screen
*, int,
206 struct wsdisplay_accessops voodoofb_accessops
= {
212 NULL
, /* load_font */
218 * Inline functions for getting access to register aperture.
221 voodoo3_write32(struct voodoofb_softc
*sc
, uint32_t reg
, uint32_t val
)
223 bus_space_write_4(sc
->sc_regt
, sc
->sc_regh
, reg
, val
);
226 static inline uint32_t
227 voodoo3_read32(struct voodoofb_softc
*sc
, uint32_t reg
)
229 return bus_space_read_4(sc
->sc_regt
, sc
->sc_regh
, reg
);
233 voodoo3_write_crtc(struct voodoofb_softc
*sc
, uint8_t reg
, uint8_t val
)
235 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, CRTC_INDEX
- 0x300, reg
);
236 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, CRTC_DATA
- 0x300, val
);
240 voodoo3_write_seq(struct voodoofb_softc
*sc
, uint8_t reg
, uint8_t val
)
242 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, SEQ_INDEX
- 0x300, reg
);
243 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, SEQ_DATA
- 0x300, val
);
247 voodoo3_write_gra(struct voodoofb_softc
*sc
, uint8_t reg
, uint8_t val
)
249 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, GRA_INDEX
- 0x300, reg
);
250 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, GRA_DATA
- 0x300, val
);
254 voodoo3_write_attr(struct voodoofb_softc
*sc
, uint8_t reg
, uint8_t val
)
256 volatile uint8_t junk
;
259 junk
= bus_space_read_1(sc
->sc_ioregt
, sc
->sc_ioregh
, IS1_R
- 0x300);
260 index
= bus_space_read_1(sc
->sc_ioregt
, sc
->sc_ioregh
, ATT_IW
- 0x300);
261 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, ATT_IW
- 0x300, reg
);
262 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, ATT_IW
- 0x300, val
);
263 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, ATT_IW
- 0x300, index
);
267 vga_outb(struct voodoofb_softc
*sc
, uint32_t reg
, uint8_t val
)
269 bus_space_write_1(sc
->sc_ioregt
, sc
->sc_ioregh
, reg
- 0x300, val
);
272 /* wait until there's room for len bytes in the FIFO */
274 voodoo3_make_room(struct voodoofb_softc
*sc
, int len
)
276 while ((voodoo3_read32(sc
, STATUS
) & 0x1f) < len
);
280 voodoofb_wait_idle(struct voodoofb_softc
*sc
)
284 voodoo3_make_room(sc
, 1);
285 voodoo3_write32(sc
, COMMAND_3D
, COMMAND_3D_NOP
);
288 i
= (voodoo3_read32(sc
, STATUS
) & STATUS_BUSY
) ? 0 : i
+ 1;
294 voodoofb_match(device_t parent
, cfdata_t match
, void *aux
)
296 struct pci_attach_args
*pa
= (struct pci_attach_args
*)aux
;
298 if (PCI_CLASS(pa
->pa_class
) != PCI_CLASS_DISPLAY
||
299 PCI_SUBCLASS(pa
->pa_class
) != PCI_SUBCLASS_DISPLAY_VGA
)
301 if ((PCI_VENDOR(pa
->pa_id
)==PCI_VENDOR_3DFX
) &&
302 (PCI_PRODUCT(pa
->pa_id
)>=PCI_PRODUCT_3DFX_VOODOO3
))
308 voodoofb_attach(device_t parent
, device_t self
, void *aux
)
310 struct voodoofb_softc
*sc
= device_private(self
);
311 struct pci_attach_args
*pa
= aux
;
313 struct wsemuldisplaydev_attach_args aa
;
314 struct rasops_info
*ri
;
315 #ifdef VOODOOFB_ENABLE_INTR
316 pci_intr_handle_t ih
;
320 int console
, width
, height
, i
, j
;
321 #ifdef HAVE_OPENFIRMWARE
322 int linebytes
, depth
, node
;
328 sc
->sc_mode
= WSDISPLAYIO_MODE_EMUL
;
329 #ifdef HAVE_OPENFIRMWARE
330 node
= pcidev_to_ofdev(pa
->pa_pc
, pa
->pa_tag
);
332 sc
->sc_pc
= pa
->pa_pc
;
333 sc
->sc_pcitag
= pa
->pa_tag
;
335 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
336 printf(": %s (rev. 0x%02x)\n", devinfo
, PCI_REVISION(pa
->pa_class
));
338 sc
->sc_memt
= pa
->pa_memt
;
339 sc
->sc_iot
= pa
->pa_iot
;
342 /* the framebuffer */
343 if (pci_mapreg_map(pa
, 0x14, PCI_MAPREG_TYPE_MEM
,
344 BUS_SPACE_MAP_CACHEABLE
| BUS_SPACE_MAP_PREFETCHABLE
|
345 BUS_SPACE_MAP_LINEAR
,
346 &sc
->sc_fbt
, &sc
->sc_fbh
, &sc
->sc_fb
, &sc
->sc_fbsize
)) {
347 aprint_error_dev(self
, "failed to map the frame buffer.\n");
350 /* memory-mapped registers */
351 if (pci_mapreg_map(pa
, 0x10, PCI_MAPREG_TYPE_MEM
, 0,
352 &sc
->sc_regt
, &sc
->sc_regh
, &sc
->sc_regs
, &sc
->sc_regsize
)) {
353 aprint_error_dev(self
, "failed to map memory-mapped registers.\n");
356 /* IO-mapped registers */
357 if (pci_mapreg_map(pa
, 0x18, PCI_MAPREG_TYPE_IO
, 0,
358 &sc
->sc_ioregt
, &sc
->sc_ioregh
, &sc
->sc_ioreg
,
359 &sc
->sc_ioregsize
)) {
360 aprint_error_dev(self
, "failed to map IO-mapped registers.\n");
364 /* we should read these from the chip instead of depending on OF */
367 #ifdef HAVE_OPENFIRMWARE
368 if (OF_getprop(node
, "width", &width
, 4) != 4)
369 OF_interpret("screen-width", 1, 1, &width
);
370 if (OF_getprop(node
, "height", &height
, 4) != 4)
371 OF_interpret("screen-height", 1, 1, &height
);
372 if (OF_getprop(node
, "linebytes", &linebytes
, 4) != 4)
373 linebytes
= width
; /* XXX */
374 if (OF_getprop(node
, "depth", &depth
, 4) != 4)
377 if (width
== -1 || height
== -1)
382 sc
->bits_per_pixel
= depth
;
383 sc
->linebytes
= linebytes
;
384 printf("%s: initial resolution %dx%d, %d bit\n", device_xname(self
),
385 sc
->width
, sc
->height
, sc
->bits_per_pixel
);
388 /* XXX this should at least be configurable via kernel config */
389 voodoofb_set_videomode(sc
, &videomode_list
[VOODOOFB_VIDEOMODE
]);
391 vcons_init(&sc
->vd
, sc
, &voodoofb_defaultscreen
, &voodoofb_accessops
);
392 sc
->vd
.init_screen
= voodoofb_init_screen
;
394 console
= voodoofb_is_console(pa
);
396 ri
= &voodoofb_console_screen
.scr_ri
;
398 vcons_init_screen(&sc
->vd
, &voodoofb_console_screen
, 1,
400 voodoofb_console_screen
.scr_flags
|= VCONS_SCREEN_IS_STATIC
;
402 voodoofb_defaultscreen
.textops
= &ri
->ri_ops
;
403 voodoofb_defaultscreen
.capabilities
= ri
->ri_caps
;
404 voodoofb_defaultscreen
.nrows
= ri
->ri_rows
;
405 voodoofb_defaultscreen
.ncols
= ri
->ri_cols
;
406 wsdisplay_cnattach(&voodoofb_defaultscreen
, ri
, 0, 0, defattr
);
409 * since we're not the console we can postpone the rest
410 * until someone actually allocates a screen for us
412 voodoofb_set_videomode(sc
, &videomode_list
[0]);
415 printf("%s: %d MB aperture at 0x%08x, %d MB registers at 0x%08x\n",
416 device_xname(self
), (u_int
)(sc
->sc_fbsize
>> 20),
417 (u_int
)sc
->sc_fb
, (u_int
)(sc
->sc_regsize
>> 20),
419 #ifdef VOODOOFB_DEBUG
420 printf("fb: %08lx\n", (ulong
)ri
->ri_bits
);
424 for (i
= 0; i
< 256; i
++) {
425 voodoofb_putpalreg(sc
, i
, rasops_cmap
[j
], rasops_cmap
[j
+ 1],
430 #ifdef VOODOOFB_ENABLE_INTR
431 /* Interrupt. We don't use it for anything yet */
432 if (pci_intr_map(pa
, &ih
)) {
433 aprint_error_dev(self
, "failed to map interrupt\n");
437 intrstr
= pci_intr_string(sc
->sc_pc
, ih
);
438 sc
->sc_ih
= pci_intr_establish(sc
->sc_pc
, ih
, IPL_NET
, voodoofb_intr
,
440 if (sc
->sc_ih
== NULL
) {
441 aprint_error_dev(self
, "failed to establish interrupt");
443 aprint_error(" at %s", intrstr
);
447 aprint_normal_dev(self
, "interrupting at %s\n", intrstr
);
450 rasops_unpack_attr(defattr
, &fg
, &bg
, &ul
);
451 sc
->sc_bg
= ri
->ri_devcmap
[bg
];
452 voodoofb_clearscreen(sc
);
455 vcons_replay_msgbuf(&voodoofb_console_screen
);
456 aa
.console
= console
;
457 aa
.scrdata
= &voodoofb_screenlist
;
458 aa
.accessops
= &voodoofb_accessops
;
459 aa
.accesscookie
= &sc
->vd
;
461 config_found(self
, &aa
, wsemuldisplaydevprint
);
462 config_found_ia(self
, "drm", aux
, voodoofb_drm_print
);
466 voodoofb_drm_print(void *opaque
, const char *pnp
)
469 aprint_normal("drm at %s", pnp
);
475 voodoofb_drm_unmap(struct voodoofb_softc
*sc
)
477 printf("%s: releasing bus resources\n", device_xname(sc
->sc_dev
));
479 bus_space_unmap(sc
->sc_ioregt
, sc
->sc_ioregh
, sc
->sc_ioregsize
);
480 bus_space_unmap(sc
->sc_regt
, sc
->sc_regh
, sc
->sc_regsize
);
481 bus_space_unmap(sc
->sc_fbt
, sc
->sc_fbh
, sc
->sc_fbsize
);
487 voodoofb_drm_map(struct voodoofb_softc
*sc
)
489 if (pci_mapreg_map(&sc
->sc_pa
, 0x14, PCI_MAPREG_TYPE_MEM
,
490 BUS_SPACE_MAP_CACHEABLE
| BUS_SPACE_MAP_PREFETCHABLE
|
491 BUS_SPACE_MAP_LINEAR
,
492 &sc
->sc_fbt
, &sc
->sc_fbh
, &sc
->sc_fb
, &sc
->sc_fbsize
)) {
493 aprint_error_dev(sc
->sc_dev
, "failed to map the frame buffer.\n");
496 /* memory-mapped registers */
497 if (pci_mapreg_map(&sc
->sc_pa
, 0x10, PCI_MAPREG_TYPE_MEM
, 0,
498 &sc
->sc_regt
, &sc
->sc_regh
, &sc
->sc_regs
, &sc
->sc_regsize
)) {
499 aprint_error_dev(sc
->sc_dev
, "failed to map memory-mapped registers.\n");
502 /* IO-mapped registers */
503 if (pci_mapreg_map(&sc
->sc_pa
, 0x18, PCI_MAPREG_TYPE_IO
, 0,
504 &sc
->sc_ioregt
, &sc
->sc_ioregh
, &sc
->sc_ioreg
,
505 &sc
->sc_ioregsize
)) {
506 aprint_error_dev(sc
->sc_dev
, "failed to map IO-mapped registers.\n");
510 /* XXX this should at least be configurable via kernel config */
511 voodoofb_set_videomode(sc
, &videomode_list
[VOODOOFB_VIDEOMODE
]);
517 voodoofb_putpalreg(struct voodoofb_softc
*sc
, uint8_t index
, uint8_t r
,
518 uint8_t g
, uint8_t b
)
522 sc
->sc_cmap_red
[index
] = r
;
523 sc
->sc_cmap_green
[index
] = g
;
524 sc
->sc_cmap_blue
[index
] = b
;
526 color
= (r
<< 16) | (g
<< 8) | b
;
527 voodoo3_make_room(sc
, 2);
528 voodoo3_write32(sc
, DACADDR
, index
);
529 voodoo3_write32(sc
, DACDATA
, color
);
535 voodoofb_putcmap(struct voodoofb_softc
*sc
, struct wsdisplay_cmap
*cm
)
538 u_int index
= cm
->index
;
539 u_int count
= cm
->count
;
541 u_char rbuf
[256], gbuf
[256], bbuf
[256];
543 #ifdef VOODOOFB_DEBUG
544 printf("putcmap: %d %d\n",index
, count
);
546 if (cm
->index
>= 256 || cm
->count
> 256 ||
547 (cm
->index
+ cm
->count
) > 256)
549 error
= copyin(cm
->red
, &rbuf
[index
], count
);
552 error
= copyin(cm
->green
, &gbuf
[index
], count
);
555 error
= copyin(cm
->blue
, &bbuf
[index
], count
);
559 memcpy(&sc
->sc_cmap_red
[index
], &rbuf
[index
], count
);
560 memcpy(&sc
->sc_cmap_green
[index
], &gbuf
[index
], count
);
561 memcpy(&sc
->sc_cmap_blue
[index
], &bbuf
[index
], count
);
563 r
= &sc
->sc_cmap_red
[index
];
564 g
= &sc
->sc_cmap_green
[index
];
565 b
= &sc
->sc_cmap_blue
[index
];
567 for (i
= 0; i
< count
; i
++) {
568 voodoofb_putpalreg(sc
, index
, *r
, *g
, *b
);
576 voodoofb_getcmap(struct voodoofb_softc
*sc
, struct wsdisplay_cmap
*cm
)
578 u_int index
= cm
->index
;
579 u_int count
= cm
->count
;
582 if (index
>= 255 || count
> 256 || index
+ count
> 256)
585 error
= copyout(&sc
->sc_cmap_red
[index
], cm
->red
, count
);
588 error
= copyout(&sc
->sc_cmap_green
[index
], cm
->green
, count
);
591 error
= copyout(&sc
->sc_cmap_blue
[index
], cm
->blue
, count
);
599 voodoofb_is_console(struct pci_attach_args
*pa
)
602 #ifdef HAVE_OPENFIRMWARE
603 /* check if we're the /chosen console device */
604 int chosen
, stdout
, node
, us
;
606 us
=pcidev_to_ofdev(pa
->pa_pc
, pa
->pa_tag
);
607 chosen
= OF_finddevice("/chosen");
608 OF_getprop(chosen
, "stdout", &stdout
, 4);
609 node
= OF_instance_to_package(stdout
);
612 /* XXX how do we know we're console on i386? */
618 voodoofb_clearscreen(struct voodoofb_softc
*sc
)
620 voodoofb_rectfill(sc
, 0, 0, sc
->width
, sc
->height
, sc
->sc_bg
);
628 voodoofb_cursor(void *cookie
, int on
, int row
, int col
)
630 struct rasops_info
*ri
= cookie
;
631 struct vcons_screen
*scr
= ri
->ri_hw
;
632 struct voodoofb_softc
*sc
= scr
->scr_cookie
;
635 wi
= ri
->ri_font
->fontwidth
;
636 he
= ri
->ri_font
->fontheight
;
638 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
639 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
640 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
641 if (ri
->ri_flg
& RI_CURSOR
) {
642 voodoofb_rectinvert(sc
, x
, y
, wi
, he
);
643 ri
->ri_flg
&= ~RI_CURSOR
;
649 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
650 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
651 voodoofb_rectinvert(sc
, x
, y
, wi
, he
);
652 ri
->ri_flg
|= RI_CURSOR
;
655 ri
->ri_flg
&= ~RI_CURSOR
;
663 voodoofb_mapchar(void *cookie
, int uni
, u_int
*index
)
670 voodoofb_putchar(void *cookie
, int row
, int col
, u_int c
, long attr
)
672 struct rasops_info
*ri
= cookie
;
673 struct vcons_screen
*scr
= ri
->ri_hw
;
674 struct voodoofb_softc
*sc
= scr
->scr_cookie
;
676 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
681 wi
= ri
->ri_font
->fontwidth
;
682 he
= ri
->ri_font
->fontheight
;
684 if (!CHAR_IN_FONT(c
, ri
->ri_font
))
686 bg
= (u_char
)ri
->ri_devcmap
[(attr
>> 16) & 0xf];
687 fg
= (u_char
)ri
->ri_devcmap
[(attr
>> 24) & 0xf];
688 x
= ri
->ri_xorigin
+ col
* wi
;
689 y
= ri
->ri_yorigin
+ row
* he
;
691 voodoofb_rectfill(sc
, x
, y
, wi
, he
, bg
);
693 uc
= c
-ri
->ri_font
->firstchar
;
694 data
= (uint8_t *)ri
->ri_font
->data
+ uc
*
696 voodoofb_setup_mono(sc
, x
, y
, wi
, he
, fg
, bg
);
697 for (i
= 0; i
< he
; i
++) {
698 voodoofb_feed_line(sc
,
699 ri
->ri_font
->stride
, data
);
700 data
+= ri
->ri_font
->stride
;
707 voodoofb_copycols(void *cookie
, int row
, int srccol
, int dstcol
, int ncols
)
709 struct rasops_info
*ri
= cookie
;
710 struct vcons_screen
*scr
= ri
->ri_hw
;
711 struct voodoofb_softc
*sc
= scr
->scr_cookie
;
712 int32_t xs
, xd
, y
, width
, height
;
714 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
715 xs
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* srccol
;
716 xd
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* dstcol
;
717 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
718 width
= ri
->ri_font
->fontwidth
* ncols
;
719 height
= ri
->ri_font
->fontheight
;
720 voodoofb_bitblt(sc
, xs
, y
, xd
, y
, width
, height
);
725 voodoofb_erasecols(void *cookie
, int row
, int startcol
, int ncols
,
728 struct rasops_info
*ri
= cookie
;
729 struct vcons_screen
*scr
= ri
->ri_hw
;
730 struct voodoofb_softc
*sc
= scr
->scr_cookie
;
731 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
733 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
734 x
= ri
->ri_xorigin
+ ri
->ri_font
->fontwidth
* startcol
;
735 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
736 width
= ri
->ri_font
->fontwidth
* ncols
;
737 height
= ri
->ri_font
->fontheight
;
738 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
740 voodoofb_rectfill(sc
, x
, y
, width
, height
, ri
->ri_devcmap
[bg
]);
745 voodoofb_copyrows(void *cookie
, int srcrow
, int dstrow
, int nrows
)
747 struct rasops_info
*ri
= cookie
;
748 struct vcons_screen
*scr
= ri
->ri_hw
;
749 struct voodoofb_softc
*sc
= scr
->scr_cookie
;
750 int32_t x
, ys
, yd
, width
, height
;
752 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
754 ys
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* srcrow
;
755 yd
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* dstrow
;
756 width
= ri
->ri_emuwidth
;
757 height
= ri
->ri_font
->fontheight
* nrows
;
758 voodoofb_bitblt(sc
, x
, ys
, x
, yd
, width
, height
);
763 voodoofb_eraserows(void *cookie
, int row
, int nrows
, long fillattr
)
765 struct rasops_info
*ri
= cookie
;
766 struct vcons_screen
*scr
= ri
->ri_hw
;
767 struct voodoofb_softc
*sc
= scr
->scr_cookie
;
768 int32_t x
, y
, width
, height
, fg
, bg
, ul
;
770 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
771 rasops_unpack_attr(fillattr
, &fg
, &bg
, &ul
);
772 if ((row
== 0) && (nrows
== ri
->ri_rows
)) {
773 /* clear the whole screen */
774 voodoofb_rectfill(sc
, 0, 0, ri
->ri_width
,
775 ri
->ri_height
, ri
->ri_devcmap
[bg
]);
778 y
= ri
->ri_yorigin
+ ri
->ri_font
->fontheight
* row
;
779 width
= ri
->ri_emuwidth
;
780 height
= ri
->ri_font
->fontheight
* nrows
;
781 voodoofb_rectfill(sc
, x
, y
, width
, height
,
788 voodoofb_bitblt(struct voodoofb_softc
*sc
, int xs
, int ys
, int xd
, int yd
, int width
, int height
)
790 uint32_t fmt
, blitcmd
;
792 fmt
= sc
->linebytes
| ((sc
->bits_per_pixel
+
793 ((sc
->bits_per_pixel
== 8) ? 0 : 8)) << 13);
794 blitcmd
= COMMAND_2D_S2S_BITBLT
| (ROP_COPY
<< 24);
806 voodoo3_make_room(sc
, 6);
808 voodoo3_write32(sc
, SRCFORMAT
, fmt
);
809 voodoo3_write32(sc
, DSTFORMAT
, fmt
);
810 voodoo3_write32(sc
, DSTSIZE
, width
| (height
<< 16));
811 voodoo3_write32(sc
, DSTXY
, xd
| (yd
<< 16));
812 voodoo3_write32(sc
, SRCXY
, xs
| (ys
<< 16));
813 voodoo3_write32(sc
, COMMAND_2D
, blitcmd
| SST_2D_GO
);
817 voodoofb_rectfill(struct voodoofb_softc
*sc
, int x
, int y
, int width
,
818 int height
, int colour
)
822 col
= (colour
<< 24) | (colour
<< 16) | (colour
<< 8) | colour
;
823 fmt
= sc
->linebytes
| ((sc
->bits_per_pixel
+
824 ((sc
->bits_per_pixel
== 8) ? 0 : 8)) << 13);
826 voodoo3_make_room(sc
, 6);
827 voodoo3_write32(sc
, DSTFORMAT
, fmt
);
828 voodoo3_write32(sc
, COLORFORE
, colour
);
829 voodoo3_write32(sc
, COLORBACK
, colour
);
830 voodoo3_write32(sc
, COMMAND_2D
, COMMAND_2D_FILLRECT
| (ROP_COPY
<< 24));
831 voodoo3_write32(sc
, DSTSIZE
, width
| (height
<< 16));
832 voodoo3_write32(sc
, LAUNCH_2D
, x
| (y
<< 16));
836 voodoofb_rectinvert(struct voodoofb_softc
*sc
, int x
, int y
, int width
,
841 fmt
= sc
->linebytes
| ((sc
->bits_per_pixel
+
842 ((sc
->bits_per_pixel
== 8) ? 0 : 8)) << 13);
844 voodoo3_make_room(sc
, 6);
845 voodoo3_write32(sc
, DSTFORMAT
, fmt
);
846 voodoo3_write32(sc
, COMMAND_2D
, COMMAND_2D_FILLRECT
|
848 voodoo3_write32(sc
, DSTSIZE
, width
| (height
<< 16));
849 voodoo3_write32(sc
, DSTXY
, x
| (y
<< 16));
850 voodoo3_write32(sc
, LAUNCH_2D
, x
| (y
<< 16));
854 voodoofb_setup_mono(struct voodoofb_softc
*sc
, int xd
, int yd
, int width
, int height
, uint32_t fg
,
857 uint32_t dfmt
, sfmt
= sc
->linebytes
;
859 dfmt
= sc
->linebytes
| ((sc
->bits_per_pixel
+
860 ((sc
->bits_per_pixel
== 8) ? 0 : 8)) << 13);
862 voodoo3_make_room(sc
, 9);
863 voodoo3_write32(sc
, SRCFORMAT
, sfmt
);
864 voodoo3_write32(sc
, DSTFORMAT
, dfmt
);
865 voodoo3_write32(sc
, COLORFORE
, fg
);
866 voodoo3_write32(sc
, COLORBACK
, bg
);
867 voodoo3_write32(sc
, DSTSIZE
, width
| (height
<< 16));
868 voodoo3_write32(sc
, DSTXY
, xd
| (yd
<< 16));
869 voodoo3_write32(sc
, SRCXY
, 0);
870 voodoo3_write32(sc
, COMMAND_2D
, COMMAND_2D_H2S_BITBLT
|
871 (ROP_COPY
<< 24) | SST_2D_GO
);
873 /* now feed the data into the chip */
877 voodoofb_feed_line(struct voodoofb_softc
*sc
, int count
, uint8_t *data
)
880 uint32_t latch
= 0, bork
;
883 voodoo3_make_room(sc
, count
);
884 for (i
= 0; i
< count
; i
++) {
886 latch
|= (bork
<< shift
);
888 voodoo3_write32(sc
, LAUNCH_2D
, latch
);
895 voodoo3_write32(sc
, LAUNCH_2D
, latch
);
898 #ifdef VOODOOFB_DEBUG
900 voodoofb_showpal(struct voodoofb_softc
*sc
)
904 for (i
= 0; i
< 16; i
++) {
905 voodoofb_rectfill(sc
, x
, 0, 64, 64, i
);
913 voodoofb_allocattr(void *cookie
, int fg
, int bg
, int flags
, long *attrp
)
921 * wsdisplay_accessops
925 voodoofb_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
928 struct vcons_data
*vd
= v
;
929 struct voodoofb_softc
*sc
= vd
->cookie
;
930 struct wsdisplay_fbinfo
*wdf
;
931 struct vcons_screen
*ms
= vd
->active
;
934 case WSDISPLAYIO_GTYPE
:
935 *(u_int
*)data
= WSDISPLAY_TYPE_PCIMISC
;
938 case WSDISPLAYIO_GINFO
:
940 wdf
->height
= ms
->scr_ri
.ri_height
;
941 wdf
->width
= ms
->scr_ri
.ri_width
;
942 wdf
->depth
= ms
->scr_ri
.ri_depth
;
946 case WSDISPLAYIO_GETCMAP
:
947 return voodoofb_getcmap(sc
,
948 (struct wsdisplay_cmap
*)data
);
950 case WSDISPLAYIO_PUTCMAP
:
951 return voodoofb_putcmap(sc
,
952 (struct wsdisplay_cmap
*)data
);
954 /* PCI config read/write passthrough. */
955 case PCI_IOC_CFGREAD
:
956 case PCI_IOC_CFGWRITE
:
957 return (pci_devioctl(sc
->sc_pc
, sc
->sc_pcitag
,
958 cmd
, data
, flag
, l
));
960 case WSDISPLAYIO_SMODE
:
962 int new_mode
= *(int*)data
;
963 if (new_mode
!= sc
->sc_mode
)
965 sc
->sc_mode
= new_mode
;
966 if(new_mode
== WSDISPLAYIO_MODE_EMUL
)
968 voodoofb_drm_map(sc
);
971 /* restore the palette */
972 for (i
= 0; i
< 256; i
++) {
973 voodoofb_putpalreg(sc
,
976 sc
->sc_cmap_green
[i
],
977 sc
->sc_cmap_blue
[i
]);
979 vcons_redraw_screen(ms
);
981 voodoofb_drm_unmap(sc
);
990 voodoofb_mmap(void *v
, void *vs
, off_t offset
, int prot
)
992 struct vcons_data
*vd
= v
;
993 struct voodoofb_softc
*sc
= vd
->cookie
;
996 /* 'regular' framebuffer mmap()ing */
997 if (offset
< sc
->sc_fbsize
) {
998 pa
= bus_space_mmap(sc
->sc_fbt
, offset
, 0, prot
,
999 BUS_SPACE_MAP_LINEAR
);
1004 * restrict all other mappings to processes with superuser privileges
1005 * or the kernel itself
1007 if (kauth_authorize_generic(kauth_cred_get(), KAUTH_GENERIC_ISSUSER
,
1009 aprint_error_dev(sc
->sc_dev
, "mmap() rejected.\n");
1013 if ((offset
>= sc
->sc_fb
) && (offset
< (sc
->sc_fb
+ sc
->sc_fbsize
))) {
1014 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
1015 BUS_SPACE_MAP_LINEAR
);
1019 if ((offset
>= sc
->sc_regs
) && (offset
< (sc
->sc_regs
+
1021 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
1022 BUS_SPACE_MAP_LINEAR
);
1026 #ifdef PCI_MAGIC_IO_RANGE
1027 /* allow mapping of IO space */
1028 if ((offset
>= PCI_MAGIC_IO_RANGE
) &&\
1029 (offset
< PCI_MAGIC_IO_RANGE
+ 0x10000)) {
1030 pa
= bus_space_mmap(sc
->sc_iot
, offset
- PCI_MAGIC_IO_RANGE
,
1031 0, prot
, BUS_SPACE_MAP_LINEAR
);
1036 #ifdef OFB_ALLOW_OTHERS
1037 if (offset
>= 0x80000000) {
1038 pa
= bus_space_mmap(sc
->sc_memt
, offset
, 0, prot
,
1039 BUS_SPACE_MAP_LINEAR
);
1047 voodoofb_init_screen(void *cookie
, struct vcons_screen
*scr
,
1048 int existing
, long *defattr
)
1050 struct voodoofb_softc
*sc
= cookie
;
1051 struct rasops_info
*ri
= &scr
->scr_ri
;
1053 ri
->ri_depth
= sc
->bits_per_pixel
;
1054 ri
->ri_width
= sc
->width
;
1055 ri
->ri_height
= sc
->height
;
1056 ri
->ri_stride
= sc
->width
;
1057 ri
->ri_flg
= RI_CENTER
| RI_FULLCLEAR
;
1059 ri
->ri_bits
= bus_space_vaddr(sc
->sc_fbt
, sc
->sc_fbh
);
1061 #ifdef VOODOOFB_DEBUG
1062 printf("addr: %08lx\n", (ulong
)ri
->ri_bits
);
1065 ri
->ri_flg
|= RI_CLEAR
;
1068 rasops_init(ri
, sc
->height
/8, sc
->width
/8);
1069 ri
->ri_caps
= WSSCREEN_WSCOLORS
;
1071 rasops_reconfig(ri
, sc
->height
/ ri
->ri_font
->fontheight
,
1072 sc
->width
/ ri
->ri_font
->fontwidth
);
1075 ri
->ri_ops
.copyrows
= voodoofb_copyrows
;
1076 ri
->ri_ops
.copycols
= voodoofb_copycols
;
1077 ri
->ri_ops
.eraserows
= voodoofb_eraserows
;
1078 ri
->ri_ops
.erasecols
= voodoofb_erasecols
;
1079 ri
->ri_ops
.cursor
= voodoofb_cursor
;
1080 ri
->ri_ops
.putchar
= voodoofb_putchar
;
1085 voodoofb_load_font(void *v
, void *cookie
, struct wsdisplay_font
*data
)
1092 #ifdef VOODOOFB_ENABLE_INTR
1094 voodoofb_intr(void *arg
)
1096 struct voodoofb_softc
*sc
= arg
;
1098 voodoo3_write32(sc
, V3_STATUS
, 0); /* clear interrupts */
1103 /* video mode stuff */
1105 #define REFFREQ 14318 /* .18 */
1107 #define ABS(a) ((a < 0) ? -a : a)
1110 voodoofb_calc_pll(int freq
, int *f_out
, int isBanshee
)
1112 int m
, n
, k
, best_m
, best_n
, best_k
, f_cur
, best_error
;
1116 best_n
= best_m
= best_k
= 0;
1124 /* This used to be 64, alas it seems the last 8 (funny that ?)
1125 * values cause jittering at lower resolutions. I've not done
1126 * any calculations to what the adjustment affects clock ranges,
1127 * but I can still run at 1600x1200@75Hz */
1129 for (n
= 1; n
< 256; n
++) {
1130 f_cur
= REFFREQ
* (n
+ 2);
1133 if (freq
- f_cur
< best_error
) {
1134 best_error
= freq
- f_cur
;
1141 for (m
= minm
; m
< maxm
; m
++) {
1142 for (k
= 0; k
< 4; k
++) {
1143 f_cur
= REFFREQ
* (n
+ 2) / (m
+ 2) / (1 << k
);
1144 if (ABS(f_cur
- freq
) < best_error
) {
1145 best_error
= ABS(f_cur
- freq
);
1156 *f_out
= REFFREQ
* (n
+ 2) / (m
+ 2) / (1 << k
);
1157 return ( n
<< 8) | (m
<< 2) | k
;
1161 voodoofb_setup_monitor(struct voodoofb_softc
*sc
, const struct videomode
*vm
)
1163 struct voodoo_regs mod
;
1164 struct voodoo_regs
*mode
;
1165 uint32_t horizontal_display_end
, horizontal_sync_start
,
1166 horizontal_sync_end
, horizontal_total
,
1167 horizontal_blanking_start
, horizontal_blanking_end
;
1169 uint32_t vertical_display_enable_end
, vertical_sync_start
,
1170 vertical_sync_end
, vertical_total
, vertical_blanking_start
,
1171 vertical_blanking_end
;
1173 uint32_t wd
; // CRTC offset
1179 memset(&mod
, 0, sizeof(mode
));
1183 wd
= (vm
->hdisplay
>> 3) - 1;
1184 horizontal_display_end
= (vm
->hdisplay
>> 3) - 1;
1185 horizontal_sync_start
= (vm
->hsync_start
>> 3) - 1;
1186 horizontal_sync_end
= (vm
->hsync_end
>> 3) - 1;
1187 horizontal_total
= (vm
->htotal
>> 3) - 1;
1188 horizontal_blanking_start
= horizontal_display_end
;
1189 horizontal_blanking_end
= horizontal_total
;
1191 vertical_display_enable_end
= vm
->vdisplay
- 1;
1192 vertical_sync_start
= vm
->vsync_start
; // - 1;
1193 vertical_sync_end
= vm
->vsync_end
; // - 1;
1194 vertical_total
= vm
->vtotal
- 2;
1195 vertical_blanking_start
= vertical_display_enable_end
;
1196 vertical_blanking_end
= vertical_total
;
1199 (vm
->hdisplay
< 400 ? 0xa0 :
1200 vm
->hdisplay
< 480 ? 0x60 :
1201 vm
->hdisplay
< 768 ? 0xe0 : 0x20);
1203 mode
->vr_seq
[0] = 3;
1204 mode
->vr_seq
[1] = 1;
1205 mode
->vr_seq
[2] = 8;
1206 mode
->vr_seq
[3] = 0;
1207 mode
->vr_seq
[4] = 6;
1209 /* crtc regs start */
1210 mode
->vr_crtc
[0] = horizontal_total
- 4;
1211 mode
->vr_crtc
[1] = horizontal_display_end
;
1212 mode
->vr_crtc
[2] = horizontal_blanking_start
;
1213 mode
->vr_crtc
[3] = 0x80 | (horizontal_blanking_end
& 0x1f);
1214 mode
->vr_crtc
[4] = horizontal_sync_start
;
1216 mode
->vr_crtc
[5] = ((horizontal_blanking_end
& 0x20) << 2) |
1217 (horizontal_sync_end
& 0x1f);
1218 mode
->vr_crtc
[6] = vertical_total
;
1219 mode
->vr_crtc
[7] = ((vertical_sync_start
& 0x200) >> 2) |
1220 ((vertical_display_enable_end
& 0x200) >> 3) |
1221 ((vertical_total
& 0x200) >> 4) |
1223 ((vertical_blanking_start
& 0x100) >> 5) |
1224 ((vertical_sync_start
& 0x100) >> 6) |
1225 ((vertical_display_enable_end
& 0x100) >> 7) |
1226 ((vertical_total
& 0x100) >> 8);
1228 mode
->vr_crtc
[8] = 0;
1229 mode
->vr_crtc
[9] = 0x40 |
1230 ((vertical_blanking_start
& 0x200) >> 4);
1232 mode
->vr_crtc
[10] = 0;
1233 mode
->vr_crtc
[11] = 0;
1234 mode
->vr_crtc
[12] = 0;
1235 mode
->vr_crtc
[13] = 0;
1236 mode
->vr_crtc
[14] = 0;
1237 mode
->vr_crtc
[15] = 0;
1239 mode
->vr_crtc
[16] = vertical_sync_start
;
1240 mode
->vr_crtc
[17] = (vertical_sync_end
& 0x0f) | 0x20;
1241 mode
->vr_crtc
[18] = vertical_display_enable_end
;
1242 mode
->vr_crtc
[19] = wd
; // CRTC offset
1243 mode
->vr_crtc
[20] = 0;
1244 mode
->vr_crtc
[21] = vertical_blanking_start
;
1245 mode
->vr_crtc
[22] = vertical_blanking_end
+ 1;
1246 mode
->vr_crtc
[23] = 128;
1247 mode
->vr_crtc
[24] = 255;
1249 /* attr regs start */
1250 mode
->vr_attr
[0] = 0;
1251 mode
->vr_attr
[1] = 0;
1252 mode
->vr_attr
[2] = 0;
1253 mode
->vr_attr
[3] = 0;
1254 mode
->vr_attr
[4] = 0;
1255 mode
->vr_attr
[5] = 0;
1256 mode
->vr_attr
[6] = 0;
1257 mode
->vr_attr
[7] = 0;
1258 mode
->vr_attr
[8] = 0;
1259 mode
->vr_attr
[9] = 0;
1260 mode
->vr_attr
[10] = 0;
1261 mode
->vr_attr
[11] = 0;
1262 mode
->vr_attr
[12] = 0;
1263 mode
->vr_attr
[13] = 0;
1264 mode
->vr_attr
[14] = 0;
1265 mode
->vr_attr
[15] = 0;
1266 mode
->vr_attr
[16] = 1;
1267 mode
->vr_attr
[17] = 0;
1268 mode
->vr_attr
[18] = 15;
1269 mode
->vr_attr
[19] = 0;
1272 /* graph regs start */
1273 mode
->vr_graph
[0] = 159;
1274 mode
->vr_graph
[1] = 127;
1275 mode
->vr_graph
[2] = 127;
1276 mode
->vr_graph
[3] = 131;
1277 mode
->vr_graph
[4] = 130;
1278 mode
->vr_graph
[5] = 142;
1279 mode
->vr_graph
[6] = 30;
1280 mode
->vr_graph
[7] = 245;
1281 mode
->vr_graph
[8] = 0;
1283 vga_outb(sc
, MISC_W
, misc
| 0x01);
1285 for(i
= 0; i
< 5; i
++)
1286 voodoo3_write_seq(sc
, i
, mode
->vr_seq
[i
]);
1287 for (i
= 0; i
< 0x19; i
++)
1288 voodoo3_write_crtc(sc
, i
, mode
->vr_crtc
[i
]);
1289 for (i
= 0; i
< 0x14; i
++)
1290 voodoo3_write_attr(sc
, i
, mode
->vr_attr
[i
]);
1291 for (i
= 0; i
< 0x09; i
++)
1292 voodoo3_write_gra(sc
, i
, mode
->vr_graph
[i
]);
1296 voodoofb_set_videomode(struct voodoofb_softc
*sc
,
1297 const struct videomode
*vm
)
1299 uint32_t miscinit0
= 0;
1301 uint32_t vp
, vidproc
= VIDPROCDEFAULT
;
1302 uint32_t bpp
= 1; /* for now */
1303 uint32_t bytes_per_row
= vm
->hdisplay
* bpp
;
1305 sc
->bits_per_pixel
= bpp
<< 3;
1306 sc
->width
= vm
->hdisplay
;
1307 sc
->height
= vm
->vdisplay
;
1308 sc
->linebytes
= bytes_per_row
;
1310 voodoofb_setup_monitor(sc
, vm
);
1311 vp
= voodoo3_read32(sc
, VIDPROCCFG
);
1313 vidproc
&= ~(0x1c0000); /* clear bits 18 to 20, bpp in vidproccfg */
1314 /* enable bits 18 to 20 to the required bpp */
1315 vidproc
|= ((bpp
- 1) << VIDCFG_PIXFMT_SHIFT
);
1317 vidpll
= voodoofb_calc_pll(vm
->dot_clock
, &fout
, 0);
1319 #ifdef VOODOOFB_DEBUG
1320 printf("old vidproc: %08x\n", vp
);
1321 printf("pll: %08x %d\n", vidpll
, fout
);
1323 /* bit 10 of vidproccfg, is enabled or disabled as needed */
1327 * bit 10 off for palettized modes only, off means
1330 vidproc
&= ~(1 << 10);
1335 miscinit0
= 0xc0000000;
1337 /* bypass palette for 16bit modes */
1338 vidproc
|= (1 << 10);
1342 miscinit0
= 0x40000000;
1344 vidproc
|= (1 << 10); /* Same for 32bit modes */
1348 printf("We support only 8 bit for now\n");
1352 voodoofb_wait_idle(sc
);
1354 voodoo3_write32(sc
, MISCINIT1
, voodoo3_read32(sc
, MISCINIT1
) | 0x01);
1356 voodoo3_make_room(sc
, 4);
1357 voodoo3_write32(sc
, VGAINIT0
, 4928);
1358 voodoo3_write32(sc
, DACMODE
, 0);
1359 voodoo3_write32(sc
, VIDDESKSTRIDE
, bytes_per_row
);
1360 voodoo3_write32(sc
, PLLCTRL0
, vidpll
);
1362 voodoo3_make_room(sc
, 5);
1363 voodoo3_write32(sc
, VIDSCREENSIZE
, sc
->width
| (sc
->height
<< 12));
1364 voodoo3_write32(sc
, VIDDESKSTART
, 1024);
1366 vidproc
&= ~VIDCFG_HWCURSOR_ENABLE
;
1367 voodoo3_write32(sc
, VIDPROCCFG
, vidproc
);
1369 voodoo3_write32(sc
, VGAINIT1
, 0);
1370 voodoo3_write32(sc
, MISCINIT0
, miscinit0
);
1371 #ifdef VOODOOFB_DEBUG
1372 printf("vidproc: %08x\n", vidproc
);
1374 voodoo3_make_room(sc
, 8);
1375 voodoo3_write32(sc
, SRCBASE
, 0);
1376 voodoo3_write32(sc
, DSTBASE
, 0);
1377 voodoo3_write32(sc
, COMMANDEXTRA_2D
, 0);
1378 voodoo3_write32(sc
, CLIP0MIN
, 0);
1379 voodoo3_write32(sc
, CLIP0MAX
, 0x0fff0fff);
1380 voodoo3_write32(sc
, CLIP1MIN
, 0);
1381 voodoo3_write32(sc
, CLIP1MAX
, 0x0fff0fff);
1382 voodoo3_write32(sc
, SRCXY
, 0);
1383 voodoofb_wait_idle(sc
);
1384 printf("%s: switched to %dx%d, %d bit\n", device_xname(sc
->sc_dev
),
1385 sc
->width
, sc
->height
, sc
->bits_per_pixel
);
1389 voodoofb_init(struct voodoofb_softc
*sc
)
1392 uint32_t vgainit0
= 0;
1393 uint32_t vidcfg
= 0;
1395 #ifdef VOODOOFB_DEBUG
1396 printf("initializing engine...");
1398 vgainit0
= voodoo3_read32(sc
, VGAINIT0
);
1399 #ifdef VOODOOFB_DEBUG
1400 printf("vga: %08x", vgainit0
);
1404 VGAINIT0_EXT_ENABLE
|
1405 VGAINIT0_WAKEUP_3C3
|
1406 VGAINIT0_ALT_READBACK
|
1407 VGAINIT0_EXTSHIFTOUT
;
1409 vidcfg
= voodoo3_read32(sc
, VIDPROCCFG
);
1410 #ifdef VOODOOFB_DEBUG
1411 printf(" vidcfg: %08x\n", vidcfg
);
1414 VIDCFG_VIDPROC_ENABLE
|
1416 vidcfg
&= ~VIDCFG_HWCURSOR_ENABLE
;
1418 voodoo3_make_room(sc
, 2);
1420 voodoo3_write32(sc
, VGAINIT0
, vgainit0
);
1421 voodoo3_write32(sc
, VIDPROCCFG
, vidcfg
);
1423 voodoo3_make_room(sc
, 8);
1424 voodoo3_write32(sc
, SRCBASE
, 0);
1425 voodoo3_write32(sc
, DSTBASE
, 0);
1426 voodoo3_write32(sc
, COMMANDEXTRA_2D
, 0);
1427 voodoo3_write32(sc
, CLIP0MIN
, 0);
1428 voodoo3_write32(sc
, CLIP0MAX
, 0x1fff1fff);
1429 voodoo3_write32(sc
, CLIP1MIN
, 0);
1430 voodoo3_write32(sc
, CLIP1MAX
, 0x1fff1fff);
1431 voodoo3_write32(sc
, SRCXY
, 0);
1433 voodoofb_wait_idle(sc
);