Re: [Nouveau] [PATCH v2 2/2] drm/nouveau: add GEM_SET_TILING staging ioctl

2015-06-15 Thread Alexandre Courbot

On 06/15/2015 04:56 PM, Daniel Vetter wrote:

On Mon, Jun 15, 2015 at 04:09:29PM +0900, Alexandre Courbot wrote:

From: Ari Hirvonen ahirvo...@nvidia.com

Add new NOUVEAU_GEM_SET_TILING ioctl to set correct tiling
mode for imported dma-bufs. This ioctl is staging for now
and enabled with the staging_tiling module option.

Signed-off-by: Ari Hirvonen ahirvo...@nvidia.com
[acour...@nvidia.com: carry upstream, many fixes]
Signed-off-by: Alexandre Courbot acour...@nvidia.com
---
  drm/nouveau/nouveau_bo.c   | 18 
  drm/nouveau/nouveau_bo.h   |  2 ++
  drm/nouveau/nouveau_drm.c  |  6 
  drm/nouveau/nouveau_gem.c  | 58 ++
  drm/nouveau/nouveau_gem.h  |  2 ++
  drm/nouveau/nouveau_ttm.c  | 13 +
  drm/nouveau/uapi/drm/nouveau_drm.h |  8 ++
  7 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/drm/nouveau/nouveau_bo.c b/drm/nouveau/nouveau_bo.c
index 6edcce1658b7..2a2ebbeb4fc0 100644
--- a/drm/nouveau/nouveau_bo.c
+++ b/drm/nouveau/nouveau_bo.c
@@ -178,6 +178,24 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
*size = roundup(*size, PAGE_SIZE);
  }

+void
+nouveau_bo_update_tiling(struct nouveau_drm *drm, struct nouveau_bo *nvbo,
+struct nvkm_mem *mem)
+{
+   switch (drm-device.info.family) {
+   case NV_DEVICE_INFO_V0_TESLA:
+   if (drm-device.info.chipset != 0x50)
+   mem-memtype = (nvbo-tile_flags  0x7f00)  8;
+   break;
+   case NV_DEVICE_INFO_V0_FERMI:
+   case NV_DEVICE_INFO_V0_KEPLER:
+   mem-memtype = (nvbo-tile_flags  0xff00)  8;
+   break;
+   default:
+   break;
+   }
+}
+
  int
  nouveau_bo_new(struct drm_device *dev, int size, int align,
   uint32_t flags, uint32_t tile_mode, uint32_t tile_flags,
diff --git a/drm/nouveau/nouveau_bo.h b/drm/nouveau/nouveau_bo.h
index e42360983229..87d07e3533eb 100644
--- a/drm/nouveau/nouveau_bo.h
+++ b/drm/nouveau/nouveau_bo.h
@@ -69,6 +69,8 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo 
**pnvbo)
  extern struct ttm_bo_driver nouveau_bo_driver;

  void nouveau_bo_move_init(struct nouveau_drm *);
+void nouveau_bo_update_tiling(struct nouveau_drm *, struct nouveau_bo *,
+ struct nvkm_mem *);
  int  nouveau_bo_new(struct drm_device *, int size, int align, u32 flags,
u32 tile_mode, u32 tile_flags, struct sg_table *sg,
struct reservation_object *robj,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 28860268cf38..45a2c88ebf8e 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, disable (0), force enable (1), 
optimus only default (-1
  int nouveau_runtime_pm = -1;
  module_param_named(runpm, nouveau_runtime_pm, int, 0400);

+MODULE_PARM_DESC(staging_tiling, enable staging GEM_SET_TILING ioctl);
+int nouveau_staging_tiling = 0;
+module_param_named(staging_tiling, nouveau_staging_tiling, int, 0600);


Please use _unsafe here to make sure that setting this option taints the
kernel and gives at least a bit of a deterrent. But in the end the policy
is still that you can't regress anything if people complain, which means
you might end up with a staging ioctl locked down forever.


That would kind of kill the whole purpose of this patchset. But at the 
same time the point of having staging ioctls is to say don't use them 
in production, so hopefully the message is clear.



The other part I don't like with this plan is that it looks a bit like it
could be easily abused to evade the open source userspace requirement
upstream has for new interfaces. Doesn't help that your first staging
ioctl doesn't come with links to mesa/hwc/whatever patches attached ;-)


Well, you could abuse it - no more than 8 times though. ;)

The point is not to evade anything though, but rather to have the 
necessary kernel code land in such a way that we can experiment with 
Mesa and other user-space.



Overall I don't think this will help - you need internal branch management
anyway, and upstreaming new ABI is somewhat painful for a reason: Screwing
things up is really expensive long-term, and the drm community has paid
that price a few too many times.


It seems to me that this staging feature can exactly help with that: 
allow new ioctls to mature a bit (no longer than a kernel release cycle) 
and avoid that ah, I wish we did this differently moment. But 
considering the number of ABIs I have driven so far (0), someone more 
experienced may challenge that belief.

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Bug 90967] [NV92] System freeze using nouveau

2015-06-15 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=90967

--- Comment #12 from homer...@gmail.com ---
Ok. I'm using debian SID. Do you have a procedure to downgrade libdrm-nouveau2
to 2.4.58 ?

I tried to add jessie and apt-get install libdrm-nouveau2=2.4.58-2 but I have
some dependencies problems with other packages (libdrm-dev, steam:i386, ...).
Maybe someone have a good couples of commands to do softly this downgrade ?

Otherwise, when do you think the problem will be solved ? There is already
someone who work on this bug ?

Thanks,
Anthony.

-- 
You are receiving this mail because:
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Bug 90888] A trivial fix for a potential crash

2015-06-15 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=90888

Ilia Mirkin imir...@alum.mit.edu changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #2 from Ilia Mirkin imir...@alum.mit.edu ---
Hrmph one small difference is that mkOp() appears to set the instruction
with -fixed = 1. I'm adding that in just in case it mattered in this case...
Converter::insertConvergenceOps seems to do this too. Now pushed. In the
future, you can just mail patches to nouveau@lists.freedesktop.org and/or
mesa-...@lists.freedesktop.org.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [Bug 90347] [NVE0+] Failure to insert texbar under some circumstances (causing bad colors in Terasology)

2015-06-15 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=90347

Ilia Mirkin imir...@alum.mit.edu changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #1 from Ilia Mirkin imir...@alum.mit.edu ---
Should be fixed by

commit a2af42c1d2dc91f4c31e25ff9fff15a89a9b6ead
Author: Ilia Mirkin imir...@alum.mit.edu
Date:   Fri Jun 12 16:09:05 2015 +0200

nvc0/ir: fix collection of first uses for texture barrier insertion

One of the places we have to insert texbars is in situations where the
result of the tex gets overwritten by a different instruction (e.g. in a
conditional statement). However in some situations it can actually
appear as though the original tex itself is an overwriting instruction.
This can naturally never really happen, so just ignore the tex
instruction when it comes up.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90347
Signed-off-by: Ilia Mirkin imir...@alum.mit.edu
Cc: 10.5 10.6 mesa-sta...@lists.freedesktop.org

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.
___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 0/2] drm/nouveau: option for staging ioctls and new GEM_SET_TILING ioctl

2015-06-15 Thread Alexandre Courbot
Second version of this patchset addressing Ben's comments and fixing a few
extra things.

This patchset proposes to introduce a staging module option to dynamically
enable features (mostly ioctls) that are merged but may be refined before
they are declared stable. The second patch illustrates the use of this
staging option with the SET_TILING ioctl, which can be used to specify the
tiling options of a PRIME-imported buffer.

The staging parameter will allow us (particularly, us at NVIDIA) to experiment
more freely with new features and avoid carrying out-of-tree patches for long
periods of time. To prevent abuse, the number of staging ioctls is limited to 8
(range 0x98 to 0xa0) that are to be recycled as staging ioctls become stable and
are assigned a final number.

Changes since v1:
- Use one module option per staging ioctl
- Only allow GEM_SET_TILING to be called on dma-buf imported buffers
- Move the code setting nvkm_mem::memtype into its own function to avoid
  duplicating code

Alexandre Courbot (1):
  drm/nouveau: placeholders for staging ioctls

Ari Hirvonen (1):
  drm/nouveau: add GEM_SET_TILING staging ioctl

 drm/nouveau/nouveau_bo.c   | 18 
 drm/nouveau/nouveau_bo.h   |  2 ++
 drm/nouveau/nouveau_drm.c  |  7 +
 drm/nouveau/nouveau_gem.c  | 58 ++
 drm/nouveau/nouveau_gem.h  |  2 ++
 drm/nouveau/nouveau_ttm.c  | 13 +
 drm/nouveau/uapi/drm/nouveau_drm.h | 11 
 7 files changed, 99 insertions(+), 12 deletions(-)

-- 
2.4.2

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 1/2] drm/nouveau: placeholders for staging ioctls

2015-06-15 Thread Alexandre Courbot
Reserve the 8 highest ioctls for staging features, i.e. ioctls that
may change or be dropped altogether and that thus should not be given a
definite number. This will allow us to experiment with experimental APIs
for a while before setting them in stone.

Staging ioctls are not expected to stay there for a long time, so we
limit their number. Besides, each staging ioctls needs to be explicitly
enabled through its own module option.

Signed-off-by: Alexandre Courbot acour...@nvidia.com
---
 drm/nouveau/nouveau_drm.c  | 1 +
 drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 63f1d39e8358..28860268cf38 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -896,6 +896,7 @@ nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
+   /* Staging ioctls */
 };
 
 long
diff --git a/drm/nouveau/uapi/drm/nouveau_drm.h 
b/drm/nouveau/uapi/drm/nouveau_drm.h
index 5507eead5863..4e7e21f41b5c 100644
--- a/drm/nouveau/uapi/drm/nouveau_drm.h
+++ b/drm/nouveau/uapi/drm/nouveau_drm.h
@@ -140,11 +140,14 @@ struct drm_nouveau_gem_cpu_fini {
 #define DRM_NOUVEAU_GEM_CPU_PREP   0x42
 #define DRM_NOUVEAU_GEM_CPU_FINI   0x43
 #define DRM_NOUVEAU_GEM_INFO   0x44
+/* range 0x98..DRM_COMMAND_END (8 entries) is reserved for staging, unstable 
ioctls */
+#define DRM_NOUVEAU_STAGING_IOCTL  0x58
 
 #define DRM_IOCTL_NOUVEAU_GEM_NEWDRM_IOWR(DRM_COMMAND_BASE + 
DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new)
 #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUFDRM_IOWR(DRM_COMMAND_BASE + 
DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf)
 #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP   DRM_IOW (DRM_COMMAND_BASE + 
DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep)
 #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI   DRM_IOW (DRM_COMMAND_BASE + 
DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini)
 #define DRM_IOCTL_NOUVEAU_GEM_INFO   DRM_IOWR(DRM_COMMAND_BASE + 
DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info)
+/* staging ioctls */
 
 #endif /* __NOUVEAU_DRM_H__ */
-- 
2.4.2

___
Nouveau mailing list
Nouveau@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/nouveau


[Nouveau] [PATCH v2 2/2] drm/nouveau: add GEM_SET_TILING staging ioctl

2015-06-15 Thread Alexandre Courbot
From: Ari Hirvonen ahirvo...@nvidia.com

Add new NOUVEAU_GEM_SET_TILING ioctl to set correct tiling
mode for imported dma-bufs. This ioctl is staging for now
and enabled with the staging_tiling module option.

Signed-off-by: Ari Hirvonen ahirvo...@nvidia.com
[acour...@nvidia.com: carry upstream, many fixes]
Signed-off-by: Alexandre Courbot acour...@nvidia.com
---
 drm/nouveau/nouveau_bo.c   | 18 
 drm/nouveau/nouveau_bo.h   |  2 ++
 drm/nouveau/nouveau_drm.c  |  6 
 drm/nouveau/nouveau_gem.c  | 58 ++
 drm/nouveau/nouveau_gem.h  |  2 ++
 drm/nouveau/nouveau_ttm.c  | 13 +
 drm/nouveau/uapi/drm/nouveau_drm.h |  8 ++
 7 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/drm/nouveau/nouveau_bo.c b/drm/nouveau/nouveau_bo.c
index 6edcce1658b7..2a2ebbeb4fc0 100644
--- a/drm/nouveau/nouveau_bo.c
+++ b/drm/nouveau/nouveau_bo.c
@@ -178,6 +178,24 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
*size = roundup(*size, PAGE_SIZE);
 }
 
+void
+nouveau_bo_update_tiling(struct nouveau_drm *drm, struct nouveau_bo *nvbo,
+struct nvkm_mem *mem)
+{
+   switch (drm-device.info.family) {
+   case NV_DEVICE_INFO_V0_TESLA:
+   if (drm-device.info.chipset != 0x50)
+   mem-memtype = (nvbo-tile_flags  0x7f00)  8;
+   break;
+   case NV_DEVICE_INFO_V0_FERMI:
+   case NV_DEVICE_INFO_V0_KEPLER:
+   mem-memtype = (nvbo-tile_flags  0xff00)  8;
+   break;
+   default:
+   break;
+   }
+}
+
 int
 nouveau_bo_new(struct drm_device *dev, int size, int align,
   uint32_t flags, uint32_t tile_mode, uint32_t tile_flags,
diff --git a/drm/nouveau/nouveau_bo.h b/drm/nouveau/nouveau_bo.h
index e42360983229..87d07e3533eb 100644
--- a/drm/nouveau/nouveau_bo.h
+++ b/drm/nouveau/nouveau_bo.h
@@ -69,6 +69,8 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo 
**pnvbo)
 extern struct ttm_bo_driver nouveau_bo_driver;
 
 void nouveau_bo_move_init(struct nouveau_drm *);
+void nouveau_bo_update_tiling(struct nouveau_drm *, struct nouveau_bo *,
+ struct nvkm_mem *);
 int  nouveau_bo_new(struct drm_device *, int size, int align, u32 flags,
u32 tile_mode, u32 tile_flags, struct sg_table *sg,
struct reservation_object *robj,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 28860268cf38..45a2c88ebf8e 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, disable (0), force enable (1), 
optimus only default (-1
 int nouveau_runtime_pm = -1;
 module_param_named(runpm, nouveau_runtime_pm, int, 0400);
 
+MODULE_PARM_DESC(staging_tiling, enable staging GEM_SET_TILING ioctl);
+int nouveau_staging_tiling = 0;
+module_param_named(staging_tiling, nouveau_staging_tiling, int, 0600);
+
 static struct drm_driver driver_stub;
 static struct drm_driver driver_pci;
 static struct drm_driver driver_platform;
@@ -897,6 +901,7 @@ nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
/* Staging ioctls */
+   DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_SET_TILING, nouveau_gem_ioctl_set_tiling, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
 };
 
 long
@@ -1029,6 +1034,7 @@ static void nouveau_display_options(void)
DRM_DEBUG_DRIVER(... runpm: %d\n, nouveau_runtime_pm);
DRM_DEBUG_DRIVER(... vram_pushbuf : %d\n, nouveau_vram_pushbuf);
DRM_DEBUG_DRIVER(... pstate   : %d\n, nouveau_pstate);
+   DRM_DEBUG_DRIVER(... staging_tiling: %d\n, nouveau_staging_tiling);
 }
 
 static const struct dev_pm_ops nouveau_pm_ops = {
diff --git a/drm/nouveau/nouveau_gem.c b/drm/nouveau/nouveau_gem.c
index 0e690bf19fc9..0e69449798aa 100644
--- a/drm/nouveau/nouveau_gem.c
+++ b/drm/nouveau/nouveau_gem.c
@@ -172,6 +172,64 @@ nouveau_gem_object_close(struct drm_gem_object *gem, 
struct drm_file *file_priv)
ttm_bo_unreserve(nvbo-bo);
 }
 
+extern int nouveau_staging_tiling;
+int
+nouveau_gem_ioctl_set_tiling(struct drm_device *dev, void *data,
+struct drm_file *file_priv)
+{
+   struct nouveau_drm *drm = nouveau_drm(dev);
+   struct nouveau_cli *cli = nouveau_cli(file_priv);
+   struct nvkm_fb *pfb = nvxx_fb(drm-device);
+   struct drm_nouveau_gem_set_tiling *req = data;
+   struct drm_gem_object *gem;
+   struct nouveau_bo *nvbo;
+   struct nvkm_vma *vma;
+   int ret = 0;
+
+   if (!nouveau_staging_tiling)
+   return -EINVAL;
+
+   if (!pfb-memtype_valid(pfb, req-tile_flags)) {
+   NV_PRINTK(error, cli, bad page flags: 0x%08x\n, 
req-tile_flags);
+  

Re: [Nouveau] [PATCH v2 2/2] drm/nouveau: add GEM_SET_TILING staging ioctl

2015-06-15 Thread Alexandre Courbot

On 06/15/2015 04:09 PM, Alexandre Courbot wrote:

From: Ari Hirvonen ahirvo...@nvidia.com

Add new NOUVEAU_GEM_SET_TILING ioctl to set correct tiling
mode for imported dma-bufs. This ioctl is staging for now
and enabled with the staging_tiling module option.


Adding Thierry to the conversation since he knows best about exported 
buffers and attributes. I wonder if this would not better be done at the 
time the buffer gets imported. It seems to me that this would be a more 
appropriate way than having an ioctl dedicated to this. Thierry, would 
you have any input based on your experience with tegradrm? In the end, 
it seems like you have settled for a similar ioctl to set the tiling 
mode of displayed buffers.




Signed-off-by: Ari Hirvonen ahirvo...@nvidia.com
[acour...@nvidia.com: carry upstream, many fixes]
Signed-off-by: Alexandre Courbot acour...@nvidia.com
---
  drm/nouveau/nouveau_bo.c   | 18 
  drm/nouveau/nouveau_bo.h   |  2 ++
  drm/nouveau/nouveau_drm.c  |  6 
  drm/nouveau/nouveau_gem.c  | 58 ++
  drm/nouveau/nouveau_gem.h  |  2 ++
  drm/nouveau/nouveau_ttm.c  | 13 +
  drm/nouveau/uapi/drm/nouveau_drm.h |  8 ++
  7 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/drm/nouveau/nouveau_bo.c b/drm/nouveau/nouveau_bo.c
index 6edcce1658b7..2a2ebbeb4fc0 100644
--- a/drm/nouveau/nouveau_bo.c
+++ b/drm/nouveau/nouveau_bo.c
@@ -178,6 +178,24 @@ nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
*size = roundup(*size, PAGE_SIZE);
  }

+void
+nouveau_bo_update_tiling(struct nouveau_drm *drm, struct nouveau_bo *nvbo,
+struct nvkm_mem *mem)
+{
+   switch (drm-device.info.family) {
+   case NV_DEVICE_INFO_V0_TESLA:
+   if (drm-device.info.chipset != 0x50)
+   mem-memtype = (nvbo-tile_flags  0x7f00)  8;
+   break;
+   case NV_DEVICE_INFO_V0_FERMI:
+   case NV_DEVICE_INFO_V0_KEPLER:
+   mem-memtype = (nvbo-tile_flags  0xff00)  8;
+   break;
+   default:
+   break;
+   }
+}
+
  int
  nouveau_bo_new(struct drm_device *dev, int size, int align,
   uint32_t flags, uint32_t tile_mode, uint32_t tile_flags,
diff --git a/drm/nouveau/nouveau_bo.h b/drm/nouveau/nouveau_bo.h
index e42360983229..87d07e3533eb 100644
--- a/drm/nouveau/nouveau_bo.h
+++ b/drm/nouveau/nouveau_bo.h
@@ -69,6 +69,8 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo 
**pnvbo)
  extern struct ttm_bo_driver nouveau_bo_driver;

  void nouveau_bo_move_init(struct nouveau_drm *);
+void nouveau_bo_update_tiling(struct nouveau_drm *, struct nouveau_bo *,
+ struct nvkm_mem *);
  int  nouveau_bo_new(struct drm_device *, int size, int align, u32 flags,
u32 tile_mode, u32 tile_flags, struct sg_table *sg,
struct reservation_object *robj,
diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c
index 28860268cf38..45a2c88ebf8e 100644
--- a/drm/nouveau/nouveau_drm.c
+++ b/drm/nouveau/nouveau_drm.c
@@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, disable (0), force enable (1), 
optimus only default (-1
  int nouveau_runtime_pm = -1;
  module_param_named(runpm, nouveau_runtime_pm, int, 0400);

+MODULE_PARM_DESC(staging_tiling, enable staging GEM_SET_TILING ioctl);
+int nouveau_staging_tiling = 0;
+module_param_named(staging_tiling, nouveau_staging_tiling, int, 0600);
+
  static struct drm_driver driver_stub;
  static struct drm_driver driver_pci;
  static struct drm_driver driver_platform;
@@ -897,6 +901,7 @@ nouveau_ioctls[] = {
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
/* Staging ioctls */
+   DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_SET_TILING, nouveau_gem_ioctl_set_tiling, 
DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW),
  };

  long
@@ -1029,6 +1034,7 @@ static void nouveau_display_options(void)
DRM_DEBUG_DRIVER(... runpm: %d\n, nouveau_runtime_pm);
DRM_DEBUG_DRIVER(... vram_pushbuf : %d\n, nouveau_vram_pushbuf);
DRM_DEBUG_DRIVER(... pstate   : %d\n, nouveau_pstate);
+   DRM_DEBUG_DRIVER(... staging_tiling: %d\n, nouveau_staging_tiling);
  }

  static const struct dev_pm_ops nouveau_pm_ops = {
diff --git a/drm/nouveau/nouveau_gem.c b/drm/nouveau/nouveau_gem.c
index 0e690bf19fc9..0e69449798aa 100644
--- a/drm/nouveau/nouveau_gem.c
+++ b/drm/nouveau/nouveau_gem.c
@@ -172,6 +172,64 @@ nouveau_gem_object_close(struct drm_gem_object *gem, 
struct drm_file *file_priv)
ttm_bo_unreserve(nvbo-bo);
  }

+extern int nouveau_staging_tiling;
+int
+nouveau_gem_ioctl_set_tiling(struct drm_device *dev, void *data,
+struct drm_file *file_priv)
+{
+   struct