|
@@ -142,89 +142,184 @@ nvd0_dmac_destroy(struct nouveau_object *core, struct nvd0_dmac *dmac)
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-nvd0_dmac_create(struct nouveau_object *core, u32 bclass, u8 head,
|
|
|
- void *data, u32 size, u64 syncbuf,
|
|
|
- struct nvd0_dmac *dmac)
|
|
|
+nv50_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
|
|
|
{
|
|
|
struct nouveau_fb *pfb = nouveau_fb(core);
|
|
|
struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS);
|
|
|
struct nouveau_object *object;
|
|
|
- u32 pushbuf = *(u32 *)data;
|
|
|
- dma_addr_t handle;
|
|
|
- void *ptr;
|
|
|
- int ret;
|
|
|
-
|
|
|
- ptr = pci_alloc_consistent(nv_device(core)->pdev, PAGE_SIZE, &handle);
|
|
|
- if (!ptr)
|
|
|
- return -ENOMEM;
|
|
|
+ int ret = nouveau_object_new(client, parent, NvEvoVRAM_LP,
|
|
|
+ NV_DMA_IN_MEMORY_CLASS,
|
|
|
+ &(struct nv_dma_class) {
|
|
|
+ .flags = NV_DMA_TARGET_VRAM |
|
|
|
+ NV_DMA_ACCESS_RDWR,
|
|
|
+ .start = 0,
|
|
|
+ .limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NV50_DMA_CONF0_ENABLE |
|
|
|
+ NV50_DMA_CONF0_PART_256,
|
|
|
+ }, sizeof(struct nv_dma_class), &object);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
|
|
|
- ret = nouveau_object_new(client, NVDRM_DEVICE, pushbuf,
|
|
|
- NV_DMA_FROM_MEMORY_CLASS,
|
|
|
+ ret = nouveau_object_new(client, parent, NvEvoFB16,
|
|
|
+ NV_DMA_IN_MEMORY_CLASS,
|
|
|
&(struct nv_dma_class) {
|
|
|
- .flags = NV_DMA_TARGET_PCI_US |
|
|
|
- NV_DMA_ACCESS_RD,
|
|
|
- .start = handle + 0x0000,
|
|
|
- .limit = handle + 0x0fff,
|
|
|
+ .flags = NV_DMA_TARGET_VRAM |
|
|
|
+ NV_DMA_ACCESS_RDWR,
|
|
|
+ .start = 0,
|
|
|
+ .limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NV50_DMA_CONF0_ENABLE | 0x70 |
|
|
|
+ NV50_DMA_CONF0_PART_256,
|
|
|
}, sizeof(struct nv_dma_class), &object);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- ret = nvd0_chan_create(core, bclass, head, data, size, &dmac->base);
|
|
|
+ ret = nouveau_object_new(client, parent, NvEvoFB32,
|
|
|
+ NV_DMA_IN_MEMORY_CLASS,
|
|
|
+ &(struct nv_dma_class) {
|
|
|
+ .flags = NV_DMA_TARGET_VRAM |
|
|
|
+ NV_DMA_ACCESS_RDWR,
|
|
|
+ .start = 0,
|
|
|
+ .limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NV50_DMA_CONF0_ENABLE | 0x7a |
|
|
|
+ NV50_DMA_CONF0_PART_256,
|
|
|
+ }, sizeof(struct nv_dma_class), &object);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+nvc0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
|
|
|
+{
|
|
|
+ struct nouveau_fb *pfb = nouveau_fb(core);
|
|
|
+ struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS);
|
|
|
+ struct nouveau_object *object;
|
|
|
+ int ret = nouveau_object_new(client, parent, NvEvoVRAM_LP,
|
|
|
+ NV_DMA_IN_MEMORY_CLASS,
|
|
|
+ &(struct nv_dma_class) {
|
|
|
+ .flags = NV_DMA_TARGET_VRAM |
|
|
|
+ NV_DMA_ACCESS_RDWR,
|
|
|
+ .start = 0,
|
|
|
+ .limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NVC0_DMA_CONF0_ENABLE,
|
|
|
+ }, sizeof(struct nv_dma_class), &object);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
- dmac->handle = handle;
|
|
|
- dmac->ptr = ptr;
|
|
|
-
|
|
|
- ret = nouveau_object_new(client, dmac->base.handle, NvEvoSync,
|
|
|
+ ret = nouveau_object_new(client, parent, NvEvoFB16,
|
|
|
NV_DMA_IN_MEMORY_CLASS,
|
|
|
&(struct nv_dma_class) {
|
|
|
.flags = NV_DMA_TARGET_VRAM |
|
|
|
NV_DMA_ACCESS_RDWR,
|
|
|
- .start = syncbuf + 0x0000,
|
|
|
- .limit = syncbuf + 0x0fff,
|
|
|
+ .start = 0,
|
|
|
+ .limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NVC0_DMA_CONF0_ENABLE | 0xfe,
|
|
|
}, sizeof(struct nv_dma_class), &object);
|
|
|
if (ret)
|
|
|
- goto out;
|
|
|
+ return ret;
|
|
|
|
|
|
- ret = nouveau_object_new(client, dmac->base.handle, NvEvoVRAM,
|
|
|
+ ret = nouveau_object_new(client, parent, NvEvoFB32,
|
|
|
NV_DMA_IN_MEMORY_CLASS,
|
|
|
&(struct nv_dma_class) {
|
|
|
.flags = NV_DMA_TARGET_VRAM |
|
|
|
NV_DMA_ACCESS_RDWR,
|
|
|
.start = 0,
|
|
|
.limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NVC0_DMA_CONF0_ENABLE | 0xfe,
|
|
|
}, sizeof(struct nv_dma_class), &object);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+nvd0_dmac_create_fbdma(struct nouveau_object *core, u32 parent)
|
|
|
+{
|
|
|
+ struct nouveau_fb *pfb = nouveau_fb(core);
|
|
|
+ struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS);
|
|
|
+ struct nouveau_object *object;
|
|
|
+ int ret = nouveau_object_new(client, parent, NvEvoVRAM_LP,
|
|
|
+ NV_DMA_IN_MEMORY_CLASS,
|
|
|
+ &(struct nv_dma_class) {
|
|
|
+ .flags = NV_DMA_TARGET_VRAM |
|
|
|
+ NV_DMA_ACCESS_RDWR,
|
|
|
+ .start = 0,
|
|
|
+ .limit = pfb->ram.size - 1,
|
|
|
+ .conf0 = NVD0_DMA_CONF0_ENABLE |
|
|
|
+ NVD0_DMA_CONF0_PAGE_LP,
|
|
|
+ }, sizeof(struct nv_dma_class), &object);
|
|
|
if (ret)
|
|
|
- goto out;
|
|
|
+ return ret;
|
|
|
|
|
|
- ret = nouveau_object_new(client, dmac->base.handle, NvEvoVRAM_LP,
|
|
|
+ ret = nouveau_object_new(client, parent, NvEvoFB32,
|
|
|
NV_DMA_IN_MEMORY_CLASS,
|
|
|
&(struct nv_dma_class) {
|
|
|
.flags = NV_DMA_TARGET_VRAM |
|
|
|
NV_DMA_ACCESS_RDWR,
|
|
|
.start = 0,
|
|
|
.limit = pfb->ram.size - 1,
|
|
|
- .conf0 = NVD0_DMA_CONF0_ENABLE |
|
|
|
+ .conf0 = NVD0_DMA_CONF0_ENABLE | 0xfe |
|
|
|
NVD0_DMA_CONF0_PAGE_LP,
|
|
|
}, sizeof(struct nv_dma_class), &object);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static int
|
|
|
+nvd0_dmac_create(struct nouveau_object *core, u32 bclass, u8 head,
|
|
|
+ void *data, u32 size, u64 syncbuf,
|
|
|
+ struct nvd0_dmac *dmac)
|
|
|
+{
|
|
|
+ struct nouveau_fb *pfb = nouveau_fb(core);
|
|
|
+ struct nouveau_object *client = nv_pclass(core, NV_CLIENT_CLASS);
|
|
|
+ struct nouveau_object *object;
|
|
|
+ u32 pushbuf = *(u32 *)data;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ dmac->ptr = pci_alloc_consistent(nv_device(core)->pdev, PAGE_SIZE,
|
|
|
+ &dmac->handle);
|
|
|
+ if (!dmac->ptr)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ ret = nouveau_object_new(client, NVDRM_DEVICE, pushbuf,
|
|
|
+ NV_DMA_FROM_MEMORY_CLASS,
|
|
|
+ &(struct nv_dma_class) {
|
|
|
+ .flags = NV_DMA_TARGET_PCI_US |
|
|
|
+ NV_DMA_ACCESS_RD,
|
|
|
+ .start = dmac->handle + 0x0000,
|
|
|
+ .limit = dmac->handle + 0x0fff,
|
|
|
+ }, sizeof(struct nv_dma_class), &object);
|
|
|
if (ret)
|
|
|
- goto out;
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ ret = nvd0_chan_create(core, bclass, head, data, size, &dmac->base);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ ret = nouveau_object_new(client, dmac->base.handle, NvEvoSync,
|
|
|
+ NV_DMA_IN_MEMORY_CLASS,
|
|
|
+ &(struct nv_dma_class) {
|
|
|
+ .flags = NV_DMA_TARGET_VRAM |
|
|
|
+ NV_DMA_ACCESS_RDWR,
|
|
|
+ .start = syncbuf + 0x0000,
|
|
|
+ .limit = syncbuf + 0x0fff,
|
|
|
+ }, sizeof(struct nv_dma_class), &object);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
|
|
|
- ret = nouveau_object_new(client, dmac->base.handle, NvEvoFB32,
|
|
|
+ ret = nouveau_object_new(client, dmac->base.handle, NvEvoVRAM,
|
|
|
NV_DMA_IN_MEMORY_CLASS,
|
|
|
&(struct nv_dma_class) {
|
|
|
.flags = NV_DMA_TARGET_VRAM |
|
|
|
NV_DMA_ACCESS_RDWR,
|
|
|
.start = 0,
|
|
|
.limit = pfb->ram.size - 1,
|
|
|
- .conf0 = 0x00fe |
|
|
|
- NVD0_DMA_CONF0_ENABLE |
|
|
|
- NVD0_DMA_CONF0_PAGE_LP,
|
|
|
}, sizeof(struct nv_dma_class), &object);
|
|
|
-out:
|
|
|
if (ret)
|
|
|
- nvd0_dmac_destroy(core, dmac);
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ if (nv_device(core)->card_type < NV_C0)
|
|
|
+ ret = nv50_dmac_create_fbdma(core, dmac->base.handle);
|
|
|
+ else
|
|
|
+ if (nv_device(core)->card_type < NV_D0)
|
|
|
+ ret = nvc0_dmac_create_fbdma(core, dmac->base.handle);
|
|
|
+ else
|
|
|
+ ret = nvd0_dmac_create_fbdma(core, dmac->base.handle);
|
|
|
return ret;
|
|
|
}
|
|
|
|