summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2016-07-15 08:52:52 -0400
committerVijayakumar Subbu <vsubbu@nvidia.com>2016-07-21 08:55:26 -0400
commit13231006671a1da11cfaf7a67e69430199820788 (patch)
tree6b4053838d672b158fe636b60768240585a21eb0 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c
parent83071083d779b67ad73172675a6dfa34ed19b414 (diff)
gpu: nvgpu: add vidmem allocation ioctl
Add NVGPU_GPU_IOCTL_ALLOC_VIDMEM to the ctrl fd for letting userspace allocate on-board GPU memory (aka vidmem). The allocations are returned as dmabuf fds. Also, report the amount of local video memory in the gpu characteristics. Jira DNVGPU-19 Jira DNVGPU-38 Change-Id: I28e361d31bb630b96d06bb1c86d022d91c7592bc Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1181152 GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index bf3d990c..2dcc4363 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -411,6 +411,14 @@ struct gk20a_dmabuf_priv {
411 u64 buffer_id; 411 u64 buffer_id;
412}; 412};
413 413
414struct gk20a_vidmem_buf {
415 struct gk20a *g;
416 struct mem_desc mem;
417 struct dma_buf *dmabuf;
418 void *dmabuf_priv;
419 void (*dmabuf_priv_delete)(void *);
420};
421
414static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); 422static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm);
415 423
416static int gk20a_comptaglines_alloc(struct gk20a_comptag_allocator *allocator, 424static int gk20a_comptaglines_alloc(struct gk20a_comptag_allocator *allocator,
@@ -1833,6 +1841,146 @@ static u64 gk20a_vm_map_duplicate_locked(struct vm_gk20a *vm,
1833 return mapped_buffer->addr; 1841 return mapped_buffer->addr;
1834} 1842}
1835 1843
1844#if defined(CONFIG_GK20A_VIDMEM)
1845static struct sg_table *gk20a_vidbuf_map_dma_buf(
1846 struct dma_buf_attachment *attach, enum dma_data_direction dir)
1847{
1848 struct gk20a_vidmem_buf *buf = attach->dmabuf->priv;
1849
1850 return buf->mem.sgt;
1851}
1852
1853static void gk20a_vidbuf_unmap_dma_buf(struct dma_buf_attachment *attach,
1854 struct sg_table *sgt,
1855 enum dma_data_direction dir)
1856{
1857}
1858
1859static void gk20a_vidbuf_release(struct dma_buf *dmabuf)
1860{
1861 struct gk20a_vidmem_buf *buf = dmabuf->priv;
1862
1863 gk20a_dbg_fn("");
1864
1865 if (buf->dmabuf_priv)
1866 buf->dmabuf_priv_delete(buf->dmabuf_priv);
1867
1868 gk20a_gmmu_free(buf->g, &buf->mem);
1869 kfree(buf);
1870}
1871
1872static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num)
1873{
1874 WARN_ON("Not supported");
1875 return NULL;
1876}
1877
1878static void *gk20a_vidbuf_kmap_atomic(struct dma_buf *dmabuf,
1879 unsigned long page_num)
1880{
1881 WARN_ON("Not supported");
1882 return NULL;
1883}
1884
1885static int gk20a_vidbuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
1886{
1887 return -EINVAL;
1888}
1889
1890static int gk20a_vidbuf_set_private(struct dma_buf *dmabuf,
1891 struct device *dev, void *priv, void (*delete)(void *priv))
1892{
1893 struct gk20a_vidmem_buf *buf = dmabuf->priv;
1894
1895 buf->dmabuf_priv = priv;
1896 buf->dmabuf_priv_delete = delete;
1897
1898 return 0;
1899}
1900
1901static void *gk20a_vidbuf_get_private(struct dma_buf *dmabuf,
1902 struct device *dev)
1903{
1904 struct gk20a_vidmem_buf *buf = dmabuf->priv;
1905
1906 return buf->dmabuf_priv;
1907}
1908
1909static const struct dma_buf_ops gk20a_vidbuf_ops = {
1910 .map_dma_buf = gk20a_vidbuf_map_dma_buf,
1911 .unmap_dma_buf = gk20a_vidbuf_unmap_dma_buf,
1912 .release = gk20a_vidbuf_release,
1913 .kmap_atomic = gk20a_vidbuf_kmap_atomic,
1914 .kmap = gk20a_vidbuf_kmap,
1915 .mmap = gk20a_vidbuf_mmap,
1916 .set_drvdata = gk20a_vidbuf_set_private,
1917 .get_drvdata = gk20a_vidbuf_get_private,
1918};
1919
1920static struct dma_buf *gk20a_vidbuf_export(struct gk20a_vidmem_buf *buf)
1921{
1922#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
1923 DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
1924
1925 exp_info.priv = buf;
1926 exp_info.ops = &gk20a_vidbuf_ops;
1927 exp_info.size = buf->mem.size;
1928 exp_info.flags = O_RDWR;
1929
1930 return dma_buf_export(&exp_info);
1931#else
1932 return dma_buf_export(buf, &gk20a_vidbuf_ops, buf->mem.size,
1933 O_RDWR, NULL);
1934#endif
1935}
1936#endif
1937
1938int gk20a_vidmem_buf_alloc(struct gk20a *g, size_t bytes)
1939{
1940#if defined(CONFIG_GK20A_VIDMEM)
1941 struct gk20a_vidmem_buf *buf;
1942 int err, fd;
1943
1944 gk20a_dbg_fn("");
1945
1946 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
1947 if (!buf)
1948 return -ENOMEM;
1949
1950 buf->g = g;
1951
1952 err = gk20a_gmmu_alloc_vid(g, bytes, &buf->mem);
1953 if (err)
1954 goto err_kfree;
1955
1956 buf->dmabuf = gk20a_vidbuf_export(buf);
1957 if (IS_ERR(buf->dmabuf)) {
1958 err = PTR_ERR(buf->dmabuf);
1959 goto err_bfree;
1960 }
1961
1962 fd = get_unused_fd_flags(O_RDWR);
1963 if (fd < 0) {
1964 /* ->release frees what we have done */
1965 dma_buf_put(buf->dmabuf);
1966 return fd;
1967 }
1968
1969 /* fclose() on this drops one ref, freeing the dma buf */
1970 fd_install(fd, buf->dmabuf->file);
1971
1972 return fd;
1973
1974err_bfree:
1975 gk20a_gmmu_free(g, &buf->mem);
1976err_kfree:
1977 kfree(buf);
1978 return err;
1979#else
1980 return -ENOSYS;
1981#endif
1982}
1983
1836u64 gk20a_vm_map(struct vm_gk20a *vm, 1984u64 gk20a_vm_map(struct vm_gk20a *vm,
1837 struct dma_buf *dmabuf, 1985 struct dma_buf *dmabuf,
1838 u64 offset_align, 1986 u64 offset_align,