Example #1
0
int
zx_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p)
{
	struct zx_softc *sc = dev;
	struct wsdisplay_fbinfo *wdf;

	/*
	 * Note that, although the emulation (text) mode is running in
	 * a 8-bit plane, we advertize the frame buffer as the full-blown
	 * 32-bit beast it is.
	 */
	switch (cmd) {
	case WSDISPLAYIO_GTYPE:
		*(u_int *)data = WSDISPLAY_TYPE_SUN24;
		break;
	case WSDISPLAYIO_GINFO:
		wdf = (struct wsdisplay_fbinfo *)data;
		wdf->height = sc->sc_sunfb.sf_height;
		wdf->width = sc->sc_sunfb.sf_width;
		wdf->depth = 32;
		wdf->cmsize = 0;
		break;
	case WSDISPLAYIO_GETSUPPORTEDDEPTH:
		*(u_int *)data = WSDISPLAYIO_DEPTH_24_32;
		break;
	case WSDISPLAYIO_LINEBYTES:
		*(u_int *)data = sc->sc_sunfb.sf_linebytes;
		break;

	case WSDISPLAYIO_GETCMAP:
	case WSDISPLAYIO_PUTCMAP:
		break;

	case WSDISPLAYIO_SMODE:
		zx_reset(sc, *(u_int *)data);
		break;

	case WSDISPLAYIO_SVIDEO:
	case WSDISPLAYIO_GVIDEO:
		break;

	default:
		return (-1);
	}

	return (0);
}
Example #2
0
void
zx_attach(struct device *parent, struct device *self, void *args)
{
	struct zx_softc *sc = (struct zx_softc *)self;
	struct sbus_attach_args *sa = args;
	struct rasops_info *ri;
	bus_space_tag_t bt;
	bus_space_handle_t bh;
	int node, isconsole = 0;
	const char *nam;

	bt = sa->sa_bustag;
	ri = &sc->sc_sunfb.sf_ro;
	node = sa->sa_node;

	/*
	 * Map the various parts of the card.
	 */
	sc->sc_bustag = 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_LC_SS0_USR,
	    sizeof(struct zx_command), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf(": couldn't map command registers\n");
		return;
	}
	sc->sc_zc = (struct zx_command *)bus_space_vaddr(bt, bh);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0,
	    sizeof(struct zx_draw), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf(": couldn't map ss0 drawing registers\n");
		return;
	}
	sc->sc_zd_ss0 = (struct zx_draw *)bus_space_vaddr(bt, bh);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1,
	    sizeof(struct zx_draw_ss1), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf(": couldn't map ss1 drawing registers\n");
		return;
	}
	sc->sc_zd_ss1 = (struct zx_draw_ss1 *)bus_space_vaddr(bt, bh);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS,
	    sizeof(struct zx_cross), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf(": couldn't map cross registers\n");
		return;
	}
	sc->sc_zx = (struct zx_cross *)bus_space_vaddr(bt, bh);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR,
	    sizeof(struct zx_cursor), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf(": couldn't map cursor registers\n");
		return;
	}
	sc->sc_zcu = (struct zx_cursor *)bus_space_vaddr(bt, bh);

	nam = getpropstring(node, "model");
	if (*nam == '\0')
		nam = sa->sa_name;
	printf(": %s", nam);

	isconsole = node == fbnode;

	/*
	 * The console is using the 8-bit overlay plane, while the prom
	 * will correctly report 32 bit depth.
	 * The following is an equivalent for
	 *    fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);
	 * forcing the depth value not to be overwritten.
	 * Furthermore, the linebytes value is in fact 8192 bytes.
	 */
	sc->sc_sunfb.sf_depth = 8;
	sc->sc_sunfb.sf_width = getpropint(node, "width", 1152);
	sc->sc_sunfb.sf_height = getpropint(node, "height", 900);
	sc->sc_sunfb.sf_linebytes = 1 << ZX_BWIDTH;
	sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height << ZX_BWIDTH;

	printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0,
	    round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR,
	    0, &bh) != 0) {
		printf("%s: couldn't map video memory\n", self->dv_xname);
		return;
	}
	ri->ri_bits = bus_space_vaddr(bt, bh);
	ri->ri_hw = sc;

	fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);

 	/*
	 * Watch out! rasops_init() invoked via fbwscons_init() did not
	 * compute ri_bits correctly when centering the display, because
	 * it has been tricked with the low depth value.
	 * Recompute now.
 	 */
	ri->ri_emustride = ri->ri_emuwidth * 4;
	ri->ri_delta = ri->ri_stride - ri->ri_emustride;
	ri->ri_pelbytes = 4;
	ri->ri_xscale = ri->ri_font->fontwidth * 4;
	ri->ri_bits = ri->ri_origbits;
	ri->ri_bits += (((ri->ri_width * 4) - ri->ri_emustride) >> 1) & ~3;
	ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
	    ri->ri_stride;
	ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
	    / ri->ri_stride;
	ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
	    % ri->ri_stride) / 4);

	ri->ri_ops.copyrows = zx_copyrows;
	ri->ri_ops.copycols = zx_copycols;
	ri->ri_ops.eraserows = zx_eraserows;
	ri->ri_ops.erasecols = zx_erasecols;
	ri->ri_ops.putchar = zx_putchar;
	ri->ri_do_cursor = zx_do_cursor;

	if (isconsole) {
		/* zx_reset() below will clear screen, so restart at 1st row */
		fbwscons_console_init(&sc->sc_sunfb, 0);
	}

	/* reset cursor & frame buffer controls */
	zx_reset(sc, WSDISPLAYIO_MODE_EMUL);

	/* enable video */
	zx_burner(sc, 1, 0);

	fbwscons_attach(&sc->sc_sunfb, &zx_accessops, isconsole);
}
Example #3
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) {