[PATCH 13/13] drm/nouveau: enable the TTM DMA pool on 32-bit DMA only device V2
From: Konrad Rzeszutek WilkIf the card is capable of more than 32-bit, then use the default TTM page pool code which allocates from anywhere in the memory. Note: If the 'ttm.no_dma' parameter is set, the override is ignored and the default TTM pool is used. V2 use pci_set_consistent_dma_mask CC: Ben Skeggs CC: Francisco Jerez CC: Dave Airlie Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: Jerome Glisse --- drivers/gpu/drm/nouveau/nouveau_bo.c | 73 - drivers/gpu/drm/nouveau/nouveau_debugfs.c |1 + drivers/gpu/drm/nouveau/nouveau_mem.c |6 ++ drivers/gpu/drm/nouveau/nouveau_sgdma.c | 60 +--- 4 files changed, 79 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7e5ca3f..36234a7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1049,10 +1049,79 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence) nouveau_fence_unref(_fence); } +static int +nouveau_ttm_tt_populate(struct ttm_tt *ttm) +{ + struct drm_nouveau_private *dev_priv; + struct drm_device *dev; + unsigned i; + int r; + + if (ttm->state != tt_unpopulated) + return 0; + + dev_priv = nouveau_bdev(ttm->bdev); + dev = dev_priv->dev; + +#ifdef CONFIG_SWIOTLB + if ((dma_get_mask(dev->dev) <= DMA_BIT_MASK(32)) && swiotlb_nr_tbl()) { + return ttm_dma_populate(ttm, dev->dev); + } +#endif + + r = ttm_page_alloc_ttm_tt_populate(ttm); + if (r) { + return r; + } + + for (i = 0; i < ttm->num_pages; i++) { + ttm->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i], + 0, PAGE_SIZE, + PCI_DMA_BIDIRECTIONAL); + if (pci_dma_mapping_error(dev->pdev, ttm->dma_address[i])) { + while (--i) { + pci_unmap_page(dev->pdev, ttm->dma_address[i], + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + ttm->dma_address[i] = 0; + } + ttm_page_alloc_ttm_tt_unpopulate(ttm); + return -EFAULT; + } + } + return 0; +} + +static void +nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) +{ + struct drm_nouveau_private *dev_priv; + struct drm_device *dev; + unsigned i; + + dev_priv = nouveau_bdev(ttm->bdev); + dev = dev_priv->dev; + +#ifdef CONFIG_SWIOTLB + if ((dma_get_mask(dev->dev) <= DMA_BIT_MASK(32)) && swiotlb_nr_tbl()) { + ttm_dma_unpopulate(ttm, dev->dev); + return; + } +#endif + + for (i = 0; i < ttm->num_pages; i++) { + if (ttm->dma_address[i]) { + pci_unmap_page(dev->pdev, ttm->dma_address[i], + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + } + } + + ttm_page_alloc_ttm_tt_unpopulate(ttm); +} + struct ttm_bo_driver nouveau_bo_driver = { .ttm_tt_create = _ttm_tt_create, - .ttm_tt_populate = _page_alloc_ttm_tt_populate, - .ttm_tt_unpopulate = _page_alloc_ttm_tt_unpopulate, + .ttm_tt_populate = _ttm_tt_populate, + .ttm_tt_unpopulate = _ttm_tt_unpopulate, .invalidate_caches = nouveau_bo_invalidate_caches, .init_mem_type = nouveau_bo_init_mem_type, .evict_flags = nouveau_bo_evict_flags, diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 8e15923..f52c2db 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -178,6 +178,7 @@ static struct drm_info_list nouveau_debugfs_list[] = { { "memory", nouveau_debugfs_memory_info, 0, NULL }, { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, { "ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL }, + { "ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL }, }; #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 36bec48..37fcaa2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -407,6 +407,12 @@ nouveau_mem_vram_init(struct drm_device *dev) ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); if (ret) return ret; + ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(dma_bits)); + if (ret) { + /* Reset to default value. */ + pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32)); + } + ret = nouveau_ttm_global_init(dev_priv); if
[PATCH 13/13] drm/nouveau: enable the TTM DMA pool on 32-bit DMA only device V2
From: Konrad Rzeszutek Wilk konrad.w...@oracle.com If the card is capable of more than 32-bit, then use the default TTM page pool code which allocates from anywhere in the memory. Note: If the 'ttm.no_dma' parameter is set, the override is ignored and the default TTM pool is used. V2 use pci_set_consistent_dma_mask CC: Ben Skeggs bske...@redhat.com CC: Francisco Jerez curroje...@riseup.net CC: Dave Airlie airl...@redhat.com Signed-off-by: Konrad Rzeszutek Wilk konrad.w...@oracle.com Reviewed-by: Jerome Glisse jgli...@redhat.com --- drivers/gpu/drm/nouveau/nouveau_bo.c | 73 - drivers/gpu/drm/nouveau/nouveau_debugfs.c |1 + drivers/gpu/drm/nouveau/nouveau_mem.c |6 ++ drivers/gpu/drm/nouveau/nouveau_sgdma.c | 60 +--- 4 files changed, 79 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7e5ca3f..36234a7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1049,10 +1049,79 @@ nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence) nouveau_fence_unref(old_fence); } +static int +nouveau_ttm_tt_populate(struct ttm_tt *ttm) +{ + struct drm_nouveau_private *dev_priv; + struct drm_device *dev; + unsigned i; + int r; + + if (ttm-state != tt_unpopulated) + return 0; + + dev_priv = nouveau_bdev(ttm-bdev); + dev = dev_priv-dev; + +#ifdef CONFIG_SWIOTLB + if ((dma_get_mask(dev-dev) = DMA_BIT_MASK(32)) swiotlb_nr_tbl()) { + return ttm_dma_populate(ttm, dev-dev); + } +#endif + + r = ttm_page_alloc_ttm_tt_populate(ttm); + if (r) { + return r; + } + + for (i = 0; i ttm-num_pages; i++) { + ttm-dma_address[i] = pci_map_page(dev-pdev, ttm-pages[i], + 0, PAGE_SIZE, + PCI_DMA_BIDIRECTIONAL); + if (pci_dma_mapping_error(dev-pdev, ttm-dma_address[i])) { + while (--i) { + pci_unmap_page(dev-pdev, ttm-dma_address[i], + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + ttm-dma_address[i] = 0; + } + ttm_page_alloc_ttm_tt_unpopulate(ttm); + return -EFAULT; + } + } + return 0; +} + +static void +nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) +{ + struct drm_nouveau_private *dev_priv; + struct drm_device *dev; + unsigned i; + + dev_priv = nouveau_bdev(ttm-bdev); + dev = dev_priv-dev; + +#ifdef CONFIG_SWIOTLB + if ((dma_get_mask(dev-dev) = DMA_BIT_MASK(32)) swiotlb_nr_tbl()) { + ttm_dma_unpopulate(ttm, dev-dev); + return; + } +#endif + + for (i = 0; i ttm-num_pages; i++) { + if (ttm-dma_address[i]) { + pci_unmap_page(dev-pdev, ttm-dma_address[i], + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + } + } + + ttm_page_alloc_ttm_tt_unpopulate(ttm); +} + struct ttm_bo_driver nouveau_bo_driver = { .ttm_tt_create = nouveau_ttm_tt_create, - .ttm_tt_populate = ttm_page_alloc_ttm_tt_populate, - .ttm_tt_unpopulate = ttm_page_alloc_ttm_tt_unpopulate, + .ttm_tt_populate = nouveau_ttm_tt_populate, + .ttm_tt_unpopulate = nouveau_ttm_tt_unpopulate, .invalidate_caches = nouveau_bo_invalidate_caches, .init_mem_type = nouveau_bo_init_mem_type, .evict_flags = nouveau_bo_evict_flags, diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 8e15923..f52c2db 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -178,6 +178,7 @@ static struct drm_info_list nouveau_debugfs_list[] = { { memory, nouveau_debugfs_memory_info, 0, NULL }, { vbios.rom, nouveau_debugfs_vbios_image, 0, NULL }, { ttm_page_pool, ttm_page_alloc_debugfs, 0, NULL }, + { ttm_dma_page_pool, ttm_dma_page_alloc_debugfs, 0, NULL }, }; #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 36bec48..37fcaa2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -407,6 +407,12 @@ nouveau_mem_vram_init(struct drm_device *dev) ret = pci_set_dma_mask(dev-pdev, DMA_BIT_MASK(dma_bits)); if (ret) return ret; + ret = pci_set_consistent_dma_mask(dev-pdev, DMA_BIT_MASK(dma_bits)); + if (ret) { + /* Reset to default value. */ + pci_set_consistent_dma_mask(dev-pdev,