Module Name:    src
Committed By:   msaitoh
Date:           Mon Dec 12 09:13:43 UTC 2016

Modified Files:
        src/sys/external/bsd/drm2/dist/drm/i915 [netbsd-7]: i915_gpu_error.c
        src/sys/external/bsd/drm2/dist/drm/nouveau [netbsd-7]: nouveau_bo.c
            nouveau_connector.c nouveau_dp.c nouveau_gem.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/core/core [netbsd-7]:
            nouveau_core_object.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device 
[netbsd-7]:
            nouveau_engine_device_base.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp [netbsd-7]:
            nouveau_engine_disp_nvd0.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo [netbsd-7]:
            nouveau_engine_fifo_base.c nouveau_engine_fifo_nv40.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit 
[netbsd-7]:
            nouveau_subdev_devinit_nv04.c
        src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm [netbsd-7]:
            nouveau_subdev_mxm_mxms.c nouveau_subdev_mxm_nv50.c
        src/sys/external/bsd/drm2/dist/drm/radeon [netbsd-7]: radeon_ttm.c
        src/sys/external/bsd/drm2/dist/drm/ttm [netbsd-7]: ttm_tt.c
        src/sys/external/bsd/drm2/dist/include/drm/ttm [netbsd-7]:
            ttm_bo_driver.h
        src/sys/external/bsd/drm2/drm [netbsd-7]: drm_vma_manager.c
        src/sys/external/bsd/drm2/include/drm [netbsd-7]: drm_wait_netbsd.h
        src/sys/external/bsd/drm2/include/drm/ttm [netbsd-7]: ttm_page_alloc.h
        src/sys/external/bsd/drm2/nouveau [netbsd-7]: nouveau_pci.c
        src/sys/external/bsd/drm2/ttm [netbsd-7]: ttm_bus_dma.c

Log Message:
Pull up following revision(s) (requested by snj in ticket #1280):
        sys/external/bsd/drm2/ttm/ttm_bus_dma.c: revision 1.2
        sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h: revision 1.14
        sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c: revision 1.2
        sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c: revision 1.7
        
sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c:
 revision 1.11
        
sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c:
 revision 1.2
        sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h: revision 1.3
        sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c: revision 1.8
        sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c: revision 1.3
        sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c: revision 1.4
        
sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c:
 revision 1.3
        sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c: revision 1.7
        sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c: 
revision 1.3
        sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c: revision 1.4
        
sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c:
 revision 1.2
        
sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c:
 revision 1.3
        
sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c:
 revision 1.3
        
sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c:
 revision 1.5
        sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h: revision 1.2
        sys/external/bsd/drm2/drm/drm_vma_manager.c: revision 1.4
        sys/external/bsd/drm2/nouveau/nouveau_pci.c: revision 1.8
- fix non-debug build
- Use %"PRIx8", not %hx, for uint8_t.  %hx is for unsigned short.
- Flush unused function. Found by joerg.
- Make sure rbtrees are empty on desctruction.
  If related to PR kern/51076, might help catch the bug a bit earlier.
- revert rev 1.6.  we don't have access to those files as normal files
  and possible will get them directly elsewhere soon.
  (if i hack my nouveau to ignore fireware failure, it end up having
  a vaguely working console and slowly working X, which is better than
  the current situation.)
- Avoid possible null pointer dereference. Found by Coverity, CID 709895.
- Mark fallthrough to suppress Coverity complaints.
  CID 143119
  CID 143120
  CID 143121
  CID 143122
  CID 143123
  CID 143124
- Sanity-check that the encoder we found is not null.
  I think the previous code guarantees that finding this encoder should
  work, so this should be a moot point. CID 145720.
- Mark intended fallthrough to suppress Coverity CID 201378.
- Mark fallthrough with a comment to appease Coverity, CID 703385.
- Make it clearer to Coverity that there's no array overrun. CID 989067.
- Rework ttm tt swapin/swapout logic.
  Rather than handling `swapping in/out' here, per se, we let uvm do
  that, we interpret `swap out' as `deactivate pages', and we add
  generic ttm operations to wire and unwire pages, for the ttm_tt
  driver to use.
  This fixes certain graphics buffer eviction logic, which enables
  nouveau to suspend/resume on one of my machines.  (The machine
  doesn't resume overall for other reasons, but the nouveau device
  suspends and resumes in isolation.)
- Use bus_space_subregion to get fifo channels out of mmio registers.
  Evidently it is not enough to just map them separately.  Ran out of
  time to investigate why, last time I poked at this and confirmed this
  change works.
- Avoid taking locks during interrupts and explain why we are doing it this way.
- We now use cpu_intr_p() all the time.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.3.4.1 \
    src/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c
cvs rdiff -u -r1.4.4.2 -r1.4.4.3 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c
cvs rdiff -u -r1.2 -r1.2.4.1 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c
cvs rdiff -u -r1.1.1.2 -r1.1.1.2.4.1 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c
cvs rdiff -u -r1.2.4.1 -r1.2.4.2 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c
cvs rdiff -u -r1.2 -r1.2.4.1 \
    src/sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c
cvs rdiff -u -r1.2.4.4 -r1.2.4.5 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c
cvs rdiff -u -r1.1.1.1.4.1 -r1.1.1.1.4.2 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c
cvs rdiff -u -r1.2.4.2 -r1.2.4.3 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.4.1 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c
cvs rdiff -u -r1.1.1.1.4.1 -r1.1.1.1.4.2 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c
cvs rdiff -u -r1.1.1.1 -r1.1.1.1.4.1 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c
cvs rdiff -u -r1.1.1.1.4.1 -r1.1.1.1.4.2 \
    
src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c
cvs rdiff -u -r1.5.4.2 -r1.5.4.3 \
    src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c
cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c
cvs rdiff -u -r1.2 -r1.2.2.1 \
    src/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h
cvs rdiff -u -r1.1.4.3 -r1.1.4.4 \
    src/sys/external/bsd/drm2/drm/drm_vma_manager.c
cvs rdiff -u -r1.4.2.4 -r1.4.2.5 \
    src/sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h
cvs rdiff -u -r1.1 -r1.1.4.1 \
    src/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h
cvs rdiff -u -r1.3.2.6 -r1.3.2.7 \
    src/sys/external/bsd/drm2/nouveau/nouveau_pci.c
cvs rdiff -u -r1.1 -r1.1.4.1 src/sys/external/bsd/drm2/ttm/ttm_bus_dma.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/i915/i915_gpu_error.c
diff -u src/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c:1.3 src/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c:1.3.4.1
--- src/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c:1.3	Fri Jul 18 19:48:34 2014
+++ src/sys/external/bsd/drm2/dist/drm/i915/i915_gpu_error.c	Mon Dec 12 09:13:42 2016
@@ -604,18 +604,33 @@ i915_error_object_create_sized(struct dr
 
 			memcpy_fromio(d, (void __iomem *) offset, PAGE_SIZE);
 		} else {
-			struct page *page;
-			void *s;
 
-			page = i915_gem_object_get_page(src, i);
+			if (cpu_intr_p() || cpu_softintr_p() ||
+			    (curlwp->l_pflag & LP_INTR) != 0) {
+				/*
+				 * We can't take locks during interrupts
+				 * and finding the page from uvm requires
+				 * taking a lock. Checking for an interrupt
+				 * context is bogus, but this is the least
+				 * intrusive change. Zero the result, doesn't
+				 * matter much, because this is only used
+				 * for diagnostics.
+				 */
+				memset(d, 0, PAGE_SIZE);
+			} else {
+				struct page *page;
+				void *s;
+
+				page = i915_gem_object_get_page(src, i);
+
+				drm_clflush_pages(&page, 1);
+
+				s = kmap_atomic(page);
+				memcpy(d, s, PAGE_SIZE);
+				kunmap_atomic(s);
 
-			drm_clflush_pages(&page, 1);
-
-			s = kmap_atomic(page);
-			memcpy(d, s, PAGE_SIZE);
-			kunmap_atomic(s);
-
-			drm_clflush_pages(&page, 1);
+				drm_clflush_pages(&page, 1);
+			}
 		}
 		local_irq_restore(flags);
 

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c:1.4.4.2 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c:1.4.4.3
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c:1.4.4.2	Thu Feb 11 23:08:41 2016
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_bo.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_bo.c,v 1.4.4.2 2016/02/11 23:08:41 snj Exp $	*/
+/*	$NetBSD: nouveau_bo.c,v 1.4.4.3 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2007 Dave Airlied
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_bo.c,v 1.4.4.2 2016/02/11 23:08:41 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_bo.c,v 1.4.4.3 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <core/engine.h>
 #include <linux/swiotlb.h>
@@ -1524,6 +1524,16 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt 
 #endif
 }
 
+#ifdef __NetBSD__
+static void
+nouveau_ttm_tt_swapout(struct ttm_tt *ttm)
+{
+	struct ttm_dma_tt *ttm_dma = container_of(ttm, struct ttm_dma_tt, ttm);
+
+	ttm_bus_dma_swapout(ttm_dma);
+}
+#endif
+
 void
 nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
 {
@@ -1581,6 +1591,7 @@ struct ttm_bo_driver nouveau_bo_driver =
 	.ttm_tt_populate = &nouveau_ttm_tt_populate,
 	.ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate,
 #ifdef __NetBSD__
+	.ttm_tt_swapout = &nouveau_ttm_tt_swapout,
 	.ttm_uvm_ops = &nouveau_uvm_ops,
 #endif
 	.invalidate_caches = nouveau_bo_invalidate_caches,

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c:1.2 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c:1.2.4.1
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c:1.2	Wed Aug  6 15:01:33 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_connector.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_connector.c,v 1.2 2014/08/06 15:01:33 riastradh Exp $	*/
+/*	$NetBSD: nouveau_connector.c,v 1.2.4.1 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright (C) 2008 Maarten Maathuis.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_connector.c,v 1.2 2014/08/06 15:01:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_connector.c,v 1.2.4.1 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <acpi/button.h>
 
@@ -308,6 +308,7 @@ nouveau_connector_detect(struct drm_conn
 				type = DCB_OUTPUT_ANALOG;
 
 			nv_encoder = find_encoder(connector, type);
+			BUG_ON(nv_encoder == NULL);
 		}
 
 		nouveau_connector_set_encoder(connector, nv_encoder);

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c:1.1.1.2 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c:1.1.1.2.4.1
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c:1.1.1.2	Wed Aug  6 12:36:23 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_dp.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_dp.c,v 1.1.1.2 2014/08/06 12:36:23 riastradh Exp $	*/
+/*	$NetBSD: nouveau_dp.c,v 1.1.1.2.4.1 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2009 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_dp.c,v 1.1.1.2 2014/08/06 12:36:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_dp.c,v 1.1.1.2.4.1 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <drm/drmP.h>
 #include <drm/drm_dp_helper.h>
@@ -51,11 +51,11 @@ nouveau_dp_probe_oui(struct drm_device *
 		return;
 
 	if (!nv_rdaux(auxch, DP_SINK_OUI, buf, 3))
-		NV_DEBUG(drm, "Sink OUI: %02hx%02hx%02hx\n",
+		NV_DEBUG(drm, "Sink OUI: %02"PRIx8"%02"PRIx8"%02"PRIx8"\n",
 			     buf[0], buf[1], buf[2]);
 
 	if (!nv_rdaux(auxch, DP_BRANCH_OUI, buf, 3))
-		NV_DEBUG(drm, "Branch OUI: %02hx%02hx%02hx\n",
+		NV_DEBUG(drm, "Branch OUI: %02"PRIx8"%02"PRIx8"%02"PRIx8"\n",
 			     buf[0], buf[1], buf[2]);
 
 }

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c:1.2.4.1 src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c:1.2.4.2
--- src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c:1.2.4.1	Sun Sep 21 17:41:52 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/nouveau_gem.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_gem.c,v 1.2.4.1 2014/09/21 17:41:52 snj Exp $	*/
+/*	$NetBSD: nouveau_gem.c,v 1.2.4.2 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright (C) 2008 Ben Skeggs.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_gem.c,v 1.2.4.1 2014/09/21 17:41:52 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_gem.c,v 1.2.4.2 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <subdev/fb.h>
 
@@ -885,19 +885,6 @@ out_next:
 	return nouveau_abi16_put(abi16, ret);
 }
 
-static inline uint32_t
-domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain)
-{
-	uint32_t flags = 0;
-
-	if (domain & NOUVEAU_GEM_DOMAIN_VRAM)
-		flags |= TTM_PL_FLAG_VRAM;
-	if (domain & NOUVEAU_GEM_DOMAIN_GART)
-		flags |= TTM_PL_FLAG_TT;
-
-	return flags;
-}
-
 int
 nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c:1.2 src/sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c:1.2.4.1
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c:1.2	Wed Aug  6 13:35:13 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/core/nouveau_core_object.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_core_object.c,v 1.2 2014/08/06 13:35:13 riastradh Exp $	*/
+/*	$NetBSD: nouveau_core_object.c,v 1.2.4.1 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_core_object.c,v 1.2 2014/08/06 13:35:13 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_core_object.c,v 1.2.4.1 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <core/object.h>
 #include <core/parent.h>
@@ -47,14 +47,18 @@ void
 nouveau_objects_init(void)
 {
 
+#ifdef NOUVEAU_OBJECT_MAGIC
 	spin_lock_init(&_objlist_lock);
+#endif
 }
 
 void
 nouveau_objects_fini(void)
 {
 
+#ifdef NOUVEAU_OBJECT_MAGIC
 	spin_lock_destroy(&_objlist_lock);
+#endif
 }
 #endif
 

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c:1.2.4.4 src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c:1.2.4.5
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c:1.2.4.4	Fri Apr 15 08:46:42 2016
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/device/nouveau_engine_device_base.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_engine_device_base.c,v 1.2.4.4 2016/04/15 08:46:42 snj Exp $	*/
+/*	$NetBSD: nouveau_engine_device_base.c,v 1.2.4.5 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_device_base.c,v 1.2.4.4 2016/04/15 08:46:42 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_device_base.c,v 1.2.4.5 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <core/object.h>
 #include <core/device.h>
@@ -297,12 +297,6 @@ nouveau_devobj_ctor(struct nouveau_objec
 #ifdef __NetBSD__
 	if (!(args->disable & NV_DEVICE_DISABLE_MMIO) &&
 	    !nv_subdev(device)->mmiosz) {
-		/*
-		 * Map only through PRAMIN -- don't map the command
-		 * FIFO MMIO regions, which start at NV_FIFO_OFFSET =
-		 * 0x800000 and are mapped separately.
-		 */
-		mmio_size = MIN(mmio_size, 0x800000);
 		/* XXX errno NetBSD->Linux */
 		ret = -bus_space_map(mmiot, mmio_base, mmio_size, 0, &mmioh);
 		if (ret) {

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c:1.1.1.1.4.1 src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c:1.1.1.1.4.2
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c:1.1.1.1.4.1	Sun Sep 21 17:41:53 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/disp/nouveau_engine_disp_nvd0.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_engine_disp_nvd0.c,v 1.1.1.1.4.1 2014/09/21 17:41:53 snj Exp $	*/
+/*	$NetBSD: nouveau_engine_disp_nvd0.c,v 1.1.1.1.4.2 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_disp_nvd0.c,v 1.1.1.1.4.1 2014/09/21 17:41:53 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_disp_nvd0.c,v 1.1.1.1.4.2 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <core/object.h>
 #include <core/parent.h>
@@ -1042,7 +1042,8 @@ exec_clkcmp(struct nv50_disp_priv *priv,
 	}
 
 	data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2);
-	if (data && id < 0xff) {
+	CTASSERT(__arraycount(info2.clkcmp) <= 0xff);
+	if (data && id < __arraycount(info2.clkcmp)) {
 		data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
 		if (data) {
 			struct nvbios_init init = {

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c:1.2.4.2 src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c:1.2.4.3
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c:1.2.4.2	Thu Feb 11 23:49:52 2016
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_base.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_engine_fifo_base.c,v 1.2.4.2 2016/02/11 23:49:52 snj Exp $	*/
+/*	$NetBSD: nouveau_engine_fifo_base.c,v 1.2.4.3 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_fifo_base.c,v 1.2.4.2 2016/02/11 23:49:52 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_fifo_base.c,v 1.2.4.3 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <core/client.h>
 #include <core/object.h>
@@ -92,13 +92,68 @@ nouveau_fifo_channel_create_(struct nouv
 
 	/* map fifo control registers */
 #ifdef __NetBSD__
-	chan->bst = nv_device_resource_tag(device, bar);
-	/* XXX errno NetBSD->Linux */
-	ret = -bus_space_map(chan->bst, nv_device_resource_start(device, bar) +
-	    addr + (chan->chid * size), size, 0, &chan->bsh);
-	if (ret)
-		return ret;
-	chan->mapped = true;
+	if (bar == 0) {
+		/*
+		 * We already map BAR 0 in the engine device base, so
+		 * grab a subregion of that.
+		 */
+		bus_space_tag_t mmiot = nv_subdev(device)->mmiot;
+		bus_space_handle_t mmioh = nv_subdev(device)->mmioh;
+		bus_size_t mmiosz = nv_subdev(device)->mmiosz;
+
+		/* Check whether it lies inside the region.  */
+		if (mmiosz < addr ||
+		    mmiosz - addr < chan->chid*size ||
+		    mmiosz - addr - chan->chid*size < size) {
+			ret = EIO;
+			nv_error(priv, "fifo channel out of range:"
+			    " addr 0x%"PRIxMAX
+			    " chid 0x%"PRIxMAX" size 0x%"PRIxMAX
+			    " mmiosz 0x%"PRIxMAX"\n",
+			    (uintmax_t)addr,
+			    (uintmax_t)chan->chid, (uintmax_t)size,
+			    (uintmax_t)mmiosz);
+			return ret;
+		}
+
+		/* Grab a subregion.  */
+		/* XXX errno NetBSD->Linux */
+		ret = -bus_space_subregion(mmiot, mmioh,
+		    (addr + chan->chid*size), size, &chan->bsh);
+		if (ret) {
+			nv_error(priv, "bus_space_subregion failed: %d\n",
+			    ret);
+			return ret;
+		}
+
+		/* Success!  No need to unmap a subregion.  */
+		chan->mapped = false;
+		chan->bst = mmiot;
+	} else {
+		chan->bst = nv_device_resource_tag(device, bar);
+		/* XXX errno NetBSD->Linux */
+		ret = -bus_space_map(chan->bst,
+		    (nv_device_resource_start(device, bar) +
+			addr + (chan->chid * size)),
+		    size, 0, &chan->bsh);
+		if (ret) {
+			nv_error(priv, "failed to map fifo channel:"
+			    " bar %d addr %"PRIxMAX" + %"PRIxMAX
+			    " + (%"PRIxMAX" * %"PRIxMAX") = %"PRIxMAX
+			    " size %"PRIxMAX": %d\n",
+			    bar,
+			    (uintmax_t)nv_device_resource_start(device, bar),
+			    (uintmax_t)addr,
+			    (uintmax_t)chan->chid,
+			    (uintmax_t)size,
+			    (uintmax_t)(nv_device_resource_start(device, bar) +
+				addr + (chan->chid * size)),
+			    (uintmax_t)size,
+			    ret);
+			return ret;
+		}
+		chan->mapped = true;
+	}
 #else
 	chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
 			     (chan->chid * size), size);

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c:1.1.1.1 src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c:1.1.1.1.4.1
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c:1.1.1.1	Wed Aug  6 12:36:24 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/engine/fifo/nouveau_engine_fifo_nv40.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_engine_fifo_nv40.c,v 1.1.1.1 2014/08/06 12:36:24 riastradh Exp $	*/
+/*	$NetBSD: nouveau_engine_fifo_nv40.c,v 1.1.1.1.4.1 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_fifo_nv40.c,v 1.1.1.1 2014/08/06 12:36:24 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_engine_fifo_nv40.c,v 1.1.1.1.4.1 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <core/os.h>
 #include <core/class.h>
@@ -315,6 +315,7 @@ nv40_fifo_init(struct nouveau_object *ob
 	case 0x49:
 	case 0x4b:
 		nv_wr32(priv, 0x002230, 0x00000001);
+		/*FALLTHROUGH*/
 	case 0x40:
 	case 0x41:
 	case 0x42:

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c:1.1.1.1.4.1 src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c:1.1.1.1.4.2
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c:1.1.1.1.4.1	Fri Mar  6 21:39:09 2015
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/devinit/nouveau_subdev_devinit_nv04.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_subdev_devinit_nv04.c,v 1.1.1.1.4.1 2015/03/06 21:39:09 snj Exp $	*/
+/*	$NetBSD: nouveau_subdev_devinit_nv04.c,v 1.1.1.1.4.2 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright (C) 2010 Francisco Jerez.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_devinit_nv04.c,v 1.1.1.1.4.1 2015/03/06 21:39:09 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_devinit_nv04.c,v 1.1.1.1.4.2 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <subdev/vga.h>
 
@@ -121,12 +121,16 @@ powerctrl_1_shift(int chip_version, int 
 	switch (reg) {
 	case 0x680520:
 		shift += 4;
+		/*FALLTHROUGH*/
 	case 0x680508:
 		shift += 4;
+		/*FALLTHROUGH*/
 	case 0x680504:
 		shift += 4;
+		/*FALLTHROUGH*/
 	case 0x680500:
 		shift += 4;
+		/*FALLTHROUGH*/
 	}
 
 	/*
@@ -245,12 +249,16 @@ setPLL_double_highregs(struct nouveau_de
 		switch (reg1) {
 		case 0x680504:
 			shift_c040 += 2;
+			/*FALLTHROUGH*/
 		case 0x680500:
 			shift_c040 += 2;
+			/*FALLTHROUGH*/
 		case 0x680520:
 			shift_c040 += 2;
+			/*FALLTHROUGH*/
 		case 0x680508:
 			shift_c040 += 2;
+			/*FALLTHROUGH*/
 		}
 
 		savedc040 = nv_rd32(devinit, 0xc040);

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c:1.1.1.1 src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c:1.1.1.1.4.1
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c:1.1.1.1	Wed Aug  6 12:36:31 2014
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_mxms.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_subdev_mxm_mxms.c,v 1.1.1.1 2014/08/06 12:36:31 riastradh Exp $	*/
+/*	$NetBSD: nouveau_subdev_mxm_mxms.c,v 1.1.1.1.4.1 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2012 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_mxm_mxms.c,v 1.1.1.1 2014/08/06 12:36:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_mxm_mxms.c,v 1.1.1.1.4.1 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <subdev/mxm.h>
 #include "mxms.h"
@@ -173,7 +173,7 @@ mxms_foreach(struct nouveau_mxm *mxm, u8
 			}
 		}
 
-		if (types & (1 << type)) {
+		if ((types & (1 << type)) && (exec != NULL)) {
 			if (!exec(mxm, desc, info))
 				return false;
 		}

Index: src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c
diff -u src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c:1.1.1.1.4.1 src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c:1.1.1.1.4.2
--- src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c:1.1.1.1.4.1	Fri Mar  6 21:39:09 2015
+++ src/sys/external/bsd/drm2/dist/drm/nouveau/core/subdev/mxm/nouveau_subdev_mxm_nv50.c	Mon Dec 12 09:13:42 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_subdev_mxm_nv50.c,v 1.1.1.1.4.1 2015/03/06 21:39:09 snj Exp $	*/
+/*	$NetBSD: nouveau_subdev_mxm_nv50.c,v 1.1.1.1.4.2 2016/12/12 09:13:42 msaitoh Exp $	*/
 
 /*
  * Copyright 2011 Red Hat Inc.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_mxm_nv50.c,v 1.1.1.1.4.1 2015/03/06 21:39:09 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_subdev_mxm_nv50.c,v 1.1.1.1.4.2 2016/12/12 09:13:42 msaitoh Exp $");
 
 #include <subdev/mxm.h>
 #include <subdev/bios.h>
@@ -170,6 +170,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bi
 		break;
 	case 0x0e: /* eDP, falls through to DPint */
 		ctx.outp[1] |= 0x00010000;
+		/*FALLTHROUGH*/
 	case 0x07: /* DP internal, wtf is this?? HP8670w */
 		ctx.outp[1] |= 0x00000004; /* use_power_scripts? */
 		type = DCB_CONNECTOR_eDP;

Index: src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c
diff -u src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c:1.5.4.2 src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c:1.5.4.3
--- src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c:1.5.4.2	Thu Apr 23 07:31:17 2015
+++ src/sys/external/bsd/drm2/dist/drm/radeon/radeon_ttm.c	Mon Dec 12 09:13:42 2016
@@ -716,6 +716,15 @@ static void radeon_ttm_tt_unpopulate(str
 }
 
 #ifdef __NetBSD__
+static void radeon_ttm_tt_swapout(struct ttm_tt *ttm)
+{
+	struct radeon_ttm_tt *gtt = container_of(ttm, struct radeon_ttm_tt,
+	    ttm.ttm);
+	struct ttm_dma_tt *ttm_dma = &gtt->ttm;
+
+	ttm_bus_dma_swapout(ttm_dma);
+}
+
 static int	radeon_ttm_fault(struct uvm_faultinfo *, vaddr_t,
 		    struct vm_page **, int, int, vm_prot_t, int);
 
@@ -731,6 +740,7 @@ static struct ttm_bo_driver radeon_bo_dr
 	.ttm_tt_populate = &radeon_ttm_tt_populate,
 	.ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate,
 #ifdef __NetBSD__
+	.ttm_tt_swapout = &radeon_ttm_tt_swapout,
 	.ttm_uvm_ops = &radeon_uvm_ops,
 #endif
 	.invalidate_caches = &radeon_invalidate_caches,

Index: src/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c
diff -u src/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c:1.6 src/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c:1.6.2.1
--- src/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c:1.6	Sun Jul 27 00:40:39 2014
+++ src/sys/external/bsd/drm2/dist/drm/ttm/ttm_tt.c	Mon Dec 12 09:13:42 2016
@@ -349,15 +349,30 @@ int ttm_tt_bind(struct ttm_tt *ttm, stru
 }
 EXPORT_SYMBOL(ttm_tt_bind);
 
-int ttm_tt_swapin(struct ttm_tt *ttm)
-{
 #ifdef __NetBSD__
+/*
+ * ttm_tt_wire(ttm)
+ *
+ *	Wire the uvm pages of ttm and fill the ttm page array.  ttm
+ *	must be unpopulated or unbound, and must be marked swapped.
+ *	This does not change either state -- the caller is expected to
+ *	include it among other operations for such a state transition.
+ */
+int
+ttm_tt_wire(struct ttm_tt *ttm)
+{
 	struct uvm_object *uobj = ttm->swap_storage;
 	struct vm_page *page;
 	unsigned i;
 	int error;
 
+	KASSERTMSG((ttm->state == tt_unpopulated || ttm->state == tt_unbound),
+	    "ttm_tt %p must be unpopulated or unbound for wiring,"
+	    " but state=%d",
+	    ttm, (int)ttm->state);
+	KASSERT(ISSET(ttm->page_flags, TTM_PAGE_FLAG_SWAPPED));
 	KASSERT(uobj != NULL);
+
 	error = uvm_obj_wirepages(uobj, 0, (ttm->num_pages << PAGE_SHIFT),
 	    &ttm->pglist);
 	if (error)
@@ -375,7 +390,37 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
 
 	/* Success!  */
 	return 0;
-#else
+}
+
+/*
+ * ttm_tt_unwire(ttm)
+ *
+ *	Nullify the ttm page array and unwire the uvm pages of ttm.
+ *	ttm must be unbound and must be marked swapped.  This does not
+ *	change either state -- the caller is expected to include it
+ *	among other operations for such a state transition.
+ */
+void
+ttm_tt_unwire(struct ttm_tt *ttm)
+{
+	struct uvm_object *uobj = ttm->swap_storage;
+	unsigned i;
+
+	KASSERTMSG((ttm->state == tt_unbound),
+	    "ttm_tt %p must be unbound for unwiring, but state=%d",
+	    ttm, (int)ttm->state);
+	KASSERT(!ISSET(ttm->page_flags, TTM_PAGE_FLAG_SWAPPED));
+	KASSERT(uobj != NULL);
+
+	uvm_obj_unwirepages(uobj, 0, (ttm->num_pages << PAGE_SHIFT));
+	for (i = 0; i < ttm->num_pages; i++)
+		ttm->pages[i] = NULL;
+}
+#endif
+
+#ifndef __NetBSD__
+int ttm_tt_swapin(struct ttm_tt *ttm)
+{
 	struct address_space *swap_space;
 	struct file *swap_storage;
 	struct page *from_page;
@@ -410,35 +455,25 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
 	return 0;
 out_err:
 	return ret;
-#endif
 }
+#endif
 
-#ifdef __NetBSD__
 int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
 {
-	struct uvm_object *uobj = ttm->swap_storage;
-	unsigned i;
-
-	KASSERT((ttm->state == tt_unbound) || (ttm->state == tt_unpopulated));
-	KASSERT(ttm->caching_state == tt_cached);
-	KASSERT(uobj != NULL);
+#ifdef __NetBSD__
 
-	/*
-	 * XXX Dunno what this persistent swap storage business is all
-	 * about, but I see nothing using it and it doesn't make sense.
-	 */
+	KASSERTMSG((ttm->state == tt_unpopulated || ttm->state == tt_unbound),
+	    "ttm_tt %p must be unpopulated or unbound for swapout,"
+	    " but state=%d",
+	    ttm, (int)ttm->state);
+	KASSERTMSG((ttm->caching_state == tt_cached),
+	    "ttm_tt %p must be cached for swapout, but caching_state=%d",
+	    ttm, (int)ttm->caching_state);
 	KASSERT(persistent_swap_storage == NULL);
 
-	uvm_obj_unwirepages(uobj, 0, (ttm->num_pages << PAGE_SHIFT));
-	for (i = 0; i < ttm->num_pages; i++)
-		ttm->pages[i] = NULL;
-
-	/* Success!  */
+	ttm->bdev->driver->ttm_tt_swapout(ttm);
 	return 0;
-}
 #else
-int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
-{
 	struct address_space *swap_space;
 	struct file *swap_storage;
 	struct page *from_page;
@@ -489,8 +524,8 @@ out_err:
 		fput(swap_storage);
 
 	return ret;
-}
 #endif
+}
 
 static void ttm_tt_clear_mapping(struct ttm_tt *ttm)
 {

Index: src/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h:1.2 src/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h:1.2.2.1
--- src/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h:1.2	Wed Jul 16 20:59:57 2014
+++ src/sys/external/bsd/drm2/dist/include/drm/ttm/ttm_bo_driver.h	Mon Dec 12 09:13:42 2016
@@ -368,6 +368,15 @@ struct ttm_bo_driver {
 	void (*ttm_tt_unpopulate)(struct ttm_tt *ttm);
 
 	/**
+	 * ttm_tt_swapout
+	 *
+	 * @ttm: The struct ttm_tt to contain the backing pages.
+	 *
+	 * Deactivate all backing pages, but don't free them
+	 */
+	void (*ttm_tt_swapout)(struct ttm_tt *ttm);
+
+	/**
 	 * struct ttm_bo_driver member invalidate_caches
 	 *
 	 * @bdev: the buffer object device.
@@ -666,6 +675,25 @@ extern void ttm_tt_destroy(struct ttm_tt
  */
 extern void ttm_tt_unbind(struct ttm_tt *ttm);
 
+#ifdef __NetBSD__
+/**
+ * ttm_tt_wire
+ *
+ * @ttm The struct ttm_tt.
+ *
+ * Wire the pages of a ttm_tt, allocating pages for it if necessary.
+ */
+extern int ttm_tt_wire(struct ttm_tt *ttm);
+
+/**
+ * ttm_tt_unwire
+ *
+ * @ttm The struct ttm_tt.
+ *
+ * Unwire the pages of a ttm_tt.
+ */
+extern void ttm_tt_unwire(struct ttm_tt *ttm);
+#else
 /**
  * ttm_tt_swapin:
  *
@@ -674,6 +702,7 @@ extern void ttm_tt_unbind(struct ttm_tt 
  * Swap in a previously swap out ttm_tt.
  */
 extern int ttm_tt_swapin(struct ttm_tt *ttm);
+#endif
 
 /**
  * ttm_tt_cache_flush:

Index: src/sys/external/bsd/drm2/drm/drm_vma_manager.c
diff -u src/sys/external/bsd/drm2/drm/drm_vma_manager.c:1.1.4.3 src/sys/external/bsd/drm2/drm/drm_vma_manager.c:1.1.4.4
--- src/sys/external/bsd/drm2/drm/drm_vma_manager.c:1.1.4.3	Sat Dec  3 12:24:50 2016
+++ src/sys/external/bsd/drm2/drm/drm_vma_manager.c	Mon Dec 12 09:13:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_vma_manager.c,v 1.1.4.3 2016/12/03 12:24:50 martin Exp $	*/
+/*	$NetBSD: drm_vma_manager.c,v 1.1.4.4 2016/12/12 09:13:43 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_vma_manager.c,v 1.1.4.3 2016/12/03 12:24:50 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_vma_manager.c,v 1.1.4.4 2016/12/12 09:13:43 msaitoh Exp $");
 
 #include <sys/kmem.h>
 #include <sys/rbtree.h>
@@ -120,6 +120,8 @@ drm_vma_offset_manager_destroy(struct dr
 {
 
 	vmem_destroy(mgr->vom_vmem);
+	KASSERTMSG((RB_TREE_MIN(&mgr->vom_nodes) == NULL),
+	    "drm vma offset manager %p not empty", mgr);
 #if 0
 	rb_tree_destroy(&mgr->vom_nodes);
 #endif
@@ -143,6 +145,8 @@ void
 drm_vma_node_destroy(struct drm_vma_offset_node *node)
 {
 
+	KASSERTMSG((RB_TREE_MIN(&node->von_files) == NULL),
+	    "drm vma node %p not empty", node);
 #if 0
 	rb_tree_destroy(&node->von_files);
 #endif

Index: src/sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h
diff -u src/sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h:1.4.2.4 src/sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h:1.4.2.5
--- src/sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h:1.4.2.4	Thu Apr 23 07:31:17 2015
+++ src/sys/external/bsd/drm2/include/drm/drm_wait_netbsd.h	Mon Dec 12 09:13:41 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_wait_netbsd.h,v 1.4.2.4 2015/04/23 07:31:17 snj Exp $	*/
+/*	$NetBSD: drm_wait_netbsd.h,v 1.4.2.5 2016/12/12 09:13:41 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -34,9 +34,7 @@
 
 #include <sys/param.h>
 #include <sys/condvar.h>
-#if DIAGNOSTIC
 #include <sys/cpu.h>		/* cpu_intr_p */
-#endif
 #include <sys/kernel.h>
 #include <sys/mutex.h>
 #include <sys/systm.h>

Index: src/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h
diff -u src/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h:1.1 src/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h:1.1.4.1
--- src/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h:1.1	Wed Jul 16 20:59:58 2014
+++ src/sys/external/bsd/drm2/include/drm/ttm/ttm_page_alloc.h	Mon Dec 12 09:13:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ttm_page_alloc.h,v 1.1 2014/07/16 20:59:58 riastradh Exp $	*/
+/*	$NetBSD: ttm_page_alloc.h,v 1.1.4.1 2016/12/12 09:13:43 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -37,6 +37,7 @@ struct ttm_mem_global;
 
 int	ttm_bus_dma_populate(struct ttm_dma_tt *);
 void	ttm_bus_dma_unpopulate(struct ttm_dma_tt *);
+void	ttm_bus_dma_swapout(struct ttm_dma_tt *);
 
 static inline int
 ttm_page_alloc_init(struct ttm_mem_global *glob __unused,

Index: src/sys/external/bsd/drm2/nouveau/nouveau_pci.c
diff -u src/sys/external/bsd/drm2/nouveau/nouveau_pci.c:1.3.2.6 src/sys/external/bsd/drm2/nouveau/nouveau_pci.c:1.3.2.7
--- src/sys/external/bsd/drm2/nouveau/nouveau_pci.c:1.3.2.6	Fri Apr 15 08:46:42 2016
+++ src/sys/external/bsd/drm2/nouveau/nouveau_pci.c	Mon Dec 12 09:13:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nouveau_pci.c,v 1.3.2.6 2016/04/15 08:46:42 snj Exp $	*/
+/*	$NetBSD: nouveau_pci.c,v 1.3.2.7 2016/12/12 09:13:43 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.3.2.6 2016/04/15 08:46:42 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.3.2.7 2016/12/12 09:13:43 msaitoh Exp $");
 
 #include <sys/types.h>
 #include <sys/device.h>
@@ -51,7 +51,6 @@ SIMPLEQ_HEAD(nouveau_pci_task_head, nouv
 
 struct nouveau_pci_softc {
 	device_t		sc_dev;
-	struct pci_attach_args	sc_pa;
 	enum {
 		NOUVEAU_TASK_ATTACH,
 		NOUVEAU_TASK_WORKQUEUE,
@@ -67,7 +66,6 @@ struct nouveau_pci_softc {
 
 static int	nouveau_pci_match(device_t, cfdata_t, void *);
 static void	nouveau_pci_attach(device_t, device_t, void *);
-static void	nouveau_attach_real(device_t);
 static int	nouveau_pci_detach(device_t, int);
 
 static bool	nouveau_pci_suspend(device_t, const pmf_qual_t *);
@@ -104,27 +102,17 @@ nouveau_pci_attach(device_t parent, devi
 {
 	struct nouveau_pci_softc *const sc = device_private(self);
 	const struct pci_attach_args *const pa = aux;
+	uint64_t devname;
+	int error;
 
 	pci_aprint_devinfo(pa, NULL);
 
 	sc->sc_dev = self;
-	sc->sc_pa = *pa;
 
 	if (!pmf_device_register(self, &nouveau_pci_suspend,
 		&nouveau_pci_resume))
 		aprint_error_dev(self, "unable to establish power handler\n");
 
-	config_mountroot(self, &nouveau_attach_real);
-}
-
-static void
-nouveau_attach_real(device_t self)
-{
-	struct nouveau_pci_softc *const sc = device_private(self);
-	const struct pci_attach_args *const pa = &sc->sc_pa;
-	uint64_t devname;
-	int error;
-
 	sc->sc_task_state = NOUVEAU_TASK_ATTACH;
 	SIMPLEQ_INIT(&sc->sc_task_u.attach);
 

Index: src/sys/external/bsd/drm2/ttm/ttm_bus_dma.c
diff -u src/sys/external/bsd/drm2/ttm/ttm_bus_dma.c:1.1 src/sys/external/bsd/drm2/ttm/ttm_bus_dma.c:1.1.4.1
--- src/sys/external/bsd/drm2/ttm/ttm_bus_dma.c:1.1	Wed Jul 16 20:59:58 2014
+++ src/sys/external/bsd/drm2/ttm/ttm_bus_dma.c	Mon Dec 12 09:13:41 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ttm_bus_dma.c,v 1.1 2014/07/16 20:59:58 riastradh Exp $	*/
+/*	$NetBSD: ttm_bus_dma.c,v 1.1.4.1 2016/12/12 09:13:41 msaitoh Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ttm_bus_dma.c,v 1.1 2014/07/16 20:59:58 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ttm_bus_dma.c,v 1.1.4.1 2016/12/12 09:13:41 msaitoh Exp $");
 
 #include <sys/bus.h>
 
@@ -40,17 +40,41 @@ __KERNEL_RCSID(0, "$NetBSD: ttm_bus_dma.
 #include <ttm/ttm_bo_driver.h>
 #include <ttm/ttm_page_alloc.h>
 
+/*
+ * ttm_bus_dma_populate(ttm_dma)
+ *
+ *	If ttm_dma is not already populated, wire its pages and load
+ *	its DMA map.  The wiring and loading are stable as long as the
+ *	associated bo is reserved.
+ *
+ *	Transitions from tt_unpopulated or tt_unbound to tt_unbound.
+ *	Marks as wired, a.k.a. !swapped.
+ */
 int
 ttm_bus_dma_populate(struct ttm_dma_tt *ttm_dma)
 {
 	int ret;
 
-	/* If it's already populated, nothing to do.  */
-	if (ttm_dma->ttm.state != tt_unpopulated)
-		return 0;
+	KASSERT(ttm_dma->ttm.state != tt_bound);
+
+	/* Check the current state.  */
+	if (ttm_dma->ttm.state == tt_unbound) {
+		/*
+		 * If it's populated, then if the pages are wired and
+		 * loaded already, nothing to do.
+		 */
+		if (!ISSET(ttm_dma->ttm.page_flags, TTM_PAGE_FLAG_SWAPPED))
+			return 0;
+	} else if (ttm_dma->ttm.state == tt_unpopulated) {
+		/* If it's unpopulated, it can't be swapped.  */
+		KASSERT(!ISSET(ttm_dma->ttm.page_flags,
+			TTM_PAGE_FLAG_SWAPPED));
+		/* Pretend it is now, for the sake of ttm_tt_wire.  */
+		ttm_dma->ttm.page_flags |= TTM_PAGE_FLAG_SWAPPED;
+	}
 
-	/* Wire the pages, allocating them if necessary.  */
-	ret = ttm_tt_swapin(&ttm_dma->ttm);
+	/* Wire the uvm pages and fill the ttm page array.  */
+	ret = ttm_tt_wire(&ttm_dma->ttm);
 	if (ret)
 		goto fail0;
 
@@ -62,34 +86,86 @@ ttm_bus_dma_populate(struct ttm_dma_tt *
 	if (ret)
 		goto fail1;
 
-	/* Success!  */
+	/* Mark it wired.  */
+	ttm_dma->ttm.page_flags &= ~TTM_PAGE_FLAG_SWAPPED;
+
+	/* Mark it populated but unbound.  */
 	ttm_dma->ttm.state = tt_unbound;
+
+	/* Success!  */
 	return 0;
 
 fail2: __unused
 	bus_dmamap_unload(ttm_dma->ttm.bdev->dmat, ttm_dma->dma_address);
-fail1:	ttm_tt_swapout(&ttm_dma->ttm, NULL);
+fail1:	ttm_tt_unwire(&ttm_dma->ttm);
 fail0:	KASSERT(ret);
 	return ret;
 }
 
-void
-ttm_bus_dma_unpopulate(struct ttm_dma_tt *ttm_dma)
+static void
+ttm_bus_dma_put(struct ttm_dma_tt *ttm_dma, int flags)
 {
 	struct uvm_object *const uobj = ttm_dma->ttm.swap_storage;
 	const size_t size = (ttm_dma->ttm.num_pages << PAGE_SHIFT);
 
-	/* Unload the DMA map.  */
-	bus_dmamap_unload(ttm_dma->ttm.bdev->dmat, ttm_dma->dma_address);
-
-	/* Unwire the pages.  */
-	ttm_tt_swapout(&ttm_dma->ttm, NULL);
+	/*
+	 * Can't be tt_bound -- still in use and needs to be removed
+	 * from GPU page tables.  Can't be tt_unpopulated -- if it
+	 * were, why are you hnadling this?  Hence tt_unbound.
+	 */
+	KASSERTMSG((ttm_dma->ttm.state == tt_unbound),
+	    "ttm_tt %p in invalid state for unpopulate/swapout: %d",
+	    &ttm_dma->ttm, (int)ttm_dma->ttm.state);
+
+	/* If pages are wired and loaded, unload and unwire them.  */
+	if (!ISSET(ttm_dma->ttm.page_flags, TTM_PAGE_FLAG_SWAPPED)) {
+		bus_dmamap_unload(ttm_dma->ttm.bdev->dmat,
+		    ttm_dma->dma_address);
+		ttm_tt_unwire(&ttm_dma->ttm);
+		ttm_dma->ttm.page_flags |= TTM_PAGE_FLAG_SWAPPED;
+	}
 
 	/* We are using uvm_aobj, which had better have a pgo_put.  */
 	KASSERT(uobj->pgops->pgo_put);
 
-	/* Release the pages.  */
+	/* Release or deactivate the pages.  */
 	mutex_enter(uobj->vmobjlock);
-	(void)(*uobj->pgops->pgo_put)(uobj, 0, size, PGO_CLEANIT|PGO_FREE);
+	(void)(*uobj->pgops->pgo_put)(uobj, 0, size, flags);
 	/* pgo_put unlocks uobj->vmobjlock.  */
+
+	/* Mark it unpopulated.  */
+	ttm_dma->ttm.state = tt_unpopulated;
+}
+
+/*
+ * ttmm_bus_dma_unpopulate(ttm_dma)
+ *
+ *	Unload any DMA map, unwire any pages, and release any pages
+ *	associated with ttm_dma.
+ *
+ *	Transitions from tt_unbound to tt_unpopulated.  Marks as
+ *	unwired, a.k.a. swapped.
+ */
+void
+ttm_bus_dma_unpopulate(struct ttm_dma_tt *ttm_dma)
+{
+
+	ttm_bus_dma_put(ttm_dma, PGO_CLEANIT|PGO_FREE);
+}
+
+/*
+ * ttm_bus_dma_swapout(ttm_dma)
+ *
+ *	Unload any DMA map, unwire any pages, and deactivate any pages
+ *	associated with ttm_dma so that they can be swapped out, but
+ *	don't release them.
+ *
+ *	Transitions from tt_unbound to tt_unpopulated.  Marks as
+ *	unwired, a.k.a. swapped.
+ */
+void
+ttm_bus_dma_swapout(struct ttm_dma_tt *ttm_dma)
+{
+
+	ttm_bus_dma_put(ttm_dma, PGO_DEACTIVATE);
 }

Reply via email to