static int check_fb_gem_memory_type(struct drm_device *drm_dev, struct exynos_drm_gem_obj *exynos_gem_obj) { unsigned int flags; /* * if exynos drm driver supports iommu then framebuffer can use * all the buffer types. */ if (is_drm_iommu_supported(drm_dev)) return 0; flags = exynos_gem_obj->flags; /* * without iommu support, not support physically non-continuous memory * for framebuffer. */ if (IS_NONCONTIG_BUFFER(flags)) { DRM_ERROR("cannot use this gem memory type for fb.\n"); return -EINVAL; } return 0; }
static void lowlevel_buffer_deallocate(struct drm_device *dev, unsigned int flags, struct rockchip_drm_gem_buf *buf) { DRM_DEBUG_KMS("%s.\n", __FILE__); if (!buf->dma_addr) { DRM_DEBUG_KMS("dma_addr is invalid.\n"); return; } DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->dma_addr, buf->size); sg_free_table(buf->sgt); kfree(buf->sgt); buf->sgt = NULL; if (!is_drm_iommu_supported(dev)) { dma_free_attrs(dev->dev, buf->size, buf->kvaddr, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); kfree(buf->pages); } else dma_free_attrs(dev->dev, buf->size, buf->pages, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); buf->dma_addr = (dma_addr_t)NULL; }
static int check_fb_gem_memory_type(struct drm_device *drm_dev, struct exynos_drm_gem *exynos_gem) { unsigned int flags; /* * if exynos drm driver supports iommu then framebuffer can use * all the buffer types. */ if (is_drm_iommu_supported(drm_dev)) return 0; flags = exynos_gem->flags; /* * Physically non-contiguous memory type for framebuffer is not * supported without IOMMU. */ if (IS_NONCONTIG_BUFFER(flags)) { DRM_ERROR("Non-contiguous GEM memory is not supported.\n"); return -EINVAL; } return 0; }
static int lowlevel_buffer_allocate(struct drm_device *dev, unsigned int flags, struct rockchip_drm_gem_buf *buf) { int ret = 0; enum dma_attr attr; unsigned int nr_pages; DRM_DEBUG_KMS("%s\n", __FILE__); if (buf->dma_addr) { DRM_DEBUG_KMS("already allocated.\n"); return 0; } init_dma_attrs(&buf->dma_attrs); /* * if ROCKCHIP_BO_CONTIG, fully physically contiguous memory * region will be allocated else physically contiguous * as possible. */ if (!(flags & ROCKCHIP_BO_NONCONTIG)) dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &buf->dma_attrs); /* * if ROCKCHIP_BO_WC or ROCKCHIP_BO_NONCACHABLE, writecombine mapping * else cachable mapping. */ if (flags & ROCKCHIP_BO_WC || !(flags & ROCKCHIP_BO_CACHABLE)) attr = DMA_ATTR_WRITE_COMBINE; else attr = DMA_ATTR_NON_CONSISTENT; dma_set_attr(attr, &buf->dma_attrs); dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->dma_attrs); nr_pages = buf->size >> PAGE_SHIFT; if (!is_drm_iommu_supported(dev)) { dma_addr_t start_addr; unsigned int i = 0; buf->pages = kzalloc(sizeof(struct page) * nr_pages, GFP_KERNEL); if (!buf->pages) { DRM_ERROR("failed to allocate pages.\n"); return -ENOMEM; } buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size, &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); if (!buf->kvaddr) { DRM_ERROR("failed to allocate buffer.\n"); kfree(buf->pages); return -ENOMEM; } start_addr = buf->dma_addr; while (i < nr_pages) { buf->pages[i] = phys_to_page(start_addr); start_addr += PAGE_SIZE; i++; } } else { buf->pages = dma_alloc_attrs(dev->dev, buf->size, &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); if (!buf->pages) { DRM_ERROR("failed to allocate buffer.\n"); return -ENOMEM; } } buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages); if (!buf->sgt) { DRM_ERROR("failed to get sg table.\n"); ret = -ENOMEM; goto err_free_attrs; } DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->dma_addr, buf->size); return ret; err_free_attrs: dma_free_attrs(dev->dev, buf->size, buf->pages, (dma_addr_t)buf->dma_addr, &buf->dma_attrs); buf->dma_addr = (dma_addr_t)NULL; if (!is_drm_iommu_supported(dev)) kfree(buf->pages); return ret; }