Sat Oct 17 21:18:16 2015 UTC ()
Add bus glue for attaching nouveau DRM


(jmcneill)
diff -r1.16 -r1.17 src/sys/arch/arm/nvidia/files.tegra
diff -r1.13 -r1.14 src/sys/arch/arm/nvidia/tegra_io.c
diff -r0 -r1.1 src/sys/arch/arm/nvidia/tegra_nouveau.c

cvs diff -r1.16 -r1.17 src/sys/arch/arm/nvidia/files.tegra (expand / switch to unified diff)

--- src/sys/arch/arm/nvidia/files.tegra 2015/08/22 15:10:04 1.16
+++ src/sys/arch/arm/nvidia/files.tegra 2015/10/17 21:18:16 1.17
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: files.tegra,v 1.16 2015/08/22 15:10:04 jmcneill Exp $ 1# $NetBSD: files.tegra,v 1.17 2015/10/17 21:18:16 jmcneill Exp $
2# 2#
3# Configuration info for NVIDIA Tegra ARM Peripherals 3# Configuration info for NVIDIA Tegra ARM Peripherals
4# 4#
5 5
6include "arch/arm/pic/files.pic" 6include "arch/arm/pic/files.pic"
7include "arch/arm/cortex/files.cortex" 7include "arch/arm/cortex/files.cortex"
8 8
9file arch/arm/arm32/arm32_boot.c 9file arch/arm/arm32/arm32_boot.c
10file arch/arm/arm32/arm32_kvminit.c 10file arch/arm/arm32/arm32_kvminit.c
11file arch/arm/arm32/arm32_reboot.c 11file arch/arm/arm32/arm32_reboot.c
12file arch/arm/arm32/irq_dispatch.S 12file arch/arm/arm32/irq_dispatch.S
13file arch/arm/arm32/armv7_generic_space.c 13file arch/arm/arm32/armv7_generic_space.c
14file arch/arm/arm/bus_space_a4x.S 14file arch/arm/arm/bus_space_a4x.S
@@ -106,26 +106,30 @@ file arch/arm/nvidia/tegra_dc.c tegra_d @@ -106,26 +106,30 @@ file arch/arm/nvidia/tegra_dc.c tegra_d
106attach genfb at tegradc with tegra_genfb 106attach genfb at tegradc with tegra_genfb
107file arch/arm/nvidia/tegra_genfb.c tegra_genfb 107file arch/arm/nvidia/tegra_genfb.c tegra_genfb
108 108
109# HDMI 109# HDMI
110device tegrahdmi: edid, ddc_read_edid, videomode 110device tegrahdmi: edid, ddc_read_edid, videomode
111attach tegrahdmi at tegraio with tegra_hdmi 111attach tegrahdmi at tegraio with tegra_hdmi
112file arch/arm/nvidia/tegra_hdmi.c tegra_hdmi 112file arch/arm/nvidia/tegra_hdmi.c tegra_hdmi
113 113
114# HDMI CEC 114# HDMI CEC
115device tegracec: hdmicecbus 115device tegracec: hdmicecbus
116attach tegracec at tegraio with tegra_cec 116attach tegracec at tegraio with tegra_cec
117file arch/arm/nvidia/tegra_cec.c tegra_cec 117file arch/arm/nvidia/tegra_cec.c tegra_cec
118 118
 119# GPU
 120attach nouveau at tegraio with tegra_nouveau
 121file arch/arm/nvidia/tegra_nouveau.c tegra_nouveau
 122
119# Console parameters 123# Console parameters
120defparam opt_tegra.h CONADDR 124defparam opt_tegra.h CONADDR
121defparam opt_tegra.h CONSPEED 125defparam opt_tegra.h CONSPEED
122defparam opt_tegra.h CONMODE 126defparam opt_tegra.h CONMODE
123 127
124# Memory parameters 128# Memory parameters
125defparam opt_tegra.h MEMSIZE 129defparam opt_tegra.h MEMSIZE
126 130
127# CPU parameters 131# CPU parameters
128defparam opt_tegra.h CPUFREQ_BOOT 132defparam opt_tegra.h CPUFREQ_BOOT
129 133
130# SOC parameters 134# SOC parameters
131defflag opt_tegra.h SOC_TEGRAK1 135defflag opt_tegra.h SOC_TEGRAK1

cvs diff -r1.13 -r1.14 src/sys/arch/arm/nvidia/Attic/tegra_io.c (expand / switch to unified diff)

--- src/sys/arch/arm/nvidia/Attic/tegra_io.c 2015/08/01 21:20:11 1.13
+++ src/sys/arch/arm/nvidia/Attic/tegra_io.c 2015/10/17 21:18:16 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tegra_io.c,v 1.13 2015/08/01 21:20:11 jmcneill Exp $ */ 1/* $NetBSD: tegra_io.c,v 1.14 2015/10/17 21:18:16 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -19,27 +19,27 @@ @@ -19,27 +19,27 @@
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_tegra.h" 29#include "opt_tegra.h"
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.13 2015/08/01 21:20:11 jmcneill Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: tegra_io.c,v 1.14 2015/10/17 21:18:16 jmcneill Exp $");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/systm.h> 35#include <sys/systm.h>
36#include <sys/device.h> 36#include <sys/device.h>
37 37
38#include <machine/cpu.h> 38#include <machine/cpu.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40 40
41#include <arm/mainbus/mainbus.h> 41#include <arm/mainbus/mainbus.h>
42#include <arm/nvidia/tegra_reg.h> 42#include <arm/nvidia/tegra_reg.h>
43#include <arm/nvidia/tegra_var.h> 43#include <arm/nvidia/tegra_var.h>
44 44
45#include "locators.h" 45#include "locators.h"
@@ -134,26 +134,30 @@ static const struct tegra_locators tegra @@ -134,26 +134,30 @@ static const struct tegra_locators tegra
134static const struct tegra_locators tegra_host1x_locators[] = { 134static const struct tegra_locators tegra_host1x_locators[] = {
135 { "tegrahost1x", 0, TEGRA_HOST1X_SIZE, NOPORT, NOINTR } 135 { "tegrahost1x", 0, TEGRA_HOST1X_SIZE, NOPORT, NOINTR }
136}; 136};
137 137
138static const struct tegra_locators tegra_ghost_locators[] = { 138static const struct tegra_locators tegra_ghost_locators[] = {
139 { "tegradc", 139 { "tegradc",
140 TEGRA_DISPLAYA_OFFSET, TEGRA_DISPLAYA_SIZE, 0, TEGRA_INTR_DISPLAYA }, 140 TEGRA_DISPLAYA_OFFSET, TEGRA_DISPLAYA_SIZE, 0, TEGRA_INTR_DISPLAYA },
141 { "tegradc", 141 { "tegradc",
142 TEGRA_DISPLAYB_OFFSET, TEGRA_DISPLAYB_SIZE, 1, TEGRA_INTR_DISPLAYB }, 142 TEGRA_DISPLAYB_OFFSET, TEGRA_DISPLAYB_SIZE, 1, TEGRA_INTR_DISPLAYB },
143 { "tegrahdmi", 143 { "tegrahdmi",
144 TEGRA_HDMI_OFFSET, TEGRA_HDMI_SIZE, NOPORT, TEGRA_INTR_HDMI }, 144 TEGRA_HDMI_OFFSET, TEGRA_HDMI_SIZE, NOPORT, TEGRA_INTR_HDMI },
145}; 145};
146 146
 147static const struct tegra_locators tegra_gpu_locators[] = {
 148 { "nouveau", 0, TEGRA_GPU_SIZE, NOPORT, NOINTR }
 149};
 150
147int 151int
148tegraio_match(device_t parent, cfdata_t cf, void *aux) 152tegraio_match(device_t parent, cfdata_t cf, void *aux)
149{ 153{
150 if (tegraio_found) 154 if (tegraio_found)
151 return 0; 155 return 0;
152 return 1; 156 return 1;
153} 157}
154 158
155void 159void
156tegraio_attach(device_t parent, device_t self, void *aux) 160tegraio_attach(device_t parent, device_t self, void *aux)
157{ 161{
158 tegraio_found = true; 162 tegraio_found = true;
159 163
@@ -161,26 +165,28 @@ tegraio_attach(device_t parent, device_t @@ -161,26 +165,28 @@ tegraio_attach(device_t parent, device_t
161 aprint_normal(": %s\n", tegra_chip_name()); 165 aprint_normal(": %s\n", tegra_chip_name());
162 166
163 tegraio_scan(self, tegra_ppsb_bsh, 167 tegraio_scan(self, tegra_ppsb_bsh,
164 tegra_ppsb_locators, __arraycount(tegra_ppsb_locators)); 168 tegra_ppsb_locators, __arraycount(tegra_ppsb_locators));
165 tegraio_scan(self, tegra_apb_bsh, 169 tegraio_scan(self, tegra_apb_bsh,
166 tegra_apb_locators, __arraycount(tegra_apb_locators)); 170 tegra_apb_locators, __arraycount(tegra_apb_locators));
167 tegraio_scan(self, tegra_ahb_a2_bsh, 171 tegraio_scan(self, tegra_ahb_a2_bsh,
168 tegra_ahb_a2_locators, __arraycount(tegra_ahb_a2_locators)); 172 tegra_ahb_a2_locators, __arraycount(tegra_ahb_a2_locators));
169 tegraio_scan(self, (bus_space_handle_t)NULL, 173 tegraio_scan(self, (bus_space_handle_t)NULL,
170 tegra_host1x_locators, __arraycount(tegra_host1x_locators)); 174 tegra_host1x_locators, __arraycount(tegra_host1x_locators));
171 tegraio_scan(self, (bus_space_handle_t)NULL, 175 tegraio_scan(self, (bus_space_handle_t)NULL,
172 tegra_ghost_locators, __arraycount(tegra_ghost_locators)); 176 tegra_ghost_locators, __arraycount(tegra_ghost_locators));
173 tegraio_scan(self, (bus_space_handle_t)NULL, 177 tegraio_scan(self, (bus_space_handle_t)NULL,
 178 tegra_gpu_locators, __arraycount(tegra_gpu_locators));
 179 tegraio_scan(self, (bus_space_handle_t)NULL,
174 tegra_pcie_locators, __arraycount(tegra_pcie_locators)); 180 tegra_pcie_locators, __arraycount(tegra_pcie_locators));
175} 181}
176 182
177static void 183static void
178tegraio_scan(device_t self, bus_space_handle_t bsh, 184tegraio_scan(device_t self, bus_space_handle_t bsh,
179 const struct tegra_locators *locators, u_int count) 185 const struct tegra_locators *locators, u_int count)
180{ 186{
181 const struct tegra_locators * const eloc = locators + count; 187 const struct tegra_locators * const eloc = locators + count;
182 for (const struct tegra_locators *loc = locators; loc < eloc; loc++) { 188 for (const struct tegra_locators *loc = locators; loc < eloc; loc++) {
183 struct tegraio_attach_args tio = { 189 struct tegraio_attach_args tio = {
184 .tio_loc = *loc, 190 .tio_loc = *loc,
185 .tio_bst = &armv7_generic_bs_tag, 191 .tio_bst = &armv7_generic_bs_tag,
186 .tio_a4x_bst = &armv7_generic_a4x_bs_tag, 192 .tio_a4x_bst = &armv7_generic_a4x_bs_tag,

File Added: src/sys/arch/arm/nvidia/tegra_nouveau.c
/* $NetBSD: tegra_nouveau.c,v 1.1 2015/10/17 21:18:16 jmcneill Exp $ */

/*-
 * Copyright (c) 2015 Jared D. McNeill <jmcneill@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);
}