Jesse Keating 7a32965
 drivers/gpu/drm/drm_crtc_helper.c           |   22 +-
Jesse Keating 7a32965
 drivers/gpu/drm/i2c/ch7006_drv.c            |   22 +-
Jesse Keating 7a32965
 drivers/gpu/drm/i2c/ch7006_priv.h           |    2 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/Makefile            |    2 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_acpi.c      |   38 ++-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_bios.c      |  636 +++++++++++++++++++++------
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_bios.h      |    4 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_bo.c        |    9 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_calc.c      |    4 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_channel.c   |    5 -
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_connector.c |  404 ++++++++----------
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_connector.h |    7 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_dma.c       |    8 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_dp.c        |   24 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_drv.c       |   31 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_drv.h       |   90 ++---
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_encoder.h   |   10 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_fbcon.c     |    2 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_fence.c     |   31 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_gem.c       |   11 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_grctx.c     |  160 -------
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_i2c.c       |   34 ++
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_i2c.h       |    3 +
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_mem.c       |  275 ++----------
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_notifier.c  |   30 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_object.c    |  105 ++---
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_reg.h       |   91 +++--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_sgdma.c     |   46 +--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nouveau_state.c     |  172 +++-----
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_crtc.c         |    5 +
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_dac.c          |   37 ++-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_dfp.c          |   12 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_display.c      |   64 ++--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_fifo.c         |   20 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_graph.c        |    5 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_instmem.c      |   21 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_mc.c           |    4 +
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv04_tv.c           |  125 ++----
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv10_fifo.c         |   10 -
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv17_tv.c           |   46 ++-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv20_graph.c        |   96 +++--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv40_fifo.c         |    8 -
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv40_graph.c        |   58 +--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv40_mc.c           |    2 +-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_crtc.c         |   42 +--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_dac.c          |   43 ++-
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_display.c      |  385 ++++++++++-------
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_fifo.c         |  126 ++----
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_graph.c        |   86 ++---
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_instmem.c      |   67 +--
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nv50_sor.c          |  105 +++---
Jesse Keating 7a32965
 drivers/gpu/drm/nouveau/nvreg.h             |   22 -
Jesse Keating 7a32965
 52 files changed, 1748 insertions(+), 1919 deletions(-)
Jesse Keating 7a32965
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
Jesse Keating 7a32965
index 9b2a541..1eaa315 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/drm_crtc_helper.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/drm_crtc_helper.c
Jesse Keating 7a32965
@@ -201,6 +201,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 EXPORT_SYMBOL(drm_helper_crtc_in_use);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static void
Jesse Keating 7a32965
+drm_encoder_disable(struct drm_encoder *encoder)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (encoder_funcs->disable)
Jesse Keating 7a32965
+		(*encoder_funcs->disable)(encoder);
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+		(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 /**
Jesse Keating 7a32965
  * drm_helper_disable_unused_functions - disable unused objects
Jesse Keating 7a32965
  * @dev: DRM device
Jesse Keating 7a32965
@@ -215,7 +226,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_encoder *encoder;
Jesse Keating 7a32965
 	struct drm_connector *connector;
Jesse Keating 7a32965
-	struct drm_encoder_helper_funcs *encoder_funcs;
Jesse Keating 7a32965
 	struct drm_crtc *crtc;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
Jesse Keating 7a32965
@@ -226,12 +236,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
Jesse Keating 7a32965
-		encoder_funcs = encoder->helper_private;
Jesse Keating 7a32965
 		if (!drm_helper_encoder_in_use(encoder)) {
Jesse Keating 7a32965
-			if (encoder_funcs->disable)
Jesse Keating 7a32965
-				(*encoder_funcs->disable)(encoder);
Jesse Keating 7a32965
-			else
Jesse Keating 7a32965
-				(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
Jesse Keating 7a32965
+			drm_encoder_disable(encoder);
Jesse Keating 7a32965
 			/* disconnector encoder from any connector */
Jesse Keating 7a32965
 			encoder->crtc = NULL;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
@@ -292,11 +298,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
Jesse Keating 7a32965
 		encoder_funcs = encoder->helper_private;
Jesse Keating 7a32965
 		/* Disable unused encoders */
Jesse Keating 7a32965
 		if (encoder->crtc == NULL)
Jesse Keating 7a32965
-			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
Jesse Keating 7a32965
+			drm_encoder_disable(encoder);
Jesse Keating 7a32965
 		/* Disable encoders whose CRTC is about to change */
Jesse Keating 7a32965
 		if (encoder_funcs->get_crtc &&
Jesse Keating 7a32965
 		    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
Jesse Keating 7a32965
-			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
Jesse Keating 7a32965
+			drm_encoder_disable(encoder);
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
Jesse Keating 7a32965
index 81681a0..833b35f 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/i2c/ch7006_drv.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
Jesse Keating 7a32965
@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder,
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	priv->params = params;
Jesse Keating 7a32965
+	priv->params = *(struct ch7006_encoder_params *)params;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static void ch7006_encoder_destroy(struct drm_encoder *encoder)
Jesse Keating 7a32965
@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
Jesse Keating 7a32965
 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
Jesse Keating 7a32965
-	struct ch7006_encoder_params *params = priv->params;
Jesse Keating 7a32965
+	struct ch7006_encoder_params *params = &priv->params;
Jesse Keating 7a32965
 	struct ch7006_state *state = &priv->state;
Jesse Keating 7a32965
 	uint8_t *regs = state->regs;
Jesse Keating 7a32965
 	struct ch7006_mode *mode = priv->mode;
Jesse Keating 7a32965
@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client)
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	ch7006_dbg(client, "\n");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int ch7006_resume(struct i2c_client *client)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	ch7006_dbg(client, "\n");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ch7006_write(client, 0x3d, 0x0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static int ch7006_encoder_init(struct i2c_client *client,
Jesse Keating 7a32965
 			       struct drm_device *dev,
Jesse Keating 7a32965
 			       struct drm_encoder_slave *encoder)
Jesse Keating 7a32965
@@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = {
Jesse Keating 7a32965
 	.i2c_driver = {
Jesse Keating 7a32965
 		.probe = ch7006_probe,
Jesse Keating 7a32965
 		.remove = ch7006_remove,
Jesse Keating 7a32965
+		.suspend = ch7006_suspend,
Jesse Keating 7a32965
+		.resume = ch7006_resume,
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		.driver = {
Jesse Keating 7a32965
 			.name = "ch7006",
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h
Jesse Keating 7a32965
index b06d3d9..1c6d2e3 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/i2c/ch7006_priv.h
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/i2c/ch7006_priv.h
Jesse Keating 7a32965
@@ -77,7 +77,7 @@ struct ch7006_state {
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct ch7006_priv {
Jesse Keating 7a32965
-	struct ch7006_encoder_params *params;
Jesse Keating 7a32965
+	struct ch7006_encoder_params params;
Jesse Keating 7a32965
 	struct ch7006_mode *mode;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct ch7006_state state;
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
Jesse Keating 7a32965
index acd31ed..4a1db73 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/Makefile
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/Makefile
Jesse Keating 7a32965
@@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
Jesse Keating 7a32965
              nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
Jesse Keating 7a32965
              nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
Jesse Keating 7a32965
              nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
Jesse Keating 7a32965
-             nouveau_dp.o nouveau_grctx.o \
Jesse Keating 7a32965
+             nouveau_dp.o \
Jesse Keating 7a32965
              nv04_timer.o \
Jesse Keating 7a32965
              nv04_mc.o nv40_mc.o nv50_mc.o \
Jesse Keating 7a32965
              nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
Jesse Keating 7a32965
index d4bcca8..c17a055 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
Jesse Keating 7a32965
@@ -3,6 +3,7 @@
Jesse Keating 7a32965
 #include <linux/slab.h>
Jesse Keating 7a32965
 #include <acpi/acpi_drivers.h>
Jesse Keating 7a32965
 #include <acpi/acpi_bus.h>
Jesse Keating 7a32965
+#include <acpi/video.h>
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #include "drmP.h"
Jesse Keating 7a32965
 #include "drm.h"
Jesse Keating 7a32965
@@ -11,6 +12,7 @@
Jesse Keating 7a32965
 #include "nouveau_drv.h"
Jesse Keating 7a32965
 #include "nouveau_drm.h"
Jesse Keating 7a32965
 #include "nv50_display.h"
Jesse Keating 7a32965
+#include "nouveau_connector.h"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #include <linux/vga_switcheroo.h>
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = {
Jesse Keating 7a32965
 	0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result)
Jesse Keating 7a32965
+static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
Jesse Keating 7a32965
 	struct acpi_object_list input;
Jesse Keating 7a32965
@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+int
Jesse Keating 7a32965
+nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
Jesse Keating 7a32965
+	struct acpi_device *acpidev;
Jesse Keating 7a32965
+	acpi_handle handle;
Jesse Keating 7a32965
+	int type, ret;
Jesse Keating 7a32965
+	void *edid;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	switch (connector->connector_type) {
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_LVDS:
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_eDP:
Jesse Keating 7a32965
+		type = ACPI_VIDEO_DISPLAY_LCD;
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+	default:
Jesse Keating 7a32965
+		return -EINVAL;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
Jesse Keating 7a32965
+	if (!handle)
Jesse Keating 7a32965
+		return -ENODEV;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ret = acpi_bus_get_device(handle, &acpidev);
Jesse Keating 7a32965
+	if (ret)
Jesse Keating 7a32965
+		return -ENODEV;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	ret = acpi_video_get_edid(acpidev, type, -1, &edid);
Jesse Keating 7a32965
+	if (ret < 0)
Jesse Keating 7a32965
+		return ret;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	nv_connector->edid = edid;
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
Jesse Keating 7a32965
index e492919..aae29cc 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
Jesse Keating 7a32965
@@ -28,6 +28,8 @@
Jesse Keating 7a32965
 #include "nouveau_hw.h"
Jesse Keating 7a32965
 #include "nouveau_encoder.h"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+#include <linux/io-mapping.h>
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 /* these defines are made up */
Jesse Keating 7a32965
 #define NV_CIO_CRE_44_HEADA 0x0
Jesse Keating 7a32965
 #define NV_CIO_CRE_44_HEADB 0x3
Jesse Keating 7a32965
@@ -209,20 +211,20 @@ static struct methods shadow_methods[] = {
Jesse Keating 7a32965
 	{ "PCIROM", load_vbios_pci, true },
Jesse Keating 7a32965
 	{ "ACPI", load_vbios_acpi, true },
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
+#define NUM_SHADOW_METHODS ARRAY_SIZE(shadow_methods)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	const int nr_methods = ARRAY_SIZE(shadow_methods);
Jesse Keating 7a32965
 	struct methods *methods = shadow_methods;
Jesse Keating 7a32965
 	int testscore = 3;
Jesse Keating 7a32965
-	int scores[nr_methods], i;
Jesse Keating 7a32965
+	int scores[NUM_SHADOW_METHODS], i;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (nouveau_vbios) {
Jesse Keating 7a32965
-		for (i = 0; i < nr_methods; i++)
Jesse Keating 7a32965
+		for (i = 0; i < NUM_SHADOW_METHODS; i++)
Jesse Keating 7a32965
 			if (!strcasecmp(nouveau_vbios, methods[i].desc))
Jesse Keating 7a32965
 				break;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		if (i < nr_methods) {
Jesse Keating 7a32965
+		if (i < NUM_SHADOW_METHODS) {
Jesse Keating 7a32965
 			NV_INFO(dev, "Attempting to use BIOS image from %s\n",
Jesse Keating 7a32965
 				methods[i].desc);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -234,7 +236,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
Jesse Keating 7a32965
 		NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios);
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	for (i = 0; i < nr_methods; i++) {
Jesse Keating 7a32965
+	for (i = 0; i < NUM_SHADOW_METHODS; i++) {
Jesse Keating 7a32965
 		NV_TRACE(dev, "Attempting to load BIOS image from %s\n",
Jesse Keating 7a32965
 			 methods[i].desc);
Jesse Keating 7a32965
 		data[0] = data[1] = 0;	/* avoid reuse of previous image */
Jesse Keating 7a32965
@@ -245,7 +247,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	while (--testscore > 0) {
Jesse Keating 7a32965
-		for (i = 0; i < nr_methods; i++) {
Jesse Keating 7a32965
+		for (i = 0; i < NUM_SHADOW_METHODS; i++) {
Jesse Keating 7a32965
 			if (scores[i] == testscore) {
Jesse Keating 7a32965
 				NV_TRACE(dev, "Using BIOS image from %s\n",
Jesse Keating 7a32965
 					 methods[i].desc);
Jesse Keating 7a32965
@@ -920,7 +922,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 		NV_ERROR(bios->dev,
Jesse Keating 7a32965
 			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
Jesse Keating 7a32965
 			 offset, config, count);
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	configval = ROM32(bios->data[offset + 11 + config * 4]);
Jesse Keating 7a32965
@@ -1022,7 +1024,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 		NV_ERROR(bios->dev,
Jesse Keating 7a32965
 			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
Jesse Keating 7a32965
 			 offset, config, count);
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	freq = ROM16(bios->data[offset + 12 + config * 2]);
Jesse Keating 7a32965
@@ -1194,7 +1196,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	dpe = nouveau_bios_dp_table(dev, dcb, &dummy);
Jesse Keating 7a32965
 	if (!dpe) {
Jesse Keating 7a32965
 		NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return 3;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	switch (cond) {
Jesse Keating 7a32965
@@ -1218,12 +1220,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
Jesse Keating 7a32965
-		if (!auxch)
Jesse Keating 7a32965
-			return -ENODEV;
Jesse Keating 7a32965
+		if (!auxch) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset);
Jesse Keating 7a32965
+			return 3;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
Jesse Keating 7a32965
-		if (ret)
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+		if (ret) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret);
Jesse Keating 7a32965
+			return 3;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		if (cond & 1)
Jesse Keating 7a32965
 			iexec->execute = false;
Jesse Keating 7a32965
@@ -1392,7 +1398,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 		NV_ERROR(bios->dev,
Jesse Keating 7a32965
 			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
Jesse Keating 7a32965
 			 offset, config, count);
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	freq = ROM32(bios->data[offset + 11 + config * 4]);
Jesse Keating 7a32965
@@ -1452,6 +1458,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	 * "mask n" and OR it with "data n" before writing it back to the device
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
 	uint8_t i2c_index = bios->data[offset + 1];
Jesse Keating 7a32965
 	uint8_t i2c_address = bios->data[offset + 2] >> 1;
Jesse Keating 7a32965
 	uint8_t count = bios->data[offset + 3];
Jesse Keating 7a32965
@@ -1466,9 +1473,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		      "Count: 0x%02X\n",
Jesse Keating 7a32965
 		offset, i2c_index, i2c_address, count);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	chan = init_i2c_device_find(bios->dev, i2c_index);
Jesse Keating 7a32965
-	if (!chan)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+	chan = init_i2c_device_find(dev, i2c_index);
Jesse Keating 7a32965
+	if (!chan) {
Jesse Keating 7a32965
+		NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	for (i = 0; i < count; i++) {
Jesse Keating 7a32965
 		uint8_t reg = bios->data[offset + 4 + i * 3];
Jesse Keating 7a32965
@@ -1479,8 +1488,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
Jesse Keating 7a32965
 				     I2C_SMBUS_READ, reg,
Jesse Keating 7a32965
 				     I2C_SMBUS_BYTE_DATA, &val;;
Jesse Keating 7a32965
-		if (ret < 0)
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+		if (ret < 0) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret);
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
Jesse Keating 7a32965
 			      "Mask: 0x%02X, Data: 0x%02X\n",
Jesse Keating 7a32965
@@ -1494,8 +1505,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
Jesse Keating 7a32965
 				     I2C_SMBUS_WRITE, reg,
Jesse Keating 7a32965
 				     I2C_SMBUS_BYTE_DATA, &val;;
Jesse Keating 7a32965
-		if (ret < 0)
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+		if (ret < 0) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return len;
Jesse Keating 7a32965
@@ -1520,6 +1533,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	 * "DCB I2C table entry index", set the register to "data n"
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
 	uint8_t i2c_index = bios->data[offset + 1];
Jesse Keating 7a32965
 	uint8_t i2c_address = bios->data[offset + 2] >> 1;
Jesse Keating 7a32965
 	uint8_t count = bios->data[offset + 3];
Jesse Keating 7a32965
@@ -1534,9 +1548,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		      "Count: 0x%02X\n",
Jesse Keating 7a32965
 		offset, i2c_index, i2c_address, count);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	chan = init_i2c_device_find(bios->dev, i2c_index);
Jesse Keating 7a32965
-	if (!chan)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+	chan = init_i2c_device_find(dev, i2c_index);
Jesse Keating 7a32965
+	if (!chan) {
Jesse Keating 7a32965
+		NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	for (i = 0; i < count; i++) {
Jesse Keating 7a32965
 		uint8_t reg = bios->data[offset + 4 + i * 2];
Jesse Keating 7a32965
@@ -1553,8 +1569,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
Jesse Keating 7a32965
 				     I2C_SMBUS_WRITE, reg,
Jesse Keating 7a32965
 				     I2C_SMBUS_BYTE_DATA, &val;;
Jesse Keating 7a32965
-		if (ret < 0)
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+		if (ret < 0) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return len;
Jesse Keating 7a32965
@@ -1577,6 +1595,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	 * address" on the I2C bus given by "DCB I2C table entry index"
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
 	uint8_t i2c_index = bios->data[offset + 1];
Jesse Keating 7a32965
 	uint8_t i2c_address = bios->data[offset + 2] >> 1;
Jesse Keating 7a32965
 	uint8_t count = bios->data[offset + 3];
Jesse Keating 7a32965
@@ -1584,7 +1603,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	struct nouveau_i2c_chan *chan;
Jesse Keating 7a32965
 	struct i2c_msg msg;
Jesse Keating 7a32965
 	uint8_t data[256];
Jesse Keating 7a32965
-	int i;
Jesse Keating 7a32965
+	int ret, i;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!iexec->execute)
Jesse Keating 7a32965
 		return len;
Jesse Keating 7a32965
@@ -1593,9 +1612,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		      "Count: 0x%02X\n",
Jesse Keating 7a32965
 		offset, i2c_index, i2c_address, count);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	chan = init_i2c_device_find(bios->dev, i2c_index);
Jesse Keating 7a32965
-	if (!chan)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+	chan = init_i2c_device_find(dev, i2c_index);
Jesse Keating 7a32965
+	if (!chan) {
Jesse Keating 7a32965
+		NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	for (i = 0; i < count; i++) {
Jesse Keating 7a32965
 		data[i] = bios->data[offset + 4 + i];
Jesse Keating 7a32965
@@ -1608,8 +1629,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		msg.flags = 0;
Jesse Keating 7a32965
 		msg.len = count;
Jesse Keating 7a32965
 		msg.buf = data;
Jesse Keating 7a32965
-		if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
Jesse Keating 7a32965
-			return -EIO;
Jesse Keating 7a32965
+		ret = i2c_transfer(&chan->adapter, &msg, 1);
Jesse Keating 7a32965
+		if (ret != 1) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return len;
Jesse Keating 7a32965
@@ -1633,6 +1657,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	 * used -- see get_tmds_index_reg()
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
 	uint8_t mlv = bios->data[offset + 1];
Jesse Keating 7a32965
 	uint32_t tmdsaddr = bios->data[offset + 2];
Jesse Keating 7a32965
 	uint8_t mask = bios->data[offset + 3];
Jesse Keating 7a32965
@@ -1647,8 +1672,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		offset, mlv, tmdsaddr, mask, data);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	reg = get_tmds_index_reg(bios->dev, mlv);
Jesse Keating 7a32965
-	if (!reg)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+	if (!reg) {
Jesse Keating 7a32965
+		NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
Jesse Keating 7a32965
+		return 5;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	bios_wr32(bios, reg,
Jesse Keating 7a32965
 		  tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
Jesse Keating 7a32965
@@ -1678,6 +1705,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	 * register is used -- see get_tmds_index_reg()
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
 	uint8_t mlv = bios->data[offset + 1];
Jesse Keating 7a32965
 	uint8_t count = bios->data[offset + 2];
Jesse Keating 7a32965
 	int len = 3 + count * 2;
Jesse Keating 7a32965
@@ -1691,8 +1719,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 		offset, mlv, count);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	reg = get_tmds_index_reg(bios->dev, mlv);
Jesse Keating 7a32965
-	if (!reg)
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+	if (!reg) {
Jesse Keating 7a32965
+		NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	for (i = 0; i < count; i++) {
Jesse Keating 7a32965
 		uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
Jesse Keating 7a32965
@@ -2039,6 +2069,323 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	return 5;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static inline void
Jesse Keating 7a32965
+bios_md32(struct nvbios *bios, uint32_t reg,
Jesse Keating 7a32965
+	  uint32_t mask, uint32_t val)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static uint32_t
Jesse Keating 7a32965
+peek_fb(struct drm_device *dev, struct io_mapping *fb,
Jesse Keating 7a32965
+	uint32_t off)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	uint32_t val = 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (off < pci_resource_len(dev->pdev, 1)) {
Jesse Keating 7a32965
+		uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		val = ioread32(p);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		io_mapping_unmap_atomic(p);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return val;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static void
Jesse Keating 7a32965
+poke_fb(struct drm_device *dev, struct io_mapping *fb,
Jesse Keating 7a32965
+	uint32_t off, uint32_t val)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	if (off < pci_resource_len(dev->pdev, 1)) {
Jesse Keating 7a32965
+		uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		iowrite32(val, p);
Jesse Keating 7a32965
+		wmb();
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		io_mapping_unmap_atomic(p);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static inline bool
Jesse Keating 7a32965
+read_back_fb(struct drm_device *dev, struct io_mapping *fb,
Jesse Keating 7a32965
+	     uint32_t off, uint32_t val)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	poke_fb(dev, fb, off, val);
Jesse Keating 7a32965
+	return val == peek_fb(dev, fb, off);
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int
Jesse Keating 7a32965
+nv04_init_compute_mem(struct nvbios *bios)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
+	uint32_t patt = 0xdeadbeef;
Jesse Keating 7a32965
+	struct io_mapping *fb;
Jesse Keating 7a32965
+	int i;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Map the framebuffer aperture */
Jesse Keating 7a32965
+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
Jesse Keating 7a32965
+				  pci_resource_len(dev->pdev, 1));
Jesse Keating 7a32965
+	if (!fb)
Jesse Keating 7a32965
+		return -ENOMEM;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Sequencer and refresh off */
Jesse Keating 7a32965
+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_BOOT_0, ~0,
Jesse Keating 7a32965
+		  NV04_PFB_BOOT_0_RAM_AMOUNT_16MB |
Jesse Keating 7a32965
+		  NV04_PFB_BOOT_0_RAM_WIDTH_128 |
Jesse Keating 7a32965
+		  NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	for (i = 0; i < 4; i++)
Jesse Keating 7a32965
+		poke_fb(dev, fb, 4 * i, patt);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	poke_fb(dev, fb, 0x400000, patt + 1);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (peek_fb(dev, fb, 0) == patt + 1) {
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT);
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_DEBUG_0,
Jesse Keating 7a32965
+			  NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		for (i = 0; i < 4; i++)
Jesse Keating 7a32965
+			poke_fb(dev, fb, 4 * i, patt);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff))
Jesse Keating 7a32965
+			bios_md32(bios, NV04_PFB_BOOT_0,
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_WIDTH_128 |
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	} else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) !=
Jesse Keating 7a32965
+		   (patt & 0xffff0000)) {
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_WIDTH_128 |
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	} else if (peek_fb(dev, fb, 0) == patt) {
Jesse Keating 7a32965
+		if (read_back_fb(dev, fb, 0x800000, patt))
Jesse Keating 7a32965
+			bios_md32(bios, NV04_PFB_BOOT_0,
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
Jesse Keating 7a32965
+		else
Jesse Keating 7a32965
+			bios_md32(bios, NV04_PFB_BOOT_0,
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+				  NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	} else if (!read_back_fb(dev, fb, 0x800000, patt)) {
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Refresh on, sequencer on */
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
Jesse Keating 7a32965
+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	io_mapping_free(fb);
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static const uint8_t *
Jesse Keating 7a32965
+nv05_memory_config(struct nvbios *bios)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	/* Defaults for BIOSes lacking a memory config table */
Jesse Keating 7a32965
+	static const uint8_t default_config_tab[][2] = {
Jesse Keating 7a32965
+		{ 0x24, 0x00 },
Jesse Keating 7a32965
+		{ 0x28, 0x00 },
Jesse Keating 7a32965
+		{ 0x24, 0x01 },
Jesse Keating 7a32965
+		{ 0x1f, 0x00 },
Jesse Keating 7a32965
+		{ 0x0f, 0x00 },
Jesse Keating 7a32965
+		{ 0x17, 0x00 },
Jesse Keating 7a32965
+		{ 0x06, 0x00 },
Jesse Keating 7a32965
+		{ 0x00, 0x00 }
Jesse Keating 7a32965
+	};
Jesse Keating 7a32965
+	int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) &
Jesse Keating 7a32965
+		 NV_PEXTDEV_BOOT_0_RAMCFG) >> 2;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (bios->legacy.mem_init_tbl_ptr)
Jesse Keating 7a32965
+		return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i];
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+		return default_config_tab[i];
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int
Jesse Keating 7a32965
+nv05_init_compute_mem(struct nvbios *bios)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
+	const uint8_t *ramcfg = nv05_memory_config(bios);
Jesse Keating 7a32965
+	uint32_t patt = 0xdeadbeef;
Jesse Keating 7a32965
+	struct io_mapping *fb;
Jesse Keating 7a32965
+	int i, v;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Map the framebuffer aperture */
Jesse Keating 7a32965
+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
Jesse Keating 7a32965
+				  pci_resource_len(dev->pdev, 1));
Jesse Keating 7a32965
+	if (!fb)
Jesse Keating 7a32965
+		return -ENOMEM;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Sequencer off */
Jesse Keating 7a32965
+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE)
Jesse Keating 7a32965
+		goto out;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* If present load the hardcoded scrambling table */
Jesse Keating 7a32965
+	if (bios->legacy.mem_init_tbl_ptr) {
Jesse Keating 7a32965
+		uint32_t *scramble_tab = (uint32_t *)&bios->data[
Jesse Keating 7a32965
+			bios->legacy.mem_init_tbl_ptr + 0x10];
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		for (i = 0; i < 8; i++)
Jesse Keating 7a32965
+			bios_wr32(bios, NV04_PFB_SCRAMBLE(i),
Jesse Keating 7a32965
+				  ROM32(scramble_tab[i]));
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Set memory type/width/length defaults depending on the straps */
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (ramcfg[1] & 0x80)
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20);
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_CFG1, 0, 1);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Probe memory bus width */
Jesse Keating 7a32965
+	for (i = 0; i < 4; i++)
Jesse Keating 7a32965
+		poke_fb(dev, fb, 4 * i, patt);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (peek_fb(dev, fb, 0xc) != patt)
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_WIDTH_128, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Probe memory length */
Jesse Keating 7a32965
+	v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB &&
Jesse Keating 7a32965
+	    (!read_back_fb(dev, fb, 0x1000000, ++patt) ||
Jesse Keating 7a32965
+	     !read_back_fb(dev, fb, 0, ++patt)))
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_AMOUNT_16MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB &&
Jesse Keating 7a32965
+	    !read_back_fb(dev, fb, 0x800000, ++patt))
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (!read_back_fb(dev, fb, 0x400000, ++patt))
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
Jesse Keating 7a32965
+			  NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+out:
Jesse Keating 7a32965
+	/* Sequencer on */
Jesse Keating 7a32965
+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	io_mapping_free(fb);
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int
Jesse Keating 7a32965
+nv10_init_compute_mem(struct nvbios *bios)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
Jesse Keating 7a32965
+	const int mem_width[] = { 0x10, 0x00, 0x20 };
Jesse Keating 7a32965
+	const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2);
Jesse Keating 7a32965
+	uint32_t patt = 0xdeadbeef;
Jesse Keating 7a32965
+	struct io_mapping *fb;
Jesse Keating 7a32965
+	int i, j, k;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Map the framebuffer aperture */
Jesse Keating 7a32965
+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
Jesse Keating 7a32965
+				  pci_resource_len(dev->pdev, 1));
Jesse Keating 7a32965
+	if (!fb)
Jesse Keating 7a32965
+		return -ENOMEM;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Probe memory bus width */
Jesse Keating 7a32965
+	for (i = 0; i < mem_width_count; i++) {
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		for (j = 0; j < 4; j++) {
Jesse Keating 7a32965
+			for (k = 0; k < 4; k++)
Jesse Keating 7a32965
+				poke_fb(dev, fb, 0x1c, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+			poke_fb(dev, fb, 0x1c, patt);
Jesse Keating 7a32965
+			poke_fb(dev, fb, 0x3c, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+			if (peek_fb(dev, fb, 0x1c) == patt)
Jesse Keating 7a32965
+				goto mem_width_found;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+mem_width_found:
Jesse Keating 7a32965
+	patt <<= 1;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Probe amount of installed memory */
Jesse Keating 7a32965
+	for (i = 0; i < 4; i++) {
Jesse Keating 7a32965
+		int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		poke_fb(dev, fb, off, patt);
Jesse Keating 7a32965
+		poke_fb(dev, fb, 0, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		peek_fb(dev, fb, 0);
Jesse Keating 7a32965
+		peek_fb(dev, fb, 0);
Jesse Keating 7a32965
+		peek_fb(dev, fb, 0);
Jesse Keating 7a32965
+		peek_fb(dev, fb, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+		if (peek_fb(dev, fb, off) == patt)
Jesse Keating 7a32965
+			goto amount_found;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* IC missing - disable the upper half memory space. */
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+amount_found:
Jesse Keating 7a32965
+	io_mapping_free(fb);
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+static int
Jesse Keating 7a32965
+nv20_init_compute_mem(struct nvbios *bios)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_device *dev = bios->dev;
Jesse Keating 7a32965
+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
Jesse Keating 7a32965
+	uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900);
Jesse Keating 7a32965
+	uint32_t amount, off;
Jesse Keating 7a32965
+	struct io_mapping *fb;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Map the framebuffer aperture */
Jesse Keating 7a32965
+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
Jesse Keating 7a32965
+				  pci_resource_len(dev->pdev, 1));
Jesse Keating 7a32965
+	if (!fb)
Jesse Keating 7a32965
+		return -ENOMEM;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Allow full addressing */
Jesse Keating 7a32965
+	bios_md32(bios, NV04_PFB_CFG0, 0, mask);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
Jesse Keating 7a32965
+	for (off = amount; off > 0x2000000; off -= 0x2000000)
Jesse Keating 7a32965
+		poke_fb(dev, fb, off - 4, off);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
Jesse Keating 7a32965
+	if (amount != peek_fb(dev, fb, amount - 4))
Jesse Keating 7a32965
+		/* IC missing - disable the upper half memory space. */
Jesse Keating 7a32965
+		bios_md32(bios, NV04_PFB_CFG0, mask, 0);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	io_mapping_free(fb);
Jesse Keating 7a32965
+	return 0;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static int
Jesse Keating 7a32965
 init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
@@ -2047,64 +2394,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
 	 * offset      (8 bit): opcode
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so
Jesse Keating 7a32965
-	 * that the hardware can correctly calculate how much VRAM it has
Jesse Keating 7a32965
-	 * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C))
Jesse Keating 7a32965
+	 * This opcode is meant to set the PFB memory config registers
Jesse Keating 7a32965
+	 * appropriately so that we can correctly calculate how much VRAM it
Jesse Keating 7a32965
+	 * has (on nv10 and better chipsets the amount of installed VRAM is
Jesse Keating 7a32965
+	 * subsequently reported in NV_PFB_CSTATUS (0x10020C)).
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * The implementation of this opcode in general consists of two parts:
Jesse Keating 7a32965
-	 * 1) determination of the memory bus width
Jesse Keating 7a32965
-	 * 2) determination of how many of the card's RAM pads have ICs attached
Jesse Keating 7a32965
+	 * The implementation of this opcode in general consists of several
Jesse Keating 7a32965
+	 * parts:
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * 1) is done by a cunning combination of writes to offsets 0x1c and
Jesse Keating 7a32965
-	 * 0x3c in the framebuffer, and seeing whether the written values are
Jesse Keating 7a32965
-	 * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0
Jesse Keating 7a32965
+	 * 1) Determination of memory type and density. Only necessary for
Jesse Keating 7a32965
+	 *    really old chipsets, the memory type reported by the strap bits
Jesse Keating 7a32965
+	 *    (0x101000) is assumed to be accurate on nv05 and newer.
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * 2) is done by a cunning combination of writes to an offset slightly
Jesse Keating 7a32965
-	 * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing
Jesse Keating 7a32965
-	 * if the test pattern can be read back. This then affects bits 12-15 of
Jesse Keating 7a32965
-	 * NV_PFB_CFG0
Jesse Keating 7a32965
+	 * 2) Determination of the memory bus width. Usually done by a cunning
Jesse Keating 7a32965
+	 *    combination of writes to offsets 0x1c and 0x3c in the fb, and
Jesse Keating 7a32965
+	 *    seeing whether the written values are read back correctly.
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * In this context a "cunning combination" may include multiple reads
Jesse Keating 7a32965
-	 * and writes to varying locations, often alternating the test pattern
Jesse Keating 7a32965
-	 * and 0, doubtless to make sure buffers are filled, residual charges
Jesse Keating 7a32965
-	 * on tracks are removed etc.
Jesse Keating 7a32965
+	 *    Only necessary on nv0x-nv1x and nv34, on the other cards we can
Jesse Keating 7a32965
+	 *    trust the straps.
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * Unfortunately, the "cunning combination"s mentioned above, and the
Jesse Keating 7a32965
-	 * changes to the bits in NV_PFB_CFG0 differ with nearly every bios
Jesse Keating 7a32965
-	 * trace I have.
Jesse Keating 7a32965
+	 * 3) Determination of how many of the card's RAM pads have ICs
Jesse Keating 7a32965
+	 *    attached, usually done by a cunning combination of writes to an
Jesse Keating 7a32965
+	 *    offset slightly less than the maximum memory reported by
Jesse Keating 7a32965
+	 *    NV_PFB_CSTATUS, then seeing if the test pattern can be read back.
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which
Jesse Keating 7a32965
-	 * we started was correct, and use that instead
Jesse Keating 7a32965
+	 * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io
Jesse Keating 7a32965
+	 * logs of the VBIOS and kmmio traces of the binary driver POSTing the
Jesse Keating 7a32965
+	 * card show nothing being done for this opcode. Why is it still listed
Jesse Keating 7a32965
+	 * in the table?!
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* no iexec->execute check by design */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS
Jesse Keating 7a32965
-	 * and kmmio traces of the binary driver POSTing the card show nothing
Jesse Keating 7a32965
-	 * being done for this opcode.  why is it still listed in the table?!
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
Jesse Keating 7a32965
+	int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (dev_priv->card_type >= NV_40)
Jesse Keating 7a32965
-		return 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * On every card I've seen, this step gets done for us earlier in
Jesse Keating 7a32965
-	 * the init scripts
Jesse Keating 7a32965
-	uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01);
Jesse Keating 7a32965
-	bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20);
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * This also has probably been done in the scripts, but an mmio trace of
Jesse Keating 7a32965
-	 * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write)
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1);
Jesse Keating 7a32965
+	if (dev_priv->chipset >= 0x40 ||
Jesse Keating 7a32965
+	    dev_priv->chipset == 0x1a ||
Jesse Keating 7a32965
+	    dev_priv->chipset == 0x1f)
Jesse Keating 7a32965
+		ret = 0;
Jesse Keating 7a32965
+	else if (dev_priv->chipset >= 0x20 &&
Jesse Keating 7a32965
+		 dev_priv->chipset != 0x34)
Jesse Keating 7a32965
+		ret = nv20_init_compute_mem(bios);
Jesse Keating 7a32965
+	else if (dev_priv->chipset >= 0x10)
Jesse Keating 7a32965
+		ret = nv10_init_compute_mem(bios);
Jesse Keating 7a32965
+	else if (dev_priv->chipset >= 0x5)
Jesse Keating 7a32965
+		ret = nv05_init_compute_mem(bios);
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+		ret = nv04_init_compute_mem(bios);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/* write back the saved configuration value */
Jesse Keating 7a32965
-	bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0);
Jesse Keating 7a32965
+	if (ret)
Jesse Keating 7a32965
+		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return 1;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
@@ -2131,7 +2471,8 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 	/* no iexec->execute check by design */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19);
Jesse Keating 7a32965
-	bios_wr32(bios, NV_PBUS_PCI_NV_19, 0);
Jesse Keating 7a32965
+	bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	bios_wr32(bios, reg, value1);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	udelay(10);
Jesse Keating 7a32965
@@ -2167,7 +2508,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	uint32_t reg, data;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (bios->major_version > 2)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
Jesse Keating 7a32965
 		       bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
Jesse Keating 7a32965
@@ -2180,14 +2521,14 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	     reg = ROM32(bios->data[seqtbloffs += 4])) {
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		switch (reg) {
Jesse Keating 7a32965
-		case NV_PFB_PRE:
Jesse Keating 7a32965
-			data = NV_PFB_PRE_CMD_PRECHARGE;
Jesse Keating 7a32965
+		case NV04_PFB_PRE:
Jesse Keating 7a32965
+			data = NV04_PFB_PRE_CMD_PRECHARGE;
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
-		case NV_PFB_PAD:
Jesse Keating 7a32965
-			data = NV_PFB_PAD_CKE_NORMAL;
Jesse Keating 7a32965
+		case NV04_PFB_PAD:
Jesse Keating 7a32965
+			data = NV04_PFB_PAD_CKE_NORMAL;
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
-		case NV_PFB_REF:
Jesse Keating 7a32965
-			data = NV_PFB_REF_CMD_REFRESH;
Jesse Keating 7a32965
+		case NV04_PFB_REF:
Jesse Keating 7a32965
+			data = NV04_PFB_REF_CMD_REFRESH;
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 		default:
Jesse Keating 7a32965
 			data = ROM32(bios->data[meminitdata]);
Jesse Keating 7a32965
@@ -2222,7 +2563,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	int clock;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (bios->major_version > 2)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	clock = ROM16(bios->data[meminitoffs + 4]) * 10;
Jesse Keating 7a32965
 	setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
Jesse Keating 7a32965
@@ -2255,7 +2596,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (bios->major_version > 2)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
Jesse Keating 7a32965
 			     NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
Jesse Keating 7a32965
@@ -2389,7 +2730,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	 * offset + 1  (8 bit): mask
Jesse Keating 7a32965
 	 * offset + 2  (8 bit): cmpval
Jesse Keating 7a32965
 	 *
Jesse Keating 7a32965
-	 * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval".
Jesse Keating 7a32965
+	 * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval".
Jesse Keating 7a32965
 	 * If condition not met skip subsequent opcodes until condition is
Jesse Keating 7a32965
 	 * inverted (INIT_NOT), or we hit INIT_RESUME
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
@@ -2401,7 +2742,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	if (!iexec->execute)
Jesse Keating 7a32965
 		return 3;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	data = bios_rd32(bios, NV_PFB_BOOT_0) & mask;
Jesse Keating 7a32965
+	data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
Jesse Keating 7a32965
 		offset, data, cmpval);
Jesse Keating 7a32965
@@ -2800,7 +3141,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (dev_priv->card_type != NV_50) {
Jesse Keating 7a32965
 		NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+		return 1;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!iexec->execute)
Jesse Keating 7a32965
@@ -2872,10 +3213,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 	uint8_t index;
Jesse Keating 7a32965
 	int i;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!iexec->execute)
Jesse Keating 7a32965
-		return len;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
+	/* critical! to know the length of the opcode */;
Jesse Keating 7a32965
 	if (!blocklen) {
Jesse Keating 7a32965
 		NV_ERROR(bios->dev,
Jesse Keating 7a32965
 			 "0x%04X: Zero block length - has the M table "
Jesse Keating 7a32965
@@ -2883,6 +3221,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	if (!iexec->execute)
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
Jesse Keating 7a32965
 	index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -3064,14 +3405,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!bios->display.output) {
Jesse Keating 7a32965
 		NV_ERROR(dev, "INIT_AUXCH: no active output\n");
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
Jesse Keating 7a32965
 	if (!auxch) {
Jesse Keating 7a32965
 		NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
Jesse Keating 7a32965
 			 bios->display.output->i2c_index);
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!iexec->execute)
Jesse Keating 7a32965
@@ -3084,7 +3425,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
Jesse Keating 7a32965
 		if (ret) {
Jesse Keating 7a32965
 			NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		data &= bios->data[offset + 0];
Jesse Keating 7a32965
@@ -3093,7 +3434,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
Jesse Keating 7a32965
 		if (ret) {
Jesse Keating 7a32965
 			NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -3123,14 +3464,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!bios->display.output) {
Jesse Keating 7a32965
 		NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
Jesse Keating 7a32965
 	if (!auxch) {
Jesse Keating 7a32965
 		NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
Jesse Keating 7a32965
 			 bios->display.output->i2c_index);
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
+		return len;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!iexec->execute)
Jesse Keating 7a32965
@@ -3141,7 +3482,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
Jesse Keating 7a32965
 		ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
Jesse Keating 7a32965
 		if (ret) {
Jesse Keating 7a32965
 			NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
+			return len;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -5151,10 +5492,14 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
Jesse Keating 7a32965
 	bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
Jesse Keating 7a32965
 	bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
Jesse Keating 7a32965
 	bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
Jesse Keating 7a32965
-	bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
Jesse Keating 7a32965
-	bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
Jesse Keating 7a32965
-	bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
Jesse Keating 7a32965
-	bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
Jesse Keating 7a32965
+	if (bios->data[legacy_i2c_offset + 4])
Jesse Keating 7a32965
+		bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
Jesse Keating 7a32965
+	if (bios->data[legacy_i2c_offset + 5])
Jesse Keating 7a32965
+		bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
Jesse Keating 7a32965
+	if (bios->data[legacy_i2c_offset + 6])
Jesse Keating 7a32965
+		bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
Jesse Keating 7a32965
+	if (bios->data[legacy_i2c_offset + 7])
Jesse Keating 7a32965
+		bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (bmplength > 74) {
Jesse Keating 7a32965
 		bios->fmaxvco = ROM32(bmp[67]);
Jesse Keating 7a32965
@@ -5589,9 +5934,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
Jesse Keating 7a32965
 			if (conf & 0x4 || conf & 0x8)
Jesse Keating 7a32965
 				entry->lvdsconf.use_power_scripts = true;
Jesse Keating 7a32965
 		} else {
Jesse Keating 7a32965
-			mask = ~0x5;
Jesse Keating 7a32965
+			mask = ~0x7;
Jesse Keating 7a32965
+			if (conf & 0x2)
Jesse Keating 7a32965
+				entry->lvdsconf.use_acpi_for_edid = true;
Jesse Keating 7a32965
 			if (conf & 0x4)
Jesse Keating 7a32965
 				entry->lvdsconf.use_power_scripts = true;
Jesse Keating 7a32965
+			entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 		if (conf & mask) {
Jesse Keating 7a32965
 			/*
Jesse Keating 7a32965
@@ -5706,13 +6054,6 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
Jesse Keating 7a32965
 	case OUTPUT_TV:
Jesse Keating 7a32965
 		entry->tvconf.has_component_output = false;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
-	case OUTPUT_TMDS:
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * Invent a DVI-A output, by copying the fields of the DVI-D
Jesse Keating 7a32965
-		 * output; reported to work by math_b on an NV20(!).
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		fabricate_vga_output(dcb, entry->i2c_index, entry->heads);
Jesse Keating 7a32965
-		break;
Jesse Keating 7a32965
 	case OUTPUT_LVDS:
Jesse Keating 7a32965
 		if ((conn & 0x00003f00) != 0x10)
Jesse Keating 7a32965
 			entry->lvdsconf.use_straps_for_mode = true;
Jesse Keating 7a32965
@@ -5793,6 +6134,31 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
Jesse Keating 7a32965
 	dcb->entries = newentries;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static bool
Jesse Keating 7a32965
+apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	/* Dell Precision M6300
Jesse Keating 7a32965
+	 *   DCB entry 2: 02025312 00000010
Jesse Keating 7a32965
+	 *   DCB entry 3: 02026312 00000020
Jesse Keating 7a32965
+	 *
Jesse Keating 7a32965
+	 * Identical, except apparently a different connector on a
Jesse Keating 7a32965
+	 * different SOR link.  Not a clue how we're supposed to know
Jesse Keating 7a32965
+	 * which one is in use if it even shares an i2c line...
Jesse Keating 7a32965
+	 *
Jesse Keating 7a32965
+	 * Ignore the connector on the second SOR link to prevent
Jesse Keating 7a32965
+	 * nasty problems until this is sorted (assuming it's not a
Jesse Keating 7a32965
+	 * VBIOS bug).
Jesse Keating 7a32965
+	 */
Jesse Keating 7a32965
+	if ((dev->pdev->device == 0x040d) &&
Jesse Keating 7a32965
+	    (dev->pdev->subsystem_vendor == 0x1028) &&
Jesse Keating 7a32965
+	    (dev->pdev->subsystem_device == 0x019b)) {
Jesse Keating 7a32965
+		if (*conn == 0x02026312 && *conf == 0x00000020)
Jesse Keating 7a32965
+			return false;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return true;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static int
Jesse Keating 7a32965
 parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
@@ -5926,6 +6292,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
Jesse Keating 7a32965
 		if ((connection & 0x0000000f) == 0x0000000f)
Jesse Keating 7a32965
 			continue;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+		if (!apply_dcb_encoder_quirks(dev, i, &connection, &config))
Jesse Keating 7a32965
+			continue;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 		NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n",
Jesse Keating 7a32965
 			     dcb->entries, connection, config);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -6182,8 +6551,10 @@ nouveau_run_vbios_init(struct drm_device *dev)
Jesse Keating 7a32965
 	int i, ret = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
-	if (nv_two_heads(dev))
Jesse Keating 7a32965
-		NVSetOwner(dev, bios->state.crtchead);
Jesse Keating 7a32965
+	if (nv_two_heads(dev)) {
Jesse Keating 7a32965
+		bios->state.crtchead = 0;
Jesse Keating 7a32965
+		NVSetOwner(dev, 0);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (bios->major_version < 5)	/* BMP only */
Jesse Keating 7a32965
 		load_nv17_hw_sequencer_ucode(dev, bios);
Jesse Keating 7a32965
@@ -6238,7 +6609,6 @@ static bool
Jesse Keating 7a32965
 nouveau_bios_posted(struct drm_device *dev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
-	bool was_locked;
Jesse Keating 7a32965
 	unsigned htotal;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (dev_priv->chipset >= NV_50) {
Jesse Keating 7a32965
@@ -6248,13 +6618,14 @@ nouveau_bios_posted(struct drm_device *dev)
Jesse Keating 7a32965
 		return true;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	was_locked = NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
+	NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
 	htotal  = NVReadVgaCrtc(dev, 0, 0x06);
Jesse Keating 7a32965
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
Jesse Keating 7a32965
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
Jesse Keating 7a32965
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
Jesse Keating 7a32965
 	htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
Jesse Keating 7a32965
-	NVLockVgaCrtcs(dev, was_locked);
Jesse Keating 7a32965
+	NVLockVgaCrtcs(dev, true);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	return (htotal != 0);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -6263,8 +6634,6 @@ nouveau_bios_init(struct drm_device *dev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
 	struct nvbios *bios = &dev_priv->vbios;
Jesse Keating 7a32965
-	uint32_t saved_nv_pextdev_boot_0;
Jesse Keating 7a32965
-	bool was_locked;
Jesse Keating 7a32965
 	int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (!NVInitVBIOS(dev))
Jesse Keating 7a32965
@@ -6284,40 +6653,29 @@ nouveau_bios_init(struct drm_device *dev)
Jesse Keating 7a32965
 	if (!bios->major_version)	/* we don't run version 0 bios */
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/* these will need remembering across a suspend */
Jesse Keating 7a32965
-	saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
Jesse Keating 7a32965
-	bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	/* init script execution disabled */
Jesse Keating 7a32965
 	bios->execute = false;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* ... unless card isn't POSTed already */
Jesse Keating 7a32965
 	if (!nouveau_bios_posted(dev)) {
Jesse Keating 7a32965
-		NV_INFO(dev, "Adaptor not initialised\n");
Jesse Keating 7a32965
-		if (dev_priv->card_type < NV_40) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "Unable to POST this chipset\n");
Jesse Keating 7a32965
-			return -ENODEV;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		NV_INFO(dev, "Running VBIOS init tables\n");
Jesse Keating 7a32965
+		NV_INFO(dev, "Adaptor not initialised, "
Jesse Keating 7a32965
+			"running VBIOS init tables.\n");
Jesse Keating 7a32965
 		bios->execute = true;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	ret = nouveau_run_vbios_init(dev);
Jesse Keating 7a32965
 	if (ret)
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* feature_byte on BMP is poor, but init always sets CR4B */
Jesse Keating 7a32965
-	was_locked = NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
+	NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
 	if (bios->major_version < 5)
Jesse Keating 7a32965
 		bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* all BIT systems need p_f_m_t for digital_min_front_porch */
Jesse Keating 7a32965
 	if (bios->is_mobile || bios->major_version >= 5)
Jesse Keating 7a32965
 		ret = parse_fp_mode_table(dev, bios);
Jesse Keating 7a32965
-	NVLockVgaCrtcs(dev, was_locked);
Jesse Keating 7a32965
+	NVLockVgaCrtcs(dev, true);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* allow subsequent scripts to execute */
Jesse Keating 7a32965
 	bios->execute = true;
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
Jesse Keating 7a32965
index adf4ec2..024458a 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
Jesse Keating 7a32965
@@ -81,6 +81,7 @@ struct dcb_connector_table_entry {
Jesse Keating 7a32965
 	enum dcb_connector_type type;
Jesse Keating 7a32965
 	uint8_t index2;
Jesse Keating 7a32965
 	uint8_t gpio_tag;
Jesse Keating 7a32965
+	void *drm;
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct dcb_connector_table {
Jesse Keating 7a32965
@@ -117,6 +118,7 @@ struct dcb_entry {
Jesse Keating 7a32965
 		struct {
Jesse Keating 7a32965
 			struct sor_conf sor;
Jesse Keating 7a32965
 			bool use_straps_for_mode;
Jesse Keating 7a32965
+			bool use_acpi_for_edid;
Jesse Keating 7a32965
 			bool use_power_scripts;
Jesse Keating 7a32965
 		} lvdsconf;
Jesse Keating 7a32965
 		struct {
Jesse Keating 7a32965
@@ -249,8 +251,6 @@ struct nvbios {
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct {
Jesse Keating 7a32965
 		int crtchead;
Jesse Keating 7a32965
-		/* these need remembering across suspend */
Jesse Keating 7a32965
-		uint32_t saved_nv_pfb_cfg0;
Jesse Keating 7a32965
 	} state;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct {
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
Jesse Keating 7a32965
index 6f3c195..d8c341d 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
Jesse Keating 7a32965
@@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
Jesse Keating 7a32965
-					evict, no_wait_reserve, no_wait_gpu, new_mem);
Jesse Keating 7a32965
-	if (nvbo->channel && nvbo->channel != chan)
Jesse Keating 7a32965
-		ret = nouveau_fence_wait(fence, NULL, false, false);
Jesse Keating 7a32965
+					evict || (nvbo->channel &&
Jesse Keating 7a32965
+						  nvbo->channel != chan),
Jesse Keating 7a32965
+					no_wait_reserve, no_wait_gpu, new_mem);
Jesse Keating 7a32965
 	nouveau_fence_unref((void *)&fence);
Jesse Keating 7a32965
 	return ret;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
@@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Software copy if the card isn't up and running yet. */
Jesse Keating 7a32965
-	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE ||
Jesse Keating 7a32965
-	    !dev_priv->channel) {
Jesse Keating 7a32965
+	if (!dev_priv->channel) {
Jesse Keating 7a32965
 		ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
Jesse Keating 7a32965
 		goto out;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c
Jesse Keating 7a32965
index 88f9bc0..ca85da7 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_calc.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_calc.c
Jesse Keating 7a32965
@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
Jesse Keating 7a32965
 	struct nv_sim_state sim_data;
Jesse Keating 7a32965
 	int MClk = nouveau_hw_get_clock(dev, MPLL);
Jesse Keating 7a32965
 	int NVClk = nouveau_hw_get_clock(dev, NVPLL);
Jesse Keating 7a32965
-	uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1);
Jesse Keating 7a32965
+	uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	sim_data.pclk_khz = VClk;
Jesse Keating 7a32965
 	sim_data.mclk_khz = MClk;
Jesse Keating 7a32965
@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
Jesse Keating 7a32965
 		sim_data.mem_latency = 3;
Jesse Keating 7a32965
 		sim_data.mem_page_miss = 10;
Jesse Keating 7a32965
 	} else {
Jesse Keating 7a32965
-		sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1;
Jesse Keating 7a32965
+		sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1;
Jesse Keating 7a32965
 		sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
Jesse Keating 7a32965
 		sim_data.mem_latency = cfg1 & 0xf;
Jesse Keating 7a32965
 		sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
Jesse Keating 7a32965
index 1fc57ef..e952c3b 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
Jesse Keating 7a32965
@@ -257,9 +257,7 @@ nouveau_channel_free(struct nouveau_channel *chan)
Jesse Keating 7a32965
 	nouveau_debugfs_channel_fini(chan);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Give outstanding push buffers a chance to complete */
Jesse Keating 7a32965
-	spin_lock_irqsave(&chan->fence.lock, flags);
Jesse Keating 7a32965
 	nouveau_fence_update(chan);
Jesse Keating 7a32965
-	spin_unlock_irqrestore(&chan->fence.lock, flags);
Jesse Keating 7a32965
 	if (chan->fence.sequence != chan->fence.sequence_ack) {
Jesse Keating 7a32965
 		struct nouveau_fence *fence = NULL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -368,8 +366,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	struct nouveau_channel *chan;
Jesse Keating 7a32965
 	int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	if (dev_priv->engine.graph.accel_blocked)
Jesse Keating 7a32965
 		return -ENODEV;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -418,7 +414,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	struct drm_nouveau_channel_free *cfree = data;
Jesse Keating 7a32965
 	struct nouveau_channel *chan;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	nouveau_channel_free(chan);
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
Jesse Keating 7a32965
index 149ed22..734e926 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
Jesse Keating 7a32965
@@ -102,63 +102,15 @@ nouveau_connector_destroy(struct drm_connector *drm_connector)
Jesse Keating 7a32965
 	kfree(drm_connector);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static void
Jesse Keating 7a32965
-nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (dev_priv->card_type >= NV_50)
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	*flags = 0;
Jesse Keating 7a32965
-	if (NVLockVgaCrtcs(dev_priv->dev, false))
Jesse Keating 7a32965
-		*flags |= 1;
Jesse Keating 7a32965
-	if (nv_heads_tied(dev_priv->dev))
Jesse Keating 7a32965
-		*flags |= 2;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (*flags & 2)
Jesse Keating 7a32965
-		NVSetOwner(dev_priv->dev, 0); /* necessary? */
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-static void
Jesse Keating 7a32965
-nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (dev_priv->card_type >= NV_50)
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (flags & 2)
Jesse Keating 7a32965
-		NVSetOwner(dev_priv->dev, 4);
Jesse Keating 7a32965
-	if (flags & 1)
Jesse Keating 7a32965
-		NVLockVgaCrtcs(dev_priv->dev, true);
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static struct nouveau_i2c_chan *
Jesse Keating 7a32965
 nouveau_connector_ddc_detect(struct drm_connector *connector,
Jesse Keating 7a32965
 			     struct nouveau_encoder **pnv_encoder)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_device *dev = connector->dev;
Jesse Keating 7a32965
-	uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
Jesse Keating 7a32965
-	int ret, flags, i;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	struct i2c_msg msgs[] = {
Jesse Keating 7a32965
-		{
Jesse Keating 7a32965
-			.addr = 0x50,
Jesse Keating 7a32965
-			.flags = 0,
Jesse Keating 7a32965
-			.len = 1,
Jesse Keating 7a32965
-			.buf = out_buf,
Jesse Keating 7a32965
-		},
Jesse Keating 7a32965
-		{
Jesse Keating 7a32965
-			.addr = 0x50,
Jesse Keating 7a32965
-			.flags = I2C_M_RD,
Jesse Keating 7a32965
-			.len = 1,
Jesse Keating 7a32965
-			.buf = buf,
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-	};
Jesse Keating 7a32965
+	int i;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
Jesse Keating 7a32965
-		struct nouveau_i2c_chan *i2c = NULL;
Jesse Keating 7a32965
+		struct nouveau_i2c_chan *i2c;
Jesse Keating 7a32965
 		struct nouveau_encoder *nv_encoder;
Jesse Keating 7a32965
 		struct drm_mode_object *obj;
Jesse Keating 7a32965
 		int id;
Jesse Keating 7a32965
@@ -171,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
Jesse Keating 7a32965
 		if (!obj)
Jesse Keating 7a32965
 			continue;
Jesse Keating 7a32965
 		nv_encoder = nouveau_encoder(obj_to_encoder(obj));
Jesse Keating 7a32965
+		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		if (nv_encoder->dcb->i2c_index < 0xf)
Jesse Keating 7a32965
-			i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
Jesse Keating 7a32965
-		if (!i2c)
Jesse Keating 7a32965
-			continue;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		nouveau_connector_ddc_prepare(connector, &flags);
Jesse Keating 7a32965
-		ret = i2c_transfer(&i2c->adapter, msgs, 2);
Jesse Keating 7a32965
-		nouveau_connector_ddc_finish(connector, flags);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (ret == 2) {
Jesse Keating 7a32965
+		if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
Jesse Keating 7a32965
 			*pnv_encoder = nv_encoder;
Jesse Keating 7a32965
 			return i2c;
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
@@ -234,21 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector)
Jesse Keating 7a32965
 	struct nouveau_connector *nv_connector = nouveau_connector(connector);
Jesse Keating 7a32965
 	struct nouveau_encoder *nv_encoder = NULL;
Jesse Keating 7a32965
 	struct nouveau_i2c_chan *i2c;
Jesse Keating 7a32965
-	int type, flags;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS)
Jesse Keating 7a32965
-		nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
Jesse Keating 7a32965
-	if (nv_encoder && nv_connector->native_mode) {
Jesse Keating 7a32965
-		unsigned status = connector_status_connected;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-#if defined(CONFIG_ACPI_BUTTON) || \
Jesse Keating 7a32965
-	(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
Jesse Keating 7a32965
-		if (!nouveau_ignorelid && !acpi_lid_open())
Jesse Keating 7a32965
-			status = connector_status_unknown;
Jesse Keating 7a32965
-#endif
Jesse Keating 7a32965
-		nouveau_connector_set_encoder(connector, nv_encoder);
Jesse Keating 7a32965
-		return status;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+	int type;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Cleanup the previous EDID block. */
Jesse Keating 7a32965
 	if (nv_connector->edid) {
Jesse Keating 7a32965
@@ -259,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
Jesse Keating 7a32965
 	if (i2c) {
Jesse Keating 7a32965
-		nouveau_connector_ddc_prepare(connector, &flags);
Jesse Keating 7a32965
 		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
Jesse Keating 7a32965
-		nouveau_connector_ddc_finish(connector, flags);
Jesse Keating 7a32965
 		drm_mode_connector_update_edid_property(connector,
Jesse Keating 7a32965
 							nv_connector->edid);
Jesse Keating 7a32965
 		if (!nv_connector->edid) {
Jesse Keating 7a32965
@@ -321,6 +249,85 @@ detect_analog:
Jesse Keating 7a32965
 	return connector_status_disconnected;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+static enum drm_connector_status
Jesse Keating 7a32965
+nouveau_connector_detect_lvds(struct drm_connector *connector)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_device *dev = connector->dev;
Jesse Keating 7a32965
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
Jesse Keating 7a32965
+	struct nouveau_encoder *nv_encoder = NULL;
Jesse Keating 7a32965
+	enum drm_connector_status status = connector_status_disconnected;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Cleanup the previous EDID block. */
Jesse Keating 7a32965
+	if (nv_connector->edid) {
Jesse Keating 7a32965
+		drm_mode_connector_update_edid_property(connector, NULL);
Jesse Keating 7a32965
+		kfree(nv_connector->edid);
Jesse Keating 7a32965
+		nv_connector->edid = NULL;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
Jesse Keating 7a32965
+	if (!nv_encoder)
Jesse Keating 7a32965
+		return connector_status_disconnected;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Try retrieving EDID via DDC */
Jesse Keating 7a32965
+	if (!dev_priv->vbios.fp_no_ddc) {
Jesse Keating 7a32965
+		status = nouveau_connector_detect(connector);
Jesse Keating 7a32965
+		if (status == connector_status_connected)
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* On some laptops (Sony, i'm looking at you) there appears to
Jesse Keating 7a32965
+	 * be no direct way of accessing the panel's EDID.  The only
Jesse Keating 7a32965
+	 * option available to us appears to be to ask ACPI for help..
Jesse Keating 7a32965
+	 *
Jesse Keating 7a32965
+	 * It's important this check's before trying straps, one of the
Jesse Keating 7a32965
+	 * said manufacturer's laptops are configured in such a way
Jesse Keating 7a32965
+	 * the nouveau decides an entry in the VBIOS FP mode table is
Jesse Keating 7a32965
+	 * valid - it's not (rh#613284)
Jesse Keating 7a32965
+	 */
Jesse Keating 7a32965
+	if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
Jesse Keating 7a32965
+		if (!nouveau_acpi_edid(dev, connector)) {
Jesse Keating 7a32965
+			status = connector_status_connected;
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* If no EDID found above, and the VBIOS indicates a hardcoded
Jesse Keating 7a32965
+	 * modeline is avalilable for the panel, set it as the panel's
Jesse Keating 7a32965
+	 * native mode and exit.
Jesse Keating 7a32965
+	 */
Jesse Keating 7a32965
+	if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc ||
Jesse Keating 7a32965
+	    nv_encoder->dcb->lvdsconf.use_straps_for_mode)) {
Jesse Keating 7a32965
+		status = connector_status_connected;
Jesse Keating 7a32965
+		goto out;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	/* Still nothing, some VBIOS images have a hardcoded EDID block
Jesse Keating 7a32965
+	 * stored for the panel stored in them.
Jesse Keating 7a32965
+	 */
Jesse Keating 7a32965
+	if (!dev_priv->vbios.fp_no_ddc) {
Jesse Keating 7a32965
+		struct edid *edid =
Jesse Keating 7a32965
+			(struct edid *)nouveau_bios_embedded_edid(dev);
Jesse Keating 7a32965
+		if (edid) {
Jesse Keating 7a32965
+			nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
Jesse Keating 7a32965
+			*(nv_connector->edid) = *edid;
Jesse Keating 7a32965
+			status = connector_status_connected;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+out:
Jesse Keating 7a32965
+#if defined(CONFIG_ACPI_BUTTON) || \
Jesse Keating 7a32965
+	(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
Jesse Keating 7a32965
+	if (status == connector_status_connected &&
Jesse Keating 7a32965
+	    !nouveau_ignorelid && !acpi_lid_open())
Jesse Keating 7a32965
+		status = connector_status_unknown;
Jesse Keating 7a32965
+#endif
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
Jesse Keating 7a32965
+	nouveau_connector_set_encoder(connector, nv_encoder);
Jesse Keating 7a32965
+	return status;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static void
Jesse Keating 7a32965
 nouveau_connector_force(struct drm_connector *connector)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
@@ -441,7 +448,8 @@ nouveau_connector_native_mode(struct drm_connector *connector)
Jesse Keating 7a32965
 	int high_w = 0, high_h = 0, high_v = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
Jesse Keating 7a32965
-		if (helper->mode_valid(connector, mode) != MODE_OK)
Jesse Keating 7a32965
+		if (helper->mode_valid(connector, mode) != MODE_OK ||
Jesse Keating 7a32965
+		    (mode->flags & DRM_MODE_FLAG_INTERLACE))
Jesse Keating 7a32965
 			continue;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		/* Use preferred mode if there is one.. */
Jesse Keating 7a32965
@@ -534,21 +542,27 @@ static int
Jesse Keating 7a32965
 nouveau_connector_get_modes(struct drm_connector *connector)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_device *dev = connector->dev;
Jesse Keating 7a32965
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
 	struct nouveau_connector *nv_connector = nouveau_connector(connector);
Jesse Keating 7a32965
 	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
Jesse Keating 7a32965
 	int ret = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/* If we're not LVDS, destroy the previous native mode, the attached
Jesse Keating 7a32965
-	 * monitor could have changed.
Jesse Keating 7a32965
+	/* destroy the native mode, the attached monitor could have changed.
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
-	if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS &&
Jesse Keating 7a32965
-	    nv_connector->native_mode) {
Jesse Keating 7a32965
+	if (nv_connector->native_mode) {
Jesse Keating 7a32965
 		drm_mode_destroy(dev, nv_connector->native_mode);
Jesse Keating 7a32965
 		nv_connector->native_mode = NULL;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (nv_connector->edid)
Jesse Keating 7a32965
 		ret = drm_add_edid_modes(connector, nv_connector->edid);
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
+	if (nv_encoder->dcb->type == OUTPUT_LVDS &&
Jesse Keating 7a32965
+	    (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
Jesse Keating 7a32965
+	     dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
Jesse Keating 7a32965
+		nv_connector->native_mode = drm_mode_create(dev);
Jesse Keating 7a32965
+		nouveau_bios_fp_mode(dev, nv_connector->native_mode);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Find the native mode if this is a digital panel, if we didn't
Jesse Keating 7a32965
 	 * find any modes through DDC previously add the native mode to
Jesse Keating 7a32965
@@ -569,7 +583,8 @@ nouveau_connector_get_modes(struct drm_connector *connector)
Jesse Keating 7a32965
 		ret = get_slave_funcs(nv_encoder)->
Jesse Keating 7a32965
 			get_modes(to_drm_encoder(nv_encoder), connector);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (nv_encoder->dcb->type == OUTPUT_LVDS)
Jesse Keating 7a32965
+	if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS ||
Jesse Keating 7a32965
+	    nv_connector->dcb->type == DCB_CONNECTOR_eDP)
Jesse Keating 7a32965
 		ret += nouveau_connector_scaler_modes_add(connector);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return ret;
Jesse Keating 7a32965
@@ -643,6 +658,44 @@ nouveau_connector_best_encoder(struct drm_connector *connector)
Jesse Keating 7a32965
 	return NULL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+void
Jesse Keating 7a32965
+nouveau_connector_set_polling(struct drm_connector *connector)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct drm_device *dev = connector->dev;
Jesse Keating 7a32965
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
+	struct drm_crtc *crtc;
Jesse Keating 7a32965
+	bool spare_crtc = false;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
Jesse Keating 7a32965
+		spare_crtc |= !crtc->enabled;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	connector->polled = 0;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	switch (connector->connector_type) {
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_VGA:
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_TV:
Jesse Keating 7a32965
+		if (dev_priv->card_type >= NV_50 ||
Jesse Keating 7a32965
+		    (nv_gf4_disp_arch(dev) && spare_crtc))
Jesse Keating 7a32965
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_DVII:
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_DVID:
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_HDMIA:
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_DisplayPort:
Jesse Keating 7a32965
+	case DRM_MODE_CONNECTOR_eDP:
Jesse Keating 7a32965
+		if (dev_priv->card_type >= NV_50)
Jesse Keating 7a32965
+			connector->polled = DRM_CONNECTOR_POLL_HPD;
Jesse Keating 7a32965
+		else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
Jesse Keating 7a32965
+			 spare_crtc)
Jesse Keating 7a32965
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	default:
Jesse Keating 7a32965
+		break;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 static const struct drm_connector_helper_funcs
Jesse Keating 7a32965
 nouveau_connector_helper_funcs = {
Jesse Keating 7a32965
 	.get_modes = nouveau_connector_get_modes,
Jesse Keating 7a32965
@@ -662,148 +715,74 @@ nouveau_connector_funcs = {
Jesse Keating 7a32965
 	.force = nouveau_connector_force
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static int
Jesse Keating 7a32965
-nouveau_connector_create_lvds(struct drm_device *dev,
Jesse Keating 7a32965
-			      struct drm_connector *connector)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct nouveau_connector *nv_connector = nouveau_connector(connector);
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
-	struct nouveau_i2c_chan *i2c = NULL;
Jesse Keating 7a32965
-	struct nouveau_encoder *nv_encoder;
Jesse Keating 7a32965
-	struct drm_display_mode native, *mode, *temp;
Jesse Keating 7a32965
-	bool dummy, if_is_24bit = false;
Jesse Keating 7a32965
-	int ret, flags;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
Jesse Keating 7a32965
-	if (!nv_encoder)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit);
Jesse Keating 7a32965
-	if (ret) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n");
Jesse Keating 7a32965
-		return ret;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	nv_connector->use_dithering = !if_is_24bit;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Firstly try getting EDID over DDC, if allowed and I2C channel
Jesse Keating 7a32965
-	 * is available.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
Jesse Keating 7a32965
-		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (i2c) {
Jesse Keating 7a32965
-		nouveau_connector_ddc_prepare(connector, &flags);
Jesse Keating 7a32965
-		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
Jesse Keating 7a32965
-		nouveau_connector_ddc_finish(connector, flags);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* If no EDID found above, and the VBIOS indicates a hardcoded
Jesse Keating 7a32965
-	 * modeline is avalilable for the panel, set it as the panel's
Jesse Keating 7a32965
-	 * native mode and exit.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
Jesse Keating 7a32965
-	     (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
Jesse Keating 7a32965
-	      dev_priv->vbios.fp_no_ddc)) {
Jesse Keating 7a32965
-		nv_connector->native_mode = drm_mode_duplicate(dev, &native);
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Still nothing, some VBIOS images have a hardcoded EDID block
Jesse Keating 7a32965
-	 * stored for the panel stored in them.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (!nv_connector->edid && !nv_connector->native_mode &&
Jesse Keating 7a32965
-	    !dev_priv->vbios.fp_no_ddc) {
Jesse Keating 7a32965
-		struct edid *edid =
Jesse Keating 7a32965
-			(struct edid *)nouveau_bios_embedded_edid(dev);
Jesse Keating 7a32965
-		if (edid) {
Jesse Keating 7a32965
-			nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
Jesse Keating 7a32965
-			*(nv_connector->edid) = *edid;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!nv_connector->edid)
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* We didn't find/use a panel mode from the VBIOS, so parse the EDID
Jesse Keating 7a32965
-	 * block and look for the preferred mode there.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	ret = drm_add_edid_modes(connector, nv_connector->edid);
Jesse Keating 7a32965
-	if (ret == 0)
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
-	nv_connector->detected_encoder = nv_encoder;
Jesse Keating 7a32965
-	nv_connector->native_mode = nouveau_connector_native_mode(connector);
Jesse Keating 7a32965
-	list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
Jesse Keating 7a32965
-		drm_mode_remove(connector, mode);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-out:
Jesse Keating 7a32965
-	if (!nv_connector->native_mode) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "LVDS present in DCB table, but couldn't "
Jesse Keating 7a32965
-			      "determine its native mode.  Disabling.\n");
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
+static const struct drm_connector_funcs
Jesse Keating 7a32965
+nouveau_connector_funcs_lvds = {
Jesse Keating 7a32965
+	.dpms = drm_helper_connector_dpms,
Jesse Keating 7a32965
+	.save = NULL,
Jesse Keating 7a32965
+	.restore = NULL,
Jesse Keating 7a32965
+	.detect = nouveau_connector_detect_lvds,
Jesse Keating 7a32965
+	.destroy = nouveau_connector_destroy,
Jesse Keating 7a32965
+	.fill_modes = drm_helper_probe_single_connector_modes,
Jesse Keating 7a32965
+	.set_property = nouveau_connector_set_property,
Jesse Keating 7a32965
+	.force = nouveau_connector_force
Jesse Keating 7a32965
+};
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-int
Jesse Keating 7a32965
-nouveau_connector_create(struct drm_device *dev,
Jesse Keating 7a32965
-			 struct dcb_connector_table_entry *dcb)
Jesse Keating 7a32965
+struct drm_connector *
Jesse Keating 7a32965
+nouveau_connector_create(struct drm_device *dev, int index)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
+	const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
 	struct nouveau_connector *nv_connector = NULL;
Jesse Keating 7a32965
+	struct dcb_connector_table_entry *dcb = NULL;
Jesse Keating 7a32965
 	struct drm_connector *connector;
Jesse Keating 7a32965
-	struct drm_encoder *encoder;
Jesse Keating 7a32965
-	int ret, type;
Jesse Keating 7a32965
+	int type, ret = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	NV_DEBUG_KMS(dev, "\n");
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	if (index >= dev_priv->vbios.dcb.connector.entries)
Jesse Keating 7a32965
+		return ERR_PTR(-EINVAL);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	dcb = &dev_priv->vbios.dcb.connector.entry[index];
Jesse Keating 7a32965
+	if (dcb->drm)
Jesse Keating 7a32965
+		return dcb->drm;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	switch (dcb->type) {
Jesse Keating 7a32965
-	case DCB_CONNECTOR_NONE:
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_VGA:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a VGA connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_VGA;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_TV_0:
Jesse Keating 7a32965
 	case DCB_CONNECTOR_TV_1:
Jesse Keating 7a32965
 	case DCB_CONNECTOR_TV_3:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a TV connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_TV;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_DVI_I:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a DVI-I connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_DVII;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_DVI_D:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a DVI-D connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_DVID;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_HDMI_0:
Jesse Keating 7a32965
 	case DCB_CONNECTOR_HDMI_1:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a HDMI connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_HDMIA;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_LVDS:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a LVDS connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_LVDS;
Jesse Keating 7a32965
+		funcs = &nouveau_connector_funcs_lvds;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_DP:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected a DisplayPort connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_DisplayPort;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	case DCB_CONNECTOR_eDP:
Jesse Keating 7a32965
-		NV_INFO(dev, "Detected an eDP connector\n");
Jesse Keating 7a32965
 		type = DRM_MODE_CONNECTOR_eDP;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	default:
Jesse Keating 7a32965
 		NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
+		return ERR_PTR(-EINVAL);
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
Jesse Keating 7a32965
 	if (!nv_connector)
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
+		return ERR_PTR(-ENOMEM);
Jesse Keating 7a32965
 	nv_connector->dcb = dcb;
Jesse Keating 7a32965
 	connector = &nv_connector->base;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -811,27 +790,21 @@ nouveau_connector_create(struct drm_device *dev,
Jesse Keating 7a32965
 	connector->interlace_allowed = false;
Jesse Keating 7a32965
 	connector->doublescan_allowed = false;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
Jesse Keating 7a32965
+	drm_connector_init(dev, connector, funcs, type);
Jesse Keating 7a32965
 	drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/* attach encoders */
Jesse Keating 7a32965
-	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
Jesse Keating 7a32965
-		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (nv_encoder->dcb->connector != dcb->index)
Jesse Keating 7a32965
-			continue;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (get_slave_funcs(nv_encoder))
Jesse Keating 7a32965
-			get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
Jesse Keating 7a32965
+	/* Check if we need dithering enabled */
Jesse Keating 7a32965
+	if (dcb->type == DCB_CONNECTOR_LVDS) {
Jesse Keating 7a32965
+		bool dummy, is_24bit = false;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-		drm_mode_connector_attach_encoder(connector, encoder);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+		ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit);
Jesse Keating 7a32965
+		if (ret) {
Jesse Keating 7a32965
+			NV_ERROR(dev, "Error parsing LVDS table, disabling "
Jesse Keating 7a32965
+				 "LVDS\n");
Jesse Keating 7a32965
+			goto fail;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!connector->encoder_ids[0]) {
Jesse Keating 7a32965
-		NV_WARN(dev, "  no encoders, ignoring\n");
Jesse Keating 7a32965
-		drm_connector_cleanup(connector);
Jesse Keating 7a32965
-		kfree(connector);
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
+		nv_connector->use_dithering = !is_24bit;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Init DVI-I specific properties */
Jesse Keating 7a32965
@@ -841,12 +814,8 @@ nouveau_connector_create(struct drm_device *dev,
Jesse Keating 7a32965
 		drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (dcb->type != DCB_CONNECTOR_LVDS)
Jesse Keating 7a32965
-		nv_connector->use_dithering = false;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	switch (dcb->type) {
Jesse Keating 7a32965
 	case DCB_CONNECTOR_VGA:
Jesse Keating 7a32965
-		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
Jesse Keating 7a32965
 		if (dev_priv->card_type >= NV_50) {
Jesse Keating 7a32965
 			drm_connector_attach_property(connector,
Jesse Keating 7a32965
 					dev->mode_config.scaling_mode_property,
Jesse Keating 7a32965
@@ -858,17 +827,6 @@ nouveau_connector_create(struct drm_device *dev,
Jesse Keating 7a32965
 	case DCB_CONNECTOR_TV_3:
Jesse Keating 7a32965
 		nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
-	case DCB_CONNECTOR_DP:
Jesse Keating 7a32965
-	case DCB_CONNECTOR_eDP:
Jesse Keating 7a32965
-	case DCB_CONNECTOR_HDMI_0:
Jesse Keating 7a32965
-	case DCB_CONNECTOR_HDMI_1:
Jesse Keating 7a32965
-	case DCB_CONNECTOR_DVI_I:
Jesse Keating 7a32965
-	case DCB_CONNECTOR_DVI_D:
Jesse Keating 7a32965
-		if (dev_priv->card_type >= NV_50)
Jesse Keating 7a32965
-			connector->polled = DRM_CONNECTOR_POLL_HPD;
Jesse Keating 7a32965
-		else
Jesse Keating 7a32965
-			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
Jesse Keating 7a32965
-		/* fall-through */
Jesse Keating 7a32965
 	default:
Jesse Keating 7a32965
 		nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -882,15 +840,15 @@ nouveau_connector_create(struct drm_device *dev,
Jesse Keating 7a32965
 		break;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	nouveau_connector_set_polling(connector);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	drm_sysfs_connector_add(connector);
Jesse Keating 7a32965
+	dcb->drm = connector;
Jesse Keating 7a32965
+	return dcb->drm;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (dcb->type == DCB_CONNECTOR_LVDS) {
Jesse Keating 7a32965
-		ret = nouveau_connector_create_lvds(dev, connector);
Jesse Keating 7a32965
-		if (ret) {
Jesse Keating 7a32965
-			connector->funcs->destroy(connector);
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+fail:
Jesse Keating 7a32965
+	drm_connector_cleanup(connector);
Jesse Keating 7a32965
+	kfree(connector);
Jesse Keating 7a32965
+	return ERR_PTR(ret);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
Jesse Keating 7a32965
index 4ef38ab..0d2e668 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
Jesse Keating 7a32965
@@ -49,7 +49,10 @@ static inline struct nouveau_connector *nouveau_connector(
Jesse Keating 7a32965
 	return container_of(con, struct nouveau_connector, base);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-int nouveau_connector_create(struct drm_device *,
Jesse Keating 7a32965
-			     struct dcb_connector_table_entry *);
Jesse Keating 7a32965
+struct drm_connector *
Jesse Keating 7a32965
+nouveau_connector_create(struct drm_device *, int index);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+void
Jesse Keating 7a32965
+nouveau_connector_set_polling(struct drm_connector *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #endif /* __NOUVEAU_CONNECTOR_H__ */
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
Jesse Keating 7a32965
index 65c441a..2e3c6ca 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
Jesse Keating 7a32965
@@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan)
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Map M2MF notifier object - fbcon. */
Jesse Keating 7a32965
-	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
Jesse Keating 7a32965
-		ret = nouveau_bo_map(chan->notifier_bo);
Jesse Keating 7a32965
-		if (ret)
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+	ret = nouveau_bo_map(chan->notifier_bo);
Jesse Keating 7a32965
+	if (ret)
Jesse Keating 7a32965
+		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Insert NOPS for NOUVEAU_DMA_SKIPS */
Jesse Keating 7a32965
 	ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
Jesse Keating 7a32965
index deeb21c..184bc95 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
Jesse Keating 7a32965
@@ -271,12 +271,26 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_device *dev = encoder->dev;
Jesse Keating 7a32965
 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
Jesse Keating 7a32965
-	uint8_t config[4];
Jesse Keating 7a32965
-	uint8_t status[3];
Jesse Keating 7a32965
+	struct bit_displayport_encoder_table *dpe;
Jesse Keating 7a32965
+	int dpe_headerlen;
Jesse Keating 7a32965
+	uint8_t config[4], status[3];
Jesse Keating 7a32965
 	bool cr_done, cr_max_vs, eq_done;
Jesse Keating 7a32965
 	int ret = 0, i, tries, voltage;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	NV_DEBUG_KMS(dev, "link training!!\n");
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
Jesse Keating 7a32965
+	if (!dpe) {
Jesse Keating 7a32965
+		NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
Jesse Keating 7a32965
+		return false;
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	if (dpe->script0) {
Jesse Keating 7a32965
+		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
Jesse Keating 7a32965
+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
Jesse Keating 7a32965
+					    nv_encoder->dcb);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 train:
Jesse Keating 7a32965
 	cr_done = eq_done = false;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -403,6 +417,12 @@ stop:
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	if (dpe->script1) {
Jesse Keating 7a32965
+		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
Jesse Keating 7a32965
+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
Jesse Keating 7a32965
+					    nv_encoder->dcb);
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	return eq_done;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
Jesse Keating 7a32965
index 2737704..203d0b6 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
Jesse Keating 7a32965
@@ -35,10 +35,6 @@
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 #include "drm_pciids.h"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
Jesse Keating 7a32965
-int nouveau_ctxfw = 0;
Jesse Keating 7a32965
-module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 MODULE_PARM_DESC(noagp, "Disable AGP");
Jesse Keating 7a32965
 int nouveau_noagp;
Jesse Keating 7a32965
 module_param_named(noagp, nouveau_noagp, int, 0400);
Jesse Keating 7a32965
@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf;
Jesse Keating 7a32965
 module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
Jesse Keating 7a32965
-int nouveau_vram_notify = 1;
Jesse Keating 7a32965
+int nouveau_vram_notify = 0;
Jesse Keating 7a32965
 module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
Jesse Keating 7a32965
@@ -155,9 +151,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
Jesse Keating 7a32965
 	struct drm_crtc *crtc;
Jesse Keating 7a32965
 	int ret, i;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!drm_core_check_feature(dev, DRIVER_MODESET))
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	if (pm_state.event == PM_EVENT_PRETHAW)
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -257,9 +250,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
Jesse Keating 7a32965
 	struct drm_crtc *crtc;
Jesse Keating 7a32965
 	int ret, i;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!drm_core_check_feature(dev, DRIVER_MODESET))
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	nouveau_fbcon_save_disable_accel(dev);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	NV_INFO(dev, "We're back, enabling device...\n");
Jesse Keating 7a32965
@@ -323,7 +313,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
Jesse Keating 7a32965
 		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
Jesse Keating 7a32965
-		int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
Jesse Keating 7a32965
 		if (!ret)
Jesse Keating 7a32965
@@ -332,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
Jesse Keating 7a32965
 			NV_ERROR(dev, "Could not pin/map cursor.\n");
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (dev_priv->card_type < NV_50) {
Jesse Keating 7a32965
+	if (dev_priv->card_type < NV_50)
Jesse Keating 7a32965
 		nv04_display_restore(dev);
Jesse Keating 7a32965
-		NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
-	} else
Jesse Keating 7a32965
+	else
Jesse Keating 7a32965
 		nv50_display_init(dev);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
Jesse Keating 7a32965
@@ -371,7 +359,8 @@ nouveau_pci_resume(struct pci_dev *pdev)
Jesse Keating 7a32965
 static struct drm_driver driver = {
Jesse Keating 7a32965
 	.driver_features =
Jesse Keating 7a32965
 		DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
Jesse Keating 7a32965
-		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
Jesse Keating 7a32965
+		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
Jesse Keating 7a32965
+		DRIVER_MODESET,
Jesse Keating 7a32965
 	.load = nouveau_load,
Jesse Keating 7a32965
 	.firstopen = nouveau_firstopen,
Jesse Keating 7a32965
 	.lastclose = nouveau_lastclose,
Jesse Keating 7a32965
@@ -438,16 +427,18 @@ static int __init nouveau_init(void)
Jesse Keating 7a32965
 			nouveau_modeset = 1;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (nouveau_modeset == 1) {
Jesse Keating 7a32965
-		driver.driver_features |= DRIVER_MODESET;
Jesse Keating 7a32965
-		nouveau_register_dsm_handler();
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+	if (!nouveau_modeset)
Jesse Keating 7a32965
+		return 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	nouveau_register_dsm_handler();
Jesse Keating 7a32965
 	return drm_init(&driver);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static void __exit nouveau_exit(void)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
+	if (!nouveau_modeset)
Jesse Keating 7a32965
+		return;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	drm_exit(&driver);
Jesse Keating 7a32965
 	nouveau_unregister_dsm_handler();
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
Jesse Keating 7a32965
index c697191..20ca5b8 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
Jesse Keating 7a32965
@@ -123,14 +123,6 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
Jesse Keating 7a32965
 	return ioptr;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-struct mem_block {
Jesse Keating 7a32965
-	struct mem_block *next;
Jesse Keating 7a32965
-	struct mem_block *prev;
Jesse Keating 7a32965
-	uint64_t start;
Jesse Keating 7a32965
-	uint64_t size;
Jesse Keating 7a32965
-	struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
Jesse Keating 7a32965
-};
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 enum nouveau_flags {
Jesse Keating 7a32965
 	NV_NFORCE   = 0x10000000,
Jesse Keating 7a32965
 	NV_NFORCE2  = 0x20000000
Jesse Keating 7a32965
@@ -149,7 +141,7 @@ struct nouveau_gpuobj {
Jesse Keating 7a32965
 	struct list_head list;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct nouveau_channel *im_channel;
Jesse Keating 7a32965
-	struct mem_block *im_pramin;
Jesse Keating 7a32965
+	struct drm_mm_node *im_pramin;
Jesse Keating 7a32965
 	struct nouveau_bo *im_backing;
Jesse Keating 7a32965
 	uint32_t im_backing_start;
Jesse Keating 7a32965
 	uint32_t *im_backing_suspend;
Jesse Keating 7a32965
@@ -196,7 +188,7 @@ struct nouveau_channel {
Jesse Keating 7a32965
 		struct list_head pending;
Jesse Keating 7a32965
 		uint32_t sequence;
Jesse Keating 7a32965
 		uint32_t sequence_ack;
Jesse Keating 7a32965
-		uint32_t last_sequence_irq;
Jesse Keating 7a32965
+		atomic_t last_sequence_irq;
Jesse Keating 7a32965
 	} fence;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* DMA push buffer */
Jesse Keating 7a32965
@@ -206,7 +198,7 @@ struct nouveau_channel {
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Notifier memory */
Jesse Keating 7a32965
 	struct nouveau_bo *notifier_bo;
Jesse Keating 7a32965
-	struct mem_block *notifier_heap;
Jesse Keating 7a32965
+	struct drm_mm notifier_heap;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* PFIFO context */
Jesse Keating 7a32965
 	struct nouveau_gpuobj_ref *ramfc;
Jesse Keating 7a32965
@@ -224,7 +216,7 @@ struct nouveau_channel {
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* Objects */
Jesse Keating 7a32965
 	struct nouveau_gpuobj_ref *ramin; /* Private instmem */
Jesse Keating 7a32965
-	struct mem_block          *ramin_heap; /* Private PRAMIN heap */
Jesse Keating 7a32965
+	struct drm_mm              ramin_heap; /* Private PRAMIN heap */
Jesse Keating 7a32965
 	struct nouveau_gpuobj_ref *ramht; /* Hash table */
Jesse Keating 7a32965
 	struct list_head           ramht_refs; /* Objects referenced by RAMHT */
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -277,8 +269,7 @@ struct nouveau_instmem_engine {
Jesse Keating 7a32965
 	void	(*clear)(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
 	int	(*bind)(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
 	int	(*unbind)(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
-	void	(*prepare_access)(struct drm_device *, bool write);
Jesse Keating 7a32965
-	void	(*finish_access)(struct drm_device *);
Jesse Keating 7a32965
+	void	(*flush)(struct drm_device *);
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct nouveau_mc_engine {
Jesse Keating 7a32965
@@ -303,10 +294,11 @@ struct nouveau_fb_engine {
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct nouveau_fifo_engine {
Jesse Keating 7a32965
-	void *priv;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	int  channels;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	struct nouveau_gpuobj_ref *playlist[2];
Jesse Keating 7a32965
+	int cur_playlist;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	int  (*init)(struct drm_device *);
Jesse Keating 7a32965
 	void (*takedown)(struct drm_device *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -339,10 +331,11 @@ struct nouveau_pgraph_object_class {
Jesse Keating 7a32965
 struct nouveau_pgraph_engine {
Jesse Keating 7a32965
 	struct nouveau_pgraph_object_class *grclass;
Jesse Keating 7a32965
 	bool accel_blocked;
Jesse Keating 7a32965
-	void *ctxprog;
Jesse Keating 7a32965
-	void *ctxvals;
Jesse Keating 7a32965
 	int grctx_size;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	/* NV2x/NV3x context table (0x400780) */
Jesse Keating 7a32965
+	struct nouveau_gpuobj_ref *ctx_table;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	int  (*init)(struct drm_device *);
Jesse Keating 7a32965
 	void (*takedown)(struct drm_device *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -500,11 +493,6 @@ enum nouveau_card_type {
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct drm_nouveau_private {
Jesse Keating 7a32965
 	struct drm_device *dev;
Jesse Keating 7a32965
-	enum {
Jesse Keating 7a32965
-		NOUVEAU_CARD_INIT_DOWN,
Jesse Keating 7a32965
-		NOUVEAU_CARD_INIT_DONE,
Jesse Keating 7a32965
-		NOUVEAU_CARD_INIT_FAILED
Jesse Keating 7a32965
-	} init_state;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	/* the card type, takes NV_* as values */
Jesse Keating 7a32965
 	enum nouveau_card_type card_type;
Jesse Keating 7a32965
@@ -533,8 +521,6 @@ struct drm_nouveau_private {
Jesse Keating 7a32965
 		atomic_t validate_sequence;
Jesse Keating 7a32965
 	} ttm;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	struct fb_info *fbdev_info;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	int fifo_alloc_count;
Jesse Keating 7a32965
 	struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -595,11 +581,7 @@ struct drm_nouveau_private {
Jesse Keating 7a32965
 	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
Jesse Keating 7a32965
 	int vm_vram_pt_nr;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	struct mem_block *ramin_heap;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
Jesse Keating 7a32965
-	uint32_t ctx_table_size;
Jesse Keating 7a32965
-	struct nouveau_gpuobj_ref *ctx_table;
Jesse Keating 7a32965
+	struct drm_mm ramin_heap;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct list_head gpuobj_list;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -618,6 +600,11 @@ struct drm_nouveau_private {
Jesse Keating 7a32965
 	struct backlight_device *backlight;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct nouveau_channel *evo;
Jesse Keating 7a32965
+	struct {
Jesse Keating 7a32965
+		struct dcb_entry *dcb;
Jesse Keating 7a32965
+		u16 script;
Jesse Keating 7a32965
+		u32 pclk;
Jesse Keating 7a32965
+	} evo_irq;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct {
Jesse Keating 7a32965
 		struct dentry *channel_root;
Jesse Keating 7a32965
@@ -652,14 +639,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do {            \
Jesse Keating 7a32965
-	struct drm_nouveau_private *nv = dev->dev_private;    \
Jesse Keating 7a32965
-	if (nv->init_state != NOUVEAU_CARD_INIT_DONE) {       \
Jesse Keating 7a32965
-		NV_ERROR(dev, "called without init\n");       \
Jesse Keating 7a32965
-		return -EINVAL;                               \
Jesse Keating 7a32965
-	}                                                     \
Jesse Keating 7a32965
-} while (0)
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do {    \
Jesse Keating 7a32965
 	struct drm_nouveau_private *nv = dev->dev_private;       \
Jesse Keating 7a32965
 	if (!nouveau_channel_owner(dev, (cl), (id))) {           \
Jesse Keating 7a32965
@@ -682,7 +661,6 @@ extern int nouveau_tv_disable;
Jesse Keating 7a32965
 extern char *nouveau_tv_norm;
Jesse Keating 7a32965
 extern int nouveau_reg_debug;
Jesse Keating 7a32965
 extern char *nouveau_vbios;
Jesse Keating 7a32965
-extern int nouveau_ctxfw;
Jesse Keating 7a32965
 extern int nouveau_ignorelid;
Jesse Keating 7a32965
 extern int nouveau_nofbaccel;
Jesse Keating 7a32965
 extern int nouveau_noaccel;
Jesse Keating 7a32965
@@ -707,15 +685,7 @@ extern bool nouveau_wait_for_idle(struct drm_device *);
Jesse Keating 7a32965
 extern int  nouveau_card_init(struct drm_device *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nouveau_mem.c */
Jesse Keating 7a32965
-extern int  nouveau_mem_init_heap(struct mem_block **, uint64_t start,
Jesse Keating 7a32965
-				 uint64_t size);
Jesse Keating 7a32965
-extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
Jesse Keating 7a32965
-						 uint64_t size, int align2,
Jesse Keating 7a32965
-						 struct drm_file *, int tail);
Jesse Keating 7a32965
-extern void nouveau_mem_takedown(struct mem_block **heap);
Jesse Keating 7a32965
-extern void nouveau_mem_free_block(struct mem_block *);
Jesse Keating 7a32965
 extern int  nouveau_mem_detect(struct drm_device *dev);
Jesse Keating 7a32965
-extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
Jesse Keating 7a32965
 extern int  nouveau_mem_init(struct drm_device *);
Jesse Keating 7a32965
 extern int  nouveau_mem_init_agp(struct drm_device *);
Jesse Keating 7a32965
 extern void nouveau_mem_close(struct drm_device *);
Jesse Keating 7a32965
@@ -857,11 +827,13 @@ void nouveau_register_dsm_handler(void);
Jesse Keating 7a32965
 void nouveau_unregister_dsm_handler(void);
Jesse Keating 7a32965
 int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
Jesse Keating 7a32965
 bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
Jesse Keating 7a32965
+int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
Jesse Keating 7a32965
 #else
Jesse Keating 7a32965
 static inline void nouveau_register_dsm_handler(void) {}
Jesse Keating 7a32965
 static inline void nouveau_unregister_dsm_handler(void) {}
Jesse Keating 7a32965
 static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
Jesse Keating 7a32965
 static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
Jesse Keating 7a32965
+static inline int nouveau_acpi_edid(struct drm_device *, struct drm_connector *) { return -EINVAL; }
Jesse Keating 7a32965
 #endif
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nouveau_backlight.c */
Jesse Keating 7a32965
@@ -1035,12 +1007,6 @@ extern int  nv50_graph_unload_context(struct drm_device *);
Jesse Keating 7a32965
 extern void nv50_graph_context_switch(struct drm_device *);
Jesse Keating 7a32965
 extern int  nv50_grctx_init(struct nouveau_grctx *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/* nouveau_grctx.c */
Jesse Keating 7a32965
-extern int  nouveau_grctx_prog_load(struct drm_device *);
Jesse Keating 7a32965
-extern void nouveau_grctx_vals_load(struct drm_device *,
Jesse Keating 7a32965
-				    struct nouveau_gpuobj *);
Jesse Keating 7a32965
-extern void nouveau_grctx_fini(struct drm_device *);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /* nv04_instmem.c */
Jesse Keating 7a32965
 extern int  nv04_instmem_init(struct drm_device *);
Jesse Keating 7a32965
 extern void nv04_instmem_takedown(struct drm_device *);
Jesse Keating 7a32965
@@ -1051,8 +1017,7 @@ extern int  nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
Jesse Keating 7a32965
 extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
 extern int  nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
 extern int  nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
-extern void nv04_instmem_prepare_access(struct drm_device *, bool write);
Jesse Keating 7a32965
-extern void nv04_instmem_finish_access(struct drm_device *);
Jesse Keating 7a32965
+extern void nv04_instmem_flush(struct drm_device *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv50_instmem.c */
Jesse Keating 7a32965
 extern int  nv50_instmem_init(struct drm_device *);
Jesse Keating 7a32965
@@ -1064,8 +1029,9 @@ extern int  nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
Jesse Keating 7a32965
 extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
 extern int  nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
 extern int  nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
Jesse Keating 7a32965
-extern void nv50_instmem_prepare_access(struct drm_device *, bool write);
Jesse Keating 7a32965
-extern void nv50_instmem_finish_access(struct drm_device *);
Jesse Keating 7a32965
+extern void nv50_instmem_flush(struct drm_device *);
Jesse Keating 7a32965
+extern void nv84_instmem_flush(struct drm_device *);
Jesse Keating 7a32965
+extern void nv50_vm_flush(struct drm_device *, int engine);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv04_mc.c */
Jesse Keating 7a32965
 extern int  nv04_mc_init(struct drm_device *);
Jesse Keating 7a32965
@@ -1088,13 +1054,14 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
Jesse Keating 7a32965
 				 unsigned long arg);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv04_dac.c */
Jesse Keating 7a32965
-extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry);
Jesse Keating 7a32965
+extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *);
Jesse Keating 7a32965
 extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
Jesse Keating 7a32965
 extern int nv04_dac_output_offset(struct drm_encoder *encoder);
Jesse Keating 7a32965
 extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
Jesse Keating 7a32965
+extern bool nv04_dac_in_use(struct drm_encoder *encoder);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv04_dfp.c */
Jesse Keating 7a32965
-extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry);
Jesse Keating 7a32965
+extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *);
Jesse Keating 7a32965
 extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
Jesse Keating 7a32965
 extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
Jesse Keating 7a32965
 			       int head, bool dl);
Jesse Keating 7a32965
@@ -1103,10 +1070,10 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv04_tv.c */
Jesse Keating 7a32965
 extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
Jesse Keating 7a32965
-extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry);
Jesse Keating 7a32965
+extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv17_tv.c */
Jesse Keating 7a32965
-extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry);
Jesse Keating 7a32965
+extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nv04_display.c */
Jesse Keating 7a32965
 extern int nv04_display_create(struct drm_device *);
Jesse Keating 7a32965
@@ -1147,7 +1114,6 @@ extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
Jesse Keating 7a32965
 extern int nouveau_fence_flush(void *obj, void *arg);
Jesse Keating 7a32965
 extern void nouveau_fence_unref(void **obj);
Jesse Keating 7a32965
 extern void *nouveau_fence_ref(void *obj);
Jesse Keating 7a32965
-extern void nouveau_fence_handler(struct drm_device *dev, int channel);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* nouveau_gem.c */
Jesse Keating 7a32965
 extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *,
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
Jesse Keating 7a32965
index e1df820..a1a0d48 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
Jesse Keating 7a32965
@@ -38,13 +38,15 @@ struct nouveau_encoder {
Jesse Keating 7a32965
 	struct dcb_entry *dcb;
Jesse Keating 7a32965
 	int or;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	/* different to drm_encoder.crtc, this reflects what's
Jesse Keating 7a32965
+	 * actually programmed on the hw, not the proposed crtc */
Jesse Keating 7a32965
+	struct drm_crtc *crtc;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
 	struct drm_display_mode mode;
Jesse Keating 7a32965
 	int last_dpms;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	struct nv04_output_reg restore;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	void (*disconnect)(struct nouveau_encoder *encoder);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	union {
Jesse Keating 7a32965
 		struct {
Jesse Keating 7a32965
 			int mc_unknown;
Jesse Keating 7a32965
@@ -71,8 +73,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct nouveau_connector *
Jesse Keating 7a32965
 nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
Jesse Keating 7a32965
-int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry);
Jesse Keating 7a32965
-int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry);
Jesse Keating 7a32965
+int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
Jesse Keating 7a32965
+int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 struct bit_displayport_encoder_table {
Jesse Keating 7a32965
 	uint32_t match;
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
Jesse Keating 7a32965
index 257ea13..2fb2444 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
Jesse Keating 7a32965
@@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev)
Jesse Keating 7a32965
 	drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-int
Jesse Keating 7a32965
+static int
Jesse Keating 7a32965
 nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
Jesse Keating 7a32965
index faddf53..813d853 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
Jesse Keating 7a32965
@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan)
Jesse Keating 7a32965
 	if (USE_REFCNT)
Jesse Keating 7a32965
 		sequence = nvchan_rd32(chan, 0x48);
Jesse Keating 7a32965
 	else
Jesse Keating 7a32965
-		sequence = chan->fence.last_sequence_irq;
Jesse Keating 7a32965
+		sequence = atomic_read(&chan->fence.last_sequence_irq);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (chan->fence.sequence_ack == sequence)
Jesse Keating 7a32965
 		return;
Jesse Keating 7a32965
 	chan->fence.sequence_ack = sequence;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	spin_lock(&chan->fence.lock);
Jesse Keating 7a32965
 	list_for_each_safe(entry, tmp, &chan->fence.pending) {
Jesse Keating 7a32965
 		fence = list_entry(entry, struct nouveau_fence, entry);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
Jesse Keating 7a32965
 		if (sequence == chan->fence.sequence_ack)
Jesse Keating 7a32965
 			break;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
+	spin_unlock(&chan->fence.lock);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 int
Jesse Keating 7a32965
@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
Jesse Keating 7a32965
 	struct nouveau_channel *chan = fence->channel;
Jesse Keating 7a32965
-	unsigned long flags;
Jesse Keating 7a32965
 	int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	ret = RING_SPACE(chan, 2);
Jesse Keating 7a32965
@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
Jesse Keating 7a32965
-		spin_lock_irqsave(&chan->fence.lock, flags);
Jesse Keating 7a32965
 		nouveau_fence_update(chan);
Jesse Keating 7a32965
-		spin_unlock_irqrestore(&chan->fence.lock, flags);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		BUG_ON(chan->fence.sequence ==
Jesse Keating 7a32965
 		       chan->fence.sequence_ack - 1);
Jesse Keating 7a32965
@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
Jesse Keating 7a32965
 	fence->sequence = ++chan->fence.sequence;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	kref_get(&fence->refcount);
Jesse Keating 7a32965
-	spin_lock_irqsave(&chan->fence.lock, flags);
Jesse Keating 7a32965
+	spin_lock(&chan->fence.lock);
Jesse Keating 7a32965
 	list_add_tail(&fence->entry, &chan->fence.pending);
Jesse Keating 7a32965
-	spin_unlock_irqrestore(&chan->fence.lock, flags);
Jesse Keating 7a32965
+	spin_unlock(&chan->fence.lock);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1);
Jesse Keating 7a32965
 	OUT_RING(chan, fence->sequence);
Jesse Keating 7a32965
@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct nouveau_fence *fence = nouveau_fence(sync_obj);
Jesse Keating 7a32965
 	struct nouveau_channel *chan = fence->channel;
Jesse Keating 7a32965
-	unsigned long flags;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (fence->signalled)
Jesse Keating 7a32965
 		return true;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	spin_lock_irqsave(&chan->fence.lock, flags);
Jesse Keating 7a32965
 	nouveau_fence_update(chan);
Jesse Keating 7a32965
-	spin_unlock_irqrestore(&chan->fence.lock, flags);
Jesse Keating 7a32965
 	return fence->signalled;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg)
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-void
Jesse Keating 7a32965
-nouveau_fence_handler(struct drm_device *dev, int channel)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
-	struct nouveau_channel *chan = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
Jesse Keating 7a32965
-		chan = dev_priv->fifos[channel];
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (chan) {
Jesse Keating 7a32965
-		spin_lock_irq(&chan->fence.lock);
Jesse Keating 7a32965
-		nouveau_fence_update(chan);
Jesse Keating 7a32965
-		spin_unlock_irq(&chan->fence.lock);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 int
Jesse Keating 7a32965
 nouveau_fence_init(struct nouveau_channel *chan)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	INIT_LIST_HEAD(&chan->fence.pending);
Jesse Keating 7a32965
 	spin_lock_init(&chan->fence.lock);
Jesse Keating 7a32965
+	atomic_set(&chan->fence.last_sequence_irq, 0);
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
Jesse Keating 7a32965
index 69c76cf..547f2c2 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
Jesse Keating 7a32965
@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	uint32_t flags = 0;
Jesse Keating 7a32965
 	int ret = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
Jesse Keating 7a32965
 		dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -577,10 +575,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	struct drm_nouveau_gem_pushbuf_bo *bo;
Jesse Keating 7a32965
 	struct nouveau_channel *chan;
Jesse Keating 7a32965
 	struct validate_op op;
Jesse Keating 7a32965
-	struct nouveau_fence *fence = 0;
Jesse Keating 7a32965
+	struct nouveau_fence *fence = NULL;
Jesse Keating 7a32965
 	int i, j, ret = 0, do_reloc = 0;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	req->vram_available = dev_priv->fb_aper_free;
Jesse Keating 7a32965
@@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
Jesse Keating 7a32965
 	int ret = -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
Jesse Keating 7a32965
 	if (!gem)
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
@@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	struct nouveau_bo *nvbo;
Jesse Keating 7a32965
 	int ret = -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
Jesse Keating 7a32965
 	if (!gem)
Jesse Keating 7a32965
 		return ret;
Jesse Keating 7a32965
@@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
Jesse Keating 7a32965
 	struct drm_gem_object *gem;
Jesse Keating 7a32965
 	int ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
Jesse Keating 7a32965
 	if (!gem)
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c
Jesse Keating 7a32965
deleted file mode 100644
Jesse Keating 7a32965
index f731c5f..0000000
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_grctx.c
Jesse Keating 7a32965
+++ /dev/null
Jesse Keating 7a32965
@@ -1,160 +0,0 @@
Jesse Keating 7a32965
-/*
Jesse Keating 7a32965
- * Copyright 2009 Red Hat Inc.
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Permission is hereby granted, free of charge, to any person obtaining a
Jesse Keating 7a32965
- * copy of this software and associated documentation files (the "Software"),
Jesse Keating 7a32965
- * to deal in the Software without restriction, including without limitation
Jesse Keating 7a32965
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jesse Keating 7a32965
- * and/or sell copies of the Software, and to permit persons to whom the
Jesse Keating 7a32965
- * Software is furnished to do so, subject to the following conditions:
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * The above copyright notice and this permission notice shall be included in
Jesse Keating 7a32965
- * all copies or substantial portions of the Software.
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jesse Keating 7a32965
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jesse Keating 7a32965
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
Jesse Keating 7a32965
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
Jesse Keating 7a32965
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
Jesse Keating 7a32965
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Jesse Keating 7a32965
- * OTHER DEALINGS IN THE SOFTWARE.
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Authors: Ben Skeggs
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-#include <linux/firmware.h>
Jesse Keating 7a32965
-#include <linux/slab.h>
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-#include "drmP.h"
Jesse Keating 7a32965
-#include "nouveau_drv.h"
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-struct nouveau_ctxprog {
Jesse Keating 7a32965
-	uint32_t signature;
Jesse Keating 7a32965
-	uint8_t  version;
Jesse Keating 7a32965
-	uint16_t length;
Jesse Keating 7a32965
-	uint32_t data[];
Jesse Keating 7a32965
-} __attribute__ ((packed));
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-struct nouveau_ctxvals {
Jesse Keating 7a32965
-	uint32_t signature;
Jesse Keating 7a32965
-	uint8_t  version;
Jesse Keating 7a32965
-	uint32_t length;
Jesse Keating 7a32965
-	struct {
Jesse Keating 7a32965
-		uint32_t offset;
Jesse Keating 7a32965
-		uint32_t value;
Jesse Keating 7a32965
-	} data[];
Jesse Keating 7a32965
-} __attribute__ ((packed));
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-int
Jesse Keating 7a32965
-nouveau_grctx_prog_load(struct drm_device *dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
Jesse Keating 7a32965
-	const int chipset = dev_priv->chipset;
Jesse Keating 7a32965
-	const struct firmware *fw;
Jesse Keating 7a32965
-	const struct nouveau_ctxprog *cp;
Jesse Keating 7a32965
-	const struct nouveau_ctxvals *cv;
Jesse Keating 7a32965
-	char name[32];
Jesse Keating 7a32965
-	int ret, i;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (pgraph->accel_blocked)
Jesse Keating 7a32965
-		return -ENODEV;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!pgraph->ctxprog) {
Jesse Keating 7a32965
-		sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
Jesse Keating 7a32965
-		ret = request_firmware(&fw, name, &dev->pdev->dev);
Jesse Keating 7a32965
-		if (ret) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL);
Jesse Keating 7a32965
-		if (!pgraph->ctxprog) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "OOM copying ctxprog\n");
Jesse Keating 7a32965
-			release_firmware(fw);
Jesse Keating 7a32965
-			return -ENOMEM;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		cp = pgraph->ctxprog;
Jesse Keating 7a32965
-		if (le32_to_cpu(cp->signature) != 0x5043564e ||
Jesse Keating 7a32965
-		    cp->version != 0 ||
Jesse Keating 7a32965
-		    le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "ctxprog invalid\n");
Jesse Keating 7a32965
-			release_firmware(fw);
Jesse Keating 7a32965
-			nouveau_grctx_fini(dev);
Jesse Keating 7a32965
-			return -EINVAL;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-		release_firmware(fw);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!pgraph->ctxvals) {
Jesse Keating 7a32965
-		sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
Jesse Keating 7a32965
-		ret = request_firmware(&fw, name, &dev->pdev->dev);
Jesse Keating 7a32965
-		if (ret) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
Jesse Keating 7a32965
-			nouveau_grctx_fini(dev);
Jesse Keating 7a32965
-			return ret;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL);
Jesse Keating 7a32965
-		if (!pgraph->ctxvals) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "OOM copying ctxvals\n");
Jesse Keating 7a32965
-			release_firmware(fw);
Jesse Keating 7a32965
-			nouveau_grctx_fini(dev);
Jesse Keating 7a32965
-			return -ENOMEM;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		cv = (void *)pgraph->ctxvals;
Jesse Keating 7a32965
-		if (le32_to_cpu(cv->signature) != 0x5643564e ||
Jesse Keating 7a32965
-		    cv->version != 0 ||
Jesse Keating 7a32965
-		    le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
Jesse Keating 7a32965
-			NV_ERROR(dev, "ctxvals invalid\n");
Jesse Keating 7a32965
-			release_firmware(fw);
Jesse Keating 7a32965
-			nouveau_grctx_fini(dev);
Jesse Keating 7a32965
-			return -EINVAL;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-		release_firmware(fw);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	cp = pgraph->ctxprog;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
Jesse Keating 7a32965
-	for (i = 0; i < le16_to_cpu(cp->length); i++)
Jesse Keating 7a32965
-		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
Jesse Keating 7a32965
-			le32_to_cpu(cp->data[i]));
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-void
Jesse Keating 7a32965
-nouveau_grctx_fini(struct drm_device *dev)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (pgraph->ctxprog) {
Jesse Keating 7a32965
-		kfree(pgraph->ctxprog);
Jesse Keating 7a32965
-		pgraph->ctxprog = NULL;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (pgraph->ctxvals) {
Jesse Keating 7a32965
-		kfree(pgraph->ctxprog);
Jesse Keating 7a32965
-		pgraph->ctxvals = NULL;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-void
Jesse Keating 7a32965
-nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
Jesse Keating 7a32965
-	struct nouveau_ctxvals *cv = pgraph->ctxvals;
Jesse Keating 7a32965
-	int i;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!cv)
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	for (i = 0; i < le32_to_cpu(cv->length); i++)
Jesse Keating 7a32965
-		nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
Jesse Keating 7a32965
-			le32_to_cpu(cv->data[i].value));
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
Jesse Keating 7a32965
index 316a3c7..97ba89e 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
Jesse Keating 7a32965
@@ -278,3 +278,37 @@ nouveau_i2c_find(struct drm_device *dev, int index)
Jesse Keating 7a32965
 	return i2c->chan;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+bool
Jesse Keating 7a32965
+nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct i2c_msg msg = {
Jesse Keating 7a32965
+		.addr = addr,
Jesse Keating 7a32965
+		.len = 0,
Jesse Keating 7a32965
+	};
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return i2c_transfer(&i2c->adapter, &msg, 1) == 1;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+int
Jesse Keating 7a32965
+nouveau_i2c_identify(struct drm_device *dev, const char *what,
Jesse Keating 7a32965
+		     struct i2c_board_info *info, int index)
Jesse Keating 7a32965
+{
Jesse Keating 7a32965
+	struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
Jesse Keating 7a32965
+	int was_locked, i;
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	was_locked = NVLockVgaCrtcs(dev, false);
Jesse Keating 7a32965
+	NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	for (i = 0; info[i].addr; i++) {
Jesse Keating 7a32965
+		if (nouveau_probe_i2c_addr(i2c, info[i].addr)) {
Jesse Keating 7a32965
+			NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
Jesse Keating 7a32965
+			goto out;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
+	}
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	NV_DEBUG(dev, "No devices found.\n");
Jesse Keating 7a32965
+out:
Jesse Keating 7a32965
+	NVLockVgaCrtcs(dev, was_locked);
Jesse Keating 7a32965
+
Jesse Keating 7a32965
+	return info[i].addr ? i : -ENODEV;
Jesse Keating 7a32965
+}
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h
Jesse Keating 7a32965
index c8eaf7a..6dd2f87 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.h
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h
Jesse Keating 7a32965
@@ -45,6 +45,9 @@ struct nouveau_i2c_chan {
Jesse Keating 7a32965
 int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
Jesse Keating 7a32965
 void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
Jesse Keating 7a32965
 struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
Jesse Keating 7a32965
+bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
Jesse Keating 7a32965
+int nouveau_i2c_identify(struct drm_device *dev, const char *what,
Jesse Keating 7a32965
+			 struct i2c_board_info *info, int index);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
Jesse Keating 7a32965
 			  uint8_t *read_byte);
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
Jesse Keating 7a32965
index c1fd42b..adf5ac4 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
Jesse Keating 7a32965
@@ -35,162 +35,6 @@
Jesse Keating 7a32965
 #include "drm_sarea.h"
Jesse Keating 7a32965
 #include "nouveau_drv.h"
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-static struct mem_block *
Jesse Keating 7a32965
-split_block(struct mem_block *p, uint64_t start, uint64_t size,
Jesse Keating 7a32965
-	    struct drm_file *file_priv)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	/* Maybe cut off the start of an existing block */
Jesse Keating 7a32965
-	if (start > p->start) {
Jesse Keating 7a32965
-		struct mem_block *newblock =
Jesse Keating 7a32965
-			kmalloc(sizeof(*newblock), GFP_KERNEL);
Jesse Keating 7a32965
-		if (!newblock)
Jesse Keating 7a32965
-			goto out;
Jesse Keating 7a32965
-		newblock->start = start;
Jesse Keating 7a32965
-		newblock->size = p->size - (start - p->start);
Jesse Keating 7a32965
-		newblock->file_priv = NULL;
Jesse Keating 7a32965
-		newblock->next = p->next;
Jesse Keating 7a32965
-		newblock->prev = p;
Jesse Keating 7a32965
-		p->next->prev = newblock;
Jesse Keating 7a32965
-		p->next = newblock;
Jesse Keating 7a32965
-		p->size -= newblock->size;
Jesse Keating 7a32965
-		p = newblock;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Maybe cut off the end of an existing block */
Jesse Keating 7a32965
-	if (size < p->size) {
Jesse Keating 7a32965
-		struct mem_block *newblock =
Jesse Keating 7a32965
-			kmalloc(sizeof(*newblock), GFP_KERNEL);
Jesse Keating 7a32965
-		if (!newblock)
Jesse Keating 7a32965
-			goto out;
Jesse Keating 7a32965
-		newblock->start = start + size;
Jesse Keating 7a32965
-		newblock->size = p->size - size;
Jesse Keating 7a32965
-		newblock->file_priv = NULL;
Jesse Keating 7a32965
-		newblock->next = p->next;
Jesse Keating 7a32965
-		newblock->prev = p;
Jesse Keating 7a32965
-		p->next->prev = newblock;
Jesse Keating 7a32965
-		p->next = newblock;
Jesse Keating 7a32965
-		p->size = size;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-out:
Jesse Keating 7a32965
-	/* Our block is in the middle */
Jesse Keating 7a32965
-	p->file_priv = file_priv;
Jesse Keating 7a32965
-	return p;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-struct mem_block *
Jesse Keating 7a32965
-nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
Jesse Keating 7a32965
-			int align2, struct drm_file *file_priv, int tail)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct mem_block *p;
Jesse Keating 7a32965
-	uint64_t mask = (1 << align2) - 1;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!heap)
Jesse Keating 7a32965
-		return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (tail) {
Jesse Keating 7a32965
-		list_for_each_prev(p, heap) {
Jesse Keating 7a32965
-			uint64_t start = ((p->start + p->size) - size) & ~mask;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-			if (p->file_priv == NULL && start >= p->start &&
Jesse Keating 7a32965
-			    start + size <= p->start + p->size)
Jesse Keating 7a32965
-				return split_block(p, start, size, file_priv);
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-	} else {
Jesse Keating 7a32965
-		list_for_each(p, heap) {
Jesse Keating 7a32965
-			uint64_t start = (p->start + mask) & ~mask;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-			if (p->file_priv == NULL &&
Jesse Keating 7a32965
-			    start + size <= p->start + p->size)
Jesse Keating 7a32965
-				return split_block(p, start, size, file_priv);
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return NULL;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-void nouveau_mem_free_block(struct mem_block *p)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	p->file_priv = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Assumes a single contiguous range.  Needs a special file_priv in
Jesse Keating 7a32965
-	 * 'heap' to stop it being subsumed.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (p->next->file_priv == NULL) {
Jesse Keating 7a32965
-		struct mem_block *q = p->next;
Jesse Keating 7a32965
-		p->size += q->size;
Jesse Keating 7a32965
-		p->next = q->next;
Jesse Keating 7a32965
-		p->next->prev = p;
Jesse Keating 7a32965
-		kfree(q);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (p->prev->file_priv == NULL) {
Jesse Keating 7a32965
-		struct mem_block *q = p->prev;
Jesse Keating 7a32965
-		q->size += p->size;
Jesse Keating 7a32965
-		q->next = p->next;
Jesse Keating 7a32965
-		q->next->prev = q;
Jesse Keating 7a32965
-		kfree(p);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/* Initialize.  How to check for an uninitialized heap?
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
Jesse Keating 7a32965
-			  uint64_t size)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!blocks)
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	*heap = kmalloc(sizeof(**heap), GFP_KERNEL);
Jesse Keating 7a32965
-	if (!*heap) {
Jesse Keating 7a32965
-		kfree(blocks);
Jesse Keating 7a32965
-		return -ENOMEM;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	blocks->start = start;
Jesse Keating 7a32965
-	blocks->size = size;
Jesse Keating 7a32965
-	blocks->file_priv = NULL;
Jesse Keating 7a32965
-	blocks->next = blocks->prev = *heap;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	memset(*heap, 0, sizeof(**heap));
Jesse Keating 7a32965
-	(*heap)->file_priv = (struct drm_file *) -1;
Jesse Keating 7a32965
-	(*heap)->next = (*heap)->prev = blocks;
Jesse Keating 7a32965
-	return 0;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/*
Jesse Keating 7a32965
- * Free all blocks associated with the releasing file_priv
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct mem_block *p;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!heap || !heap->next)
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	list_for_each(p, heap) {
Jesse Keating 7a32965
-		if (p->file_priv == file_priv)
Jesse Keating 7a32965
-			p->file_priv = NULL;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Assumes a single contiguous range.  Needs a special file_priv in
Jesse Keating 7a32965
-	 * 'heap' to stop it being subsumed.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	list_for_each(p, heap) {
Jesse Keating 7a32965
-		while ((p->file_priv == NULL) &&
Jesse Keating 7a32965
-					(p->next->file_priv == NULL) &&
Jesse Keating 7a32965
-					(p->next != heap)) {
Jesse Keating 7a32965
-			struct mem_block *q = p->next;
Jesse Keating 7a32965
-			p->size += q->size;
Jesse Keating 7a32965
-			p->next = q->next;
Jesse Keating 7a32965
-			p->next->prev = p;
Jesse Keating 7a32965
-			kfree(q);
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
  * NV10-NV40 tiling helpers
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
@@ -299,7 +143,6 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
Jesse Keating 7a32965
 		phys |= 0x30;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	dev_priv->engine.instmem.prepare_access(dev, true);
Jesse Keating 7a32965
 	while (size) {
Jesse Keating 7a32965
 		unsigned offset_h = upper_32_bits(phys);
Jesse Keating 7a32965
 		unsigned offset_l = lower_32_bits(phys);
Jesse Keating 7a32965
@@ -331,36 +174,12 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
Jesse Keating 7a32965
 			}
Jesse Keating 7a32965
 		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
-	dev_priv->engine.instmem.finish_access(dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00050001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return -EBUSY;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00000001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return -EBUSY;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00040001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return -EBUSY;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00060001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return -EBUSY;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+	dev_priv->engine.instmem.flush(dev);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 5);
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 0);
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 4);
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 6);
Jesse Keating 7a32965
 	return 0;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -374,7 +193,6 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
Jesse Keating 7a32965
 	virt -= dev_priv->vm_vram_base;
Jesse Keating 7a32965
 	pages = (size >> 16) << 1;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	dev_priv->engine.instmem.prepare_access(dev, true);
Jesse Keating 7a32965
 	while (pages) {
Jesse Keating 7a32965
 		pgt = dev_priv->vm_vram_pt[virt >> 29];
Jesse Keating 7a32965
 		pte = (virt & 0x1ffe0000ULL) >> 15;
Jesse Keating 7a32965
@@ -388,57 +206,19 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
Jesse Keating 7a32965
 		while (pte < end)
Jesse Keating 7a32965
 			nv_wo32(dev, pgt, pte++, 0);
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
-	dev_priv->engine.instmem.finish_access(dev);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00050001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00000001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00040001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+	dev_priv->engine.instmem.flush(dev);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	nv_wr32(dev, 0x100c80, 0x00060001);
Jesse Keating 7a32965
-	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
Jesse Keating 7a32965
-		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 5);
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 0);
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 4);
Jesse Keating 7a32965
+	nv50_vm_flush(dev, 6);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
  * Cleanup everything
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
-void nouveau_mem_takedown(struct mem_block **heap)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct mem_block *p;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!*heap)
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	for (p = (*heap)->next; p != *heap;) {
Jesse Keating 7a32965
-		struct mem_block *q = p;
Jesse Keating 7a32965
-		p = p->next;
Jesse Keating 7a32965
-		kfree(q);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	kfree(*heap);
Jesse Keating 7a32965
-	*heap = NULL;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-void nouveau_mem_close(struct drm_device *dev)
Jesse Keating 7a32965
+void
Jesse Keating 7a32965
+nouveau_mem_close(struct drm_device *dev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -449,8 +229,7 @@ void nouveau_mem_close(struct drm_device *dev)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	nouveau_ttm_global_release(dev_priv);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (drm_core_has_AGP(dev) && dev->agp &&
Jesse Keating 7a32965
-	    drm_core_check_feature(dev, DRIVER_MODESET)) {
Jesse Keating 7a32965
+	if (drm_core_has_AGP(dev) && dev->agp) {
Jesse Keating 7a32965
 		struct drm_agp_mem *entry, *tempe;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 		/* Remove AGP resources, but leave dev->agp
Jesse Keating 7a32965
@@ -470,29 +249,29 @@ void nouveau_mem_close(struct drm_device *dev)
Jesse Keating 7a32965
 		dev->agp->enabled = 0;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (dev_priv->fb_mtrr) {
Jesse Keating 7a32965
+	if (dev_priv->fb_mtrr >= 0) {
Jesse Keating 7a32965
 		drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),
Jesse Keating 7a32965
 			     drm_get_resource_len(dev, 1), DRM_MTRR_WC);
Jesse Keating 7a32965
-		dev_priv->fb_mtrr = 0;
Jesse Keating 7a32965
+		dev_priv->fb_mtrr = -1;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static uint32_t
Jesse Keating 7a32965
 nouveau_mem_detect_nv04(struct drm_device *dev)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
-	uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
Jesse Keating 7a32965
+	uint32_t boot0 = nv_rd32(dev, NV04_PFB_BOOT_0);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (boot0 & 0x00000100)
Jesse Keating 7a32965
 		return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
Jesse Keating 7a32965
-	case NV04_BOOT_0_RAM_AMOUNT_32MB:
Jesse Keating 7a32965
+	switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
Jesse Keating 7a32965
+	case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
Jesse Keating 7a32965
 		return 32 * 1024 * 1024;
Jesse Keating 7a32965
-	case NV04_BOOT_0_RAM_AMOUNT_16MB:
Jesse Keating 7a32965
+	case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
Jesse Keating 7a32965
 		return 16 * 1024 * 1024;
Jesse Keating 7a32965
-	case NV04_BOOT_0_RAM_AMOUNT_8MB:
Jesse Keating 7a32965
+	case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
Jesse Keating 7a32965
 		return 8 * 1024 * 1024;
Jesse Keating 7a32965
-	case NV04_BOOT_0_RAM_AMOUNT_4MB:
Jesse Keating 7a32965
+	case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
Jesse Keating 7a32965
 		return 4 * 1024 * 1024;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -536,12 +315,18 @@ nouveau_mem_detect(struct drm_device *dev)
Jesse Keating 7a32965
 	} else
Jesse Keating 7a32965
 	if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
Jesse Keating 7a32965
 		dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
Jesse Keating 7a32965
+	} else
Jesse Keating 7a32965
+	if (dev_priv->card_type < NV_50) {
Jesse Keating 7a32965
+		dev_priv->vram_size  = nv_rd32(dev, NV04_PFB_FIFO_DATA);
Jesse Keating 7a32965
+		dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
Jesse Keating 7a32965
 	} else {
Jesse Keating 7a32965
-		dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
Jesse Keating 7a32965
-		dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
Jesse Keating 7a32965
-		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
Jesse Keating 7a32965
+		dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA);
Jesse Keating 7a32965
+		dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
Jesse Keating 7a32965
+		dev_priv->vram_size &= 0xffffffff00ll;
Jesse Keating 7a32965
+		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
Jesse Keating 7a32965
 			dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
Jesse Keating 7a32965
 			dev_priv->vram_sys_base <<= 12;
Jesse Keating 7a32965
+		}
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
Jesse Keating 7a32965
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
Jesse Keating 7a32965
index 9537f3e..3ec181f 100644
Jesse Keating 7a32965
--- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
Jesse Keating 7a32965
+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
Jesse Keating 7a32965
@@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
Jesse Keating 7a32965
 	if (ret)
Jesse Keating 7a32965
 		goto out_err;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size);
Jesse Keating 7a32965
+	ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size);
Jesse Keating 7a32965
 	if (ret)
Jesse Keating 7a32965
 		goto out_err;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
Jesse Keating 7a32965
 	nouveau_bo_unpin(chan->notifier_bo);
Jesse Keating 7a32965
 	mutex_unlock(&dev->struct_mutex);
Jesse Keating 7a32965
 	drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
Jesse Keating 7a32965
-	nouveau_mem_takedown(&chan->notifier_heap);
Jesse Keating 7a32965
+	drm_mm_takedown(&chan->notifier_heap);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 static void
Jesse Keating 7a32965
@@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
Jesse Keating 7a32965
 	NV_DEBUG(dev, "\n");
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (gpuobj->priv)
Jesse Keating 7a32965
-		nouveau_mem_free_block(gpuobj->priv);
Jesse Keating 7a32965
+		drm_mm_put_block(gpuobj->priv);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 int
Jesse Keating 7a32965
@@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
Jesse Keating 7a32965
 	struct drm_device *dev = chan->dev;
Jesse Keating 7a32965
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
Jesse Keating 7a32965
 	struct nouveau_gpuobj *nobj = NULL;
Jesse Keating 7a32965
-	struct mem_block *mem;
Jesse Keating 7a32965
+	struct drm_mm_node *mem;
Jesse Keating 7a32965
 	uint32_t offset;
Jesse Keating 7a32965
 	int target, ret;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (!chan->notifier_heap) {
Jesse Keating 7a32965
-		NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n",
Jesse Keating 7a32965
-			 chan->id);
Jesse Keating 7a32965
-		return -EINVAL;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0,
Jesse Keating 7a32965
-				      (struct drm_file *)-2, 0);
Jesse Keating 7a32965
+	mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0);
Jesse Keating 7a32965
+	if