drm/nouveau: port all engines to new engine module format

This is a HUGE commit, but it's not nearly as bad as it looks - any problems
can be isolated to a particular chipset and engine combination.  It was
simply too difficult to port each one at a time, the compat layers are
*already* ridiculous.

Most of the changes here are simply to the glue, the process for each of the
engine modules was to start with a standard skeleton and copy+paste the old
code into the appropriate places, fixing up variable names etc as needed.

v2: Marcin Slusarz <marcin.slusarz@gmail.com>
- fix find/replace bug in license header

v3: Ben Skeggs <bskeggs@redhat.com>
- bump indirect pushbuf size to 8KiB, 4KiB barely enough for userspace and
  left no space for kernel's requirements during GEM pushbuf submission.
- fix duplicate assignments noticed by clang

v4: Marcin Slusarz <marcin.slusarz@gmail.com>
- add sparse annotations to nv04_fifo_pause/nv04_fifo_start
- use ioread32_native/iowrite32_native for fifo control registers

v5: Ben Skeggs <bskeggs@redhat.com>
- rebase on v3.6-rc4, modified to keep copy engine fix intact
- nv10/fence: unmap fence bo before destroying
- fixed fermi regression when using nvidia gr fuc
- fixed typo in supported dma_mask checking

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index f3f0b4c3..8b8bc83 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -43,19 +43,31 @@
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
 #include "drm_fb_helper.h"
-#include "nouveau_drv.h"
-#include <nouveau_drm.h>
-#include "nouveau_crtc.h"
+
+#include "nouveau_drm.h"
+#include "nouveau_gem.h"
+#include "nouveau_bo.h"
 #include "nouveau_fb.h"
 #include "nouveau_fbcon.h"
-#include "nouveau_dma.h"
+#include "nouveau_chan.h"
+
+#include "nouveau_crtc.h"
+
+#include <core/client.h>
+#include <core/device.h>
+
+#include <subdev/fb.h>
+
+MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
+static int nouveau_nofbaccel = 0;
+module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
 
 static void
 nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-	struct nouveau_fbdev *nfbdev = info->par;
-	struct drm_device *dev = nfbdev->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fbdev *fbcon = info->par;
+	struct nouveau_drm *drm = nouveau_newpriv(fbcon->dev);
+	struct nouveau_device *device = nv_device(drm->device);
 	int ret;
 
 	if (info->state != FBINFO_STATE_RUNNING)
@@ -63,15 +75,15 @@
 
 	ret = -ENODEV;
 	if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
-	    mutex_trylock(&dev_priv->channel->mutex)) {
-		if (dev_priv->card_type < NV_50)
+	    mutex_trylock(&drm->client.mutex)) {
+		if (device->card_type < NV_50)
 			ret = nv04_fbcon_fillrect(info, rect);
 		else
-		if (dev_priv->card_type < NV_C0)
+		if (device->card_type < NV_C0)
 			ret = nv50_fbcon_fillrect(info, rect);
 		else
 			ret = nvc0_fbcon_fillrect(info, rect);
-		mutex_unlock(&dev_priv->channel->mutex);
+		mutex_unlock(&drm->client.mutex);
 	}
 
 	if (ret == 0)
@@ -85,9 +97,9 @@
 static void
 nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
 {
-	struct nouveau_fbdev *nfbdev = info->par;
-	struct drm_device *dev = nfbdev->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fbdev *fbcon = info->par;
+	struct nouveau_drm *drm = nouveau_newpriv(fbcon->dev);
+	struct nouveau_device *device = nv_device(drm->device);
 	int ret;
 
 	if (info->state != FBINFO_STATE_RUNNING)
@@ -95,15 +107,15 @@
 
 	ret = -ENODEV;
 	if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
-	    mutex_trylock(&dev_priv->channel->mutex)) {
-		if (dev_priv->card_type < NV_50)
+	    mutex_trylock(&drm->client.mutex)) {
+		if (device->card_type < NV_50)
 			ret = nv04_fbcon_copyarea(info, image);
 		else
-		if (dev_priv->card_type < NV_C0)
+		if (device->card_type < NV_C0)
 			ret = nv50_fbcon_copyarea(info, image);
 		else
 			ret = nvc0_fbcon_copyarea(info, image);
-		mutex_unlock(&dev_priv->channel->mutex);
+		mutex_unlock(&drm->client.mutex);
 	}
 
 	if (ret == 0)
@@ -117,9 +129,9 @@
 static void
 nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-	struct nouveau_fbdev *nfbdev = info->par;
-	struct drm_device *dev = nfbdev->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fbdev *fbcon = info->par;
+	struct nouveau_drm *drm = nouveau_newpriv(fbcon->dev);
+	struct nouveau_device *device = nv_device(drm->device);
 	int ret;
 
 	if (info->state != FBINFO_STATE_RUNNING)
@@ -127,15 +139,15 @@
 
 	ret = -ENODEV;
 	if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) &&
-	    mutex_trylock(&dev_priv->channel->mutex)) {
-		if (dev_priv->card_type < NV_50)
+	    mutex_trylock(&drm->client.mutex)) {
+		if (device->card_type < NV_50)
 			ret = nv04_fbcon_imageblit(info, image);
 		else
-		if (dev_priv->card_type < NV_C0)
+		if (device->card_type < NV_C0)
 			ret = nv50_fbcon_imageblit(info, image);
 		else
 			ret = nvc0_fbcon_imageblit(info, image);
-		mutex_unlock(&dev_priv->channel->mutex);
+		mutex_unlock(&drm->client.mutex);
 	}
 
 	if (ret == 0)
@@ -149,10 +161,9 @@
 static int
 nouveau_fbcon_sync(struct fb_info *info)
 {
-	struct nouveau_fbdev *nfbdev = info->par;
-	struct drm_device *dev = nfbdev->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_channel *chan = dev_priv->channel;
+	struct nouveau_fbdev *fbcon = info->par;
+	struct nouveau_drm *drm = nouveau_newpriv(fbcon->dev);
+	struct nouveau_channel *chan = drm->channel;
 	int ret;
 
 	if (!chan || !chan->accel_done || in_interrupt() ||
@@ -160,11 +171,11 @@
 	    info->flags & FBINFO_HWACCEL_DISABLED)
 		return 0;
 
-	if (!mutex_trylock(&chan->mutex))
+	if (!mutex_trylock(&drm->client.mutex))
 		return 0;
 
 	ret = nouveau_channel_idle(chan);
-	mutex_unlock(&chan->mutex);
+	mutex_unlock(&drm->client.mutex);
 	if (ret) {
 		nouveau_fbcon_gpu_lockup(info);
 		return 0;
@@ -224,9 +235,9 @@
 }
 
 static void
-nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
+nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *fbcon)
 {
-	struct fb_info *info = nfbdev->helper.fbdev;
+	struct fb_info *info = fbcon->helper.fbdev;
 	struct fb_fillrect rect;
 
 	/* Clear the entire fbcon.  The drm will program every connector
@@ -242,11 +253,12 @@
 }
 
 static int
-nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
+nouveau_fbcon_create(struct nouveau_fbdev *fbcon,
 		     struct drm_fb_helper_surface_size *sizes)
 {
-	struct drm_device *dev = nfbdev->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct drm_device *dev = fbcon->dev;
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
+	struct nouveau_device *device = nv_device(drm->device);
 	struct fb_info *info;
 	struct drm_framebuffer *fb;
 	struct nouveau_framebuffer *nouveau_fb;
@@ -254,7 +266,6 @@
 	struct nouveau_bo *nvbo;
 	struct drm_mode_fb_cmd2 mode_cmd;
 	struct pci_dev *pdev = dev->pdev;
-	struct device *device = &pdev->dev;
 	int size, ret;
 
 	mode_cmd.width = sizes->surface_width;
@@ -272,37 +283,38 @@
 	ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM,
 			      0, 0x0000, &nvbo);
 	if (ret) {
-		NV_ERROR(dev, "failed to allocate framebuffer\n");
+		NV_ERROR(drm, "failed to allocate framebuffer\n");
 		goto out;
 	}
 
 	ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM);
 	if (ret) {
-		NV_ERROR(dev, "failed to pin fb: %d\n", ret);
+		NV_ERROR(drm, "failed to pin fb: %d\n", ret);
 		nouveau_bo_ref(NULL, &nvbo);
 		goto out;
 	}
 
 	ret = nouveau_bo_map(nvbo);
 	if (ret) {
-		NV_ERROR(dev, "failed to map fb: %d\n", ret);
+		NV_ERROR(drm, "failed to map fb: %d\n", ret);
 		nouveau_bo_unpin(nvbo);
 		nouveau_bo_ref(NULL, &nvbo);
 		goto out;
 	}
 
-	chan = nouveau_nofbaccel ? NULL : dev_priv->channel;
-	if (chan && dev_priv->card_type >= NV_50) {
-		ret = nouveau_bo_vma_add(nvbo, chan->vm, &nfbdev->nouveau_fb.vma);
+	chan = nouveau_nofbaccel ? NULL : drm->channel;
+	if (chan && device->card_type >= NV_50) {
+		ret = nouveau_bo_vma_add(nvbo, nv_client(chan->cli)->vm,
+					&fbcon->nouveau_fb.vma);
 		if (ret) {
-			NV_ERROR(dev, "failed to map fb into chan: %d\n", ret);
+			NV_ERROR(drm, "failed to map fb into chan: %d\n", ret);
 			chan = NULL;
 		}
 	}
 
 	mutex_lock(&dev->struct_mutex);
 
-	info = framebuffer_alloc(0, device);
+	info = framebuffer_alloc(0, &pdev->dev);
 	if (!info) {
 		ret = -ENOMEM;
 		goto out_unref;
@@ -314,16 +326,16 @@
 		goto out_unref;
 	}
 
-	info->par = nfbdev;
+	info->par = fbcon;
 
-	nouveau_framebuffer_init(dev, &nfbdev->nouveau_fb, &mode_cmd, nvbo);
+	nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo);
 
-	nouveau_fb = &nfbdev->nouveau_fb;
+	nouveau_fb = &fbcon->nouveau_fb;
 	fb = &nouveau_fb->base;
 
 	/* setup helper */
-	nfbdev->helper.fb = fb;
-	nfbdev->helper.fbdev = info;
+	fbcon->helper.fb = fb;
+	fbcon->helper.fbdev = info;
 
 	strcpy(info->fix.id, "nouveaufb");
 	if (nouveau_nofbaccel)
@@ -342,25 +354,18 @@
 	info->screen_size = size;
 
 	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
-	drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height);
-
-	/* Set aperture base/size for vesafb takeover */
-	info->apertures = dev_priv->apertures;
-	if (!info->apertures) {
-		ret = -ENOMEM;
-		goto out_unref;
-	}
+	drm_fb_helper_fill_var(info, &fbcon->helper, sizes->fb_width, sizes->fb_height);
 
 	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
 	mutex_unlock(&dev->struct_mutex);
 
-	if (dev_priv->channel && !nouveau_nofbaccel) {
+	if (chan) {
 		ret = -ENODEV;
-		if (dev_priv->card_type < NV_50)
+		if (device->card_type < NV_50)
 			ret = nv04_fbcon_accel_init(info);
 		else
-		if (dev_priv->card_type < NV_C0)
+		if (device->card_type < NV_C0)
 			ret = nv50_fbcon_accel_init(info);
 		else
 			ret = nvc0_fbcon_accel_init(info);
@@ -369,13 +374,12 @@
 			info->fbops = &nouveau_fbcon_ops;
 	}
 
-	nouveau_fbcon_zfill(dev, nfbdev);
+	nouveau_fbcon_zfill(dev, fbcon);
 
 	/* To allow resizeing without swapping buffers */
-	NV_INFO(dev, "allocated %dx%d fb: 0x%lx, bo %p\n",
-						nouveau_fb->base.width,
-						nouveau_fb->base.height,
-						nvbo->bo.offset, nvbo);
+	NV_INFO(drm, "allocated %dx%d fb: 0x%lx, bo %p\n",
+		nouveau_fb->base.width, nouveau_fb->base.height,
+		nvbo->bo.offset, nvbo);
 
 	vga_switcheroo_client_fb_set(dev->pdev, info);
 	return 0;
@@ -390,12 +394,12 @@
 nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper,
 				    struct drm_fb_helper_surface_size *sizes)
 {
-	struct nouveau_fbdev *nfbdev = (struct nouveau_fbdev *)helper;
+	struct nouveau_fbdev *fbcon = (struct nouveau_fbdev *)helper;
 	int new_fb = 0;
 	int ret;
 
 	if (!helper->fb) {
-		ret = nouveau_fbcon_create(nfbdev, sizes);
+		ret = nouveau_fbcon_create(fbcon, sizes);
 		if (ret)
 			return ret;
 		new_fb = 1;
@@ -406,18 +410,18 @@
 void
 nouveau_fbcon_output_poll_changed(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
+	drm_fb_helper_hotplug_event(&drm->fbcon->helper);
 }
 
 static int
-nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
+nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
 {
-	struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
+	struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb;
 	struct fb_info *info;
 
-	if (nfbdev->helper.fbdev) {
-		info = nfbdev->helper.fbdev;
+	if (fbcon->helper.fbdev) {
+		info = fbcon->helper.fbdev;
 		unregister_framebuffer(info);
 		if (info->cmap.len)
 			fb_dealloc_cmap(&info->cmap);
@@ -430,17 +434,17 @@
 		drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem);
 		nouveau_fb->nvbo = NULL;
 	}
-	drm_fb_helper_fini(&nfbdev->helper);
+	drm_fb_helper_fini(&fbcon->helper);
 	drm_framebuffer_cleanup(&nouveau_fb->base);
 	return 0;
 }
 
 void nouveau_fbcon_gpu_lockup(struct fb_info *info)
 {
-	struct nouveau_fbdev *nfbdev = info->par;
-	struct drm_device *dev = nfbdev->dev;
+	struct nouveau_fbdev *fbcon = info->par;
+	struct nouveau_drm *drm = nouveau_newpriv(fbcon->dev);
 
-	NV_ERROR(dev, "GPU lockup - switching to software fbcon\n");
+	NV_ERROR(drm, "GPU lockup - switching to software fbcon\n");
 	info->flags |= FBINFO_HWACCEL_DISABLED;
 }
 
@@ -451,74 +455,81 @@
 };
 
 
-int nouveau_fbcon_init(struct drm_device *dev)
+int
+nouveau_fbcon_init(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_fbdev *nfbdev;
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
+	struct nouveau_fb *pfb = nouveau_fb(drm->device);
+	struct nouveau_fbdev *fbcon;
 	int preferred_bpp;
 	int ret;
 
-	nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
-	if (!nfbdev)
+	if (!dev->mode_config.num_crtc)
+		return 0;
+
+	fbcon = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
+	if (!fbcon)
 		return -ENOMEM;
 
-	nfbdev->dev = dev;
-	dev_priv->nfbdev = nfbdev;
-	nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs;
+	fbcon->dev = dev;
+	drm->fbcon = fbcon;
+	fbcon->helper.funcs = &nouveau_fbcon_helper_funcs;
 
-	ret = drm_fb_helper_init(dev, &nfbdev->helper,
+	ret = drm_fb_helper_init(dev, &fbcon->helper,
 				 dev->mode_config.num_crtc, 4);
 	if (ret) {
-		kfree(nfbdev);
+		kfree(fbcon);
 		return ret;
 	}
 
-	drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
+	drm_fb_helper_single_add_all_connectors(&fbcon->helper);
 
-	if (nvfb_vram_size(dev) <= 32 * 1024 * 1024)
+	if (pfb->ram.size <= 32 * 1024 * 1024)
 		preferred_bpp = 8;
-	else if (nvfb_vram_size(dev) <= 64 * 1024 * 1024)
+	else
+	if (pfb->ram.size <= 64 * 1024 * 1024)
 		preferred_bpp = 16;
 	else
 		preferred_bpp = 32;
 
-	drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp);
+	drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
 	return 0;
 }
 
-void nouveau_fbcon_fini(struct drm_device *dev)
+void
+nouveau_fbcon_fini(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
 
-	if (!dev_priv->nfbdev)
+	if (!drm->fbcon)
 		return;
 
-	nouveau_fbcon_destroy(dev, dev_priv->nfbdev);
-	kfree(dev_priv->nfbdev);
-	dev_priv->nfbdev = NULL;
+	nouveau_fbcon_destroy(dev, drm->fbcon);
+	kfree(drm->fbcon);
+	drm->fbcon = NULL;
 }
 
 void nouveau_fbcon_save_disable_accel(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
 
-	dev_priv->nfbdev->saved_flags = dev_priv->nfbdev->helper.fbdev->flags;
-	dev_priv->nfbdev->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
+	drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
+	drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
 }
 
 void nouveau_fbcon_restore_accel(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	dev_priv->nfbdev->helper.fbdev->flags = dev_priv->nfbdev->saved_flags;
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
+	drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
 }
 
 void nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
 	console_lock();
 	if (state == 0)
 		nouveau_fbcon_save_disable_accel(dev);
-	fb_set_suspend(dev_priv->nfbdev->helper.fbdev, state);
+	fb_set_suspend(drm->fbcon->helper.fbdev, state);
 	if (state == 1)
 		nouveau_fbcon_restore_accel(dev);
 	console_unlock();
@@ -526,6 +537,6 @@
 
 void nouveau_fbcon_zfill_all(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	nouveau_fbcon_zfill(dev, dev_priv->nfbdev);
+	struct nouveau_drm *drm = nouveau_newpriv(dev);
+	nouveau_fbcon_zfill(dev, drm->fbcon);
 }