summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/agpvar.h3
-rw-r--r--sys/dev/pci/drm/drm_drv.c18
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.c231
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.h9
-rw-r--r--sys/dev/pci/drm/i915/intel_fb.c5
5 files changed, 62 insertions, 204 deletions
diff --git a/sys/dev/pci/agpvar.h b/sys/dev/pci/agpvar.h
index 556d019d250..8e1eda3a271 100644
--- a/sys/dev/pci/agpvar.h
+++ b/sys/dev/pci/agpvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: agpvar.h,v 1.26 2013/03/18 12:02:56 jsg Exp $ */
+/* $OpenBSD: agpvar.h,v 1.27 2013/04/14 19:04:37 kettenis Exp $ */
/* $NetBSD: agpvar.h,v 1.4 2001/10/01 21:54:48 fvdl Exp $ */
/*-
@@ -47,6 +47,7 @@
#define BUS_DMA_GTT_NOCACHE (1 << 30)
#define BUS_DMA_GTT_CACHE_LLC (1 << 29)
#define BUS_DMA_GTT_CACHE_LLC_MLC (1 << 28)
+#define BUS_DMA_GTT_WRAPAROUND (1 << 27)
struct agp_attach_args {
char *aa_busname;
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index 45dd52488e4..7b5d7cf97c9 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_drv.c,v 1.103 2013/04/10 01:35:55 guenther Exp $ */
+/* $OpenBSD: drm_drv.c,v 1.104 2013/04/14 19:04:37 kettenis Exp $ */
/*-
* Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org>
* Copyright © 2008 Intel Corporation
@@ -1707,6 +1707,22 @@ drm_gem_load_uao(bus_dma_tag_t dmat, bus_dmamap_t map, struct uvm_object *uao,
if ((ret = bus_dmamap_load_raw(dmat, map, segs, i, size, flags)) != 0)
goto unwire;
+ /*
+ * Create a mapping that wraps around once; the second half
+ * maps to the same set of physical pages as the first half.
+ * Used to implement fast vertical scrolling in inteldrm(4).
+ *
+ * XXX This is an ugly hack that wastes pages and abuses the
+ * internals of the scatter gather DMA code.
+ */
+ if (flags & BUS_DMA_GTT_WRAPAROUND) {
+ struct sg_page_map *spm = map->_dm_cookie;
+
+ for (i = spm->spm_pagecnt / 2; i < spm->spm_pagecnt; i++)
+ spm->spm_map[i].spe_pa = spm->spm_map[i - spm->spm_pagecnt / 2].spe_pa;
+ agp_bus_dma_rebind(dmat, map, flags);
+ }
+
*segp = segs;
return (0);
diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c
index 839f06c1f92..6683df9ea51 100644
--- a/sys/dev/pci/drm/i915/i915_drv.c
+++ b/sys/dev/pci/drm/i915/i915_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_drv.c,v 1.17 2013/04/05 02:54:51 jsg Exp $ */
+/* $OpenBSD: i915_drv.c,v 1.18 2013/04/14 19:04:37 kettenis Exp $ */
/*
* Copyright (c) 2008-2009 Owain G. Ainsworth <oga@openbsd.org>
*
@@ -751,204 +751,53 @@ inteldrm_doswitch(void *v, void *cookie)
* Accelerated routines.
*/
-int inteldrm_copycols(void *, int, int, int, int);
-int inteldrm_erasecols(void *, int, int, int, long);
int inteldrm_copyrows(void *, int, int, int);
-int inteldrm_eraserows(void *cookie, int, int, long);
-void inteldrm_copyrect(struct inteldrm_softc *, int, int, int, int, int, int);
-void inteldrm_fillrect(struct inteldrm_softc *, int, int, int, int, int);
-
-int
-inteldrm_copycols(void *cookie, int row, int src, int dst, int num)
-{
- struct rasops_info *ri = cookie;
- struct inteldrm_softc *sc = ri->ri_hw;
- struct drm_device *dev = (struct drm_device *)sc->drmdev;
-
- if (dev->open_count > 0 || sc->noaccel)
- return sc->noaccel_copycols(cookie, row, src, dst, num);
-
- num *= ri->ri_font->fontwidth;
- src *= ri->ri_font->fontwidth;
- dst *= ri->ri_font->fontwidth;
- row *= ri->ri_font->fontheight;
-
- inteldrm_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row,
- ri->ri_xorigin + dst, ri->ri_yorigin + row,
- num, ri->ri_font->fontheight);
-
- return 0;
-}
-
-int
-inteldrm_erasecols(void *cookie, int row, int col, int num, long attr)
-{
- struct rasops_info *ri = cookie;
- struct inteldrm_softc *sc = ri->ri_hw;
- struct drm_device *dev = (struct drm_device *)sc->drmdev;
- int bg, fg;
-
- if (dev->open_count > 0 || sc->noaccel)
- return sc->noaccel_erasecols(cookie, row, col, num, attr);
-
- ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
-
- row *= ri->ri_font->fontheight;
- col *= ri->ri_font->fontwidth;
- num *= ri->ri_font->fontwidth;
-
- inteldrm_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row,
- num, ri->ri_font->fontheight, ri->ri_devcmap[bg]);
-
- return 0;
-}
int
inteldrm_copyrows(void *cookie, int src, int dst, int num)
{
struct rasops_info *ri = cookie;
struct inteldrm_softc *sc = ri->ri_hw;
- struct drm_device *dev = (struct drm_device *)sc->drmdev;
-
- if (dev->open_count > 0 || sc->noaccel)
- return sc->noaccel_copyrows(cookie, src, dst, num);
-
- num *= ri->ri_font->fontheight;
- src *= ri->ri_font->fontheight;
- dst *= ri->ri_font->fontheight;
-
- inteldrm_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src,
- ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num);
-
- return 0;
-}
-
-int
-inteldrm_eraserows(void *cookie, int row, int num, long attr)
-{
- struct rasops_info *ri = cookie;
- struct inteldrm_softc *sc = ri->ri_hw;
- struct drm_device *dev = (struct drm_device *)sc->drmdev;
- int bg, fg;
- int x, y, w;
-
- if (dev->open_count > 0 || sc->noaccel)
- return sc->noaccel_eraserows(cookie, row, num, attr);
-
- ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
- if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) {
- num = ri->ri_height;
- x = y = 0;
- w = ri->ri_width;
- } else {
- num *= ri->ri_font->fontheight;
- x = ri->ri_xorigin;
- y = ri->ri_yorigin + row * ri->ri_font->fontheight;
- w = ri->ri_emuwidth;
- }
- inteldrm_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]);
-
- return 0;
-}
-
-void
-inteldrm_copyrect(struct inteldrm_softc *dev_priv, int sx, int sy,
- int dx, int dy, int w, int h)
-{
- struct drm_device *dev = (struct drm_device *)dev_priv->drmdev;
- bus_addr_t base = dev_priv->fbdev->ifb.obj->gtt_offset;
- uint32_t pitch = dev_priv->fbdev->ifb.base.pitches[0];
- struct intel_ring_buffer *ring;
- uint32_t seqno;
- int ret, i;
-
- if (HAS_BLT(dev))
- ring = &dev_priv->rings[BCS];
- else
- ring = &dev_priv->rings[RCS];
-
- ret = intel_ring_begin(ring, 8);
- if (ret)
- return;
-
- intel_ring_emit(ring, XY_SRC_COPY_BLT_CMD |
- XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB);
- intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_GXCOPY | pitch);
- intel_ring_emit(ring, (dx << 0) | (dy << 16));
- intel_ring_emit(ring, ((dx + w) << 0) | ((dy + h) << 16));
- intel_ring_emit(ring, base);
- intel_ring_emit(ring, (sx << 0) | (sy << 16));
- intel_ring_emit(ring, pitch);
- intel_ring_emit(ring, base);
- intel_ring_advance(ring);
-
- ret = ring->flush(ring, 0, I915_GEM_GPU_DOMAINS);
- if (ret)
- return;
-
- ret = i915_add_request(ring, NULL, &seqno);
- if (ret)
- return;
-
- for (i = 1000000; i != 0; i--) {
- if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
- break;
- DELAY(1);
- }
-
- i915_gem_retire_requests_ring(ring);
-}
-
-void
-inteldrm_fillrect(struct inteldrm_softc *dev_priv, int x, int y,
- int w, int h, int color)
-{
- struct drm_device *dev = (struct drm_device *)dev_priv->drmdev;
- bus_addr_t base = dev_priv->fbdev->ifb.obj->gtt_offset;
- uint32_t pitch = dev_priv->fbdev->ifb.base.pitches[0];
- struct intel_ring_buffer *ring;
- uint32_t seqno;
- int ret, i;
-
- if (HAS_BLT(dev))
- ring = &dev_priv->rings[BCS];
- else
- ring = &dev_priv->rings[RCS];
+ if (dst == 0 && (src + num) == ri->ri_rows) {
+ struct inteldrm_softc *dev_priv = sc;
+ struct drm_fb_helper *helper = &dev_priv->fbdev->helper;
+ size_t size = dev_priv->fbdev->ifb.obj->base.size / 2;
+ int delta = src * ri->ri_font->fontheight * ri->ri_stride;
+ int i;
- ret = intel_ring_begin(ring, 6);
- if (ret)
- return;
+ bzero(ri->ri_bits, delta);
-#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|4)
-#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
-#define XY_COLOR_BLT_WRITE_RGB (1<<20)
-#define BLT_ROP_PATCOPY (0xf0<<16)
-
- intel_ring_emit(ring, XY_COLOR_BLT_CMD |
- XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
- intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_PATCOPY | pitch);
- intel_ring_emit(ring, (x << 0) | (y << 16));
- intel_ring_emit(ring, ((x + w) << 0) | ((y + h) << 16));
- intel_ring_emit(ring, base);
- intel_ring_emit(ring, color);
- intel_ring_advance(ring);
-
- ret = ring->flush(ring, 0, I915_GEM_GPU_DOMAINS);
- if (ret)
- return;
+ sc->sc_offset += delta;
+ ri->ri_bits += delta;
+ ri->ri_origbits += delta;
+ if (sc->sc_offset > size) {
+ sc->sc_offset -= size;
+ ri->ri_bits -= size;
+ ri->ri_origbits -= size;
+ }
- ret = i915_add_request(ring, NULL, &seqno);
- if (ret)
- return;
+ for (i = 0; i < helper->crtc_count; i++) {
+ struct drm_mode_set *mode_set =
+ &helper->crtc_info[i].mode_set;
+ struct drm_crtc *crtc = mode_set->crtc;
+ struct drm_framebuffer *fb = helper->fb;
+
+ if (!crtc->enabled)
+ continue;
+
+ mode_set->x = (sc->sc_offset % ri->ri_stride) /
+ (ri->ri_depth / 8);
+ mode_set->y = sc->sc_offset / ri->ri_stride;
+ if (fb == crtc->fb)
+ dev_priv->display.update_plane(crtc, fb,
+ mode_set->x, mode_set->y);
+ }
- for (i = 1000000; i != 0; i--) {
- if (i915_seqno_passed(ring->get_seqno(ring, true), seqno))
- break;
- DELAY(1);
+ return 0;
}
- i915_gem_retire_requests_ring(ring);
+ return sc->sc_copyrows(cookie, src, dst, num);
}
void
@@ -1171,14 +1020,8 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux)
rasops_init(ri, 96, 132);
ri->ri_hw = dev_priv;
- dev_priv->noaccel_copyrows = ri->ri_copyrows;
- dev_priv->noaccel_copycols = ri->ri_copycols;
- dev_priv->noaccel_eraserows = ri->ri_eraserows;
- dev_priv->noaccel_erasecols = ri->ri_erasecols;
+ dev_priv->sc_copyrows = ri->ri_copyrows;
ri->ri_copyrows = inteldrm_copyrows;
- ri->ri_copycols = inteldrm_copycols;
- ri->ri_eraserows = inteldrm_eraserows;
- ri->ri_erasecols = inteldrm_erasecols;
inteldrm_stdscreen.capabilities = ri->ri_caps;
inteldrm_stdscreen.nrows = ri->ri_rows;
@@ -1202,6 +1045,8 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux)
aa.console = 1;
}
+ printf("%s: %dx%d\n", dev_priv->dev.dv_xname, ri->ri_width, ri->ri_height);
+
vga_sc->sc_type = -1;
config_found(parent, &aa, wsemuldisplaydevprint);
}
@@ -1257,7 +1102,6 @@ inteldrm_activate(struct device *arg, int act)
switch (act) {
case DVACT_QUIESCE:
// inteldrm_quiesce(dev_priv);
- dev_priv->noaccel = 1;
i915_drm_freeze(dev);
break;
case DVACT_SUSPEND:
@@ -1270,7 +1114,6 @@ inteldrm_activate(struct device *arg, int act)
// wakeup(&dev_priv->flags);
i915_drm_thaw(dev);
intel_fb_restore_mode(dev);
- dev_priv->noaccel = 0;
break;
}
diff --git a/sys/dev/pci/drm/i915/i915_drv.h b/sys/dev/pci/drm/i915/i915_drv.h
index c3a6f99ffa6..bf35b7d46a7 100644
--- a/sys/dev/pci/drm/i915/i915_drv.h
+++ b/sys/dev/pci/drm/i915/i915_drv.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: i915_drv.h,v 1.12 2013/04/03 07:36:57 jsg Exp $ */
+/* $OpenBSD: i915_drv.h,v 1.13 2013/04/14 19:04:37 kettenis Exp $ */
/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
*/
/*
@@ -512,11 +512,8 @@ struct inteldrm_softc {
struct workq_task switchwqt;
struct rasops_info ro;
- int noaccel;
- int (*noaccel_copycols)(void *, int, int, int, int);
- int (*noaccel_erasecols)(void *, int, int, int, long);
- int (*noaccel_copyrows)(void *, int, int, int);
- int (*noaccel_eraserows)(void *, int, int, long);
+ int sc_offset;
+ int (*sc_copyrows)(void *, int, int, int);
uint32_t gpio_mmio_base;
diff --git a/sys/dev/pci/drm/i915/intel_fb.c b/sys/dev/pci/drm/i915/intel_fb.c
index d415bb82509..dc0f448deba 100644
--- a/sys/dev/pci/drm/i915/intel_fb.c
+++ b/sys/dev/pci/drm/i915/intel_fb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intel_fb.c,v 1.2 2013/03/19 03:58:10 jsg Exp $ */
+/* $OpenBSD: intel_fb.c,v 1.3 2013/04/14 19:04:37 kettenis Exp $ */
/*
* Copyright © 2007 David Airlie
*
@@ -66,13 +66,14 @@ intelfb_create(struct intel_fbdev *ifbdev,
sizes->surface_depth);
size = mode_cmd.pitches[0] * mode_cmd.height;
- size = roundup2(size, PAGE_SIZE);
+ size = roundup2(size, PAGE_SIZE) * 2;
obj = i915_gem_alloc_object(dev, size);
if (!obj) {
DRM_ERROR("failed to allocate framebuffer\n");
ret = -ENOMEM;
goto out;
}
+ obj->dma_flags |= BUS_DMA_GTT_WRAPAROUND;
DRM_LOCK();