[kernel] cleanup drm patches

Kyle McMartin kyle at fedoraproject.org
Sat Oct 16 17:19:38 UTC 2010


commit d3e4af8507577f6aa9e7bf7ee1b61f112a5cd379
Author: Kyle McMartin <kyle at dreadnought.i.jkkm.org>
Date:   Sat Oct 16 13:19:24 2010 -0400

    cleanup drm patches

 drm-nouveau-updates.patch                          | 6998 +-------------------
 ...-rework-output-polling-to-be-back-in-core.patch |  958 ---
 kernel.spec                                        |   14 +-
 revert-drm-kms-toggle-poll-around-switcheroo.patch |   65 -
 4 files changed, 8 insertions(+), 8027 deletions(-)
---
diff --git a/drm-nouveau-updates.patch b/drm-nouveau-updates.patch
index 1b704ff..607602c 100644
--- a/drm-nouveau-updates.patch
+++ b/drm-nouveau-updates.patch
@@ -1,6997 +1 @@
- drivers/gpu/drm/drm_crtc_helper.c           |   22 +-
- drivers/gpu/drm/i2c/ch7006_drv.c            |   22 +-
- drivers/gpu/drm/i2c/ch7006_priv.h           |    2 +-
- drivers/gpu/drm/nouveau/Makefile            |    2 +-
- drivers/gpu/drm/nouveau/nouveau_acpi.c      |   38 ++-
- drivers/gpu/drm/nouveau/nouveau_bios.c      |  636 +++++++++++++++++++++------
- drivers/gpu/drm/nouveau/nouveau_bios.h      |    4 +-
- drivers/gpu/drm/nouveau/nouveau_bo.c        |    9 +-
- drivers/gpu/drm/nouveau/nouveau_calc.c      |    4 +-
- drivers/gpu/drm/nouveau/nouveau_channel.c   |    5 -
- drivers/gpu/drm/nouveau/nouveau_connector.c |  404 ++++++++----------
- drivers/gpu/drm/nouveau/nouveau_connector.h |    7 +-
- drivers/gpu/drm/nouveau/nouveau_dma.c       |    8 +-
- drivers/gpu/drm/nouveau/nouveau_dp.c        |   24 +-
- drivers/gpu/drm/nouveau/nouveau_drv.c       |   31 +-
- drivers/gpu/drm/nouveau/nouveau_drv.h       |   90 ++---
- drivers/gpu/drm/nouveau/nouveau_encoder.h   |   10 +-
- drivers/gpu/drm/nouveau/nouveau_fbcon.c     |    2 +-
- drivers/gpu/drm/nouveau/nouveau_fence.c     |   31 +-
- drivers/gpu/drm/nouveau/nouveau_gem.c       |   11 +-
- drivers/gpu/drm/nouveau/nouveau_grctx.c     |  160 -------
- drivers/gpu/drm/nouveau/nouveau_i2c.c       |   34 ++
- drivers/gpu/drm/nouveau/nouveau_i2c.h       |    3 +
- drivers/gpu/drm/nouveau/nouveau_mem.c       |  275 ++----------
- drivers/gpu/drm/nouveau/nouveau_notifier.c  |   30 +-
- drivers/gpu/drm/nouveau/nouveau_object.c    |  105 ++---
- drivers/gpu/drm/nouveau/nouveau_reg.h       |   91 +++--
- drivers/gpu/drm/nouveau/nouveau_sgdma.c     |   46 +--
- drivers/gpu/drm/nouveau/nouveau_state.c     |  172 +++-----
- drivers/gpu/drm/nouveau/nv04_crtc.c         |    5 +
- drivers/gpu/drm/nouveau/nv04_dac.c          |   37 ++-
- drivers/gpu/drm/nouveau/nv04_dfp.c          |   12 +-
- drivers/gpu/drm/nouveau/nv04_display.c      |   64 ++--
- drivers/gpu/drm/nouveau/nv04_fifo.c         |   20 +-
- drivers/gpu/drm/nouveau/nv04_graph.c        |    5 +-
- drivers/gpu/drm/nouveau/nv04_instmem.c      |   21 +-
- drivers/gpu/drm/nouveau/nv04_mc.c           |    4 +
- drivers/gpu/drm/nouveau/nv04_tv.c           |  125 ++----
- drivers/gpu/drm/nouveau/nv10_fifo.c         |   10 -
- drivers/gpu/drm/nouveau/nv17_tv.c           |   46 ++-
- drivers/gpu/drm/nouveau/nv20_graph.c        |   96 +++--
- drivers/gpu/drm/nouveau/nv40_fifo.c         |    8 -
- drivers/gpu/drm/nouveau/nv40_graph.c        |   58 +--
- drivers/gpu/drm/nouveau/nv40_mc.c           |    2 +-
- drivers/gpu/drm/nouveau/nv50_crtc.c         |   42 +--
- drivers/gpu/drm/nouveau/nv50_dac.c          |   43 ++-
- drivers/gpu/drm/nouveau/nv50_display.c      |  385 ++++++++++-------
- drivers/gpu/drm/nouveau/nv50_fifo.c         |  126 ++----
- drivers/gpu/drm/nouveau/nv50_graph.c        |   86 ++---
- drivers/gpu/drm/nouveau/nv50_instmem.c      |   67 +--
- drivers/gpu/drm/nouveau/nv50_sor.c          |  105 +++---
- drivers/gpu/drm/nouveau/nvreg.h             |   22 -
- 52 files changed, 1748 insertions(+), 1919 deletions(-)
-
-diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
-index 9b2a541..1eaa315 100644
---- a/drivers/gpu/drm/drm_crtc_helper.c
-+++ b/drivers/gpu/drm/drm_crtc_helper.c
-@@ -201,6 +201,17 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
- }
- EXPORT_SYMBOL(drm_helper_crtc_in_use);
- 
-+static void
-+drm_encoder_disable(struct drm_encoder *encoder)
-+{
-+	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
-+
-+	if (encoder_funcs->disable)
-+		(*encoder_funcs->disable)(encoder);
-+	else
-+		(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
-+}
-+
- /**
-  * drm_helper_disable_unused_functions - disable unused objects
-  * @dev: DRM device
-@@ -215,7 +226,6 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
- {
- 	struct drm_encoder *encoder;
- 	struct drm_connector *connector;
--	struct drm_encoder_helper_funcs *encoder_funcs;
- 	struct drm_crtc *crtc;
- 
- 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-@@ -226,12 +236,8 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
- 	}
- 
- 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
--		encoder_funcs = encoder->helper_private;
- 		if (!drm_helper_encoder_in_use(encoder)) {
--			if (encoder_funcs->disable)
--				(*encoder_funcs->disable)(encoder);
--			else
--				(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
-+			drm_encoder_disable(encoder);
- 			/* disconnector encoder from any connector */
- 			encoder->crtc = NULL;
- 		}
-@@ -292,11 +298,11 @@ drm_crtc_prepare_encoders(struct drm_device *dev)
- 		encoder_funcs = encoder->helper_private;
- 		/* Disable unused encoders */
- 		if (encoder->crtc == NULL)
--			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
-+			drm_encoder_disable(encoder);
- 		/* Disable encoders whose CRTC is about to change */
- 		if (encoder_funcs->get_crtc &&
- 		    encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
--			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
-+			drm_encoder_disable(encoder);
- 	}
- }
- 
-diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c
-index 81681a0..833b35f 100644
---- a/drivers/gpu/drm/i2c/ch7006_drv.c
-+++ b/drivers/gpu/drm/i2c/ch7006_drv.c
-@@ -33,7 +33,7 @@ static void ch7006_encoder_set_config(struct drm_encoder *encoder,
- {
- 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
- 
--	priv->params = params;
-+	priv->params = *(struct ch7006_encoder_params *)params;
- }
- 
- static void ch7006_encoder_destroy(struct drm_encoder *encoder)
-@@ -114,7 +114,7 @@ static void ch7006_encoder_mode_set(struct drm_encoder *encoder,
- {
- 	struct i2c_client *client = drm_i2c_encoder_get_client(encoder);
- 	struct ch7006_priv *priv = to_ch7006_priv(encoder);
--	struct ch7006_encoder_params *params = priv->params;
-+	struct ch7006_encoder_params *params = &priv->params;
- 	struct ch7006_state *state = &priv->state;
- 	uint8_t *regs = state->regs;
- 	struct ch7006_mode *mode = priv->mode;
-@@ -428,6 +428,22 @@ static int ch7006_remove(struct i2c_client *client)
- 	return 0;
- }
- 
-+static int ch7006_suspend(struct i2c_client *client, pm_message_t mesg)
-+{
-+	ch7006_dbg(client, "\n");
-+
-+	return 0;
-+}
-+
-+static int ch7006_resume(struct i2c_client *client)
-+{
-+	ch7006_dbg(client, "\n");
-+
-+	ch7006_write(client, 0x3d, 0x0);
-+
-+	return 0;
-+}
-+
- static int ch7006_encoder_init(struct i2c_client *client,
- 			       struct drm_device *dev,
- 			       struct drm_encoder_slave *encoder)
-@@ -487,6 +503,8 @@ static struct drm_i2c_encoder_driver ch7006_driver = {
- 	.i2c_driver = {
- 		.probe = ch7006_probe,
- 		.remove = ch7006_remove,
-+		.suspend = ch7006_suspend,
-+		.resume = ch7006_resume,
- 
- 		.driver = {
- 			.name = "ch7006",
-diff --git a/drivers/gpu/drm/i2c/ch7006_priv.h b/drivers/gpu/drm/i2c/ch7006_priv.h
-index b06d3d9..1c6d2e3 100644
---- a/drivers/gpu/drm/i2c/ch7006_priv.h
-+++ b/drivers/gpu/drm/i2c/ch7006_priv.h
-@@ -77,7 +77,7 @@ struct ch7006_state {
- };
- 
- struct ch7006_priv {
--	struct ch7006_encoder_params *params;
-+	struct ch7006_encoder_params params;
- 	struct ch7006_mode *mode;
- 
- 	struct ch7006_state state;
-diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
-index acd31ed..4a1db73 100644
---- a/drivers/gpu/drm/nouveau/Makefile
-+++ b/drivers/gpu/drm/nouveau/Makefile
-@@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
-              nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \
-              nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
-              nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
--             nouveau_dp.o nouveau_grctx.o \
-+             nouveau_dp.o \
-              nv04_timer.o \
-              nv04_mc.o nv40_mc.o nv50_mc.o \
-              nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
-diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
-index d4bcca8..c17a055 100644
---- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
-@@ -3,6 +3,7 @@
- #include <linux/slab.h>
- #include <acpi/acpi_drivers.h>
- #include <acpi/acpi_bus.h>
-+#include <acpi/video.h>
- 
- #include "drmP.h"
- #include "drm.h"
-@@ -11,6 +12,7 @@
- #include "nouveau_drv.h"
- #include "nouveau_drm.h"
- #include "nv50_display.h"
-+#include "nouveau_connector.h"
- 
- #include <linux/vga_switcheroo.h>
- 
-@@ -42,7 +44,7 @@ static const char nouveau_dsm_muid[] = {
- 	0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
- };
- 
--static int nouveau_dsm(acpi_handle handle, int func, int arg, int *result)
-+static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
- {
- 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- 	struct acpi_object_list input;
-@@ -259,3 +261,37 @@ int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
- {
- 	return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
- }
-+
-+int
-+nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
-+{
-+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
-+	struct acpi_device *acpidev;
-+	acpi_handle handle;
-+	int type, ret;
-+	void *edid;
-+
-+	switch (connector->connector_type) {
-+	case DRM_MODE_CONNECTOR_LVDS:
-+	case DRM_MODE_CONNECTOR_eDP:
-+		type = ACPI_VIDEO_DISPLAY_LCD;
-+		break;
-+	default:
-+		return -EINVAL;
-+	}
-+
-+	handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
-+	if (!handle)
-+		return -ENODEV;
-+
-+	ret = acpi_bus_get_device(handle, &acpidev);
-+	if (ret)
-+		return -ENODEV;
-+
-+	ret = acpi_video_get_edid(acpidev, type, -1, &edid);
-+	if (ret < 0)
-+		return ret;
-+
-+	nv_connector->edid = edid;
-+	return 0;
-+}
-diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
-index e492919..aae29cc 100644
---- a/drivers/gpu/drm/nouveau/nouveau_bios.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
-@@ -28,6 +28,8 @@
- #include "nouveau_hw.h"
- #include "nouveau_encoder.h"
- 
-+#include <linux/io-mapping.h>
-+
- /* these defines are made up */
- #define NV_CIO_CRE_44_HEADA 0x0
- #define NV_CIO_CRE_44_HEADB 0x3
-@@ -209,20 +211,20 @@ static struct methods shadow_methods[] = {
- 	{ "PCIROM", load_vbios_pci, true },
- 	{ "ACPI", load_vbios_acpi, true },
- };
-+#define NUM_SHADOW_METHODS ARRAY_SIZE(shadow_methods)
- 
- static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
- {
--	const int nr_methods = ARRAY_SIZE(shadow_methods);
- 	struct methods *methods = shadow_methods;
- 	int testscore = 3;
--	int scores[nr_methods], i;
-+	int scores[NUM_SHADOW_METHODS], i;
- 
- 	if (nouveau_vbios) {
--		for (i = 0; i < nr_methods; i++)
-+		for (i = 0; i < NUM_SHADOW_METHODS; i++)
- 			if (!strcasecmp(nouveau_vbios, methods[i].desc))
- 				break;
- 
--		if (i < nr_methods) {
-+		if (i < NUM_SHADOW_METHODS) {
- 			NV_INFO(dev, "Attempting to use BIOS image from %s\n",
- 				methods[i].desc);
- 
-@@ -234,7 +236,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
- 		NV_ERROR(dev, "VBIOS source \'%s\' invalid\n", nouveau_vbios);
- 	}
- 
--	for (i = 0; i < nr_methods; i++) {
-+	for (i = 0; i < NUM_SHADOW_METHODS; i++) {
- 		NV_TRACE(dev, "Attempting to load BIOS image from %s\n",
- 			 methods[i].desc);
- 		data[0] = data[1] = 0;	/* avoid reuse of previous image */
-@@ -245,7 +247,7 @@ static bool NVShadowVBIOS(struct drm_device *dev, uint8_t *data)
- 	}
- 
- 	while (--testscore > 0) {
--		for (i = 0; i < nr_methods; i++) {
-+		for (i = 0; i < NUM_SHADOW_METHODS; i++) {
- 			if (scores[i] == testscore) {
- 				NV_TRACE(dev, "Using BIOS image from %s\n",
- 					 methods[i].desc);
-@@ -920,7 +922,7 @@ init_io_restrict_prog(struct nvbios *bios, uint16_t offset,
- 		NV_ERROR(bios->dev,
- 			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- 			 offset, config, count);
--		return -EINVAL;
-+		return len;
- 	}
- 
- 	configval = ROM32(bios->data[offset + 11 + config * 4]);
-@@ -1022,7 +1024,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
- 		NV_ERROR(bios->dev,
- 			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- 			 offset, config, count);
--		return -EINVAL;
-+		return len;
- 	}
- 
- 	freq = ROM16(bios->data[offset + 12 + config * 2]);
-@@ -1194,7 +1196,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	dpe = nouveau_bios_dp_table(dev, dcb, &dummy);
- 	if (!dpe) {
- 		NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset);
--		return -EINVAL;
-+		return 3;
- 	}
- 
- 	switch (cond) {
-@@ -1218,12 +1220,16 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		int ret;
- 
- 		auxch = nouveau_i2c_find(dev, bios->display.output->i2c_index);
--		if (!auxch)
--			return -ENODEV;
-+		if (!auxch) {
-+			NV_ERROR(dev, "0x%04X: couldn't get auxch\n", offset);
-+			return 3;
-+		}
- 
- 		ret = nouveau_dp_auxch(auxch, 9, 0xd, &cond, 1);
--		if (ret)
--			return ret;
-+		if (ret) {
-+			NV_ERROR(dev, "0x%04X: auxch rd fail: %d\n", offset, ret);
-+			return 3;
-+		}
- 
- 		if (cond & 1)
- 			iexec->execute = false;
-@@ -1392,7 +1398,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
- 		NV_ERROR(bios->dev,
- 			 "0x%04X: Config 0x%02X exceeds maximal bound 0x%02X\n",
- 			 offset, config, count);
--		return -EINVAL;
-+		return len;
- 	}
- 
- 	freq = ROM32(bios->data[offset + 11 + config * 4]);
-@@ -1452,6 +1458,7 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	 * "mask n" and OR it with "data n" before writing it back to the device
- 	 */
- 
-+	struct drm_device *dev = bios->dev;
- 	uint8_t i2c_index = bios->data[offset + 1];
- 	uint8_t i2c_address = bios->data[offset + 2] >> 1;
- 	uint8_t count = bios->data[offset + 3];
-@@ -1466,9 +1473,11 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		      "Count: 0x%02X\n",
- 		offset, i2c_index, i2c_address, count);
- 
--	chan = init_i2c_device_find(bios->dev, i2c_index);
--	if (!chan)
--		return -ENODEV;
-+	chan = init_i2c_device_find(dev, i2c_index);
-+	if (!chan) {
-+		NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
-+		return len;
-+	}
- 
- 	for (i = 0; i < count; i++) {
- 		uint8_t reg = bios->data[offset + 4 + i * 3];
-@@ -1479,8 +1488,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- 				     I2C_SMBUS_READ, reg,
- 				     I2C_SMBUS_BYTE_DATA, &val);
--		if (ret < 0)
--			return ret;
-+		if (ret < 0) {
-+			NV_ERROR(dev, "0x%04X: i2c rd fail: %d\n", offset, ret);
-+			return len;
-+		}
- 
- 		BIOSLOG(bios, "0x%04X: I2CReg: 0x%02X, Value: 0x%02X, "
- 			      "Mask: 0x%02X, Data: 0x%02X\n",
-@@ -1494,8 +1505,10 @@ init_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- 				     I2C_SMBUS_WRITE, reg,
- 				     I2C_SMBUS_BYTE_DATA, &val);
--		if (ret < 0)
--			return ret;
-+		if (ret < 0) {
-+			NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
-+			return len;
-+		}
- 	}
- 
- 	return len;
-@@ -1520,6 +1533,7 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	 * "DCB I2C table entry index", set the register to "data n"
- 	 */
- 
-+	struct drm_device *dev = bios->dev;
- 	uint8_t i2c_index = bios->data[offset + 1];
- 	uint8_t i2c_address = bios->data[offset + 2] >> 1;
- 	uint8_t count = bios->data[offset + 3];
-@@ -1534,9 +1548,11 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		      "Count: 0x%02X\n",
- 		offset, i2c_index, i2c_address, count);
- 
--	chan = init_i2c_device_find(bios->dev, i2c_index);
--	if (!chan)
--		return -ENODEV;
-+	chan = init_i2c_device_find(dev, i2c_index);
-+	if (!chan) {
-+		NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
-+		return len;
-+	}
- 
- 	for (i = 0; i < count; i++) {
- 		uint8_t reg = bios->data[offset + 4 + i * 2];
-@@ -1553,8 +1569,10 @@ init_zm_i2c_byte(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		ret = i2c_smbus_xfer(&chan->adapter, i2c_address, 0,
- 				     I2C_SMBUS_WRITE, reg,
- 				     I2C_SMBUS_BYTE_DATA, &val);
--		if (ret < 0)
--			return ret;
-+		if (ret < 0) {
-+			NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
-+			return len;
-+		}
- 	}
- 
- 	return len;
-@@ -1577,6 +1595,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	 * address" on the I2C bus given by "DCB I2C table entry index"
- 	 */
- 
-+	struct drm_device *dev = bios->dev;
- 	uint8_t i2c_index = bios->data[offset + 1];
- 	uint8_t i2c_address = bios->data[offset + 2] >> 1;
- 	uint8_t count = bios->data[offset + 3];
-@@ -1584,7 +1603,7 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	struct nouveau_i2c_chan *chan;
- 	struct i2c_msg msg;
- 	uint8_t data[256];
--	int i;
-+	int ret, i;
- 
- 	if (!iexec->execute)
- 		return len;
-@@ -1593,9 +1612,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		      "Count: 0x%02X\n",
- 		offset, i2c_index, i2c_address, count);
- 
--	chan = init_i2c_device_find(bios->dev, i2c_index);
--	if (!chan)
--		return -ENODEV;
-+	chan = init_i2c_device_find(dev, i2c_index);
-+	if (!chan) {
-+		NV_ERROR(dev, "0x%04X: i2c bus not found\n", offset);
-+		return len;
-+	}
- 
- 	for (i = 0; i < count; i++) {
- 		data[i] = bios->data[offset + 4 + i];
-@@ -1608,8 +1629,11 @@ init_zm_i2c(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		msg.flags = 0;
- 		msg.len = count;
- 		msg.buf = data;
--		if (i2c_transfer(&chan->adapter, &msg, 1) != 1)
--			return -EIO;
-+		ret = i2c_transfer(&chan->adapter, &msg, 1);
-+		if (ret != 1) {
-+			NV_ERROR(dev, "0x%04X: i2c wr fail: %d\n", offset, ret);
-+			return len;
-+		}
- 	}
- 
- 	return len;
-@@ -1633,6 +1657,7 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	 * used -- see get_tmds_index_reg()
- 	 */
- 
-+	struct drm_device *dev = bios->dev;
- 	uint8_t mlv = bios->data[offset + 1];
- 	uint32_t tmdsaddr = bios->data[offset + 2];
- 	uint8_t mask = bios->data[offset + 3];
-@@ -1647,8 +1672,10 @@ init_tmds(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		offset, mlv, tmdsaddr, mask, data);
- 
- 	reg = get_tmds_index_reg(bios->dev, mlv);
--	if (!reg)
--		return -EINVAL;
-+	if (!reg) {
-+		NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
-+		return 5;
-+	}
- 
- 	bios_wr32(bios, reg,
- 		  tmdsaddr | NV_PRAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE);
-@@ -1678,6 +1705,7 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
- 	 * register is used -- see get_tmds_index_reg()
- 	 */
- 
-+	struct drm_device *dev = bios->dev;
- 	uint8_t mlv = bios->data[offset + 1];
- 	uint8_t count = bios->data[offset + 2];
- 	int len = 3 + count * 2;
-@@ -1691,8 +1719,10 @@ init_zm_tmds_group(struct nvbios *bios, uint16_t offset,
- 		offset, mlv, count);
- 
- 	reg = get_tmds_index_reg(bios->dev, mlv);
--	if (!reg)
--		return -EINVAL;
-+	if (!reg) {
-+		NV_ERROR(dev, "0x%04X: no tmds_index_reg\n", offset);
-+		return len;
-+	}
- 
- 	for (i = 0; i < count; i++) {
- 		uint8_t tmdsaddr = bios->data[offset + 3 + i * 2];
-@@ -2039,6 +2069,323 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	return 5;
- }
- 
-+static inline void
-+bios_md32(struct nvbios *bios, uint32_t reg,
-+	  uint32_t mask, uint32_t val)
-+{
-+	bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val);
-+}
-+
-+static uint32_t
-+peek_fb(struct drm_device *dev, struct io_mapping *fb,
-+	uint32_t off)
-+{
-+	uint32_t val = 0;
-+
-+	if (off < pci_resource_len(dev->pdev, 1)) {
-+		uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off);
-+
-+		val = ioread32(p);
-+
-+		io_mapping_unmap_atomic(p);
-+	}
-+
-+	return val;
-+}
-+
-+static void
-+poke_fb(struct drm_device *dev, struct io_mapping *fb,
-+	uint32_t off, uint32_t val)
-+{
-+	if (off < pci_resource_len(dev->pdev, 1)) {
-+		uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off);
-+
-+		iowrite32(val, p);
-+		wmb();
-+
-+		io_mapping_unmap_atomic(p);
-+	}
-+}
-+
-+static inline bool
-+read_back_fb(struct drm_device *dev, struct io_mapping *fb,
-+	     uint32_t off, uint32_t val)
-+{
-+	poke_fb(dev, fb, off, val);
-+	return val == peek_fb(dev, fb, off);
-+}
-+
-+static int
-+nv04_init_compute_mem(struct nvbios *bios)
-+{
-+	struct drm_device *dev = bios->dev;
-+	uint32_t patt = 0xdeadbeef;
-+	struct io_mapping *fb;
-+	int i;
-+
-+	/* Map the framebuffer aperture */
-+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
-+				  pci_resource_len(dev->pdev, 1));
-+	if (!fb)
-+		return -ENOMEM;
-+
-+	/* Sequencer and refresh off */
-+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
-+	bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF);
-+
-+	bios_md32(bios, NV04_PFB_BOOT_0, ~0,
-+		  NV04_PFB_BOOT_0_RAM_AMOUNT_16MB |
-+		  NV04_PFB_BOOT_0_RAM_WIDTH_128 |
-+		  NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT);
-+
-+	for (i = 0; i < 4; i++)
-+		poke_fb(dev, fb, 4 * i, patt);
-+
-+	poke_fb(dev, fb, 0x400000, patt + 1);
-+
-+	if (peek_fb(dev, fb, 0) == patt + 1) {
-+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
-+			  NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT);
-+		bios_md32(bios, NV04_PFB_DEBUG_0,
-+			  NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
-+
-+		for (i = 0; i < 4; i++)
-+			poke_fb(dev, fb, 4 * i, patt);
-+
-+		if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff))
-+			bios_md32(bios, NV04_PFB_BOOT_0,
-+				  NV04_PFB_BOOT_0_RAM_WIDTH_128 |
-+				  NV04_PFB_BOOT_0_RAM_AMOUNT,
-+				  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-+
-+	} else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) !=
-+		   (patt & 0xffff0000)) {
-+		bios_md32(bios, NV04_PFB_BOOT_0,
-+			  NV04_PFB_BOOT_0_RAM_WIDTH_128 |
-+			  NV04_PFB_BOOT_0_RAM_AMOUNT,
-+			  NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
-+
-+	} else if (peek_fb(dev, fb, 0) == patt) {
-+		if (read_back_fb(dev, fb, 0x800000, patt))
-+			bios_md32(bios, NV04_PFB_BOOT_0,
-+				  NV04_PFB_BOOT_0_RAM_AMOUNT,
-+				  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-+		else
-+			bios_md32(bios, NV04_PFB_BOOT_0,
-+				  NV04_PFB_BOOT_0_RAM_AMOUNT,
-+				  NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
-+
-+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE,
-+			  NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT);
-+
-+	} else if (!read_back_fb(dev, fb, 0x800000, patt)) {
-+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
-+			  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-+
-+	}
-+
-+	/* Refresh on, sequencer on */
-+	bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
-+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
-+
-+	io_mapping_free(fb);
-+	return 0;
-+}
-+
-+static const uint8_t *
-+nv05_memory_config(struct nvbios *bios)
-+{
-+	/* Defaults for BIOSes lacking a memory config table */
-+	static const uint8_t default_config_tab[][2] = {
-+		{ 0x24, 0x00 },
-+		{ 0x28, 0x00 },
-+		{ 0x24, 0x01 },
-+		{ 0x1f, 0x00 },
-+		{ 0x0f, 0x00 },
-+		{ 0x17, 0x00 },
-+		{ 0x06, 0x00 },
-+		{ 0x00, 0x00 }
-+	};
-+	int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) &
-+		 NV_PEXTDEV_BOOT_0_RAMCFG) >> 2;
-+
-+	if (bios->legacy.mem_init_tbl_ptr)
-+		return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i];
-+	else
-+		return default_config_tab[i];
-+}
-+
-+static int
-+nv05_init_compute_mem(struct nvbios *bios)
-+{
-+	struct drm_device *dev = bios->dev;
-+	const uint8_t *ramcfg = nv05_memory_config(bios);
-+	uint32_t patt = 0xdeadbeef;
-+	struct io_mapping *fb;
-+	int i, v;
-+
-+	/* Map the framebuffer aperture */
-+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
-+				  pci_resource_len(dev->pdev, 1));
-+	if (!fb)
-+		return -ENOMEM;
-+
-+	/* Sequencer off */
-+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20);
-+
-+	if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE)
-+		goto out;
-+
-+	bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0);
-+
-+	/* If present load the hardcoded scrambling table */
-+	if (bios->legacy.mem_init_tbl_ptr) {
-+		uint32_t *scramble_tab = (uint32_t *)&bios->data[
-+			bios->legacy.mem_init_tbl_ptr + 0x10];
-+
-+		for (i = 0; i < 8; i++)
-+			bios_wr32(bios, NV04_PFB_SCRAMBLE(i),
-+				  ROM32(scramble_tab[i]));
-+	}
-+
-+	/* Set memory type/width/length defaults depending on the straps */
-+	bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]);
-+
-+	if (ramcfg[1] & 0x80)
-+		bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE);
-+
-+	bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20);
-+	bios_md32(bios, NV04_PFB_CFG1, 0, 1);
-+
-+	/* Probe memory bus width */
-+	for (i = 0; i < 4; i++)
-+		poke_fb(dev, fb, 4 * i, patt);
-+
-+	if (peek_fb(dev, fb, 0xc) != patt)
-+		bios_md32(bios, NV04_PFB_BOOT_0,
-+			  NV04_PFB_BOOT_0_RAM_WIDTH_128, 0);
-+
-+	/* Probe memory length */
-+	v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT;
-+
-+	if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB &&
-+	    (!read_back_fb(dev, fb, 0x1000000, ++patt) ||
-+	     !read_back_fb(dev, fb, 0, ++patt)))
-+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
-+			  NV04_PFB_BOOT_0_RAM_AMOUNT_16MB);
-+
-+	if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB &&
-+	    !read_back_fb(dev, fb, 0x800000, ++patt))
-+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
-+			  NV04_PFB_BOOT_0_RAM_AMOUNT_8MB);
-+
-+	if (!read_back_fb(dev, fb, 0x400000, ++patt))
-+		bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT,
-+			  NV04_PFB_BOOT_0_RAM_AMOUNT_4MB);
-+
-+out:
-+	/* Sequencer on */
-+	NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20);
-+
-+	io_mapping_free(fb);
-+	return 0;
-+}
-+
-+static int
-+nv10_init_compute_mem(struct nvbios *bios)
-+{
-+	struct drm_device *dev = bios->dev;
-+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
-+	const int mem_width[] = { 0x10, 0x00, 0x20 };
-+	const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2);
-+	uint32_t patt = 0xdeadbeef;
-+	struct io_mapping *fb;
-+	int i, j, k;
-+
-+	/* Map the framebuffer aperture */
-+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
-+				  pci_resource_len(dev->pdev, 1));
-+	if (!fb)
-+		return -ENOMEM;
-+
-+	bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
-+
-+	/* Probe memory bus width */
-+	for (i = 0; i < mem_width_count; i++) {
-+		bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]);
-+
-+		for (j = 0; j < 4; j++) {
-+			for (k = 0; k < 4; k++)
-+				poke_fb(dev, fb, 0x1c, 0);
-+
-+			poke_fb(dev, fb, 0x1c, patt);
-+			poke_fb(dev, fb, 0x3c, 0);
-+
-+			if (peek_fb(dev, fb, 0x1c) == patt)
-+				goto mem_width_found;
-+		}
-+	}
-+
-+mem_width_found:
-+	patt <<= 1;
-+
-+	/* Probe amount of installed memory */
-+	for (i = 0; i < 4; i++) {
-+		int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000;
-+
-+		poke_fb(dev, fb, off, patt);
-+		poke_fb(dev, fb, 0, 0);
-+
-+		peek_fb(dev, fb, 0);
-+		peek_fb(dev, fb, 0);
-+		peek_fb(dev, fb, 0);
-+		peek_fb(dev, fb, 0);
-+
-+		if (peek_fb(dev, fb, off) == patt)
-+			goto amount_found;
-+	}
-+
-+	/* IC missing - disable the upper half memory space. */
-+	bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0);
-+
-+amount_found:
-+	io_mapping_free(fb);
-+	return 0;
-+}
-+
-+static int
-+nv20_init_compute_mem(struct nvbios *bios)
-+{
-+	struct drm_device *dev = bios->dev;
-+	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
-+	uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900);
-+	uint32_t amount, off;
-+	struct io_mapping *fb;
-+
-+	/* Map the framebuffer aperture */
-+	fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1),
-+				  pci_resource_len(dev->pdev, 1));
-+	if (!fb)
-+		return -ENOMEM;
-+
-+	bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1);
-+
-+	/* Allow full addressing */
-+	bios_md32(bios, NV04_PFB_CFG0, 0, mask);
-+
-+	amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
-+	for (off = amount; off > 0x2000000; off -= 0x2000000)
-+		poke_fb(dev, fb, off - 4, off);
-+
-+	amount = bios_rd32(bios, NV04_PFB_FIFO_DATA);
-+	if (amount != peek_fb(dev, fb, amount - 4))
-+		/* IC missing - disable the upper half memory space. */
-+		bios_md32(bios, NV04_PFB_CFG0, mask, 0);
-+
-+	io_mapping_free(fb);
-+	return 0;
-+}
-+
- static int
- init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- {
-@@ -2047,64 +2394,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	 *
- 	 * offset      (8 bit): opcode
- 	 *
--	 * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so
--	 * that the hardware can correctly calculate how much VRAM it has
--	 * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C))
-+	 * This opcode is meant to set the PFB memory config registers
-+	 * appropriately so that we can correctly calculate how much VRAM it
-+	 * has (on nv10 and better chipsets the amount of installed VRAM is
-+	 * subsequently reported in NV_PFB_CSTATUS (0x10020C)).
- 	 *
--	 * The implementation of this opcode in general consists of two parts:
--	 * 1) determination of the memory bus width
--	 * 2) determination of how many of the card's RAM pads have ICs attached
-+	 * The implementation of this opcode in general consists of several
-+	 * parts:
- 	 *
--	 * 1) is done by a cunning combination of writes to offsets 0x1c and
--	 * 0x3c in the framebuffer, and seeing whether the written values are
--	 * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0
-+	 * 1) Determination of memory type and density. Only necessary for
-+	 *    really old chipsets, the memory type reported by the strap bits
-+	 *    (0x101000) is assumed to be accurate on nv05 and newer.
- 	 *
--	 * 2) is done by a cunning combination of writes to an offset slightly
--	 * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing
--	 * if the test pattern can be read back. This then affects bits 12-15 of
--	 * NV_PFB_CFG0
-+	 * 2) Determination of the memory bus width. Usually done by a cunning
-+	 *    combination of writes to offsets 0x1c and 0x3c in the fb, and
-+	 *    seeing whether the written values are read back correctly.
- 	 *
--	 * In this context a "cunning combination" may include multiple reads
--	 * and writes to varying locations, often alternating the test pattern
--	 * and 0, doubtless to make sure buffers are filled, residual charges
--	 * on tracks are removed etc.
-+	 *    Only necessary on nv0x-nv1x and nv34, on the other cards we can
-+	 *    trust the straps.
- 	 *
--	 * Unfortunately, the "cunning combination"s mentioned above, and the
--	 * changes to the bits in NV_PFB_CFG0 differ with nearly every bios
--	 * trace I have.
-+	 * 3) Determination of how many of the card's RAM pads have ICs
-+	 *    attached, usually done by a cunning combination of writes to an
-+	 *    offset slightly less than the maximum memory reported by
-+	 *    NV_PFB_CSTATUS, then seeing if the test pattern can be read back.
- 	 *
--	 * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which
--	 * we started was correct, and use that instead
-+	 * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io
-+	 * logs of the VBIOS and kmmio traces of the binary driver POSTing the
-+	 * card show nothing being done for this opcode. Why is it still listed
-+	 * in the table?!
- 	 */
- 
- 	/* no iexec->execute check by design */
- 
--	/*
--	 * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS
--	 * and kmmio traces of the binary driver POSTing the card show nothing
--	 * being done for this opcode.  why is it still listed in the table?!
--	 */
--
- 	struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
-+	int ret;
- 
--	if (dev_priv->card_type >= NV_40)
--		return 1;
--
--	/*
--	 * On every card I've seen, this step gets done for us earlier in
--	 * the init scripts
--	uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01);
--	bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20);
--	 */
--
--	/*
--	 * This also has probably been done in the scripts, but an mmio trace of
--	 * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write)
--	 */
--	bios_wr32(bios, NV_PFB_REFCTRL, NV_PFB_REFCTRL_VALID_1);
-+	if (dev_priv->chipset >= 0x40 ||
-+	    dev_priv->chipset == 0x1a ||
-+	    dev_priv->chipset == 0x1f)
-+		ret = 0;
-+	else if (dev_priv->chipset >= 0x20 &&
-+		 dev_priv->chipset != 0x34)
-+		ret = nv20_init_compute_mem(bios);
-+	else if (dev_priv->chipset >= 0x10)
-+		ret = nv10_init_compute_mem(bios);
-+	else if (dev_priv->chipset >= 0x5)
-+		ret = nv05_init_compute_mem(bios);
-+	else
-+		ret = nv04_init_compute_mem(bios);
- 
--	/* write back the saved configuration value */
--	bios_wr32(bios, NV_PFB_CFG0, bios->state.saved_nv_pfb_cfg0);
-+	if (ret)
-+		return ret;
- 
- 	return 1;
- }
-@@ -2131,7 +2471,8 @@ init_reset(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 	/* no iexec->execute check by design */
- 
- 	pci_nv_19 = bios_rd32(bios, NV_PBUS_PCI_NV_19);
--	bios_wr32(bios, NV_PBUS_PCI_NV_19, 0);
-+	bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19 & ~0xf00);
-+
- 	bios_wr32(bios, reg, value1);
- 
- 	udelay(10);
-@@ -2167,7 +2508,7 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
- 	uint32_t reg, data;
- 
- 	if (bios->major_version > 2)
--		return -ENODEV;
-+		return 0;
- 
- 	bios_idxprt_wr(bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX, bios_idxprt_rd(
- 		       bios, NV_VIO_SRX, NV_VIO_SR_CLOCK_INDEX) | 0x20);
-@@ -2180,14 +2521,14 @@ init_configure_mem(struct nvbios *bios, uint16_t offset,
- 	     reg = ROM32(bios->data[seqtbloffs += 4])) {
- 
- 		switch (reg) {
--		case NV_PFB_PRE:
--			data = NV_PFB_PRE_CMD_PRECHARGE;
-+		case NV04_PFB_PRE:
-+			data = NV04_PFB_PRE_CMD_PRECHARGE;
- 			break;
--		case NV_PFB_PAD:
--			data = NV_PFB_PAD_CKE_NORMAL;
-+		case NV04_PFB_PAD:
-+			data = NV04_PFB_PAD_CKE_NORMAL;
- 			break;
--		case NV_PFB_REF:
--			data = NV_PFB_REF_CMD_REFRESH;
-+		case NV04_PFB_REF:
-+			data = NV04_PFB_REF_CMD_REFRESH;
- 			break;
- 		default:
- 			data = ROM32(bios->data[meminitdata]);
-@@ -2222,7 +2563,7 @@ init_configure_clk(struct nvbios *bios, uint16_t offset,
- 	int clock;
- 
- 	if (bios->major_version > 2)
--		return -ENODEV;
-+		return 0;
- 
- 	clock = ROM16(bios->data[meminitoffs + 4]) * 10;
- 	setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock);
-@@ -2255,7 +2596,7 @@ init_configure_preinit(struct nvbios *bios, uint16_t offset,
- 	uint8_t cr3c = ((straps << 2) & 0xf0) | (straps & (1 << 6));
- 
- 	if (bios->major_version > 2)
--		return -ENODEV;
-+		return 0;
- 
- 	bios_idxprt_wr(bios, NV_CIO_CRX__COLOR,
- 			     NV_CIO_CRE_SCRATCH4__INDEX, cr3c);
-@@ -2389,7 +2730,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset,
- 	 * offset + 1  (8 bit): mask
- 	 * offset + 2  (8 bit): cmpval
- 	 *
--	 * Test if (NV_PFB_BOOT_0 & "mask") equals "cmpval".
-+	 * Test if (NV04_PFB_BOOT_0 & "mask") equals "cmpval".
- 	 * If condition not met skip subsequent opcodes until condition is
- 	 * inverted (INIT_NOT), or we hit INIT_RESUME
- 	 */
-@@ -2401,7 +2742,7 @@ init_ram_condition(struct nvbios *bios, uint16_t offset,
- 	if (!iexec->execute)
- 		return 3;
- 
--	data = bios_rd32(bios, NV_PFB_BOOT_0) & mask;
-+	data = bios_rd32(bios, NV04_PFB_BOOT_0) & mask;
- 
- 	BIOSLOG(bios, "0x%04X: Checking if 0x%08X equals 0x%08X\n",
- 		offset, data, cmpval);
-@@ -2800,7 +3141,7 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 
- 	if (dev_priv->card_type != NV_50) {
- 		NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
--		return -ENODEV;
-+		return 1;
- 	}
- 
- 	if (!iexec->execute)
-@@ -2872,10 +3213,7 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
- 	uint8_t index;
- 	int i;
- 
--
--	if (!iexec->execute)
--		return len;
--
-+	/* critical! to know the length of the opcode */;
- 	if (!blocklen) {
- 		NV_ERROR(bios->dev,
- 			 "0x%04X: Zero block length - has the M table "
-@@ -2883,6 +3221,9 @@ init_ram_restrict_zm_reg_group(struct nvbios *bios, uint16_t offset,
- 		return -EINVAL;
- 	}
- 
-+	if (!iexec->execute)
-+		return len;
-+
- 	strap_ramcfg = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) >> 2) & 0xf;
- 	index = bios->data[bios->ram_restrict_tbl_ptr + strap_ramcfg];
- 
-@@ -3064,14 +3405,14 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 
- 	if (!bios->display.output) {
- 		NV_ERROR(dev, "INIT_AUXCH: no active output\n");
--		return -EINVAL;
-+		return len;
- 	}
- 
- 	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
- 	if (!auxch) {
- 		NV_ERROR(dev, "INIT_AUXCH: couldn't get auxch %d\n",
- 			 bios->display.output->i2c_index);
--		return -ENODEV;
-+		return len;
- 	}
- 
- 	if (!iexec->execute)
-@@ -3084,7 +3425,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		ret = nouveau_dp_auxch(auxch, 9, addr, &data, 1);
- 		if (ret) {
- 			NV_ERROR(dev, "INIT_AUXCH: rd auxch fail %d\n", ret);
--			return ret;
-+			return len;
- 		}
- 
- 		data &= bios->data[offset + 0];
-@@ -3093,7 +3434,7 @@ init_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		ret = nouveau_dp_auxch(auxch, 8, addr, &data, 1);
- 		if (ret) {
- 			NV_ERROR(dev, "INIT_AUXCH: wr auxch fail %d\n", ret);
--			return ret;
-+			return len;
- 		}
- 	}
- 
-@@ -3123,14 +3464,14 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 
- 	if (!bios->display.output) {
- 		NV_ERROR(dev, "INIT_ZM_AUXCH: no active output\n");
--		return -EINVAL;
-+		return len;
- 	}
- 
- 	auxch = init_i2c_device_find(dev, bios->display.output->i2c_index);
- 	if (!auxch) {
- 		NV_ERROR(dev, "INIT_ZM_AUXCH: couldn't get auxch %d\n",
- 			 bios->display.output->i2c_index);
--		return -ENODEV;
-+		return len;
- 	}
- 
- 	if (!iexec->execute)
-@@ -3141,7 +3482,7 @@ init_zm_auxch(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
- 		ret = nouveau_dp_auxch(auxch, 8, addr, &bios->data[offset], 1);
- 		if (ret) {
- 			NV_ERROR(dev, "INIT_ZM_AUXCH: wr auxch fail %d\n", ret);
--			return ret;
-+			return len;
- 		}
- 	}
- 
-@@ -5151,10 +5492,14 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi
- 	bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset];
- 	bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1];
- 	bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2];
--	bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
--	bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
--	bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
--	bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
-+	if (bios->data[legacy_i2c_offset + 4])
-+		bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4];
-+	if (bios->data[legacy_i2c_offset + 5])
-+		bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5];
-+	if (bios->data[legacy_i2c_offset + 6])
-+		bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6];
-+	if (bios->data[legacy_i2c_offset + 7])
-+		bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7];
- 
- 	if (bmplength > 74) {
- 		bios->fmaxvco = ROM32(bmp[67]);
-@@ -5589,9 +5934,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
- 			if (conf & 0x4 || conf & 0x8)
- 				entry->lvdsconf.use_power_scripts = true;
- 		} else {
--			mask = ~0x5;
-+			mask = ~0x7;
-+			if (conf & 0x2)
-+				entry->lvdsconf.use_acpi_for_edid = true;
- 			if (conf & 0x4)
- 				entry->lvdsconf.use_power_scripts = true;
-+			entry->lvdsconf.sor.link = (conf & 0x00000030) >> 4;
- 		}
- 		if (conf & mask) {
- 			/*
-@@ -5706,13 +6054,6 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
- 	case OUTPUT_TV:
- 		entry->tvconf.has_component_output = false;
- 		break;
--	case OUTPUT_TMDS:
--		/*
--		 * Invent a DVI-A output, by copying the fields of the DVI-D
--		 * output; reported to work by math_b on an NV20(!).
--		 */
--		fabricate_vga_output(dcb, entry->i2c_index, entry->heads);
--		break;
- 	case OUTPUT_LVDS:
- 		if ((conn & 0x00003f00) != 0x10)
- 			entry->lvdsconf.use_straps_for_mode = true;
-@@ -5793,6 +6134,31 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
- 	dcb->entries = newentries;
- }
- 
-+static bool
-+apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
-+{
-+	/* Dell Precision M6300
-+	 *   DCB entry 2: 02025312 00000010
-+	 *   DCB entry 3: 02026312 00000020
-+	 *
-+	 * Identical, except apparently a different connector on a
-+	 * different SOR link.  Not a clue how we're supposed to know
-+	 * which one is in use if it even shares an i2c line...
-+	 *
-+	 * Ignore the connector on the second SOR link to prevent
-+	 * nasty problems until this is sorted (assuming it's not a
-+	 * VBIOS bug).
-+	 */
-+	if ((dev->pdev->device == 0x040d) &&
-+	    (dev->pdev->subsystem_vendor == 0x1028) &&
-+	    (dev->pdev->subsystem_device == 0x019b)) {
-+		if (*conn == 0x02026312 && *conf == 0x00000020)
-+			return false;
-+	}
-+
-+	return true;
-+}
-+
- static int
- parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
- {
-@@ -5926,6 +6292,9 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads)
- 		if ((connection & 0x0000000f) == 0x0000000f)
- 			continue;
- 
-+		if (!apply_dcb_encoder_quirks(dev, i, &connection, &config))
-+			continue;
-+
- 		NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n",
- 			     dcb->entries, connection, config);
- 
-@@ -6182,8 +6551,10 @@ nouveau_run_vbios_init(struct drm_device *dev)
- 	int i, ret = 0;
- 
- 	NVLockVgaCrtcs(dev, false);
--	if (nv_two_heads(dev))
--		NVSetOwner(dev, bios->state.crtchead);
-+	if (nv_two_heads(dev)) {
-+		bios->state.crtchead = 0;
-+		NVSetOwner(dev, 0);
-+	}
- 
- 	if (bios->major_version < 5)	/* BMP only */
- 		load_nv17_hw_sequencer_ucode(dev, bios);
-@@ -6238,7 +6609,6 @@ static bool
- nouveau_bios_posted(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	bool was_locked;
- 	unsigned htotal;
- 
- 	if (dev_priv->chipset >= NV_50) {
-@@ -6248,13 +6618,14 @@ nouveau_bios_posted(struct drm_device *dev)
- 		return true;
- 	}
- 
--	was_locked = NVLockVgaCrtcs(dev, false);
-+	NVLockVgaCrtcs(dev, false);
- 	htotal  = NVReadVgaCrtc(dev, 0, 0x06);
- 	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
- 	htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
- 	htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
- 	htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
--	NVLockVgaCrtcs(dev, was_locked);
-+	NVLockVgaCrtcs(dev, true);
-+
- 	return (htotal != 0);
- }
- 
-@@ -6263,8 +6634,6 @@ nouveau_bios_init(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nvbios *bios = &dev_priv->vbios;
--	uint32_t saved_nv_pextdev_boot_0;
--	bool was_locked;
- 	int ret;
- 
- 	if (!NVInitVBIOS(dev))
-@@ -6284,40 +6653,29 @@ nouveau_bios_init(struct drm_device *dev)
- 	if (!bios->major_version)	/* we don't run version 0 bios */
- 		return 0;
- 
--	/* these will need remembering across a suspend */
--	saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0);
--	bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV_PFB_CFG0);
--
- 	/* init script execution disabled */
- 	bios->execute = false;
- 
- 	/* ... unless card isn't POSTed already */
- 	if (!nouveau_bios_posted(dev)) {
--		NV_INFO(dev, "Adaptor not initialised\n");
--		if (dev_priv->card_type < NV_40) {
--			NV_ERROR(dev, "Unable to POST this chipset\n");
--			return -ENODEV;
--		}
--
--		NV_INFO(dev, "Running VBIOS init tables\n");
-+		NV_INFO(dev, "Adaptor not initialised, "
-+			"running VBIOS init tables.\n");
- 		bios->execute = true;
- 	}
- 
--	bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0);
--
- 	ret = nouveau_run_vbios_init(dev);
- 	if (ret)
- 		return ret;
- 
- 	/* feature_byte on BMP is poor, but init always sets CR4B */
--	was_locked = NVLockVgaCrtcs(dev, false);
-+	NVLockVgaCrtcs(dev, false);
- 	if (bios->major_version < 5)
- 		bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
- 
- 	/* all BIT systems need p_f_m_t for digital_min_front_porch */
- 	if (bios->is_mobile || bios->major_version >= 5)
- 		ret = parse_fp_mode_table(dev, bios);
--	NVLockVgaCrtcs(dev, was_locked);
-+	NVLockVgaCrtcs(dev, true);
- 
- 	/* allow subsequent scripts to execute */
- 	bios->execute = true;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
-index adf4ec2..024458a 100644
---- a/drivers/gpu/drm/nouveau/nouveau_bios.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
-@@ -81,6 +81,7 @@ struct dcb_connector_table_entry {
- 	enum dcb_connector_type type;
- 	uint8_t index2;
- 	uint8_t gpio_tag;
-+	void *drm;
- };
- 
- struct dcb_connector_table {
-@@ -117,6 +118,7 @@ struct dcb_entry {
- 		struct {
- 			struct sor_conf sor;
- 			bool use_straps_for_mode;
-+			bool use_acpi_for_edid;
- 			bool use_power_scripts;
- 		} lvdsconf;
- 		struct {
-@@ -249,8 +251,6 @@ struct nvbios {
- 
- 	struct {
- 		int crtchead;
--		/* these need remembering across suspend */
--		uint32_t saved_nv_pfb_cfg0;
- 	} state;
- 
- 	struct {
-diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
-index 6f3c195..d8c341d 100644
---- a/drivers/gpu/drm/nouveau/nouveau_bo.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
-@@ -461,9 +461,9 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
- 		return ret;
- 
- 	ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL,
--					evict, no_wait_reserve, no_wait_gpu, new_mem);
--	if (nvbo->channel && nvbo->channel != chan)
--		ret = nouveau_fence_wait(fence, NULL, false, false);
-+					evict || (nvbo->channel &&
-+						  nvbo->channel != chan),
-+					no_wait_reserve, no_wait_gpu, new_mem);
- 	nouveau_fence_unref((void *)&fence);
- 	return ret;
- }
-@@ -711,8 +711,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
- 		return ret;
- 
- 	/* Software copy if the card isn't up and running yet. */
--	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DONE ||
--	    !dev_priv->channel) {
-+	if (!dev_priv->channel) {
- 		ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem);
- 		goto out;
- 	}
-diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c
-index 88f9bc0..ca85da7 100644
---- a/drivers/gpu/drm/nouveau/nouveau_calc.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_calc.c
-@@ -200,7 +200,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
- 	struct nv_sim_state sim_data;
- 	int MClk = nouveau_hw_get_clock(dev, MPLL);
- 	int NVClk = nouveau_hw_get_clock(dev, NVPLL);
--	uint32_t cfg1 = nvReadFB(dev, NV_PFB_CFG1);
-+	uint32_t cfg1 = nvReadFB(dev, NV04_PFB_CFG1);
- 
- 	sim_data.pclk_khz = VClk;
- 	sim_data.mclk_khz = MClk;
-@@ -218,7 +218,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
- 		sim_data.mem_latency = 3;
- 		sim_data.mem_page_miss = 10;
- 	} else {
--		sim_data.memory_type = nvReadFB(dev, NV_PFB_CFG0) & 0x1;
-+		sim_data.memory_type = nvReadFB(dev, NV04_PFB_CFG0) & 0x1;
- 		sim_data.memory_width = (nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
- 		sim_data.mem_latency = cfg1 & 0xf;
- 		sim_data.mem_page_miss = ((cfg1 >> 4) & 0xf) + ((cfg1 >> 31) & 0x1);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
-index 1fc57ef..e952c3b 100644
---- a/drivers/gpu/drm/nouveau/nouveau_channel.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
-@@ -257,9 +257,7 @@ nouveau_channel_free(struct nouveau_channel *chan)
- 	nouveau_debugfs_channel_fini(chan);
- 
- 	/* Give outstanding push buffers a chance to complete */
--	spin_lock_irqsave(&chan->fence.lock, flags);
- 	nouveau_fence_update(chan);
--	spin_unlock_irqrestore(&chan->fence.lock, flags);
- 	if (chan->fence.sequence != chan->fence.sequence_ack) {
- 		struct nouveau_fence *fence = NULL;
- 
-@@ -368,8 +366,6 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
- 	struct nouveau_channel *chan;
- 	int ret;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	if (dev_priv->engine.graph.accel_blocked)
- 		return -ENODEV;
- 
-@@ -418,7 +414,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data,
- 	struct drm_nouveau_channel_free *cfree = data;
- 	struct nouveau_channel *chan;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
- 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan);
- 
- 	nouveau_channel_free(chan);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
-index 149ed22..734e926 100644
---- a/drivers/gpu/drm/nouveau/nouveau_connector.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
-@@ -102,63 +102,15 @@ nouveau_connector_destroy(struct drm_connector *drm_connector)
- 	kfree(drm_connector);
- }
- 
--static void
--nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
--{
--	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
--
--	if (dev_priv->card_type >= NV_50)
--		return;
--
--	*flags = 0;
--	if (NVLockVgaCrtcs(dev_priv->dev, false))
--		*flags |= 1;
--	if (nv_heads_tied(dev_priv->dev))
--		*flags |= 2;
--
--	if (*flags & 2)
--		NVSetOwner(dev_priv->dev, 0); /* necessary? */
--}
--
--static void
--nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
--{
--	struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
--
--	if (dev_priv->card_type >= NV_50)
--		return;
--
--	if (flags & 2)
--		NVSetOwner(dev_priv->dev, 4);
--	if (flags & 1)
--		NVLockVgaCrtcs(dev_priv->dev, true);
--}
--
- static struct nouveau_i2c_chan *
- nouveau_connector_ddc_detect(struct drm_connector *connector,
- 			     struct nouveau_encoder **pnv_encoder)
- {
- 	struct drm_device *dev = connector->dev;
--	uint8_t out_buf[] = { 0x0, 0x0}, buf[2];
--	int ret, flags, i;
--
--	struct i2c_msg msgs[] = {
--		{
--			.addr = 0x50,
--			.flags = 0,
--			.len = 1,
--			.buf = out_buf,
--		},
--		{
--			.addr = 0x50,
--			.flags = I2C_M_RD,
--			.len = 1,
--			.buf = buf,
--		}
--	};
-+	int i;
- 
- 	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
--		struct nouveau_i2c_chan *i2c = NULL;
-+		struct nouveau_i2c_chan *i2c;
- 		struct nouveau_encoder *nv_encoder;
- 		struct drm_mode_object *obj;
- 		int id;
-@@ -171,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
- 		if (!obj)
- 			continue;
- 		nv_encoder = nouveau_encoder(obj_to_encoder(obj));
-+		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
- 
--		if (nv_encoder->dcb->i2c_index < 0xf)
--			i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
--		if (!i2c)
--			continue;
--
--		nouveau_connector_ddc_prepare(connector, &flags);
--		ret = i2c_transfer(&i2c->adapter, msgs, 2);
--		nouveau_connector_ddc_finish(connector, flags);
--
--		if (ret == 2) {
-+		if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
- 			*pnv_encoder = nv_encoder;
- 			return i2c;
- 		}
-@@ -234,21 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector)
- 	struct nouveau_connector *nv_connector = nouveau_connector(connector);
- 	struct nouveau_encoder *nv_encoder = NULL;
- 	struct nouveau_i2c_chan *i2c;
--	int type, flags;
--
--	if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS)
--		nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
--	if (nv_encoder && nv_connector->native_mode) {
--		unsigned status = connector_status_connected;
--
--#if defined(CONFIG_ACPI_BUTTON) || \
--	(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
--		if (!nouveau_ignorelid && !acpi_lid_open())
--			status = connector_status_unknown;
--#endif
--		nouveau_connector_set_encoder(connector, nv_encoder);
--		return status;
--	}
-+	int type;
- 
- 	/* Cleanup the previous EDID block. */
- 	if (nv_connector->edid) {
-@@ -259,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector)
- 
- 	i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
- 	if (i2c) {
--		nouveau_connector_ddc_prepare(connector, &flags);
- 		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
--		nouveau_connector_ddc_finish(connector, flags);
- 		drm_mode_connector_update_edid_property(connector,
- 							nv_connector->edid);
- 		if (!nv_connector->edid) {
-@@ -321,6 +249,85 @@ detect_analog:
- 	return connector_status_disconnected;
- }
- 
-+static enum drm_connector_status
-+nouveau_connector_detect_lvds(struct drm_connector *connector)
-+{
-+	struct drm_device *dev = connector->dev;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_connector *nv_connector = nouveau_connector(connector);
-+	struct nouveau_encoder *nv_encoder = NULL;
-+	enum drm_connector_status status = connector_status_disconnected;
-+
-+	/* Cleanup the previous EDID block. */
-+	if (nv_connector->edid) {
-+		drm_mode_connector_update_edid_property(connector, NULL);
-+		kfree(nv_connector->edid);
-+		nv_connector->edid = NULL;
-+	}
-+
-+	nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
-+	if (!nv_encoder)
-+		return connector_status_disconnected;
-+
-+	/* Try retrieving EDID via DDC */
-+	if (!dev_priv->vbios.fp_no_ddc) {
-+		status = nouveau_connector_detect(connector);
-+		if (status == connector_status_connected)
-+			goto out;
-+	}
-+
-+	/* On some laptops (Sony, i'm looking at you) there appears to
-+	 * be no direct way of accessing the panel's EDID.  The only
-+	 * option available to us appears to be to ask ACPI for help..
-+	 *
-+	 * It's important this check's before trying straps, one of the
-+	 * said manufacturer's laptops are configured in such a way
-+	 * the nouveau decides an entry in the VBIOS FP mode table is
-+	 * valid - it's not (rh#613284)
-+	 */
-+	if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
-+		if (!nouveau_acpi_edid(dev, connector)) {
-+			status = connector_status_connected;
-+			goto out;
-+		}
-+	}
-+
-+	/* If no EDID found above, and the VBIOS indicates a hardcoded
-+	 * modeline is avalilable for the panel, set it as the panel's
-+	 * native mode and exit.
-+	 */
-+	if (nouveau_bios_fp_mode(dev, NULL) && (dev_priv->vbios.fp_no_ddc ||
-+	    nv_encoder->dcb->lvdsconf.use_straps_for_mode)) {
-+		status = connector_status_connected;
-+		goto out;
-+	}
-+
-+	/* Still nothing, some VBIOS images have a hardcoded EDID block
-+	 * stored for the panel stored in them.
-+	 */
-+	if (!dev_priv->vbios.fp_no_ddc) {
-+		struct edid *edid =
-+			(struct edid *)nouveau_bios_embedded_edid(dev);
-+		if (edid) {
-+			nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-+			*(nv_connector->edid) = *edid;
-+			status = connector_status_connected;
-+		}
-+	}
-+
-+out:
-+#if defined(CONFIG_ACPI_BUTTON) || \
-+	(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
-+	if (status == connector_status_connected &&
-+	    !nouveau_ignorelid && !acpi_lid_open())
-+		status = connector_status_unknown;
-+#endif
-+
-+	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
-+	nouveau_connector_set_encoder(connector, nv_encoder);
-+	return status;
-+}
-+
- static void
- nouveau_connector_force(struct drm_connector *connector)
- {
-@@ -441,7 +448,8 @@ nouveau_connector_native_mode(struct drm_connector *connector)
- 	int high_w = 0, high_h = 0, high_v = 0;
- 
- 	list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
--		if (helper->mode_valid(connector, mode) != MODE_OK)
-+		if (helper->mode_valid(connector, mode) != MODE_OK ||
-+		    (mode->flags & DRM_MODE_FLAG_INTERLACE))
- 			continue;
- 
- 		/* Use preferred mode if there is one.. */
-@@ -534,21 +542,27 @@ static int
- nouveau_connector_get_modes(struct drm_connector *connector)
- {
- 	struct drm_device *dev = connector->dev;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_connector *nv_connector = nouveau_connector(connector);
- 	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
- 	int ret = 0;
- 
--	/* If we're not LVDS, destroy the previous native mode, the attached
--	 * monitor could have changed.
-+	/* destroy the native mode, the attached monitor could have changed.
- 	 */
--	if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS &&
--	    nv_connector->native_mode) {
-+	if (nv_connector->native_mode) {
- 		drm_mode_destroy(dev, nv_connector->native_mode);
- 		nv_connector->native_mode = NULL;
- 	}
- 
- 	if (nv_connector->edid)
- 		ret = drm_add_edid_modes(connector, nv_connector->edid);
-+	else
-+	if (nv_encoder->dcb->type == OUTPUT_LVDS &&
-+	    (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
-+	     dev_priv->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
-+		nv_connector->native_mode = drm_mode_create(dev);
-+		nouveau_bios_fp_mode(dev, nv_connector->native_mode);
-+	}
- 
- 	/* Find the native mode if this is a digital panel, if we didn't
- 	 * find any modes through DDC previously add the native mode to
-@@ -569,7 +583,8 @@ nouveau_connector_get_modes(struct drm_connector *connector)
- 		ret = get_slave_funcs(nv_encoder)->
- 			get_modes(to_drm_encoder(nv_encoder), connector);
- 
--	if (nv_encoder->dcb->type == OUTPUT_LVDS)
-+	if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS ||
-+	    nv_connector->dcb->type == DCB_CONNECTOR_eDP)
- 		ret += nouveau_connector_scaler_modes_add(connector);
- 
- 	return ret;
-@@ -643,6 +658,44 @@ nouveau_connector_best_encoder(struct drm_connector *connector)
- 	return NULL;
- }
- 
-+void
-+nouveau_connector_set_polling(struct drm_connector *connector)
-+{
-+	struct drm_device *dev = connector->dev;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct drm_crtc *crtc;
-+	bool spare_crtc = false;
-+
-+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
-+		spare_crtc |= !crtc->enabled;
-+
-+	connector->polled = 0;
-+
-+	switch (connector->connector_type) {
-+	case DRM_MODE_CONNECTOR_VGA:
-+	case DRM_MODE_CONNECTOR_TV:
-+		if (dev_priv->card_type >= NV_50 ||
-+		    (nv_gf4_disp_arch(dev) && spare_crtc))
-+			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-+		break;
-+
-+	case DRM_MODE_CONNECTOR_DVII:
-+	case DRM_MODE_CONNECTOR_DVID:
-+	case DRM_MODE_CONNECTOR_HDMIA:
-+	case DRM_MODE_CONNECTOR_DisplayPort:
-+	case DRM_MODE_CONNECTOR_eDP:
-+		if (dev_priv->card_type >= NV_50)
-+			connector->polled = DRM_CONNECTOR_POLL_HPD;
-+		else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID ||
-+			 spare_crtc)
-+			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-+		break;
-+
-+	default:
-+		break;
-+	}
-+}
-+
- static const struct drm_connector_helper_funcs
- nouveau_connector_helper_funcs = {
- 	.get_modes = nouveau_connector_get_modes,
-@@ -662,148 +715,74 @@ nouveau_connector_funcs = {
- 	.force = nouveau_connector_force
- };
- 
--static int
--nouveau_connector_create_lvds(struct drm_device *dev,
--			      struct drm_connector *connector)
--{
--	struct nouveau_connector *nv_connector = nouveau_connector(connector);
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nouveau_i2c_chan *i2c = NULL;
--	struct nouveau_encoder *nv_encoder;
--	struct drm_display_mode native, *mode, *temp;
--	bool dummy, if_is_24bit = false;
--	int ret, flags;
--
--	nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
--	if (!nv_encoder)
--		return -ENODEV;
--
--	ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &if_is_24bit);
--	if (ret) {
--		NV_ERROR(dev, "Error parsing LVDS table, disabling LVDS\n");
--		return ret;
--	}
--	nv_connector->use_dithering = !if_is_24bit;
--
--	/* Firstly try getting EDID over DDC, if allowed and I2C channel
--	 * is available.
--	 */
--	if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf)
--		i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
--
--	if (i2c) {
--		nouveau_connector_ddc_prepare(connector, &flags);
--		nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
--		nouveau_connector_ddc_finish(connector, flags);
--	}
--
--	/* If no EDID found above, and the VBIOS indicates a hardcoded
--	 * modeline is avalilable for the panel, set it as the panel's
--	 * native mode and exit.
--	 */
--	if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) &&
--	     (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
--	      dev_priv->vbios.fp_no_ddc)) {
--		nv_connector->native_mode = drm_mode_duplicate(dev, &native);
--		goto out;
--	}
--
--	/* Still nothing, some VBIOS images have a hardcoded EDID block
--	 * stored for the panel stored in them.
--	 */
--	if (!nv_connector->edid && !nv_connector->native_mode &&
--	    !dev_priv->vbios.fp_no_ddc) {
--		struct edid *edid =
--			(struct edid *)nouveau_bios_embedded_edid(dev);
--		if (edid) {
--			nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
--			*(nv_connector->edid) = *edid;
--		}
--	}
--
--	if (!nv_connector->edid)
--		goto out;
--
--	/* We didn't find/use a panel mode from the VBIOS, so parse the EDID
--	 * block and look for the preferred mode there.
--	 */
--	ret = drm_add_edid_modes(connector, nv_connector->edid);
--	if (ret == 0)
--		goto out;
--	nv_connector->detected_encoder = nv_encoder;
--	nv_connector->native_mode = nouveau_connector_native_mode(connector);
--	list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
--		drm_mode_remove(connector, mode);
--
--out:
--	if (!nv_connector->native_mode) {
--		NV_ERROR(dev, "LVDS present in DCB table, but couldn't "
--			      "determine its native mode.  Disabling.\n");
--		return -ENODEV;
--	}
--
--	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
--	return 0;
--}
-+static const struct drm_connector_funcs
-+nouveau_connector_funcs_lvds = {
-+	.dpms = drm_helper_connector_dpms,
-+	.save = NULL,
-+	.restore = NULL,
-+	.detect = nouveau_connector_detect_lvds,
-+	.destroy = nouveau_connector_destroy,
-+	.fill_modes = drm_helper_probe_single_connector_modes,
-+	.set_property = nouveau_connector_set_property,
-+	.force = nouveau_connector_force
-+};
- 
--int
--nouveau_connector_create(struct drm_device *dev,
--			 struct dcb_connector_table_entry *dcb)
-+struct drm_connector *
-+nouveau_connector_create(struct drm_device *dev, int index)
- {
-+	const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_connector *nv_connector = NULL;
-+	struct dcb_connector_table_entry *dcb = NULL;
- 	struct drm_connector *connector;
--	struct drm_encoder *encoder;
--	int ret, type;
-+	int type, ret = 0;
- 
- 	NV_DEBUG_KMS(dev, "\n");
- 
-+	if (index >= dev_priv->vbios.dcb.connector.entries)
-+		return ERR_PTR(-EINVAL);
-+
-+	dcb = &dev_priv->vbios.dcb.connector.entry[index];
-+	if (dcb->drm)
-+		return dcb->drm;
-+
- 	switch (dcb->type) {
--	case DCB_CONNECTOR_NONE:
--		return 0;
- 	case DCB_CONNECTOR_VGA:
--		NV_INFO(dev, "Detected a VGA connector\n");
- 		type = DRM_MODE_CONNECTOR_VGA;
- 		break;
- 	case DCB_CONNECTOR_TV_0:
- 	case DCB_CONNECTOR_TV_1:
- 	case DCB_CONNECTOR_TV_3:
--		NV_INFO(dev, "Detected a TV connector\n");
- 		type = DRM_MODE_CONNECTOR_TV;
- 		break;
- 	case DCB_CONNECTOR_DVI_I:
--		NV_INFO(dev, "Detected a DVI-I connector\n");
- 		type = DRM_MODE_CONNECTOR_DVII;
- 		break;
- 	case DCB_CONNECTOR_DVI_D:
--		NV_INFO(dev, "Detected a DVI-D connector\n");
- 		type = DRM_MODE_CONNECTOR_DVID;
- 		break;
- 	case DCB_CONNECTOR_HDMI_0:
- 	case DCB_CONNECTOR_HDMI_1:
--		NV_INFO(dev, "Detected a HDMI connector\n");
- 		type = DRM_MODE_CONNECTOR_HDMIA;
- 		break;
- 	case DCB_CONNECTOR_LVDS:
--		NV_INFO(dev, "Detected a LVDS connector\n");
- 		type = DRM_MODE_CONNECTOR_LVDS;
-+		funcs = &nouveau_connector_funcs_lvds;
- 		break;
- 	case DCB_CONNECTOR_DP:
--		NV_INFO(dev, "Detected a DisplayPort connector\n");
- 		type = DRM_MODE_CONNECTOR_DisplayPort;
- 		break;
- 	case DCB_CONNECTOR_eDP:
--		NV_INFO(dev, "Detected an eDP connector\n");
- 		type = DRM_MODE_CONNECTOR_eDP;
- 		break;
- 	default:
- 		NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
--		return -EINVAL;
-+		return ERR_PTR(-EINVAL);
- 	}
- 
- 	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
- 	if (!nv_connector)
--		return -ENOMEM;
-+		return ERR_PTR(-ENOMEM);
- 	nv_connector->dcb = dcb;
- 	connector = &nv_connector->base;
- 
-@@ -811,27 +790,21 @@ nouveau_connector_create(struct drm_device *dev,
- 	connector->interlace_allowed = false;
- 	connector->doublescan_allowed = false;
- 
--	drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
-+	drm_connector_init(dev, connector, funcs, type);
- 	drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
- 
--	/* attach encoders */
--	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
--		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
--
--		if (nv_encoder->dcb->connector != dcb->index)
--			continue;
--
--		if (get_slave_funcs(nv_encoder))
--			get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
-+	/* Check if we need dithering enabled */
-+	if (dcb->type == DCB_CONNECTOR_LVDS) {
-+		bool dummy, is_24bit = false;
- 
--		drm_mode_connector_attach_encoder(connector, encoder);
--	}
-+		ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit);
-+		if (ret) {
-+			NV_ERROR(dev, "Error parsing LVDS table, disabling "
-+				 "LVDS\n");
-+			goto fail;
-+		}
- 
--	if (!connector->encoder_ids[0]) {
--		NV_WARN(dev, "  no encoders, ignoring\n");
--		drm_connector_cleanup(connector);
--		kfree(connector);
--		return 0;
-+		nv_connector->use_dithering = !is_24bit;
- 	}
- 
- 	/* Init DVI-I specific properties */
-@@ -841,12 +814,8 @@ nouveau_connector_create(struct drm_device *dev,
- 		drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
- 	}
- 
--	if (dcb->type != DCB_CONNECTOR_LVDS)
--		nv_connector->use_dithering = false;
--
- 	switch (dcb->type) {
- 	case DCB_CONNECTOR_VGA:
--		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
- 		if (dev_priv->card_type >= NV_50) {
- 			drm_connector_attach_property(connector,
- 					dev->mode_config.scaling_mode_property,
-@@ -858,17 +827,6 @@ nouveau_connector_create(struct drm_device *dev,
- 	case DCB_CONNECTOR_TV_3:
- 		nv_connector->scaling_mode = DRM_MODE_SCALE_NONE;
- 		break;
--	case DCB_CONNECTOR_DP:
--	case DCB_CONNECTOR_eDP:
--	case DCB_CONNECTOR_HDMI_0:
--	case DCB_CONNECTOR_HDMI_1:
--	case DCB_CONNECTOR_DVI_I:
--	case DCB_CONNECTOR_DVI_D:
--		if (dev_priv->card_type >= NV_50)
--			connector->polled = DRM_CONNECTOR_POLL_HPD;
--		else
--			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
--		/* fall-through */
- 	default:
- 		nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN;
- 
-@@ -882,15 +840,15 @@ nouveau_connector_create(struct drm_device *dev,
- 		break;
- 	}
- 
-+	nouveau_connector_set_polling(connector);
-+
- 	drm_sysfs_connector_add(connector);
-+	dcb->drm = connector;
-+	return dcb->drm;
- 
--	if (dcb->type == DCB_CONNECTOR_LVDS) {
--		ret = nouveau_connector_create_lvds(dev, connector);
--		if (ret) {
--			connector->funcs->destroy(connector);
--			return ret;
--		}
--	}
-+fail:
-+	drm_connector_cleanup(connector);
-+	kfree(connector);
-+	return ERR_PTR(ret);
- 
--	return 0;
- }
-diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
-index 4ef38ab..0d2e668 100644
---- a/drivers/gpu/drm/nouveau/nouveau_connector.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
-@@ -49,7 +49,10 @@ static inline struct nouveau_connector *nouveau_connector(
- 	return container_of(con, struct nouveau_connector, base);
- }
- 
--int nouveau_connector_create(struct drm_device *,
--			     struct dcb_connector_table_entry *);
-+struct drm_connector *
-+nouveau_connector_create(struct drm_device *, int index);
-+
-+void
-+nouveau_connector_set_polling(struct drm_connector *);
- 
- #endif /* __NOUVEAU_CONNECTOR_H__ */
-diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
-index 65c441a..2e3c6ca 100644
---- a/drivers/gpu/drm/nouveau/nouveau_dma.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
-@@ -92,11 +92,9 @@ nouveau_dma_init(struct nouveau_channel *chan)
- 		return ret;
- 
- 	/* Map M2MF notifier object - fbcon. */
--	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
--		ret = nouveau_bo_map(chan->notifier_bo);
--		if (ret)
--			return ret;
--	}
-+	ret = nouveau_bo_map(chan->notifier_bo);
-+	if (ret)
-+		return ret;
- 
- 	/* Insert NOPS for NOUVEAU_DMA_SKIPS */
- 	ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
-index deeb21c..184bc95 100644
---- a/drivers/gpu/drm/nouveau/nouveau_dp.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
-@@ -271,12 +271,26 @@ nouveau_dp_link_train(struct drm_encoder *encoder)
- {
- 	struct drm_device *dev = encoder->dev;
- 	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
--	uint8_t config[4];
--	uint8_t status[3];
-+	struct bit_displayport_encoder_table *dpe;
-+	int dpe_headerlen;
-+	uint8_t config[4], status[3];
- 	bool cr_done, cr_max_vs, eq_done;
- 	int ret = 0, i, tries, voltage;
- 
- 	NV_DEBUG_KMS(dev, "link training!!\n");
-+
-+	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
-+	if (!dpe) {
-+		NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
-+		return false;
-+	}
-+
-+	if (dpe->script0) {
-+		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
-+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
-+					    nv_encoder->dcb);
-+	}
-+
- train:
- 	cr_done = eq_done = false;
- 
-@@ -403,6 +417,12 @@ stop:
- 		}
- 	}
- 
-+	if (dpe->script1) {
-+		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
-+		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
-+					    nv_encoder->dcb);
-+	}
-+
- 	return eq_done;
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
-index 2737704..203d0b6 100644
---- a/drivers/gpu/drm/nouveau/nouveau_drv.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
-@@ -35,10 +35,6 @@
- 
- #include "drm_pciids.h"
- 
--MODULE_PARM_DESC(ctxfw, "Use external firmware blob for grctx init (NV40)");
--int nouveau_ctxfw = 0;
--module_param_named(ctxfw, nouveau_ctxfw, int, 0400);
--
- MODULE_PARM_DESC(noagp, "Disable AGP");
- int nouveau_noagp;
- module_param_named(noagp, nouveau_noagp, int, 0400);
-@@ -56,7 +52,7 @@ int nouveau_vram_pushbuf;
- module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400);
- 
- MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM");
--int nouveau_vram_notify = 1;
-+int nouveau_vram_notify = 0;
- module_param_named(vram_notify, nouveau_vram_notify, int, 0400);
- 
- MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)");
-@@ -155,9 +151,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
- 	struct drm_crtc *crtc;
- 	int ret, i;
- 
--	if (!drm_core_check_feature(dev, DRIVER_MODESET))
--		return -ENODEV;
--
- 	if (pm_state.event == PM_EVENT_PRETHAW)
- 		return 0;
- 
-@@ -257,9 +250,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
- 	struct drm_crtc *crtc;
- 	int ret, i;
- 
--	if (!drm_core_check_feature(dev, DRIVER_MODESET))
--		return -ENODEV;
--
- 	nouveau_fbcon_save_disable_accel(dev);
- 
- 	NV_INFO(dev, "We're back, enabling device...\n");
-@@ -323,7 +313,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
- 
- 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- 		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
--		int ret;
- 
- 		ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
- 		if (!ret)
-@@ -332,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
- 			NV_ERROR(dev, "Could not pin/map cursor.\n");
- 	}
- 
--	if (dev_priv->card_type < NV_50) {
-+	if (dev_priv->card_type < NV_50)
- 		nv04_display_restore(dev);
--		NVLockVgaCrtcs(dev, false);
--	} else
-+	else
- 		nv50_display_init(dev);
- 
- 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-@@ -371,7 +359,8 @@ nouveau_pci_resume(struct pci_dev *pdev)
- static struct drm_driver driver = {
- 	.driver_features =
- 		DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
--		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
-+		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
-+		DRIVER_MODESET,
- 	.load = nouveau_load,
- 	.firstopen = nouveau_firstopen,
- 	.lastclose = nouveau_lastclose,
-@@ -438,16 +427,18 @@ static int __init nouveau_init(void)
- 			nouveau_modeset = 1;
- 	}
- 
--	if (nouveau_modeset == 1) {
--		driver.driver_features |= DRIVER_MODESET;
--		nouveau_register_dsm_handler();
--	}
-+	if (!nouveau_modeset)
-+		return 0;
- 
-+	nouveau_register_dsm_handler();
- 	return drm_init(&driver);
- }
- 
- static void __exit nouveau_exit(void)
- {
-+	if (!nouveau_modeset)
-+		return;
-+
- 	drm_exit(&driver);
- 	nouveau_unregister_dsm_handler();
- }
-diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
-index c697191..20ca5b8 100644
---- a/drivers/gpu/drm/nouveau/nouveau_drv.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
-@@ -123,14 +123,6 @@ nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
- 	return ioptr;
- }
- 
--struct mem_block {
--	struct mem_block *next;
--	struct mem_block *prev;
--	uint64_t start;
--	uint64_t size;
--	struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
--};
--
- enum nouveau_flags {
- 	NV_NFORCE   = 0x10000000,
- 	NV_NFORCE2  = 0x20000000
-@@ -149,7 +141,7 @@ struct nouveau_gpuobj {
- 	struct list_head list;
- 
- 	struct nouveau_channel *im_channel;
--	struct mem_block *im_pramin;
-+	struct drm_mm_node *im_pramin;
- 	struct nouveau_bo *im_backing;
- 	uint32_t im_backing_start;
- 	uint32_t *im_backing_suspend;
-@@ -196,7 +188,7 @@ struct nouveau_channel {
- 		struct list_head pending;
- 		uint32_t sequence;
- 		uint32_t sequence_ack;
--		uint32_t last_sequence_irq;
-+		atomic_t last_sequence_irq;
- 	} fence;
- 
- 	/* DMA push buffer */
-@@ -206,7 +198,7 @@ struct nouveau_channel {
- 
- 	/* Notifier memory */
- 	struct nouveau_bo *notifier_bo;
--	struct mem_block *notifier_heap;
-+	struct drm_mm notifier_heap;
- 
- 	/* PFIFO context */
- 	struct nouveau_gpuobj_ref *ramfc;
-@@ -224,7 +216,7 @@ struct nouveau_channel {
- 
- 	/* Objects */
- 	struct nouveau_gpuobj_ref *ramin; /* Private instmem */
--	struct mem_block          *ramin_heap; /* Private PRAMIN heap */
-+	struct drm_mm              ramin_heap; /* Private PRAMIN heap */
- 	struct nouveau_gpuobj_ref *ramht; /* Hash table */
- 	struct list_head           ramht_refs; /* Objects referenced by RAMHT */
- 
-@@ -277,8 +269,7 @@ struct nouveau_instmem_engine {
- 	void	(*clear)(struct drm_device *, struct nouveau_gpuobj *);
- 	int	(*bind)(struct drm_device *, struct nouveau_gpuobj *);
- 	int	(*unbind)(struct drm_device *, struct nouveau_gpuobj *);
--	void	(*prepare_access)(struct drm_device *, bool write);
--	void	(*finish_access)(struct drm_device *);
-+	void	(*flush)(struct drm_device *);
- };
- 
- struct nouveau_mc_engine {
-@@ -303,10 +294,11 @@ struct nouveau_fb_engine {
- };
- 
- struct nouveau_fifo_engine {
--	void *priv;
--
- 	int  channels;
- 
-+	struct nouveau_gpuobj_ref *playlist[2];
-+	int cur_playlist;
-+
- 	int  (*init)(struct drm_device *);
- 	void (*takedown)(struct drm_device *);
- 
-@@ -339,10 +331,11 @@ struct nouveau_pgraph_object_class {
- struct nouveau_pgraph_engine {
- 	struct nouveau_pgraph_object_class *grclass;
- 	bool accel_blocked;
--	void *ctxprog;
--	void *ctxvals;
- 	int grctx_size;
- 
-+	/* NV2x/NV3x context table (0x400780) */
-+	struct nouveau_gpuobj_ref *ctx_table;
-+
- 	int  (*init)(struct drm_device *);
- 	void (*takedown)(struct drm_device *);
- 
-@@ -500,11 +493,6 @@ enum nouveau_card_type {
- 
- struct drm_nouveau_private {
- 	struct drm_device *dev;
--	enum {
--		NOUVEAU_CARD_INIT_DOWN,
--		NOUVEAU_CARD_INIT_DONE,
--		NOUVEAU_CARD_INIT_FAILED
--	} init_state;
- 
- 	/* the card type, takes NV_* as values */
- 	enum nouveau_card_type card_type;
-@@ -533,8 +521,6 @@ struct drm_nouveau_private {
- 		atomic_t validate_sequence;
- 	} ttm;
- 
--	struct fb_info *fbdev_info;
--
- 	int fifo_alloc_count;
- 	struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
- 
-@@ -595,11 +581,7 @@ struct drm_nouveau_private {
- 	struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
- 	int vm_vram_pt_nr;
- 
--	struct mem_block *ramin_heap;
--
--	/* context table pointed to be NV_PGRAPH_CHANNEL_CTX_TABLE (0x400780) */
--	uint32_t ctx_table_size;
--	struct nouveau_gpuobj_ref *ctx_table;
-+	struct drm_mm ramin_heap;
- 
- 	struct list_head gpuobj_list;
- 
-@@ -618,6 +600,11 @@ struct drm_nouveau_private {
- 	struct backlight_device *backlight;
- 
- 	struct nouveau_channel *evo;
-+	struct {
-+		struct dcb_entry *dcb;
-+		u16 script;
-+		u32 pclk;
-+	} evo_irq;
- 
- 	struct {
- 		struct dentry *channel_root;
-@@ -652,14 +639,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
- 	return 0;
- }
- 
--#define NOUVEAU_CHECK_INITIALISED_WITH_RETURN do {            \
--	struct drm_nouveau_private *nv = dev->dev_private;    \
--	if (nv->init_state != NOUVEAU_CARD_INIT_DONE) {       \
--		NV_ERROR(dev, "called without init\n");       \
--		return -EINVAL;                               \
--	}                                                     \
--} while (0)
--
- #define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do {    \
- 	struct drm_nouveau_private *nv = dev->dev_private;       \
- 	if (!nouveau_channel_owner(dev, (cl), (id))) {           \
-@@ -682,7 +661,6 @@ extern int nouveau_tv_disable;
- extern char *nouveau_tv_norm;
- extern int nouveau_reg_debug;
- extern char *nouveau_vbios;
--extern int nouveau_ctxfw;
- extern int nouveau_ignorelid;
- extern int nouveau_nofbaccel;
- extern int nouveau_noaccel;
-@@ -707,15 +685,7 @@ extern bool nouveau_wait_for_idle(struct drm_device *);
- extern int  nouveau_card_init(struct drm_device *);
- 
- /* nouveau_mem.c */
--extern int  nouveau_mem_init_heap(struct mem_block **, uint64_t start,
--				 uint64_t size);
--extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
--						 uint64_t size, int align2,
--						 struct drm_file *, int tail);
--extern void nouveau_mem_takedown(struct mem_block **heap);
--extern void nouveau_mem_free_block(struct mem_block *);
- extern int  nouveau_mem_detect(struct drm_device *dev);
--extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
- extern int  nouveau_mem_init(struct drm_device *);
- extern int  nouveau_mem_init_agp(struct drm_device *);
- extern void nouveau_mem_close(struct drm_device *);
-@@ -857,11 +827,13 @@ void nouveau_register_dsm_handler(void);
- void nouveau_unregister_dsm_handler(void);
- int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
- bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
-+int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
- #else
- static inline void nouveau_register_dsm_handler(void) {}
- static inline void nouveau_unregister_dsm_handler(void) {}
- static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
- static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
-+static inline int nouveau_acpi_edid(struct drm_device *, struct drm_connector *) { return -EINVAL; }
- #endif
- 
- /* nouveau_backlight.c */
-@@ -1035,12 +1007,6 @@ extern int  nv50_graph_unload_context(struct drm_device *);
- extern void nv50_graph_context_switch(struct drm_device *);
- extern int  nv50_grctx_init(struct nouveau_grctx *);
- 
--/* nouveau_grctx.c */
--extern int  nouveau_grctx_prog_load(struct drm_device *);
--extern void nouveau_grctx_vals_load(struct drm_device *,
--				    struct nouveau_gpuobj *);
--extern void nouveau_grctx_fini(struct drm_device *);
--
- /* nv04_instmem.c */
- extern int  nv04_instmem_init(struct drm_device *);
- extern void nv04_instmem_takedown(struct drm_device *);
-@@ -1051,8 +1017,7 @@ extern int  nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
- extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
- extern int  nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
- extern int  nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
--extern void nv04_instmem_prepare_access(struct drm_device *, bool write);
--extern void nv04_instmem_finish_access(struct drm_device *);
-+extern void nv04_instmem_flush(struct drm_device *);
- 
- /* nv50_instmem.c */
- extern int  nv50_instmem_init(struct drm_device *);
-@@ -1064,8 +1029,9 @@ extern int  nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *,
- extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *);
- extern int  nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *);
- extern int  nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *);
--extern void nv50_instmem_prepare_access(struct drm_device *, bool write);
--extern void nv50_instmem_finish_access(struct drm_device *);
-+extern void nv50_instmem_flush(struct drm_device *);
-+extern void nv84_instmem_flush(struct drm_device *);
-+extern void nv50_vm_flush(struct drm_device *, int engine);
- 
- /* nv04_mc.c */
- extern int  nv04_mc_init(struct drm_device *);
-@@ -1088,13 +1054,14 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
- 				 unsigned long arg);
- 
- /* nv04_dac.c */
--extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry);
-+extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *);
- extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
- extern int nv04_dac_output_offset(struct drm_encoder *encoder);
- extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
-+extern bool nv04_dac_in_use(struct drm_encoder *encoder);
- 
- /* nv04_dfp.c */
--extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry);
-+extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *);
- extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
- extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
- 			       int head, bool dl);
-@@ -1103,10 +1070,10 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
- 
- /* nv04_tv.c */
- extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
--extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry);
-+extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
- 
- /* nv17_tv.c */
--extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry);
-+extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
- 
- /* nv04_display.c */
- extern int nv04_display_create(struct drm_device *);
-@@ -1147,7 +1114,6 @@ extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
- extern int nouveau_fence_flush(void *obj, void *arg);
- extern void nouveau_fence_unref(void **obj);
- extern void *nouveau_fence_ref(void *obj);
--extern void nouveau_fence_handler(struct drm_device *dev, int channel);
- 
- /* nouveau_gem.c */
- extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *,
-diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
-index e1df820..a1a0d48 100644
---- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
-@@ -38,13 +38,15 @@ struct nouveau_encoder {
- 	struct dcb_entry *dcb;
- 	int or;
- 
-+	/* different to drm_encoder.crtc, this reflects what's
-+	 * actually programmed on the hw, not the proposed crtc */
-+	struct drm_crtc *crtc;
-+
- 	struct drm_display_mode mode;
- 	int last_dpms;
- 
- 	struct nv04_output_reg restore;
- 
--	void (*disconnect)(struct nouveau_encoder *encoder);
--
- 	union {
- 		struct {
- 			int mc_unknown;
-@@ -71,8 +73,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
- 
- struct nouveau_connector *
- nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
--int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry);
--int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry);
-+int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
-+int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
- 
- struct bit_displayport_encoder_table {
- 	uint32_t match;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-index 257ea13..2fb2444 100644
---- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
-@@ -333,7 +333,7 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev)
- 	drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
- }
- 
--int
-+static int
- nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
- {
- 	struct nouveau_framebuffer *nouveau_fb = &nfbdev->nouveau_fb;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
-index faddf53..813d853 100644
---- a/drivers/gpu/drm/nouveau/nouveau_fence.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
-@@ -67,12 +67,13 @@ nouveau_fence_update(struct nouveau_channel *chan)
- 	if (USE_REFCNT)
- 		sequence = nvchan_rd32(chan, 0x48);
- 	else
--		sequence = chan->fence.last_sequence_irq;
-+		sequence = atomic_read(&chan->fence.last_sequence_irq);
- 
- 	if (chan->fence.sequence_ack == sequence)
- 		return;
- 	chan->fence.sequence_ack = sequence;
- 
-+	spin_lock(&chan->fence.lock);
- 	list_for_each_safe(entry, tmp, &chan->fence.pending) {
- 		fence = list_entry(entry, struct nouveau_fence, entry);
- 
-@@ -84,6 +85,7 @@ nouveau_fence_update(struct nouveau_channel *chan)
- 		if (sequence == chan->fence.sequence_ack)
- 			break;
- 	}
-+	spin_unlock(&chan->fence.lock);
- }
- 
- int
-@@ -119,7 +121,6 @@ nouveau_fence_emit(struct nouveau_fence *fence)
- {
- 	struct drm_nouveau_private *dev_priv = fence->channel->dev->dev_private;
- 	struct nouveau_channel *chan = fence->channel;
--	unsigned long flags;
- 	int ret;
- 
- 	ret = RING_SPACE(chan, 2);
-@@ -127,9 +128,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
- 		return ret;
- 
- 	if (unlikely(chan->fence.sequence == chan->fence.sequence_ack - 1)) {
--		spin_lock_irqsave(&chan->fence.lock, flags);
- 		nouveau_fence_update(chan);
--		spin_unlock_irqrestore(&chan->fence.lock, flags);
- 
- 		BUG_ON(chan->fence.sequence ==
- 		       chan->fence.sequence_ack - 1);
-@@ -138,9 +137,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
- 	fence->sequence = ++chan->fence.sequence;
- 
- 	kref_get(&fence->refcount);
--	spin_lock_irqsave(&chan->fence.lock, flags);
-+	spin_lock(&chan->fence.lock);
- 	list_add_tail(&fence->entry, &chan->fence.pending);
--	spin_unlock_irqrestore(&chan->fence.lock, flags);
-+	spin_unlock(&chan->fence.lock);
- 
- 	BEGIN_RING(chan, NvSubSw, USE_REFCNT ? 0x0050 : 0x0150, 1);
- 	OUT_RING(chan, fence->sequence);
-@@ -173,14 +172,11 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg)
- {
- 	struct nouveau_fence *fence = nouveau_fence(sync_obj);
- 	struct nouveau_channel *chan = fence->channel;
--	unsigned long flags;
- 
- 	if (fence->signalled)
- 		return true;
- 
--	spin_lock_irqsave(&chan->fence.lock, flags);
- 	nouveau_fence_update(chan);
--	spin_unlock_irqrestore(&chan->fence.lock, flags);
- 	return fence->signalled;
- }
- 
-@@ -221,27 +217,12 @@ nouveau_fence_flush(void *sync_obj, void *sync_arg)
- 	return 0;
- }
- 
--void
--nouveau_fence_handler(struct drm_device *dev, int channel)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nouveau_channel *chan = NULL;
--
--	if (channel >= 0 && channel < dev_priv->engine.fifo.channels)
--		chan = dev_priv->fifos[channel];
--
--	if (chan) {
--		spin_lock_irq(&chan->fence.lock);
--		nouveau_fence_update(chan);
--		spin_unlock_irq(&chan->fence.lock);
--	}
--}
--
- int
- nouveau_fence_init(struct nouveau_channel *chan)
- {
- 	INIT_LIST_HEAD(&chan->fence.pending);
- 	spin_lock_init(&chan->fence.lock);
-+	atomic_set(&chan->fence.last_sequence_irq, 0);
- 	return 0;
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
-index 69c76cf..547f2c2 100644
---- a/drivers/gpu/drm/nouveau/nouveau_gem.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
-@@ -137,8 +137,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
- 	uint32_t flags = 0;
- 	int ret = 0;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL))
- 		dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping;
- 
-@@ -577,10 +575,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
- 	struct drm_nouveau_gem_pushbuf_bo *bo;
- 	struct nouveau_channel *chan;
- 	struct validate_op op;
--	struct nouveau_fence *fence = 0;
-+	struct nouveau_fence *fence = NULL;
- 	int i, j, ret = 0, do_reloc = 0;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
- 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan);
- 
- 	req->vram_available = dev_priv->fb_aper_free;
-@@ -760,8 +757,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
- 	bool no_wait = !!(req->flags & NOUVEAU_GEM_CPU_PREP_NOWAIT);
- 	int ret = -EINVAL;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
- 	if (!gem)
- 		return ret;
-@@ -800,8 +795,6 @@ nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
- 	struct nouveau_bo *nvbo;
- 	int ret = -EINVAL;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
- 	if (!gem)
- 		return ret;
-@@ -827,8 +820,6 @@ nouveau_gem_ioctl_info(struct drm_device *dev, void *data,
- 	struct drm_gem_object *gem;
- 	int ret;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	gem = drm_gem_object_lookup(dev, file_priv, req->handle);
- 	if (!gem)
- 		return -EINVAL;
-diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c
-deleted file mode 100644
-index f731c5f..0000000
---- a/drivers/gpu/drm/nouveau/nouveau_grctx.c
-+++ /dev/null
-@@ -1,160 +0,0 @@
--/*
-- * Copyright 2009 Red Hat Inc.
-- *
-- * Permission is hereby granted, free of charge, to any person obtaining a
-- * copy of this software and associated documentation files (the "Software"),
-- * to deal in the Software without restriction, including without limitation
-- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- * and/or sell copies of the Software, and to permit persons to whom the
-- * Software is furnished to do so, subject to the following conditions:
-- *
-- * The above copyright notice and this permission notice shall be included in
-- * all copies or substantial portions of the Software.
-- *
-- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
-- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-- * OTHER DEALINGS IN THE SOFTWARE.
-- *
-- * Authors: Ben Skeggs
-- */
--
--#include <linux/firmware.h>
--#include <linux/slab.h>
--
--#include "drmP.h"
--#include "nouveau_drv.h"
--
--struct nouveau_ctxprog {
--	uint32_t signature;
--	uint8_t  version;
--	uint16_t length;
--	uint32_t data[];
--} __attribute__ ((packed));
--
--struct nouveau_ctxvals {
--	uint32_t signature;
--	uint8_t  version;
--	uint32_t length;
--	struct {
--		uint32_t offset;
--		uint32_t value;
--	} data[];
--} __attribute__ ((packed));
--
--int
--nouveau_grctx_prog_load(struct drm_device *dev)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
--	const int chipset = dev_priv->chipset;
--	const struct firmware *fw;
--	const struct nouveau_ctxprog *cp;
--	const struct nouveau_ctxvals *cv;
--	char name[32];
--	int ret, i;
--
--	if (pgraph->accel_blocked)
--		return -ENODEV;
--
--	if (!pgraph->ctxprog) {
--		sprintf(name, "nouveau/nv%02x.ctxprog", chipset);
--		ret = request_firmware(&fw, name, &dev->pdev->dev);
--		if (ret) {
--			NV_ERROR(dev, "No ctxprog for NV%02x\n", chipset);
--			return ret;
--		}
--
--		pgraph->ctxprog = kmemdup(fw->data, fw->size, GFP_KERNEL);
--		if (!pgraph->ctxprog) {
--			NV_ERROR(dev, "OOM copying ctxprog\n");
--			release_firmware(fw);
--			return -ENOMEM;
--		}
--
--		cp = pgraph->ctxprog;
--		if (le32_to_cpu(cp->signature) != 0x5043564e ||
--		    cp->version != 0 ||
--		    le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
--			NV_ERROR(dev, "ctxprog invalid\n");
--			release_firmware(fw);
--			nouveau_grctx_fini(dev);
--			return -EINVAL;
--		}
--		release_firmware(fw);
--	}
--
--	if (!pgraph->ctxvals) {
--		sprintf(name, "nouveau/nv%02x.ctxvals", chipset);
--		ret = request_firmware(&fw, name, &dev->pdev->dev);
--		if (ret) {
--			NV_ERROR(dev, "No ctxvals for NV%02x\n", chipset);
--			nouveau_grctx_fini(dev);
--			return ret;
--		}
--
--		pgraph->ctxvals = kmemdup(fw->data, fw->size, GFP_KERNEL);
--		if (!pgraph->ctxvals) {
--			NV_ERROR(dev, "OOM copying ctxvals\n");
--			release_firmware(fw);
--			nouveau_grctx_fini(dev);
--			return -ENOMEM;
--		}
--
--		cv = (void *)pgraph->ctxvals;
--		if (le32_to_cpu(cv->signature) != 0x5643564e ||
--		    cv->version != 0 ||
--		    le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
--			NV_ERROR(dev, "ctxvals invalid\n");
--			release_firmware(fw);
--			nouveau_grctx_fini(dev);
--			return -EINVAL;
--		}
--		release_firmware(fw);
--	}
--
--	cp = pgraph->ctxprog;
--
--	nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
--	for (i = 0; i < le16_to_cpu(cp->length); i++)
--		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
--			le32_to_cpu(cp->data[i]));
--
--	return 0;
--}
--
--void
--nouveau_grctx_fini(struct drm_device *dev)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
--
--	if (pgraph->ctxprog) {
--		kfree(pgraph->ctxprog);
--		pgraph->ctxprog = NULL;
--	}
--
--	if (pgraph->ctxvals) {
--		kfree(pgraph->ctxprog);
--		pgraph->ctxvals = NULL;
--	}
--}
--
--void
--nouveau_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
--	struct nouveau_ctxvals *cv = pgraph->ctxvals;
--	int i;
--
--	if (!cv)
--		return;
--
--	for (i = 0; i < le32_to_cpu(cv->length); i++)
--		nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
--			le32_to_cpu(cv->data[i].value));
--}
-diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
-index 316a3c7..97ba89e 100644
---- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
-@@ -278,3 +278,37 @@ nouveau_i2c_find(struct drm_device *dev, int index)
- 	return i2c->chan;
- }
- 
-+bool
-+nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
-+{
-+	struct i2c_msg msg = {
-+		.addr = addr,
-+		.len = 0,
-+	};
-+
-+	return i2c_transfer(&i2c->adapter, &msg, 1) == 1;
-+}
-+
-+int
-+nouveau_i2c_identify(struct drm_device *dev, const char *what,
-+		     struct i2c_board_info *info, int index)
-+{
-+	struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
-+	int was_locked, i;
-+
-+	was_locked = NVLockVgaCrtcs(dev, false);
-+	NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
-+
-+	for (i = 0; info[i].addr; i++) {
-+		if (nouveau_probe_i2c_addr(i2c, info[i].addr)) {
-+			NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
-+			goto out;
-+		}
-+	}
-+
-+	NV_DEBUG(dev, "No devices found.\n");
-+out:
-+	NVLockVgaCrtcs(dev, was_locked);
-+
-+	return info[i].addr ? i : -ENODEV;
-+}
-diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h
-index c8eaf7a..6dd2f87 100644
---- a/drivers/gpu/drm/nouveau/nouveau_i2c.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h
-@@ -45,6 +45,9 @@ struct nouveau_i2c_chan {
- int nouveau_i2c_init(struct drm_device *, struct dcb_i2c_entry *, int index);
- void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
- struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
-+bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
-+int nouveau_i2c_identify(struct drm_device *dev, const char *what,
-+			 struct i2c_board_info *info, int index);
- 
- int nouveau_dp_i2c_aux_ch(struct i2c_adapter *, int mode, uint8_t write_byte,
- 			  uint8_t *read_byte);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
-index c1fd42b..adf5ac4 100644
---- a/drivers/gpu/drm/nouveau/nouveau_mem.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
-@@ -35,162 +35,6 @@
- #include "drm_sarea.h"
- #include "nouveau_drv.h"
- 
--static struct mem_block *
--split_block(struct mem_block *p, uint64_t start, uint64_t size,
--	    struct drm_file *file_priv)
--{
--	/* Maybe cut off the start of an existing block */
--	if (start > p->start) {
--		struct mem_block *newblock =
--			kmalloc(sizeof(*newblock), GFP_KERNEL);
--		if (!newblock)
--			goto out;
--		newblock->start = start;
--		newblock->size = p->size - (start - p->start);
--		newblock->file_priv = NULL;
--		newblock->next = p->next;
--		newblock->prev = p;
--		p->next->prev = newblock;
--		p->next = newblock;
--		p->size -= newblock->size;
--		p = newblock;
--	}
--
--	/* Maybe cut off the end of an existing block */
--	if (size < p->size) {
--		struct mem_block *newblock =
--			kmalloc(sizeof(*newblock), GFP_KERNEL);
--		if (!newblock)
--			goto out;
--		newblock->start = start + size;
--		newblock->size = p->size - size;
--		newblock->file_priv = NULL;
--		newblock->next = p->next;
--		newblock->prev = p;
--		p->next->prev = newblock;
--		p->next = newblock;
--		p->size = size;
--	}
--
--out:
--	/* Our block is in the middle */
--	p->file_priv = file_priv;
--	return p;
--}
--
--struct mem_block *
--nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size,
--			int align2, struct drm_file *file_priv, int tail)
--{
--	struct mem_block *p;
--	uint64_t mask = (1 << align2) - 1;
--
--	if (!heap)
--		return NULL;
--
--	if (tail) {
--		list_for_each_prev(p, heap) {
--			uint64_t start = ((p->start + p->size) - size) & ~mask;
--
--			if (p->file_priv == NULL && start >= p->start &&
--			    start + size <= p->start + p->size)
--				return split_block(p, start, size, file_priv);
--		}
--	} else {
--		list_for_each(p, heap) {
--			uint64_t start = (p->start + mask) & ~mask;
--
--			if (p->file_priv == NULL &&
--			    start + size <= p->start + p->size)
--				return split_block(p, start, size, file_priv);
--		}
--	}
--
--	return NULL;
--}
--
--void nouveau_mem_free_block(struct mem_block *p)
--{
--	p->file_priv = NULL;
--
--	/* Assumes a single contiguous range.  Needs a special file_priv in
--	 * 'heap' to stop it being subsumed.
--	 */
--	if (p->next->file_priv == NULL) {
--		struct mem_block *q = p->next;
--		p->size += q->size;
--		p->next = q->next;
--		p->next->prev = p;
--		kfree(q);
--	}
--
--	if (p->prev->file_priv == NULL) {
--		struct mem_block *q = p->prev;
--		q->size += p->size;
--		q->next = p->next;
--		q->next->prev = q;
--		kfree(p);
--	}
--}
--
--/* Initialize.  How to check for an uninitialized heap?
-- */
--int nouveau_mem_init_heap(struct mem_block **heap, uint64_t start,
--			  uint64_t size)
--{
--	struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL);
--
--	if (!blocks)
--		return -ENOMEM;
--
--	*heap = kmalloc(sizeof(**heap), GFP_KERNEL);
--	if (!*heap) {
--		kfree(blocks);
--		return -ENOMEM;
--	}
--
--	blocks->start = start;
--	blocks->size = size;
--	blocks->file_priv = NULL;
--	blocks->next = blocks->prev = *heap;
--
--	memset(*heap, 0, sizeof(**heap));
--	(*heap)->file_priv = (struct drm_file *) -1;
--	(*heap)->next = (*heap)->prev = blocks;
--	return 0;
--}
--
--/*
-- * Free all blocks associated with the releasing file_priv
-- */
--void nouveau_mem_release(struct drm_file *file_priv, struct mem_block *heap)
--{
--	struct mem_block *p;
--
--	if (!heap || !heap->next)
--		return;
--
--	list_for_each(p, heap) {
--		if (p->file_priv == file_priv)
--			p->file_priv = NULL;
--	}
--
--	/* Assumes a single contiguous range.  Needs a special file_priv in
--	 * 'heap' to stop it being subsumed.
--	 */
--	list_for_each(p, heap) {
--		while ((p->file_priv == NULL) &&
--					(p->next->file_priv == NULL) &&
--					(p->next != heap)) {
--			struct mem_block *q = p->next;
--			p->size += q->size;
--			p->next = q->next;
--			p->next->prev = p;
--			kfree(q);
--		}
--	}
--}
--
- /*
-  * NV10-NV40 tiling helpers
-  */
-@@ -299,7 +143,6 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
- 		phys |= 0x30;
- 	}
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	while (size) {
- 		unsigned offset_h = upper_32_bits(phys);
- 		unsigned offset_l = lower_32_bits(phys);
-@@ -331,36 +174,12 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
- 			}
- 		}
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
--
--	nv_wr32(dev, 0x100c80, 0x00050001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return -EBUSY;
--	}
--
--	nv_wr32(dev, 0x100c80, 0x00000001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return -EBUSY;
--	}
--
--	nv_wr32(dev, 0x100c80, 0x00040001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return -EBUSY;
--	}
--
--	nv_wr32(dev, 0x100c80, 0x00060001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return -EBUSY;
--	}
-+	dev_priv->engine.instmem.flush(dev);
- 
-+	nv50_vm_flush(dev, 5);
-+	nv50_vm_flush(dev, 0);
-+	nv50_vm_flush(dev, 4);
-+	nv50_vm_flush(dev, 6);
- 	return 0;
- }
- 
-@@ -374,7 +193,6 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
- 	virt -= dev_priv->vm_vram_base;
- 	pages = (size >> 16) << 1;
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	while (pages) {
- 		pgt = dev_priv->vm_vram_pt[virt >> 29];
- 		pte = (virt & 0x1ffe0000ULL) >> 15;
-@@ -388,57 +206,19 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
- 		while (pte < end)
- 			nv_wo32(dev, pgt, pte++, 0);
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
--
--	nv_wr32(dev, 0x100c80, 0x00050001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return;
--	}
--
--	nv_wr32(dev, 0x100c80, 0x00000001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return;
--	}
--
--	nv_wr32(dev, 0x100c80, 0x00040001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return;
--	}
-+	dev_priv->engine.instmem.flush(dev);
- 
--	nv_wr32(dev, 0x100c80, 0x00060001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--	}
-+	nv50_vm_flush(dev, 5);
-+	nv50_vm_flush(dev, 0);
-+	nv50_vm_flush(dev, 4);
-+	nv50_vm_flush(dev, 6);
- }
- 
- /*
-  * Cleanup everything
-  */
--void nouveau_mem_takedown(struct mem_block **heap)
--{
--	struct mem_block *p;
--
--	if (!*heap)
--		return;
--
--	for (p = (*heap)->next; p != *heap;) {
--		struct mem_block *q = p;
--		p = p->next;
--		kfree(q);
--	}
--
--	kfree(*heap);
--	*heap = NULL;
--}
--
--void nouveau_mem_close(struct drm_device *dev)
-+void
-+nouveau_mem_close(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 
-@@ -449,8 +229,7 @@ void nouveau_mem_close(struct drm_device *dev)
- 
- 	nouveau_ttm_global_release(dev_priv);
- 
--	if (drm_core_has_AGP(dev) && dev->agp &&
--	    drm_core_check_feature(dev, DRIVER_MODESET)) {
-+	if (drm_core_has_AGP(dev) && dev->agp) {
- 		struct drm_agp_mem *entry, *tempe;
- 
- 		/* Remove AGP resources, but leave dev->agp
-@@ -470,29 +249,29 @@ void nouveau_mem_close(struct drm_device *dev)
- 		dev->agp->enabled = 0;
- 	}
- 
--	if (dev_priv->fb_mtrr) {
-+	if (dev_priv->fb_mtrr >= 0) {
- 		drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),
- 			     drm_get_resource_len(dev, 1), DRM_MTRR_WC);
--		dev_priv->fb_mtrr = 0;
-+		dev_priv->fb_mtrr = -1;
- 	}
- }
- 
- static uint32_t
- nouveau_mem_detect_nv04(struct drm_device *dev)
- {
--	uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
-+	uint32_t boot0 = nv_rd32(dev, NV04_PFB_BOOT_0);
- 
- 	if (boot0 & 0x00000100)
- 		return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
- 
--	switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
--	case NV04_BOOT_0_RAM_AMOUNT_32MB:
-+	switch (boot0 & NV04_PFB_BOOT_0_RAM_AMOUNT) {
-+	case NV04_PFB_BOOT_0_RAM_AMOUNT_32MB:
- 		return 32 * 1024 * 1024;
--	case NV04_BOOT_0_RAM_AMOUNT_16MB:
-+	case NV04_PFB_BOOT_0_RAM_AMOUNT_16MB:
- 		return 16 * 1024 * 1024;
--	case NV04_BOOT_0_RAM_AMOUNT_8MB:
-+	case NV04_PFB_BOOT_0_RAM_AMOUNT_8MB:
- 		return 8 * 1024 * 1024;
--	case NV04_BOOT_0_RAM_AMOUNT_4MB:
-+	case NV04_PFB_BOOT_0_RAM_AMOUNT_4MB:
- 		return 4 * 1024 * 1024;
- 	}
- 
-@@ -536,12 +315,18 @@ nouveau_mem_detect(struct drm_device *dev)
- 	} else
- 	if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
- 		dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
-+	} else
-+	if (dev_priv->card_type < NV_50) {
-+		dev_priv->vram_size  = nv_rd32(dev, NV04_PFB_FIFO_DATA);
-+		dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK;
- 	} else {
--		dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
--		dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
--		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
-+		dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA);
-+		dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32;
-+		dev_priv->vram_size &= 0xffffffff00ll;
-+		if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) {
- 			dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10);
- 			dev_priv->vram_sys_base <<= 12;
-+		}
- 	}
- 
- 	NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
-diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c
-index 9537f3e..3ec181f 100644
---- a/drivers/gpu/drm/nouveau/nouveau_notifier.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c
-@@ -55,7 +55,7 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan)
- 	if (ret)
- 		goto out_err;
- 
--	ret = nouveau_mem_init_heap(&chan->notifier_heap, 0, ntfy->bo.mem.size);
-+	ret = drm_mm_init(&chan->notifier_heap, 0, ntfy->bo.mem.size);
- 	if (ret)
- 		goto out_err;
- 
-@@ -80,7 +80,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan)
- 	nouveau_bo_unpin(chan->notifier_bo);
- 	mutex_unlock(&dev->struct_mutex);
- 	drm_gem_object_unreference_unlocked(chan->notifier_bo->gem);
--	nouveau_mem_takedown(&chan->notifier_heap);
-+	drm_mm_takedown(&chan->notifier_heap);
- }
- 
- static void
-@@ -90,7 +90,7 @@ nouveau_notifier_gpuobj_dtor(struct drm_device *dev,
- 	NV_DEBUG(dev, "\n");
- 
- 	if (gpuobj->priv)
--		nouveau_mem_free_block(gpuobj->priv);
-+		drm_mm_put_block(gpuobj->priv);
- }
- 
- int
-@@ -100,18 +100,13 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
- 	struct drm_device *dev = chan->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_gpuobj *nobj = NULL;
--	struct mem_block *mem;
-+	struct drm_mm_node *mem;
- 	uint32_t offset;
- 	int target, ret;
- 
--	if (!chan->notifier_heap) {
--		NV_ERROR(dev, "Channel %d doesn't have a notifier heap!\n",
--			 chan->id);
--		return -EINVAL;
--	}
--
--	mem = nouveau_mem_alloc_block(chan->notifier_heap, size, 0,
--				      (struct drm_file *)-2, 0);
-+	mem = drm_mm_search_free(&chan->notifier_heap, size, 0, 0);
-+	if (mem)
-+		mem = drm_mm_get_block(mem, size, 0);
- 	if (!mem) {
- 		NV_ERROR(dev, "Channel %d notifier block full\n", chan->id);
- 		return -ENOMEM;
-@@ -144,17 +139,17 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle,
- 				     mem->size, NV_DMA_ACCESS_RW, target,
- 				     &nobj);
- 	if (ret) {
--		nouveau_mem_free_block(mem);
-+		drm_mm_put_block(mem);
- 		NV_ERROR(dev, "Error creating notifier ctxdma: %d\n", ret);
- 		return ret;
- 	}
--	nobj->dtor   = nouveau_notifier_gpuobj_dtor;
--	nobj->priv   = mem;
-+	nobj->dtor = nouveau_notifier_gpuobj_dtor;
-+	nobj->priv = mem;
- 
- 	ret = nouveau_gpuobj_ref_add(dev, chan, handle, nobj, NULL);
- 	if (ret) {
- 		nouveau_gpuobj_del(dev, &nobj);
--		nouveau_mem_free_block(mem);
-+		drm_mm_put_block(mem);
- 		NV_ERROR(dev, "Error referencing notifier ctxdma: %d\n", ret);
- 		return ret;
- 	}
-@@ -170,7 +165,7 @@ nouveau_notifier_offset(struct nouveau_gpuobj *nobj, uint32_t *poffset)
- 		return -EINVAL;
- 
- 	if (poffset) {
--		struct mem_block *mem = nobj->priv;
-+		struct drm_mm_node *mem = nobj->priv;
- 
- 		if (*poffset >= mem->size)
- 			return false;
-@@ -189,7 +184,6 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data,
- 	struct nouveau_channel *chan;
- 	int ret;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
- 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan);
- 
- 	ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
-index e7c100b..4bf6b33 100644
---- a/drivers/gpu/drm/nouveau/nouveau_object.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
-@@ -132,7 +132,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
- 		}
- 	}
- 
--	instmem->prepare_access(dev, true);
- 	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
- 	do {
- 		if (!nouveau_ramht_entry_valid(dev, ramht, co)) {
-@@ -143,7 +142,7 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
- 			nv_wo32(dev, ramht, (co + 4)/4, ctx);
- 
- 			list_add_tail(&ref->list, &chan->ramht_refs);
--			instmem->finish_access(dev);
-+			instmem->flush(dev);
- 			return 0;
- 		}
- 		NV_DEBUG(dev, "collision ch%d 0x%08x: h=0x%08x\n",
-@@ -153,7 +152,6 @@ nouveau_ramht_insert(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
- 		if (co >= dev_priv->ramht_size)
- 			co = 0;
- 	} while (co != ho);
--	instmem->finish_access(dev);
- 
- 	NV_ERROR(dev, "RAMHT space exhausted. ch=%d\n", chan->id);
- 	return -ENOMEM;
-@@ -173,7 +171,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
- 		return;
- 	}
- 
--	instmem->prepare_access(dev, true);
- 	co = ho = nouveau_ramht_hash_handle(dev, chan->id, ref->handle);
- 	do {
- 		if (nouveau_ramht_entry_valid(dev, ramht, co) &&
-@@ -186,7 +183,7 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
- 			nv_wo32(dev, ramht, (co + 4)/4, 0x00000000);
- 
- 			list_del(&ref->list);
--			instmem->finish_access(dev);
-+			instmem->flush(dev);
- 			return;
- 		}
- 
-@@ -195,7 +192,6 @@ nouveau_ramht_remove(struct drm_device *dev, struct nouveau_gpuobj_ref *ref)
- 			co = 0;
- 	} while (co != ho);
- 	list_del(&ref->list);
--	instmem->finish_access(dev);
- 
- 	NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n",
- 		 chan->id, ref->handle);
-@@ -209,7 +205,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_engine *engine = &dev_priv->engine;
- 	struct nouveau_gpuobj *gpuobj;
--	struct mem_block *pramin = NULL;
-+	struct drm_mm *pramin = NULL;
- 	int ret;
- 
- 	NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
-@@ -233,25 +229,12 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
- 	 * available.
- 	 */
- 	if (chan) {
--		if (chan->ramin_heap) {
--			NV_DEBUG(dev, "private heap\n");
--			pramin = chan->ramin_heap;
--		} else
--		if (dev_priv->card_type < NV_50) {
--			NV_DEBUG(dev, "global heap fallback\n");
--			pramin = dev_priv->ramin_heap;
--		}
-+		NV_DEBUG(dev, "channel heap\n");
-+		pramin = &chan->ramin_heap;
- 	} else {
- 		NV_DEBUG(dev, "global heap\n");
--		pramin = dev_priv->ramin_heap;
--	}
--
--	if (!pramin) {
--		NV_ERROR(dev, "No PRAMIN heap!\n");
--		return -EINVAL;
--	}
-+		pramin = &dev_priv->ramin_heap;
- 
--	if (!chan) {
- 		ret = engine->instmem.populate(dev, gpuobj, &size);
- 		if (ret) {
- 			nouveau_gpuobj_del(dev, &gpuobj);
-@@ -260,9 +243,10 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
- 	}
- 
- 	/* Allocate a chunk of the PRAMIN aperture */
--	gpuobj->im_pramin = nouveau_mem_alloc_block(pramin, size,
--						    drm_order(align),
--						    (struct drm_file *)-2, 0);
-+	gpuobj->im_pramin = drm_mm_search_free(pramin, size, align, 0);
-+	if (gpuobj->im_pramin)
-+		gpuobj->im_pramin = drm_mm_get_block(gpuobj->im_pramin, size, align);
-+
- 	if (!gpuobj->im_pramin) {
- 		nouveau_gpuobj_del(dev, &gpuobj);
- 		return -ENOMEM;
-@@ -279,10 +263,9 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
- 	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
- 		int i;
- 
--		engine->instmem.prepare_access(dev, true);
- 		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
- 			nv_wo32(dev, gpuobj, i/4, 0);
--		engine->instmem.finish_access(dev);
-+		engine->instmem.flush(dev);
- 	}
- 
- 	*gpuobj_ret = gpuobj;
-@@ -370,10 +353,9 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
- 	}
- 
- 	if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
--		engine->instmem.prepare_access(dev, true);
- 		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
- 			nv_wo32(dev, gpuobj, i/4, 0);
--		engine->instmem.finish_access(dev);
-+		engine->instmem.flush(dev);
- 	}
- 
- 	if (gpuobj->dtor)
-@@ -386,7 +368,7 @@ nouveau_gpuobj_del(struct drm_device *dev, struct nouveau_gpuobj **pgpuobj)
- 		if (gpuobj->flags & NVOBJ_FLAG_FAKE)
- 			kfree(gpuobj->im_pramin);
- 		else
--			nouveau_mem_free_block(gpuobj->im_pramin);
-+			drm_mm_put_block(gpuobj->im_pramin);
- 	}
- 
- 	list_del(&gpuobj->list);
-@@ -589,7 +571,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
- 	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
- 
- 	if (p_offset != ~0) {
--		gpuobj->im_pramin = kzalloc(sizeof(struct mem_block),
-+		gpuobj->im_pramin = kzalloc(sizeof(struct drm_mm_node),
- 					    GFP_KERNEL);
- 		if (!gpuobj->im_pramin) {
- 			nouveau_gpuobj_del(dev, &gpuobj);
-@@ -605,10 +587,9 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, uint32_t p_offset,
- 	}
- 
- 	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
--		dev_priv->engine.instmem.prepare_access(dev, true);
- 		for (i = 0; i < gpuobj->im_pramin->size; i += 4)
- 			nv_wo32(dev, gpuobj, i/4, 0);
--		dev_priv->engine.instmem.finish_access(dev);
-+		dev_priv->engine.instmem.flush(dev);
- 	}
- 
- 	if (pref) {
-@@ -696,8 +677,6 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
- 		return ret;
- 	}
- 
--	instmem->prepare_access(dev, true);
--
- 	if (dev_priv->card_type < NV_50) {
- 		uint32_t frame, adjust, pte_flags = 0;
- 
-@@ -734,7 +713,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
- 		nv_wo32(dev, *gpuobj, 5, flags5);
- 	}
- 
--	instmem->finish_access(dev);
-+	instmem->flush(dev);
- 
- 	(*gpuobj)->engine = NVOBJ_ENGINE_SW;
- 	(*gpuobj)->class  = class;
-@@ -849,7 +828,6 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
- 		return ret;
- 	}
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	if (dev_priv->card_type >= NV_50) {
- 		nv_wo32(dev, *gpuobj, 0, class);
- 		nv_wo32(dev, *gpuobj, 5, 0x00010000);
-@@ -874,7 +852,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
- 			}
- 		}
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	(*gpuobj)->engine = NVOBJ_ENGINE_GR;
- 	(*gpuobj)->class  = class;
-@@ -920,6 +898,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
- 	base = 0;
- 
- 	/* PGRAPH context */
-+	size += dev_priv->engine.graph.grctx_size;
- 
- 	if (dev_priv->card_type == NV_50) {
- 		/* Various fixed table thingos */
-@@ -930,12 +909,8 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
- 		size += 0x8000;
- 		/* RAMFC */
- 		size += 0x1000;
--		/* PGRAPH context */
--		size += 0x70000;
- 	}
- 
--	NV_DEBUG(dev, "ch%d PRAMIN size: 0x%08x bytes, base alloc=0x%08x\n",
--		 chan->id, size, base);
- 	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, size, 0x1000, 0,
- 				     &chan->ramin);
- 	if (ret) {
-@@ -944,8 +919,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
- 	}
- 	pramin = chan->ramin->gpuobj;
- 
--	ret = nouveau_mem_init_heap(&chan->ramin_heap,
--				    pramin->im_pramin->start + base, size);
-+	ret = drm_mm_init(&chan->ramin_heap, pramin->im_pramin->start + base, size);
- 	if (ret) {
- 		NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
- 		nouveau_gpuobj_ref_del(dev, &chan->ramin);
-@@ -969,15 +943,11 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- 
- 	NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
- 
--	/* Reserve a block of PRAMIN for the channel
--	 *XXX: maybe on <NV50 too at some point
--	 */
--	if (0 || dev_priv->card_type == NV_50) {
--		ret = nouveau_gpuobj_channel_init_pramin(chan);
--		if (ret) {
--			NV_ERROR(dev, "init pramin\n");
--			return ret;
--		}
-+	/* Allocate a chunk of memory for per-channel object storage */
-+	ret = nouveau_gpuobj_channel_init_pramin(chan);
-+	if (ret) {
-+		NV_ERROR(dev, "init pramin\n");
-+		return ret;
- 	}
- 
- 	/* NV50 VM
-@@ -988,17 +958,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- 	if (dev_priv->card_type >= NV_50) {
- 		uint32_t vm_offset, pde;
- 
--		instmem->prepare_access(dev, true);
--
- 		vm_offset = (dev_priv->chipset & 0xf0) == 0x50 ? 0x1400 : 0x200;
- 		vm_offset += chan->ramin->gpuobj->im_pramin->start;
- 
- 		ret = nouveau_gpuobj_new_fake(dev, vm_offset, ~0, 0x4000,
- 							0, &chan->vm_pd, NULL);
--		if (ret) {
--			instmem->finish_access(dev);
-+		if (ret)
- 			return ret;
--		}
- 		for (i = 0; i < 0x4000; i += 8) {
- 			nv_wo32(dev, chan->vm_pd, (i+0)/4, 0x00000000);
- 			nv_wo32(dev, chan->vm_pd, (i+4)/4, 0xdeadcafe);
-@@ -1008,10 +974,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- 		ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
- 					     dev_priv->gart_info.sg_ctxdma,
- 					     &chan->vm_gart_pt);
--		if (ret) {
--			instmem->finish_access(dev);
-+		if (ret)
- 			return ret;
--		}
- 		nv_wo32(dev, chan->vm_pd, pde++,
- 			    chan->vm_gart_pt->instance | 0x03);
- 		nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
-@@ -1021,17 +985,15 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
- 			ret = nouveau_gpuobj_ref_add(dev, NULL, 0,
- 						     dev_priv->vm_vram_pt[i],
- 						     &chan->vm_vram_pt[i]);
--			if (ret) {
--				instmem->finish_access(dev);
-+			if (ret)
- 				return ret;
--			}
- 
- 			nv_wo32(dev, chan->vm_pd, pde++,
- 				    chan->vm_vram_pt[i]->instance | 0x61);
- 			nv_wo32(dev, chan->vm_pd, pde++, 0x00000000);
- 		}
- 
--		instmem->finish_access(dev);
-+		instmem->flush(dev);
- 	}
- 
- 	/* RAMHT */
-@@ -1130,8 +1092,8 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
- 	for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
- 		nouveau_gpuobj_ref_del(dev, &chan->vm_vram_pt[i]);
- 
--	if (chan->ramin_heap)
--		nouveau_mem_takedown(&chan->ramin_heap);
-+	if (chan->ramin_heap.fl_entry.next)
-+		drm_mm_takedown(&chan->ramin_heap);
- 	if (chan->ramin)
- 		nouveau_gpuobj_ref_del(dev, &chan->ramin);
- 
-@@ -1164,10 +1126,8 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
- 			return -ENOMEM;
- 		}
- 
--		dev_priv->engine.instmem.prepare_access(dev, false);
- 		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
- 			gpuobj->im_backing_suspend[i] = nv_ro32(dev, gpuobj, i);
--		dev_priv->engine.instmem.finish_access(dev);
- 	}
- 
- 	return 0;
-@@ -1212,10 +1172,9 @@ nouveau_gpuobj_resume(struct drm_device *dev)
- 		if (!gpuobj->im_backing_suspend)
- 			continue;
- 
--		dev_priv->engine.instmem.prepare_access(dev, true);
- 		for (i = 0; i < gpuobj->im_pramin->size / 4; i++)
- 			nv_wo32(dev, gpuobj, i, gpuobj->im_backing_suspend[i]);
--		dev_priv->engine.instmem.finish_access(dev);
-+		dev_priv->engine.instmem.flush(dev);
- 	}
- 
- 	nouveau_gpuobj_suspend_cleanup(dev);
-@@ -1232,7 +1191,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
- 	struct nouveau_channel *chan;
- 	int ret;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
- 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan);
- 
- 	if (init->handle == ~0)
-@@ -1283,7 +1241,6 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
- 	struct nouveau_channel *chan;
- 	int ret;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
- 	NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan);
- 
- 	ret = nouveau_gpuobj_ref_find(chan, objfree->handle, &ref);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h
-index 6ca80a3..9c1056c 100644
---- a/drivers/gpu/drm/nouveau/nouveau_reg.h
-+++ b/drivers/gpu/drm/nouveau/nouveau_reg.h
-@@ -1,19 +1,64 @@
- 
-+#define NV04_PFB_BOOT_0						0x00100000
-+#	define NV04_PFB_BOOT_0_RAM_AMOUNT			0x00000003
-+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB			0x00000000
-+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_4MB			0x00000001
-+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_8MB			0x00000002
-+#	define NV04_PFB_BOOT_0_RAM_AMOUNT_16MB			0x00000003
-+#	define NV04_PFB_BOOT_0_RAM_WIDTH_128			0x00000004
-+#	define NV04_PFB_BOOT_0_RAM_TYPE				0x00000028
-+#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT		0x00000000
-+#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT		0x00000008
-+#	define NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT_4BANK	0x00000010
-+#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT		0x00000018
-+#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBIT		0x00000020
-+#	define NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_64MBITX16		0x00000028
-+#	define NV04_PFB_BOOT_0_UMA_ENABLE			0x00000100
-+#	define NV04_PFB_BOOT_0_UMA_SIZE				0x0000f000
-+#define NV04_PFB_DEBUG_0					0x00100080
-+#	define NV04_PFB_DEBUG_0_PAGE_MODE			0x00000001
-+#	define NV04_PFB_DEBUG_0_REFRESH_OFF			0x00000010
-+#	define NV04_PFB_DEBUG_0_REFRESH_COUNTX64		0x00003f00
-+#	define NV04_PFB_DEBUG_0_REFRESH_SLOW_CLK		0x00004000
-+#	define NV04_PFB_DEBUG_0_SAFE_MODE			0x00008000
-+#	define NV04_PFB_DEBUG_0_ALOM_ENABLE			0x00010000
-+#	define NV04_PFB_DEBUG_0_CASOE				0x00100000
-+#	define NV04_PFB_DEBUG_0_CKE_INVERT			0x10000000
-+#	define NV04_PFB_DEBUG_0_REFINC				0x20000000
-+#	define NV04_PFB_DEBUG_0_SAVE_POWER_OFF			0x40000000
-+#define NV04_PFB_CFG0						0x00100200
-+#	define NV04_PFB_CFG0_SCRAMBLE				0x20000000
-+#define NV04_PFB_CFG1						0x00100204
-+#define NV04_PFB_FIFO_DATA					0x0010020c
-+#	define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK		0xfff00000
-+#	define NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_SHIFT		20
-+#define NV10_PFB_REFCTRL					0x00100210
-+#	define NV10_PFB_REFCTRL_VALID_1				(1 << 31)
-+#define NV04_PFB_PAD						0x0010021c
-+#	define NV04_PFB_PAD_CKE_NORMAL				(1 << 0)
-+#define NV10_PFB_TILE(i)                              (0x00100240 + (i*16))
-+#define NV10_PFB_TILE__SIZE					8
-+#define NV10_PFB_TLIMIT(i)                            (0x00100244 + (i*16))
-+#define NV10_PFB_TSIZE(i)                             (0x00100248 + (i*16))
-+#define NV10_PFB_TSTATUS(i)                           (0x0010024c + (i*16))
-+#define NV04_PFB_REF						0x001002d0
-+#	define NV04_PFB_REF_CMD_REFRESH				(1 << 0)
-+#define NV04_PFB_PRE						0x001002d4
-+#	define NV04_PFB_PRE_CMD_PRECHARGE			(1 << 0)
-+#define NV10_PFB_CLOSE_PAGE2					0x0010033c
-+#define NV04_PFB_SCRAMBLE(i)                         (0x00100400 + 4 * (i))
-+#define NV40_PFB_TILE(i)                              (0x00100600 + (i*16))
-+#define NV40_PFB_TILE__SIZE_0					12
-+#define NV40_PFB_TILE__SIZE_1					15
-+#define NV40_PFB_TLIMIT(i)                            (0x00100604 + (i*16))
-+#define NV40_PFB_TSIZE(i)                             (0x00100608 + (i*16))
-+#define NV40_PFB_TSTATUS(i)                           (0x0010060c + (i*16))
-+#define NV40_PFB_UNK_800					0x00100800
- 
--#define NV03_BOOT_0                                        0x00100000
--#    define NV03_BOOT_0_RAM_AMOUNT                         0x00000003
--#    define NV03_BOOT_0_RAM_AMOUNT_8MB                     0x00000000
--#    define NV03_BOOT_0_RAM_AMOUNT_2MB                     0x00000001
--#    define NV03_BOOT_0_RAM_AMOUNT_4MB                     0x00000002
--#    define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM               0x00000003
--#    define NV04_BOOT_0_RAM_AMOUNT_32MB                    0x00000000
--#    define NV04_BOOT_0_RAM_AMOUNT_4MB                     0x00000001
--#    define NV04_BOOT_0_RAM_AMOUNT_8MB                     0x00000002
--#    define NV04_BOOT_0_RAM_AMOUNT_16MB                    0x00000003
--
--#define NV04_FIFO_DATA                                     0x0010020c
--#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK              0xfff00000
--#    define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT             20
-+#define NV_PEXTDEV_BOOT_0					0x00101000
-+#define NV_PEXTDEV_BOOT_0_RAMCFG				0x0000003c
-+#	define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT		(8 << 12)
-+#define NV_PEXTDEV_BOOT_3					0x0010100c
- 
- #define NV_RAMIN                                           0x00700000
- 
-@@ -131,23 +176,6 @@
- #define NV04_PTIMER_TIME_1                                 0x00009410
- #define NV04_PTIMER_ALARM_0                                0x00009420
- 
--#define NV04_PFB_CFG0                                      0x00100200
--#define NV04_PFB_CFG1                                      0x00100204
--#define NV40_PFB_020C                                      0x0010020C
--#define NV10_PFB_TILE(i)                                   (0x00100240 + (i*16))
--#define NV10_PFB_TILE__SIZE                                8
--#define NV10_PFB_TLIMIT(i)                                 (0x00100244 + (i*16))
--#define NV10_PFB_TSIZE(i)                                  (0x00100248 + (i*16))
--#define NV10_PFB_TSTATUS(i)                                (0x0010024C + (i*16))
--#define NV10_PFB_CLOSE_PAGE2                               0x0010033C
--#define NV40_PFB_TILE(i)                                   (0x00100600 + (i*16))
--#define NV40_PFB_TILE__SIZE_0                              12
--#define NV40_PFB_TILE__SIZE_1                              15
--#define NV40_PFB_TLIMIT(i)                                 (0x00100604 + (i*16))
--#define NV40_PFB_TSIZE(i)                                  (0x00100608 + (i*16))
--#define NV40_PFB_TSTATUS(i)                                (0x0010060C + (i*16))
--#define NV40_PFB_UNK_800					0x00100800
--
- #define NV04_PGRAPH_DEBUG_0                                0x00400080
- #define NV04_PGRAPH_DEBUG_1                                0x00400084
- #define NV04_PGRAPH_DEBUG_2                                0x00400088
-@@ -814,6 +842,7 @@
- #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE                           0x80000000
- #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL                            0x00000fff
- #define NV50_SOR_DP_CTRL(i,l)            (0x0061c10c + (i) * 0x800 + (l) * 0x80)
-+#define NV50_SOR_DP_CTRL_ENABLED                                     0x00000001
- #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED                      0x00004000
- #define NV50_SOR_DP_CTRL_LANE_MASK                                   0x001f0000
- #define NV50_SOR_DP_CTRL_LANE_0_ENABLED                              0x00010000
-diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
-index 1d6ee8b..491767f 100644
---- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
-@@ -97,7 +97,6 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
- 
- 	NV_DEBUG(dev, "pg=0x%lx\n", mem->mm_node->start);
- 
--	dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
- 	pte = nouveau_sgdma_pte(nvbe->dev, mem->mm_node->start << PAGE_SHIFT);
- 	nvbe->pte_start = pte;
- 	for (i = 0; i < nvbe->nr_pages; i++) {
-@@ -116,24 +115,11 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem)
- 			dma_offset += NV_CTXDMA_PAGE_SIZE;
- 		}
- 	}
--	dev_priv->engine.instmem.finish_access(nvbe->dev);
-+	dev_priv->engine.instmem.flush(nvbe->dev);
- 
- 	if (dev_priv->card_type == NV_50) {
--		nv_wr32(dev, 0x100c80, 0x00050001);
--		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
--						nv_rd32(dev, 0x100c80));
--			return -EBUSY;
--		}
--
--		nv_wr32(dev, 0x100c80, 0x00000001);
--		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
--						nv_rd32(dev, 0x100c80));
--			return -EBUSY;
--		}
-+		nv50_vm_flush(dev, 5); /* PGRAPH */
-+		nv50_vm_flush(dev, 0); /* PFIFO */
- 	}
- 
- 	nvbe->bound = true;
-@@ -154,7 +140,6 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
- 	if (!nvbe->bound)
- 		return 0;
- 
--	dev_priv->engine.instmem.prepare_access(nvbe->dev, true);
- 	pte = nvbe->pte_start;
- 	for (i = 0; i < nvbe->nr_pages; i++) {
- 		dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus;
-@@ -170,24 +155,11 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
- 			dma_offset += NV_CTXDMA_PAGE_SIZE;
- 		}
- 	}
--	dev_priv->engine.instmem.finish_access(nvbe->dev);
-+	dev_priv->engine.instmem.flush(nvbe->dev);
- 
- 	if (dev_priv->card_type == NV_50) {
--		nv_wr32(dev, 0x100c80, 0x00050001);
--		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
--						nv_rd32(dev, 0x100c80));
--			return -EBUSY;
--		}
--
--		nv_wr32(dev, 0x100c80, 0x00000001);
--		if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--			NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--			NV_ERROR(dev, "0x100c80 = 0x%08x\n",
--						nv_rd32(dev, 0x100c80));
--			return -EBUSY;
--		}
-+		nv50_vm_flush(dev, 5);
-+		nv50_vm_flush(dev, 0);
- 	}
- 
- 	nvbe->bound = false;
-@@ -272,7 +244,6 @@ nouveau_sgdma_init(struct drm_device *dev)
- 		pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0,
- 			     PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	if (dev_priv->card_type < NV_50) {
- 		/* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and
- 		 * confirmed to work on c51.  Perhaps means NV_DMA_TARGET_PCIE
-@@ -294,7 +265,7 @@ nouveau_sgdma_init(struct drm_device *dev)
- 			nv_wo32(dev, gpuobj, (i+4)/4, 0);
- 		}
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	dev_priv->gart_info.type      = NOUVEAU_GART_SGDMA;
- 	dev_priv->gart_info.aper_base = 0;
-@@ -325,14 +296,11 @@ nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma;
--	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
- 	int pte;
- 
- 	pte = (offset >> NV_CTXDMA_PAGE_SHIFT);
- 	if (dev_priv->card_type < NV_50) {
--		instmem->prepare_access(dev, false);
- 		*page = nv_ro32(dev, gpuobj, (pte + 2)) & ~NV_CTXDMA_PAGE_MASK;
--		instmem->finish_access(dev);
- 		return 0;
- 	}
- 
-diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
-index b02a231..621e080 100644
---- a/drivers/gpu/drm/nouveau/nouveau_state.c
-+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
-@@ -54,8 +54,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- 		engine->instmem.clear		= nv04_instmem_clear;
- 		engine->instmem.bind		= nv04_instmem_bind;
- 		engine->instmem.unbind		= nv04_instmem_unbind;
--		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
--		engine->instmem.finish_access	= nv04_instmem_finish_access;
-+		engine->instmem.flush		= nv04_instmem_flush;
- 		engine->mc.init			= nv04_mc_init;
- 		engine->mc.takedown		= nv04_mc_takedown;
- 		engine->timer.init		= nv04_timer_init;
-@@ -95,8 +94,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- 		engine->instmem.clear		= nv04_instmem_clear;
- 		engine->instmem.bind		= nv04_instmem_bind;
- 		engine->instmem.unbind		= nv04_instmem_unbind;
--		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
--		engine->instmem.finish_access	= nv04_instmem_finish_access;
-+		engine->instmem.flush		= nv04_instmem_flush;
- 		engine->mc.init			= nv04_mc_init;
- 		engine->mc.takedown		= nv04_mc_takedown;
- 		engine->timer.init		= nv04_timer_init;
-@@ -138,8 +136,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- 		engine->instmem.clear		= nv04_instmem_clear;
- 		engine->instmem.bind		= nv04_instmem_bind;
- 		engine->instmem.unbind		= nv04_instmem_unbind;
--		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
--		engine->instmem.finish_access	= nv04_instmem_finish_access;
-+		engine->instmem.flush		= nv04_instmem_flush;
- 		engine->mc.init			= nv04_mc_init;
- 		engine->mc.takedown		= nv04_mc_takedown;
- 		engine->timer.init		= nv04_timer_init;
-@@ -181,8 +178,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- 		engine->instmem.clear		= nv04_instmem_clear;
- 		engine->instmem.bind		= nv04_instmem_bind;
- 		engine->instmem.unbind		= nv04_instmem_unbind;
--		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
--		engine->instmem.finish_access	= nv04_instmem_finish_access;
-+		engine->instmem.flush		= nv04_instmem_flush;
- 		engine->mc.init			= nv04_mc_init;
- 		engine->mc.takedown		= nv04_mc_takedown;
- 		engine->timer.init		= nv04_timer_init;
-@@ -225,8 +221,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- 		engine->instmem.clear		= nv04_instmem_clear;
- 		engine->instmem.bind		= nv04_instmem_bind;
- 		engine->instmem.unbind		= nv04_instmem_unbind;
--		engine->instmem.prepare_access	= nv04_instmem_prepare_access;
--		engine->instmem.finish_access	= nv04_instmem_finish_access;
-+		engine->instmem.flush		= nv04_instmem_flush;
- 		engine->mc.init			= nv40_mc_init;
- 		engine->mc.takedown		= nv40_mc_takedown;
- 		engine->timer.init		= nv04_timer_init;
-@@ -271,8 +266,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
- 		engine->instmem.clear		= nv50_instmem_clear;
- 		engine->instmem.bind		= nv50_instmem_bind;
- 		engine->instmem.unbind		= nv50_instmem_unbind;
--		engine->instmem.prepare_access	= nv50_instmem_prepare_access;
--		engine->instmem.finish_access	= nv50_instmem_finish_access;
-+		if (dev_priv->chipset == 0x50)
-+			engine->instmem.flush	= nv50_instmem_flush;
-+		else
-+			engine->instmem.flush	= nv84_instmem_flush;
- 		engine->mc.init			= nv50_mc_init;
- 		engine->mc.takedown		= nv50_mc_takedown;
- 		engine->timer.init		= nv04_timer_init;
-@@ -407,11 +404,6 @@ nouveau_card_init(struct drm_device *dev)
- 	struct nouveau_engine *engine;
- 	int ret;
- 
--	NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
--
--	if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
--		return 0;
--
- 	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
- 	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
- 				       nouveau_switcheroo_can_switch);
-@@ -421,15 +413,12 @@ nouveau_card_init(struct drm_device *dev)
- 	if (ret)
- 		goto out;
- 	engine = &dev_priv->engine;
--	dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
- 	spin_lock_init(&dev_priv->context_switch_lock);
- 
- 	/* Parse BIOS tables / Run init tables if card not POSTed */
--	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
--		ret = nouveau_bios_init(dev);
--		if (ret)
--			goto out;
--	}
-+	ret = nouveau_bios_init(dev);
-+	if (ret)
-+		goto out;
- 
- 	ret = nouveau_mem_detect(dev);
- 	if (ret)
-@@ -485,12 +474,19 @@ nouveau_card_init(struct drm_device *dev)
- 			goto out_graph;
- 	}
- 
-+	if (dev_priv->card_type >= NV_50)
-+		ret = nv50_display_create(dev);
-+	else
-+		ret = nv04_display_create(dev);
-+	if (ret)
-+		goto out_fifo;
-+
- 	/* this call irq_preinstall, register irq handler and
- 	 * call irq_postinstall
- 	 */
- 	ret = drm_irq_install(dev);
- 	if (ret)
--		goto out_fifo;
-+		goto out_display;
- 
- 	ret = drm_vblank_init(dev, 0);
- 	if (ret)
-@@ -504,35 +500,21 @@ nouveau_card_init(struct drm_device *dev)
- 			goto out_irq;
- 	}
- 
--	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
--		if (dev_priv->card_type >= NV_50)
--			ret = nv50_display_create(dev);
--		else
--			ret = nv04_display_create(dev);
--		if (ret)
--			goto out_channel;
--	}
--
- 	ret = nouveau_backlight_init(dev);
- 	if (ret)
- 		NV_ERROR(dev, "Error %d registering backlight\n", ret);
- 
--	dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
--
--	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
--		nouveau_fbcon_init(dev);
--		drm_kms_helper_poll_init(dev);
--	}
--
-+	nouveau_fbcon_init(dev);
-+	drm_kms_helper_poll_init(dev);
- 	return 0;
- 
--out_channel:
--	if (dev_priv->channel) {
--		nouveau_channel_free(dev_priv->channel);
--		dev_priv->channel = NULL;
--	}
- out_irq:
- 	drm_irq_uninstall(dev);
-+out_display:
-+	if (dev_priv->card_type >= NV_50)
-+		nv50_display_destroy(dev);
-+	else
-+		nv04_display_destroy(dev);
- out_fifo:
- 	if (!nouveau_noaccel)
- 		engine->fifo.takedown(dev);
-@@ -566,45 +548,37 @@ static void nouveau_card_takedown(struct drm_device *dev)
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_engine *engine = &dev_priv->engine;
- 
--	NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state);
-+	nouveau_backlight_exit(dev);
- 
--	if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
--
--		nouveau_backlight_exit(dev);
--
--		if (dev_priv->channel) {
--			nouveau_channel_free(dev_priv->channel);
--			dev_priv->channel = NULL;
--		}
--
--		if (!nouveau_noaccel) {
--			engine->fifo.takedown(dev);
--			engine->graph.takedown(dev);
--		}
--		engine->fb.takedown(dev);
--		engine->timer.takedown(dev);
--		engine->mc.takedown(dev);
-+	if (dev_priv->channel) {
-+		nouveau_channel_free(dev_priv->channel);
-+		dev_priv->channel = NULL;
-+	}
- 
--		mutex_lock(&dev->struct_mutex);
--		ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
--		ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
--		mutex_unlock(&dev->struct_mutex);
--		nouveau_sgdma_takedown(dev);
-+	if (!nouveau_noaccel) {
-+		engine->fifo.takedown(dev);
-+		engine->graph.takedown(dev);
-+	}
-+	engine->fb.takedown(dev);
-+	engine->timer.takedown(dev);
-+	engine->mc.takedown(dev);
- 
--		nouveau_gpuobj_takedown(dev);
--		nouveau_mem_close(dev);
--		engine->instmem.takedown(dev);
-+	mutex_lock(&dev->struct_mutex);
-+	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
-+	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
-+	mutex_unlock(&dev->struct_mutex);
-+	nouveau_sgdma_takedown(dev);
- 
--		if (drm_core_check_feature(dev, DRIVER_MODESET))
--			drm_irq_uninstall(dev);
-+	nouveau_gpuobj_takedown(dev);
-+	nouveau_mem_close(dev);
-+	engine->instmem.takedown(dev);
- 
--		nouveau_gpuobj_late_takedown(dev);
--		nouveau_bios_takedown(dev);
-+	drm_irq_uninstall(dev);
- 
--		vga_client_register(dev->pdev, NULL, NULL, NULL);
-+	nouveau_gpuobj_late_takedown(dev);
-+	nouveau_bios_takedown(dev);
- 
--		dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
--	}
-+	vga_client_register(dev->pdev, NULL, NULL, NULL);
- }
- 
- /* here a client dies, release the stuff that was allocated for its
-@@ -691,6 +665,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
- 	struct drm_nouveau_private *dev_priv;
- 	uint32_t reg0;
- 	resource_size_t mmio_start_offs;
-+	int ret;
- 
- 	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
- 	if (!dev_priv)
-@@ -699,7 +674,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
- 	dev_priv->dev = dev;
- 
- 	dev_priv->flags = flags & NOUVEAU_FLAGS;
--	dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
- 
- 	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
- 		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
-@@ -812,46 +786,28 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
- 		dev_priv->flags |= NV_NFORCE2;
- 
- 	/* For kernel modesetting, init card now and bring up fbcon */
--	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
--		int ret = nouveau_card_init(dev);
--		if (ret)
--			return ret;
--	}
-+	ret = nouveau_card_init(dev);
-+	if (ret)
-+		return ret;
- 
- 	return 0;
- }
- 
--static void nouveau_close(struct drm_device *dev)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--
--	/* In the case of an error dev_priv may not be allocated yet */
--	if (dev_priv)
--		nouveau_card_takedown(dev);
--}
--
--/* KMS: we need mmio at load time, not when the first drm client opens. */
- void nouveau_lastclose(struct drm_device *dev)
- {
--	if (drm_core_check_feature(dev, DRIVER_MODESET))
--		return;
--
--	nouveau_close(dev);
- }
- 
- int nouveau_unload(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 
--	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
--		drm_kms_helper_poll_fini(dev);
--		nouveau_fbcon_fini(dev);
--		if (dev_priv->card_type >= NV_50)
--			nv50_display_destroy(dev);
--		else
--			nv04_display_destroy(dev);
--		nouveau_close(dev);
--	}
-+	drm_kms_helper_poll_fini(dev);
-+	nouveau_fbcon_fini(dev);
-+	if (dev_priv->card_type >= NV_50)
-+		nv50_display_destroy(dev);
-+	else
-+		nv04_display_destroy(dev);
-+	nouveau_card_takedown(dev);
- 
- 	iounmap(dev_priv->mmio);
- 	iounmap(dev_priv->ramin);
-@@ -867,8 +823,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct drm_nouveau_getparam *getparam = data;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	switch (getparam->param) {
- 	case NOUVEAU_GETPARAM_CHIPSET_ID:
- 		getparam->value = dev_priv->chipset;
-@@ -937,8 +891,6 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data,
- {
- 	struct drm_nouveau_setparam *setparam = data;
- 
--	NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
--
- 	switch (setparam->param) {
- 	default:
- 		NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
-diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
-index eba687f..1c20c08 100644
---- a/drivers/gpu/drm/nouveau/nv04_crtc.c
-+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
-@@ -157,6 +157,7 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
- {
- 	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- 	struct drm_device *dev = crtc->dev;
-+	struct drm_connector *connector;
- 	unsigned char seq1 = 0, crtc17 = 0;
- 	unsigned char crtc1A;
- 
-@@ -211,6 +212,10 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode)
- 	NVVgaSeqReset(dev, nv_crtc->index, false);
- 
- 	NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A);
-+
-+	/* Update connector polling modes */
-+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-+		nouveau_connector_set_polling(connector);
- }
- 
- static bool
-diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
-index 1cb19e3..2d0fee5 100644
---- a/drivers/gpu/drm/nouveau/nv04_dac.c
-+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
-@@ -261,12 +261,11 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder)
- 
- 	saved_routput = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset);
- 	head = (saved_routput & 0x100) >> 8;
--#if 0
--	/* if there's a spare crtc, using it will minimise flicker for the case
--	 * where the in-use crtc is in use by an off-chip tmds encoder */
--	if (xf86_config->crtc[head]->enabled && !xf86_config->crtc[head ^ 1]->enabled)
-+
-+	/* if there's a spare crtc, using it will minimise flicker */
-+	if (!(NVReadVgaCrtc(dev, head, NV_CIO_CRE_RPC1_INDEX) & 0xC0))
- 		head ^= 1;
--#endif
-+
- 	/* nv driver and nv31 use 0xfffffeee, nv34 and 6600 use 0xfffffece */
- 	routput = (saved_routput & 0xfffffece) | head << 8;
- 
-@@ -315,9 +314,12 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
- {
- 	struct drm_device *dev = encoder->dev;
- 	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
--	uint32_t sample = nv17_dac_sample_load(encoder);
- 
--	if (sample & NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
-+	if (nv04_dac_in_use(encoder))
-+		return connector_status_disconnected;
-+
-+	if (nv17_dac_sample_load(encoder) &
-+	    NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
- 		NV_INFO(dev, "Load detected on output %c\n",
- 			'@' + ffs(dcb->or));
- 		return connector_status_connected;
-@@ -330,6 +332,9 @@ static bool nv04_dac_mode_fixup(struct drm_encoder *encoder,
- 				struct drm_display_mode *mode,
- 				struct drm_display_mode *adjusted_mode)
- {
-+	if (nv04_dac_in_use(encoder))
-+		return false;
-+
- 	return true;
- }
- 
-@@ -428,6 +433,17 @@ void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
- 	}
- }
- 
-+/* Check if the DAC corresponding to 'encoder' is being used by
-+ * someone else. */
-+bool nv04_dac_in_use(struct drm_encoder *encoder)
-+{
-+	struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
-+	struct dcb_entry *dcb = nouveau_encoder(encoder)->dcb;
-+
-+	return nv_gf4_disp_arch(encoder->dev) &&
-+		(dev_priv->dac_users[ffs(dcb->or) - 1] & ~(1 << dcb->index));
-+}
-+
- static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
- {
- 	struct drm_device *dev = encoder->dev;
-@@ -501,11 +517,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = {
- 	.destroy = nv04_dac_destroy,
- };
- 
--int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
-+int
-+nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
- {
- 	const struct drm_encoder_helper_funcs *helper;
--	struct drm_encoder *encoder;
- 	struct nouveau_encoder *nv_encoder = NULL;
-+	struct drm_device *dev = connector->dev;
-+	struct drm_encoder *encoder;
- 
- 	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
- 	if (!nv_encoder)
-@@ -527,5 +545,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
- 	encoder->possible_crtcs = entry->heads;
- 	encoder->possible_clones = 0;
- 
-+	drm_mode_connector_attach_encoder(connector, encoder);
- 	return 0;
- }
-diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
-index 41634d4..3311f3a 100644
---- a/drivers/gpu/drm/nouveau/nv04_dfp.c
-+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
-@@ -413,10 +413,6 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
- 	struct dcb_entry *dcbe = nv_encoder->dcb;
- 	int head = nouveau_crtc(encoder->crtc)->index;
- 
--	NV_INFO(dev, "Output %s is running on CRTC %d using output %c\n",
--		drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
--		nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
--
- 	if (dcbe->type == OUTPUT_TMDS)
- 		run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
- 	else if (dcbe->type == OUTPUT_LVDS)
-@@ -584,11 +580,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = {
- 	.destroy = nv04_dfp_destroy,
- };
- 
--int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
-+int
-+nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
- {
- 	const struct drm_encoder_helper_funcs *helper;
--	struct drm_encoder *encoder;
- 	struct nouveau_encoder *nv_encoder = NULL;
-+	struct drm_encoder *encoder;
- 	int type;
- 
- 	switch (entry->type) {
-@@ -613,11 +610,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
- 	nv_encoder->dcb = entry;
- 	nv_encoder->or = ffs(entry->or) - 1;
- 
--	drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type);
-+	drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type);
- 	drm_encoder_helper_add(encoder, helper);
- 
- 	encoder->possible_crtcs = entry->heads;
- 	encoder->possible_clones = 0;
- 
-+	drm_mode_connector_attach_encoder(connector, encoder);
- 	return 0;
- }
-diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c
-index c7898b4..c6df391 100644
---- a/drivers/gpu/drm/nouveau/nv04_display.c
-+++ b/drivers/gpu/drm/nouveau/nv04_display.c
-@@ -32,8 +32,6 @@
- #include "nouveau_encoder.h"
- #include "nouveau_connector.h"
- 
--#define MULTIPLE_ENCODERS(e) (e & (e - 1))
--
- static void
- nv04_display_store_initial_head_owner(struct drm_device *dev)
- {
-@@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
- 
- 	if (dev_priv->chipset != 0x11) {
- 		dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
--		goto ownerknown;
-+		return;
- 	}
- 
- 	/* reading CR44 is broken on nv11, so we attempt to infer it */
-@@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
- 		bool tvA = false;
- 		bool tvB = false;
- 
--		NVLockVgaCrtcs(dev, false);
--
- 		slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
- 									0x80;
- 		if (slaved_on_B)
-@@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
- 			tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
- 					MASK(NV_CIO_CRE_LCD_LCD_SELECT));
- 
--		NVLockVgaCrtcs(dev, true);
--
- 		if (slaved_on_A && !tvA)
- 			dev_priv->crtc_owner = 0x0;
- 		else if (slaved_on_B && !tvB)
-@@ -79,14 +73,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
- 		else
- 			dev_priv->crtc_owner = 0x0;
- 	}
--
--ownerknown:
--	NV_INFO(dev, "Initial CRTC_OWNER is %d\n", dev_priv->crtc_owner);
--
--	/* we need to ensure the heads are not tied henceforth, or reading any
--	 * 8 bit reg on head B will fail
--	 * setting a single arbitrary head solves that */
--	NVSetOwner(dev, 0);
- }
- 
- int
-@@ -94,14 +80,20 @@ nv04_display_create(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct dcb_table *dcb = &dev_priv->vbios.dcb;
-+	struct drm_connector *connector, *ct;
- 	struct drm_encoder *encoder;
- 	struct drm_crtc *crtc;
- 	int i, ret;
- 
- 	NV_DEBUG_KMS(dev, "\n");
- 
--	if (nv_two_heads(dev))
-+	NVLockVgaCrtcs(dev, false);
-+
-+	if (nv_two_heads(dev)) {
- 		nv04_display_store_initial_head_owner(dev);
-+		NVSetOwner(dev, 0);
-+	}
-+
- 	nouveau_hw_save_vga_fonts(dev, 1);
- 
- 	drm_mode_config_init(dev);
-@@ -132,19 +124,23 @@ nv04_display_create(struct drm_device *dev)
- 	for (i = 0; i < dcb->entries; i++) {
- 		struct dcb_entry *dcbent = &dcb->entry[i];
- 
-+		connector = nouveau_connector_create(dev, dcbent->connector);
-+		if (IS_ERR(connector))
-+			continue;
-+
- 		switch (dcbent->type) {
- 		case OUTPUT_ANALOG:
--			ret = nv04_dac_create(dev, dcbent);
-+			ret = nv04_dac_create(connector, dcbent);
- 			break;
- 		case OUTPUT_LVDS:
- 		case OUTPUT_TMDS:
--			ret = nv04_dfp_create(dev, dcbent);
-+			ret = nv04_dfp_create(connector, dcbent);
- 			break;
- 		case OUTPUT_TV:
- 			if (dcbent->location == DCB_LOC_ON_CHIP)
--				ret = nv17_tv_create(dev, dcbent);
-+				ret = nv17_tv_create(connector, dcbent);
- 			else
--				ret = nv04_tv_create(dev, dcbent);
-+				ret = nv04_tv_create(connector, dcbent);
- 			break;
- 		default:
- 			NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
-@@ -155,12 +151,16 @@ nv04_display_create(struct drm_device *dev)
- 			continue;
- 	}
- 
--	for (i = 0; i < dcb->connector.entries; i++)
--		nouveau_connector_create(dev, &dcb->connector.entry[i]);
-+	list_for_each_entry_safe(connector, ct,
-+				 &dev->mode_config.connector_list, head) {
-+		if (!connector->encoder_ids[0]) {
-+			NV_WARN(dev, "%s has no encoders, removing\n",
-+				drm_get_connector_name(connector));
-+			connector->funcs->destroy(connector);
-+		}
-+	}
- 
- 	/* Save previous state */
--	NVLockVgaCrtcs(dev, false);
--
- 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- 		crtc->funcs->save(crtc);
- 
-@@ -176,6 +176,7 @@ nv04_display_create(struct drm_device *dev)
- void
- nv04_display_destroy(struct drm_device *dev)
- {
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct drm_encoder *encoder;
- 	struct drm_crtc *crtc;
- 
-@@ -191,8 +192,6 @@ nv04_display_destroy(struct drm_device *dev)
- 	}
- 
- 	/* Restore state */
--	NVLockVgaCrtcs(dev, false);
--
- 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- 		struct drm_encoder_helper_funcs *func = encoder->helper_private;
- 
-@@ -205,12 +204,15 @@ nv04_display_destroy(struct drm_device *dev)
- 	drm_mode_config_cleanup(dev);
- 
- 	nouveau_hw_save_vga_fonts(dev, 0);
-+
-+	if (nv_two_heads(dev))
-+		NVSetOwner(dev, dev_priv->crtc_owner);
-+	NVLockVgaCrtcs(dev, true);
- }
- 
- void
- nv04_display_restore(struct drm_device *dev)
- {
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct drm_encoder *encoder;
- 	struct drm_crtc *crtc;
- 
-@@ -232,13 +234,5 @@ nv04_display_restore(struct drm_device *dev)
- 
- 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- 		crtc->funcs->restore(crtc);
--
--	if (nv_two_heads(dev)) {
--		NV_INFO(dev, "Restoring CRTC_OWNER to %d.\n",
--			dev_priv->crtc_owner);
--		NVSetOwner(dev, dev_priv->crtc_owner);
--	}
--
--	NVLockVgaCrtcs(dev, true);
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c
-index 66fe559..06cedd9 100644
---- a/drivers/gpu/drm/nouveau/nv04_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nv04_fifo.c
-@@ -112,6 +112,12 @@ nv04_fifo_channel_id(struct drm_device *dev)
- 			NV03_PFIFO_CACHE1_PUSH1_CHID_MASK;
- }
- 
-+#ifdef __BIG_ENDIAN
-+#define DMA_FETCH_ENDIANNESS NV_PFIFO_CACHE1_BIG_ENDIAN
-+#else
-+#define DMA_FETCH_ENDIANNESS 0
-+#endif
-+
- int
- nv04_fifo_create_context(struct nouveau_channel *chan)
- {
-@@ -131,18 +137,13 @@ nv04_fifo_create_context(struct nouveau_channel *chan)
- 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- 
- 	/* Setup initial state */
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	RAMFC_WR(DMA_PUT, chan->pushbuf_base);
- 	RAMFC_WR(DMA_GET, chan->pushbuf_base);
- 	RAMFC_WR(DMA_INSTANCE, chan->pushbuf->instance >> 4);
- 	RAMFC_WR(DMA_FETCH, (NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
- 			     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
- 			     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 |
--#ifdef __BIG_ENDIAN
--			     NV_PFIFO_CACHE1_BIG_ENDIAN |
--#endif
--			     0));
--	dev_priv->engine.instmem.finish_access(dev);
-+			     DMA_FETCH_ENDIANNESS));
- 
- 	/* enable the fifo dma operation */
- 	nv_wr32(dev, NV04_PFIFO_MODE,
-@@ -169,8 +170,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid)
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	uint32_t fc = NV04_RAMFC(chid), tmp;
- 
--	dev_priv->engine.instmem.prepare_access(dev, false);
--
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
- 	tmp = nv_ri32(dev, fc + 8);
-@@ -181,8 +180,6 @@ nv04_fifo_do_load_context(struct drm_device *dev, int chid)
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_ri32(dev, fc + 20));
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_PULL1, nv_ri32(dev, fc + 24));
- 
--	dev_priv->engine.instmem.finish_access(dev);
--
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
- }
-@@ -223,7 +220,6 @@ nv04_fifo_unload_context(struct drm_device *dev)
- 		return -EINVAL;
- 	}
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	RAMFC_WR(DMA_PUT, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
- 	RAMFC_WR(DMA_GET, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
- 	tmp  = nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_DCOUNT) << 16;
-@@ -233,7 +229,6 @@ nv04_fifo_unload_context(struct drm_device *dev)
- 	RAMFC_WR(DMA_FETCH, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_FETCH));
- 	RAMFC_WR(ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE));
- 	RAMFC_WR(PULL1_ENGINE, nv_rd32(dev, NV04_PFIFO_CACHE1_PULL1));
--	dev_priv->engine.instmem.finish_access(dev);
- 
- 	nv04_fifo_do_load_context(dev, pfifo->channels - 1);
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
-@@ -297,6 +292,7 @@ nv04_fifo_init(struct drm_device *dev)
- 
- 	nv04_fifo_init_intr(dev);
- 	pfifo->enable(dev);
-+	pfifo->reassign(dev, true);
- 
- 	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
- 		if (dev_priv->fifos[i]) {
-diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c
-index 618355e..c897342 100644
---- a/drivers/gpu/drm/nouveau/nv04_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv04_graph.c
-@@ -342,7 +342,7 @@ static uint32_t nv04_graph_ctx_regs[] = {
- };
- 
- struct graph_state {
--	int nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
-+	uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
- };
- 
- struct nouveau_channel *
-@@ -527,8 +527,7 @@ static int
- nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass,
- 			int mthd, uint32_t data)
- {
--	chan->fence.last_sequence_irq = data;
--	nouveau_fence_handler(chan->dev, chan->id);
-+	atomic_set(&chan->fence.last_sequence_irq, data);
- 	return 0;
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c
-index a3b9563..4408232 100644
---- a/drivers/gpu/drm/nouveau/nv04_instmem.c
-+++ b/drivers/gpu/drm/nouveau/nv04_instmem.c
-@@ -49,10 +49,8 @@ nv04_instmem_determine_amount(struct drm_device *dev)
- 	NV_DEBUG(dev, "RAMIN size: %dKiB\n", dev_priv->ramin_rsvd_vram >> 10);
- 
- 	/* Clear all of it, except the BIOS image that's in the first 64KiB */
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	for (i = 64 * 1024; i < dev_priv->ramin_rsvd_vram; i += 4)
- 		nv_wi32(dev, i, 0x00000000);
--	dev_priv->engine.instmem.finish_access(dev);
- }
- 
- static void
-@@ -106,7 +104,7 @@ int nv04_instmem_init(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	uint32_t offset;
--	int ret = 0;
-+	int ret;
- 
- 	nv04_instmem_determine_amount(dev);
- 	nv04_instmem_configure_fixed_tables(dev);
-@@ -129,14 +127,14 @@ int nv04_instmem_init(struct drm_device *dev)
- 			offset = 0x40000;
- 	}
- 
--	ret = nouveau_mem_init_heap(&dev_priv->ramin_heap,
--				    offset, dev_priv->ramin_rsvd_vram - offset);
-+	ret = drm_mm_init(&dev_priv->ramin_heap, offset,
-+			  dev_priv->ramin_rsvd_vram - offset);
- 	if (ret) {
--		dev_priv->ramin_heap = NULL;
--		NV_ERROR(dev, "Failed to init RAMIN heap\n");
-+		NV_ERROR(dev, "Failed to init RAMIN heap: %d\n", ret);
-+		return ret;
- 	}
- 
--	return ret;
-+	return 0;
- }
- 
- void
-@@ -186,12 +184,7 @@ nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
- }
- 
- void
--nv04_instmem_prepare_access(struct drm_device *dev, bool write)
--{
--}
--
--void
--nv04_instmem_finish_access(struct drm_device *dev)
-+nv04_instmem_flush(struct drm_device *dev)
- {
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nv04_mc.c b/drivers/gpu/drm/nouveau/nv04_mc.c
-index 617ed1e..2af43a1 100644
---- a/drivers/gpu/drm/nouveau/nv04_mc.c
-+++ b/drivers/gpu/drm/nouveau/nv04_mc.c
-@@ -11,6 +11,10 @@ nv04_mc_init(struct drm_device *dev)
- 	 */
- 
- 	nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
-+
-+	/* Disable PROM access. */
-+	nv_wr32(dev, NV_PBUS_PCI_NV_20, NV_PBUS_PCI_NV_20_ROM_SHADOW_ENABLED);
-+
- 	return 0;
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
-index c4e3404..94e299c 100644
---- a/drivers/gpu/drm/nouveau/nv04_tv.c
-+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
-@@ -34,69 +34,26 @@
- 
- #include "i2c/ch7006.h"
- 
--static struct {
--	struct i2c_board_info board_info;
--	struct drm_encoder_funcs funcs;
--	struct drm_encoder_helper_funcs hfuncs;
--	void *params;
--
--} nv04_tv_encoder_info[] = {
-+static struct i2c_board_info nv04_tv_encoder_info[] = {
- 	{
--		.board_info = { I2C_BOARD_INFO("ch7006", 0x75) },
--		.params = &(struct ch7006_encoder_params) {
-+		I2C_BOARD_INFO("ch7006", 0x75),
-+		.platform_data = &(struct ch7006_encoder_params) {
- 			CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER,
- 			0, 0, 0,
- 			CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED,
- 			CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC
--		},
-+		}
- 	},
-+	{ }
- };
- 
--static bool probe_i2c_addr(struct i2c_adapter *adapter, int addr)
--{
--	struct i2c_msg msg = {
--		.addr = addr,
--		.len = 0,
--	};
--
--	return i2c_transfer(adapter, &msg, 1) == 1;
--}
--
- int nv04_tv_identify(struct drm_device *dev, int i2c_index)
- {
--	struct nouveau_i2c_chan *i2c;
--	bool was_locked;
--	int i, ret;
--
--	NV_TRACE(dev, "Probing TV encoders on I2C bus: %d\n", i2c_index);
--
--	i2c = nouveau_i2c_find(dev, i2c_index);
--	if (!i2c)
--		return -ENODEV;
--
--	was_locked = NVLockVgaCrtcs(dev, false);
--
--	for (i = 0; i < ARRAY_SIZE(nv04_tv_encoder_info); i++) {
--		if (probe_i2c_addr(&i2c->adapter,
--				   nv04_tv_encoder_info[i].board_info.addr)) {
--			ret = i;
--			break;
--		}
--	}
--
--	if (i < ARRAY_SIZE(nv04_tv_encoder_info)) {
--		NV_TRACE(dev, "Detected TV encoder: %s\n",
--			 nv04_tv_encoder_info[i].board_info.type);
--
--	} else {
--		NV_TRACE(dev, "No TV encoders found.\n");
--		i = -ENODEV;
--	}
--
--	NVLockVgaCrtcs(dev, was_locked);
--	return i;
-+	return nouveau_i2c_identify(dev, "TV encoder",
-+				    nv04_tv_encoder_info, i2c_index);
- }
- 
-+
- #define PLLSEL_TV_CRTC1_MASK				\
- 	(NV_PRAMDAC_PLL_COEFF_SELECT_TV_VSCLK1		\
- 	 | NV_PRAMDAC_PLL_COEFF_SELECT_TV_PCLK1)
-@@ -214,30 +171,32 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
- 
- static void nv04_tv_destroy(struct drm_encoder *encoder)
- {
--	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
--
- 	to_encoder_slave(encoder)->slave_funcs->destroy(encoder);
- 
- 	drm_encoder_cleanup(encoder);
- 
--	kfree(nv_encoder);
-+	kfree(encoder->helper_private);
-+	kfree(nouveau_encoder(encoder));
- }
- 
--int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
-+static const struct drm_encoder_funcs nv04_tv_funcs = {
-+	.destroy = nv04_tv_destroy,
-+};
-+
-+int
-+nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
- {
- 	struct nouveau_encoder *nv_encoder;
- 	struct drm_encoder *encoder;
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct i2c_adapter *adap;
--	struct drm_encoder_funcs *funcs = NULL;
--	struct drm_encoder_helper_funcs *hfuncs = NULL;
--	struct drm_encoder_slave_funcs *sfuncs = NULL;
--	int i2c_index = entry->i2c_index;
-+	struct drm_device *dev = connector->dev;
-+	struct drm_encoder_helper_funcs *hfuncs;
-+	struct drm_encoder_slave_funcs *sfuncs;
-+	struct nouveau_i2c_chan *i2c =
-+		nouveau_i2c_find(dev, entry->i2c_index);
- 	int type, ret;
--	bool was_locked;
- 
- 	/* Ensure that we can talk to this encoder */
--	type = nv04_tv_identify(dev, i2c_index);
-+	type = nv04_tv_identify(dev, entry->i2c_index);
- 	if (type < 0)
- 		return type;
- 
-@@ -246,41 +205,32 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
- 	if (!nv_encoder)
- 		return -ENOMEM;
- 
-+	hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL);
-+	if (!hfuncs) {
-+		ret = -ENOMEM;
-+		goto fail_free;
-+	}
-+
- 	/* Initialize the common members */
- 	encoder = to_drm_encoder(nv_encoder);
- 
--	funcs = &nv04_tv_encoder_info[type].funcs;
--	hfuncs = &nv04_tv_encoder_info[type].hfuncs;
--
--	drm_encoder_init(dev, encoder, funcs, DRM_MODE_ENCODER_TVDAC);
-+	drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC);
- 	drm_encoder_helper_add(encoder, hfuncs);
- 
- 	encoder->possible_crtcs = entry->heads;
- 	encoder->possible_clones = 0;
--
- 	nv_encoder->dcb = entry;
- 	nv_encoder->or = ffs(entry->or) - 1;
- 
- 	/* Run the slave-specific initialization */
--	adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter;
--
--	was_locked = NVLockVgaCrtcs(dev, false);
--
--	ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap,
--				   &nv04_tv_encoder_info[type].board_info);
--
--	NVLockVgaCrtcs(dev, was_locked);
--
-+	ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
-+				   &i2c->adapter, &nv04_tv_encoder_info[type]);
- 	if (ret < 0)
--		goto fail;
-+		goto fail_cleanup;
- 
- 	/* Fill the function pointers */
- 	sfuncs = to_encoder_slave(encoder)->slave_funcs;
- 
--	*funcs = (struct drm_encoder_funcs) {
--		.destroy = nv04_tv_destroy,
--	};
--
- 	*hfuncs = (struct drm_encoder_helper_funcs) {
- 		.dpms = nv04_tv_dpms,
- 		.save = sfuncs->save,
-@@ -292,14 +242,17 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
- 		.detect = sfuncs->detect,
- 	};
- 
--	/* Set the slave encoder configuration */
--	sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
-+	/* Attach it to the specified connector. */
-+	sfuncs->set_config(encoder, nv04_tv_encoder_info[type].platform_data);
-+	sfuncs->create_resources(encoder, connector);
-+	drm_mode_connector_attach_encoder(connector, encoder);
- 
- 	return 0;
- 
--fail:
-+fail_cleanup:
- 	drm_encoder_cleanup(encoder);
--
-+	kfree(hfuncs);
-+fail_free:
- 	kfree(nv_encoder);
- 	return ret;
- }
-diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c
-index 7aeabf2..7a4069c 100644
---- a/drivers/gpu/drm/nouveau/nv10_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nv10_fifo.c
-@@ -55,7 +55,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
- 	/* Fill entries that are seen filled in dumps of nvidia driver just
- 	 * after channel's is put into DMA mode
- 	 */
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	nv_wi32(dev, fc +  0, chan->pushbuf_base);
- 	nv_wi32(dev, fc +  4, chan->pushbuf_base);
- 	nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
-@@ -66,7 +65,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan)
- 			      NV_PFIFO_CACHE1_BIG_ENDIAN |
- #endif
- 			      0);
--	dev_priv->engine.instmem.finish_access(dev);
- 
- 	/* enable the fifo dma operation */
- 	nv_wr32(dev, NV04_PFIFO_MODE,
-@@ -91,8 +89,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid)
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	uint32_t fc = NV10_RAMFC(chid), tmp;
- 
--	dev_priv->engine.instmem.prepare_access(dev, false);
--
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
- 	nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
-@@ -117,8 +113,6 @@ nv10_fifo_do_load_context(struct drm_device *dev, int chid)
- 	nv_wr32(dev, NV10_PFIFO_CACHE1_DMA_SUBROUTINE, nv_ri32(dev, fc + 48));
- 
- out:
--	dev_priv->engine.instmem.finish_access(dev);
--
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
- }
-@@ -155,8 +149,6 @@ nv10_fifo_unload_context(struct drm_device *dev)
- 		return 0;
- 	fc = NV10_RAMFC(chid);
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
--
- 	nv_wi32(dev, fc +  0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
- 	nv_wi32(dev, fc +  4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
- 	nv_wi32(dev, fc +  8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
-@@ -179,8 +171,6 @@ nv10_fifo_unload_context(struct drm_device *dev)
- 	nv_wi32(dev, fc + 48, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
- 
- out:
--	dev_priv->engine.instmem.finish_access(dev);
--
- 	nv10_fifo_do_load_context(dev, pfifo->channels - 1);
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, pfifo->channels - 1);
- 	return 0;
-diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c
-index 74c8803..bb3a284 100644
---- a/drivers/gpu/drm/nouveau/nv17_tv.c
-+++ b/drivers/gpu/drm/nouveau/nv17_tv.c
-@@ -116,6 +116,21 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder)
- 	return sample;
- }
- 
-+static bool
-+get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
-+{
-+	/* Zotac FX5200 */
-+	if (dev->pdev->device == 0x0322 &&
-+	    dev->pdev->subsystem_vendor == 0x19da &&
-+	    (dev->pdev->subsystem_device == 0x1035 ||
-+	     dev->pdev->subsystem_device == 0x2035)) {
-+		*pin_mask = 0xc;
-+		return false;
-+	}
-+
-+	return true;
-+}
-+
- static enum drm_connector_status
- nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
- {
-@@ -124,12 +139,20 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
- 	struct drm_mode_config *conf = &dev->mode_config;
- 	struct nv17_tv_encoder *tv_enc = to_tv_enc(encoder);
- 	struct dcb_entry *dcb = tv_enc->base.dcb;
-+	bool reliable = get_tv_detect_quirks(dev, &tv_enc->pin_mask);
- 
--	if (dev_priv->chipset == 0x42 ||
--	    dev_priv->chipset == 0x43)
--		tv_enc->pin_mask = nv42_tv_sample_load(encoder) >> 28 & 0xe;
--	else
--		tv_enc->pin_mask = nv17_dac_sample_load(encoder) >> 28 & 0xe;
-+	if (nv04_dac_in_use(encoder))
-+		return connector_status_disconnected;
-+
-+	if (reliable) {
-+		if (dev_priv->chipset == 0x42 ||
-+		    dev_priv->chipset == 0x43)
-+			tv_enc->pin_mask =
-+				nv42_tv_sample_load(encoder) >> 28 & 0xe;
-+		else
-+			tv_enc->pin_mask =
-+				nv17_dac_sample_load(encoder) >> 28 & 0xe;
-+	}
- 
- 	switch (tv_enc->pin_mask) {
- 	case 0x2:
-@@ -154,7 +177,9 @@ nv17_tv_detect(struct drm_encoder *encoder, struct drm_connector *connector)
- 					 conf->tv_subconnector_property,
- 					 tv_enc->subconnector);
- 
--	if (tv_enc->subconnector) {
-+	if (!reliable) {
-+		return connector_status_unknown;
-+	} else if (tv_enc->subconnector) {
- 		NV_INFO(dev, "Load detected on output %c\n",
- 			'@' + ffs(dcb->or));
- 		return connector_status_connected;
-@@ -296,6 +321,9 @@ static bool nv17_tv_mode_fixup(struct drm_encoder *encoder,
- {
- 	struct nv17_tv_norm_params *tv_norm = get_tv_norm(encoder);
- 
-+	if (nv04_dac_in_use(encoder))
-+		return false;
-+
- 	if (tv_norm->kind == CTV_ENC_MODE)
- 		adjusted_mode->clock = tv_norm->ctv_enc_mode.mode.clock;
- 	else
-@@ -744,8 +772,10 @@ static struct drm_encoder_funcs nv17_tv_funcs = {
- 	.destroy = nv17_tv_destroy,
- };
- 
--int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
-+int
-+nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
- {
-+	struct drm_device *dev = connector->dev;
- 	struct drm_encoder *encoder;
- 	struct nv17_tv_encoder *tv_enc = NULL;
- 
-@@ -774,5 +804,7 @@ int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
- 	encoder->possible_crtcs = entry->heads;
- 	encoder->possible_clones = 0;
- 
-+	nv17_tv_create_resources(encoder, connector);
-+	drm_mode_connector_attach_encoder(connector, encoder);
- 	return 0;
- }
-diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c
-index d6fc0a8..191c15c 100644
---- a/drivers/gpu/drm/nouveau/nv20_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv20_graph.c
-@@ -370,68 +370,54 @@ nv20_graph_create_context(struct nouveau_channel *chan)
- {
- 	struct drm_device *dev = chan->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- 	void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
--	unsigned int ctx_size;
- 	unsigned int idoffs = 0x28/4;
- 	int ret;
- 
- 	switch (dev_priv->chipset) {
- 	case 0x20:
--		ctx_size = NV20_GRCTX_SIZE;
- 		ctx_init = nv20_graph_context_init;
- 		idoffs = 0;
- 		break;
- 	case 0x25:
- 	case 0x28:
--		ctx_size = NV25_GRCTX_SIZE;
- 		ctx_init = nv25_graph_context_init;
- 		break;
- 	case 0x2a:
--		ctx_size = NV2A_GRCTX_SIZE;
- 		ctx_init = nv2a_graph_context_init;
- 		idoffs = 0;
- 		break;
- 	case 0x30:
- 	case 0x31:
--		ctx_size = NV30_31_GRCTX_SIZE;
- 		ctx_init = nv30_31_graph_context_init;
- 		break;
- 	case 0x34:
--		ctx_size = NV34_GRCTX_SIZE;
- 		ctx_init = nv34_graph_context_init;
- 		break;
- 	case 0x35:
- 	case 0x36:
--		ctx_size = NV35_36_GRCTX_SIZE;
- 		ctx_init = nv35_36_graph_context_init;
- 		break;
- 	default:
--		ctx_size = 0;
--		ctx_init = nv35_36_graph_context_init;
--		NV_ERROR(dev, "Please contact the devs if you want your NV%x"
--			      " card to work\n", dev_priv->chipset);
--		return -ENOSYS;
--		break;
-+		BUG_ON(1);
- 	}
- 
--	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, ctx_size, 16,
--					  NVOBJ_FLAG_ZERO_ALLOC,
--					  &chan->ramin_grctx);
-+	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
-+				     16, NVOBJ_FLAG_ZERO_ALLOC,
-+				     &chan->ramin_grctx);
- 	if (ret)
- 		return ret;
- 
- 	/* Initialise default context values */
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	ctx_init(dev, chan->ramin_grctx->gpuobj);
- 
- 	/* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
- 	nv_wo32(dev, chan->ramin_grctx->gpuobj, idoffs,
- 					(chan->id << 24) | 0x1); /* CTX_USER */
- 
--	nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id,
--			chan->ramin_grctx->instance >> 4);
--
--	dev_priv->engine.instmem.finish_access(dev);
-+	nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id,
-+		     chan->ramin_grctx->instance >> 4);
- 	return 0;
- }
- 
-@@ -440,13 +426,12 @@ nv20_graph_destroy_context(struct nouveau_channel *chan)
- {
- 	struct drm_device *dev = chan->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- 
- 	if (chan->ramin_grctx)
- 		nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
--	nv_wo32(dev, dev_priv->ctx_table->gpuobj, chan->id, 0);
--	dev_priv->engine.instmem.finish_access(dev);
-+	nv_wo32(dev, pgraph->ctx_table->gpuobj, chan->id, 0);
- }
- 
- int
-@@ -538,29 +523,44 @@ nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr,
- int
- nv20_graph_init(struct drm_device *dev)
- {
--	struct drm_nouveau_private *dev_priv =
--		(struct drm_nouveau_private *)dev->dev_private;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- 	uint32_t tmp, vramsz;
- 	int ret, i;
- 
-+	switch (dev_priv->chipset) {
-+	case 0x20:
-+		pgraph->grctx_size = NV20_GRCTX_SIZE;
-+		break;
-+	case 0x25:
-+	case 0x28:
-+		pgraph->grctx_size = NV25_GRCTX_SIZE;
-+		break;
-+	case 0x2a:
-+		pgraph->grctx_size = NV2A_GRCTX_SIZE;
-+		break;
-+	default:
-+		NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
-+		pgraph->accel_blocked = true;
-+		return 0;
-+	}
-+
- 	nv_wr32(dev, NV03_PMC_ENABLE,
- 		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
- 	nv_wr32(dev, NV03_PMC_ENABLE,
- 		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
- 
--	if (!dev_priv->ctx_table) {
-+	if (!pgraph->ctx_table) {
- 		/* Create Context Pointer Table */
--		dev_priv->ctx_table_size = 32 * 4;
--		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
--						  dev_priv->ctx_table_size, 16,
-+		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16,
- 						  NVOBJ_FLAG_ZERO_ALLOC,
--						  &dev_priv->ctx_table);
-+						  &pgraph->ctx_table);
- 		if (ret)
- 			return ret;
- 	}
- 
- 	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
--		 dev_priv->ctx_table->instance >> 4);
-+		     pgraph->ctx_table->instance >> 4);
- 
- 	nv20_graph_rdi(dev);
- 
-@@ -644,34 +644,52 @@ void
- nv20_graph_takedown(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- 
--	nouveau_gpuobj_ref_del(dev, &dev_priv->ctx_table);
-+	nouveau_gpuobj_ref_del(dev, &pgraph->ctx_table);
- }
- 
- int
- nv30_graph_init(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
- 	int ret, i;
- 
-+	switch (dev_priv->chipset) {
-+	case 0x30:
-+	case 0x31:
-+		pgraph->grctx_size = NV30_31_GRCTX_SIZE;
-+		break;
-+	case 0x34:
-+		pgraph->grctx_size = NV34_GRCTX_SIZE;
-+		break;
-+	case 0x35:
-+	case 0x36:
-+		pgraph->grctx_size = NV35_36_GRCTX_SIZE;
-+		break;
-+	default:
-+		NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
-+		pgraph->accel_blocked = true;
-+		return 0;
-+	}
-+
- 	nv_wr32(dev, NV03_PMC_ENABLE,
- 		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
- 	nv_wr32(dev, NV03_PMC_ENABLE,
- 		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
- 
--	if (!dev_priv->ctx_table) {
-+	if (!pgraph->ctx_table) {
- 		/* Create Context Pointer Table */
--		dev_priv->ctx_table_size = 32 * 4;
--		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0,
--						  dev_priv->ctx_table_size, 16,
-+		ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 32 * 4, 16,
- 						  NVOBJ_FLAG_ZERO_ALLOC,
--						  &dev_priv->ctx_table);
-+						  &pgraph->ctx_table);
- 		if (ret)
- 			return ret;
- 	}
- 
- 	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
--			dev_priv->ctx_table->instance >> 4);
-+		     pgraph->ctx_table->instance >> 4);
- 
- 	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
- 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
-diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c
-index 500ccfd..2b67f18 100644
---- a/drivers/gpu/drm/nouveau/nv40_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nv40_fifo.c
-@@ -48,7 +48,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
- 
- 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	nv_wi32(dev, fc +  0, chan->pushbuf_base);
- 	nv_wi32(dev, fc +  4, chan->pushbuf_base);
- 	nv_wi32(dev, fc + 12, chan->pushbuf->instance >> 4);
-@@ -61,7 +60,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan)
- 			      0x30000000 /* no idea.. */);
- 	nv_wi32(dev, fc + 56, chan->ramin_grctx->instance >> 4);
- 	nv_wi32(dev, fc + 60, 0x0001FFFF);
--	dev_priv->engine.instmem.finish_access(dev);
- 
- 	/* enable the fifo dma operation */
- 	nv_wr32(dev, NV04_PFIFO_MODE,
-@@ -89,8 +87,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	uint32_t fc = NV40_RAMFC(chid), tmp, tmp2;
- 
--	dev_priv->engine.instmem.prepare_access(dev, false);
--
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUT, nv_ri32(dev, fc + 0));
- 	nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_GET, nv_ri32(dev, fc + 4));
- 	nv_wr32(dev, NV10_PFIFO_CACHE1_REF_CNT, nv_ri32(dev, fc + 8));
-@@ -127,8 +123,6 @@ nv40_fifo_do_load_context(struct drm_device *dev, int chid)
- 	nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76));
- 	nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80));
- 
--	dev_priv->engine.instmem.finish_access(dev);
--
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
- }
-@@ -166,7 +160,6 @@ nv40_fifo_unload_context(struct drm_device *dev)
- 		return 0;
- 	fc = NV40_RAMFC(chid);
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	nv_wi32(dev, fc + 0, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUT));
- 	nv_wi32(dev, fc + 4, nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_GET));
- 	nv_wi32(dev, fc + 8, nv_rd32(dev, NV10_PFIFO_CACHE1_REF_CNT));
-@@ -200,7 +193,6 @@ nv40_fifo_unload_context(struct drm_device *dev)
- 	tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
- 	nv_wi32(dev, fc + 72, tmp);
- #endif
--	dev_priv->engine.instmem.finish_access(dev);
- 
- 	nv40_fifo_do_load_context(dev, pfifo->channels - 1);
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
-diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c
-index 704a25d..ef550ce 100644
---- a/drivers/gpu/drm/nouveau/nv40_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv40_graph.c
-@@ -58,6 +58,7 @@ nv40_graph_create_context(struct nouveau_channel *chan)
- 	struct drm_device *dev = chan->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-+	struct nouveau_grctx ctx = {};
- 	int ret;
- 
- 	ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size,
-@@ -67,20 +68,13 @@ nv40_graph_create_context(struct nouveau_channel *chan)
- 		return ret;
- 
- 	/* Initialise default context values */
--	dev_priv->engine.instmem.prepare_access(dev, true);
--	if (!pgraph->ctxprog) {
--		struct nouveau_grctx ctx = {};
--
--		ctx.dev = chan->dev;
--		ctx.mode = NOUVEAU_GRCTX_VALS;
--		ctx.data = chan->ramin_grctx->gpuobj;
--		nv40_grctx_init(&ctx);
--	} else {
--		nouveau_grctx_vals_load(dev, chan->ramin_grctx->gpuobj);
--	}
-+	ctx.dev = chan->dev;
-+	ctx.mode = NOUVEAU_GRCTX_VALS;
-+	ctx.data = chan->ramin_grctx->gpuobj;
-+	nv40_grctx_init(&ctx);
-+
- 	nv_wo32(dev, chan->ramin_grctx->gpuobj, 0,
- 		     chan->ramin_grctx->gpuobj->im_pramin->start);
--	dev_priv->engine.instmem.finish_access(dev);
- 	return 0;
- }
- 
-@@ -238,7 +232,8 @@ nv40_graph_init(struct drm_device *dev)
- 	struct drm_nouveau_private *dev_priv =
- 		(struct drm_nouveau_private *)dev->dev_private;
- 	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
--	uint32_t vramsz;
-+	struct nouveau_grctx ctx = {};
-+	uint32_t vramsz, *cp;
- 	int i, j;
- 
- 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
-@@ -246,32 +241,22 @@ nv40_graph_init(struct drm_device *dev)
- 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
- 			 NV_PMC_ENABLE_PGRAPH);
- 
--	if (nouveau_ctxfw) {
--		nouveau_grctx_prog_load(dev);
--		dev_priv->engine.graph.grctx_size = 175 * 1024;
--	}
-+	cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL);
-+	if (!cp)
-+		return -ENOMEM;
- 
--	if (!dev_priv->engine.graph.ctxprog) {
--		struct nouveau_grctx ctx = {};
--		uint32_t *cp;
-+	ctx.dev = dev;
-+	ctx.mode = NOUVEAU_GRCTX_PROG;
-+	ctx.data = cp;
-+	ctx.ctxprog_max = 256;
-+	nv40_grctx_init(&ctx);
-+	dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
- 
--		cp = kmalloc(sizeof(*cp) * 256, GFP_KERNEL);
--		if (!cp)
--			return -ENOMEM;
-+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
-+	for (i = 0; i < ctx.ctxprog_len; i++)
-+		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
- 
--		ctx.dev = dev;
--		ctx.mode = NOUVEAU_GRCTX_PROG;
--		ctx.data = cp;
--		ctx.ctxprog_max = 256;
--		nv40_grctx_init(&ctx);
--		dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
--
--		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
--		for (i = 0; i < ctx.ctxprog_len; i++)
--			nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
--
--		kfree(cp);
--	}
-+	kfree(cp);
- 
- 	/* No context present currently */
- 	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
-@@ -407,7 +392,6 @@ nv40_graph_init(struct drm_device *dev)
- 
- void nv40_graph_takedown(struct drm_device *dev)
- {
--	nouveau_grctx_fini(dev);
- }
- 
- struct nouveau_pgraph_object_class nv40_graph_grclass[] = {
-diff --git a/drivers/gpu/drm/nouveau/nv40_mc.c b/drivers/gpu/drm/nouveau/nv40_mc.c
-index 2a3495e..e4e72c1 100644
---- a/drivers/gpu/drm/nouveau/nv40_mc.c
-+++ b/drivers/gpu/drm/nouveau/nv40_mc.c
-@@ -19,7 +19,7 @@ nv40_mc_init(struct drm_device *dev)
- 	case 0x46: /* G72 */
- 	case 0x4e:
- 	case 0x4c: /* C51_G7X */
--		tmp = nv_rd32(dev, NV40_PFB_020C);
-+		tmp = nv_rd32(dev, NV04_PFB_FIFO_DATA);
- 		nv_wr32(dev, NV40_PMC_1700, tmp);
- 		nv_wr32(dev, NV40_PMC_1704, 0);
- 		nv_wr32(dev, NV40_PMC_1708, 0);
-diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
-index b4e4a3b..5d11ea1 100644
---- a/drivers/gpu/drm/nouveau/nv50_crtc.c
-+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
-@@ -440,47 +440,15 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
- {
- 	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
- 	struct drm_device *dev = crtc->dev;
--	struct drm_encoder *encoder;
--	uint32_t dac = 0, sor = 0;
- 
- 	NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
- 
--	/* Disconnect all unused encoders. */
--	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
--		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
--
--		if (!drm_helper_encoder_in_use(encoder))
--			continue;
--
--		if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
--		    nv_encoder->dcb->type == OUTPUT_TV)
--			dac |= (1 << nv_encoder->or);
--		else
--			sor |= (1 << nv_encoder->or);
--	}
--
--	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
--		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
--
--		if (nv_encoder->dcb->type == OUTPUT_ANALOG ||
--		    nv_encoder->dcb->type == OUTPUT_TV) {
--			if (dac & (1 << nv_encoder->or))
--				continue;
--		} else {
--			if (sor & (1 << nv_encoder->or))
--				continue;
--		}
--
--		nv_encoder->disconnect(nv_encoder);
--	}
--
- 	nv50_crtc_blank(nv_crtc, true);
- }
- 
- static void
- nv50_crtc_commit(struct drm_crtc *crtc)
- {
--	struct drm_crtc *crtc2;
- 	struct drm_device *dev = crtc->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_channel *evo = dev_priv->evo;
-@@ -491,20 +459,14 @@ nv50_crtc_commit(struct drm_crtc *crtc)
- 
- 	nv50_crtc_blank(nv_crtc, false);
- 
--	/* Explicitly blank all unused crtc's. */
--	list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) {
--		if (!drm_helper_crtc_in_use(crtc2))
--			nv50_crtc_blank(nouveau_crtc(crtc2), true);
--	}
--
- 	ret = RING_SPACE(evo, 2);
- 	if (ret) {
- 		NV_ERROR(dev, "no space while committing crtc\n");
- 		return;
- 	}
- 	BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
--	OUT_RING(evo, 0);
--	FIRE_RING(evo);
-+	OUT_RING  (evo, 0);
-+	FIRE_RING (evo);
- }
- 
- static bool
-diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c
-index 1fd9537..1bc0859 100644
---- a/drivers/gpu/drm/nouveau/nv50_dac.c
-+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
-@@ -37,22 +37,31 @@
- #include "nv50_display.h"
- 
- static void
--nv50_dac_disconnect(struct nouveau_encoder *nv_encoder)
-+nv50_dac_disconnect(struct drm_encoder *encoder)
- {
--	struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
-+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-+	struct drm_device *dev = encoder->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_channel *evo = dev_priv->evo;
- 	int ret;
- 
-+	if (!nv_encoder->crtc)
-+		return;
-+	nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
-+
- 	NV_DEBUG_KMS(dev, "Disconnecting DAC %d\n", nv_encoder->or);
- 
--	ret = RING_SPACE(evo, 2);
-+	ret = RING_SPACE(evo, 4);
- 	if (ret) {
- 		NV_ERROR(dev, "no space while disconnecting DAC\n");
- 		return;
- 	}
- 	BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 1);
--	OUT_RING(evo, 0);
-+	OUT_RING  (evo, 0);
-+	BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-+	OUT_RING  (evo, 0);
-+
-+	nv_encoder->crtc = NULL;
- }
- 
- static enum drm_connector_status
-@@ -213,7 +222,8 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
- 	uint32_t mode_ctl = 0, mode_ctl2 = 0;
- 	int ret;
- 
--	NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
-+	NV_DEBUG_KMS(dev, "or %d type %d crtc %d\n",
-+		     nv_encoder->or, nv_encoder->dcb->type, crtc->index);
- 
- 	nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
- 
-@@ -243,6 +253,14 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
- 	BEGIN_RING(evo, 0, NV50_EVO_DAC(nv_encoder->or, MODE_CTRL), 2);
- 	OUT_RING(evo, mode_ctl);
- 	OUT_RING(evo, mode_ctl2);
-+
-+	nv_encoder->crtc = encoder->crtc;
-+}
-+
-+static struct drm_crtc *
-+nv50_dac_crtc_get(struct drm_encoder *encoder)
-+{
-+	return nouveau_encoder(encoder)->crtc;
- }
- 
- static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
-@@ -253,7 +271,9 @@ static const struct drm_encoder_helper_funcs nv50_dac_helper_funcs = {
- 	.prepare = nv50_dac_prepare,
- 	.commit = nv50_dac_commit,
- 	.mode_set = nv50_dac_mode_set,
--	.detect = nv50_dac_detect
-+	.get_crtc = nv50_dac_crtc_get,
-+	.detect = nv50_dac_detect,
-+	.disable = nv50_dac_disconnect
- };
- 
- static void
-@@ -275,14 +295,11 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = {
- };
- 
- int
--nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
-+nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
- {
- 	struct nouveau_encoder *nv_encoder;
- 	struct drm_encoder *encoder;
- 
--	NV_DEBUG_KMS(dev, "\n");
--	NV_INFO(dev, "Detected a DAC output\n");
--
- 	nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
- 	if (!nv_encoder)
- 		return -ENOMEM;
-@@ -291,14 +308,14 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
- 	nv_encoder->dcb = entry;
- 	nv_encoder->or = ffs(entry->or) - 1;
- 
--	nv_encoder->disconnect = nv50_dac_disconnect;
--
--	drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs,
-+	drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs,
- 			 DRM_MODE_ENCODER_DAC);
- 	drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);
- 
- 	encoder->possible_crtcs = entry->heads;
- 	encoder->possible_clones = 0;
-+
-+	drm_mode_connector_attach_encoder(connector, encoder);
- 	return 0;
- }
- 
-diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
-index 580a5d1..c19ed8c 100644
---- a/drivers/gpu/drm/nouveau/nv50_display.c
-+++ b/drivers/gpu/drm/nouveau/nv50_display.c
-@@ -71,14 +71,13 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name,
- 		return ret;
- 	}
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	nv_wo32(dev, obj, 0, (tile_flags << 22) | (magic_flags << 16) | class);
- 	nv_wo32(dev, obj, 1, limit);
- 	nv_wo32(dev, obj, 2, offset);
- 	nv_wo32(dev, obj, 3, 0x00000000);
- 	nv_wo32(dev, obj, 4, 0x00000000);
- 	nv_wo32(dev, obj, 5, 0x00010000);
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	return 0;
- }
-@@ -110,8 +109,8 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
- 		return ret;
- 	}
- 
--	ret = nouveau_mem_init_heap(&chan->ramin_heap, chan->ramin->gpuobj->
--				    im_pramin->start, 32768);
-+	ret = drm_mm_init(&chan->ramin_heap,
-+			  chan->ramin->gpuobj->im_pramin->start, 32768);
- 	if (ret) {
- 		NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret);
- 		nv50_evo_channel_del(pchan);
-@@ -465,6 +464,7 @@ int nv50_display_create(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct dcb_table *dcb = &dev_priv->vbios.dcb;
-+	struct drm_connector *connector, *ct;
- 	int ret, i;
- 
- 	NV_DEBUG_KMS(dev, "\n");
-@@ -507,14 +507,18 @@ int nv50_display_create(struct drm_device *dev)
- 			continue;
- 		}
- 
-+		connector = nouveau_connector_create(dev, entry->connector);
-+		if (IS_ERR(connector))
-+			continue;
-+
- 		switch (entry->type) {
- 		case OUTPUT_TMDS:
- 		case OUTPUT_LVDS:
- 		case OUTPUT_DP:
--			nv50_sor_create(dev, entry);
-+			nv50_sor_create(connector, entry);
- 			break;
- 		case OUTPUT_ANALOG:
--			nv50_dac_create(dev, entry);
-+			nv50_dac_create(connector, entry);
- 			break;
- 		default:
- 			NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
-@@ -522,11 +526,13 @@ int nv50_display_create(struct drm_device *dev)
- 		}
- 	}
- 
--	for (i = 0 ; i < dcb->connector.entries; i++) {
--		if (i != 0 && dcb->connector.entry[i].index2 ==
--			      dcb->connector.entry[i - 1].index2)
--			continue;
--		nouveau_connector_create(dev, &dcb->connector.entry[i]);
-+	list_for_each_entry_safe(connector, ct,
-+				 &dev->mode_config.connector_list, head) {
-+		if (!connector->encoder_ids[0]) {
-+			NV_WARN(dev, "%s has no encoders, removing\n",
-+				drm_get_connector_name(connector));
-+			connector->funcs->destroy(connector);
-+		}
- 	}
- 
- 	ret = nv50_display_init(dev);
-@@ -552,131 +558,28 @@ int nv50_display_destroy(struct drm_device *dev)
- 	return 0;
- }
- 
--static inline uint32_t
--nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	uint32_t mc;
--
--	if (sor) {
--		if (dev_priv->chipset < 0x90 ||
--		    dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
--			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or));
--		else
--			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or));
--	} else {
--		mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or));
--	}
--
--	return mc;
--}
--
--static int
--nv50_display_irq_head(struct drm_device *dev, int *phead,
--		      struct dcb_entry **pdcbent)
--{
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL);
--	uint32_t dac = 0, sor = 0;
--	int head, i, or = 0, type = OUTPUT_ANY;
--
--	/* We're assuming that head 0 *or* head 1 will be active here,
--	 * and not both.  I'm not sure if the hw will even signal both
--	 * ever, but it definitely shouldn't for us as we commit each
--	 * CRTC separately, and submission will be blocked by the GPU
--	 * until we handle each in turn.
--	 */
--	NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
--	head = ffs((unk30 >> 9) & 3) - 1;
--	if (head < 0)
--		return -EINVAL;
--
--	/* This assumes CRTCs are never bound to multiple encoders, which
--	 * should be the case.
--	 */
--	for (i = 0; i < 3 && type == OUTPUT_ANY; i++) {
--		uint32_t mc = nv50_display_mode_ctrl(dev, false, i);
--		if (!(mc & (1 << head)))
--			continue;
--
--		switch ((mc >> 8) & 0xf) {
--		case 0: type = OUTPUT_ANALOG; break;
--		case 1: type = OUTPUT_TV; break;
--		default:
--			NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac);
--			return -1;
--		}
--
--		or = i;
--	}
--
--	for (i = 0; i < 4 && type == OUTPUT_ANY; i++) {
--		uint32_t mc = nv50_display_mode_ctrl(dev, true, i);
--		if (!(mc & (1 << head)))
--			continue;
--
--		switch ((mc >> 8) & 0xf) {
--		case 0: type = OUTPUT_LVDS; break;
--		case 1: type = OUTPUT_TMDS; break;
--		case 2: type = OUTPUT_TMDS; break;
--		case 5: type = OUTPUT_TMDS; break;
--		case 8: type = OUTPUT_DP; break;
--		case 9: type = OUTPUT_DP; break;
--		default:
--			NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor);
--			return -1;
--		}
--
--		or = i;
--	}
--
--	NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or);
--	if (type == OUTPUT_ANY) {
--		NV_ERROR(dev, "unknown encoder!!\n");
--		return -1;
--	}
--
--	for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
--		struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i];
--
--		if (dcbent->type != type)
--			continue;
--
--		if (!(dcbent->or & (1 << or)))
--			continue;
--
--		*phead = head;
--		*pdcbent = dcbent;
--		return 0;
--	}
--
--	NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or);
--	return 0;
--}
--
--static uint32_t
--nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent,
--			   int pxclk)
-+static u16
-+nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb,
-+			   u32 mc, int pxclk)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_connector *nv_connector = NULL;
- 	struct drm_encoder *encoder;
- 	struct nvbios *bios = &dev_priv->vbios;
--	uint32_t mc, script = 0, or;
-+	u32 script = 0, or;
- 
- 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- 		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
- 
--		if (nv_encoder->dcb != dcbent)
-+		if (nv_encoder->dcb != dcb)
- 			continue;
- 
- 		nv_connector = nouveau_encoder_connector_get(nv_encoder);
- 		break;
- 	}
- 
--	or = ffs(dcbent->or) - 1;
--	mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or);
--	switch (dcbent->type) {
-+	or = ffs(dcb->or) - 1;
-+	switch (dcb->type) {
- 	case OUTPUT_LVDS:
- 		script = (mc >> 8) & 0xf;
- 		if (bios->fp_no_ddc) {
-@@ -767,17 +670,88 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
- static void
- nv50_display_unk10_handler(struct drm_device *dev)
- {
--	struct dcb_entry *dcbent;
--	int head, ret;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	u32 unk30 = nv_rd32(dev, 0x610030), mc;
-+	int i, crtc, or, type = OUTPUT_ANY;
- 
--	ret = nv50_display_irq_head(dev, &head, &dcbent);
--	if (ret)
--		goto ack;
-+	NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-+	dev_priv->evo_irq.dcb = NULL;
- 
- 	nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8);
- 
--	nouveau_bios_run_display_table(dev, dcbent, 0, -1);
-+	/* Determine which CRTC we're dealing with, only 1 ever will be
-+	 * signalled at the same time with the current nouveau code.
-+	 */
-+	crtc = ffs((unk30 & 0x00000060) >> 5) - 1;
-+	if (crtc < 0)
-+		goto ack;
-+
-+	/* Nothing needs to be done for the encoder */
-+	crtc = ffs((unk30 & 0x00000180) >> 7) - 1;
-+	if (crtc < 0)
-+		goto ack;
-+
-+	/* Find which encoder was connected to the CRTC */
-+	for (i = 0; type == OUTPUT_ANY && i < 3; i++) {
-+		mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i));
-+		NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc);
-+		if (!(mc & (1 << crtc)))
-+			continue;
-+
-+		switch ((mc & 0x00000f00) >> 8) {
-+		case 0: type = OUTPUT_ANALOG; break;
-+		case 1: type = OUTPUT_TV; break;
-+		default:
-+			NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
-+			goto ack;
-+		}
-+
-+		or = i;
-+	}
-+
-+	for (i = 0; type == OUTPUT_ANY && i < 4; i++) {
-+		if (dev_priv->chipset  < 0x90 ||
-+		    dev_priv->chipset == 0x92 ||
-+		    dev_priv->chipset == 0xa0)
-+			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i));
-+		else
-+			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i));
- 
-+		NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc);
-+		if (!(mc & (1 << crtc)))
-+			continue;
-+
-+		switch ((mc & 0x00000f00) >> 8) {
-+		case 0: type = OUTPUT_LVDS; break;
-+		case 1: type = OUTPUT_TMDS; break;
-+		case 2: type = OUTPUT_TMDS; break;
-+		case 5: type = OUTPUT_TMDS; break;
-+		case 8: type = OUTPUT_DP; break;
-+		case 9: type = OUTPUT_DP; break;
-+		default:
-+			NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
-+			goto ack;
-+		}
-+
-+		or = i;
-+	}
-+
-+	/* There was no encoder to disable */
-+	if (type == OUTPUT_ANY)
-+		goto ack;
-+
-+	/* Disable the encoder */
-+	for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
-+		struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i];
-+
-+		if (dcb->type == type && (dcb->or & (1 << or))) {
-+			nouveau_bios_run_display_table(dev, dcb, 0, -1);
-+			dev_priv->evo_irq.dcb = dcb;
-+			goto ack;
-+		}
-+	}
-+
-+	NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc);
- ack:
- 	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10);
- 	nv_wr32(dev, 0x610030, 0x80000000);
-@@ -817,33 +791,103 @@ nv50_display_unk20_dp_hack(struct drm_device *dev, struct dcb_entry *dcb)
- static void
- nv50_display_unk20_handler(struct drm_device *dev)
- {
--	struct dcb_entry *dcbent;
--	uint32_t tmp, pclk, script;
--	int head, or, ret;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc;
-+	struct dcb_entry *dcb;
-+	int i, crtc, or, type = OUTPUT_ANY;
- 
--	ret = nv50_display_irq_head(dev, &head, &dcbent);
--	if (ret)
-+	NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-+	dcb = dev_priv->evo_irq.dcb;
-+	if (dcb) {
-+		nouveau_bios_run_display_table(dev, dcb, 0, -2);
-+		dev_priv->evo_irq.dcb = NULL;
-+	}
-+
-+	/* CRTC clock change requested? */
-+	crtc = ffs((unk30 & 0x00000600) >> 9) - 1;
-+	if (crtc >= 0) {
-+		pclk  = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK));
-+		pclk &= 0x003fffff;
-+
-+		nv50_crtc_set_clock(dev, crtc, pclk);
-+
-+		tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc));
-+		tmp &= ~0x000000f;
-+		nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp);
-+	}
-+
-+	/* Nothing needs to be done for the encoder */
-+	crtc = ffs((unk30 & 0x00000180) >> 7) - 1;
-+	if (crtc < 0)
- 		goto ack;
--	or = ffs(dcbent->or) - 1;
--	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
--	script = nv50_display_script_select(dev, dcbent, pclk);
-+	pclk  = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff;
- 
--	NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk);
-+	/* Find which encoder is connected to the CRTC */
-+	for (i = 0; type == OUTPUT_ANY && i < 3; i++) {
-+		mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i));
-+		NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc);
-+		if (!(mc & (1 << crtc)))
-+			continue;
- 
--	if (dcbent->type != OUTPUT_DP)
--		nouveau_bios_run_display_table(dev, dcbent, 0, -2);
-+		switch ((mc & 0x00000f00) >> 8) {
-+		case 0: type = OUTPUT_ANALOG; break;
-+		case 1: type = OUTPUT_TV; break;
-+		default:
-+			NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc);
-+			goto ack;
-+		}
- 
--	nv50_crtc_set_clock(dev, head, pclk);
-+		or = i;
-+	}
- 
--	nouveau_bios_run_display_table(dev, dcbent, script, pclk);
-+	for (i = 0; type == OUTPUT_ANY && i < 4; i++) {
-+		if (dev_priv->chipset  < 0x90 ||
-+		    dev_priv->chipset == 0x92 ||
-+		    dev_priv->chipset == 0xa0)
-+			mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i));
-+		else
-+			mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i));
- 
--	nv50_display_unk20_dp_hack(dev, dcbent);
-+		NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc);
-+		if (!(mc & (1 << crtc)))
-+			continue;
- 
--	tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head));
--	tmp &= ~0x000000f;
--	nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp);
-+		switch ((mc & 0x00000f00) >> 8) {
-+		case 0: type = OUTPUT_LVDS; break;
-+		case 1: type = OUTPUT_TMDS; break;
-+		case 2: type = OUTPUT_TMDS; break;
-+		case 5: type = OUTPUT_TMDS; break;
-+		case 8: type = OUTPUT_DP; break;
-+		case 9: type = OUTPUT_DP; break;
-+		default:
-+			NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc);
-+			goto ack;
-+		}
-+
-+		or = i;
-+	}
-+
-+	if (type == OUTPUT_ANY)
-+		goto ack;
-+
-+	/* Enable the encoder */
-+	for (i = 0; i < dev_priv->vbios.dcb.entries; i++) {
-+		dcb = &dev_priv->vbios.dcb.entry[i];
-+		if (dcb->type == type && (dcb->or & (1 << or)))
-+			break;
-+	}
-+
-+	if (i == dev_priv->vbios.dcb.entries) {
-+		NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc);
-+		goto ack;
-+	}
-+
-+	script = nv50_display_script_select(dev, dcb, mc, pclk);
-+	nouveau_bios_run_display_table(dev, dcb, script, pclk);
-+
-+	nv50_display_unk20_dp_hack(dev, dcb);
- 
--	if (dcbent->type != OUTPUT_ANALOG) {
-+	if (dcb->type != OUTPUT_ANALOG) {
- 		tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or));
- 		tmp &= ~0x00000f0f;
- 		if (script & 0x0100)
-@@ -853,24 +897,61 @@ nv50_display_unk20_handler(struct drm_device *dev)
- 		nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0);
- 	}
- 
-+	dev_priv->evo_irq.dcb = dcb;
-+	dev_priv->evo_irq.pclk = pclk;
-+	dev_priv->evo_irq.script = script;
-+
- ack:
- 	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20);
- 	nv_wr32(dev, 0x610030, 0x80000000);
- }
- 
-+/* If programming a TMDS output on a SOR that can also be configured for
-+ * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
-+ *
-+ * It looks like the VBIOS TMDS scripts make an attempt at this, however,
-+ * the VBIOS scripts on at least one board I have only switch it off on
-+ * link 0, causing a blank display if the output has previously been
-+ * programmed for DisplayPort.
-+ */
-+static void
-+nv50_display_unk40_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb)
-+{
-+	int or = ffs(dcb->or) - 1, link = !(dcb->dpconf.sor.link & 1);
-+	struct drm_encoder *encoder;
-+	u32 tmp;
-+
-+	if (dcb->type != OUTPUT_TMDS)
-+		return;
-+
-+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-+		struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-+
-+		if (nv_encoder->dcb->type == OUTPUT_DP &&
-+		    nv_encoder->dcb->or & (1 << or)) {
-+			tmp  = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
-+			tmp &= ~NV50_SOR_DP_CTRL_ENABLED;
-+			nv_wr32(dev, NV50_SOR_DP_CTRL(or, link), tmp);
-+			break;
-+		}
-+	}
-+}
-+
- static void
- nv50_display_unk40_handler(struct drm_device *dev)
- {
--	struct dcb_entry *dcbent;
--	int head, pclk, script, ret;
-+	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct dcb_entry *dcb = dev_priv->evo_irq.dcb;
-+	u16 script = dev_priv->evo_irq.script;
-+	u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk;
- 
--	ret = nv50_display_irq_head(dev, &head, &dcbent);
--	if (ret)
-+	NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
-+	dev_priv->evo_irq.dcb = NULL;
-+	if (!dcb)
- 		goto ack;
--	pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff;
--	script = nv50_display_script_select(dev, dcbent, pclk);
- 
--	nouveau_bios_run_display_table(dev, dcbent, script, -pclk);
-+	nouveau_bios_run_display_table(dev, dcb, script, -pclk);
-+	nv50_display_unk40_dp_set_tmds(dev, dcb);
- 
- ack:
- 	nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40);
-diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
-index e20c0e2..fb0281a 100644
---- a/drivers/gpu/drm/nouveau/nv50_fifo.c
-+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
-@@ -28,41 +28,33 @@
- #include "drm.h"
- #include "nouveau_drv.h"
- 
--struct nv50_fifo_priv {
--	struct nouveau_gpuobj_ref *thingo[2];
--	int cur_thingo;
--};
--
--#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
--
- static void
--nv50_fifo_init_thingo(struct drm_device *dev)
-+nv50_fifo_playlist_update(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
-+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
- 	struct nouveau_gpuobj_ref *cur;
- 	int i, nr;
- 
- 	NV_DEBUG(dev, "\n");
- 
--	cur = priv->thingo[priv->cur_thingo];
--	priv->cur_thingo = !priv->cur_thingo;
-+	cur = pfifo->playlist[pfifo->cur_playlist];
-+	pfifo->cur_playlist = !pfifo->cur_playlist;
- 
- 	/* We never schedule channel 0 or 127 */
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	for (i = 1, nr = 0; i < 127; i++) {
- 		if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc)
- 			nv_wo32(dev, cur->gpuobj, nr++, i);
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	nv_wr32(dev, 0x32f4, cur->instance >> 12);
- 	nv_wr32(dev, 0x32ec, nr);
- 	nv_wr32(dev, 0x2500, 0x101);
- }
- 
--static int
--nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt)
-+static void
-+nv50_fifo_channel_enable(struct drm_device *dev, int channel)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_channel *chan = dev_priv->fifos[channel];
-@@ -70,37 +62,28 @@ nv50_fifo_channel_enable(struct drm_device *dev, int channel, bool nt)
- 
- 	NV_DEBUG(dev, "ch%d\n", channel);
- 
--	if (!chan->ramfc)
--		return -EINVAL;
--
--	if (IS_G80)
-+	if (dev_priv->chipset == 0x50)
- 		inst = chan->ramfc->instance >> 12;
- 	else
- 		inst = chan->ramfc->instance >> 8;
--	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel),
--		 inst | NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
- 
--	if (!nt)
--		nv50_fifo_init_thingo(dev);
--	return 0;
-+	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst |
-+		     NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED);
- }
- 
- static void
--nv50_fifo_channel_disable(struct drm_device *dev, int channel, bool nt)
-+nv50_fifo_channel_disable(struct drm_device *dev, int channel)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	uint32_t inst;
- 
--	NV_DEBUG(dev, "ch%d, nt=%d\n", channel, nt);
-+	NV_DEBUG(dev, "ch%d\n", channel);
- 
--	if (IS_G80)
-+	if (dev_priv->chipset == 0x50)
- 		inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80;
- 	else
- 		inst = NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84;
- 	nv_wr32(dev, NV50_PFIFO_CTX_TABLE(channel), inst);
--
--	if (!nt)
--		nv50_fifo_init_thingo(dev);
- }
- 
- static void
-@@ -133,12 +116,12 @@ nv50_fifo_init_context_table(struct drm_device *dev)
- 
- 	for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) {
- 		if (dev_priv->fifos[i])
--			nv50_fifo_channel_enable(dev, i, true);
-+			nv50_fifo_channel_enable(dev, i);
- 		else
--			nv50_fifo_channel_disable(dev, i, true);
-+			nv50_fifo_channel_disable(dev, i);
- 	}
- 
--	nv50_fifo_init_thingo(dev);
-+	nv50_fifo_playlist_update(dev);
- }
- 
- static void
-@@ -162,41 +145,38 @@ nv50_fifo_init_regs(struct drm_device *dev)
- 	nv_wr32(dev, 0x3270, 0);
- 
- 	/* Enable dummy channels setup by nv50_instmem.c */
--	nv50_fifo_channel_enable(dev, 0, true);
--	nv50_fifo_channel_enable(dev, 127, true);
-+	nv50_fifo_channel_enable(dev, 0);
-+	nv50_fifo_channel_enable(dev, 127);
- }
- 
- int
- nv50_fifo_init(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nv50_fifo_priv *priv;
-+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
- 	int ret;
- 
- 	NV_DEBUG(dev, "\n");
- 
--	priv = dev_priv->engine.fifo.priv;
--	if (priv) {
--		priv->cur_thingo = !priv->cur_thingo;
-+	if (pfifo->playlist[0]) {
-+		pfifo->cur_playlist = !pfifo->cur_playlist;
- 		goto just_reset;
- 	}
- 
--	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
--	if (!priv)
--		return -ENOMEM;
--	dev_priv->engine.fifo.priv = priv;
--
- 	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
--				     NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]);
-+				     NVOBJ_FLAG_ZERO_ALLOC,
-+				     &pfifo->playlist[0]);
- 	if (ret) {
--		NV_ERROR(dev, "error creating thingo0: %d\n", ret);
-+		NV_ERROR(dev, "error creating playlist 0: %d\n", ret);
- 		return ret;
- 	}
- 
- 	ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
--				     NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]);
-+				     NVOBJ_FLAG_ZERO_ALLOC,
-+				     &pfifo->playlist[1]);
- 	if (ret) {
--		NV_ERROR(dev, "error creating thingo1: %d\n", ret);
-+		nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]);
-+		NV_ERROR(dev, "error creating playlist 1: %d\n", ret);
- 		return ret;
- 	}
- 
-@@ -216,18 +196,15 @@ void
- nv50_fifo_takedown(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nv50_fifo_priv *priv = dev_priv->engine.fifo.priv;
-+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
- 
- 	NV_DEBUG(dev, "\n");
- 
--	if (!priv)
-+	if (!pfifo->playlist[0])
- 		return;
- 
--	nouveau_gpuobj_ref_del(dev, &priv->thingo[0]);
--	nouveau_gpuobj_ref_del(dev, &priv->thingo[1]);
--
--	dev_priv->engine.fifo.priv = NULL;
--	kfree(priv);
-+	nouveau_gpuobj_ref_del(dev, &pfifo->playlist[0]);
-+	nouveau_gpuobj_ref_del(dev, &pfifo->playlist[1]);
- }
- 
- int
-@@ -248,7 +225,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
- 
- 	NV_DEBUG(dev, "ch%d\n", chan->id);
- 
--	if (IS_G80) {
-+	if (dev_priv->chipset == 0x50) {
- 		uint32_t ramin_poffset = chan->ramin->gpuobj->im_pramin->start;
- 		uint32_t ramin_voffset = chan->ramin->gpuobj->im_backing_start;
- 
-@@ -281,10 +258,10 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
- 
- 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
--
- 	nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4);
--	nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4));
-+	nv_wo32(dev, ramfc, 0x80/4, (0 << 27) /* 4KiB */ |
-+				    (4 << 24) /* SEARCH_FULL */ |
-+				    (chan->ramht->instance >> 4));
- 	nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff);
- 	nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff);
- 	nv_wo32(dev, ramfc, 0x40/4, 0x00000000);
-@@ -295,7 +272,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
- 				    chan->dma.ib_base * 4);
- 	nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16);
- 
--	if (!IS_G80) {
-+	if (dev_priv->chipset != 0x50) {
- 		nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id);
- 		nv_wo32(dev, chan->ramin->gpuobj, 1,
- 						chan->ramfc->instance >> 8);
-@@ -304,16 +281,10 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
- 		nv_wo32(dev, ramfc, 0x98/4, chan->ramin->instance >> 12);
- 	}
- 
--	dev_priv->engine.instmem.finish_access(dev);
--
--	ret = nv50_fifo_channel_enable(dev, chan->id, false);
--	if (ret) {
--		NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret);
--		spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
--		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
--		return ret;
--	}
-+	dev_priv->engine.instmem.flush(dev);
- 
-+	nv50_fifo_channel_enable(dev, chan->id);
-+	nv50_fifo_playlist_update(dev);
- 	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
- 	return 0;
- }
-@@ -328,11 +299,12 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan)
- 
- 	/* This will ensure the channel is seen as disabled. */
- 	chan->ramfc = NULL;
--	nv50_fifo_channel_disable(dev, chan->id, false);
-+	nv50_fifo_channel_disable(dev, chan->id);
- 
- 	/* Dummy channel, also used on ch 127 */
- 	if (chan->id == 0)
--		nv50_fifo_channel_disable(dev, 127, false);
-+		nv50_fifo_channel_disable(dev, 127);
-+	nv50_fifo_playlist_update(dev);
- 
- 	nouveau_gpuobj_ref_del(dev, &ramfc);
- 	nouveau_gpuobj_ref_del(dev, &chan->cache);
-@@ -349,8 +321,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
- 
- 	NV_DEBUG(dev, "ch%d\n", chan->id);
- 
--	dev_priv->engine.instmem.prepare_access(dev, false);
--
- 	nv_wr32(dev, 0x3330, nv_ro32(dev, ramfc, 0x00/4));
- 	nv_wr32(dev, 0x3334, nv_ro32(dev, ramfc, 0x04/4));
- 	nv_wr32(dev, 0x3240, nv_ro32(dev, ramfc, 0x08/4));
-@@ -396,7 +366,7 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
- 
- 	/* guessing that all the 0x34xx regs aren't on NV50 */
--	if (!IS_G80) {
-+	if (dev_priv->chipset != 0x50) {
- 		nv_wr32(dev, 0x340c, nv_ro32(dev, ramfc, 0x88/4));
- 		nv_wr32(dev, 0x3400, nv_ro32(dev, ramfc, 0x8c/4));
- 		nv_wr32(dev, 0x3404, nv_ro32(dev, ramfc, 0x90/4));
-@@ -404,8 +374,6 @@ nv50_fifo_load_context(struct nouveau_channel *chan)
- 		nv_wr32(dev, 0x3410, nv_ro32(dev, ramfc, 0x98/4));
- 	}
- 
--	dev_priv->engine.instmem.finish_access(dev);
--
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, chan->id | (1<<16));
- 	return 0;
- }
-@@ -434,8 +402,6 @@ nv50_fifo_unload_context(struct drm_device *dev)
- 	ramfc = chan->ramfc->gpuobj;
- 	cache = chan->cache->gpuobj;
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
--
- 	nv_wo32(dev, ramfc, 0x00/4, nv_rd32(dev, 0x3330));
- 	nv_wo32(dev, ramfc, 0x04/4, nv_rd32(dev, 0x3334));
- 	nv_wo32(dev, ramfc, 0x08/4, nv_rd32(dev, 0x3240));
-@@ -482,7 +448,7 @@ nv50_fifo_unload_context(struct drm_device *dev)
- 	}
- 
- 	/* guessing that all the 0x34xx regs aren't on NV50 */
--	if (!IS_G80) {
-+	if (dev_priv->chipset != 0x50) {
- 		nv_wo32(dev, ramfc, 0x84/4, ptr >> 1);
- 		nv_wo32(dev, ramfc, 0x88/4, nv_rd32(dev, 0x340c));
- 		nv_wo32(dev, ramfc, 0x8c/4, nv_rd32(dev, 0x3400));
-@@ -491,7 +457,7 @@ nv50_fifo_unload_context(struct drm_device *dev)
- 		nv_wo32(dev, ramfc, 0x98/4, nv_rd32(dev, 0x3410));
- 	}
- 
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	/*XXX: probably reload ch127 (NULL) state back too */
- 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1, 127);
-diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
-index b203d06..1413028 100644
---- a/drivers/gpu/drm/nouveau/nv50_graph.c
-+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
-@@ -30,8 +30,6 @@
- 
- #include "nouveau_grctx.h"
- 
--#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
--
- static void
- nv50_graph_init_reset(struct drm_device *dev)
- {
-@@ -103,37 +101,33 @@ static int
- nv50_graph_init_ctxctl(struct drm_device *dev)
- {
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-+	struct nouveau_grctx ctx = {};
-+	uint32_t *cp;
-+	int i;
- 
- 	NV_DEBUG(dev, "\n");
- 
--	if (nouveau_ctxfw) {
--		nouveau_grctx_prog_load(dev);
--		dev_priv->engine.graph.grctx_size = 0x70000;
-+	cp = kmalloc(512 * 4, GFP_KERNEL);
-+	if (!cp) {
-+		NV_ERROR(dev, "failed to allocate ctxprog\n");
-+		dev_priv->engine.graph.accel_blocked = true;
-+		return 0;
- 	}
--	if (!dev_priv->engine.graph.ctxprog) {
--		struct nouveau_grctx ctx = {};
--		uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL);
--		int i;
--		if (!cp) {
--			NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n");
--			dev_priv->engine.graph.accel_blocked = true;
--			return 0;
--		}
--		ctx.dev = dev;
--		ctx.mode = NOUVEAU_GRCTX_PROG;
--		ctx.data = cp;
--		ctx.ctxprog_max = 512;
--		if (!nv50_grctx_init(&ctx)) {
--			dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
--
--			nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
--			for (i = 0; i < ctx.ctxprog_len; i++)
--				nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
--		} else {
--			dev_priv->engine.graph.accel_blocked = true;
--		}
--		kfree(cp);
-+
-+	ctx.dev = dev;
-+	ctx.mode = NOUVEAU_GRCTX_PROG;
-+	ctx.data = cp;
-+	ctx.ctxprog_max = 512;
-+	if (!nv50_grctx_init(&ctx)) {
-+		dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
-+
-+		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
-+		for (i = 0; i < ctx.ctxprog_len; i++)
-+			nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]);
-+	} else {
-+		dev_priv->engine.graph.accel_blocked = true;
- 	}
-+	kfree(cp);
- 
- 	nv_wr32(dev, 0x400320, 4);
- 	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0);
-@@ -164,7 +158,6 @@ void
- nv50_graph_takedown(struct drm_device *dev)
- {
- 	NV_DEBUG(dev, "\n");
--	nouveau_grctx_fini(dev);
- }
- 
- void
-@@ -212,8 +205,9 @@ nv50_graph_create_context(struct nouveau_channel *chan)
- 	struct drm_device *dev = chan->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_gpuobj *ramin = chan->ramin->gpuobj;
--	struct nouveau_gpuobj *ctx;
-+	struct nouveau_gpuobj *obj;
- 	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-+	struct nouveau_grctx ctx = {};
- 	int hdr, ret;
- 
- 	NV_DEBUG(dev, "ch%d\n", chan->id);
-@@ -223,10 +217,9 @@ nv50_graph_create_context(struct nouveau_channel *chan)
- 				     NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
- 	if (ret)
- 		return ret;
--	ctx = chan->ramin_grctx->gpuobj;
-+	obj = chan->ramin_grctx->gpuobj;
- 
--	hdr = IS_G80 ? 0x200 : 0x20;
--	dev_priv->engine.instmem.prepare_access(dev, true);
-+	hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
- 	nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002);
- 	nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance +
- 					   pgraph->grctx_size - 1);
-@@ -234,21 +227,15 @@ nv50_graph_create_context(struct nouveau_channel *chan)
- 	nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0);
- 	nv_wo32(dev, ramin, (hdr + 0x10)/4, 0);
- 	nv_wo32(dev, ramin, (hdr + 0x14)/4, 0x00010000);
--	dev_priv->engine.instmem.finish_access(dev);
--
--	dev_priv->engine.instmem.prepare_access(dev, true);
--	if (!pgraph->ctxprog) {
--		struct nouveau_grctx ctx = {};
--		ctx.dev = chan->dev;
--		ctx.mode = NOUVEAU_GRCTX_VALS;
--		ctx.data = chan->ramin_grctx->gpuobj;
--		nv50_grctx_init(&ctx);
--	} else {
--		nouveau_grctx_vals_load(dev, ctx);
--	}
--	nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
--	dev_priv->engine.instmem.finish_access(dev);
- 
-+	ctx.dev = chan->dev;
-+	ctx.mode = NOUVEAU_GRCTX_VALS;
-+	ctx.data = obj;
-+	nv50_grctx_init(&ctx);
-+
-+	nv_wo32(dev, obj, 0x00000/4, chan->ramin->instance >> 12);
-+
-+	dev_priv->engine.instmem.flush(dev);
- 	return 0;
- }
- 
-@@ -257,17 +244,16 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
- {
- 	struct drm_device *dev = chan->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	int i, hdr = IS_G80 ? 0x200 : 0x20;
-+	int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
- 
- 	NV_DEBUG(dev, "ch%d\n", chan->id);
- 
- 	if (!chan->ramin || !chan->ramin->gpuobj)
- 		return;
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	for (i = hdr; i < hdr + 24; i += 4)
- 		nv_wo32(dev, chan->ramin->gpuobj, i/4, 0);
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	nouveau_gpuobj_ref_del(dev, &chan->ramin_grctx);
- }
-diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
-index 5f21df3..b7ad258 100644
---- a/drivers/gpu/drm/nouveau/nv50_instmem.c
-+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
-@@ -35,8 +35,6 @@ struct nv50_instmem_priv {
- 	struct nouveau_gpuobj_ref *pramin_pt;
- 	struct nouveau_gpuobj_ref *pramin_bar;
- 	struct nouveau_gpuobj_ref *fb_bar;
--
--	bool last_access_wr;
- };
- 
- #define NV50_INSTMEM_PAGE_SHIFT 12
-@@ -147,7 +145,7 @@ nv50_instmem_init(struct drm_device *dev)
- 	if (ret)
- 		return ret;
- 
--	if (nouveau_mem_init_heap(&chan->ramin_heap, c_base, c_size - c_base))
-+	if (drm_mm_init(&chan->ramin_heap, c_base, c_size - c_base))
- 		return -ENOMEM;
- 
- 	/* RAMFC + zero channel's PRAMIN up to start of VM pagedir */
-@@ -262,23 +260,18 @@ nv50_instmem_init(struct drm_device *dev)
- 
- 	/* Assume that praying isn't enough, check that we can re-read the
- 	 * entire fake channel back from the PRAMIN BAR */
--	dev_priv->engine.instmem.prepare_access(dev, false);
- 	for (i = 0; i < c_size; i += 4) {
- 		if (nv_rd32(dev, NV_RAMIN + i) != nv_ri32(dev, i)) {
- 			NV_ERROR(dev, "Error reading back PRAMIN at 0x%08x\n",
- 									i);
--			dev_priv->engine.instmem.finish_access(dev);
- 			return -EINVAL;
- 		}
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
- 
- 	nv_wr32(dev, NV50_PUNK_BAR0_PRAMIN, save_nv001700);
- 
- 	/* Global PRAMIN heap */
--	if (nouveau_mem_init_heap(&dev_priv->ramin_heap,
--				  c_size, dev_priv->ramin_size - c_size)) {
--		dev_priv->ramin_heap = NULL;
-+	if (drm_mm_init(&dev_priv->ramin_heap, c_size, dev_priv->ramin_size - c_size)) {
- 		NV_ERROR(dev, "Failed to init RAMIN heap\n");
- 	}
- 
-@@ -321,7 +314,7 @@ nv50_instmem_takedown(struct drm_device *dev)
- 		nouveau_gpuobj_del(dev, &chan->vm_pd);
- 		nouveau_gpuobj_ref_del(dev, &chan->ramfc);
- 		nouveau_gpuobj_ref_del(dev, &chan->ramin);
--		nouveau_mem_takedown(&chan->ramin_heap);
-+		drm_mm_takedown(&chan->ramin_heap);
- 
- 		dev_priv->fifos[0] = dev_priv->fifos[127] = NULL;
- 		kfree(chan);
-@@ -436,14 +429,14 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
- 	if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
- 		return -EINVAL;
- 
--	NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n",
-+	NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n",
- 		 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
- 
- 	pte     = (gpuobj->im_pramin->start >> 12) << 1;
- 	pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
- 	vram    = gpuobj->im_backing_start;
- 
--	NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n",
-+	NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n",
- 		 gpuobj->im_pramin->start, pte, pte_end);
- 	NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start);
- 
-@@ -453,27 +446,15 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
- 		vram |= 0x30;
- 	}
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	while (pte < pte_end) {
- 		nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram));
- 		nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram));
- 		vram += NV50_INSTMEM_PAGE_SIZE;
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
--
--	nv_wr32(dev, 0x100c80, 0x00040001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (1)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return -EBUSY;
--	}
-+	dev_priv->engine.instmem.flush(dev);
- 
--	nv_wr32(dev, 0x100c80, 0x00060001);
--	if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
--		NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
--		NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
--		return -EBUSY;
--	}
-+	nv50_vm_flush(dev, 4);
-+	nv50_vm_flush(dev, 6);
- 
- 	gpuobj->im_bound = 1;
- 	return 0;
-@@ -492,36 +473,36 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
- 	pte     = (gpuobj->im_pramin->start >> 12) << 1;
- 	pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
- 
--	dev_priv->engine.instmem.prepare_access(dev, true);
- 	while (pte < pte_end) {
- 		nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
- 		nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
- 	}
--	dev_priv->engine.instmem.finish_access(dev);
-+	dev_priv->engine.instmem.flush(dev);
- 
- 	gpuobj->im_bound = 0;
- 	return 0;
- }
- 
- void
--nv50_instmem_prepare_access(struct drm_device *dev, bool write)
-+nv50_instmem_flush(struct drm_device *dev)
- {
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
--
--	priv->last_access_wr = write;
-+	nv_wr32(dev, 0x00330c, 0x00000001);
-+	if (!nv_wait(0x00330c, 0x00000001, 0x00000000))
-+		NV_ERROR(dev, "PRAMIN flush timeout\n");
- }
- 
- void
--nv50_instmem_finish_access(struct drm_device *dev)
-+nv84_instmem_flush(struct drm_device *dev)
- {
--	struct drm_nouveau_private *dev_priv = dev->dev_private;
--	struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
--
--	if (priv->last_access_wr) {
--		nv_wr32(dev, 0x070000, 0x00000001);
--		if (!nv_wait(0x070000, 0x00000001, 0x00000000))
--			NV_ERROR(dev, "PRAMIN flush timeout\n");
--	}
-+	nv_wr32(dev, 0x070000, 0x00000001);
-+	if (!nv_wait(0x070000, 0x00000001, 0x00000000))
-+		NV_ERROR(dev, "PRAMIN flush timeout\n");
- }
- 
-+void
-+nv50_vm_flush(struct drm_device *dev, int engine)
-+{
-+	nv_wr32(dev, 0x100c80, (engine << 16) | 1);
-+	if (!nv_wait(0x100c80, 0x00000001, 0x00000000))
-+		NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
-+}
-diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
-index 812778d..bcd4cf8 100644
---- a/drivers/gpu/drm/nouveau/nv50_sor.c
-+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
-@@ -37,52 +37,32 @@
- #include "nv50_display.h"
- 
- static void
--nv50_sor_disconnect(struct nouveau_encoder *nv_encoder)
-+nv50_sor_disconnect(struct drm_encoder *encoder)
- {
--	struct drm_device *dev = to_drm_encoder(nv_encoder)->dev;
-+	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-+	struct drm_device *dev = encoder->dev;
- 	struct drm_nouveau_private *dev_priv = dev->dev_private;
- 	struct nouveau_channel *evo = dev_priv->evo;
- 	int ret;
- 
-+	if (!nv_encoder->crtc)
-+		return;
-+	nv50_crtc_blank(nouveau_crtc(nv_encoder->crtc), true);
-+
- 	NV_DEBUG_KMS(dev, "Disconnecting SOR %d\n", nv_encoder->or);
- 
--	ret = RING_SPACE(evo, 2);
-+	ret = RING_SPACE(evo, 4);
- 	if (ret) {
- 		NV_ERROR(dev, "no space while disconnecting SOR\n");
- 		return;
- 	}
- 	BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
--	OUT_RING(evo, 0);
--}
--
--static void
--nv50_sor_dp_link_train(struct drm_encoder *encoder)
--{
--	struct drm_device *dev = encoder->dev;
--	struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
--	struct bit_displayport_encoder_table *dpe;
--	int dpe_headerlen;
--
--	dpe = nouveau_bios_dp_table(dev, nv_encoder->dcb, &dpe_headerlen);
--	if (!dpe) {
--		NV_ERROR(dev, "SOR-%d: no DP encoder table!\n", nv_encoder->or);
--		return;
--	}
-+	OUT_RING  (evo, 0);
-+	BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1);
-+	OUT_RING  (evo, 0);
- 
--	if (dpe->script0) {
--		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or);
--		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script0),
--					    nv_encoder->dcb);
--	}
--
--	if (!nouveau_dp_link_train(encoder))
--		NV_ERROR(dev, "SOR-%d: link training failed\n", nv_encoder->or);
--
--	if (dpe->script1) {
--		NV_DEBUG_KMS(dev, "SOR-%d: running DP script 1\n", nv_encoder->or);
--		nouveau_bios_run_init_table(dev, le16_to_cpu(dpe->script1),
--					    nv_encoder->dcb);
--	}
-+	nv_encoder->crtc = NULL;
-+	nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
- }
- 
- static void
-@@ -94,14 +74,16 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
- 	uint32_t val;
- 	int or = nv_encoder->or;
- 
--	NV_DEBUG_KMS(dev, "or %d mode %d\n", or, mode);
-+	NV_DEBUG_KMS(dev, "or %d type %d mode %d\n", or, nv_encoder->dcb->type, mode);
- 
- 	nv_encoder->last_dpms = mode;
- 	list_for_each_entry(enc, &dev->mode_config.encoder_list, head) {
- 		struct nouveau_encoder *nvenc = nouveau_encoder(enc);
- 
- 		if (nvenc == nv_encoder ||
--		    nvenc->disconnect != nv50_sor_disconnect ||
-+		    (nvenc->dcb->type != OUTPUT_TMDS &&
-+		     nvenc->dcb->type != OUTPUT_LVDS &&
-+		     nvenc->dcb->type != OUTPUT_DP) ||
- 		    nvenc->dcb->or != nv_encoder->dcb->or)
- 			continue;
- 
-@@ -133,8 +115,22 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
- 			 nv_rd32(dev, NV50_PDISPLAY_SOR_DPMS_STATE(or)));
- 	}
- 
--	if (nv_encoder->dcb->type == OUTPUT_DP && mode == DRM_MODE_DPMS_ON)
--		nv50_sor_dp_link_train(encoder);
-+	if (nv_encoder->dcb->type == OUTPUT_DP) {
-+		struct nouveau_i2c_chan *auxch;
-+
-+		auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
-+		if (!auxch)
-+			return;
-+
-+		if (mode == DRM_MODE_DPMS_ON) {
-+			u8 status = DP_SET_POWER_D0;
-+			nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
-+			nouveau_dp_link_train(encoder);
-+		} else {
-+			u8 status = DP_SET_POWER_D3;
-+			nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
-+		}
-+	}
- }
- 
- static void
-@@ -196,7 +192,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
- 	uint32_t mode_ctl = 0;
- 	int ret;
- 
--	NV_DEBUG_KMS(dev, "or %d\n", nv_encoder->or);
-+	NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n",
-+		     nv_encoder->or, nv_encoder->dcb->type, crtc->index);
- 
- 	nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
- 
-@@ -239,6 +236,14 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
- 	}
- 	BEGIN_RING(evo, 0, NV50_EVO_SOR(nv_encoder->or, MODE_CTRL), 1);
- 	OUT_RING(evo, mode_ctl);
-+
-+	nv_encoder->crtc = encoder->crtc;
-+}
-+
-+static struct drm_crtc *
-+nv50_sor_crtc_get(struct drm_encoder *encoder)
-+{
-+	return nouveau_encoder(encoder)->crtc;
- }
- 
- static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
-@@ -249,7 +254,9 @@ static const struct drm_encoder_helper_funcs nv50_sor_helper_funcs = {
- 	.prepare = nv50_sor_prepare,
- 	.commit = nv50_sor_commit,
- 	.mode_set = nv50_sor_mode_set,
--	.detect = NULL
-+	.get_crtc = nv50_sor_crtc_get,
-+	.detect = NULL,
-+	.disable = nv50_sor_disconnect
- };
- 
- static void
-@@ -272,32 +279,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
- };
- 
- int
--nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
-+nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
- {
- 	struct nouveau_encoder *nv_encoder = NULL;
-+	struct drm_device *dev = connector->dev;
- 	struct drm_encoder *encoder;
--	bool dum;
- 	int type;
- 
- 	NV_DEBUG_KMS(dev, "\n");
- 
- 	switch (entry->type) {
- 	case OUTPUT_TMDS:
--		NV_INFO(dev, "Detected a TMDS output\n");
-+	case OUTPUT_DP:
- 		type = DRM_MODE_ENCODER_TMDS;
- 		break;
- 	case OUTPUT_LVDS:
--		NV_INFO(dev, "Detected a LVDS output\n");
- 		type = DRM_MODE_ENCODER_LVDS;
--
--		if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) {
--			NV_ERROR(dev, "Failed parsing LVDS table\n");
--			return -EINVAL;
--		}
--		break;
--	case OUTPUT_DP:
--		NV_INFO(dev, "Detected a DP output\n");
--		type = DRM_MODE_ENCODER_TMDS;
- 		break;
- 	default:
- 		return -EINVAL;
-@@ -310,8 +307,7 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
- 
- 	nv_encoder->dcb = entry;
- 	nv_encoder->or = ffs(entry->or) - 1;
--
--	nv_encoder->disconnect = nv50_sor_disconnect;
-+	nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
- 
- 	drm_encoder_init(dev, encoder, &nv50_sor_encoder_funcs, type);
- 	drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);
-@@ -342,5 +338,6 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
- 			nv_encoder->dp.mc_unknown = 5;
- 	}
- 
-+	drm_mode_connector_attach_encoder(connector, encoder);
- 	return 0;
- }
-diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h
-index 5998c35..ad64673 100644
---- a/drivers/gpu/drm/nouveau/nvreg.h
-+++ b/drivers/gpu/drm/nouveau/nvreg.h
-@@ -147,28 +147,6 @@
- #	define NV_VIO_GX_DONT_CARE_INDEX	0x07
- #	define NV_VIO_GX_BIT_MASK_INDEX		0x08
- 
--#define NV_PFB_BOOT_0			0x00100000
--#define NV_PFB_CFG0			0x00100200
--#define NV_PFB_CFG1			0x00100204
--#define NV_PFB_CSTATUS			0x0010020C
--#define NV_PFB_REFCTRL			0x00100210
--#	define NV_PFB_REFCTRL_VALID_1			(1 << 31)
--#define NV_PFB_PAD			0x0010021C
--#	define NV_PFB_PAD_CKE_NORMAL			(1 << 0)
--#define NV_PFB_TILE_NV10		0x00100240
--#define NV_PFB_TILE_SIZE_NV10		0x00100244
--#define NV_PFB_REF			0x001002D0
--#	define NV_PFB_REF_CMD_REFRESH			(1 << 0)
--#define NV_PFB_PRE			0x001002D4
--#	define NV_PFB_PRE_CMD_PRECHARGE			(1 << 0)
--#define NV_PFB_CLOSE_PAGE2		0x0010033C
--#define NV_PFB_TILE_NV40		0x00100600
--#define NV_PFB_TILE_SIZE_NV40		0x00100604
--
--#define NV_PEXTDEV_BOOT_0		0x00101000
--#	define NV_PEXTDEV_BOOT_0_STRAP_FP_IFACE_12BIT	(8 << 12)
--#define NV_PEXTDEV_BOOT_3		0x0010100c
--
- #define NV_PCRTC_INTR_0					0x00600100
- #	define NV_PCRTC_INTR_0_VBLANK				(1 << 0)
- #define NV_PCRTC_INTR_EN_0				0x00600140
+nil
diff --git a/kernel.spec b/kernel.spec
index dfa85e3..affce54 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -648,8 +648,7 @@ Patch800: linux-2.6-crash-driver.patch
 Patch1555: fix_xen_guest_on_old_EC2.patch
 
 # DRM
-Patch1801: drm-revert-drm-fbdev-rework-output-polling-to-be-back-in-core.patch
-Patch1802: revert-drm-kms-toggle-poll-around-switcheroo.patch
+
 # nouveau + drm fixes
 Patch1810: drm-nouveau-updates.patch
 Patch1819: drm-intel-big-hammer.patch
@@ -1261,13 +1260,14 @@ ApplyPatch linux-2.6-e1000-ich9-montevina.patch
 # Assorted Virt Fixes
 ApplyPatch fix_xen_guest_on_old_EC2.patch
 
-#ApplyPatch drm-revert-drm-fbdev-rework-output-polling-to-be-back-in-core.patch
-#ApplyPatch revert-drm-kms-toggle-poll-around-switcheroo.patch
+# DRM core
 
-# Nouveau DRM + drm fixes
-#ApplyPatch drm-nouveau-updates.patch
-ApplyPatch drm-intel-big-hammer.patch
+# Nouveau DRM
+ApplyOptionalPatch drm-nouveau-updates.patch
+
+# Intel DRM
 ApplyOptionalPatch drm-intel-next.patch
+ApplyPatch drm-intel-big-hammer.patch
 ApplyPatch drm-intel-make-lvds-work.patch
 ApplyPatch linux-2.6-intel-iommu-igfx.patch
 


More information about the scm-commits mailing list