summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/man/man4/man4.sparc/pnozz.413
-rw-r--r--sys/arch/sparc/dev/p9100.c108
-rw-r--r--sys/arch/sparc/dev/tctrl.c51
-rw-r--r--sys/arch/sparc/dev/tctrlvar.h3
4 files changed, 148 insertions, 27 deletions
diff --git a/share/man/man4/man4.sparc/pnozz.4 b/share/man/man4/man4.sparc/pnozz.4
index 31e7057736a..cd3e3fa9566 100644
--- a/share/man/man4/man4.sparc/pnozz.4
+++ b/share/man/man4/man4.sparc/pnozz.4
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pnozz.4,v 1.22 2004/09/30 19:59:27 mickey Exp $
+.\" $OpenBSD: pnozz.4,v 1.23 2005/07/19 09:36:02 miod Exp $
.\"
.\" Copyright (c) 1999 Jason L. Wright (jason@thought.net)
.\" All rights reserved.
@@ -24,7 +24,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 16, 2003
+.Dd July 19, 2005
.Dt PNOZZ 4 sparc
.Os
.Sh NAME
@@ -62,6 +62,11 @@ device is also configured, the
.Nm
will be powered down when the lid of the laptop
is closed or the screen is blanked.
+.Sh EXTERNAL VIDEO
+If the
+.Xr tctrl 4
+device is also configured, the external video output will be enabled when
+an external display is connected, even if the laptop lid is closed.
.Sh SEE ALSO
.Xr agten 4 ,
.Xr bwtwo 4 ,
@@ -85,6 +90,4 @@ is closed or the screen is blanked.
.Xr wsdisplay 4 ,
.Xr zx 4
.Sh BUGS
-There is currently no way to switch back and forth from
-the onboard display to the external connector.
-It is not possible to change resolutions or color depth.
+It is not possible yet to change resolutions or color depth.
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);