Example #1
0
/*
 * Attach.. plug pointer in and print some info.
 * Then try and attach a wsdisplay or ite to us.
 * Note: self is NULL durring console init.
 */
void
grfattach(device_t parent, device_t self, void *aux)
{
#if NWSDISPLAY > 0
	struct wsemuldisplaydev_attach_args wa;
	long defattr;
#endif
	struct grf_softc *gp;
	int maj;

	gp = device_private(parent);
	gp->g_device = self;
	grfsp[gp->g_unit] = gp;

	/*
	 * find our major device number
	 */
	maj = cdevsw_lookup_major(&grf_cdevsw);

	gp->g_grfdev = makedev(maj, gp->g_unit);
	if (self != NULL) {
		printf(": width %d height %d", gp->g_display.gd_dwidth,
		    gp->g_display.gd_dheight);
		if (gp->g_display.gd_colors == 2)
			printf(" monochrome\n");
		else
			printf(" colors %d\n", gp->g_display.gd_colors);
#if NWSDISPLAY > 0
		vcons_init(&gp->g_vd, gp, gp->g_screens[0], gp->g_accessops);
		gp->g_vd.init_screen = grf_init_screen;
		if (gp->g_flags & GF_CONSOLE) {
			console_vcons.scr_flags |= VCONS_SCREEN_IS_STATIC;
			vcons_init_screen(&gp->g_vd,
			    &console_vcons, 1, &defattr);
			gp->g_screens[0]->textops =
			    &console_vcons.scr_ri.ri_ops;
			wsdisplay_cnattach(gp->g_screens[0],
			    &console_vcons.scr_ri, 0, 0, defattr);
			vcons_replay_msgbuf(&console_vcons);
		}

		/* attach wsdisplay */
		wa.console = (gp->g_flags & GF_CONSOLE) != 0;
		wa.scrdata = &gp->g_screenlist;
		wa.accessops = gp->g_accessops;
		wa.accesscookie = &gp->g_vd;
		config_found(self, &wa, wsemuldisplaydevprint);
#endif  /* NWSDISPLAY > 0 */
	}

#if NWSDISPLAY == 0
	/*
	 * try and attach an ite
	 */
	amiga_config_found(cfdata, self, gp, grfprint);
#endif
}
static void
vidcvideo_attach(device_t parent, device_t self, void *aux)
{
	struct vidcvideo_softc *sc = device_private(self);
	struct fb_devconfig *dc;
	struct wsemuldisplaydev_attach_args waa;
	long defattr;
	
	sc->sc_dev = self;

	dc = sc->sc_dc = &vidcvideo_console_dc;

	/*
	 * for reasons which are crazy we init vidcvideo twice,
	 * the second time sets up the cursor
	 */
	vidcvideo_init();
	if (!vidcvideo_is_console) {
		vidcvideo_getdevconfig(videomemory.vidm_vbase, 
				videomemory.vidm_size,
			       	sc->sc_dc);
	}

	vcons_init(&dc->dc_vd, dc, &vidcvideo_stdscreen, &vidcvideo_accessops);
	dc->dc_vd.init_screen = vidcvideoinit_screen;

	vcons_init_screen(&dc->dc_vd, &dc->dc_console, 1, &defattr);

	dc->dc_console.scr_flags |= VCONS_SCREEN_IS_STATIC;

	vidcvideo_printdetails();
	aprint_normal(": mode %s, %dbpp\n", dc->mode_info.timings.name,
	    dc->dc_depth);

	/* set up interrupt flags */
	vidcvideo_queue_dc_change(dc, WSDISPLAY_CMAP_DOLUT);

	/* Establish an interrupt handler, and clear any pending interrupts */
	dc->dc_ih = intr_claim(IRQ_FLYBACK, IPL_TTY, "vblank", vidcvideointr, dc);

	waa.console = (vidcvideo_is_console ? 1 : 0);
	waa.scrdata = &vidcvideo_screenlist;
	waa.accessops = &vidcvideo_accessops;
	waa.accesscookie = &dc->dc_vd;

	config_found(self, &waa, wsemuldisplaydevprint);
}
Example #3
0
static void
newport_attach(device_t parent, device_t self, void *aux)
{
	struct gio_attach_args *ga = aux;
	struct newport_softc *sc = device_private(self);
	struct wsemuldisplaydev_attach_args wa;
	unsigned long defattr;

	sc->sc_dev = self;
	if (newport_is_console && ga->ga_addr == newport_console_dc.dc_addr) {
		wa.console = 1;
		sc->sc_dc = &newport_console_dc;
	} else {
		wa.console = 0;
		sc->sc_dc = malloc(sizeof(struct newport_devconfig),
		    M_DEVBUF, M_WAITOK | M_ZERO);
		if (sc->sc_dc == NULL)
			panic("newport_attach: out of memory");

		newport_attach_common(sc->sc_dc, ga);
	}

	aprint_naive(": Display adapter\n");

	aprint_normal(": SGI NG1 (board revision %d, cmap revision %d, xmap revision %d, vc2 revision %d), depth %d\n",
	    sc->sc_dc->dc_boardrev, sc->sc_dc->dc_cmaprev,
	    sc->sc_dc->dc_xmaprev, sc->sc_dc->dc_vc2rev, sc->sc_dc->dc_depth);
	vcons_init(&sc->sc_dc->dc_vd, sc->sc_dc, sc->sc_dc->dc_screen,
	    &newport_accessops);
	sc->sc_dc->dc_vd.init_screen = newport_init_screen;
	if (newport_is_console) {
		newport_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
		vcons_init_screen(&sc->sc_dc->dc_vd, &newport_console_screen,
		    1, &defattr);
		sc->sc_dc->dc_screen->textops =
		    &newport_console_screen.scr_ri.ri_ops;
		memcpy(&newport_textops, &newport_console_screen.scr_ri.ri_ops,
		    sizeof(struct wsdisplay_emulops));
		vcons_replay_msgbuf(&newport_console_screen);
	}
	wa.scrdata = &newport_screenlist;
	wa.accessops = &newport_accessops;
	wa.accesscookie = &sc->sc_dc->dc_vd;

	config_found(sc->sc_dev, &wa, wsemuldisplaydevprint);
}
Example #4
0
static void
zx_attach(device_t parent, device_t self, void *args)
{
	struct zx_softc *sc;
	struct sbus_attach_args *sa;
	bus_space_handle_t bh;
	bus_space_tag_t bt;
	struct fbdevice *fb;
#if NWSDISPLAY > 0
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri = &zx_console_screen.scr_ri;
	unsigned long defattr;
#endif
	int isconsole, width, height;

	sc = device_private(self);
	sc->sc_dv = self;

	sa = args;
	fb = &sc->sc_fb;
	bt = sa->sa_bustag;
	sc->sc_bt = bt;
	sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0,
	    0x800000, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, &bh) != 0) {
		aprint_error_dev(self, "can't map bits\n");
		return;
	}
	fb->fb_pixels = (void *)bus_space_vaddr(bt, bh);
	sc->sc_pixels = (uint32_t *)fb->fb_pixels;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map zc\n");
		return;
	}

	sc->sc_bhzc = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map ld/ss0\n");
		return;
	}
	sc->sc_bhzdss0 = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map ld/ss1\n");
		return;
	}
	sc->sc_bhzdss1 = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map zx\n");
		return;
	}
	sc->sc_bhzx = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map zcu\n");
		return;
	}
	sc->sc_bhzcu = bh;

	fb->fb_driver = &zx_fbdriver;
	fb->fb_device = sc->sc_dv;
	fb->fb_flags = device_cfdata(sc->sc_dv)->cf_flags & FB_USERMASK;
	fb->fb_pfour = NULL;
	fb->fb_linebytes = prom_getpropint(sa->sa_node, "linebytes", 8192);

	width = prom_getpropint(sa->sa_node, "width", 1280);
	height = prom_getpropint(sa->sa_node, "height", 1024);
	fb_setsize_obp(fb, 32, width, height, sa->sa_node);

	fb->fb_type.fb_cmsize = 256;
	fb->fb_type.fb_depth = 32;
	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
	fb->fb_type.fb_type = FBTYPE_SUNLEO;

	printf(": %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height);
	isconsole = fb_is_console(sa->sa_node);
	if (isconsole)
		printf(" (console)");
	printf("\n");

	if (sa->sa_nintr != 0)
		bus_intr_establish(bt, sa->sa_pri, IPL_NONE, zx_intr, sc);

	sc->sc_cmap = malloc(768, M_DEVBUF, M_NOWAIT);
	zx_reset(sc);

#if NWSDISPLAY > 0
	sc->sc_width = fb->fb_type.fb_width;
	sc->sc_stride = 8192; /* 32 bit */
	sc->sc_height = fb->fb_type.fb_height;

	/* setup rasops and so on for wsdisplay */
	wsfont_init();
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
	sc->sc_bg = WS_DEFAULT_BG;

	vcons_init(&sc->vd, sc, &zx_defaultscreen, &zx_accessops);
	sc->vd.init_screen = zx_init_screen;

	if (isconsole) {
		/* we mess with zx_console_screen only once */
		vcons_init_screen(&sc->vd, &zx_console_screen, 1,
		    &defattr);
		zx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
		
		zx_defaultscreen.textops = &ri->ri_ops;
		zx_defaultscreen.capabilities = WSSCREEN_WSCOLORS;
		zx_defaultscreen.nrows = ri->ri_rows;
		zx_defaultscreen.ncols = ri->ri_cols;
		zx_fillrect(sc, 0, 0, width, height,
		     ri->ri_devcmap[defattr >> 16], ZX_STD_ROP);
		wsdisplay_cnattach(&zx_defaultscreen, ri, 0, 0, defattr);
		vcons_replay_msgbuf(&zx_console_screen);
	} else {
		/* 
		 * we're not the console so we just clear the screen and don't 
		 * set up any sort of text display
		 */
		if (zx_defaultscreen.textops == NULL) {
Example #5
0
void
cgthreeattach(struct cgthree_softc *sc, const char *name, int isconsole)
{
	int i;
	struct fbdevice *fb = &sc->sc_fb;
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri = &cg3_console_screen.scr_ri;
	unsigned long defattr;
	volatile struct fbcontrol *fbc = sc->sc_fbc;
	volatile struct bt_regs *bt = &fbc->fbc_dac;

	fb->fb_driver = &cgthreefbdriver;
	fb->fb_type.fb_cmsize = 256;
	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
	printf(": %s, %d x %d", name,
		fb->fb_type.fb_width, fb->fb_type.fb_height);

	/* Transfer video magic to board, if it's not running */
	if ((fbc->fbc_ctrl & FBC_TIMING) == 0) {
		int sense = (fbc->fbc_status & FBS_MSENSE);
		/* Search table for video timings fitting this monitor */
		for (i = 0; i < sizeof(cg3_videoctrl)/sizeof(cg3_videoctrl[0]);
		     i++) {
			int j;
			if (sense != cg3_videoctrl[i].sense)
				continue;

			printf(" setting video ctrl");
			for (j = 0; j < 12; j++)
				fbc->fbc_vcontrol[j] =
					cg3_videoctrl[i].vctrl[j];
			fbc->fbc_ctrl |= FBC_TIMING;
			break;
		}
	}

	/* make sure we are not blanked */
	cgthree_set_video(sc, 1);
	BT_INIT(bt, 0);

	if (isconsole) {
		printf(" (console)\n");
	} else
		printf("\n");

	fb_attach(fb, isconsole);

	sc->sc_width = fb->fb_type.fb_width;
	sc->sc_stride = fb->fb_type.fb_width;
	sc->sc_height = fb->fb_type.fb_height;

	/* setup rasops and so on for wsdisplay */
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	vcons_init(&sc->vd, sc, &cgthree_defaultscreen, &cgthree_accessops);
	sc->vd.init_screen = cgthree_init_screen;

	if(isconsole) {
		/* we mess with cg3_console_screen only once */
		vcons_init_screen(&sc->vd, &cg3_console_screen, 1,
		    &defattr);
		memset(sc->sc_fb.fb_pixels, (defattr >> 16) & 0xff,
		    sc->sc_stride * sc->sc_height);
		cg3_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

		cgthree_defaultscreen.textops = &ri->ri_ops;
		cgthree_defaultscreen.capabilities = ri->ri_caps;
		cgthree_defaultscreen.nrows = ri->ri_rows;
		cgthree_defaultscreen.ncols = ri->ri_cols;
		sc->vd.active = &cg3_console_screen;
		wsdisplay_cnattach(&cgthree_defaultscreen, ri, 0, 0, defattr);
		vcons_replay_msgbuf(&cg3_console_screen);
	} else {
		/* 
		 * we're not the console so we just clear the screen and don't 
		 * set up any sort of text display
		 */
	}
Example #6
0
static void
ofbattach(device_t parent, device_t self, void *aux)
{
	struct ofb_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct wsemuldisplaydev_attach_args a;
	struct rasops_info *ri = &rascons_console_screen.scr_ri;
	long defattr;
	int console, node, sub;
	char devinfo[256];

	sc->sc_dev = self;

	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
	printf(": %s\n", devinfo);

	if (console_node == 0)
		return;

	node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
	console = (node == console_node);
	if (!console) {
		/* check if any of the childs matches */
		sub = OF_child(node);
		while ((sub != 0) && (sub != console_node)) {
			sub = OF_peer(sub);
		}
		if (sub == console_node) {
			console = true;
		}
	}
	
	sc->sc_memt = pa->pa_memt;
	sc->sc_iot = pa->pa_iot;	
	sc->sc_pc = pa->pa_pc;
	sc->sc_pcitag = pa->pa_tag;
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	if (!console)
		return;
	
	vcons_init(&sc->vd, sc, &rascons_stdscreen, &ofb_accessops);
	sc->vd.init_screen = ofb_init_screen;

	sc->sc_node = console_node;

	sc->sc_ih = console_instance;
	vcons_init_screen(&sc->vd, &rascons_console_screen, 1, &defattr);
	rascons_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
	
	printf("%s: %d x %d, %dbpp\n", device_xname(self),
	       ri->ri_width, ri->ri_height, ri->ri_depth);
	
	sc->sc_fbaddr = 0;
	if (OF_getprop(sc->sc_node, "address", &sc->sc_fbaddr, 4) != 4)
		OF_interpret("frame-buffer-adr", 0, 1, &sc->sc_fbaddr);
	if (sc->sc_fbaddr == 0) {
		printf("%s: Unable to find the framebuffer address.\n",
		    device_xname(sc->sc_dev));
		return;
	}
	sc->sc_fbsize = round_page(ri->ri_stride * ri->ri_height);

	/* XXX */
	if (OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs,
	    sizeof(sc->sc_addrs)) == -1) {
		sc->sc_node = OF_parent(sc->sc_node);
		OF_getprop(sc->sc_node, "assigned-addresses", sc->sc_addrs,
		    sizeof(sc->sc_addrs));
	}

	ofb_init_cmap(sc);

	a.console = console;
	a.scrdata = &ofb_screenlist;
	a.accessops = &ofb_accessops;
	a.accesscookie = &sc->vd;

	config_found(self, &a, wsemuldisplaydevprint);

	config_found_ia(self, "drm", aux, ofb_drm_print);
}
Example #7
0
void
bwtwoattach(struct bwtwo_softc *sc, const char *name, int isconsole)
{
	struct fbdevice *fb = &sc->sc_fb;
	int isoverlay;
#if NWSDISPLAY > 0
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri = &bw2_console_screen.scr_ri;
	unsigned long defattr = 0;
#endif

	/* Fill in the remaining fbdevice values */
	fb->fb_driver = &bwtwofbdriver;
	fb->fb_device = sc->sc_dev;
	fb->fb_type.fb_type = FBTYPE_SUN2BW;
	fb->fb_type.fb_cmsize = 0;
	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
	printf(": %s, %d x %d", name,
	       fb->fb_type.fb_width, fb->fb_type.fb_height);

	/* Are we an overlay bw2? */
	if ((fb->fb_flags & FB_PFOUR) == 0 || (sc->sc_ovtype == BWO_NONE))
		isoverlay = 0;
	else
		isoverlay = 1;

	/* Insure video is enabled */
	sc->sc_set_video(sc, 1);

	if (isconsole) {
		printf(" (console)\n");
#ifdef RASTERCONSOLE
		/*
		 * XXX rcons doesn't seem to work properly on the overlay
		 * XXX plane.  This is a temporary kludge until someone
		 * XXX fixes it.
		 */
		if (!isoverlay)
			fbrcons_init(fb);
#endif
	} else
		printf("\n");

	if (isoverlay) {
		const char *ovnam;

		switch (sc->sc_ovtype) {
		case BWO_CGFOUR:
			ovnam = "cgfour";
			break;

		case BWO_CGEIGHT:
			ovnam = "cgeight";
			break;

		default:
			ovnam = "unknown";
			break;
		}
		printf("%s: %s overlay plane\n",
		    device_xname(sc->sc_dev), ovnam);
	}

	/*
	 * If we're on an overlay plane of a color framebuffer,
	 * then we don't force the issue in fb_attach() because
	 * we'd like the color framebuffer to actually be the
	 * "console framebuffer".  We're only around to speed
	 * up rconsole.
	 */
	if (isoverlay)
		fb_attach(fb, 0);
	else
		fb_attach(fb, isconsole);

#if NWSDISPLAY > 0
	sc->sc_width = fb->fb_type.fb_width;
	sc->sc_stride = fb->fb_type.fb_width/8;
	sc->sc_height = fb->fb_type.fb_height;

	/* setup rasops and so on for wsdisplay */
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	vcons_init(&sc->vd, sc, &bwtwo_defaultscreen, &bwtwo_accessops);
	sc->vd.init_screen = bwtwo_init_screen;

	if(isconsole && !isoverlay) {
		/* we mess with bw2_console_screen only once */
		vcons_init_screen(&sc->vd, &bw2_console_screen, 1,
		    &defattr);
		bw2_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

		bwtwo_defaultscreen.textops = &ri->ri_ops;
		bwtwo_defaultscreen.capabilities = ri->ri_caps;
		bwtwo_defaultscreen.nrows = ri->ri_rows;
		bwtwo_defaultscreen.ncols = ri->ri_cols;
		sc->vd.active = &bw2_console_screen;
		wsdisplay_cnattach(&bwtwo_defaultscreen, ri, 0, 0, defattr);
	} else {
		/* 
		 * we're not the console so we just clear the screen and don't 
		 * set up any sort of text display
		 */
		if (bwtwo_defaultscreen.textops == NULL) {
			/* 
			 * ugly, but...
			 * we want the console settings to win, so we only
			 * touch anything when we find an untouched screen
			 * definition. In this case we fill it from fb to
			 * avoid problems in case no bwtwo is the console
			 */
			bwtwo_defaultscreen.textops = &ri->ri_ops;
			bwtwo_defaultscreen.capabilities = ri->ri_caps;
			bwtwo_defaultscreen.nrows = ri->ri_rows;
			bwtwo_defaultscreen.ncols = ri->ri_cols;
		}
	}

	aa.scrdata = &bwtwo_screenlist;
	if (isoverlay)
		aa.console = 0;
	else
		aa.console = isconsole;
	aa.accessops = &bwtwo_accessops;
	aa.accesscookie = &sc->vd;
	config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
#endif

}
Example #8
0
static void
igmafb_attach(device_t parent, device_t self, void *aux)
{
    struct igmafb_softc *sc = device_private(self);
    struct igma_attach_args *iaa = (struct igma_attach_args *)aux;
    struct rasops_info *ri;
    prop_dictionary_t dict;
    bool is_console;
    unsigned long defattr;
    struct wsemuldisplaydev_attach_args waa;

    sc->sc_dev = self;

    aprint_normal("\n");

    dict = device_properties(self);
    prop_dictionary_get_bool(dict, "is_console", &is_console);
    if (iaa->iaa_console)
        is_console = true;

    sc->sc_chip = iaa->iaa_chip;

    sc->sc_fbaddr = bus_space_vaddr(sc->sc_chip.gmt, sc->sc_chip.gmh);
    sc->sc_fbsize = 16 * 1024 * 1024;

    igmafb_guess_size(sc, &sc->sc_width, &sc->sc_height);
    sc->sc_depth = 32;
    sc->sc_stride = (sc->sc_width*4 + 511)/512*512;

    aprint_normal("%s: %d x %d, %d bit, stride %d\n", device_xname(self),
                  sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride);

    aprint_normal("%s: %d MB video memory at 0x%p\n", device_xname(self),
                  (int)sc->sc_fbsize >> 20, (void *)sc->sc_chip.gmb);

    sc->sc_vga_save = kmem_alloc(256*1024, KM_SLEEP);

    igmafb_get_brightness(sc, &sc->sc_brightness);
    igmafb_get_brightness_max(sc, &sc->sc_brightness_max);
    sc->sc_backlight = sc->sc_brightness != 0;

    sc->sc_defaultscreen_descr = (struct wsscreen_descr) {
        "default",
        0, 0,
        NULL,
        8, 16,
        WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
        NULL
    };
    sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
    sc->sc_screenlist = (struct wsscreen_list) {
        1, sc->sc_screens
    };

    vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
               &igmafb_accessops);
    sc->vd.init_screen = igmafb_init_screen;

    /* enable hardware display */
    igmafb_set_mode(sc, true);

    ri = &sc->sc_console_screen.scr_ri;

    if (is_console) {
        vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
                          &defattr);

        sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC
                                           | VCONS_NO_COPYROWS | VCONS_NO_COPYCOLS;
        vcons_redraw_screen(&sc->sc_console_screen);

        sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
        sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
        sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
        sc->sc_defaultscreen_descr.ncols = ri->ri_cols;

        wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
                           defattr);
        vcons_replay_msgbuf(&sc->sc_console_screen);
    } else {
        if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
            /* do some minimal setup to avoid weirdness later */
            vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
                              &defattr);
        } else
            (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
    }

    waa.console = is_console;
    waa.scrdata = &sc->sc_screenlist;
    waa.accessops = &igmafb_accessops;
    waa.accesscookie = &sc->vd;

    config_found(sc->sc_dev, &waa, wsemuldisplaydevprint);
}

/*
 * wsdisplay accessops
 */

static int
igmafb_ioctl(void *v, void *vs, u_long cmd, void *data, int flags,
             struct lwp *l)
{
    struct vcons_data *vd = v;
    struct igmafb_softc *sc = vd->cookie;
    struct wsdisplay_fbinfo *wdf;
    struct vcons_screen *ms = vd->active;
    struct wsdisplayio_fbinfo *fbi;
    struct wsdisplay_param *param;
    int val;

    switch (cmd) {
    case WSDISPLAYIO_GTYPE:
        *(u_int *)data = WSDISPLAY_TYPE_PCIMISC;
        return 0;
    case WSDISPLAYIO_GINFO:
        if (ms == NULL)
            return ENODEV;
        wdf = data;
        wdf->width  = ms->scr_ri.ri_width;
        wdf->height = ms->scr_ri.ri_height;
        wdf->depth  = ms->scr_ri.ri_depth;
        wdf->cmsize = 256; /* XXX */
        return 0;
    case WSDISPLAYIO_LINEBYTES:
        if (ms == NULL)
            return ENODEV;
        *(u_int *)data = ms->scr_ri.ri_stride;
        return 0;
    case WSDISPLAYIO_GET_FBINFO:
        fbi = data;
        return wsdisplayio_get_fbinfo(&ms->scr_ri, fbi);
    case WSDISPLAYIO_SVIDEO:
        val = (*(u_int *)data) != WSDISPLAYIO_VIDEO_OFF;
        sc->sc_backlight = val;
        if (val)
            igmafb_set_brightness(sc, sc->sc_brightness);
        else
            igmafb_set_brightness(sc, 0);
        return 0;
    case WSDISPLAYIO_GETPARAM:
        param = (struct wsdisplay_param *)data;
        switch (param->param) {
        case WSDISPLAYIO_PARAM_BRIGHTNESS:
            param->min = 0;
            param->max = 255;
            if (sc->sc_backlight)
                igmafb_get_brightness(sc, &val);
            else
                val = sc->sc_brightness;
            val = val * 255 / sc->sc_brightness_max;
            param->curval = val;
            return 0;
        case WSDISPLAYIO_PARAM_BACKLIGHT:
            param->min = 0;
            param->max = 1;
            param->curval = sc->sc_backlight;
            return 0;
        }
        return EPASSTHROUGH;
    case WSDISPLAYIO_SETPARAM:
        param = (struct wsdisplay_param *)data;
        switch (param->param) {
        case WSDISPLAYIO_PARAM_BRIGHTNESS:
            val = param->curval;
            if (val < 0)
                val = 0;
            if (val > 255)
                val = 255;
            val = val * sc->sc_brightness_max / 255;
            sc->sc_brightness = val;
            if (sc->sc_backlight)
                igmafb_set_brightness(sc, val);
            return 0;
        case WSDISPLAYIO_PARAM_BACKLIGHT:
            val = param->curval;
            sc->sc_backlight = val;
            if (val)
                igmafb_set_brightness(sc, sc->sc_brightness);
            else
                igmafb_set_brightness(sc, 0);
            return 0;
        }
        return EPASSTHROUGH;
    }

    return EPASSTHROUGH;
}

static paddr_t
igmafb_mmap(void *v, void *vs, off_t offset, int prot)
{
    struct vcons_data *vd = v;
    struct igmafb_softc *sc = vd->cookie;

    if ((offset & PAGE_MASK) != 0)
        return -1;

    if (offset < 0 || offset >= sc->sc_fbsize)
        return -1;

    return bus_space_mmap(sc->sc_chip.gmt, sc->sc_chip.gmb, offset, prot,
                          BUS_SPACE_MAP_LINEAR);
}

static void
igmafb_pollc(void *v, int on)
{
    struct vcons_data *vd = v;
    struct igmafb_softc *sc = vd->cookie;

    if (sc == NULL)
        return;
    if (sc->sc_console_screen.scr_vd == NULL)
        return;

    if (on)
        vcons_enable_polling(&sc->vd);
    else
        vcons_disable_polling(&sc->vd);
}

static void
igmafb_init_screen(void *cookie, struct vcons_screen *scr,
                   int existing, long *defattr)
{
    struct igmafb_softc *sc = cookie;
    struct rasops_info *ri = &scr->scr_ri;

    memset(ri, 0, sizeof(struct rasops_info));

    ri->ri_depth = sc->sc_depth;
    ri->ri_width = sc->sc_width;
    ri->ri_height = sc->sc_height;
    ri->ri_stride = sc->sc_stride;
    ri->ri_flg = RI_CENTER | RI_FULLCLEAR;

    ri->ri_bits = (char *)sc->sc_fbaddr;

    if (existing) {
        ri->ri_flg |= RI_CLEAR;
    }

    switch (sc->sc_depth) {
    case 32:
        ri->ri_rnum = 8;
        ri->ri_gnum = 8;
        ri->ri_bnum = 8;
        ri->ri_rpos = 16;
        ri->ri_gpos = 8;
        ri->ri_bpos = 0;
        break;
    }

    rasops_init(ri, 0, 0);
    ri->ri_caps = WSSCREEN_WSCOLORS;

    rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
                    sc->sc_width / ri->ri_font->fontwidth);

    ri->ri_hw = scr;
}

static void
igmafb_guess_size(struct igmafb_softc *sc, int *widthp, int *heightp)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    int pipe = cd->use_pipe;
    u_int32_t r;

    r = co->read_reg(cd, PIPE_HTOTAL(pipe));
    *widthp = PIPE_HTOTAL_GET_ACTIVE(r);
    r = co->read_reg(cd, PIPE_VTOTAL(pipe));
    *heightp = PIPE_VTOTAL_GET_ACTIVE(r);

    aprint_normal("%s: vga active size %d x %d\n",
                  device_xname(sc->sc_dev),
                  *widthp, *heightp);

    if (*widthp < 640 || *heightp < 400) {
        r = co->read_reg(cd, PF_WINSZ(pipe));
        *widthp  = PF_WINSZ_GET_WIDTH(r);
        *heightp = PF_WINSZ_GET_HEIGHT(r);

        aprint_normal("%s: window size %d x %d\n",
                      device_xname(sc->sc_dev),
                      *widthp, *heightp);
    }

    if (*widthp  < 640) *widthp  = 640;
    if (*heightp < 400) *heightp = 400;
}

static void
igmafb_set_mode(struct igmafb_softc *sc, bool enable)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    int pipe = cd->use_pipe;
    u_int32_t r;
    u_int8_t b;
    int i;

    if (enable) {
        /* disable VGA machinery */
        b = co->read_vga(cd, 0x01);
        co->write_vga(cd, 0x01, b | 0x20);

        /* disable VGA compatible display */
        r = co->read_reg(cd, sc->sc_chip.vga_cntrl);
        co->write_reg(cd, sc->sc_chip.vga_cntrl, r | VGA_CNTRL_DISABLE);

        /* save VGA memory */
        memcpy(sc->sc_vga_save, sc->sc_fbaddr, 256*1024);

        /* configure panel fitter */
        co->write_reg(cd, PF_WINPOS(pipe),
                      PF_WINPOS_VAL(0, 0));
        co->write_reg(cd, PF_WINSZ(pipe),
                      PF_WINSZ_VAL(sc->sc_width, sc->sc_height));

        /* pipe size */
        co->write_reg(cd, PIPE_SRCSZ(pipe),
                      PIPE_SRCSZ_VAL(sc->sc_width, sc->sc_height));

        /* enable pipe */
        co->write_reg(cd, PIPE_CONF(pipe),
                      PIPE_CONF_ENABLE | PIPE_CONF_8BPP);

        /* configure planes */
        r = co->read_reg(cd, PRI_CTRL(pipe));
        r &= ~(PRI_CTRL_PIXFMTMSK | PRI_CTRL_TILED);
        r |= PRI_CTRL_ENABLE | PRI_CTRL_BGR;
        co->write_reg(cd, PRI_CTRL(pipe), r | cd->pri_cntrl);
        co->write_reg(cd, PRI_LINOFF(pipe), 0);
        co->write_reg(cd, PRI_STRIDE(pipe), sc->sc_stride);
        co->write_reg(cd, PRI_SURF(pipe), 0);
        co->write_reg(cd, PRI_TILEOFF(pipe), 0);

        if (cd->quirks & IGMA_PLANESTART_QUIRK)
            igmafb_planestart_quirk(sc);

        if (cd->quirks & IGMA_PFITDISABLE_QUIRK)
            igmafb_pfitdisable_quirk(sc);
    } else {
        /* disable planes */
        co->write_reg(cd, PRI_CTRL(pipe), 0 | cd->pri_cntrl);
        co->write_reg(cd, PRI_LINOFF(pipe), 0);
        co->write_reg(cd, PRI_STRIDE(pipe), 2560);
        co->write_reg(cd, PRI_SURF(pipe), 0);
        co->write_reg(cd, PRI_TILEOFF(pipe), 0);

        /* pipe size */
        co->write_reg(cd, PIPE_SRCSZ(pipe),
                      PIPE_SRCSZ_VAL(720,400));

        /* disable pipe */
        co->write_reg(cd, PIPE_CONF(pipe), 0);
        for (i=0; i<10; ++i) {
            delay(10);
            if ((co->read_reg(cd, PIPE_CONF(pipe)) & PIPE_CONF_STATE) == 0)
                break;
        }

        /* workaround before enabling VGA */
        r = co->read_reg(cd, 0x42000);
        co->write_reg(cd, 0x42000, (r & 0x1fffffff) | 0xa0000000);
        r = co->read_reg(cd, 0x42004);
        co->write_reg(cd, 0x42004, (r & 0xfbffffff) | 0x00000000);

        /* configure panel fitter */
        co->write_reg(cd, PF_WINPOS(pipe),
                      PF_WINPOS_VAL(0, 0));
        co->write_reg(cd, PF_WINSZ(pipe),
                      PF_WINSZ_VAL(sc->sc_width, sc->sc_height));

        /* enable VGA compatible display */
        r = co->read_reg(cd, sc->sc_chip.vga_cntrl);
        co->write_reg(cd, sc->sc_chip.vga_cntrl, r & ~VGA_CNTRL_DISABLE);

        /* enable VGA machinery */
        b = co->read_vga(cd, 0x01);
        co->write_vga(cd, 0x01, b & ~0x20);

        /* restore VGA memory */
        memcpy(sc->sc_fbaddr, sc->sc_vga_save, 256*1024);

        /* enable pipe again */
        co->write_reg(cd, PIPE_CONF(pipe),
                      PIPE_CONF_ENABLE | PIPE_CONF_6BPP | PIPE_CONF_DITHER);
    }
}

static void
igmafb_planestart_quirk(struct igmafb_softc *sc)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    int pipe = cd->use_pipe;
    u_int32_t cntrl, fwbcl;

    /* disable self refresh */
    fwbcl = co->read_reg(cd, FW_BLC_SELF);
    co->write_reg(cd, FW_BLC_SELF, fwbcl & ~FW_BLC_SELF_EN);

    cntrl = co->read_reg(cd, CUR_CNTR(pipe));
    co->write_reg(cd, CUR_CNTR(pipe), 1<<5 | 0x07);

    /* "wait for vblank" */
    delay(40000);

    co->write_reg(cd, CUR_CNTR(pipe), cntrl);
    co->write_reg(cd, CUR_BASE(pipe),
                  co->read_reg(cd, CUR_BASE(pipe)));

    co->write_reg(cd, FW_BLC_SELF, fwbcl);
}

static void
igmafb_pfitdisable_quirk(struct igmafb_softc *sc)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r;

    /* disable i965 panel fitter */
    r = co->read_reg(cd, PF_CTRL_I965);
    co->write_reg(cd, PF_CTRL_I965, r & ~PF_ENABLE);
}

static void
igmafb_get_brightness_max(struct igmafb_softc *sc, int *valp)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r, f;

    r = co->read_reg(cd, cd->backlight_cntrl);
    f = BACKLIGHT_GET_FREQ(r);
    if (f == 0) {
        r = co->read_reg(cd, RAWCLK_FREQ);
        f = r * 1000000 / (200 * 128);
        if (f == 0 || f > 32767)
            f = 125 * 100000 / (200 * 128);
    }

    *valp = f;
}

static void
igmafb_get_brightness(struct igmafb_softc *sc, int *valp)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r, v;

    r = co->read_reg(cd, cd->backlight_cntrl);
    v = BACKLIGHT_GET_CYCLE(r);
    *valp = v;
}

static void
igmafb_set_brightness(struct igmafb_softc *sc, int val)
{
    const struct igma_chip *cd = &sc->sc_chip;
    const struct igma_chip_ops *co = cd->ops;
    u_int32_t r, f, l;

    r = co->read_reg(cd, cd->backlight_cntrl);
    f = BACKLIGHT_GET_FREQ(r);
    l = BACKLIGHT_GET_LEGACY(r);

    co->write_reg(cd, cd->backlight_cntrl,
                  BACKLIGHT_VAL(f,l,val));
}
Example #9
0
/*
 * Attach a display.  We need to notice if it is the console, too.
 */
static void
p9100_sbus_attach(struct device *parent, struct device *self, void *args)
{
	struct p9100_softc *sc = device_private(self);
	struct sbus_attach_args *sa = args;
	struct fbdevice *fb = &sc->sc_fb;
	int isconsole;
	int node;
	int i, j;
	uint8_t ver;

#if NWSDISPLAY > 0
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri;
	unsigned long defattr;
#endif

	sc->sc_last_offset = 0xffffffff;

	/* Remember cookies for p9100_mmap() */
	sc->sc_bustag = sa->sa_bustag;
	sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag,
		sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base);
	sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/

	sc->sc_cmd_paddr = sbus_bus_addr(sa->sa_bustag,
		sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base);
	sc->sc_cmd_psize = (bus_size_t)sa->sa_reg[1].oa_size;

	sc->sc_fb_paddr = sbus_bus_addr(sa->sa_bustag,
		sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base);
	sc->sc_fb_psize = (bus_size_t)sa->sa_reg[2].oa_size;

	fb->fb_driver = &p9100fbdriver;
	fb->fb_device = &sc->sc_dev;
	fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK;
#ifdef PNOZZ_EMUL_CG3
	fb->fb_type.fb_type = FBTYPE_SUN3COLOR;
#else
	fb->fb_type.fb_type = FBTYPE_P9100;
#endif
	fb->fb_pixels = NULL;

	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;

	node = sa->sa_node;
	isconsole = fb_is_console(node);
	if (!isconsole) {
		aprint_normal("\n");
		aprint_error_dev(self, "fatal error: PROM didn't configure device\n");
		return;
	}

	/*
	 * When the ROM has mapped in a p9100 display, the address
	 * maps only the video RAM, so in any case we have to map the
	 * registers ourselves.  We only need the video RAM if we are
	 * going to print characters via rconsole.
	 */
	if (sbus_bus_map(sc->sc_bustag,
			 sa->sa_reg[0].oa_space,
			 sa->sa_reg[0].oa_base,
			 /*
			  * XXX for some reason the SBus resources don't cover
			  * all registers, so we just map what we need
			  */
			 /*sc->sc_ctl_psize*/ 0x8000,
			 /*BUS_SPACE_MAP_LINEAR*/0, &sc->sc_ctl_memh) != 0) {
		aprint_error_dev(self, "cannot map control registers\n");
		return;
	}

	if (sa->sa_npromvaddrs != 0)
		fb->fb_pixels = (void *)sa->sa_promvaddrs[0];

	if (fb->fb_pixels == NULL) {
		if (sbus_bus_map(sc->sc_bustag,
				sa->sa_reg[2].oa_space,
				sa->sa_reg[2].oa_base,
				sc->sc_fb_psize,
				BUS_SPACE_MAP_LINEAR, &sc->sc_fb_memh) != 0) {
			aprint_error_dev(self, "cannot map framebuffer\n");
			return;
		}
		fb->fb_pixels = (char *)sc->sc_fb_memh;
	} else {
		sc->sc_fb_memh = (bus_space_handle_t) fb->fb_pixels;
	}

	i = p9100_ctl_read_4(sc, 0x0004);
	switch ((i >> 26) & 7) {
	    case 5: fb->fb_type.fb_depth = 32; break;
	    case 7: fb->fb_type.fb_depth = 24; break;
	    case 3: fb->fb_type.fb_depth = 16; break;
	    case 2: fb->fb_type.fb_depth = 8; break;
	    default: {
		panic("pnozz: can't determine screen depth (0x%02x)", i);
	    }
	}
	sc->sc_depth = (fb->fb_type.fb_depth >> 3);

	/* XXX for some reason I get a kernel trap with this */
	sc->sc_width = prom_getpropint(node, "width", 800);
	sc->sc_height = prom_getpropint(node, "height", 600);

	sc->sc_stride = prom_getpropint(node, "linebytes", sc->sc_width *
	    (fb->fb_type.fb_depth >> 3));

	/* check the RAMDAC */
	ver = p9100_ramdac_read_ctl(sc, DAC_VERSION);

	p9100_init_engine(sc);

	fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height,
	    node);

	sbus_establish(&sc->sc_sd, &sc->sc_dev);
	bus_intr_establish(sc->sc_bustag, sa->sa_pri, IPL_BIO,
	    p9100_intr, sc);

	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
	printf(": rev %d / %x, %dx%d, depth %d mem %x",
	       (i & 7), ver, fb->fb_type.fb_width, fb->fb_type.fb_height,
	       fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize);

	fb->fb_type.fb_cmsize = prom_getpropint(node, "cmsize", 256);
	if ((1 << fb->fb_type.fb_depth) != fb->fb_type.fb_cmsize)
		printf(", %d entry colormap", fb->fb_type.fb_cmsize);

	/* Initialize the default color map. */
	/*bt_initcmap(&sc->sc_cmap, 256);*/
	j = 0;
	for (i = 0; i < 256; i++) {
		sc->sc_cmap.cm_map[i][0] = rasops_cmap[j];
		j++;
		sc->sc_cmap.cm_map[i][1] = rasops_cmap[j];
		j++;
		sc->sc_cmap.cm_map[i][2] = rasops_cmap[j];
		j++;
	}
	p9100loadcmap(sc, 0, 256);

	/* make sure we are not blanked */
	if (isconsole)
		p9100_set_video(sc, 1);

	if (shutdownhook_establish(p9100_shutdown, sc) == NULL) {
		panic("%s: could not establish shutdown hook",
		      device_xname(&sc->sc_dev));
	}

	if (isconsole) {
		printf(" (console)\n");
#ifdef RASTERCONSOLE
		/*p9100loadcmap(sc, 255, 1);*/
		fbrcons_init(fb);
#endif
	} else
		printf("\n");

#if NWSDISPLAY > 0
	wsfont_init();

	vcons_init(&sc->vd, sc, &p9100_defscreendesc, &p9100_accessops);
	sc->vd.init_screen = p9100_init_screen;

	vcons_init_screen(&sc->vd, &p9100_console_screen, 1, &defattr);
	p9100_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

	sc->sc_bg = (defattr >> 16) & 0xff;
	p9100_clearscreen(sc);

	ri = &p9100_console_screen.scr_ri;

	p9100_defscreendesc.nrows = ri->ri_rows;
	p9100_defscreendesc.ncols = ri->ri_cols;
	p9100_defscreendesc.textops = &ri->ri_ops;
	p9100_defscreendesc.capabilities = ri->ri_caps;

	if(isconsole) {
		wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr);
	}

	aa.console = isconsole;
	aa.scrdata = &p9100_screenlist;
	aa.accessops = &p9100_accessops;
	aa.accesscookie = &sc->vd;

	config_found(self, &aa, wsemuldisplaydevprint);
#endif
	/* cursor sprite handling */
	p9100_init_cursor(sc);

	/* attach the fb */
	fb_attach(fb, isconsole);

	/* register with power management */
	sc->sc_video = 1;
	sc->sc_powerstate = PWR_RESUME;
	powerhook_establish(device_xname(&sc->sc_dev), p9100_power_hook, sc);

#if NTCTRL > 0
	/* register callback for external monitor status change */
	tadpole_register_callback(p9100_set_extvga, sc);
#endif
}
Example #10
0
static void
cg14_setup_wsdisplay(struct cgfourteen_softc *sc, int is_cons)
{
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri;
	long defattr;

 	sc->sc_defaultscreen_descr = (struct wsscreen_descr){
		"default",
		0, 0,
		NULL,
		8, 16,
		WSSCREEN_WSCOLORS | WSSCREEN_HILIT,
		NULL
	};
	sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
	sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
	vcons_init(&sc->sc_vd, sc, &sc->sc_defaultscreen_descr,
	    &cg14_accessops);
	sc->sc_vd.init_screen = cg14_init_screen;

	ri = &sc->sc_console_screen.scr_ri;

	if (is_cons) {
		vcons_init_screen(&sc->sc_vd, &sc->sc_console_screen, 1,
		    &defattr);
		sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;

		sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
		sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
		sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
		sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
		wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
		    defattr);
	} else {
		/*
		 * since we're not the console we can postpone the rest
		 * until someone actually allocates a screen for us
		 */
	}

	cg14_init_cmap(sc);

	aa.console = is_cons;
	aa.scrdata = &sc->sc_screenlist;
	aa.accessops = &cg14_accessops;
	aa.accesscookie = &sc->sc_vd;

	config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
}

static void
cg14_init_cmap(struct cgfourteen_softc *sc)
{
	int i, j = 0;

	for (i = 0; i < 256; i++) {

		sc->sc_cmap.cm_map[i][3] = rasops_cmap[j];
		sc->sc_cmap.cm_map[i][2] = rasops_cmap[j + 1];
		sc->sc_cmap.cm_map[i][1] = rasops_cmap[j + 2];
		j += 3;
	}
	cg14_load_hwcmap(sc, 0, 256);
}

static int
cg14_putcmap(struct cgfourteen_softc *sc, struct wsdisplay_cmap *cm)
{
	u_int index = cm->index;
	u_int count = cm->count;
	int i, error;
	u_char rbuf[256], gbuf[256], bbuf[256];

	if (cm->index >= 256 || cm->count > 256 ||
	    (cm->index + cm->count) > 256)
		return EINVAL;
	error = copyin(cm->red, &rbuf[index], count);
	if (error)
		return error;
	error = copyin(cm->green, &gbuf[index], count);
	if (error)
		return error;
	error = copyin(cm->blue, &bbuf[index], count);
	if (error)
		return error;

	for (i = 0; i < count; i++) {
		sc->sc_cmap.cm_map[index][3] = rbuf[index];
		sc->sc_cmap.cm_map[index][2] = gbuf[index];
		sc->sc_cmap.cm_map[index][1] = bbuf[index];
		
		index++;
	}
	cg14_load_hwcmap(sc, 0, 256);
	return 0;
}