Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/nvidia Add bus glue for attaching nouveau DRM
details: https://anonhg.NetBSD.org/src/rev/0a19075b9f17
branches: trunk
changeset: 341088:0a19075b9f17
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Oct 17 21:18:16 2015 +0000
description:
Add bus glue for attaching nouveau DRM
diffstat:
sys/arch/arm/nvidia/files.tegra | 6 +-
sys/arch/arm/nvidia/tegra_io.c | 10 +-
sys/arch/arm/nvidia/tegra_nouveau.c | 225 ++++++++++++++++++++++++++++++++++++
3 files changed, 238 insertions(+), 3 deletions(-)
diffs (287 lines):
diff -r c8756e7f2ffd -r 0a19075b9f17 sys/arch/arm/nvidia/files.tegra
--- a/sys/arch/arm/nvidia/files.tegra Sat Oct 17 21:17:15 2015 +0000
+++ b/sys/arch/arm/nvidia/files.tegra Sat Oct 17 21:18:16 2015 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.tegra,v 1.16 2015/08/22 15:10:04 jmcneill Exp $
+# $NetBSD: files.tegra,v 1.17 2015/10/17 21:18:16 jmcneill Exp $
#
# Configuration info for NVIDIA Tegra ARM Peripherals
#
@@ -116,6 +116,10 @@
attach tegracec at tegraio with tegra_cec
file arch/arm/nvidia/tegra_cec.c tegra_cec
+# GPU
+attach nouveau at tegraio with tegra_nouveau
+file arch/arm/nvidia/tegra_nouveau.c tegra_nouveau
+
# Console parameters
defparam opt_tegra.h CONADDR
defparam opt_tegra.h CONSPEED
diff -r c8756e7f2ffd -r 0a19075b9f17 sys/arch/arm/nvidia/tegra_io.c
--- a/sys/arch/arm/nvidia/tegra_io.c Sat Oct 17 21:17:15 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_io.c Sat Oct 17 21:18:16 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_io.c,v 1.13 2015/08/01 21:20:11 jmcneill Exp $ */
+/* $NetBSD: tegra_io.c,v 1.14 2015/10/17 21:18:16 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_tegra.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.13 2015/08/01 21:20:11 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.14 2015/10/17 21:18:16 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -144,6 +144,10 @@
TEGRA_HDMI_OFFSET, TEGRA_HDMI_SIZE, NOPORT, TEGRA_INTR_HDMI },
};
+static const struct tegra_locators tegra_gpu_locators[] = {
+ { "nouveau", 0, TEGRA_GPU_SIZE, NOPORT, NOINTR }
+};
+
int
tegraio_match(device_t parent, cfdata_t cf, void *aux)
{
@@ -171,6 +175,8 @@
tegraio_scan(self, (bus_space_handle_t)NULL,
tegra_ghost_locators, __arraycount(tegra_ghost_locators));
tegraio_scan(self, (bus_space_handle_t)NULL,
+ tegra_gpu_locators, __arraycount(tegra_gpu_locators));
+ tegraio_scan(self, (bus_space_handle_t)NULL,
tegra_pcie_locators, __arraycount(tegra_pcie_locators));
}
diff -r c8756e7f2ffd -r 0a19075b9f17 sys/arch/arm/nvidia/tegra_nouveau.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/nvidia/tegra_nouveau.c Sat Oct 17 21:18:16 2015 +0000
@@ -0,0 +1,225 @@
+/* $NetBSD: tegra_nouveau.c,v 1.1 2015/10/17 21:18:16 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * 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 AUTHOR ``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 AUTHOR 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 "locators.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: tegra_nouveau.c,v 1.1 2015/10/17 21:18:16 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <arm/nvidia/tegra_reg.h>
+#include <arm/nvidia/tegra_var.h>
+
+#include <drm/drmP.h>
+#include <engine/device.h>
+
+extern char *nouveau_config;
+extern char *nouveau_debug;
+extern struct drm_driver *const nouveau_drm_driver;
+
+static int tegra_nouveau_match(device_t, cfdata_t, void *);
+static void tegra_nouveau_attach(device_t, device_t, void *);
+
+struct tegra_nouveau_softc {
+ device_t sc_dev;
+ struct drm_device *sc_drm_dev;
+ struct platform_device sc_platform_dev;
+ struct nouveau_device *sc_nv_dev;
+};
+
+static int tegra_nouveau_init(struct tegra_nouveau_softc *);
+
+static int tegra_nouveau_get_irq(struct drm_device *);
+static const char *tegra_nouveau_get_name(struct drm_device *);
+static int tegra_nouveau_set_busid(struct drm_device *,
+ struct drm_master *);
+static int tegra_nouveau_irq_install(struct drm_device *,
+ irqreturn_t (*)(void *),
+ int, const char *, void *,
+ struct drm_bus_irq_cookie **);
+static void tegra_nouveau_irq_uninstall(struct drm_device *,
+ struct drm_bus_irq_cookie *);
+
+static struct drm_bus drm_tegra_nouveau_bus = {
+ .bus_type = DRIVER_BUS_PLATFORM,
+ .get_irq = tegra_nouveau_get_irq,
+ .get_name = tegra_nouveau_get_name,
+ .set_busid = tegra_nouveau_set_busid,
+ .irq_install = tegra_nouveau_irq_install,
+ .irq_uninstall = tegra_nouveau_irq_uninstall
+};
+
+CFATTACH_DECL_NEW(tegra_nouveau, sizeof(struct tegra_nouveau_softc),
+ tegra_nouveau_match, tegra_nouveau_attach, NULL, NULL);
+
+static int
+tegra_nouveau_match(device_t parent, cfdata_t cf, void *aux)
+{
+ return 1;
+}
+
+static void
+tegra_nouveau_attach(device_t parent, device_t self, void *aux)
+{
+ struct tegra_nouveau_softc * const sc = device_private(self);
+#if notyet
+ struct tegraio_attach_args * const tio = aux;
+ const struct tegra_locators * const loc = &tio->tio_loc;
+#endif
+ int error;
+
+ sc->sc_dev = self;
+#if notyet
+ sc->sc_bst = tio->tio_bst;
+ bus_space_subregion(tio->tio_bst, tio->tio_bsh,
+ loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+#endif
+
+ aprint_naive("\n");
+ aprint_normal(": GPU\n");
+
+ tegra_car_gpu_enable();
+
+ error = -nouveau_device_create(&sc->sc_platform_dev,
+ NOUVEAU_BUS_PLATFORM, -1, device_xname(self),
+ nouveau_config, nouveau_debug, &sc->sc_nv_dev);
+ if (error) {
+ aprint_error_dev(self, "couldn't create nouveau device: %d\n",
+ error);
+ return;
+ }
+
+ error = tegra_nouveau_init(sc);
+ if (error) {
+ aprint_error_dev(self, "couldn't attach drm: %d\n", error);
+ return;
+ }
+}
+
+static int
+tegra_nouveau_init(struct tegra_nouveau_softc *sc)
+{
+ struct drm_driver * const driver = nouveau_drm_driver;
+ struct drm_device *dev;
+ bus_space_tag_t bst = &armv7_generic_bs_tag;
+ int error;
+
+ driver->kdriver.platform_device = &sc->sc_platform_dev;
+ driver->bus = &drm_tegra_nouveau_bus;
+
+ dev = drm_dev_alloc(driver, sc->sc_dev);
+ if (dev == NULL)
+ return ENOMEM;
+ dev->platformdev = &sc->sc_platform_dev;
+
+ dev->platformdev->id = -1;
+ dev->platformdev->nresource = 2;
+ dev->platformdev->resource[0].tag = bst;
+ dev->platformdev->resource[0].start = TEGRA_GPU_BASE;
+ dev->platformdev->resource[0].len = 0x01000000;
+ dev->platformdev->resource[1].tag = bst;
+ dev->platformdev->resource[1].start = TEGRA_GPU_BASE +
+ dev->platformdev->resource[0].len;
+ dev->platformdev->resource[1].len = 0x01000000;
+
+ error = -drm_dev_register(dev, 0);
+ if (error) {
+ drm_dev_unref(dev);
+ Debugger();
+ return error;
+ }
+
+ device_printf(sc->sc_dev, "initialized %s %d.%d.%d %s on minor %d\n",
+ driver->name, driver->major, driver->minor, driver->patchlevel,
+ driver->date, dev->primary->index);
+
+ return 0;
+}
+
+static int
+tegra_nouveau_get_irq(struct drm_device *dev)
+{
+ return TEGRA_INTR_GPU;
+}
+
+static const char *tegra_nouveau_get_name(struct drm_device *dev)
+{
+ return "tegra_nouveau";
+}
+
+static int
+tegra_nouveau_set_busid(struct drm_device *dev, struct drm_master *master)
+{
+ int id;
+
+ id = dev->platformdev->id;
+ if (id < 0)
+ id = 0;
+
+ master->unique = kmem_asprintf("platform:tegra_nouveau:%02d", id);
+ if (master->unique == NULL)
+ return -ENOMEM;
+ master->unique_len = strlen(master->unique);
+
+ return 0;
+}
+
+static int
+tegra_nouveau_irq_install(struct drm_device *dev,
+ irqreturn_t (*handler)(void *), int flags, const char *name, void *arg,
+ struct drm_bus_irq_cookie **cookiep)
+{
+ void *ih;
+ int irq = TEGRA_INTR_GPU;
+
+ ih = intr_establish(irq, IPL_DRM, IST_LEVEL, handler, arg);
+ if (ih == NULL) {
+ aprint_error_dev(dev->dev,
+ "couldn't establish interrupt (%s)\n", name);
+ return -ENOENT;
+ }
+
+ aprint_normal_dev(dev->dev, "interrupting on irq %d (%s)\n",
+ irq, name);
+ *cookiep = (struct drm_bus_irq_cookie *)ih;
+ return 0;
+}
+
+static void
+tegra_nouveau_irq_uninstall(struct drm_device *dev,
+ struct drm_bus_irq_cookie *cookie)
+{
+ intr_disestablish(cookie);
+}
Home |
Main Index |
Thread Index |
Old Index