gpu: nvgpu: Attach compression state to dma-buf

Bug 1509620

Change-Id: I694fe43ef5d1f4f329d997a3d60e006785374cc3
Signed-off-by: Lauri Peltonen <lpeltonen@nvidia.com>
Reviewed-on: http://git-master/r/439849
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Lauri Peltonen
2014-07-18 02:31:44 +03:00
committed by Dan Willemsen
parent bcf60a22c3
commit c60a300c4a
2 changed files with 78 additions and 0 deletions

View File

@@ -32,6 +32,7 @@
#include "gk20a.h"
#include "mm_gk20a.h"
#include "fence_gk20a.h"
#include "hw_gmmu_gk20a.h"
#include "hw_fb_gk20a.h"
#include "hw_bus_gk20a.h"
@@ -121,10 +122,13 @@ struct gk20a_dmabuf_priv {
struct sg_table *sgt;
int pin_count;
struct list_head states;
};
static void gk20a_mm_delete_priv(void *_priv)
{
struct gk20a_buffer_state *s, *s_tmp;
struct gk20a_dmabuf_priv *priv = _priv;
if (!priv)
return;
@@ -136,6 +140,13 @@ static void gk20a_mm_delete_priv(void *_priv)
priv->comptags.lines);
}
/* Free buffer states */
list_for_each_entry_safe(s, s_tmp, &priv->states, list) {
gk20a_fence_put(s->fence);
list_del(&s->list);
kfree(s);
}
kfree(priv);
}
@@ -2438,6 +2449,7 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev)
goto priv_exist_or_err;
}
mutex_init(&priv->lock);
INIT_LIST_HEAD(&priv->states);
dma_buf_set_drvdata(dmabuf, dev, priv, gk20a_mm_delete_priv);
priv_exist_or_err:
mutex_unlock(&priv_lock);
@@ -2447,6 +2459,50 @@ priv_exist_or_err:
return 0;
}
int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct device *dev,
u64 offset, struct gk20a_buffer_state **state)
{
int err = 0;
struct gk20a_dmabuf_priv *priv;
struct gk20a_buffer_state *s;
if (WARN_ON(offset >= (u64)dmabuf->size))
return -EINVAL;
err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev);
if (err)
return err;
priv = dma_buf_get_drvdata(dmabuf, dev);
if (WARN_ON(!priv))
return -ENOSYS;
mutex_lock(&priv->lock);
list_for_each_entry(s, &priv->states, list)
if (s->offset == offset)
goto out;
/* State not found, create state. */
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
err = -ENOMEM;
goto out;
}
s->offset = offset;
INIT_LIST_HEAD(&s->list);
mutex_init(&s->lock);
list_add_tail(&priv->states, &s->list);
out:
mutex_unlock(&priv->lock);
if (!err)
*state = s;
return err;
}
static int gk20a_dmabuf_get_kind(struct dma_buf *dmabuf)
{

View File

@@ -174,6 +174,25 @@ struct compbit_store_desc {
u64 base_iova;
};
struct gk20a_buffer_state {
struct list_head list;
/* The valid compbits and the fence must be changed atomically. */
struct mutex lock;
/* Offset of the surface within the dma-buf whose state is
* described by this struct (one dma-buf can contain multiple
* surfaces with different states). */
size_t offset;
/* A bitmask of valid sets of compbits (0 = uncompressed). */
u32 valid_compbits;
/* This struct reflects the state of the buffer when this
* fence signals. */
struct gk20a_fence *fence;
};
struct page_table_gk20a {
/* backing for */
/* Either a *page or a *mem_handle */
@@ -484,6 +503,9 @@ dma_addr_t gk20a_mm_gpuva_to_iova(struct vm_gk20a *vm, u64 gpu_vaddr);
int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev);
int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct device *dev,
u64 offset, struct gk20a_buffer_state **state);
int map_gmmu_pages(void *handle, struct sg_table *sgt,
void **va, size_t size);
void unmap_gmmu_pages(void *handle, struct sg_table *sgt, void *va);