[BACK]Return to jfb.c CVS log [TXT][DIR] Up to [local] / sys / arch / jornada / dev

File: [local] / sys / arch / jornada / dev / jfb.c (download)

Revision 1.2, Sun May 11 09:26:11 2008 UTC (16 years ago) by nbrk
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +7 -3 lines

Sync up my latest modifications related to OpenBSD/jornada.
At this point PCMCIA is not done (this is primary goal since it's only
expansion bus for SA-1110) but some other chip subsystems rather work.
One of most recent problems sit in ported NetBSD pcic driver. It cause memory
abort passing odd addr to bus_space_write_2 (APB transactions are word-wide,
but I try to emulate 2-bytes accesses in bus_space_map for sa1111).
Other problematic/untested areas: sacic, saic. UART driver is a stub and not
really useful.
But even with this problems I have overdone my plans with this porting effort.

/*	$Id: jfb.c,v 1.2 2008/05/11 09:26:11 nbrk Exp $	*/
/*
 * Jornada framebuffer.
 * 640x240 @16bpp
 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/conf.h>

#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wsfont/vt220l8x10.h>

#include <machine/bus.h>

#include <arm/sa11x0/sa11x0_reg.h>
#include <arm/sa11x0/sa11x0_var.h>
#include <jornada/dev/jfbreg.h>

#include "wsdisplay.h"

#define JFB_DFLTWIDTH	640
#define JFB_DFLTHEIGHT	240
#define JFB_DFLTBPP		16

struct jfb_softc {
	struct device	sc_dev;
	bus_space_tag_t	sc_bust;
	bus_space_handle_t	sc_bush;
	uint8_t	*sc_bits;

	int	sc_width;
	int	sc_height;
	int	sc_depth;
	int	sc_linebytes;

	int sc_rows;
	int sc_cols;

	struct rasops_info	sc_ri;
	long sc_defattr;	/* XXX kill me */

	struct	wsscreen_descr sc_wsd;
	struct	wsscreen_list sc_wsl;
	struct	wsscreen_descr *sc_scrlist[1];
};

int	jfb_match(struct device *parent, void *cf, void *aux);
void	jfb_attach(struct device *parent, struct device *self, void *aux);
void	jfbfakecnattach(bus_addr_t addr);
void	jfb_rasopsinit(struct jfb_softc *sc);
void	jfb_setcmap(struct rasops_info *ri);

struct	jfb_softc jfb_sc;
int	jfb_initted = 0;

/* autoconf stuff */
struct cfattach	jfb_ca = {
	sizeof(struct jfb_softc), jfb_match, jfb_attach, NULL, NULL
};

struct cfdriver jfb_cd = {
	NULL, "jfb", DV_DULL
};


int
jfb_match(struct device *parent, void *cf, void *aux)
{
	return(1);
}

void
jfb_attach(struct device *parent, struct device *self, void *aux)
{
	struct jfb_softc *sc = (void *)self;
	struct saip_attach_args *saa = aux;
	struct wsemuldisplaydev_attach_args waa;

	sc->sc_bust = saa->sai_iot;

	/* use bootstrap softc if it is already configured */
//	if (jfb_initted)
//		*sc = jfb_sc;

	if (bus_space_map(sc->sc_bust, saa->sai_addr, JFB_SIZE , BUS_SPACE_MAP_LINEAR, &sc->sc_bush)) {
		printf(": can't map i/o space\n");
		return;
	}

	sc->sc_bits = (uint8_t *)sc->sc_bush;

	/* TODO use flags for mode selection */
	sc->sc_width = JFB_DFLTWIDTH;
	sc->sc_height = JFB_DFLTHEIGHT;
	sc->sc_depth = JFB_DFLTBPP;
	sc->sc_linebytes = sc->sc_width * (sc->sc_depth / 8);

	sc->sc_cols = 80;
	sc->sc_rows = 24;

	jfb_rasopsinit(sc);

	printf(": Jornada framebuffer (%dx%d @%dbpp)\n", sc->sc_width, sc->sc_height, sc->sc_depth);

	sc->sc_scrlist[0] = &sc->sc_wsd;
	sc->sc_wsl.nscreens = 1;
	sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist;

	waa.scrdata = &sc->sc_wsl;
	waa.accesscookie = sc;
	waa.defaultscreens = 0;

//	config_found((struct device *)sc, &waa, wsemuldisplaydevprint);

	return;
}

void
jfbfakecnattach(bus_addr_t addr)
{
	struct jfb_softc	*sc = &jfb_sc;

	sc->sc_bits = (uint8_t *)addr;

	if (jfb_initted == 0) {
		/*
		 * First attachment.
		 * Initialize with defaults.
		 */

		/* clear the screen */
		sc->sc_ri.ri_flg = RI_CLEAR | RI_FULLCLEAR;

		sc->sc_width = JFB_DFLTWIDTH;
		sc->sc_height = JFB_DFLTHEIGHT;
		sc->sc_depth = JFB_DFLTBPP;
		sc->sc_linebytes = sc->sc_width * (sc->sc_depth / 8);

		sc->sc_cols = 80;
		sc->sc_rows = 24;

		/* set up rasops */
		jfb_rasopsinit(sc);

		jfb_initted = 1;

		wsdisplay_cnattach(&sc->sc_wsd, &sc->sc_ri, 0, 0, 0);
	} else {
		/*
		 * Already attached.
		 * Tweak some settings and reconfigure rasops.
		 */

		/* reset ri_bits */
		sc->sc_ri.ri_flg &= ~RI_CFGDONE;
		sc->sc_ri.ri_bits = sc->sc_bits;
		/* do not clear the screen */
		sc->sc_ri.ri_flg &= ~RI_CLEAR;

		rasops_reconfig(&sc->sc_ri, 160, 160);
	}
}

void
jfb_rasopsinit(struct jfb_softc *sc)
{
	struct rasops_info	*ri = &sc->sc_ri;
	struct wsscreen_descr	*wsd = &sc->sc_wsd;
	extern struct wsdisplay_font	vt220l8x10;

	ri->ri_hw = sc;
	ri->ri_bits = sc->sc_bits;

	/* claim minimal colour capabilities */
	ri->ri_caps = WSSCREEN_WSCOLORS;

	ri->ri_depth = sc->sc_depth;
	ri->ri_width = sc->sc_width;
	ri->ri_height = sc->sc_height;
	ri->ri_stride = sc->sc_linebytes;

	/* FIXME: see how colors are packed in 16bits/pixel ? */
	ri->ri_rnum = 5;
	ri->ri_gnum = 6;
	ri->ri_bnum = 5;
	ri->ri_rpos = 11;
	ri->ri_gpos = 5;
	ri->ri_bpos = 0;
	
	ri->ri_font = &vt220l8x10;

	/* XXX XXX please tell me why? */
	/* rasops_init(ri, sc->sc_cols, sc->sc_rows); */
	rasops_init(ri, 160, 160);

	/* tune colours */
	jfb_setcmap(ri);

	/* XXX XXX XXX */
	ri->ri_ops.alloc_attr(ri,
		    WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, &sc->sc_defattr);
/* initialize wsscreen_descr */
	strlcpy(wsd->name, "std", sizeof(wsd->name));
	wsd->ncols = sc->sc_cols;
	wsd->nrows = sc->sc_rows;
	wsd->capabilities = ri->ri_caps;
	wsd->textops = &ri->ri_ops;
}

void
jfb_setcmap(struct rasops_info *ri)
{
	/* more intensive white */
	ri->ri_devcmap[WSCOL_WHITE] = 0xffff;
}