- Make VDAC state per-board.

- Add an ioctl to reset the STIC.
- Add an ioctl to restore the screen contents from backing.
- Other tweaks.
This commit is contained in:
ad 2001-01-09 16:04:03 +00:00
parent b115d1fc2e
commit 1b4eef2721
3 changed files with 167 additions and 284 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: pxg.c,v 1.2 2000/12/22 13:30:32 ad Exp $ */ /* $NetBSD: pxg.c,v 1.3 2001/01/09 16:04:03 ad Exp $ */
/*- /*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
@ -73,7 +73,7 @@
#define PXG_STIC_POLL_OFFSET 0x000000 /* STIC DMA poll space */ #define PXG_STIC_POLL_OFFSET 0x000000 /* STIC DMA poll space */
#define PXG_STAMP_OFFSET 0x0c0000 /* pixelstamp space on STIC */ #define PXG_STAMP_OFFSET 0x0c0000 /* pixelstamp space on STIC */
#define PXG_STIC_OFFSET 0x180000 /* STIC registers */ #define PXG_STIC_OFFSET 0x180000 /* STIC registers */
#define PXG_SRAM_OFFSET 0x200000 /* i860 SRAM */ #define PXG_SRAM_OFFSET 0x200000 /* 128 or 256kB of SRAM */
#define PXG_HOST_INTR_OFFSET 0x280000 /* i860 host interrupt */ #define PXG_HOST_INTR_OFFSET 0x280000 /* i860 host interrupt */
#define PXG_COPROC_INTR_OFFSET 0x2c0000 /* i860 coprocessor interrupt */ #define PXG_COPROC_INTR_OFFSET 0x2c0000 /* i860 coprocessor interrupt */
#define PXG_VDAC_OFFSET 0x300000 /* VDAC registers (bt459) */ #define PXG_VDAC_OFFSET 0x300000 /* VDAC registers (bt459) */
@ -216,15 +216,6 @@ pxg_init(struct stic_info *si)
else else
si->si_depth = pxg_probe_planes(si); si->si_depth = pxg_probe_planes(si);
#ifdef notdef
/* Restart the co-processor and enable STIC interrupts */
slot[PXG_I860_START_OFFSET >> 2] = 1;
tc_syncbus();
DELAY(2000);
sr->sr_sticsr = STIC_INT_WE | STIC_INT_CLR;
tc_wmb();
#endif
stic_init(si); stic_init(si);
} }
@ -295,12 +286,8 @@ pxg_intr(void *cookie)
tc_wmb(); tc_wmb();
/* /*
* Since we disable the co-processor, we won't get to see vblank * On the PXG, STIC interrupts are posted to the co-processor.
* interrupts (so in effect, this code is useless). * Since we don't yet run it, this code is useless.
*
* Packet-done and error interrupts will only ever be seen by the
* co-processor (although ULTRIX seems to think that they're posted
* to us - more investigation required).
*/ */
if (it == 3) { if (it == 3) {
sr->sr_ipdvint = sr->sr_ipdvint =
@ -315,50 +302,12 @@ pxg_intr(void *cookie)
static u_int32_t * static u_int32_t *
pxg_pbuf_get(struct stic_info *si) pxg_pbuf_get(struct stic_info *si)
{ {
#ifdef notdef
volatile u_int32_t *poll;
/* Ask i860 which buffer to use */
poll = si->si_slotkva;
poll += PXG_COPROC_INTR_OFFSET >> 2;
/*
* XXX These should be defined as constants. 0x30 is "pause
* coprocessor and interrupt."
*/
*poll = 0x30;
tc_wmb();
for (i = 1000000; i; i--) {
DELAY(4);
switch(j = *poll) {
case 2:
si->si_pbuf_select = STIC_PACKET_SIZE;
break;
case 1:
si->si_pbuf_select = 0;
break;
default:
if (j == 0x30)
continue;
break;
}
break;
}
if (j != 1 || j != 2) {
/* STIC has lost the plot, punish it */
stic_reset(si);
si->si_pbuf_select = 0;
}
#else
/* /*
* XXX We should be synchronizing with STIC_INT_P so that an ISR * XXX We should be synchronizing with STIC_INT_P so that an ISR
* doesn't blow us up. * doesn't blow us up.
*/ */
si->si_pbuf_select ^= STIC_PACKET_SIZE; si->si_pbuf_select ^= STIC_PACKET_SIZE;
#endif
return ((u_int32_t *)((caddr_t)si->si_buf + si->si_pbuf_select)); return ((u_int32_t *)((caddr_t)si->si_buf + si->si_pbuf_select));
} }
@ -381,18 +330,8 @@ pxg_pbuf_post(struct stic_info *si, u_int32_t *buf)
tc_syncbus(); tc_syncbus();
for (c = STAMP_RETRIES; c != 0; c--) { for (c = STAMP_RETRIES; c != 0; c--) {
if (*poll == STAMP_OK) { if (*poll == STAMP_OK)
#ifdef notdef return (0);
/* Tell the co-processor that we are done. */
poll = si->si_slotkva + (PXG_HOST_INTR_OFFSET >> 2);
poll[0] = 0;
tc_wmb();
poll[2] = 0;
tc_wmb();
#endif
return (0);
}
DELAY(STAMP_DELAY); DELAY(STAMP_DELAY);
} }

View File

@ -1,7 +1,7 @@
/* $NetBSD: stic.c,v 1.6 2000/12/22 13:30:32 ad Exp $ */ /* $NetBSD: stic.c,v 1.7 2001/01/09 16:04:03 ad Exp $ */
/*- /*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
@ -89,6 +89,7 @@
#include <alpha/alpha_cpu.h> #include <alpha/alpha_cpu.h>
#endif #endif
#include <machine/vmparam.h>
#include <machine/bus.h> #include <machine/bus.h>
#include <machine/intr.h> #include <machine/intr.h>
@ -160,15 +161,14 @@ static int stic_show_screen(void *, void *, int,
void (*) (void *, int, int), void *); void (*) (void *, int, int), void *);
static void stic_do_switch(void *); static void stic_do_switch(void *);
static void stic_setup_backing(struct stic_info *, struct stic_screen *); static void stic_setup_backing(struct stic_info *, struct stic_screen *);
static void stic_setup_cmap(struct stic_screen *); static void stic_setup_vdac(struct stic_info *si);
static void stic_setup_cursor(struct stic_info *, struct stic_screen *);
static int stic_get_cmap(struct stic_screen *, struct wsdisplay_cmap *); static int stic_get_cmap(struct stic_info *, struct wsdisplay_cmap *);
static int stic_set_cmap(struct stic_screen *, struct wsdisplay_cmap *); static int stic_set_cmap(struct stic_info *, struct wsdisplay_cmap *);
static int stic_set_cursor(struct stic_screen *, struct wsdisplay_cursor *); static int stic_set_cursor(struct stic_info *, struct wsdisplay_cursor *);
static int stic_get_cursor(struct stic_screen *, struct wsdisplay_cursor *); static int stic_get_cursor(struct stic_info *, struct wsdisplay_cursor *);
static void stic_set_curpos(struct stic_screen *, struct wsdisplay_curpos *); static void stic_set_curpos(struct stic_info *, struct wsdisplay_curpos *);
static void stic_set_hwcurpos(struct stic_screen *); static void stic_set_hwcurpos(struct stic_info *);
static void stic_cursor(void *, int, int, int); static void stic_cursor(void *, int, int, int);
static void stic_copycols(void *, int, int, int, int); static void stic_copycols(void *, int, int, int, int);
@ -323,8 +323,6 @@ stic_init(struct stic_info *si)
REG(vdac, bt_reg) = 0x00ffffff; tc_wmb(); REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
REG(vdac, bt_reg) = 0x00ffffff; tc_wmb(); REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
si->si_vdacctl = STIC_VDAC_BLINK;
/* Get a font and set up screen metrics. */ /* Get a font and set up screen metrics. */
wsfont_init(); wsfont_init();
cookie = wsfont_find(NULL, 0, 0, 0); cookie = wsfont_find(NULL, 0, 0, 0);
@ -344,6 +342,8 @@ stic_init(struct stic_info *si)
if ((u_int)si->si_fonth > 32 || (u_int)si->si_fontw > 16) if ((u_int)si->si_fonth > 32 || (u_int)si->si_fontw > 16)
panic("stic_init: unusable font"); panic("stic_init: unusable font");
#endif #endif
stic_setup_vdac(si);
} }
void void
@ -430,27 +430,26 @@ stic_cnattach(struct stic_info *si)
ss = &stic_consscr; ss = &stic_consscr;
si->si_curscreen = ss; si->si_curscreen = ss;
ss->ss_flags = SS_ALLOCED | SS_ACTIVE | SS_CURENB | SS_CURENB_CHANGED; ss->ss_flags = SS_ALLOCED | SS_ACTIVE;
ss->ss_si = si; ss->ss_si = si;
stic_setup_cursor(si, ss); si->si_flags |= SI_CURENB | SI_CURENB_CHANGED;
stic_setup_cmap(ss);
stic_flush(si); stic_flush(si);
stic_eraserows(ss, 0, si->si_consh, 0);
stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, &defattr); stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, &defattr);
stic_eraserows(ss, 0, si->si_consh, 0);
wsdisplay_cnattach(&stic_stdscreen, ss, 0, 0, defattr); wsdisplay_cnattach(&stic_stdscreen, ss, 0, 0, defattr);
} }
static void static void
stic_setup_cursor(struct stic_info *si, struct stic_screen *ss) stic_setup_vdac(struct stic_info *si)
{ {
u_int8_t *ip, *mp; u_int8_t *ip, *mp;
int r, c, o, b; int r, c, o, b;
ip = (u_int8_t *)ss->ss_cursor.cc_image; ip = (u_int8_t *)si->si_cursor.cc_image;
mp = ip + (sizeof(ss->ss_cursor.cc_image) >> 1); mp = ip + (sizeof(si->si_cursor.cc_image) >> 1);
memset(ip, 0, sizeof(ss->ss_cursor.cc_image)); memset(ip, 0, sizeof(si->si_cursor.cc_image));
for (r = 0; r < si->si_fonth; r++) { for (r = 0; r < si->si_fonth; r++) {
for (c = 0; c < si->si_fontw; c++) { for (c = 0; c < si->si_fontw; c++) {
@ -464,30 +463,36 @@ stic_setup_cursor(struct stic_info *si, struct stic_screen *ss)
mp += 16; mp += 16;
} }
ss->ss_cursor.cc_size.x = 64; si->si_cursor.cc_size.x = 64;
ss->ss_cursor.cc_size.y = si->si_fonth; si->si_cursor.cc_size.y = si->si_fonth;
ss->ss_cursor.cc_hot.x = 0; si->si_cursor.cc_hot.x = 0;
ss->ss_cursor.cc_hot.y = 0; si->si_cursor.cc_hot.y = 0;
ss->ss_cursor.cc_color[0] = 0xff; si->si_cursor.cc_color[0] = 0xff;
ss->ss_cursor.cc_color[2] = 0xff; si->si_cursor.cc_color[2] = 0xff;
ss->ss_cursor.cc_color[4] = 0xff; si->si_cursor.cc_color[4] = 0xff;
ss->ss_cursor.cc_color[1] = 0x00; si->si_cursor.cc_color[1] = 0x00;
ss->ss_cursor.cc_color[3] = 0x00; si->si_cursor.cc_color[3] = 0x00;
ss->ss_cursor.cc_color[5] = 0x00; si->si_cursor.cc_color[5] = 0x00;
ss->ss_flags |= SS_CURSHAPE_CHANGED | SS_CURCMAP_CHANGED; memset(&si->si_cmap, 0, sizeof(si->si_cmap));
for (i = 0; i < 16; i++) {
si->si_cmap.r[i] = stic_cmap[i*3 + 0];
si->si_cmap.g[i] = stic_cmap[i*3 + 1];
si->si_cmap.b[i] = stic_cmap[i*3 + 2];
}
si->si_flags |= SI_CMAP_CHANGED | SI_CURSHAPE_CHANGED |
SI_CURCMAP_CHANGED;
} }
static int static int
sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{ {
struct stic_info *si; struct stic_info *si;
struct stic_screen *ss;
struct stic_xinfo *sxi; struct stic_xinfo *sxi;
ss = (struct stic_screen *)v; si = v;
si = ss->ss_si;
switch (cmd) { switch (cmd) {
case WSDISPLAYIO_GTYPE: case WSDISPLAYIO_GTYPE:
@ -498,16 +503,16 @@ sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
#define wsd_fbip ((struct wsdisplay_fbinfo *)data) #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
wsd_fbip->height = 1024; wsd_fbip->height = 1024;
wsd_fbip->width = 1280; wsd_fbip->width = 1280;
wsd_fbip->depth = si->si_depth; wsd_fbip->depth = si->si_depth == 8 ? 8 : 32;
wsd_fbip->cmsize = CMAP_SIZE; wsd_fbip->cmsize = CMAP_SIZE;
#undef fbt #undef fbt
return (0); return (0);
case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_GETCMAP:
return (stic_get_cmap(ss, (struct wsdisplay_cmap *)data)); return (stic_get_cmap(si, (struct wsdisplay_cmap *)data));
case WSDISPLAYIO_PUTCMAP: case WSDISPLAYIO_PUTCMAP:
return (stic_set_cmap(ss, (struct wsdisplay_cmap *)data)); return (stic_set_cmap(si, (struct wsdisplay_cmap *)data));
case WSDISPLAYIO_SVIDEO: case WSDISPLAYIO_SVIDEO:
#if 0 /* XXX later */ #if 0 /* XXX later */
@ -525,12 +530,11 @@ sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
return (0); return (0);
case WSDISPLAYIO_GCURPOS: case WSDISPLAYIO_GCURPOS:
*(struct wsdisplay_curpos *)data = ss->ss_cursor.cc_pos; *(struct wsdisplay_curpos *)data = si->si_cursor.cc_pos;
return (0); return (0);
case WSDISPLAYIO_SCURPOS: case WSDISPLAYIO_SCURPOS:
stic_set_curpos(ss, (struct wsdisplay_curpos *)data); stic_set_curpos(si, (struct wsdisplay_curpos *)data);
stic_set_hwcurpos(ss);
return (0); return (0);
case WSDISPLAYIO_GCURMAX: case WSDISPLAYIO_GCURMAX:
@ -539,10 +543,20 @@ sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
return (0); return (0);
case WSDISPLAYIO_GCURSOR: case WSDISPLAYIO_GCURSOR:
return (stic_get_cursor(ss, (struct wsdisplay_cursor *)data)); return (stic_get_cursor(si, (struct wsdisplay_cursor *)data));
case WSDISPLAYIO_SCURSOR: case WSDISPLAYIO_SCURSOR:
return (stic_set_cursor(ss, (struct wsdisplay_cursor *)data)); return (stic_set_cursor(si, (struct wsdisplay_cursor *)data));
case STICIO_RESET:
stic_reset(si);
return (0);
case STICIO_RESTORE:
stic_setup_vdac(si);
stic_flush(si);
stic_do_switch(si->si_curscreen);
return (0);
case STICIO_GXINFO: case STICIO_GXINFO:
sxi = (struct stic_xinfo *)data; sxi = (struct stic_xinfo *)data;
@ -551,20 +565,6 @@ sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
sxi->sxi_buf_size = si->si_buf_size; sxi->sxi_buf_size = si->si_buf_size;
sxi->sxi_buf_phys = (u_long)si->si_buf_phys; sxi->sxi_buf_phys = (u_long)si->si_buf_phys;
return (0); return (0);
case STICIO_SBLINK:
if ((int *)data != 0)
si->si_vdacctl |= STIC_VDAC_BLINK;
else
si->si_vdacctl &= ~STIC_VDAC_BLINK;
return (0);
case STICIO_S24BIT:
if ((int *)data != 0)
si->si_vdacctl |= STIC_VDAC_24BIT;
else
si->si_vdacctl &= ~STIC_VDAC_24BIT;
return (0);
} }
if (si->si_ioctl != NULL) if (si->si_ioctl != NULL)
@ -614,21 +614,6 @@ stic_setup_backing(struct stic_info *si, struct stic_screen *ss)
memset(ss->ss_backing, 0, size); memset(ss->ss_backing, 0, size);
} }
static void
stic_setup_cmap(struct stic_screen *ss)
{
int i;
memset(&ss->ss_cmap, 0, sizeof(ss->ss_cmap));
for (i = 0; i < 16; i++) {
ss->ss_cmap.r[i] = stic_cmap[i*3 + 0];
ss->ss_cmap.g[i] = stic_cmap[i*3 + 1];
ss->ss_cmap.b[i] = stic_cmap[i*3 + 2];
}
ss->ss_flags |= SS_CMAP_CHANGED;
}
static int static int
stic_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, stic_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
int *curxp, int *curyp, long *attrp) int *curxp, int *curyp, long *attrp)
@ -638,10 +623,6 @@ stic_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
si = (struct stic_info *)v; si = (struct stic_info *)v;
/* ZZZ */
printf("stic_alloc_screen: %s, %dx%d %p/%p\n",
type->name, type->ncols, type->nrows, type, &stic_stdscreen);
if ((stic_consscr.ss_flags & SS_ALLOCED) == 0) if ((stic_consscr.ss_flags & SS_ALLOCED) == 0)
ss = &stic_consscr; ss = &stic_consscr;
else { else {
@ -651,17 +632,13 @@ stic_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
stic_setup_backing(si, ss); stic_setup_backing(si, ss);
ss->ss_si = si; ss->ss_si = si;
ss->ss_flags |= SS_ALLOCED | SS_CURENB; ss->ss_flags = SS_ALLOCED;
*cookiep = ss; *cookiep = ss;
*curxp = 0; *curxp = 0;
*curyp = 0; *curyp = 0;
stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, attrp); stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, attrp);
stic_setup_cursor(si, ss);
stic_setup_cmap(ss);
printf("stic_alloc_screen: you got %p\n", ss);
return (0); return (0);
} }
@ -695,8 +672,6 @@ stic_show_screen(void *v, void *cookie, int waitok,
si->si_switchcb = cb; si->si_switchcb = cb;
si->si_switchcbarg = cbarg; si->si_switchcbarg = cbarg;
printf("stic_show_screen: cookie=%p v=%p\n", cookie, v);
if (cb != NULL) { if (cb != NULL) {
callout_reset(&si->si_switch_callout, 0, stic_do_switch, callout_reset(&si->si_switch_callout, 0, stic_do_switch,
cookie); cookie);
@ -718,13 +693,6 @@ stic_do_switch(void *cookie)
ss = cookie; ss = cookie;
si = ss->ss_si; si = ss->ss_si;
printf("stic_do_switch: cookie=%p si=%p\n", cookie, si);
if (ss == si->si_curscreen) {
si->si_switchcbarg = NULL;
return;
}
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
if (ss->ss_backing == NULL) if (ss->ss_backing == NULL)
panic("stic_do_switch: screen not backed"); panic("stic_do_switch: screen not backed");
@ -752,17 +720,18 @@ stic_do_switch(void *cookie)
stic_putchar(ss, r, c, p[0] >> 8, stic_putchar(ss, r, c, p[0] >> 8,
p[0] & 0x00ff); p[0] & 0x00ff);
if ((p[1] & 0xfff0) != 0) if ((p[1] & 0xfff0) != 0)
stic_putchar(ss, r, c, p[1] >> 8, stic_putchar(ss, r, c + 1, p[1] >> 8,
p[1] & 0x00ff); p[1] & 0x00ff);
} }
/* Re-enable the screen's backing and flush out the new VDAC state. */ /*
* Re-enable the screen's backing, and move the cursor to the
* correct spot.
*/
ss->ss_backing = sp; ss->ss_backing = sp;
ss->ss_flags |= SS_ALL_CHANGED; si->si_cursor.cc_pos.x = ss->ss_curx;
stic_flush(si); si->si_cursor.cc_pos.y = ss->ss_cury;
stic_set_hwcurpos(si);
/* Move the cursor to the correct spot. */
stic_set_hwcurpos(ss);
/* Tell wscons that we're done. */ /* Tell wscons that we're done. */
if (si->si_switchcbarg != NULL) { if (si->si_switchcbarg != NULL) {
@ -1135,79 +1104,72 @@ static void
stic_cursor(void *cookie, int on, int row, int col) stic_cursor(void *cookie, int on, int row, int col)
{ {
struct stic_screen *ss; struct stic_screen *ss;
struct stic_info *si;
ss = cookie; ss = cookie;
si = ss->ss_si;
/* XXX We should do cursor on/off. */ ss->ss_curx = col * si->si_fontw;
ss->ss_cursor.cc_pos.x = col * ss->ss_si->si_fontw; ss->ss_cury = row * si->si_fonth;
ss->ss_cursor.cc_pos.y = row * ss->ss_si->si_fonth;
stic_set_hwcurpos(ss); if ((ss->ss_flags & SS_ACTIVE) != 0) {
/* XXX We should do cursor on/off. */
si->si_cursor.cc_pos.x = ss->ss_curx;
si->si_cursor.cc_pos.y = ss->ss_cury;
stic_set_hwcurpos(si);
}
} }
void void
stic_flush(struct stic_info *si) stic_flush(struct stic_info *si)
{ {
struct stic_screen *ss;
volatile u_int32_t *vdac; volatile u_int32_t *vdac;
int v; int v;
ss = si->si_curscreen; if ((si->si_flags & SI_ALL_CHANGED) == 0)
if ((ss->ss_flags & SS_ALL_CHANGED) == 0)
return; return;
vdac = si->si_vdac; vdac = si->si_vdac;
v = ss->ss_flags; v = si->si_flags;
ss->ss_flags &= ~SS_ALL_CHANGED; si->si_flags &= ~SI_ALL_CHANGED;
if ((v & SS_CURENB_CHANGED) != 0) { if ((v & SI_CURENB_CHANGED) != 0) {
SELECT(vdac, BT459_IREG_CCR); SELECT(vdac, BT459_IREG_CCR);
if ((v & SS_CURENB) != 0) { if ((v & SI_CURENB) != 0)
if ((si->si_vdacctl & STIC_VDAC_BLINK) != 0) REG(vdac, bt_reg) = 0x00c0c0c0;
REG(vdac, bt_reg) = 0x00c1c1c1; else
else
REG(vdac, bt_reg) = 0x00c0c0c0;
} else
REG(vdac, bt_reg) = 0x00000000; REG(vdac, bt_reg) = 0x00000000;
tc_wmb(); tc_wmb();
} }
if ((v & SS_CURCMAP_CHANGED) != 0) { if ((v & SI_CURCMAP_CHANGED) != 0) {
u_int8_t *cp; u_int8_t *cp;
cp = ss->ss_cursor.cc_color; cp = si->si_cursor.cc_color;
SELECT(vdac, BT459_IREG_CCOLOR_2); SELECT(vdac, BT459_IREG_CCOLOR_2);
if ((si->si_vdacctl & STIC_VDAC_24BIT) != 0) { REG(vdac, bt_reg) = DUPBYTE0(cp[1]); tc_wmb();
REG(vdac, bt_reg) = cp[1]; tc_wmb(); REG(vdac, bt_reg) = DUPBYTE0(cp[3]); tc_wmb();
REG(vdac, bt_reg) = cp[3] << 8; tc_wmb(); REG(vdac, bt_reg) = DUPBYTE0(cp[5]); tc_wmb();
REG(vdac, bt_reg) = cp[5] << 16; tc_wmb(); REG(vdac, bt_reg) = DUPBYTE0(cp[0]); tc_wmb();
REG(vdac, bt_reg) = cp[0]; tc_wmb(); REG(vdac, bt_reg) = DUPBYTE0(cp[2]); tc_wmb();
REG(vdac, bt_reg) = cp[2] << 8; tc_wmb(); REG(vdac, bt_reg) = DUPBYTE0(cp[4]); tc_wmb();
REG(vdac, bt_reg) = cp[4] << 16; tc_wmb();
} else {
REG(vdac, bt_reg) = DUPBYTE0(cp[1]); tc_wmb();
REG(vdac, bt_reg) = DUPBYTE0(cp[3]); tc_wmb();
REG(vdac, bt_reg) = DUPBYTE0(cp[5]); tc_wmb();
REG(vdac, bt_reg) = DUPBYTE0(cp[0]); tc_wmb();
REG(vdac, bt_reg) = DUPBYTE0(cp[2]); tc_wmb();
REG(vdac, bt_reg) = DUPBYTE0(cp[4]); tc_wmb();
}
} }
if ((v & SS_CURSHAPE_CHANGED) != 0) { if ((v & SI_CURSHAPE_CHANGED) != 0) {
u_int8_t *ip, *mp, img, msk; u_int8_t *ip, *mp, img, msk;
u_int8_t u; u_int8_t u;
int bcnt; int bcnt;
ip = (u_int8_t *)ss->ss_cursor.cc_image; ip = (u_int8_t *)si->si_cursor.cc_image;
mp = (u_int8_t *)(ss->ss_cursor.cc_image + CURSOR_MAX_SIZE); mp = (u_int8_t *)(si->si_cursor.cc_image + CURSOR_MAX_SIZE);
bcnt = 0; bcnt = 0;
SELECT(vdac, BT459_IREG_CRAM_BASE+0); SELECT(vdac, BT459_IREG_CRAM_BASE+0);
/* 64 pixel scan line is consisted with 16 byte cursor ram */ /* 64 pixel scan line is consisted with 16 byte cursor ram */
while (bcnt < ss->ss_cursor.cc_size.y * 16) { while (bcnt < si->si_cursor.cc_size.y * 16) {
/* pad right half 32 pixel when smaller than 33 */ /* pad right half 32 pixel when smaller than 33 */
if ((bcnt & 0x8) && ss->ss_cursor.cc_size.x < 33) { if ((bcnt & 0x8) && si->si_cursor.cc_size.x < 33) {
REG(vdac, bt_reg) = 0; tc_wmb(); REG(vdac, bt_reg) = 0; tc_wmb();
REG(vdac, bt_reg) = 0; tc_wmb(); REG(vdac, bt_reg) = 0; tc_wmb();
} else { } else {
@ -1231,38 +1193,27 @@ stic_flush(struct stic_info *si)
} }
} }
if ((v & SS_CMAP_CHANGED) != 0) { if ((v & SI_CMAP_CHANGED) != 0) {
struct stic_hwcmap256 *cm; struct stic_hwcmap256 *cm;
int index; int index;
cm = &ss->ss_cmap; cm = &si->si_cmap;
SELECT(vdac, 0); SELECT(vdac, 0);
SELECT(vdac, 0); SELECT(vdac, 0);
if ((si->si_vdacctl & STIC_VDAC_24BIT) == 0) { for (index = 0; index < CMAP_SIZE; index++) {
for (index = 0; index < CMAP_SIZE; index++) { REG(vdac, bt_cmap) = DUPBYTE0(cm->r[index]);
REG(vdac, bt_cmap) = DUPBYTE0(cm->r[index]); tc_wmb();
tc_wmb(); REG(vdac, bt_cmap) = DUPBYTE0(cm->g[index]);
REG(vdac, bt_cmap) = DUPBYTE0(cm->g[index]); tc_wmb();
tc_wmb(); REG(vdac, bt_cmap) = DUPBYTE0(cm->b[index]);
REG(vdac, bt_cmap) = DUPBYTE0(cm->b[index]); tc_wmb();
tc_wmb();
}
} else {
for (index = 0; index < CMAP_SIZE; index++) {
REG(vdac, bt_cmap) = cm->r[index];
tc_wmb();
REG(vdac, bt_cmap) = cm->g[index] << 8;
tc_wmb();
REG(vdac, bt_cmap) = cm->b[index] << 16;
tc_wmb();
}
} }
} }
} }
static int static int
stic_get_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p) stic_get_cmap(struct stic_info *si, struct wsdisplay_cmap *p)
{ {
u_int index, count; u_int index, count;
@ -1277,21 +1228,21 @@ stic_get_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p)
!uvm_useracc(p->blue, count, B_WRITE)) !uvm_useracc(p->blue, count, B_WRITE))
return (EFAULT); return (EFAULT);
copyout(&ss->ss_cmap.r[index], p->red, count); copyout(&si->si_cmap.r[index], p->red, count);
copyout(&ss->ss_cmap.g[index], p->green, count); copyout(&si->si_cmap.g[index], p->green, count);
copyout(&ss->ss_cmap.b[index], p->blue, count); copyout(&si->si_cmap.b[index], p->blue, count);
return (0); return (0);
} }
static int static int
stic_set_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p) stic_set_cmap(struct stic_info *si, struct wsdisplay_cmap *p)
{ {
u_int index, count; u_int index, count;
index = p->index; index = p->index;
count = p->count; count = p->count;
if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE) if ((index + count) > CMAP_SIZE)
return (EINVAL); return (EINVAL);
if (!uvm_useracc(p->red, count, B_READ) || if (!uvm_useracc(p->red, count, B_READ) ||
@ -1299,26 +1250,26 @@ stic_set_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p)
!uvm_useracc(p->blue, count, B_READ)) !uvm_useracc(p->blue, count, B_READ))
return (EFAULT); return (EFAULT);
copyin(p->red, &ss->ss_cmap.r[index], count); copyin(p->red, &si->si_cmap.r[index], count);
copyin(p->green, &ss->ss_cmap.g[index], count); copyin(p->green, &si->si_cmap.g[index], count);
copyin(p->blue, &ss->ss_cmap.b[index], count); copyin(p->blue, &si->si_cmap.b[index], count);
ss->ss_flags |= SS_CMAP_CHANGED; si->si_flags |= SI_CMAP_CHANGED;
/* /*
* XXX Since we don't yet receive vblank interrupts from the PXG, we * XXX Since we don't yet receive vblank interrupts from the PXG, we
* must flush immediatley. * must flush immediatley.
*/ */
if (ss->ss_si->si_disptype == WSDISPLAY_TYPE_PXG) if (si->si_disptype == WSDISPLAY_TYPE_PXG)
stic_flush(ss->ss_si); stic_flush(si);
return (0); return (0);
} }
static int static int
stic_set_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p) stic_set_cursor(struct stic_info *si, struct wsdisplay_cursor *p)
{ {
#define cc (&ss->ss_cursor) #define cc (&si->si_cursor)
int v, index, count, icount; int v, index, count, icount;
v = p->which; v = p->which;
@ -1347,25 +1298,22 @@ stic_set_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p)
if (v & WSDISPLAY_CURSOR_DOCUR) if (v & WSDISPLAY_CURSOR_DOCUR)
cc->cc_hot = p->hot; cc->cc_hot = p->hot;
if (v & WSDISPLAY_CURSOR_DOPOS) if (v & WSDISPLAY_CURSOR_DOPOS)
stic_set_curpos(ss, &p->pos); stic_set_curpos(si, &p->pos);
stic_set_hwcurpos(ss);
} }
ss->ss_flags &= ~SS_ALL_CHANGED;
if ((v & WSDISPLAY_CURSOR_DOCUR) != 0) { if ((v & WSDISPLAY_CURSOR_DOCUR) != 0) {
if (p->enable) if (p->enable)
ss->ss_flags |= SS_CURENB; si->si_flags |= SI_CURENB;
else else
ss->ss_flags &= ~SS_CURENB; si->si_flags &= ~SI_CURENB;
ss->ss_flags |= SS_CURENB_CHANGED; si->si_flags |= SI_CURENB_CHANGED;
} }
if ((v & WSDISPLAY_CURSOR_DOCMAP) != 0) { if ((v & WSDISPLAY_CURSOR_DOCMAP) != 0) {
copyin(p->cmap.red, &cc->cc_color[index], count); copyin(p->cmap.red, &cc->cc_color[index], count);
copyin(p->cmap.green, &cc->cc_color[index + 2], count); copyin(p->cmap.green, &cc->cc_color[index + 2], count);
copyin(p->cmap.blue, &cc->cc_color[index + 4], count); copyin(p->cmap.blue, &cc->cc_color[index + 4], count);
ss->ss_flags |= SS_CURCMAP_CHANGED; si->si_flags |= SI_CURCMAP_CHANGED;
} }
if ((v & WSDISPLAY_CURSOR_DOSHAPE) != 0) { if ((v & WSDISPLAY_CURSOR_DOSHAPE) != 0) {
@ -1373,30 +1321,30 @@ stic_set_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p)
memset(cc->cc_image, 0, sizeof cc->cc_image); memset(cc->cc_image, 0, sizeof cc->cc_image);
copyin(p->image, cc->cc_image, icount); copyin(p->image, cc->cc_image, icount);
copyin(p->mask, cc->cc_image+CURSOR_MAX_SIZE, icount); copyin(p->mask, cc->cc_image+CURSOR_MAX_SIZE, icount);
ss->ss_flags |= SS_CURSHAPE_CHANGED; si->si_flags |= SI_CURSHAPE_CHANGED;
} }
/* /*
* XXX Since we don't yet receive vblank interrupts from the PXG, we * XXX Since we don't yet receive vblank interrupts from the PXG, we
* must flush immediatley. * must flush immediatley.
*/ */
if (ss->ss_si->si_disptype == WSDISPLAY_TYPE_PXG) if (si->si_disptype == WSDISPLAY_TYPE_PXG)
stic_flush(ss->ss_si); stic_flush(si);
return (0); return (0);
#undef cc #undef cc
} }
static int static int
stic_get_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p) stic_get_cursor(struct stic_info *si, struct wsdisplay_cursor *p)
{ {
/* XXX No X support yet. */ /* XXX */
return (ENOTTY); return (ENOTTY);
} }
static void static void
stic_set_curpos(struct stic_screen *ss, struct wsdisplay_curpos *curpos) stic_set_curpos(struct stic_info *si, struct wsdisplay_curpos *curpos)
{ {
int x, y; int x, y;
@ -1412,23 +1360,21 @@ stic_set_curpos(struct stic_screen *ss, struct wsdisplay_curpos *curpos)
else if (x > 1279) else if (x > 1279)
x = 1279; x = 1279;
ss->ss_cursor.cc_pos.x = x; si->si_cursor.cc_pos.x = x;
ss->ss_cursor.cc_pos.y = y; si->si_cursor.cc_pos.y = y;
stic_set_hwcurpos(ss); stic_set_hwcurpos(si);
} }
static void static void
stic_set_hwcurpos(struct stic_screen *ss) stic_set_hwcurpos(struct stic_info *si)
{ {
struct stic_info *si;
volatile u_int32_t *vdac; volatile u_int32_t *vdac;
int x, y, s; int x, y, s;
si = ss->ss_si;
vdac = si->si_vdac; vdac = si->si_vdac;
x = ss->ss_cursor.cc_pos.x - ss->ss_cursor.cc_hot.x; x = si->si_cursor.cc_pos.x - si->si_cursor.cc_hot.x;
y = ss->ss_cursor.cc_pos.y - ss->ss_cursor.cc_hot.y; y = si->si_cursor.cc_pos.y - si->si_cursor.cc_hot.y;
x += STIC_MAGIC_X; x += STIC_MAGIC_X;
y += STIC_MAGIC_Y; y += STIC_MAGIC_Y;

View File

@ -1,7 +1,7 @@
/* $NetBSD: sticvar.h,v 1.6 2000/12/22 13:30:32 ad Exp $ */ /* $NetBSD: sticvar.h,v 1.7 2001/01/09 16:04:04 ad Exp $ */
/*- /*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
@ -70,19 +70,10 @@ struct stic_screen {
int ss_flags; int ss_flags;
int ss_curx; int ss_curx;
int ss_cury; int ss_cury;
struct stic_hwcursor64 ss_cursor;
struct stic_hwcmap256 ss_cmap;
}; };
#define SS_CURENB_CHANGED 0x0001 #define SS_ALLOCED 0x01
#define SS_CURCMAP_CHANGED 0x0002 #define SS_ACTIVE 0x02
#define SS_CURSHAPE_CHANGED 0x0004
#define SS_CMAP_CHANGED 0x0008
#define SS_ALL_CHANGED 0x000f
#define SS_ALLOCED 0x0010
#define SS_ACTIVE 0x0020
#define SS_CURENB 0x0040
struct stic_info { struct stic_info {
u_int32_t *si_slotkva; u_int32_t *si_slotkva;
@ -114,15 +105,22 @@ struct stic_info {
paddr_t si_buf_phys; paddr_t si_buf_phys;
size_t si_buf_size; size_t si_buf_size;
int si_vdacctl; int si_flags;
struct stic_hwcursor64 si_cursor;
struct stic_hwcmap256 si_cmap;
struct callout si_switch_callout; struct callout si_switch_callout;
void (*si_switchcb)(void *, int, int); void (*si_switchcb)(void *, int, int);
void *si_switchcbarg; void *si_switchcbarg;
}; };
#define STIC_VDAC_BLINK 0x01 #define SI_CURENB_CHANGED 0x0001
#define STIC_VDAC_24BIT 0x02 #define SI_CURCMAP_CHANGED 0x0002
#define SI_CURSHAPE_CHANGED 0x0004
#define SI_CMAP_CHANGED 0x0008
#define SI_ALL_CHANGED 0x000f
#define SI_CURENB 0x0100
void stic_init(struct stic_info *); void stic_init(struct stic_info *);
void stic_attach(struct device *, struct stic_info *, int); void stic_attach(struct device *, struct stic_info *, int);
@ -135,7 +133,7 @@ extern struct stic_info stic_consinfo;
#endif /* _KERNEL */ #endif /* _KERNEL */
#define STIC_PACKET_SIZE 4096 #define STIC_PACKET_SIZE 4096
#define STIC_IMGBUF_SIZE 8192 #define STIC_IMGBUF_SIZE 1280*4
struct stic_xinfo { struct stic_xinfo {
int sxi_stampw; int sxi_stampw;
@ -144,16 +142,16 @@ struct stic_xinfo {
u_long sxi_buf_phys; u_long sxi_buf_phys;
}; };
#define STICIO_GXINFO _IOR('s', 0, struct stic_xinfo) #define STICIO_GXINFO _IOR('S', 0, struct stic_xinfo)
#define STICIO_SBLINK _IOW('s', 1, int) #define STICIO_RESET _IO('S', 1)
#define STICIO_S24BIT _IOW('s', 2, int) #define STICIO_START860 _IO('S', 2)
#define STICIO_START860 _IO('s', 3) #define STICIO_RESET860 _IO('S', 3)
#define STICIO_RESET860 _IO('s', 4) #define STICIO_RESTORE _IO('S', 4)
struct stic_xmap { struct stic_xmap {
u_int32_t sxm_stic[PAGE_SIZE]; u_int8_t sxm_stic[NBPG];
u_int32_t sxm_poll[0x0c0000 / sizeof(u_int32_t)]; u_int8_t sxm_poll[0x0c0000];
u_int32_t sxm_buf[256 * 1024 / sizeof(u_int32_t)]; u_int8_t sxm_buf[256 * 1024];
}; };
#endif /* !_TC_STICVAR_H_ */ #endif /* !_TC_STICVAR_H_ */