diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-07-19 09:36:05 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-07-19 09:36:05 +0000 |
commit | 1243fe64db4490fee7fbe153ec125430c161907b (patch) | |
tree | cbf0e74e1c53b877e7e1627c8d6bbe124697724a /sys | |
parent | af4b7556bf32794c6c279ec0ab99947cf4d205f9 (diff) |
On the SPARCbooks, allow tctrl(4) to control the external video output,
acting when the external display status changes, with the help of the
pnozz(4) driver.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc/dev/p9100.c | 108 | ||||
-rw-r--r-- | sys/arch/sparc/dev/tctrl.c | 51 | ||||
-rw-r--r-- | sys/arch/sparc/dev/tctrlvar.h | 3 |
3 files changed, 140 insertions, 22 deletions
diff --git a/sys/arch/sparc/dev/p9100.c b/sys/arch/sparc/dev/p9100.c index 7a8c4548b70..de538f86bc7 100644 --- a/sys/arch/sparc/dev/p9100.c +++ b/sys/arch/sparc/dev/p9100.c @@ -1,4 +1,4 @@ -/* $OpenBSD: p9100.c,v 1.37 2005/07/09 22:22:12 miod Exp $ */ +/* $OpenBSD: p9100.c,v 1.38 2005/07/19 09:36:04 miod Exp $ */ /* * Copyright (c) 2003, 2005, Miodrag Vallat. @@ -61,6 +61,7 @@ #include <sparc/dev/btvar.h> #include <sparc/dev/sbusvar.h> +#include <dev/ic/ibm525reg.h> #include <dev/ic/p9000.h> #include "tctrl.h" @@ -68,19 +69,31 @@ #include <sparc/dev/tctrlvar.h> #endif +/* + * SBus registers mappings + */ +#define P9100_NREG 4 +#define P9100_REG_CTL 0 +#define P9100_REG_CMD 1 +#define P9100_REG_VRAM 2 +#define P9100_REG_CONFIG 3 + /* per-display variables */ struct p9100_softc { - struct sunfb sc_sunfb; /* common base part */ - struct sbusdev sc_sd; /* sbus device */ - struct rom_reg sc_phys; /* phys address description */ + struct sunfb sc_sunfb; /* common base part */ + struct sbusdev sc_sd; /* sbus device */ + struct rom_reg sc_phys; volatile u_int8_t *sc_cmd; /* command registers (dac, etc) */ volatile u_int8_t *sc_ctl; /* control registers (draw engine) */ - union bt_cmap sc_cmap; /* Brooktree color map */ - struct intrhand sc_ih; + union bt_cmap sc_cmap; /* Brooktree color map */ + struct intrhand sc_ih; + int sc_flags; +#define SCF_EXTERNAL 0x01 /* external video enabled */ u_int32_t sc_junk; /* throwaway value */ }; void p9100_burner(void *, u_int, u_int); +void p9100_external_video(void *, int); int p9100_intr(void *); int p9100_ioctl(void *, u_long, caddr_t, int, struct proc *); static __inline__ @@ -89,6 +102,8 @@ void p9100_loadcmap_immediate(struct p9100_softc *, u_int, u_int); paddr_t p9100_mmap(void *, off_t, int); int p9100_pick_romfont(struct p9100_softc *); void p9100_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t); +u_int p9100_read_ramdac(struct p9100_softc *, u_int); +void p9100_write_ramdac(struct p9100_softc *, u_int, u_int); struct wsdisplay_accessops p9100_accessops = { p9100_ioctl, @@ -122,14 +137,6 @@ struct cfdriver pnozz_cd = { }; /* - * SBus registers mappings - */ -#define P9100_NREG 3 -#define P9100_REG_CTL 0 -#define P9100_REG_CMD 1 -#define P9100_REG_VRAM 2 - -/* * IBM RGB525 RAMDAC registers */ @@ -227,18 +234,20 @@ p9100attach(struct device *parent, struct device *self, void *args) int isconsole, fontswitch, clear; #ifdef DIAGNOSTIC - if (ca->ca_ra.ra_nreg < P9100_NREG) { + if (ca->ca_ra.ra_nreg < P9100_NREG - 1) { printf(": expected %d registers, got only %d\n", P9100_NREG, ca->ca_ra.ra_nreg); return; } #endif + sc->sc_flags = 0; + sc->sc_phys = ca->ca_ra.ra_reg[P9100_REG_VRAM]; - sc->sc_ctl = mapiodev(&(ca->ca_ra.ra_reg[P9100_REG_CTL]), 0, + sc->sc_ctl = mapiodev(&ca->ca_ra.ra_reg[P9100_REG_CTL], 0, ca->ca_ra.ra_reg[P9100_REG_CTL].rr_len); - sc->sc_cmd = mapiodev(&(ca->ca_ra.ra_reg[P9100_REG_CMD]), 0, + sc->sc_cmd = mapiodev(&ca->ca_ra.ra_reg[P9100_REG_CMD], 0, ca->ca_ra.ra_reg[P9100_REG_CMD].rr_len); node = ca->ca_ra.ra_node; @@ -266,7 +275,9 @@ p9100attach(struct device *parent, struct device *self, void *args) fb_depth = 8; break; } + fb_setsize(&sc->sc_sunfb, fb_depth, 800, 600, node, ca->ca_bustype); + ri->ri_bits = mapiodev(&sc->sc_phys, 0, round_page(sc->sc_sunfb.sf_fbsize)); ri->ri_hw = sc; @@ -300,6 +311,18 @@ p9100attach(struct device *parent, struct device *self, void *args) * XXX there should be a rasops "clear margins" feature */ fontswitch = p9100_pick_romfont(sc); + + /* + * Register the external video control callback with tctrl; tctrl + * will invoke it immediately to set the appropriate behaviour. + * If tctrl is not configured, simply enable external video. + */ +#if NTCTRL > 0 + tadpole_register_extvideo(p9100_external_video, sc); +#else + p9100_external_video(sc, 1); +#endif + clear = !isconsole || fontswitch; fbwscons_init(&sc->sc_sunfb, clear ? RI_CLEAR : 0); if (!clear) { @@ -435,7 +458,7 @@ p9100_mmap(void *v, off_t offset, int prot) { struct p9100_softc *sc = v; - if (offset & PGOFSET) + if ((offset & PAGE_MASK) != 0) return (-1); if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) { @@ -483,6 +506,31 @@ p9100_loadcmap_deferred(struct p9100_softc *sc, u_int start, u_int ncolors) IER_VBLANK_ENABLE | IER_VBLANK_INTERRUPT); } +u_int +p9100_read_ramdac(struct p9100_softc *sc, u_int reg) +{ + P9100_SELECT_DAC(sc); + + P9100_WRITE_RAMDAC(sc, IBM525_IDXLOW, (reg & 0xff)); + P9100_FLUSH_DAC(sc); + P9100_WRITE_RAMDAC(sc, IBM525_IDXHIGH, ((reg >> 8) & 0xff)); + P9100_FLUSH_DAC(sc); + return (P9100_READ_RAMDAC(sc, IBM525_REGDATA)); +} + +void +p9100_write_ramdac(struct p9100_softc *sc, u_int reg, u_int value) +{ + P9100_SELECT_DAC(sc); + + P9100_WRITE_RAMDAC(sc, IBM525_IDXLOW, (reg & 0xff)); + P9100_FLUSH_DAC(sc); + P9100_WRITE_RAMDAC(sc, IBM525_IDXHIGH, ((reg >> 8) & 0xff)); + P9100_FLUSH_DAC(sc); + P9100_WRITE_RAMDAC(sc, IBM525_REGDATA, value); + P9100_FLUSH_DAC(sc); +} + void p9100_burner(void *v, u_int on, u_int flags) { @@ -835,3 +883,27 @@ p9100_pick_romfont(struct p9100_softc *sc) return (0); } + +/* + * External video control + */ +void +p9100_external_video(void *v, int on) +{ + struct p9100_softc *sc = v; + int s; + + s = splhigh(); + + if (on) { + p9100_write_ramdac(sc, IBM525_POWER, + p9100_read_ramdac(sc, IBM525_POWER) & ~P_DAC_PWR_DISABLE); + sc->sc_flags |= SCF_EXTERNAL; + } else { + p9100_write_ramdac(sc, IBM525_POWER, + p9100_read_ramdac(sc, IBM525_POWER) | P_DAC_PWR_DISABLE); + sc->sc_flags &= ~SCF_EXTERNAL; + } + + splx(s); +} diff --git a/sys/arch/sparc/dev/tctrl.c b/sys/arch/sparc/dev/tctrl.c index 1ba1763f496..aa2594e01b0 100644 --- a/sys/arch/sparc/dev/tctrl.c +++ b/sys/arch/sparc/dev/tctrl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tctrl.c,v 1.15 2005/07/17 12:16:51 miod Exp $ */ +/* $OpenBSD: tctrl.c,v 1.16 2005/07/19 09:36:04 miod Exp $ */ /* $NetBSD: tctrl.c,v 1.2 1999/08/11 00:46:06 matt Exp $ */ /*- @@ -159,6 +159,10 @@ struct tctrl_softc { /* /dev/apm{,ctl} fields */ struct klist sc_note; u_int sc_apmflags; + + /* external video control callback */ + void (*sc_evcb)(void *, int); + void *sc_evdata; }; int tctrl_match(struct device *, void *, void *); @@ -504,6 +508,15 @@ tctrl_read_event_status(void *arg) tctrl_request(sc, &req); v = req.rspbuf[0] * 256 + req.rspbuf[1]; + + /* + * Read the new external status value if necessary + */ + if (v & (TS102_EVENT_STATUS_DC_STATUS_CHANGE | + TS102_EVENT_STATUS_LID_STATUS_CHANGE | + TS102_EVENT_STATUS_EXTERNAL_VGA_STATUS_CHANGE)) + tctrl_read_ext_status(sc); + if (v & TS102_EVENT_STATUS_SHUTDOWN_REQUEST) { printf("%s: SHUTDOWN REQUEST!\n", sc->sc_dev.dv_xname); } @@ -521,7 +534,6 @@ tctrl_read_event_status(void *arg) apm_record_event(sc, APM_BATTERY_LOW); } if (v & TS102_EVENT_STATUS_DC_STATUS_CHANGE) { - tctrl_read_ext_status(sc); if ((sc->sc_apmflags & SCFLAG_NOPRINT) == 0) printf("%s: main power %s\n", sc->sc_dev.dv_xname, (sc->sc_ext_status & TS102_EXT_STATUS_MAIN_POWER_AVAILABLE) ? @@ -534,7 +546,6 @@ tctrl_read_event_status(void *arg) #endif } if (v & TS102_EVENT_STATUS_LID_STATUS_CHANGE) { - tctrl_read_ext_status(sc); /* blank or restore video if necessary */ if (sc->sc_tft_on) tctrl_tft(sc); @@ -544,6 +555,22 @@ tctrl_read_event_status(void *arg) "closed" : "opened"); #endif } + if (v & TS102_EVENT_STATUS_EXTERNAL_VGA_STATUS_CHANGE) { + printf("%s: external vga %s\n", sc->sc_dev.dv_xname, + sc->sc_ext_status & TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED ? + "attached" : "detached"); +#ifdef TCTRLDEBUG + req.cmdbuf[0] = TS102_OP_RD_EXT_VGA_PORT; + req.cmdlen = 1; + req.rsplen = 2; + tctrl_request(sc, &req); + printf("%s: vga status %x\n", sc->sc_dev.dv_xname, + req.rspbuf[0]); +#endif + if (sc->sc_evcb != NULL) + (*sc->sc_evcb)(sc->sc_evdata, sc->sc_ext_status & + TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED); + } } void @@ -828,6 +855,24 @@ tadpole_get_video() } void +tadpole_register_extvideo(void (*cb)(void *, int), void *data) +{ + struct tctrl_softc *sc; + + if (tctrl_cd.cd_devs == NULL + || tctrl_cd.cd_ndevs == 0 + || tctrl_cd.cd_devs[0] == NULL) { + return; + } + + sc = (struct tctrl_softc *)tctrl_cd.cd_devs[0]; + sc->sc_evcb = cb; + sc->sc_evdata = data; + + (*cb)(data, sc->sc_ext_status & TS102_EXT_STATUS_EXTERNAL_VGA_ATTACHED); +} + +void tadpole_set_pcmcia(int slot, int enabled) { struct tctrl_softc *sc; diff --git a/sys/arch/sparc/dev/tctrlvar.h b/sys/arch/sparc/dev/tctrlvar.h index 6a42512d9d8..a07ff1d2ff5 100644 --- a/sys/arch/sparc/dev/tctrlvar.h +++ b/sys/arch/sparc/dev/tctrlvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tctrlvar.h,v 1.5 2005/03/29 12:55:55 miod Exp $ */ +/* $OpenBSD: tctrlvar.h,v 1.6 2005/07/19 09:36:04 miod Exp $ */ /* $NetBSD: tctrlvar.h,v 1.1 1999/08/09 18:39:58 matt Exp $ */ /*- @@ -43,6 +43,7 @@ int tadpole_bell(u_int, u_int, u_int); int tadpole_get_brightness(void); u_int tadpole_get_video(void); void tadpole_powerdown(void); +void tadpole_register_extvideo(void (*)(void *, int), void *); void tadpole_set_brightness(int); void tadpole_set_pcmcia(int, int); void tadpole_set_video(int); |