aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:27:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:27:02 -0400
commitba331d5decbfe1cc8b1bf10fb7005f4b972c4f0e (patch)
treeaf12491d851d3d953f6b482df450045e83368ed9
parent09fa30226130652af75152d9010c603c66d46f6e (diff)
parent1898f4426b3863216a9041389b34a3b995883027 (diff)
Merge branch 'drm-nouveau-destage' of git://people.freedesktop.org/~airlied/linux
Pull nouveau destaging + Kelper modesetting support from Dave Airlie: "This pull request is unexpected and not something I had mentioned previously. So NVIDIA announced new Kepler GPUs this morning, and Ben has killed himself getting modesetting support for them together to have on launch day. Most of the code to support the new chips has already gone in, however this pull contains a few more pieces along with the final enables so the driver binds to the new Kepler cards. Its quite amazing that nouveau can support a GPU on its launch day even if its just unaccelerated modesetting, and I'd like to have support in the next kernel. In order to sweeten the deal, Ben has also requested nouveau destage and become ABI stable, the only change is the version number bump which he prepared userspace for quite a long time ago. The driver hasn't broken ABI since that one big break that caused a lot of fuss. It's also quite a small set of code, and not likely to break anything." * 'drm-nouveau-destage' of git://people.freedesktop.org/~airlied/linux: drm/nouveau/dp: support version 4.0 of DP table drm/nve0/disp: nvidia randomly decided to move the dithering method drm/nve0: initial modesetting support for kepler chipsets drm/nouveau: add bios connector type for dms59 drm/nouveau: move out of staging drivers drm/nouveau: bump version to 1.0.0 drm/nvd0/disp: ignore clock set if no pclk drm/nouveau: oops, increase channel dispc_vma to 4 drm/nouveau: inform userspace of new kernel subchannel requirements drm/nouveau: remove m2mf creation on userspace channels drm/nvc0-/disp: reimplement flip completion method as fifo method drm/nouveau: move fence sequence check to start of loop drm/nouveau: remove subchannel names from places where it doesn't matter drm/nouveau/ttm: always do buffer moves on kernel channel
-rw-r--r--drivers/gpu/drm/Kconfig2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c34
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c61
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h40
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c35
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c152
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_fifo.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_graph.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c23
-rw-r--r--drivers/staging/Kconfig2
19 files changed, 288 insertions, 186 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 87ca18b82e15..cc1148837e24 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -88,6 +88,8 @@ config DRM_RADEON
88 88
89source "drivers/gpu/drm/radeon/Kconfig" 89source "drivers/gpu/drm/radeon/Kconfig"
90 90
91source "drivers/gpu/drm/nouveau/Kconfig"
92
91config DRM_I810 93config DRM_I810
92 tristate "Intel I810" 94 tristate "Intel I810"
93 # !PREEMPT because of missing ioctl locking 95 # !PREEMPT because of missing ioctl locking
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 8dbeeea91872..637afe71de56 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -1144,7 +1144,8 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1144 break; 1144 break;
1145 case 1: 1145 case 1:
1146 case 2: 1146 case 2:
1147 if (!(entry[5] & cond)) 1147 if ((table[0] < 0x40 && !(entry[5] & cond)) ||
1148 (table[0] == 0x40 && !(entry[4] & cond)))
1148 iexec->execute = false; 1149 iexec->execute = false;
1149 break; 1150 break;
1150 case 5: 1151 case 5:
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 1f3233df00e6..298a3af48d14 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -69,6 +69,8 @@ enum dcb_connector_type {
69 DCB_CONNECTOR_TV_3 = 0x13, 69 DCB_CONNECTOR_TV_3 = 0x13,
70 DCB_CONNECTOR_DVI_I = 0x30, 70 DCB_CONNECTOR_DVI_I = 0x30,
71 DCB_CONNECTOR_DVI_D = 0x31, 71 DCB_CONNECTOR_DVI_D = 0x31,
72 DCB_CONNECTOR_DMS59_0 = 0x38,
73 DCB_CONNECTOR_DMS59_1 = 0x39,
72 DCB_CONNECTOR_LVDS = 0x40, 74 DCB_CONNECTOR_LVDS = 0x40,
73 DCB_CONNECTOR_LVDS_SPWG = 0x41, 75 DCB_CONNECTOR_LVDS_SPWG = 0x41,
74 DCB_CONNECTOR_DP = 0x46, 76 DCB_CONNECTOR_DP = 0x46,
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index ec54364ac828..7d15a774f9c9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -693,16 +693,12 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
693 struct ttm_mem_reg *new_mem) 693 struct ttm_mem_reg *new_mem)
694{ 694{
695 struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); 695 struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev);
696 struct nouveau_channel *chan = chan = dev_priv->channel;
696 struct nouveau_bo *nvbo = nouveau_bo(bo); 697 struct nouveau_bo *nvbo = nouveau_bo(bo);
697 struct ttm_mem_reg *old_mem = &bo->mem; 698 struct ttm_mem_reg *old_mem = &bo->mem;
698 struct nouveau_channel *chan;
699 int ret; 699 int ret;
700 700
701 chan = nvbo->channel; 701 mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);
702 if (!chan) {
703 chan = dev_priv->channel;
704 mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX);
705 }
706 702
707 /* create temporary vmas for the transfer and attach them to the 703 /* create temporary vmas for the transfer and attach them to the
708 * old nouveau_mem node, these will get cleaned up after ttm has 704 * old nouveau_mem node, these will get cleaned up after ttm has
@@ -734,8 +730,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
734 } 730 }
735 731
736out: 732out:
737 if (chan == dev_priv->channel) 733 mutex_unlock(&chan->mutex);
738 mutex_unlock(&chan->mutex);
739 return ret; 734 return ret;
740} 735}
741 736
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index a018defb7621..44e6416d4a33 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -122,7 +122,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
122 struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv); 122 struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
123 struct nouveau_channel *chan; 123 struct nouveau_channel *chan;
124 unsigned long flags; 124 unsigned long flags;
125 int ret; 125 int ret, i;
126 126
127 /* allocate and lock channel structure */ 127 /* allocate and lock channel structure */
128 chan = kzalloc(sizeof(*chan), GFP_KERNEL); 128 chan = kzalloc(sizeof(*chan), GFP_KERNEL);
@@ -184,7 +184,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
184 return ret; 184 return ret;
185 } 185 }
186 186
187 nouveau_dma_pre_init(chan); 187 nouveau_dma_init(chan);
188 chan->user_put = 0x40; 188 chan->user_put = 0x40;
189 chan->user_get = 0x44; 189 chan->user_get = 0x44;
190 if (dev_priv->card_type >= NV_50) 190 if (dev_priv->card_type >= NV_50)
@@ -202,9 +202,18 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
202 202
203 pfifo->reassign(dev, true); 203 pfifo->reassign(dev, true);
204 204
205 ret = nouveau_dma_init(chan); 205 /* Insert NOPs for NOUVEAU_DMA_SKIPS */
206 if (!ret) 206 ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
207 ret = nouveau_fence_channel_init(chan); 207 if (ret) {
208 nouveau_channel_put(&chan);
209 return ret;
210 }
211
212 for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
213 OUT_RING (chan, 0x00000000);
214 FIRE_RING(chan);
215
216 ret = nouveau_fence_channel_init(chan);
208 if (ret) { 217 if (ret) {
209 nouveau_channel_put(&chan); 218 nouveau_channel_put(&chan);
210 return ret; 219 return ret;
@@ -427,18 +436,11 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
427 } 436 }
428 437
429 if (dev_priv->card_type < NV_C0) { 438 if (dev_priv->card_type < NV_C0) {
430 init->subchan[0].handle = NvM2MF; 439 init->subchan[0].handle = NvSw;
431 if (dev_priv->card_type < NV_50) 440 init->subchan[0].grclass = NV_SW;
432 init->subchan[0].grclass = 0x0039;
433 else
434 init->subchan[0].grclass = 0x5039;
435 init->subchan[1].handle = NvSw;
436 init->subchan[1].grclass = NV_SW;
437 init->nr_subchan = 2;
438 } else {
439 init->subchan[0].handle = 0x9039;
440 init->subchan[0].grclass = 0x9039;
441 init->nr_subchan = 1; 441 init->nr_subchan = 1;
442 } else {
443 init->nr_subchan = 0;
442 } 444 }
443 445
444 /* Named memory object area */ 446 /* Named memory object area */
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 9f9d50dbca7f..8f510fd956b0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -867,6 +867,8 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb)
867 case DCB_CONNECTOR_TV_0 : 867 case DCB_CONNECTOR_TV_0 :
868 case DCB_CONNECTOR_TV_1 : 868 case DCB_CONNECTOR_TV_1 :
869 case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV; 869 case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV;
870 case DCB_CONNECTOR_DMS59_0 :
871 case DCB_CONNECTOR_DMS59_1 :
870 case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII; 872 case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII;
871 case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID; 873 case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID;
872 case DCB_CONNECTOR_LVDS : 874 case DCB_CONNECTOR_LVDS :
@@ -1013,13 +1015,10 @@ nouveau_connector_create(struct drm_device *dev, int index)
1013 1015
1014 /* Add overscan compensation options to digital outputs */ 1016 /* Add overscan compensation options to digital outputs */
1015 if (disp->underscan_property && 1017 if (disp->underscan_property &&
1016 (nv_connector->type == DCB_CONNECTOR_DVI_D || 1018 (type == DRM_MODE_CONNECTOR_DVID ||
1017 nv_connector->type == DCB_CONNECTOR_DVI_I || 1019 type == DRM_MODE_CONNECTOR_DVII ||
1018 nv_connector->type == DCB_CONNECTOR_HDMI_0 || 1020 type == DRM_MODE_CONNECTOR_HDMIA ||
1019 nv_connector->type == DCB_CONNECTOR_HDMI_1 || 1021 type == DRM_MODE_CONNECTOR_DisplayPort)) {
1020 nv_connector->type == DCB_CONNECTOR_DP ||
1021 nv_connector->type == DCB_CONNECTOR_DMS59_DP0 ||
1022 nv_connector->type == DCB_CONNECTOR_DMS59_DP1)) {
1023 drm_connector_attach_property(connector, 1022 drm_connector_attach_property(connector,
1024 disp->underscan_property, 1023 disp->underscan_property,
1025 UNDERSCAN_OFF); 1024 UNDERSCAN_OFF);
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index c01ae781e2a7..a85e112863d1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -441,15 +441,19 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
441 goto fail; 441 goto fail;
442 442
443 /* Emit the pageflip */ 443 /* Emit the pageflip */
444 ret = RING_SPACE(chan, 2); 444 ret = RING_SPACE(chan, 3);
445 if (ret) 445 if (ret)
446 goto fail; 446 goto fail;
447 447
448 if (dev_priv->card_type < NV_C0) 448 if (dev_priv->card_type < NV_C0) {
449 BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 449 BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
450 else 450 OUT_RING (chan, 0x00000000);
451 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1); 451 OUT_RING (chan, 0x00000000);
452 OUT_RING (chan, 0); 452 } else {
453 BEGIN_NVC0(chan, 2, 0, NV10_SUBCHAN_REF_CNT, 1);
454 OUT_RING (chan, ++chan->fence.sequence);
455 BEGIN_NVC0(chan, 8, 0, NVSW_SUBCHAN_PAGE_FLIP, 0x0000);
456 }
453 FIRE_RING (chan); 457 FIRE_RING (chan);
454 458
455 ret = nouveau_fence_new(chan, pfence, true); 459 ret = nouveau_fence_new(chan, pfence, true);
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index 4c2e4e5925fe..295932e66ac5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -31,7 +31,7 @@
31#include "nouveau_ramht.h" 31#include "nouveau_ramht.h"
32 32
33void 33void
34nouveau_dma_pre_init(struct nouveau_channel *chan) 34nouveau_dma_init(struct nouveau_channel *chan)
35{ 35{
36 struct drm_nouveau_private *dev_priv = chan->dev->dev_private; 36 struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
37 struct nouveau_bo *pushbuf = chan->pushbuf_bo; 37 struct nouveau_bo *pushbuf = chan->pushbuf_bo;
@@ -54,65 +54,6 @@ nouveau_dma_pre_init(struct nouveau_channel *chan)
54 chan->dma.free = chan->dma.max - chan->dma.cur; 54 chan->dma.free = chan->dma.max - chan->dma.cur;
55} 55}
56 56
57int
58nouveau_dma_init(struct nouveau_channel *chan)
59{
60 struct drm_device *dev = chan->dev;
61 struct drm_nouveau_private *dev_priv = dev->dev_private;
62 int ret, i;
63
64 if (dev_priv->card_type >= NV_C0) {
65 ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039);
66 if (ret)
67 return ret;
68
69 ret = RING_SPACE(chan, 2);
70 if (ret)
71 return ret;
72
73 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1);
74 OUT_RING (chan, 0x00009039);
75 FIRE_RING (chan);
76 return 0;
77 }
78
79 /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
80 ret = nouveau_gpuobj_gr_new(chan, NvM2MF, dev_priv->card_type < NV_50 ?
81 0x0039 : 0x5039);
82 if (ret)
83 return ret;
84
85 /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
86 ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
87 &chan->m2mf_ntfy);
88 if (ret)
89 return ret;
90
91 /* Insert NOPS for NOUVEAU_DMA_SKIPS */
92 ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
93 if (ret)
94 return ret;
95
96 for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
97 OUT_RING(chan, 0);
98
99 /* Initialise NV_MEMORY_TO_MEMORY_FORMAT */
100 ret = RING_SPACE(chan, 6);
101 if (ret)
102 return ret;
103 BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
104 OUT_RING (chan, NvM2MF);
105 BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
106 OUT_RING (chan, NvNotify0);
107 OUT_RING (chan, chan->vram_handle);
108 OUT_RING (chan, chan->gart_handle);
109
110 /* Sit back and pray the channel works.. */
111 FIRE_RING(chan);
112
113 return 0;
114}
115
116void 57void
117OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords) 58OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords)
118{ 59{
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
index 23d4edf992b7..bcf0fd9e313e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.h
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
@@ -48,8 +48,8 @@ void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
48 48
49/* Hardcoded object assignments to subchannels (subchannel id). */ 49/* Hardcoded object assignments to subchannels (subchannel id). */
50enum { 50enum {
51 NvSubM2MF = 0, 51 NvSubSw = 0,
52 NvSubSw = 1, 52 NvSubM2MF = 1,
53 NvSub2D = 2, 53 NvSub2D = 2,
54 NvSubCtxSurf2D = 2, 54 NvSubCtxSurf2D = 2,
55 NvSubGdiRect = 3, 55 NvSubGdiRect = 3,
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 302b2f7d0678..d996134b1b28 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -188,6 +188,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
188 case 0x20: 188 case 0x20:
189 case 0x21: 189 case 0x21:
190 case 0x30: 190 case 0x30:
191 case 0x40:
191 break; 192 break;
192 default: 193 default:
193 NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]); 194 NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]);
@@ -366,6 +367,10 @@ dp_set_downspread(struct drm_device *dev, struct dp_state *dp, bool enable)
366 if (table[0] >= 0x20 && table[0] <= 0x30) { 367 if (table[0] >= 0x20 && table[0] <= 0x30) {
367 if (enable) script = ROM16(entry[12]); 368 if (enable) script = ROM16(entry[12]);
368 else script = ROM16(entry[14]); 369 else script = ROM16(entry[14]);
370 } else
371 if (table[0] == 0x40) {
372 if (enable) script = ROM16(entry[11]);
373 else script = ROM16(entry[13]);
369 } 374 }
370 } 375 }
371 376
@@ -380,6 +385,9 @@ dp_link_train_init(struct drm_device *dev, struct dp_state *dp)
380 if (table) { 385 if (table) {
381 if (table[0] >= 0x20 && table[0] <= 0x30) 386 if (table[0] >= 0x20 && table[0] <= 0x30)
382 script = ROM16(entry[6]); 387 script = ROM16(entry[6]);
388 else
389 if (table[0] == 0x40)
390 script = ROM16(entry[5]);
383 } 391 }
384 392
385 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); 393 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
@@ -393,6 +401,9 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
393 if (table) { 401 if (table) {
394 if (table[0] >= 0x20 && table[0] <= 0x30) 402 if (table[0] >= 0x20 && table[0] <= 0x30)
395 script = ROM16(entry[8]); 403 script = ROM16(entry[8]);
404 else
405 if (table[0] == 0x40)
406 script = ROM16(entry[7]);
396 } 407 }
397 408
398 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); 409 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index a184ba331273..3aef353a926c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -26,15 +26,15 @@
26#define __NOUVEAU_DRV_H__ 26#define __NOUVEAU_DRV_H__
27 27
28#define DRIVER_AUTHOR "Stephane Marchesin" 28#define DRIVER_AUTHOR "Stephane Marchesin"
29#define DRIVER_EMAIL "dri-devel@lists.sourceforge.net" 29#define DRIVER_EMAIL "nouveau@lists.freedesktop.org"
30 30
31#define DRIVER_NAME "nouveau" 31#define DRIVER_NAME "nouveau"
32#define DRIVER_DESC "nVidia Riva/TNT/GeForce" 32#define DRIVER_DESC "nVidia Riva/TNT/GeForce"
33#define DRIVER_DATE "20090420" 33#define DRIVER_DATE "20120316"
34 34
35#define DRIVER_MAJOR 0 35#define DRIVER_MAJOR 1
36#define DRIVER_MINOR 0 36#define DRIVER_MINOR 0
37#define DRIVER_PATCHLEVEL 16 37#define DRIVER_PATCHLEVEL 0
38 38
39#define NOUVEAU_FAMILY 0x0000FFFF 39#define NOUVEAU_FAMILY 0x0000FFFF
40#define NOUVEAU_FLAGS 0xFFFF0000 40#define NOUVEAU_FLAGS 0xFFFF0000
@@ -113,8 +113,6 @@ struct nouveau_bo {
113 int pbbo_index; 113 int pbbo_index;
114 bool validate_mapped; 114 bool validate_mapped;
115 115
116 struct nouveau_channel *channel;
117
118 struct list_head vma_list; 116 struct list_head vma_list;
119 unsigned page_shift; 117 unsigned page_shift;
120 118
@@ -296,7 +294,7 @@ struct nouveau_channel {
296 294
297 uint32_t sw_subchannel[8]; 295 uint32_t sw_subchannel[8];
298 296
299 struct nouveau_vma dispc_vma[2]; 297 struct nouveau_vma dispc_vma[4];
300 struct { 298 struct {
301 struct nouveau_gpuobj *vblsem; 299 struct nouveau_gpuobj *vblsem;
302 uint32_t vblsem_head; 300 uint32_t vblsem_head;
@@ -703,6 +701,7 @@ enum nouveau_card_type {
703 NV_50 = 0x50, 701 NV_50 = 0x50,
704 NV_C0 = 0xc0, 702 NV_C0 = 0xc0,
705 NV_D0 = 0xd0, 703 NV_D0 = 0xd0,
704 NV_E0 = 0xe0,
706}; 705};
707 706
708struct drm_nouveau_private { 707struct drm_nouveau_private {
@@ -1091,8 +1090,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan)
1091#endif 1090#endif
1092 1091
1093/* nouveau_dma.c */ 1092/* nouveau_dma.c */
1094extern void nouveau_dma_pre_init(struct nouveau_channel *); 1093extern void nouveau_dma_init(struct nouveau_channel *);
1095extern int nouveau_dma_init(struct nouveau_channel *);
1096extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); 1094extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
1097 1095
1098/* nouveau_acpi.c */ 1096/* nouveau_acpi.c */
@@ -1765,13 +1763,27 @@ nv44_graph_class(struct drm_device *dev)
1765#define NV_MEM_TYPE_VM 0x7f 1763#define NV_MEM_TYPE_VM 0x7f
1766#define NV_MEM_COMP_VM 0x03 1764#define NV_MEM_COMP_VM 0x03
1767 1765
1766/* FIFO methods */
1767#define NV01_SUBCHAN_OBJECT 0x00000000
1768#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH 0x00000010
1769#define NV84_SUBCHAN_SEMAPHORE_ADDRESS_LOW 0x00000014
1770#define NV84_SUBCHAN_SEMAPHORE_SEQUENCE 0x00000018
1771#define NV84_SUBCHAN_SEMAPHORE_TRIGGER 0x0000001c
1772#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL 0x00000001
1773#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG 0x00000002
1774#define NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_GEQUAL 0x00000004
1775#define NV84_SUBCHAN_NOTIFY_INTR 0x00000020
1776#define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024
1777#define NV10_SUBCHAN_REF_CNT 0x00000050
1778#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054
1779#define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060
1780#define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064
1781#define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068
1782#define NV11_SUBCHAN_SEMAPHORE_RELEASE 0x0000006c
1783#define NV40_SUBCHAN_YIELD 0x00000080
1784
1768/* NV_SW object class */ 1785/* NV_SW object class */
1769#define NV_SW 0x0000506e 1786#define NV_SW 0x0000506e
1770#define NV_SW_DMA_SEMAPHORE 0x00000060
1771#define NV_SW_SEMAPHORE_OFFSET 0x00000064
1772#define NV_SW_SEMAPHORE_ACQUIRE 0x00000068
1773#define NV_SW_SEMAPHORE_RELEASE 0x0000006c
1774#define NV_SW_YIELD 0x00000080
1775#define NV_SW_DMA_VBLSEM 0x0000018c 1787#define NV_SW_DMA_VBLSEM 0x0000018c
1776#define NV_SW_VBLSEM_OFFSET 0x00000400 1788#define NV_SW_VBLSEM_OFFSET 0x00000400
1777#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404 1789#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index 2f6daae68b9d..c1dc20f6cb85 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -93,18 +93,17 @@ nouveau_fence_update(struct nouveau_channel *chan)
93 } 93 }
94 94
95 list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { 95 list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) {
96 sequence = fence->sequence; 96 if (fence->sequence > chan->fence.sequence_ack)
97 break;
98
97 fence->signalled = true; 99 fence->signalled = true;
98 list_del(&fence->entry); 100 list_del(&fence->entry);
99 101 if (fence->work)
100 if (unlikely(fence->work))
101 fence->work(fence->priv, true); 102 fence->work(fence->priv, true);
102 103
103 kref_put(&fence->refcount, nouveau_fence_del); 104 kref_put(&fence->refcount, nouveau_fence_del);
104
105 if (sequence == chan->fence.sequence_ack)
106 break;
107 } 105 }
106
108out: 107out:
109 spin_unlock(&chan->fence.lock); 108 spin_unlock(&chan->fence.lock);
110} 109}
@@ -165,9 +164,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
165 164
166 if (USE_REFCNT(dev)) { 165 if (USE_REFCNT(dev)) {
167 if (dev_priv->card_type < NV_C0) 166 if (dev_priv->card_type < NV_C0)
168 BEGIN_RING(chan, NvSubSw, 0x0050, 1); 167 BEGIN_RING(chan, 0, NV10_SUBCHAN_REF_CNT, 1);
169 else 168 else
170 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0050, 1); 169 BEGIN_NVC0(chan, 2, 0, NV10_SUBCHAN_REF_CNT, 1);
171 } else { 170 } else {
172 BEGIN_RING(chan, NvSubSw, 0x0150, 1); 171 BEGIN_RING(chan, NvSubSw, 0x0150, 1);
173 } 172 }
@@ -344,7 +343,7 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
344 if (ret) 343 if (ret)
345 return ret; 344 return ret;
346 345
347 BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 3); 346 BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 3);
348 OUT_RING (chan, NvSema); 347 OUT_RING (chan, NvSema);
349 OUT_RING (chan, offset); 348 OUT_RING (chan, offset);
350 OUT_RING (chan, 1); 349 OUT_RING (chan, 1);
@@ -354,9 +353,9 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
354 if (ret) 353 if (ret)
355 return ret; 354 return ret;
356 355
357 BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1); 356 BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
358 OUT_RING (chan, chan->vram_handle); 357 OUT_RING (chan, chan->vram_handle);
359 BEGIN_RING(chan, NvSubSw, 0x0010, 4); 358 BEGIN_RING(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
360 OUT_RING (chan, upper_32_bits(offset)); 359 OUT_RING (chan, upper_32_bits(offset));
361 OUT_RING (chan, lower_32_bits(offset)); 360 OUT_RING (chan, lower_32_bits(offset));
362 OUT_RING (chan, 1); 361 OUT_RING (chan, 1);
@@ -366,7 +365,7 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
366 if (ret) 365 if (ret)
367 return ret; 366 return ret;
368 367
369 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); 368 BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
370 OUT_RING (chan, upper_32_bits(offset)); 369 OUT_RING (chan, upper_32_bits(offset));
371 OUT_RING (chan, lower_32_bits(offset)); 370 OUT_RING (chan, lower_32_bits(offset));
372 OUT_RING (chan, 1); 371 OUT_RING (chan, 1);
@@ -397,10 +396,10 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
397 if (ret) 396 if (ret)
398 return ret; 397 return ret;
399 398
400 BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 2); 399 BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
401 OUT_RING (chan, NvSema); 400 OUT_RING (chan, NvSema);
402 OUT_RING (chan, offset); 401 OUT_RING (chan, offset);
403 BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1); 402 BEGIN_RING(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
404 OUT_RING (chan, 1); 403 OUT_RING (chan, 1);
405 } else 404 } else
406 if (dev_priv->chipset < 0xc0) { 405 if (dev_priv->chipset < 0xc0) {
@@ -408,9 +407,9 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
408 if (ret) 407 if (ret)
409 return ret; 408 return ret;
410 409
411 BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1); 410 BEGIN_RING(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
412 OUT_RING (chan, chan->vram_handle); 411 OUT_RING (chan, chan->vram_handle);
413 BEGIN_RING(chan, NvSubSw, 0x0010, 4); 412 BEGIN_RING(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
414 OUT_RING (chan, upper_32_bits(offset)); 413 OUT_RING (chan, upper_32_bits(offset));
415 OUT_RING (chan, lower_32_bits(offset)); 414 OUT_RING (chan, lower_32_bits(offset));
416 OUT_RING (chan, 1); 415 OUT_RING (chan, 1);
@@ -420,7 +419,7 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
420 if (ret) 419 if (ret)
421 return ret; 420 return ret;
422 421
423 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); 422 BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
424 OUT_RING (chan, upper_32_bits(offset)); 423 OUT_RING (chan, upper_32_bits(offset));
425 OUT_RING (chan, lower_32_bits(offset)); 424 OUT_RING (chan, lower_32_bits(offset));
426 OUT_RING (chan, 1); 425 OUT_RING (chan, 1);
@@ -510,7 +509,7 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
510 if (ret) 509 if (ret)
511 return ret; 510 return ret;
512 511
513 BEGIN_RING(chan, NvSubSw, 0, 1); 512 BEGIN_RING(chan, NvSubSw, NV01_SUBCHAN_OBJECT, 1);
514 OUT_RING (chan, NvSw); 513 OUT_RING (chan, NvSw);
515 FIRE_RING (chan); 514 FIRE_RING (chan);
516 } 515 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 7ce3fde40743..ed52a6f41613 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -426,9 +426,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list,
426 return ret; 426 return ret;
427 } 427 }
428 428
429 nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan;
430 ret = nouveau_bo_validate(nvbo, true, false, false); 429 ret = nouveau_bo_validate(nvbo, true, false, false);
431 nvbo->channel = NULL;
432 if (unlikely(ret)) { 430 if (unlikely(ret)) {
433 if (ret != -ERESTARTSYS) 431 if (ret != -ERESTARTSYS)
434 NV_ERROR(dev, "fail ttm_validate\n"); 432 NV_ERROR(dev, "fail ttm_validate\n");
@@ -678,19 +676,13 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
678 return PTR_ERR(bo); 676 return PTR_ERR(bo);
679 } 677 }
680 678
681 /* Mark push buffers as being used on PFIFO, the validation code 679 /* Ensure all push buffers are on validate list */
682 * will then make sure that if the pushbuf bo moves, that they
683 * happen on the kernel channel, which will in turn cause a sync
684 * to happen before we try and submit the push buffer.
685 */
686 for (i = 0; i < req->nr_push; i++) { 680 for (i = 0; i < req->nr_push; i++) {
687 if (push[i].bo_index >= req->nr_buffers) { 681 if (push[i].bo_index >= req->nr_buffers) {
688 NV_ERROR(dev, "push %d buffer not in list\n", i); 682 NV_ERROR(dev, "push %d buffer not in list\n", i);
689 ret = -EINVAL; 683 ret = -EINVAL;
690 goto out_prevalid; 684 goto out_prevalid;
691 } 685 }
692
693 bo[push[i].bo_index].read_domains |= (1 << 31);
694 } 686 }
695 687
696 /* Validate buffer list */ 688 /* Validate buffer list */
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 9c144fb8bbba..a3ae91fa8141 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -479,6 +479,47 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
479 engine->pm.voltage_get = nouveau_voltage_gpio_get; 479 engine->pm.voltage_get = nouveau_voltage_gpio_get;
480 engine->pm.voltage_set = nouveau_voltage_gpio_set; 480 engine->pm.voltage_set = nouveau_voltage_gpio_set;
481 break; 481 break;
482 case 0xe0:
483 engine->instmem.init = nvc0_instmem_init;
484 engine->instmem.takedown = nvc0_instmem_takedown;
485 engine->instmem.suspend = nvc0_instmem_suspend;
486 engine->instmem.resume = nvc0_instmem_resume;
487 engine->instmem.get = nv50_instmem_get;
488 engine->instmem.put = nv50_instmem_put;
489 engine->instmem.map = nv50_instmem_map;
490 engine->instmem.unmap = nv50_instmem_unmap;
491 engine->instmem.flush = nv84_instmem_flush;
492 engine->mc.init = nv50_mc_init;
493 engine->mc.takedown = nv50_mc_takedown;
494 engine->timer.init = nv04_timer_init;
495 engine->timer.read = nv04_timer_read;
496 engine->timer.takedown = nv04_timer_takedown;
497 engine->fb.init = nvc0_fb_init;
498 engine->fb.takedown = nvc0_fb_takedown;
499 engine->fifo.channels = 0;
500 engine->fifo.init = nouveau_stub_init;
501 engine->fifo.takedown = nouveau_stub_takedown;
502 engine->fifo.disable = nvc0_fifo_disable;
503 engine->fifo.enable = nvc0_fifo_enable;
504 engine->fifo.reassign = nvc0_fifo_reassign;
505 engine->fifo.unload_context = nouveau_stub_init;
506 engine->display.early_init = nouveau_stub_init;
507 engine->display.late_takedown = nouveau_stub_takedown;
508 engine->display.create = nvd0_display_create;
509 engine->display.destroy = nvd0_display_destroy;
510 engine->display.init = nvd0_display_init;
511 engine->display.fini = nvd0_display_fini;
512 engine->gpio.init = nv50_gpio_init;
513 engine->gpio.fini = nv50_gpio_fini;
514 engine->gpio.drive = nvd0_gpio_drive;
515 engine->gpio.sense = nvd0_gpio_sense;
516 engine->gpio.irq_enable = nv50_gpio_irq_enable;
517 engine->vram.init = nvc0_vram_init;
518 engine->vram.takedown = nv50_vram_fini;
519 engine->vram.get = nvc0_vram_new;
520 engine->vram.put = nv50_vram_del;
521 engine->vram.flags_valid = nvc0_vram_flags_valid;
522 break;
482 default: 523 default:
483 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); 524 NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
484 return 1; 525 return 1;
@@ -552,6 +593,75 @@ static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
552 return can_switch; 593 return can_switch;
553} 594}
554 595
596static void
597nouveau_card_channel_fini(struct drm_device *dev)
598{
599 struct drm_nouveau_private *dev_priv = dev->dev_private;
600
601 if (dev_priv->channel)
602 nouveau_channel_put_unlocked(&dev_priv->channel);
603}
604
605static int
606nouveau_card_channel_init(struct drm_device *dev)
607{
608 struct drm_nouveau_private *dev_priv = dev->dev_private;
609 struct nouveau_channel *chan;
610 int ret, oclass;
611
612 ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT);
613 dev_priv->channel = chan;
614 if (ret)
615 return ret;
616
617 mutex_unlock(&dev_priv->channel->mutex);
618
619 if (dev_priv->card_type <= NV_50) {
620 if (dev_priv->card_type < NV_50)
621 oclass = 0x0039;
622 else
623 oclass = 0x5039;
624
625 ret = nouveau_gpuobj_gr_new(chan, NvM2MF, oclass);
626 if (ret)
627 goto error;
628
629 ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
630 &chan->m2mf_ntfy);
631 if (ret)
632 goto error;
633
634 ret = RING_SPACE(chan, 6);
635 if (ret)
636 goto error;
637
638 BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
639 OUT_RING (chan, NvM2MF);
640 BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
641 OUT_RING (chan, NvNotify0);
642 OUT_RING (chan, chan->vram_handle);
643 OUT_RING (chan, chan->gart_handle);
644 } else
645 if (dev_priv->card_type <= NV_C0) {
646 ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039);
647 if (ret)
648 goto error;
649
650 ret = RING_SPACE(chan, 2);
651 if (ret)
652 goto error;
653
654 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1);
655 OUT_RING (chan, 0x00009039);
656 }
657
658 FIRE_RING (chan);
659error:
660 if (ret)
661 nouveau_card_channel_fini(dev);
662 return ret;
663}
664
555int 665int
556nouveau_card_init(struct drm_device *dev) 666nouveau_card_init(struct drm_device *dev)
557{ 667{
@@ -738,17 +848,14 @@ nouveau_card_init(struct drm_device *dev)
738 nouveau_backlight_init(dev); 848 nouveau_backlight_init(dev);
739 nouveau_pm_init(dev); 849 nouveau_pm_init(dev);
740 850
741 if (dev_priv->eng[NVOBJ_ENGINE_GR]) { 851 ret = nouveau_fence_init(dev);
742 ret = nouveau_fence_init(dev); 852 if (ret)
743 if (ret) 853 goto out_pm;
744 goto out_pm;
745 854
746 ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL, 855 if (!dev_priv->noaccel) {
747 NvDmaFB, NvDmaTT); 856 ret = nouveau_card_channel_init(dev);
748 if (ret) 857 if (ret)
749 goto out_fence; 858 goto out_fence;
750
751 mutex_unlock(&dev_priv->channel->mutex);
752 } 859 }
753 860
754 if (dev->mode_config.num_crtc) { 861 if (dev->mode_config.num_crtc) {
@@ -762,7 +869,7 @@ nouveau_card_init(struct drm_device *dev)
762 return 0; 869 return 0;
763 870
764out_chan: 871out_chan:
765 nouveau_channel_put_unlocked(&dev_priv->channel); 872 nouveau_card_channel_fini(dev);
766out_fence: 873out_fence:
767 nouveau_fence_fini(dev); 874 nouveau_fence_fini(dev);
768out_pm: 875out_pm:
@@ -820,11 +927,8 @@ static void nouveau_card_takedown(struct drm_device *dev)
820 nouveau_display_fini(dev); 927 nouveau_display_fini(dev);
821 } 928 }
822 929
823 if (dev_priv->channel) { 930 nouveau_card_channel_fini(dev);
824 nouveau_channel_put_unlocked(&dev_priv->channel); 931 nouveau_fence_fini(dev);
825 nouveau_fence_fini(dev);
826 }
827
828 nouveau_pm_fini(dev); 932 nouveau_pm_fini(dev);
829 nouveau_backlight_exit(dev); 933 nouveau_backlight_exit(dev);
830 nouveau_display_destroy(dev); 934 nouveau_display_destroy(dev);
@@ -993,8 +1097,8 @@ static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
993int nouveau_load(struct drm_device *dev, unsigned long flags) 1097int nouveau_load(struct drm_device *dev, unsigned long flags)
994{ 1098{
995 struct drm_nouveau_private *dev_priv; 1099 struct drm_nouveau_private *dev_priv;
1100 unsigned long long offset, length;
996 uint32_t reg0 = ~0, strap; 1101 uint32_t reg0 = ~0, strap;
997 resource_size_t mmio_start_offs;
998 int ret; 1102 int ret;
999 1103
1000 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); 1104 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
@@ -1048,6 +1152,9 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
1048 case 0xd0: 1152 case 0xd0:
1049 dev_priv->card_type = NV_D0; 1153 dev_priv->card_type = NV_D0;
1050 break; 1154 break;
1155 case 0xe0:
1156 dev_priv->card_type = NV_E0;
1157 break;
1051 default: 1158 default:
1052 break; 1159 break;
1053 } 1160 }
@@ -1072,17 +1179,20 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
1072 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", 1179 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
1073 dev_priv->card_type, reg0); 1180 dev_priv->card_type, reg0);
1074 1181
1075 /* map the mmio regs */ 1182 /* map the mmio regs, limiting the amount to preserve vmap space */
1076 mmio_start_offs = pci_resource_start(dev->pdev, 0); 1183 offset = pci_resource_start(dev->pdev, 0);
1077 dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000); 1184 length = pci_resource_len(dev->pdev, 0);
1185 if (dev_priv->card_type < NV_E0)
1186 length = min(length, (unsigned long long)0x00800000);
1187
1188 dev_priv->mmio = ioremap(offset, length);
1078 if (!dev_priv->mmio) { 1189 if (!dev_priv->mmio) {
1079 NV_ERROR(dev, "Unable to initialize the mmio mapping. " 1190 NV_ERROR(dev, "Unable to initialize the mmio mapping. "
1080 "Please report your setup to " DRIVER_EMAIL "\n"); 1191 "Please report your setup to " DRIVER_EMAIL "\n");
1081 ret = -EINVAL; 1192 ret = -EINVAL;
1082 goto err_priv; 1193 goto err_priv;
1083 } 1194 }
1084 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", 1195 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", offset);
1085 (unsigned long long)mmio_start_offs);
1086 1196
1087 /* determine frequency of timing crystal */ 1197 /* determine frequency of timing crystal */
1088 strap = nv_rd32(dev, 0x101000); 1198 strap = nv_rd32(dev, 0x101000);
@@ -1140,7 +1250,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
1140 } 1250 }
1141 } else { 1251 } else {
1142 dev_priv->ramin_size = 1 * 1024 * 1024; 1252 dev_priv->ramin_size = 1 * 1024 * 1024;
1143 dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN, 1253 dev_priv->ramin = ioremap(offset + NV_RAMIN,
1144 dev_priv->ramin_size); 1254 dev_priv->ramin_size);
1145 if (!dev_priv->ramin) { 1255 if (!dev_priv->ramin) {
1146 NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n"); 1256 NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 0e47a898f415..8b78b9cfa383 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -474,15 +474,15 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
474 } 474 }
475 475
476 if (dev_priv->chipset < 0xc0) { 476 if (dev_priv->chipset < 0xc0) {
477 BEGIN_RING(chan, NvSubSw, 0x0060, 2); 477 BEGIN_RING(chan, 0, 0x0060, 2);
478 OUT_RING (chan, NvEvoSema0 + nv_crtc->index); 478 OUT_RING (chan, NvEvoSema0 + nv_crtc->index);
479 OUT_RING (chan, dispc->sem.offset); 479 OUT_RING (chan, dispc->sem.offset);
480 BEGIN_RING(chan, NvSubSw, 0x006c, 1); 480 BEGIN_RING(chan, 0, 0x006c, 1);
481 OUT_RING (chan, 0xf00d0000 | dispc->sem.value); 481 OUT_RING (chan, 0xf00d0000 | dispc->sem.value);
482 BEGIN_RING(chan, NvSubSw, 0x0064, 2); 482 BEGIN_RING(chan, 0, 0x0064, 2);
483 OUT_RING (chan, dispc->sem.offset ^ 0x10); 483 OUT_RING (chan, dispc->sem.offset ^ 0x10);
484 OUT_RING (chan, 0x74b1e000); 484 OUT_RING (chan, 0x74b1e000);
485 BEGIN_RING(chan, NvSubSw, 0x0060, 1); 485 BEGIN_RING(chan, 0, 0x0060, 1);
486 if (dev_priv->chipset < 0x84) 486 if (dev_priv->chipset < 0x84)
487 OUT_RING (chan, NvSema); 487 OUT_RING (chan, NvSema);
488 else 488 else
@@ -490,12 +490,12 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
490 } else { 490 } else {
491 u64 offset = chan->dispc_vma[nv_crtc->index].offset; 491 u64 offset = chan->dispc_vma[nv_crtc->index].offset;
492 offset += dispc->sem.offset; 492 offset += dispc->sem.offset;
493 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); 493 BEGIN_NVC0(chan, 2, 0, 0x0010, 4);
494 OUT_RING (chan, upper_32_bits(offset)); 494 OUT_RING (chan, upper_32_bits(offset));
495 OUT_RING (chan, lower_32_bits(offset)); 495 OUT_RING (chan, lower_32_bits(offset));
496 OUT_RING (chan, 0xf00d0000 | dispc->sem.value); 496 OUT_RING (chan, 0xf00d0000 | dispc->sem.value);
497 OUT_RING (chan, 0x1002); 497 OUT_RING (chan, 0x1002);
498 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); 498 BEGIN_NVC0(chan, 2, 0, 0x0010, 4);
499 OUT_RING (chan, upper_32_bits(offset)); 499 OUT_RING (chan, upper_32_bits(offset));
500 OUT_RING (chan, lower_32_bits(offset ^ 0x10)); 500 OUT_RING (chan, lower_32_bits(offset ^ 0x10));
501 OUT_RING (chan, 0x74b1e000); 501 OUT_RING (chan, 0x74b1e000);
diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c
index dcbe0d5d0241..50d68a7a1379 100644
--- a/drivers/gpu/drm/nouveau/nvc0_fifo.c
+++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c
@@ -436,6 +436,24 @@ nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
436 printk(" on channel 0x%010llx\n", (u64)inst << 12); 436 printk(" on channel 0x%010llx\n", (u64)inst << 12);
437} 437}
438 438
439static int
440nvc0_fifo_page_flip(struct drm_device *dev, u32 chid)
441{
442 struct drm_nouveau_private *dev_priv = dev->dev_private;
443 struct nouveau_channel *chan = NULL;
444 unsigned long flags;
445 int ret = -EINVAL;
446
447 spin_lock_irqsave(&dev_priv->channels.lock, flags);
448 if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) {
449 chan = dev_priv->channels.ptr[chid];
450 if (likely(chan))
451 ret = nouveau_finish_page_flip(chan, NULL);
452 }
453 spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
454 return ret;
455}
456
439static void 457static void
440nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) 458nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
441{ 459{
@@ -445,11 +463,21 @@ nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
445 u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; 463 u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
446 u32 subc = (addr & 0x00070000); 464 u32 subc = (addr & 0x00070000);
447 u32 mthd = (addr & 0x00003ffc); 465 u32 mthd = (addr & 0x00003ffc);
466 u32 show = stat;
448 467
449 NV_INFO(dev, "PSUBFIFO %d:", unit); 468 if (stat & 0x00200000) {
450 nouveau_bitfield_print(nvc0_fifo_subfifo_intr, stat); 469 if (mthd == 0x0054) {
451 NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", 470 if (!nvc0_fifo_page_flip(dev, chid))
452 unit, chid, subc, mthd, data); 471 show &= ~0x00200000;
472 }
473 }
474
475 if (show) {
476 NV_INFO(dev, "PFIFO%d:", unit);
477 nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show);
478 NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
479 unit, chid, subc, mthd, data);
480 }
453 481
454 nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); 482 nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008);
455 nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); 483 nv_wr32(dev, 0x040108 + (unit * 0x2000), stat);
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
index 8ee3963f9030..9066102d1159 100644
--- a/drivers/gpu/drm/nouveau/nvc0_graph.c
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
@@ -333,14 +333,6 @@ nvc0_graph_fini(struct drm_device *dev, int engine, bool suspend)
333 return 0; 333 return 0;
334} 334}
335 335
336static int
337nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
338 u32 class, u32 mthd, u32 data)
339{
340 nouveau_finish_page_flip(chan, NULL);
341 return 0;
342}
343
344static void 336static void
345nvc0_graph_init_obj418880(struct drm_device *dev) 337nvc0_graph_init_obj418880(struct drm_device *dev)
346{ 338{
@@ -889,7 +881,6 @@ nvc0_graph_create(struct drm_device *dev)
889 881
890 NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ 882 NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
891 NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ 883 NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
892 NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
893 NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ 884 NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
894 if (fermi >= 0x9197) 885 if (fermi >= 0x9197)
895 NVOBJ_CLASS(dev, 0x9197, GR); /* 3D (NVC1-) */ 886 NVOBJ_CLASS(dev, 0x9197, GR); /* 3D (NVC1-) */
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index dfb8a951cbbe..0247250939e8 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -303,12 +303,12 @@ nvd0_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
303 offset = chan->dispc_vma[nv_crtc->index].offset; 303 offset = chan->dispc_vma[nv_crtc->index].offset;
304 offset += evo->sem.offset; 304 offset += evo->sem.offset;
305 305
306 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); 306 BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
307 OUT_RING (chan, upper_32_bits(offset)); 307 OUT_RING (chan, upper_32_bits(offset));
308 OUT_RING (chan, lower_32_bits(offset)); 308 OUT_RING (chan, lower_32_bits(offset));
309 OUT_RING (chan, 0xf00d0000 | evo->sem.value); 309 OUT_RING (chan, 0xf00d0000 | evo->sem.value);
310 OUT_RING (chan, 0x1002); 310 OUT_RING (chan, 0x1002);
311 BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0010, 4); 311 BEGIN_NVC0(chan, 2, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
312 OUT_RING (chan, upper_32_bits(offset)); 312 OUT_RING (chan, upper_32_bits(offset));
313 OUT_RING (chan, lower_32_bits(offset ^ 0x10)); 313 OUT_RING (chan, lower_32_bits(offset ^ 0x10));
314 OUT_RING (chan, 0x74b1e000); 314 OUT_RING (chan, 0x74b1e000);
@@ -363,10 +363,12 @@ nvd0_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
363static int 363static int
364nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) 364nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update)
365{ 365{
366 struct drm_nouveau_private *dev_priv = nv_crtc->base.dev->dev_private;
366 struct drm_device *dev = nv_crtc->base.dev; 367 struct drm_device *dev = nv_crtc->base.dev;
367 struct nouveau_connector *nv_connector; 368 struct nouveau_connector *nv_connector;
368 struct drm_connector *connector; 369 struct drm_connector *connector;
369 u32 *push, mode = 0x00; 370 u32 *push, mode = 0x00;
371 u32 mthd;
370 372
371 nv_connector = nouveau_crtc_connector_get(nv_crtc); 373 nv_connector = nouveau_crtc_connector_get(nv_crtc);
372 connector = &nv_connector->base; 374 connector = &nv_connector->base;
@@ -384,9 +386,14 @@ nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update)
384 mode |= nv_connector->dithering_depth; 386 mode |= nv_connector->dithering_depth;
385 } 387 }
386 388
389 if (dev_priv->card_type < NV_E0)
390 mthd = 0x0490 + (nv_crtc->index * 0x0300);
391 else
392 mthd = 0x04a0 + (nv_crtc->index * 0x0300);
393
387 push = evo_wait(dev, EVO_MASTER, 4); 394 push = evo_wait(dev, EVO_MASTER, 4);
388 if (push) { 395 if (push) {
389 evo_mthd(push, 0x0490 + (nv_crtc->index * 0x300), 1); 396 evo_mthd(push, mthd, 1);
390 evo_data(push, mode); 397 evo_data(push, mode);
391 if (update) { 398 if (update) {
392 evo_mthd(push, 0x0080, 1); 399 evo_mthd(push, 0x0080, 1);
@@ -1219,6 +1226,11 @@ nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_entry *dcb,
1219 if (table[0] == 0x30) { 1226 if (table[0] == 0x30) {
1220 config = entry + table[4]; 1227 config = entry + table[4];
1221 config += table[5] * preem; 1228 config += table[5] * preem;
1229 } else
1230 if (table[0] == 0x40) {
1231 config = table + table[1];
1232 config += table[2] * table[3];
1233 config += table[6] * preem;
1222 } 1234 }
1223 } 1235 }
1224 1236
@@ -1251,6 +1263,7 @@ nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_entry *dcb, int crtc,
1251 table = nouveau_dp_bios_data(dev, dcb, &entry); 1263 table = nouveau_dp_bios_data(dev, dcb, &entry);
1252 if (table) { 1264 if (table) {
1253 if (table[0] == 0x30) entry = ROMPTR(dev, entry[10]); 1265 if (table[0] == 0x30) entry = ROMPTR(dev, entry[10]);
1266 else if (table[0] == 0x40) entry = ROMPTR(dev, entry[9]);
1254 else entry = NULL; 1267 else entry = NULL;
1255 1268
1256 while (entry) { 1269 while (entry) {
@@ -1661,7 +1674,9 @@ nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask)
1661 } 1674 }
1662 1675
1663 pclk = nv_rd32(dev, 0x660450 + (crtc * 0x300)) / 1000; 1676 pclk = nv_rd32(dev, 0x660450 + (crtc * 0x300)) / 1000;
1664 if (mask & 0x00010000) { 1677 NV_DEBUG_KMS(dev, "PDISP: crtc %d pclk %d mask 0x%08x\n",
1678 crtc, pclk, mask);
1679 if (pclk && (mask & 0x00010000)) {
1665 nv50_crtc_set_clock(dev, crtc, pclk); 1680 nv50_crtc_set_clock(dev, crtc, pclk);
1666 } 1681 }
1667 1682
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index f1abfb179b47..97d412d91458 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -64,8 +64,6 @@ source "drivers/staging/phison/Kconfig"
64 64
65source "drivers/staging/line6/Kconfig" 65source "drivers/staging/line6/Kconfig"
66 66
67source "drivers/gpu/drm/nouveau/Kconfig"
68
69source "drivers/staging/octeon/Kconfig" 67source "drivers/staging/octeon/Kconfig"
70 68
71source "drivers/staging/serqt_usb2/Kconfig" 69source "drivers/staging/serqt_usb2/Kconfig"