summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-07-19 09:36:05 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-07-19 09:36:05 +0000
commit1243fe64db4490fee7fbe153ec125430c161907b (patch)
treecbf0e74e1c53b877e7e1627c8d6bbe124697724a /sys
parentaf4b7556bf32794c6c279ec0ab99947cf4d205f9 (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.c108
-rw-r--r--sys/arch/sparc/dev/tctrl.c51
-rw-r--r--sys/arch/sparc/dev/tctrlvar.h3
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);