File: [local] / sys / arch / jornada / dev / jfb.c (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:09:01 2008 UTC (16 years, 4 months ago) by nbrk
Branch: OPENBSD_4_2_BASE
CVS Tags: jornada-partial-support-wip Changes since 1.1: +0 -0 lines
Import of OpenBSD 4.2 release kernel tree with initial code to support
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO
Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)
|
/* $Id: jfb.c,v 1.1.1.1 2008/03/04 16:09:01 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;
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);
/* 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;
}