summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorreinoud <reinoud@NetBSD.org>2002-03-23 21:27:41 +0000
committerreinoud <reinoud@NetBSD.org>2002-03-23 21:27:41 +0000
commit2b488a7d9f42c3d6038e07cb516253ee53a2d9ee (patch)
tree21fd022767482cff125b7d6da3adbdccd16dbb99 /sys
parent8e6517a8e3fe58f7791e6ec41c8141b79321c347 (diff)
Big rototil of the vidcvideo code to cleanup illogical structures and to
incorporate write back support for processors not having a write through cache. The current fb_devconfig structure now really holds the device's configuration and the softc really only holds the attachment information. This used to be mixed giving rise to weird stuctures and cross references. The number of vertical syncs before the video memory writeback is triggered is configurable ... default is to wait for 5 Vsync .. aprox minumum 10 times a second, but more likely in the order of 12,5 times a second. When printing is in progress no write back is performed... only after the waiting time. The reasoning behind this is that as long as the screen is printed too the cache will be purged of dirty data anyway due to the processing and new screen memory useage.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm/iomd/vidcvideo.c179
-rw-r--r--sys/arch/arm/iomd/vidcvideo.h9
2 files changed, 113 insertions, 75 deletions
diff --git a/sys/arch/arm/iomd/vidcvideo.c b/sys/arch/arm/iomd/vidcvideo.c
index dfe9785c50d..fbac0fb48da 100644
--- a/sys/arch/arm/iomd/vidcvideo.c
+++ b/sys/arch/arm/iomd/vidcvideo.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vidcvideo.c,v 1.8 2002/03/23 18:10:24 reinoud Exp $ */
+/* $NetBSD: vidcvideo.c,v 1.9 2002/03/23 21:27:41 reinoud Exp $ */
/*
* Copyright (c) 2001 Reinoud Zandijk
@@ -36,7 +36,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: vidcvideo.c,v 1.8 2002/03/23 18:10:24 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vidcvideo.c,v 1.9 2002/03/23 21:27:41 reinoud Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -58,12 +58,15 @@ __KERNEL_RCSID(0, "$NetBSD: vidcvideo.c,v 1.8 2002/03/23 18:10:24 reinoud Exp $"
#include <uvm/uvm_extern.h>
#include <arm/arm32/pmap.h>
+#include <arm/cpufunc.h>
#include <machine/intr.h>
/* for vidc_mode ... needs to be MI indepenent one day */
#include <arm/iomd/vidc.h>
#include <arm/iomd/vidc20config.h>
+#include <arm/iomd/vidcvideo.h>
#include <machine/bootconfig.h>
+
extern videomemory_t videomemory;
#define machine_btop(x) arm_byte_to_page(x)
@@ -72,26 +75,6 @@ extern videomemory_t videomemory;
/* FOR DEBUG */
extern videomemory_t videomemory;
-struct fb_devconfig {
- vaddr_t dc_vaddr; /* memory space virtual base address */
- paddr_t dc_paddr; /* memory space physical base address */
- vsize_t dc_size; /* size of slot memory */
- int dc_wid; /* width of frame buffer */
- int dc_ht; /* height of frame buffer */
- int dc_log2_depth; /* log2 of bits per pixel */
- int dc_depth; /* depth, bits per pixel */
- int dc_rowbytes; /* bytes in a FB scan line */
- vaddr_t dc_videobase; /* base of flat frame buffer */
- int dc_blanked; /* currently has video disabled */
- void *dc_hwscroll_cookie; /* cookie for hardware scroll */
-
- struct vidc_mode mode_info;
- struct rasops_info rinfo;
-
- /* Origional rasops functions for deligation */
- struct wsdisplay_emulops orig_ri_ops;
-};
-
struct hwcmap256 {
#define CMAP_SIZE 256 /* 256 R/G/B entries */
@@ -113,16 +96,40 @@ struct hwcursor32 {
};
-struct vidcvideo_softc {
- struct device sc_dev;
- struct fb_devconfig *sc_dc; /* device configuration */
- struct hwcmap256 sc_cmap; /* software copy of colormap */
- struct hwcursor32 sc_cursor; /* software copy of cursor */
- int sc_curenb; /* cursor sprite enabled */
- int sc_changed; /* need update of hardware */
+struct fb_devconfig {
+ vaddr_t dc_vaddr; /* memory space virtual base address */
+ paddr_t dc_paddr; /* memory space physical base address */
+ vsize_t dc_size; /* size of slot memory */
+ int dc_wid; /* width of frame buffer */
+ int dc_ht; /* height of frame buffer */
+ int dc_log2_depth; /* log2 of bits per pixel */
+ int dc_depth; /* depth, bits per pixel */
+ int dc_rowbytes; /* bytes in a FB scan line */
+ vaddr_t dc_videobase; /* base of flat frame buffer */
+ int dc_blanked; /* currently has video disabled */
+ void *dc_hwscroll_cookie; /* cookie for hardware scroll */
+
+ int dc_curenb; /* is cursor sprite enabled ? */
+ int dc_changed; /* need update of hardware */
+ int dc_writeback_delay; /* Screenarea write back vsync counter */
#define WSDISPLAY_CMAP_DOLUT 0x20
#define WSDISPLAY_VIDEO_ONOFF 0x40
- int nscreens;
+#define WSDISPLAY_WB_COUNTER 0x80
+
+ struct hwcmap256 dc_cmap; /* software copy of colormap */
+ struct hwcursor32 dc_cursor; /* software copy of cursor */
+
+ struct vidc_mode mode_info;
+ struct rasops_info rinfo;
+
+ struct wsdisplay_emulops orig_ri_ops; /* Rasops functions for deligation */
+};
+
+
+struct vidcvideo_softc {
+ struct device sc_dev;
+ struct fb_devconfig *sc_dc; /* device configuration */
+ int nscreens; /* number of screens configured */
};
@@ -271,7 +278,10 @@ vidcvideo_getdevconfig(dense_addr, dc)
dc->rinfo.ri_width = dc->dc_wid;
dc->rinfo.ri_height = dc->dc_ht;
dc->rinfo.ri_stride = dc->dc_rowbytes;
- dc->rinfo.ri_hw = NULL;
+ dc->rinfo.ri_hw = dc; /* link back */
+
+ /* intitialise miscelanious */
+ dc->dc_writeback_delay = 0;
}
@@ -341,6 +351,7 @@ vidcvideo_attach(parent, self, aux)
void *aux;
{
struct vidcvideo_softc *sc = (struct vidcvideo_softc *)self;
+ struct fb_devconfig *dc;
struct wsemuldisplaydev_attach_args waa;
struct hwcmap256 *cm;
const u_int8_t *p;
@@ -362,12 +373,14 @@ vidcvideo_attach(parent, self, aux)
return;
};
+ dc = sc->sc_dc;
+
vidcvideo_printdetails();
- printf(": using %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
- sc->sc_dc->dc_depth);
+ printf(": using %d x %d, %dbpp\n", dc->dc_wid, dc->dc_ht,
+ dc->dc_depth);
/* initialise rasops */
- cm = &sc->sc_cmap;
+ cm = &dc->dc_cmap;
p = rasops_cmap;
for (index = 0; index < CMAP_SIZE; index++, p += 3) {
cm->r[index] = p[0];
@@ -376,20 +389,20 @@ vidcvideo_attach(parent, self, aux)
}
/* what does these do ? */
- sc->sc_cursor.cc_magic.x = CX_MAGIC_X;
- sc->sc_cursor.cc_magic.y = CX_MAGIC_Y;
+ dc->dc_cursor.cc_magic.x = CX_MAGIC_X;
+ dc->dc_cursor.cc_magic.y = CX_MAGIC_Y;
/* set up interrupt flags */
- sc->sc_changed |= WSDISPLAY_CMAP_DOLUT;
+ dc->dc_changed |= WSDISPLAY_CMAP_DOLUT;
/*
* Set up a link in the rasops structure to our device config
* for acceleration stuff
*/
- sc->sc_dc->rinfo.ri_hw = sc->sc_dc;
+ dc->rinfo.ri_hw = sc->sc_dc;
/* Establish an interrupt handler, and clear any pending interrupts */
- intr_claim(IRQ_FLYBACK, IPL_TTY, "vblank", vidcvideointr, sc);
+ intr_claim(IRQ_FLYBACK, IPL_TTY, "vblank", vidcvideointr, dc);
waa.console = (vidcvideo_is_console ? 1 : 0);
waa.scrdata = &vidcvideo_screenlist;
@@ -419,9 +432,9 @@ vidcvideoioctl(v, cmd, data, flag, p)
case WSDISPLAYIO_GINFO:
#define wsd_fbip ((struct wsdisplay_fbinfo *)data)
- wsd_fbip->height = sc->sc_dc->dc_ht;
- wsd_fbip->width = sc->sc_dc->dc_wid;
- wsd_fbip->depth = sc->sc_dc->dc_depth;
+ wsd_fbip->height = dc->dc_ht;
+ wsd_fbip->width = dc->dc_wid;
+ wsd_fbip->depth = dc->dc_depth;
wsd_fbip->cmsize = CMAP_SIZE;
#undef fbt
return (0);
@@ -435,7 +448,7 @@ vidcvideoioctl(v, cmd, data, flag, p)
case WSDISPLAYIO_SVIDEO:
state = *(int *)data;
dc->dc_blanked = (state == WSDISPLAYIO_VIDEO_OFF);
- sc->sc_changed |= WSDISPLAY_VIDEO_ONOFF;
+ dc->dc_changed |= WSDISPLAY_VIDEO_ONOFF;
/* done on video blank */
return (0);
@@ -445,12 +458,12 @@ vidcvideoioctl(v, cmd, data, flag, p)
return (0);
case WSDISPLAYIO_GCURPOS:
- *(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
+ *(struct wsdisplay_curpos *)data = dc->dc_cursor.cc_pos;
return (0);
case WSDISPLAYIO_SCURPOS:
set_curpos(sc, (struct wsdisplay_curpos *)data);
- sc->sc_changed |= WSDISPLAY_CURSOR_DOPOS;
+ dc->dc_changed |= WSDISPLAY_CURSOR_DOPOS;
return (0);
case WSDISPLAYIO_GCURMAX:
@@ -502,6 +515,7 @@ vidcvideo_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
long *attrp;
{
struct vidcvideo_softc *sc = v;
+ struct fb_devconfig *dc = sc->sc_dc;
long defattr;
/*
@@ -512,12 +526,12 @@ vidcvideo_alloc_screen(v, type, cookiep, curxp, curyp, attrp)
return (ENOMEM);
/* Add the screen to wscons to control */
- *cookiep = &sc->sc_dc->rinfo;
+ *cookiep = &dc->rinfo;
*curxp = 0;
*curyp = 0;
- vidcvideo_getdevconfig(videomemory.vidm_vbase, sc->sc_dc);
- vidcvideo_config_wscons(sc->sc_dc);
- (*sc->sc_dc->rinfo.ri_ops.alloc_attr)(&sc->sc_dc->rinfo, 0, 0, 0, &defattr);
+ vidcvideo_getdevconfig(videomemory.vidm_vbase, dc);
+ vidcvideo_config_wscons(dc);
+ (*dc->rinfo.ri_ops.alloc_attr)(&dc->rinfo, 0, 0, 0, &defattr);
*attrp = defattr;
sc->nscreens++;
@@ -574,21 +588,29 @@ static int
vidcvideointr(arg)
void *arg;
{
- struct vidcvideo_softc *sc = arg;
- int v;
+ struct fb_devconfig *dc = arg;
+ int v, cleared = 0;
- v = sc->sc_changed;
+ v = dc->dc_changed;
if (v == 0)
return (1);
+ if (v & WSDISPLAY_WB_COUNTER) {
+ dc->dc_writeback_delay--;
+ if (dc->dc_writeback_delay == 0) {
+ cpu_dcache_wb_range(dc->dc_vaddr, dc->dc_size);
+ cleared |= WSDISPLAY_WB_COUNTER;
+ };
+ }
+
if (v & WSDISPLAY_CMAP_DOLUT) {
- struct hwcmap256 *cm = &sc->sc_cmap;
+ struct hwcmap256 *cm = &dc->dc_cmap;
int index;
- if (sc->sc_dc->dc_depth == 4) {
+ if (dc->dc_depth == 4) {
/* palette for 4 bpp is different from 8bpp */
vidcvideo_write(VIDC_PALREG, 0x00000000);
- for (index=0; index < 1<<sc->sc_dc->dc_depth; index++)
+ for (index=0; index < (1 << dc->dc_depth); index++)
vidcvideo_write(VIDC_PALETTE,
VIDC_COL(cm->r[index],
cm->g[index],
@@ -596,7 +618,7 @@ vidcvideointr(arg)
;
};
- if (sc->sc_dc->dc_depth == 8) {
+ if (dc->dc_depth == 8) {
/* dunno what to do in more than 8bpp */
/* palettes only make sense in 8bpp and less modes on VIDC */
vidcvideo_write(VIDC_PALREG, 0x00000000);
@@ -606,22 +628,26 @@ vidcvideointr(arg)
);
};
};
+ cleared |= WSDISPLAY_CMAP_DOLUT;
}
if (v & WSDISPLAY_VIDEO_ONOFF) {
- vidcvideo_blank(sc->sc_dc->dc_blanked);
+ vidcvideo_blank(dc->dc_blanked);
+ cleared |= WSDISPLAY_VIDEO_ONOFF;
};
if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT)) {
int x, y;
- x = sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x;
- y = sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y;
+ x = dc->dc_cursor.cc_pos.x - dc->dc_cursor.cc_hot.x;
+ y = dc->dc_cursor.cc_pos.y - dc->dc_cursor.cc_hot.y;
vidcvideo_updatecursor(x, y);
+ cleared |= WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT;
};
if (v & WSDISPLAY_CURSOR_DOCUR) {
- vidcvideo_enablecursor(sc->sc_curenb);
+ vidcvideo_enablecursor(dc->dc_curenb);
+ cleared |= WSDISPLAY_CURSOR_DOCUR;
};
@@ -698,7 +724,8 @@ vidcvideointr(arg)
}
#endif /* XXX snip XXX */
- sc->sc_changed = 0;
+ dc->dc_changed ^= cleared;
+
return (1);
}
@@ -751,9 +778,9 @@ get_cmap(sc, p)
!uvm_useracc(p->blue, count, B_WRITE))
return (EFAULT);
- copyout(&sc->sc_cmap.r[index], p->red, count);
- copyout(&sc->sc_cmap.g[index], p->green, count);
- copyout(&sc->sc_cmap.b[index], p->blue, count);
+ copyout(&sc->sc_dc->dc_cmap.r[index], p->red, count);
+ copyout(&sc->sc_dc->dc_cmap.g[index], p->green, count);
+ copyout(&sc->sc_dc->dc_cmap.b[index], p->blue, count);
return (0);
}
@@ -764,6 +791,7 @@ set_cmap(sc, p)
struct vidcvideo_softc *sc;
struct wsdisplay_cmap *p;
{
+ struct fb_devconfig *dc = sc->sc_dc;
u_int index = p->index, count = p->count;
if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
@@ -774,10 +802,10 @@ set_cmap(sc, p)
!uvm_useracc(p->blue, count, B_READ))
return (EFAULT);
- copyin(p->red, &sc->sc_cmap.r[index], count);
- copyin(p->green, &sc->sc_cmap.g[index], count);
- copyin(p->blue, &sc->sc_cmap.b[index], count);
- sc->sc_changed |= WSDISPLAY_CMAP_DOLUT;
+ copyin(p->red, &dc->dc_cmap.r[index], count);
+ copyin(p->green, &dc->dc_cmap.g[index], count);
+ copyin(p->blue, &dc->dc_cmap.b[index], count);
+ dc->dc_changed |= WSDISPLAY_CMAP_DOLUT;
return (0);
}
@@ -787,7 +815,8 @@ set_cursor(sc, p)
struct vidcvideo_softc *sc;
struct wsdisplay_cursor *p;
{
-#define cc (&sc->sc_cursor)
+#define cc (&dc->dc_cursor)
+ struct fb_devconfig *dc = sc->sc_dc;
u_int v, index, count, icount;
v = p->which;
@@ -811,7 +840,7 @@ set_cursor(sc, p)
}
if (v & WSDISPLAY_CURSOR_DOCUR)
- sc->sc_curenb = p->enable;
+ dc->dc_curenb = p->enable;
if (v & WSDISPLAY_CURSOR_DOPOS)
set_curpos(sc, &p->pos);
if (v & WSDISPLAY_CURSOR_DOHOT)
@@ -828,7 +857,7 @@ set_cursor(sc, p)
copyin(p->image, cc->cc_image, icount);
copyin(p->mask, cc->cc_mask, icount);
}
- sc->sc_changed |= v;
+ dc->dc_changed |= v;
return (0);
#undef cc
@@ -860,8 +889,8 @@ set_curpos(sc, curpos)
x = 0;
else if (x > dc->dc_wid)
x = dc->dc_wid;
- sc->sc_cursor.cc_pos.x = x;
- sc->sc_cursor.cc_pos.y = y;
+ dc->dc_cursor.cc_pos.x = x;
+ dc->dc_cursor.cc_pos.y = y;
}
@@ -932,6 +961,10 @@ static void vv_putchar(id, row, col, uc, attr)
struct rasops_info *ri = id;
struct fb_devconfig *dc = (struct fb_devconfig *) (ri->ri_hw);
+ /* delay the write back operation of the screen area */
+ dc->dc_writeback_delay = SCREEN_WRITE_BACK_DELAY;
+ dc->dc_changed |= WSDISPLAY_WB_COUNTER;
+
/* just delegate */
dc->orig_ri_ops.putchar(id, row, col, uc, attr);
}
diff --git a/sys/arch/arm/iomd/vidcvideo.h b/sys/arch/arm/iomd/vidcvideo.h
index 6c6988d2d0e..a01f6fc2b0f 100644
--- a/sys/arch/arm/iomd/vidcvideo.h
+++ b/sys/arch/arm/iomd/vidcvideo.h
@@ -1,4 +1,4 @@
-/* $NetBSD: vidcvideo.h,v 1.1 2001/10/05 22:27:43 reinoud Exp $ */
+/* $NetBSD: vidcvideo.h,v 1.2 2002/03/23 21:27:41 reinoud Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,9 +35,14 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * Definitions for wscons attachment on the VIDC wscons driver
*
*/
+
+/* lazy screen write back configuration */
+#define SCREEN_WRITE_BACK_DELAY 5
+
+
+/* Definitions for wscons attachment on the VIDC wscons driver */
extern int vidcvideo_cnattach __P((vaddr_t));