diff options
-rw-r--r-- | sys/dev/pci/agpvar.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 18 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 231 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.h | 9 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/intel_fb.c | 5 |
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(); |