Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/riastradh-drm2]: src/sys/external/bsd/drm2 Add local drm_memory.c to imp...
details: https://anonhg.NetBSD.org/src/rev/1e9f9c959dad
branches: riastradh-drm2
changeset: 788131:1e9f9c959dad
user: riastradh <riastradh%NetBSD.org@localhost>
date: Wed Jul 24 02:23:06 2013 +0000
description:
Add local drm_memory.c to implement drm_ioremap and drm_iounmap.
diffstat:
sys/external/bsd/drm2/dist/include/drm/drmP.h | 27 +++
sys/external/bsd/drm2/drm/drm_memory.c | 218 ++++++++++++++++++++++++++
2 files changed, 245 insertions(+), 0 deletions(-)
diffs (273 lines):
diff -r 07dc551e2fc3 -r 1e9f9c959dad sys/external/bsd/drm2/dist/include/drm/drmP.h
--- a/sys/external/bsd/drm2/dist/include/drm/drmP.h Wed Jul 24 02:22:43 2013 +0000
+++ b/sys/external/bsd/drm2/dist/include/drm/drmP.h Wed Jul 24 02:23:06 2013 +0000
@@ -610,6 +610,19 @@
struct drm_hw_lock *lock;
};
+#ifdef __NetBSD__
+/*
+ * XXX Remember: memory mappings only. bm_flags must include
+ * BUS_SPACE_MAP_LINEAR.
+ */
+struct drm_bus_map {
+ bus_addr_t bm_base;
+ bus_size_t bm_size;
+ bus_space_handle_t bm_bsh;
+ int bm_flags;
+ unsigned int bm_mapped;
+};
+#endif
/**
* Kernel side of a mapping
@@ -622,6 +635,11 @@
void *handle; /**< User-space: "Handle" to pass to mmap() */
/**< Kernel-space: kernel-virtual address */
int mtrr; /**< MTRR slot used */
+
+#ifdef __NetBSD__
+ bus_space_handle_t bsh;
+ struct drm_bus_map *bus_map;
+#endif
};
typedef struct drm_local_map drm_local_map_t;
@@ -1255,6 +1273,15 @@
struct platform_device *platformdev; /**< Platform device struture */
struct usb_device *usbdev;
+#ifdef __NetBSD__
+ bus_space_tag_t bst;
+ struct drm_bus_map *bus_maps;
+ size_t bus_nmaps;
+ /* XXX What does this have to do with AGP? */
+ struct drm_bus_map *agp_maps;
+ size_t agp_nmaps;
+#endif
+
struct drm_sg_mem *sg; /**< Scatter gather memory */
unsigned int num_crtcs; /**< Number of CRTCs on this device */
void *dev_private; /**< device private data */
diff -r 07dc551e2fc3 -r 1e9f9c959dad sys/external/bsd/drm2/drm/drm_memory.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/drm/drm_memory.c Wed Jul 24 02:23:06 2013 +0000
@@ -0,0 +1,218 @@
+/* $NetBSD: drm_memory.c,v 1.1.2.1 2013/07/24 02:23:06 riastradh Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: drm_memory.c,v 1.1.2.1 2013/07/24 02:23:06 riastradh Exp $");
+
+/* XXX Cargo-culted from the old drm_memory.c. */
+
+#ifdef _KERNEL_OPT
+#include "agp_i810.h"
+#include "genfb.h"
+#else
+#define NAGP_I810 1 /* XXX WTF? */
+#define NGENFB 0 /* XXX WTF? */
+#endif
+
+#include <sys/bus.h>
+
+#if NAGP_I810 > 0
+/* XXX include order botch -- shouldn't need to include pcivar.h */
+#include <dev/pci/pcivar.h>
+#include <dev/pci/agpvar.h>
+#endif
+
+#if NGENFB > 0
+#include <dev/wsfb/genfbvar.h>
+#endif
+
+#include <drm/drmP.h>
+
+/*
+ * XXX drm_bus_borrow is a horrible kludge!
+ */
+static bool
+drm_bus_borrow(bus_addr_t base, bus_space_handle_t *handlep)
+{
+
+#if NAGP_I810 > 0
+ if (agp_i810_borrow(base, handlep))
+ return true;
+#endif
+
+#if NGENFB > 0
+ if (genfb_borrow(base, handlep))
+ return true;
+#endif
+
+ return false;
+}
+
+void *
+drm_ioremap(struct drm_device *dev, struct drm_local_map *map)
+{
+ const bus_space_tag_t bst = dev->bst;
+ unsigned int unit;
+ int error;
+
+ /*
+ * Search dev's bus maps for a match.
+ */
+ for (unit = 0; unit < dev->bus_nmaps; unit++) {
+ struct drm_bus_map *const bm = &dev->bus_maps[unit];
+
+ /* Reject maps starting after the request. */
+ if (map->offset < bm->bm_base)
+ continue;
+
+ /* Reject maps smaller than the request. */
+ if (bm->bm_size < map->size)
+ continue;
+
+ /*
+ * Reject maps that the request doesn't fit in. (Make
+ * sure to avoid integer overflow.)
+ */
+ if ((bm->bm_size - map->size) <
+ (map->offset - bm->bm_base))
+ continue;
+
+ /* Has it been mapped yet? If not, map it. */
+ if (bm->bm_mapped == 0) {
+ KASSERT(ISSET(bm->bm_flags, BUS_SPACE_MAP_LINEAR));
+ error = bus_space_map(bst, bm->bm_base,
+ bm->bm_size, bm->bm_flags, &bm->bm_bsh);
+ if (error) {
+ if (drm_bus_borrow(map->offset, &map->bsh)) {
+ map->bus_map = NULL;
+ goto win;
+ }
+ return NULL;
+ }
+ }
+
+ /* Mark it used and make a subregion just for the request. */
+ bm->bm_mapped++;
+ error = bus_space_subregion(bst, bm->bm_bsh,
+ map->offset - bm->bm_base, map->size, &map->bsh);
+ if (error) {
+ /*
+ * Back out: unmark it and, if nobody else was
+ * using it, unmap it.
+ */
+ if (--bm->bm_mapped == 0)
+ bus_space_unmap(bst, bm->bm_bsh,
+ bm->bm_size);
+ return NULL;
+ }
+
+ /* Got it! */
+ map->bus_map = bm;
+ goto win;
+ }
+
+ /*
+ * No dice. Try mapping it directly ourselves.
+ *
+ * XXX Is this sensible? What prevents us from clobbering some
+ * existing map? And what does this have to do with agp?
+ */
+ for (unit = 0; unit < dev->agp_nmaps; unit++) {
+ struct drm_bus_map *const bm = &dev->agp_maps[unit];
+
+ /* Is this one allocated? */
+ if (bm->bm_mapped > 0) {
+ /*
+ * Make sure it has the same base.
+ *
+ * XXX Why must it be the same base? Can't we
+ * subregion here too?
+ */
+ if (bm->bm_base != map->offset)
+ continue;
+
+ /* Make sure it's big enough. */
+ if (bm->bm_size < map->size)
+ continue;
+
+ /* Mark it used and return it. */
+ bm->bm_mapped++;
+
+ /* XXX size is an input/output parameter too...? */
+ map->size = bm->bm_size;
+
+ map->bsh = bm->bm_bsh;
+ map->bus_map = bm;
+ goto win;
+ } else {
+ const int flags = BUS_SPACE_MAP_PREFETCHABLE |
+ BUS_SPACE_MAP_LINEAR;
+
+ /* Try mapping the request. */
+ error = bus_space_map(bst, map->offset, map->size,
+ flags, &bm->bm_bsh);
+ if (error)
+ return NULL; /* XXX Why not continue? */
+
+ /* Got it. Allocate this bus map. */
+ bm->bm_mapped++;
+ bm->bm_base = map->offset;
+ bm->bm_size = map->size;
+ bm->bm_flags = flags; /* XXX What for? */
+
+ map->bsh = bm->bm_bsh;
+ map->bus_map = bm;
+ goto win;
+ }
+ }
+
+ return NULL;
+
+win:
+ return bus_space_vaddr(bst, map->bsh);
+}
+
+void
+drm_iounmap(struct drm_device *dev, struct drm_local_map *map)
+{
+ const bus_space_tag_t bst = dev->bst;
+ struct drm_bus_map *const bm = map->bus_map;
+
+ /*
+ * bm may be null if we have committed the horrible deed of
+ * borrowing from agp_i810 or genfb.
+ */
+ if (bm != NULL) {
+ KASSERT(bm->bm_mapped > 0);
+ if (--bm->bm_mapped)
+ bus_space_unmap(bst, bm->bm_bsh, bm->bm_size);
+ }
+}
Home |
Main Index |
Thread Index |
Old Index