From a39bec69a604211a5c9e4fc5b8c1788bf0a7716c Mon Sep 17 00:00:00 2001 From: macallan Date: Wed, 10 Mar 2010 05:16:17 +0000 Subject: [PATCH] - move register definition in their own header, reduce magic numbers - get geometry and framebuffer layout from the chip instead of hardcoding - get rid of some now superfluous leftovers - remove some debug code - clean things up a bit - dump registers with WCFB_DEBUG even if we're not the console --- sys/dev/pci/wcfb.c | 87 +++++++++++++++++-------------------------- sys/dev/pci/wcfbreg.h | 56 ++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 sys/dev/pci/wcfbreg.h diff --git a/sys/dev/pci/wcfb.c b/sys/dev/pci/wcfb.c index 81fc298e2ffe..0d50b8bcbbc3 100644 --- a/sys/dev/pci/wcfb.c +++ b/sys/dev/pci/wcfb.c @@ -1,4 +1,4 @@ -/* $NetBSD: wcfb.c,v 1.5 2010/03/10 02:41:02 macallan Exp $ */ +/* $NetBSD: wcfb.c,v 1.6 2010/03/10 05:16:17 macallan Exp $ */ /*- * Copyright (c) 2010 Michael Lorenz @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wcfb.c,v 1.5 2010/03/10 02:41:02 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wcfb.c,v 1.6 2010/03/10 05:16:17 macallan Exp $"); #include #include @@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: wcfb.c,v 1.5 2010/03/10 02:41:02 macallan Exp $"); #include #include #include +#include #include #include @@ -94,7 +95,7 @@ struct wcfb_softc { u_char sc_cmap_red[256]; u_char sc_cmap_green[256]; u_char sc_cmap_blue[256]; - uint32_t sc_fb0off; + uint32_t sc_fb0off, sc_fb1off; void (*copycols)(void *, int, int, int, int); void (*erasecols)(void *, int, int, int, long); @@ -151,8 +152,9 @@ wcfb_attach(device_t parent, device_t self, void *aux) prop_dictionary_t dict; struct wsemuldisplaydev_attach_args aa; int i, j; + uint32_t reg; unsigned long defattr; - bool is_console; + bool is_console = 0; char devinfo[256]; void *wtf; @@ -164,23 +166,14 @@ wcfb_attach(device_t parent, device_t self, void *aux) dict = device_properties(self); prop_dictionary_get_bool(dict, "is_console", &is_console); - if(!is_console) return; - +#ifndef WCFB_DEBUG + if (!is_console) return; +#endif sc->sc_memt = pa->pa_memt; sc->sc_iot = pa->pa_iot; sc->sc_pc = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; - /* fill in parameters from properties */ - if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) { - aprint_error("%s: no width property\n", device_xname(self)); - return; - } - if (!prop_dictionary_get_uint32(dict, "height", &sc->sc_height)) { - aprint_error("%s: no height property\n", device_xname(self)); - return; - } - if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_MEM, 0, &sc->sc_regt, &sc->sc_regh, &sc->sc_reg, &sc->sc_regsize)) { aprint_error("%s: failed to map registers.\n", @@ -203,13 +196,19 @@ wcfb_attach(device_t parent, device_t self, void *aux) sc->sc_fbaddr = bus_space_vaddr(sc->sc_memt, sc->sc_fbh); - sc->sc_fb0off = bus_space_read_4(sc->sc_regt, sc->sc_regh, 0x8080) - - sc->sc_fb; + sc->sc_fb0off = + bus_space_read_4(sc->sc_regt, sc->sc_regh, WC_FB8_ADDR0) - sc->sc_fb; sc->sc_fb0 = sc->sc_fbaddr + sc->sc_fb0off; - sc->sc_fb1 = sc->sc_fb0 + 0x200000; + sc->sc_fb1off = + bus_space_read_4(sc->sc_regt, sc->sc_regh, WC_FB8_ADDR1) - sc->sc_fb; + sc->sc_fb1 = sc->sc_fbaddr + sc->sc_fb1off; - sc->sc_stride = 1 << - ((bus_space_read_4(sc->sc_regt, sc->sc_regh, 0x8074) & 0x00ff0000) >> 16); + reg = bus_space_read_4(sc->sc_regt, sc->sc_regh, WC_RESOLUTION); + sc->sc_height = (reg >> 16) + 1; + sc->sc_width = (reg & 0xffff) + 1; + sc->sc_stride = 1 << + ((bus_space_read_4(sc->sc_regt, sc->sc_regh, WC_CONFIG) & + 0x00ff0000) >> 16); printf("%s: %d x %d, %d\n", device_xname(sc->sc_dev), sc->sc_width, sc->sc_height, sc->sc_stride); @@ -229,6 +228,9 @@ wcfb_attach(device_t parent, device_t self, void *aux) printf("\n"); } + /* make sure video output is on */ + bus_space_write_4(sc->sc_regt, sc->sc_regh, WC_DPMS_STATE, WC_DPMS_ON); + sc->sc_defaultscreen_descr = (struct wsscreen_descr){ "default", 0, 0, @@ -263,20 +265,16 @@ wcfb_attach(device_t parent, device_t self, void *aux) rasops_cmap[j + 2]); j += 3; } - wcfb_putpalreg(sc, 0, 0, 0, 0); - wcfb_putpalreg(sc, 15, 0xff, 0xff, 0xff); if (is_console) { vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; -#if 0 - wcfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, - ri->ri_devcmap[(defattr >> 16) & 0xff]); -#else - /*memset(sc->sc_fbaddr + sc->sc_fb0off, 0, 0x400000);*/ -#endif + memset(sc->sc_fb0, ri->ri_devcmap[(defattr >> 16) & 0xff], + sc->sc_stride * sc->sc_height); + memset(sc->sc_fb1, ri->ri_devcmap[(defattr >> 16) & 0xff], + sc->sc_stride * sc->sc_height); sc->sc_defaultscreen_descr.textops = &ri->ri_ops; sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; sc->sc_defaultscreen_descr.nrows = ri->ri_rows; @@ -289,7 +287,11 @@ wcfb_attach(device_t parent, device_t self, void *aux) * since we're not the console we can postpone the rest * until someone actually allocates a screen for us */ - (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr); + memset(sc->sc_fb0, WS_DEFAULT_BG, + sc->sc_stride * sc->sc_height); + memset(sc->sc_fb1, WS_DEFAULT_BG, + sc->sc_stride * sc->sc_height); + return; } aa.console = is_console; @@ -350,27 +352,6 @@ wcfb_mmap(void *v, void *vs, off_t offset, int prot) } #endif - /* - * XXX this should be generalized, let's just - * #define PCI_IOAREA_PADDR - * #define PCI_IOAREA_OFFSET - * #define PCI_IOAREA_SIZE - * somewhere in a MD header and compile this code only if all are - * present - */ - /* - * PCI_IOAREA_PADDR is useless, that's what the IO tag is for - * the address isn't guaranteed to be the same on each host bridge - * either, never mind the fact that it would be a bus address - */ -#ifdef PCI_MAGIC_IO_RANGE - /* allow to map our IO space */ - if ((offset >= PCI_MAGIC_IO_RANGE) && - (offset < PCI_MAGIC_IO_RANGE + 0x10000)) { - return bus_space_mmap(sc->sc_iot, offset - PCI_MAGIC_IO_RANGE, - 0, prot, BUS_SPACE_MAP_LINEAR); - } -#endif return -1; } @@ -443,9 +424,9 @@ wcfb_putpalreg(struct wcfb_softc *sc, int i, int r, int g, int b) { uint32_t rgb; - bus_space_write_4(sc->sc_regt, sc->sc_regh, 0x80bc, i); + bus_space_write_4(sc->sc_regt, sc->sc_regh, WC_CMAP_INDEX, i); rgb = (b << 22) | (g << 12) | (r << 2); - bus_space_write_4(sc->sc_regt, sc->sc_regh, 0x80c0, rgb); + bus_space_write_4(sc->sc_regt, sc->sc_regh, WC_CMAP_DATA, rgb); } static void diff --git a/sys/dev/pci/wcfbreg.h b/sys/dev/pci/wcfbreg.h new file mode 100644 index 000000000000..64cb278bab45 --- /dev/null +++ b/sys/dev/pci/wcfbreg.h @@ -0,0 +1,56 @@ +/* $NetBSD: wcfbreg.h,v 1.1 2010/03/10 05:16:17 macallan Exp $ */ + +/*- + * Copyright (c) 2010 Michael Lorenz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * register definitions for 3Dlabs Wildcat + * mostly from OpenBSD's ifb driver + */ + +#ifndef WCFBREG_H +#define WCFBREG_H + +#define WC_RESOLUTION 0x8070 +#define WC_CONFIG 0x8074 /* contains log2(stride) in 0x00ff0000 */ +#define WC_FB8_ADDR0 0x8080 +#define WC_FB8_ADDR1 0x8084 + +#define WC_CMAP_INDEX 0x80bc +#define WC_CMAP_DATA 0x80c0 + +/* + * 80e4 DPMS state register + * States ``off'' and ``suspend'' need chip reprogramming before video can + * be enabled again. + */ +#define WC_DPMS_STATE 0x80e4 + #define WC_DPMS_OFF 0x00000000 + #define WC_DPMS_SUSPEND 0x00000001 + #define WC_DPMS_STANDBY 0x00000002 + #define WC_DPMS_ON 0x00000003 + +#endif