aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-07-09 00:20:15 -0400
committerBen Skeggs <bskeggs@redhat.com>2013-07-09 20:48:01 -0400
commit00fc6f6f731efb7b76b839598e494b01890d901d (patch)
treee23c7501a572dbfce5217d18d7f3e5e01c18b2ee /drivers/gpu/drm
parent06b237ef3903a0a5e33785105ea5203153323dd8 (diff)
drm/nouveau: use dedicated channel for async moves on GT/GF chipsets.
The moves themselves were generally async to graphics previously, with the exception that if the "main" channel is used to synchronise a page flip at the same time, it can end up blocked for a noticable amount of time for large buffer moves. Not really critical, and there's better ways of handling this, but they are all rather invasive, so this is fine for now. Based on a patch by Maarten Lankhorst addressing the same issue. Reported-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Acked-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c12
2 files changed, 15 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 824a98811de6..459a44550ce5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -581,7 +581,7 @@ nve0_bo_move_init(struct nouveau_channel *chan, u32 handle)
581 int ret = RING_SPACE(chan, 2); 581 int ret = RING_SPACE(chan, 2);
582 if (ret == 0) { 582 if (ret == 0) {
583 BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1); 583 BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
584 OUT_RING (chan, handle); 584 OUT_RING (chan, handle & 0x0000ffff);
585 FIRE_RING (chan); 585 FIRE_RING (chan);
586 } 586 }
587 return ret; 587 return ret;
@@ -1017,7 +1017,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
1017 struct ttm_mem_reg *, struct ttm_mem_reg *); 1017 struct ttm_mem_reg *, struct ttm_mem_reg *);
1018 int (*init)(struct nouveau_channel *, u32 handle); 1018 int (*init)(struct nouveau_channel *, u32 handle);
1019 } _methods[] = { 1019 } _methods[] = {
1020 { "COPY", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init }, 1020 { "COPY", 4, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
1021 { "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init }, 1021 { "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
1022 { "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init }, 1022 { "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
1023 { "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init }, 1023 { "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init },
@@ -1037,7 +1037,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
1037 struct nouveau_channel *chan; 1037 struct nouveau_channel *chan;
1038 u32 handle = (mthd->engine << 16) | mthd->oclass; 1038 u32 handle = (mthd->engine << 16) | mthd->oclass;
1039 1039
1040 if (mthd->init == nve0_bo_move_init) 1040 if (mthd->engine)
1041 chan = drm->cechan; 1041 chan = drm->cechan;
1042 else 1042 else
1043 chan = drm->channel; 1043 chan = drm->channel;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 4eca52b8d573..61972668fd05 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -192,6 +192,18 @@ nouveau_accel_init(struct nouveau_drm *drm)
192 192
193 arg0 = NVE0_CHANNEL_IND_ENGINE_GR; 193 arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
194 arg1 = 1; 194 arg1 = 1;
195 } else
196 if (device->chipset >= 0xa3 &&
197 device->chipset != 0xaa &&
198 device->chipset != 0xac) {
199 ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
200 NVDRM_CHAN + 1, NvDmaFB, NvDmaTT,
201 &drm->cechan);
202 if (ret)
203 NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
204
205 arg0 = NvDmaFB;
206 arg1 = NvDmaTT;
195 } else { 207 } else {
196 arg0 = NvDmaFB; 208 arg0 = NvDmaFB;
197 arg1 = NvDmaTT; 209 arg1 = NvDmaTT;