Module Name:    src
Committed By:   riastradh
Date:           Fri Mar  6 01:43:07 UTC 2015

Modified Files:
        src/sys/external/bsd/drm2/dist/drm/nouveau: nouveau_bo.h nouveau_drm.c
            nouveau_fbcon.c nouveau_vga.h
        src/sys/external/bsd/drm2/include/linux: pci.h reboot.h
        src/sys/external/bsd/drm2/nouveau: files.nouveau
        src/sys/external/bsd/drm2/pci: drm_pci.c
Added Files:
        src/sys/external/bsd/drm2/nouveau: nouveau_pci.c nouveau_pci.h
            nouveau_sysfs.c nouveau_vga.c nouveaufb.c nouveaufb.h

Log Message:
One last round for nouveau.  It links!


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.h
cvs rdiff -u -r1.3 -r1.4 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
cvs rdiff -u -r1.1.1.2 -r1.2 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c
cvs rdiff -u -r1.1.1.1 -r1.2 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_vga.h
cvs rdiff -u -r1.14 -r1.15 src/sys/external/bsd/drm2/include/linux/pci.h
cvs rdiff -u -r1.1 -r1.2 src/sys/external/bsd/drm2/include/linux/reboot.h
cvs rdiff -u -r1.7 -r1.8 src/sys/external/bsd/drm2/nouveau/files.nouveau
cvs rdiff -u -r0 -r1.1 src/sys/external/bsd/drm2/nouveau/nouveau_pci.c \
    src/sys/external/bsd/drm2/nouveau/nouveau_pci.h \
    src/sys/external/bsd/drm2/nouveau/nouveau_sysfs.c \
    src/sys/external/bsd/drm2/nouveau/nouveau_vga.c \
    src/sys/external/bsd/drm2/nouveau/nouveaufb.c \
    src/sys/external/bsd/drm2/nouveau/nouveaufb.h
cvs rdiff -u -r1.10 -r1.11 src/sys/external/bsd/drm2/pci/drm_pci.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/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.h
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.h:1.2 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.h:1.3
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.h:1.2	Wed Aug  6 13:35:13 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.h	Fri Mar  6 01:43:07 2015
@@ -1,8 +1,12 @@
 #ifndef __NOUVEAU_BO_H__
 #define __NOUVEAU_BO_H__
 
+#include <ttm/ttm_bo_api.h>
+
 struct nouveau_channel;
+struct nouveau_drm;
 struct nouveau_fence;
+struct nouveau_vm;
 struct nouveau_vma;
 
 struct nouveau_bo {

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.3 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.4
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c:1.3	Sat Aug 23 08:03:33 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c	Fri Mar  6 01:43:07 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_drm.c,v 1.3 2014/08/23 08:03:33 riastradh Exp $	*/
+/*	$NetBSD: nouveau_drm.c,v 1.4 2015/03/06 01:43:07 riastradh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.3 2014/08/23 08:03:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_drm.c,v 1.4 2015/03/06 01:43:07 riastradh Exp $");
 
 #include <linux/console.h>
 #include <linux/module.h>
@@ -539,7 +539,6 @@ nouveau_drm_remove(struct pci_dev *pdev)
 }
 #endif
 
-#ifndef __NetBSD__		/* XXX nouveau pm */
 static int
 nouveau_do_suspend(struct drm_device *dev, bool runtime)
 {
@@ -625,9 +624,11 @@ int nouveau_pmops_suspend(struct device 
 	if (ret)
 		return ret;
 
+#ifndef __NetBSD__		/* pmf handles this for us.  */
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
+#endif
 	return 0;
 }
 
@@ -673,12 +674,14 @@ int nouveau_pmops_resume(struct device *
 	    drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
 		return 0;
 
+#ifndef __NetBSD__		/* pmf handles this for us */
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	ret = pci_enable_device(pdev);
 	if (ret)
 		return ret;
 	pci_set_master(pdev);
+#endif
 
 	ret = nouveau_do_resume(drm_dev);
 	if (ret)
@@ -692,6 +695,7 @@ int nouveau_pmops_resume(struct device *
 	return 0;
 }
 
+#ifndef __NetBSD__		/* XXX nouveau pm */
 static int nouveau_pmops_freeze(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c:1.2
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c:1.1.1.2	Wed Aug  6 12:36:23 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c	Fri Mar  6 01:43:07 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_fbcon.c,v 1.1.1.2 2014/08/06 12:36:23 riastradh Exp $	*/
+/*	$NetBSD: nouveau_fbcon.c,v 1.2 2015/03/06 01:43:07 riastradh Exp $	*/
 
 /*
  * Copyright © 2007 David Airlie
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_fbcon.c,v 1.1.1.2 2014/08/06 12:36:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_fbcon.c,v 1.2 2015/03/06 01:43:07 riastradh Exp $");
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -56,11 +56,18 @@ __KERNEL_RCSID(0, "$NetBSD: nouveau_fbco
 
 #include "nouveau_crtc.h"
 
+#ifdef __NetBSD__
+#include "nouveaufb.h"
+#endif
+
 #include <core/client.h>
 #include <core/device.h>
 
 #include <subdev/fb.h>
 
+#ifdef __NetBSD__		/* XXX nouveau fbaccel */
+static const int nouveau_nofbaccel = 1;
+#else
 MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
 static int nouveau_nofbaccel = 0;
 module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
@@ -216,6 +223,7 @@ static struct fb_ops nouveau_fbcon_sw_op
 	.fb_debug_enter = drm_fb_helper_debug_enter,
 	.fb_debug_leave = drm_fb_helper_debug_leave,
 };
+#endif	/* XXX nouveau fbaccel */
 
 static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
 				    u16 blue, int regno)
@@ -240,6 +248,12 @@ static void nouveau_fbcon_gamma_get(stru
 static void
 nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
 {
+#ifdef __NetBSD__		/* XXX nouveau fbaccel */
+	struct nouveau_bo *const nvbo = fbcon->nouveau_fb.nvbo;
+
+	(void)memset(__UNVOLATILE(nvbo_kmap_obj_iovirtual(nvbo)), 0,
+	    nvbo->bo.num_pages << PAGE_SHIFT);
+#else
 	struct fb_info *info = fbcon->helper.fbdev;
 	struct fb_fillrect rect;
 
@@ -253,6 +267,7 @@ nouveau_fbcon_zfill(struct drm_device *d
 	rect.color = 0;
 	rect.rop = ROP_COPY;
 	info->fbops->fb_fillrect(info, &rect);
+#endif
 }
 
 static int
@@ -263,13 +278,17 @@ nouveau_fbcon_create(struct drm_fb_helpe
 	struct drm_device *dev = fbcon->dev;
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	struct nouveau_device *device = nv_device(drm->device);
+#ifndef __NetBSD__
 	struct fb_info *info;
+#endif
 	struct drm_framebuffer *fb;
 	struct nouveau_framebuffer *nouveau_fb;
 	struct nouveau_channel *chan;
 	struct nouveau_bo *nvbo;
 	struct drm_mode_fb_cmd2 mode_cmd;
+#ifndef __NetBSD__
 	struct pci_dev *pdev = dev->pdev;
+#endif
 	int size, ret;
 
 	mode_cmd.width = sizes->surface_width;
@@ -313,6 +332,32 @@ nouveau_fbcon_create(struct drm_fb_helpe
 		}
 	}
 
+#ifdef __NetBSD__
+	nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo);
+	nouveau_fb = &fbcon->nouveau_fb;
+	fb = &nouveau_fb->base;
+
+	nouveau_fbcon_zfill(dev, fbcon);
+
+    {
+	static const struct nouveaufb_attach_args zero_nfa;
+	struct nouveaufb_attach_args nfa = zero_nfa;
+
+	nfa.nfa_fb_helper = helper;
+	nfa.nfa_fb_sizes = *sizes;
+	nfa.nfa_fb_ptr = nvbo_kmap_obj_iovirtual(nvbo);
+	nfa.nfa_fb_linebytes = mode_cmd.pitches[0];
+
+	helper->fbdev = config_found_ia(dev->dev, "nouveaufbbus", &nfa, NULL);
+	if (helper->fbdev == NULL) {
+		DRM_ERROR("failed to attach nouveaufb\n");
+		goto out_unlock;
+	}
+    }
+	helper->fb = fb;
+
+	return 0;
+#else
 	mutex_lock(&dev->struct_mutex);
 
 	info = framebuffer_alloc(0, &pdev->dev);
@@ -385,9 +430,12 @@ nouveau_fbcon_create(struct drm_fb_helpe
 
 	vga_switcheroo_client_fb_set(dev->pdev, info);
 	return 0;
+#endif	/* defined(__NetBSD__) */
 
 out_unlock:
+#ifndef __NetBSD__
 	mutex_unlock(&dev->struct_mutex);
+#endif
 	if (chan)
 		nouveau_bo_vma_del(nvbo, &fbcon->nouveau_fb.vma);
 	nouveau_bo_unmap(nvbo);
@@ -411,14 +459,26 @@ static int
 nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
 {
 	struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb;
+#ifndef __NetBSD__
 	struct fb_info *info;
+#endif
 
 	if (fbcon->helper.fbdev) {
+#ifdef __NetBSD__
+		int ret;
+
+		/* XXX errno NetBSD->Linux */
+		ret = -config_detach(fbcon->helper.fbdev, DETACH_FORCE);
+		if (ret)
+			DRM_ERROR("failed to detach nouveaufb: %d\n", ret);
+		fbcon->helper.fbdev = NULL;
+#else
 		info = fbcon->helper.fbdev;
 		unregister_framebuffer(info);
 		if (info->cmap.len)
 			fb_dealloc_cmap(&info->cmap);
 		framebuffer_release(info);
+#endif
 	}
 
 	if (nouveau_fb->nvbo) {
@@ -434,6 +494,7 @@ nouveau_fbcon_destroy(struct drm_device 
 	return 0;
 }
 
+#ifndef __NetBSD__		/* XXX nouveau fbaccel */
 void nouveau_fbcon_gpu_lockup(struct fb_info *info)
 {
 	struct nouveau_fbdev *fbcon = info->par;
@@ -442,6 +503,7 @@ void nouveau_fbcon_gpu_lockup(struct fb_
 	NV_ERROR(drm, "GPU lockup - switching to software fbcon\n");
 	info->flags |= FBINFO_HWACCEL_DISABLED;
 }
+#endif
 
 static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
 	.gamma_set = nouveau_fbcon_gamma_set,
@@ -511,25 +573,30 @@ nouveau_fbcon_fini(struct drm_device *de
 void
 nouveau_fbcon_save_disable_accel(struct drm_device *dev)
 {
+#ifndef __NetBSD__		/* XXX nouveau fbaccel */
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	if (drm->fbcon) {
 		drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
 		drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
 	}
+#endif
 }
 
 void
 nouveau_fbcon_restore_accel(struct drm_device *dev)
 {
+#ifndef __NetBSD__		/* XXX nouveau fbaccel */
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	if (drm->fbcon) {
 		drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
 	}
+#endif
 }
 
 void
 nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
 {
+#ifndef __NetBSD__
 	struct nouveau_drm *drm = nouveau_drm(dev);
 	if (drm->fbcon) {
 		console_lock();
@@ -540,6 +607,7 @@ nouveau_fbcon_set_suspend(struct drm_dev
 			nouveau_fbcon_restore_accel(dev);
 		console_unlock();
 	}
+#endif
 }
 
 void

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_vga.h
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_vga.h:1.1.1.1 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_vga.h:1.2
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_vga.h:1.1.1.1	Wed Jul 16 19:35:26 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_vga.h	Fri Mar  6 01:43:07 2015
@@ -1,6 +1,9 @@
 #ifndef __NOUVEAU_VGA_H__
 #define __NOUVEAU_VGA_H__
 
+struct nouveau_drm;
+struct drm_device;
+
 void nouveau_vga_init(struct nouveau_drm *);
 void nouveau_vga_fini(struct nouveau_drm *);
 void nouveau_vga_lastclose(struct drm_device *dev);

Index: src/sys/external/bsd/drm2/include/linux/pci.h
diff -u src/sys/external/bsd/drm2/include/linux/pci.h:1.14 src/sys/external/bsd/drm2/include/linux/pci.h:1.15
--- src/sys/external/bsd/drm2/include/linux/pci.h:1.14	Wed Feb 25 14:51:22 2015
+++ src/sys/external/bsd/drm2/include/linux/pci.h	Fri Mar  6 01:43:07 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: pci.h,v 1.14 2015/02/25 14:51:22 riastradh Exp $	*/
+/*	$NetBSD: pci.h,v 1.15 2015/03/06 01:43:07 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -59,6 +59,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
 
 struct pci_bus {
 	u_int		number;
@@ -78,6 +79,8 @@ struct pci_device_id {
 
 #define	PCI_BASE_CLASS_DISPLAY	PCI_CLASS_DISPLAY
 
+#define	PCI_CLASS_DISPLAY_VGA						\
+	((PCI_CLASS_DISPLAY << 8) | PCI_SUBCLASS_DISPLAY_VGA)
 #define	PCI_CLASS_BRIDGE_ISA						\
 	((PCI_CLASS_BRIDGE << 8) | PCI_SUBCLASS_BRIDGE_ISA)
 CTASSERT(PCI_CLASS_BRIDGE_ISA == 0x0601);
@@ -125,6 +128,7 @@ struct pci_dev {
 	bus_size_t		pd_rom_size;
 	void			*pd_rom_vaddr;
 	device_t		pd_dev;
+	struct drm_device	*pd_drm_dev; /* XXX Nouveau kludge!  */
 	struct {
 		pcireg_t		type;
 		bus_addr_t		addr;
@@ -154,6 +158,21 @@ pci_dev_dev(struct pci_dev *pdev)
 	return pdev->pd_dev;
 }
 
+/* XXX Nouveau kludge!  Don't believe me!  */
+static inline struct pci_dev *
+to_pci_dev(struct device *dev)
+{
+
+	return container_of(dev, struct pci_dev, dev);
+}
+
+/* XXX Nouveau kludge!  */
+static inline struct drm_device *
+pci_get_drvdata(struct pci_dev *pdev)
+{
+	return pdev->pd_drm_dev;
+}
+
 static inline void
 linux_pci_dev_init(struct pci_dev *pdev, device_t dev,
     const struct pci_attach_args *pa, int kludges)

Index: src/sys/external/bsd/drm2/include/linux/reboot.h
diff -u src/sys/external/bsd/drm2/include/linux/reboot.h:1.1 src/sys/external/bsd/drm2/include/linux/reboot.h:1.2
--- src/sys/external/bsd/drm2/include/linux/reboot.h:1.1	Wed Aug  6 13:53:12 2014
+++ src/sys/external/bsd/drm2/include/linux/reboot.h	Fri Mar  6 01:43:07 2015
@@ -1,7 +1,7 @@
-/*	$NetBSD: reboot.h,v 1.1 2014/08/06 13:53:12 riastradh Exp $	*/
+/*	$NetBSD: reboot.h,v 1.2 2015/03/06 01:43:07 riastradh Exp $	*/
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2015 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -32,9 +32,18 @@
 #ifndef	_LINUX_REBOOT_H_
 #define	_LINUX_REBOOT_H_
 
-#define	orderly_poweroff	linux_orderly_poweroff
+#include <sys/types.h>
+#include <sys/reboot.h>
 
 /* XXX Implement this by posting a CRITICAL-OVER envsys event?  */
-int	orderly_poweroff(bool);
+static inline int
+orderly_poweroff(bool force __unused)
+{
+
+	cpu_reboot(RB_POWERDOWN, NULL);
+
+	return 0;
+}
+
 
 #endif	/* _LINUX_REBOOT_H_ */

Index: src/sys/external/bsd/drm2/nouveau/files.nouveau
diff -u src/sys/external/bsd/drm2/nouveau/files.nouveau:1.7 src/sys/external/bsd/drm2/nouveau/files.nouveau:1.8
--- src/sys/external/bsd/drm2/nouveau/files.nouveau:1.7	Wed Feb 25 22:11:59 2015
+++ src/sys/external/bsd/drm2/nouveau/files.nouveau	Fri Mar  6 01:43:07 2015
@@ -1,16 +1,29 @@
-#	$NetBSD: files.nouveau,v 1.7 2015/02/25 22:11:59 riastradh Exp $
+#	$NetBSD: files.nouveau,v 1.8 2015/03/06 01:43:07 riastradh Exp $
 
-device	nouveau: drmkms, drmkms_pci, drmkms_ttm, genfb, wsemuldisplaydev
+define	nouveaufbbus	{ }
+device	nouveau: drmkms, drmkms_pci, drmkms_ttm, nouveaufbbus
 attach	nouveau at pci
 
+device	nouveaufb: nouveaufbbus, drmfb, drmfb_pci, wsemuldisplaydev
+attach	nouveaufb at nouveaufbbus
+
+# Local additions.  External sources are listd below.
+file	external/bsd/drm2/nouveau/nouveau_pci.c			nouveau
+file	external/bsd/drm2/nouveau/nouveau_sysfs.c		nouveau
+file	external/bsd/drm2/nouveau/nouveau_vga.c			nouveau
+file	external/bsd/drm2/nouveau/nouveaufb.c			nouveaufb
+
 makeoptions	nouveau	CPPFLAGS+="-I$S/external/bsd/drm2/dist/drm/nouveau"
 makeoptions	nouveau	CPPFLAGS+="-I$S/external/bsd/drm2/dist/drm/nouveau/core"
 makeoptions	nouveau	CPPFLAGS+="-I$S/external/bsd/drm2/dist/drm/nouveau/core/include"
+makeoptions	nouveau	CPPFLAGS+="-I$S/external/bsd/drm2/nouveau"
 
 # XXX DEBUG ALL THE BUGS!
 makeoptions	nouveau	CPPFLAGS+="-DCONFIG_NOUVEAU_DEBUG=1000"
 makeoptions	nouveau	CPPFLAGS+="-DCONFIG_NOUVEAU_DEBUG_DEFAULT=6"
 
+# XXX If you find a way to apply the warning flags to all Nouveau
+# sources, please apply it here and remove this stupidly gigantic list!
 makeoptions	nouveau	"CWARNFLAGS.nouveau_agp.c"+="-Wno-missing-field-initializers"
 makeoptions	nouveau	"CWARNFLAGS.nouveau_bios.c"+="-Wno-shadow"
 makeoptions	nouveau	"CWARNFLAGS.nouveau_bo.c"+="-Wno-missing-field-initializers"
@@ -557,7 +570,7 @@ file	external/bsd/drm2/dist/drm/nouveau/
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_dma.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_drm.c	nouveau
-#file	external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c	nouveau
+file	external/bsd/drm2/dist/drm/nouveau/nouveau_fbcon.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_fence.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c	nouveau
 file	external/bsd/drm2/dist/drm/nouveau/nouveau_hwmon.c	nouveau

Index: src/sys/external/bsd/drm2/pci/drm_pci.c
diff -u src/sys/external/bsd/drm2/pci/drm_pci.c:1.10 src/sys/external/bsd/drm2/pci/drm_pci.c:1.11
--- src/sys/external/bsd/drm2/pci/drm_pci.c:1.10	Fri Mar  6 01:24:24 2015
+++ src/sys/external/bsd/drm2/pci/drm_pci.c	Fri Mar  6 01:43:07 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_pci.c,v 1.10 2015/03/06 01:24:24 riastradh Exp $	*/
+/*	$NetBSD: drm_pci.c,v 1.11 2015/03/06 01:43:07 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.10 2015/03/06 01:24:24 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_pci.c,v 1.11 2015/03/06 01:43:07 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/errno.h>
@@ -111,6 +111,7 @@ drm_pci_attach(device_t self, const stru
 	}
 
 	dev->pdev = pdev;
+	pdev->pd_drm_dev = dev;	/* XXX Nouveau kludge.  */
 
 	/* XXX Set the power state to D0?  */
 

Added files:

Index: src/sys/external/bsd/drm2/nouveau/nouveau_pci.c
diff -u /dev/null src/sys/external/bsd/drm2/nouveau/nouveau_pci.c:1.1
--- /dev/null	Fri Mar  6 01:43:08 2015
+++ src/sys/external/bsd/drm2/nouveau/nouveau_pci.c	Fri Mar  6 01:43:07 2015
@@ -0,0 +1,227 @@
+/*	$NetBSD: nouveau_pci.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2015 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: nouveau_pci.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+#include <sys/workqueue.h>
+
+#include <drm/drmP.h>
+
+#include "nouveau_drm.h"
+#include "nouveau_pci.h"
+
+SIMPLEQ_HEAD(nouveau_task_head, nouveau_task);
+
+struct nouveau_softc {
+	device_t		sc_dev;
+	enum {
+		NOUVEAU_TASK_ATTACH,
+		NOUVEAU_TASK_WORKQUEUE,
+	}			sc_task_state;
+	union {
+		struct workqueue		*workqueue;
+		struct nouveau_task_head	attach;
+	}			sc_task_u;
+	struct drm_device	*sc_drm_dev;
+	struct pci_dev		sc_pci_dev;
+};
+
+static int	nouveau_match(device_t, cfdata_t, void *);
+static void	nouveau_attach(device_t, device_t, void *);
+static int	nouveau_detach(device_t, int);
+
+static bool	nouveau_suspend(device_t, const pmf_qual_t *);
+static bool	nouveau_resume(device_t, const pmf_qual_t *);
+
+static void	nouveau_task_work(struct work *, void *);
+
+CFATTACH_DECL_NEW(nouveau, sizeof(struct nouveau_softc),
+    nouveau_match, nouveau_attach, nouveau_detach, NULL);
+
+/* Kludge to get this from nouveau_drm.c.  */
+extern struct drm_driver *const nouveau_drm_driver;
+
+static int
+nouveau_match(device_t parent, cfdata_t match, void *aux)
+{
+	extern int nouveau_guarantee_initialized(void);
+	const struct pci_attach_args *const pa = aux;
+	int error;
+
+	error = nouveau_guarantee_initialized();
+	if (error) {
+		aprint_error("nouveau: failed to initialize: %d\n", error);
+		return 0;
+	}
+
+	if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA &&
+	    PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS)
+		return 0;
+
+	if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
+		return 0;
+
+	return 6;		/* XXX Beat genfb_pci...  */
+}
+
+static void
+nouveau_attach(device_t parent, device_t self, void *aux)
+{
+	struct nouveau_softc *const sc = device_private(self);
+	const struct pci_attach_args *const pa = aux;
+	int error;
+
+	pci_aprint_devinfo(pa, NULL);
+
+	sc->sc_dev = self;
+
+	if (!pmf_device_register(self, &nouveau_suspend,
+		&nouveau_resume))
+		aprint_error_dev(self, "unable to establish power handler\n");
+
+	sc->sc_task_state = NOUVEAU_TASK_ATTACH;
+	SIMPLEQ_INIT(&sc->sc_task_u.attach);
+
+
+	/* XXX errno Linux->NetBSD */
+	error = -drm_pci_attach(self, pa, &sc->sc_pci_dev, nouveau_drm_driver,
+	    0, &sc->sc_drm_dev);
+	if (error) {
+		aprint_error_dev(self, "unable to attach drm: %d\n", error);
+		return;
+	}
+
+	while (!SIMPLEQ_EMPTY(&sc->sc_task_u.attach)) {
+		struct nouveau_task *const task =
+		    SIMPLEQ_FIRST(&sc->sc_task_u.attach);
+
+		SIMPLEQ_REMOVE_HEAD(&sc->sc_task_u.attach, nt_u.queue);
+		(*task->nt_fn)(task);
+	}
+
+	sc->sc_task_state = NOUVEAU_TASK_WORKQUEUE;
+	error = workqueue_create(&sc->sc_task_u.workqueue, "intelfb",
+	    &nouveau_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE);
+	if (error) {
+		aprint_error_dev(self, "unable to create workqueue: %d\n",
+		    error);
+		sc->sc_task_u.workqueue = NULL;
+		return;
+	}
+}
+
+static int
+nouveau_detach(device_t self, int flags)
+{
+	struct nouveau_softc *const sc = device_private(self);
+	int error;
+
+	/* XXX Check for in-use before tearing it all down...  */
+	error = config_detach_children(self, flags);
+	if (error)
+		return error;
+
+	if (sc->sc_task_state == NOUVEAU_TASK_ATTACH)
+		goto out;
+	if (sc->sc_task_u.workqueue != NULL) {
+		workqueue_destroy(sc->sc_task_u.workqueue);
+		sc->sc_task_u.workqueue = NULL;
+	}
+
+	if (sc->sc_drm_dev == NULL)
+		goto out;
+	/* XXX errno Linux->NetBSD */
+	error = -drm_pci_detach(sc->sc_drm_dev, flags);
+	if (error)
+		/* XXX Kinda too late to fail now...  */
+		return error;
+	sc->sc_drm_dev = NULL;
+
+out:	pmf_device_deregister(self);
+	return 0;
+}
+
+/*
+ * XXX Synchronize with nouveau_do_suspend in nouveau_drm.c.
+ */
+static bool
+nouveau_suspend(device_t self, const pmf_qual_t *qual __unused)
+{
+	struct nouveau_softc *const sc = device_private(self);
+	struct device *const dev = &sc->sc_pci_dev.dev; /* XXX KLUDGE */
+
+	return nouveau_pmops_suspend(dev) == 0;
+}
+
+static bool
+nouveau_resume(device_t self, const pmf_qual_t *qual)
+{
+	struct nouveau_softc *const sc = device_private(self);
+	struct device *const dev = &sc->sc_pci_dev.dev; /* XXX KLUDGE */
+
+	return nouveau_pmops_resume(dev) == 0;
+}
+
+static void
+nouveau_task_work(struct work *work, void *cookie __unused)
+{
+	struct nouveau_task *const task = container_of(work,
+	    struct nouveau_task, nt_u.work);
+
+	(*task->nt_fn)(task);
+}
+
+int
+nouveau_task_schedule(device_t self, struct nouveau_task *task)
+{
+	struct nouveau_softc *const sc = device_private(self);
+
+	switch (sc->sc_task_state) {
+	case NOUVEAU_TASK_ATTACH:
+		SIMPLEQ_INSERT_TAIL(&sc->sc_task_u.attach, task, nt_u.queue);
+		return 0;
+	case NOUVEAU_TASK_WORKQUEUE:
+		if (sc->sc_task_u.workqueue == NULL) {
+			aprint_error_dev(self, "unable to schedule task\n");
+			return EIO;
+		}
+		workqueue_enqueue(sc->sc_task_u.workqueue, &task->nt_u.work,
+		    NULL);
+		return 0;
+	default:
+		panic("nouveau in invalid task state: %d\n",
+		    (int)sc->sc_task_state);
+	}
+}
Index: src/sys/external/bsd/drm2/nouveau/nouveau_pci.h
diff -u /dev/null src/sys/external/bsd/drm2/nouveau/nouveau_pci.h:1.1
--- /dev/null	Fri Mar  6 01:43:08 2015
+++ src/sys/external/bsd/drm2/nouveau/nouveau_pci.h	Fri Mar  6 01:43:07 2015
@@ -0,0 +1,55 @@
+/*	$NetBSD: nouveau_pci.h,v 1.1 2015/03/06 01:43:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2015 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.
+ */
+
+#ifndef	_NOUVEAU_NOUVEAU_PCI_H_
+#define	_NOUVEAU_NOUVEAU_PCI_H_
+
+#include <sys/queue.h>
+#include <sys/workqueue.h>
+
+struct nouveau_task {
+	union {
+		SIMPLEQ_ENTRY(nouveau_task)	queue;
+		struct work			work;
+	}			nt_u;
+	void			(*nt_fn)(struct nouveau_task *);
+};
+
+static inline void
+nouveau_task_init(struct nouveau_task *task, void (*fn)(struct nouveau_task *))
+{
+
+	task->nt_fn = fn;
+}
+
+int	nouveau_task_schedule(device_t, struct nouveau_task *);
+
+#endif	/* _NOUVEAU_NOUVEAU_PCI_H_ */
Index: src/sys/external/bsd/drm2/nouveau/nouveau_sysfs.c
diff -u /dev/null src/sys/external/bsd/drm2/nouveau/nouveau_sysfs.c:1.1
--- /dev/null	Fri Mar  6 01:43:08 2015
+++ src/sys/external/bsd/drm2/nouveau/nouveau_sysfs.c	Fri Mar  6 01:43:07 2015
@@ -0,0 +1,47 @@
+/*	$NetBSD: nouveau_sysfs.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2015 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: nouveau_sysfs.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $");
+
+#include "nouveau_sysfs.h"
+
+int
+nouveau_sysfs_init(struct drm_device *dev __unused)
+{
+
+	return 0;
+}
+
+void
+nouveau_sysfs_fini(struct drm_device *dev __unused)
+{
+}
Index: src/sys/external/bsd/drm2/nouveau/nouveau_vga.c
diff -u /dev/null src/sys/external/bsd/drm2/nouveau/nouveau_vga.c:1.1
--- /dev/null	Fri Mar  6 01:43:08 2015
+++ src/sys/external/bsd/drm2/nouveau/nouveau_vga.c	Fri Mar  6 01:43:07 2015
@@ -0,0 +1,50 @@
+/*	$NetBSD: nouveau_vga.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2015 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: nouveau_vga.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $");
+
+#include "nouveau_vga.h"
+
+void
+nouveau_vga_init(struct nouveau_drm *dev __unused)
+{
+}
+
+void
+nouveau_vga_fini(struct nouveau_drm *dev __unused)
+{
+}
+
+void
+nouveau_vga_lastclose(struct drm_device *dev __unused)
+{
+}
Index: src/sys/external/bsd/drm2/nouveau/nouveaufb.c
diff -u /dev/null src/sys/external/bsd/drm2/nouveau/nouveaufb.c:1.1
--- /dev/null	Fri Mar  6 01:43:08 2015
+++ src/sys/external/bsd/drm2/nouveau/nouveaufb.c	Fri Mar  6 01:43:07 2015
@@ -0,0 +1,196 @@
+/*	$NetBSD: nouveaufb.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2015 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: nouveaufb.c,v 1.1 2015/03/06 01:43:07 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+
+#include <drm/drmP.h>
+#include <drm/drmfb.h>
+#include <drm/drmfb_pci.h>
+
+#include "nouveau_bo.h"
+#include "nouveau_drm.h"
+#include "nouveau_fbcon.h"
+#include "nouveau_pci.h"
+#include "nouveaufb.h"
+
+static int	nouveaufb_match(device_t, cfdata_t, void *);
+static void	nouveaufb_attach(device_t, device_t, void *);
+static int	nouveaufb_detach(device_t, int);
+
+static void	nouveaufb_attach_task(struct nouveau_task *);
+
+static bool	nouveaufb_shutdown(device_t, int);
+static paddr_t	nouveaufb_drmfb_mmapfb(struct drmfb_softc *, off_t, int);
+
+struct nouveaufb_softc {
+	struct drmfb_softc		sc_drmfb; /* XXX Must be first.  */
+	device_t			sc_dev;
+	struct nouveaufb_attach_args	sc_nfa;
+	struct nouveau_task		sc_attach_task;
+	bool				sc_scheduled:1;
+	bool				sc_attached:1;
+};
+
+static const struct drmfb_params nouveaufb_drmfb_params = {
+	.dp_mmapfb = nouveaufb_drmfb_mmapfb,
+	.dp_mmap = drmfb_pci_mmap,
+	.dp_ioctl = drmfb_pci_ioctl,
+	.dp_is_vga_console = drmfb_pci_is_vga_console,
+};
+
+CFATTACH_DECL_NEW(nouveaufb, sizeof(struct nouveaufb_softc),
+    nouveaufb_match, nouveaufb_attach, nouveaufb_detach, NULL);
+
+static int
+nouveaufb_match(device_t parent, cfdata_t match, void *aux)
+{
+
+	return 1;
+}
+
+static void
+nouveaufb_attach(device_t parent, device_t self, void *aux)
+{
+	struct nouveaufb_softc *const sc = device_private(self);
+	const struct nouveaufb_attach_args *const nfa = aux;
+	int error;
+
+	sc->sc_dev = self;
+	sc->sc_nfa = *nfa;
+	sc->sc_scheduled = false;
+	sc->sc_attached = false;
+
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	nouveau_task_init(&sc->sc_attach_task, &nouveaufb_attach_task);
+	error = nouveau_task_schedule(parent, &sc->sc_attach_task);
+	if (error) {
+		aprint_error_dev(self, "failed to schedule mode set: %d\n",
+		    error);
+		goto fail0;
+	}
+	sc->sc_scheduled = true;
+
+	/* Success!  */
+	return;
+
+fail0:	return;
+}
+
+static int
+nouveaufb_detach(device_t self, int flags)
+{
+	struct nouveaufb_softc *const sc = device_private(self);
+	int error;
+
+	if (sc->sc_scheduled)
+		return EBUSY;
+
+	if (sc->sc_attached) {
+		pmf_device_deregister(self);
+		error = drmfb_detach(&sc->sc_drmfb, flags);
+		if (error) {
+			/* XXX Ugh.  */
+			(void)pmf_device_register1(self, NULL, NULL,
+			    &nouveaufb_shutdown);
+			return error;
+		}
+		sc->sc_attached = false;
+	}
+
+	return 0;
+}
+
+static void
+nouveaufb_attach_task(struct nouveau_task *task)
+{
+	struct nouveaufb_softc *const sc = container_of(task,
+	    struct nouveaufb_softc, sc_attach_task);
+	const struct nouveaufb_attach_args *const nfa = &sc->sc_nfa;
+	const struct drmfb_attach_args da = {
+		.da_dev = sc->sc_dev,
+		.da_fb_helper = nfa->nfa_fb_helper,
+		.da_fb_sizes = &nfa->nfa_fb_sizes,
+		.da_fb_vaddr = __UNVOLATILE(nfa->nfa_fb_ptr),
+		.da_params = &nouveaufb_drmfb_params,
+	};
+	int error;
+
+	error = drmfb_attach(&sc->sc_drmfb, &da);
+	if (error) {
+		aprint_error_dev(sc->sc_dev, "failed to attach drmfb: %d\n",
+		    error);
+		return;
+	}
+
+	if (pmf_device_register1(sc->sc_dev, NULL, NULL, &nouveaufb_shutdown))
+		aprint_error_dev(sc->sc_dev,
+		    "failed to register shutdown handler\n");
+
+	sc->sc_attached = true;
+}
+
+static bool
+nouveaufb_shutdown(device_t self, int flags)
+{
+	struct nouveaufb_softc *const sc = device_private(self);
+
+	return drmfb_shutdown(&sc->sc_drmfb, flags);
+}
+
+static paddr_t
+nouveaufb_drmfb_mmapfb(struct drmfb_softc *drmfb, off_t offset, int prot)
+{
+	struct nouveaufb_softc *const sc = container_of(drmfb,
+	    struct nouveaufb_softc, sc_drmfb);
+	struct drm_fb_helper *const helper = sc->sc_nfa.nfa_fb_helper;
+	struct nouveau_fbdev *const fbdev = container_of(helper,
+	    struct nouveau_fbdev, helper);
+	struct nouveau_bo *const nvbo = fbdev->nouveau_fb.nvbo;
+	const unsigned num_pages __diagused = nvbo->bo.num_pages;
+	int flags = 0;
+
+	KASSERT(0 <= offset);
+	KASSERT(offset < (num_pages << PAGE_SHIFT));
+
+	if (ISSET(nvbo->bo.mem.placement, TTM_PL_FLAG_WC))
+		flags |= BUS_SPACE_MAP_PREFETCHABLE;
+
+	return bus_space_mmap(nvbo->bo.bdev->memt, nvbo->bo.mem.bus.base,
+	    nvbo->bo.mem.bus.offset + offset, prot, flags);
+}
Index: src/sys/external/bsd/drm2/nouveau/nouveaufb.h
diff -u /dev/null src/sys/external/bsd/drm2/nouveau/nouveaufb.h:1.1
--- /dev/null	Fri Mar  6 01:43:08 2015
+++ src/sys/external/bsd/drm2/nouveau/nouveaufb.h	Fri Mar  6 01:43:07 2015
@@ -0,0 +1,48 @@
+/*	$NetBSD: nouveaufb.h,v 1.1 2015/03/06 01:43:07 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2015 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.
+ */
+
+#ifndef	_NOUVEAU_NOUVEAUFB_H_
+#define	_NOUVEAU_NOUVEAUFB_H_
+
+#include <sys/bus.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+
+struct nouveaufb_attach_args {
+	struct drm_device			*nfa_drm_dev;
+	struct drm_fb_helper			*nfa_fb_helper;
+	struct drm_fb_helper_surface_size	nfa_fb_sizes;
+	volatile void				*nfa_fb_ptr;
+	uint32_t				nfa_fb_linebytes;
+};
+
+#endif	/* _NOUVEAU_NOUVEAUFB_H_ */

Reply via email to