Subject: 24-bit graphics driver, revisited
To: None <port-sparc@netbsd.org>
From: David C. Myers <myers@iname.com>
List: port-sparc
Date: 02/06/2000 11:05:02
This is a multi-part message in MIME format.
--------------04D95E8512546332870D75EA
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit



Folks:

I'm just getting back to my 24-bit graphics card driver project, and
have run into an issue that has me stumped.  My Sbus driver locks up the
machine at random times.  No crash or panic or anything like that.  It
just locks up solid, requiring a power cycle.  I've attached the source
code, in the hopes that some enterprising soul with time on their hands
will take a look and tell me what I've done wrong.  

Note that Xsun24 does come up using my driver, but the colors are all
screwed up.  (The lockups happen well after Xsun24 gets running.)  In
contrast, a simple userland utility I've written is able to map in the
video memory and scribble to it all day, with no lockups.

Many thanks for any help.  

-David.
--------------04D95E8512546332870D75EA
Content-Type: text/plain; charset=us-ascii;
 name="pllx.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="pllx.c"

/*
 * Copyright (c) 1996
 *	The President and Fellows of Harvard College. All rights reserved.
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This software was developed by the Computer Systems Engineering group
 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
 * contributed to Berkeley.
 *
 * All advertising materials mentioning features or use of this software
 * must display the following acknowledgement:
 *	This product includes software developed by Harvard University.
 *	This product includes software developed by the University of
 *	California, Lawrence Berkeley Laboratory.
 *
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 *	This product includes software developed by Harvard University and
 *	its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
 *
 *   Based on:
 *	NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp
 *	NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp
 *
 *
 * Parallax graphics board support by David Myers.
 */





#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/device.h>
#include <sys/ioctl.h>
#include <sys/malloc.h>
#include <sys/mman.h>
#include <sys/tty.h>
#include <sys/conf.h>

#include <vm/vm.h>

#include <machine/fbio.h>
#include <machine/autoconf.h>
#include <machine/pmap.h>
#include <machine/fbvar.h>
#include <machine/cpu.h>
#include <machine/conf.h>





static void	pllx_attach(struct device *, struct device *, void *);
static int	pllx_match(struct device *, struct cfdata *, void *);
static void	pllxunblank(struct device *);



struct pllx_softc {
    struct device	sc_dev;		/* base device */
    struct sbusdev 	sc_sd;		/* sbus device */
    struct fbdevice	sc_fb;		/* frame buffer device */
    struct fbcmap	sc_cmap;
    bus_space_tag_t	sc_bustag;
    bus_type_t		sc_btype;	/* phys address description */
    bus_addr_t		sc_paddr;	/* for device mmap() */
};



/* 
Somewhere, the following macro is defined.  It creates a bunch of
system-required prototype definitions for each cdev.  This same
declaration also needs to go into /sys/arch/sparc/include/machine/conf.h.
*/

cdev_decl(pllx);



struct cfattach pllx_ca = {
    sizeof(struct pllx_softc), pllx_match, pllx_attach
};


extern struct cfdriver pllx_cd;



/* frame buffer generic driver */
static struct fbdriver pllxfbdriver = {
    pllxunblank, pllxopen, pllxclose, pllxioctl,
    pllxpoll, pllxmmap
};



extern int fbnode;
extern struct tty *fbconstty;





int pllx_match(parent, cf, aux)
     struct device *parent;
     struct cfdata *cf;
     void *aux;
{
    struct sbus_attach_args *sa = aux;
    return (strcmp("PGI,tvtwo", sa->sa_name) == 0);
}




void pllx_attach(parent, self, aux)
     struct device *parent, *self;
     void *aux;
{
    struct sbus_attach_args *sa = aux;
    struct pllx_softc *sc = (struct pllx_softc *)self;
    struct fbdevice *fb = &sc->sc_fb;
    int node;
    int isconsole;

    node = sa->sa_node;

    sc->sc_bustag = sa->sa_bustag;
    sc->sc_btype = (bus_type_t)sa->sa_reg[0].sbr_slot;
    sc->sc_paddr = sa->sa_offset;

    fb->fb_driver = &pllxfbdriver;
    fb->fb_device = &sc->sc_dev;

    /* 
       Force the pllx board into 32 bpp, 1152x900 mode.
       I'm not sure what the difference is between 24 and 32 bit
       modes, but it *must* be 32bpp.  At 24bpp, there's no
       detectable visual difference, but you'll get mysterious lockups.
       It also appears to be faster at 32bpp.
     */

    fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
    fb->fb_type.fb_depth = 32;
    fb->fb_type.fb_width = 1152;
    fb->fb_type.fb_height = 900;
    fb->fb_type.fb_size = 4194304;  /* 4MB */
    fb->fb_linebytes = 1152 * 4;
    fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags & FB_USERMASK;

    sbus_establish(&sc->sc_sd, &sc->sc_dev);

    printf(": Parallax tvtwo, %d x %d\n",
	   fb->fb_type.fb_width, fb->fb_type.fb_height);

    /* see if we're the console */
    isconsole = node == fbnode && fbconstty != NULL;

    /* Attach to /dev/fb */
    if (node == fbnode)
	fb_attach(&sc->sc_fb, isconsole);
}




int pllxopen(dev, flags, mode, p)
     dev_t dev;
     int flags, mode;
     struct proc *p;
{
    int unit = minor(dev);

    if (unit >= pllx_cd.cd_ndevs || pllx_cd.cd_devs[unit] == NULL)
	return (ENXIO);

    return (0);
}



int pllxclose(dev, flags, mode, p)
     dev_t dev;
     int flags, mode;
     struct proc *p;
{
    return (0);
}





int pllxioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) {
    struct pllx_softc *sc = pllx_cd.cd_devs[minor(dev)];
    struct fbgattr *fba;

    switch (cmd) {
    case FBIOGTYPE:
	*(struct fbtype *)data = sc->sc_fb.fb_type;
	break;

    case FBIOGATTR:
	fba = (struct fbgattr *)data;
	fba->real_type = sc->sc_fb.fb_type.fb_type;  /* FBTYPE_MEMCOLOR */
	fba->owner = 0;		/* XXX ??? */
	fba->fbtype = sc->sc_fb.fb_type;
	fba->sattr.flags = 0;
	fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
	fba->sattr.dev_specific[0] = -1;
	fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
	fba->emu_types[1] = -1;
	break;

    case FBIOGETCMAP:
	/* printf("pllxioctl: FBIOGETCMAP\n"); */
	break;

    case FBIOPUTCMAP:
	/* printf("pllxioctl: FBIOPUTCMAP\n"); */
	break;

    case FBIOGVIDEO:
	/* printf("pllxioctl: FBIOGVIDEO\n"); */
	break;
	
    case FBIOSVIDEO:
	/* printf("pllxioctl: FBIOSVIDEO\n"); */
	break;
	
	/* 
	   Note: we don't want to implement FBIOSCURSOR, FBIOGCURSOR, or FBIOCURMAX.
	   X will check for these, and if they return successfully, it will assume the board
	   has a hardware cursor.  In fact, the Parallax *does* have a hardware cursor,
	   but I don't know how to support it.
	*/

    default:
	return (ENOTTY);
    }
    

    return (0);
}




static void pllxunblank(dev)
     struct device *dev;
{
}




/* 
   Parallax Memory Map

   The original Parallax driver source code for Solaris contains
   the following memory layout:

   PROM0		0 - FFFF
   1-bit framebuffer	10000 - 37FFF
   unused		38000 - 3FFFF
   registers		40000 - 404D0
   unused		404D4 - 4FFFF
   CCube		50000 - 5FFFF
   unused		60000 - 7FFFF
   8-bit framebuffer	80000 - 17FFFF
   unused		180000 - 1FFFFF
   24-bit framebuffer	200000 - 6FFFFF
   unused		700000 - 7EFFFF
   PROM1		7F0000 - 7FFFFF

   Ccube is the MPEG compression codec built into some models of
   Parallax boards.  It has nothing to do with the framebuffer
   itself.  Someday, I'd like to be able to support it.
*/


int pllxmmap(dev, off, prot)
     dev_t dev;
     int off, prot;
{
    struct pllx_softc *sc = pllx_cd.cd_devs[minor(dev)];
    bus_space_handle_t bh;

    if (off & PGOFSET)
	panic("pllxmmap");

    /* 
       Offset the parallax board by 0x200000 (as per memory map above)
    */

    if (bus_space_mmap(sc->sc_bustag,
		       sc->sc_btype,
		       0x200000 + off,
		       BUS_SPACE_MAP_LINEAR, &bh))
	return (-1);
    
    return ((int) bh);
}





int pllxpoll(dev, events, p)
     dev_t dev;
     int events;
     struct proc *p;
{
    return (seltrue(dev, events, p));
}











--------------04D95E8512546332870D75EA--