diff options
Diffstat (limited to 'sys/arch/sparc/dev')
-rw-r--r-- | sys/arch/sparc/dev/tvtwo.c | 119 |
1 files changed, 83 insertions, 36 deletions
diff --git a/sys/arch/sparc/dev/tvtwo.c b/sys/arch/sparc/dev/tvtwo.c index 1b9b628507a..a46eb9c44cb 100644 --- a/sys/arch/sparc/dev/tvtwo.c +++ b/sys/arch/sparc/dev/tvtwo.c @@ -1,6 +1,6 @@ -/* $OpenBSD: tvtwo.c,v 1.9 2006/02/12 00:04:21 miod Exp $ */ +/* $OpenBSD: tvtwo.c,v 1.10 2006/02/12 12:02:29 miod Exp $ */ /* - * Copyright (c) 2003, Miodrag Vallat. + * Copyright (c) 2003, 2006, Miodrag Vallat. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,8 +39,8 @@ */ /* - * Currently, this driver can only handle the 24-bit plane of the frame - * buffer, in an unaccelerated mode. + * Currently, this driver can only handle the 8-bit and 24-bit planes of the + * frame buffer, in an unaccelerated mode. * * TODO: * - nvram handling @@ -90,13 +90,10 @@ * We currently refuse to attach to the old version because mapping * things requires us to play with the sbus register ranges, and I * don't want to play this game without the hardware at hand -- miod - * - * At PROM initialization, the board will be in 24-bit mode, - * so no specific initialization is necessary. */ #define PX_PROM0_OFFSET 0x000000 -#define PX_OVERAY_OFFSET 0x010000 +#define PX_OVERLAY_OFFSET 0x010000 #define PX_REG_OFFSET 0x040000 #define PX_CCUBE_OFFSET 0x050000 #define PX_PLANE8_OFFSET 0x080000 @@ -125,6 +122,8 @@ struct tvtwo_softc { struct sbusdev sc_sd; /* sbus device */ struct rom_reg sc_phys; + volatile u_int8_t *sc_m8; + volatile u_int8_t *sc_m24; volatile u_int8_t *sc_regs; }; @@ -132,10 +131,6 @@ int tvtwo_ioctl(void *, u_long, caddr_t, int, struct proc *); paddr_t tvtwo_mmap(void *, off_t, int); void tvtwo_burner(void *, u_int, u_int); -static __inline__ void tvtwo_ramdac_wraddr(struct tvtwo_softc *sc, - u_int32_t addr); -void tvtwo_initcmap(struct tvtwo_softc *); - struct wsdisplay_accessops tvtwo_accessops = { tvtwo_ioctl, tvtwo_mmap, @@ -149,6 +144,12 @@ struct wsdisplay_accessops tvtwo_accessops = { NULL /* pollc */ }; +void tvtwo_directcmap(struct tvtwo_softc *); +static __inline__ +void tvtwo_ramdac_wraddr(struct tvtwo_softc *, u_int32_t); +void tvtwo_reset(struct tvtwo_softc *, u_int); +void tvtwo_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t); + int tvtwomatch(struct device *, void *, void *); void tvtwoattach(struct device *, struct device *, void *); @@ -227,27 +228,36 @@ tvtwoattach(struct device *parent, struct device *self, void *args) width = getpropint(node, "hres", width); height = getpropint(node, "vres", height); - fb_setsize(&sc->sc_sunfb, 32, width, height, node, ca->ca_bustype); + + /* + * Since the depth property is usually missing, we could do + * fb_setsize(&sc->sc_sunfb, 8, width, height, node, ca->ca_bustype); + * but for safety in case it would exist and be set to 32, do it + * manually... + */ + sc->sc_sunfb.sf_depth = 8; + sc->sc_sunfb.sf_width = width; + sc->sc_sunfb.sf_height = height; + sc->sc_sunfb.sf_linebytes = width; + sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_linebytes * height; /* Map the frame buffer memory area we're interested in. */ sc->sc_phys = ca->ca_ra.ra_reg[0]; - sc->sc_sunfb.sf_ro.ri_bits = mapiodev(ca->ca_ra.ra_reg, - PX_PLANE24_OFFSET, round_page(sc->sc_sunfb.sf_fbsize)); + sc->sc_m8 = mapiodev(ca->ca_ra.ra_reg, + PX_PLANE8_OFFSET, round_page(sc->sc_sunfb.sf_fbsize)); + sc->sc_m24 = mapiodev(ca->ca_ra.ra_reg, + PX_PLANE24_OFFSET, round_page(4 * sc->sc_sunfb.sf_fbsize)); - /* Initialize a direct color map. */ - tvtwo_initcmap(sc); - - /* - * Clear display. We can't pass RI_CLEAR to fbwscons_init - * below and have rasops do it for us as we want a white background. - */ - memset(sc->sc_sunfb.sf_ro.ri_bits, 0xff, sc->sc_sunfb.sf_fbsize); + /* Enable video. */ + tvtwo_burner(sc, 1, 0); sc->sc_sunfb.sf_ro.ri_hw = sc; - fbwscons_init(&sc->sc_sunfb, 0); + sc->sc_sunfb.sf_ro.ri_bits = (u_char *)sc->sc_m8; + fbwscons_init(&sc->sc_sunfb, isconsole ? RI_CLEARMARGINS : RI_CLEAR); + fbwscons_setcolormap(&sc->sc_sunfb, tvtwo_setcolor); if (isconsole) { - fbwscons_console_init(&sc->sc_sunfb, 0); + fbwscons_console_init(&sc->sc_sunfb, -1); } sbus_establish(&sc->sc_sd, &sc->sc_sunfb.sf_dev); @@ -264,6 +274,10 @@ tvtwo_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p) struct tvtwo_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 32-bit. + */ switch (cmd) { case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_SUN24; @@ -272,17 +286,27 @@ tvtwo_ioctl(void *dev, u_long cmd, caddr_t data, int flags, struct proc *p) wdf = (struct wsdisplay_fbinfo *)data; wdf->height = sc->sc_sunfb.sf_height; wdf->width = sc->sc_sunfb.sf_width; - wdf->depth = sc->sc_sunfb.sf_depth; + wdf->depth = 32; wdf->cmsize = 0; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = sc->sc_sunfb.sf_linebytes; + *(u_int *)data = sc->sc_sunfb.sf_linebytes * 4; break; case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_PUTCMAP: break; + case WSDISPLAYIO_SMODE: + if (*(int *)data == WSDISPLAYIO_MODE_EMUL) { + /* Back from X11 to text mode */ + tvtwo_reset(sc, 8); + } else { + /* Starting X11, initialize 32-bit mode */ + tvtwo_reset(sc, 32); + } + break; + case WSDISPLAYIO_SVIDEO: case WSDISPLAYIO_GVIDEO: break; @@ -308,7 +332,7 @@ tvtwo_mmap(void *v, off_t offset, int prot) return (-1); /* Allow mapping as a dumb framebuffer from offset 0 */ - if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) { + if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize * 4) { return (REG2PHYS(&sc->sc_phys, PX_PLANE24_OFFSET + offset) | PMAP_NC); } @@ -316,6 +340,30 @@ tvtwo_mmap(void *v, off_t offset, int prot) return (-1); } +void +tvtwo_burner(void *v, u_int on, u_int flags) +{ + struct tvtwo_softc *sc = v; + volatile u_int32_t *dispkludge = + (u_int32_t *)(sc->sc_regs + PX_REG_DISPKLUDGE); + + if (on) + *dispkludge = DISPKLUDGE_DEFAULT & ~DISPKLUDGE_BLANK; + else + *dispkludge = DISPKLUDGE_DEFAULT | DISPKLUDGE_BLANK; +} + +void +tvtwo_reset(struct tvtwo_softc *sc, u_int depth) +{ + if (depth == 32) { + /* Initialize a direct color map. */ + tvtwo_directcmap(sc); + } else { + fbwscons_setcolormap(&sc->sc_sunfb, tvtwo_setcolor); + } +} + /* * Simple Bt463 programming routines. */ @@ -330,7 +378,7 @@ tvtwo_ramdac_wraddr(struct tvtwo_softc *sc, u_int32_t addr) } void -tvtwo_initcmap(struct tvtwo_softc *sc) +tvtwo_directcmap(struct tvtwo_softc *sc) { volatile u_int32_t *dac = (u_int32_t *)(sc->sc_regs + PX_REG_BT463_RED); u_int32_t c; @@ -344,14 +392,13 @@ tvtwo_initcmap(struct tvtwo_softc *sc) } void -tvtwo_burner(void *v, u_int on, u_int flags) +tvtwo_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b) { struct tvtwo_softc *sc = v; - volatile u_int32_t *dispkludge = - (u_int32_t *)(sc->sc_regs + PX_REG_DISPKLUDGE); + volatile u_int32_t *dac = (u_int32_t *)(sc->sc_regs + PX_REG_BT463_RED); - if (on) - *dispkludge = DISPKLUDGE_DEFAULT & ~DISPKLUDGE_BLANK; - else - *dispkludge = DISPKLUDGE_DEFAULT | DISPKLUDGE_BLANK; + tvtwo_ramdac_wraddr(sc, index); + dac[3] = r; + dac[3] = g; + dac[3] = b; } |