diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 3621e7f23477da53b7af04edc60af11fe6f5d1ee..6828d81ed7b99daea875ffd06c4dd399d4aa05dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -298,7 +298,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) else init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; - if (device->card_type < NV_C0) { + if (device->card_type < NV_10) { init->subchan[0].handle = 0x00000000; init->subchan[0].grclass = 0x0000; init->subchan[1].handle = NvSw; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index e84f4c32331bf291f7cd3eeb3f253cd8fd543f37..cc5152be2cf121a0901d323bf41b57886b56b27a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -346,22 +346,17 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) OUT_RING(chan, 0x00000000); - /* allocate software object class (used for fences on <= nv05, and - * to signal flip completion), bind it to a subchannel. - */ - if ((device->card_type < NV_E0) || gart /* nve0: want_nvsw */) { + /* allocate software object class (used for fences on <= nv05) */ + if (device->card_type < NV_10) { ret = nouveau_object_new(nv_object(client), chan->handle, - NvSw, nouveau_abi16_swclass(chan->drm), - NULL, 0, &object); + NvSw, 0x006e, NULL, 0, &object); if (ret) return ret; swch = (void *)object->parent; swch->flip = nouveau_flip_complete; swch->flip_data = chan; - } - if (device->card_type < NV_C0) { ret = RING_SPACE(chan, 2); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 2418b0de589eb631b4fc7e3297c78bdce5557e45..7a3759f1c41a67bac6b48cdcfd5b10b5ac30ae39 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -191,6 +192,32 @@ nouveau_accel_init(struct nouveau_drm *drm) return; } + ret = nouveau_object_new(nv_object(drm), NVDRM_CHAN, NVDRM_NVSW, + nouveau_abi16_swclass(drm), NULL, 0, &object); + if (ret == 0) { + struct nouveau_software_chan *swch = (void *)object->parent; + ret = RING_SPACE(drm->channel, 2); + if (ret == 0) { + if (device->card_type < NV_C0) { + BEGIN_NV04(drm->channel, NvSubSw, 0, 1); + OUT_RING (drm->channel, NVDRM_NVSW); + } else + if (device->card_type < NV_E0) { + BEGIN_NVC0(drm->channel, FermiSw, 0, 1); + OUT_RING (drm->channel, 0x001f0000); + } + } + swch = (void *)object->parent; + swch->flip = nouveau_flip_complete; + swch->flip_data = drm->channel; + } + + if (ret) { + NV_ERROR(drm, "failed to allocate software object, %d\n", ret); + nouveau_accel_fini(drm); + return; + } + if (device->card_type < NV_C0) { ret = nouveau_gpuobj_new(drm->device, NULL, 32, 0, 0, &drm->notify); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 71ed2dadae61cc7f6e1789fbf58b318538694d49..4b0fb6c66be918857bc6529b3a7c5a7c7a49a498 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -56,6 +56,7 @@ enum nouveau_drm_handle { NVDRM_CONTROL = 0xdddddddc, NVDRM_PUSH = 0xbbbb0000, /* |= client chid */ NVDRM_CHAN = 0xcccc0000, /* |= client chid */ + NVDRM_NVSW = 0x55550000, }; struct nouveau_cli {