Module Name:    src
Committed By:   jmcneill
Date:           Sat Oct 17 21:18:16 UTC 2015

Modified Files:
        src/sys/arch/arm/nvidia: files.tegra tegra_io.c
Added Files:
        src/sys/arch/arm/nvidia: tegra_nouveau.c

Log Message:
Add bus glue for attaching nouveau DRM


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/nvidia/files.tegra
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/nvidia/tegra_io.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/nvidia/tegra_nouveau.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/nvidia/files.tegra
diff -u src/sys/arch/arm/nvidia/files.tegra:1.16 src/sys/arch/arm/nvidia/files.tegra:1.17
--- src/sys/arch/arm/nvidia/files.tegra:1.16	Sat Aug 22 15:10:04 2015
+++ src/sys/arch/arm/nvidia/files.tegra	Sat Oct 17 21:18:16 2015
@@ -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 @@ device	tegracec: hdmicecbus
 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

Index: src/sys/arch/arm/nvidia/tegra_io.c
diff -u src/sys/arch/arm/nvidia/tegra_io.c:1.13 src/sys/arch/arm/nvidia/tegra_io.c:1.14
--- src/sys/arch/arm/nvidia/tegra_io.c:1.13	Sat Aug  1 21:20:11 2015
+++ src/sys/arch/arm/nvidia/tegra_io.c	Sat Oct 17 21:18:16 2015
@@ -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 <jmcne...@invisible.ca>
@@ -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 @@ static const struct tegra_locators tegra
     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_attach(device_t parent, device_t
 	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));
 }
 

Added files:

Index: src/sys/arch/arm/nvidia/tegra_nouveau.c
diff -u /dev/null src/sys/arch/arm/nvidia/tegra_nouveau.c:1.1
--- /dev/null	Sat Oct 17 21:18:16 2015
+++ src/sys/arch/arm/nvidia/tegra_nouveau.c	Sat Oct 17 21:18:16 2015
@@ -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 <jmcne...@invisible.ca>
+ * 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);
+}

Reply via email to