mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
drm/rockchip: add dmabuf sync partial to dma_buf_ops
Change-Id: I6ba192c11a0ff9eeafa4f4f0260addb1e56c4afc Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
This commit is contained in:
@@ -1820,6 +1820,26 @@ static int rockchip_drm_gem_dmabuf_end_cpu_access(struct dma_buf *dma_buf,
|
|||||||
return rockchip_gem_prime_end_cpu_access(obj, dir);
|
return rockchip_gem_prime_end_cpu_access(obj, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rockchip_drm_gem_begin_cpu_access_partial(
|
||||||
|
struct dma_buf *dma_buf,
|
||||||
|
enum dma_data_direction dir,
|
||||||
|
unsigned int offset, unsigned int len)
|
||||||
|
{
|
||||||
|
struct drm_gem_object *obj = dma_buf->priv;
|
||||||
|
|
||||||
|
return rockchip_gem_prime_begin_cpu_access_partial(obj, dir, offset, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rockchip_drm_gem_end_cpu_access_partial(
|
||||||
|
struct dma_buf *dma_buf,
|
||||||
|
enum dma_data_direction dir,
|
||||||
|
unsigned int offset, unsigned int len)
|
||||||
|
{
|
||||||
|
struct drm_gem_object *obj = dma_buf->priv;
|
||||||
|
|
||||||
|
return rockchip_gem_prime_end_cpu_access_partial(obj, dir, offset, len);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct dma_buf_ops rockchip_drm_gem_prime_dmabuf_ops = {
|
static const struct dma_buf_ops rockchip_drm_gem_prime_dmabuf_ops = {
|
||||||
.attach = drm_gem_map_attach,
|
.attach = drm_gem_map_attach,
|
||||||
.detach = drm_gem_map_detach,
|
.detach = drm_gem_map_detach,
|
||||||
@@ -1833,6 +1853,8 @@ static const struct dma_buf_ops rockchip_drm_gem_prime_dmabuf_ops = {
|
|||||||
.vunmap = drm_gem_dmabuf_vunmap,
|
.vunmap = drm_gem_dmabuf_vunmap,
|
||||||
.begin_cpu_access = rockchip_drm_gem_dmabuf_begin_cpu_access,
|
.begin_cpu_access = rockchip_drm_gem_dmabuf_begin_cpu_access,
|
||||||
.end_cpu_access = rockchip_drm_gem_dmabuf_end_cpu_access,
|
.end_cpu_access = rockchip_drm_gem_dmabuf_end_cpu_access,
|
||||||
|
.begin_cpu_access_partial = rockchip_drm_gem_begin_cpu_access_partial,
|
||||||
|
.end_cpu_access_partial = rockchip_drm_gem_end_cpu_access_partial,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||||
|
|||||||
@@ -1027,3 +1027,95 @@ int rockchip_gem_prime_end_cpu_access(struct drm_gem_object *obj,
|
|||||||
rk_obj->sgt->nents, dir);
|
rk_obj->sgt->nents, dir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rockchip_gem_prime_sgl_sync_range(struct device *dev,
|
||||||
|
struct scatterlist *sgl, unsigned int nents,
|
||||||
|
unsigned int offset, unsigned int length,
|
||||||
|
enum dma_data_direction dir, bool for_cpu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct scatterlist *sg;
|
||||||
|
unsigned int len = 0;
|
||||||
|
dma_addr_t sg_dma_addr;
|
||||||
|
|
||||||
|
for_each_sg(sgl, sg, nents, i) {
|
||||||
|
if (sg_dma_len(sg) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
pr_warn_ratelimited("Partial cmo only supported with 1 segment\n"
|
||||||
|
"is dma_set_max_seg_size being set on dev:%s\n",
|
||||||
|
dev_name(dev));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_sg(sgl, sg, nents, i) {
|
||||||
|
unsigned int sg_offset, sg_left, size = 0;
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
sg_dma_addr = sg_dma_address(sg);
|
||||||
|
|
||||||
|
len += sg->length;
|
||||||
|
if (len <= offset) {
|
||||||
|
sg_dma_addr += sg->length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sg_left = len - offset;
|
||||||
|
sg_offset = sg->length - sg_left;
|
||||||
|
|
||||||
|
size = (length < sg_left) ? length : sg_left;
|
||||||
|
if (for_cpu)
|
||||||
|
dma_sync_single_range_for_cpu(dev, sg_dma_addr,
|
||||||
|
sg_offset, size, dir);
|
||||||
|
else
|
||||||
|
dma_sync_single_range_for_device(dev, sg_dma_addr,
|
||||||
|
sg_offset, size, dir);
|
||||||
|
|
||||||
|
offset += size;
|
||||||
|
length -= size;
|
||||||
|
sg_dma_addr += sg->length;
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rockchip_gem_prime_begin_cpu_access_partial(struct drm_gem_object *obj,
|
||||||
|
enum dma_data_direction dir,
|
||||||
|
unsigned int offset,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
|
||||||
|
struct drm_device *drm = obj->dev;
|
||||||
|
|
||||||
|
if (!rk_obj->sgt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rockchip_gem_prime_sgl_sync_range(drm->dev, rk_obj->sgt->sgl,
|
||||||
|
rk_obj->sgt->nents,
|
||||||
|
offset, len, dir, true);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rockchip_gem_prime_end_cpu_access_partial(struct drm_gem_object *obj,
|
||||||
|
enum dma_data_direction dir,
|
||||||
|
unsigned int offset,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
|
||||||
|
struct drm_device *drm = obj->dev;
|
||||||
|
|
||||||
|
if (!rk_obj->sgt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rockchip_gem_prime_sgl_sync_range(drm->dev, rk_obj->sgt->sgl,
|
||||||
|
rk_obj->sgt->nents,
|
||||||
|
offset, len, dir, false);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -91,4 +91,15 @@ int rockchip_gem_prime_begin_cpu_access(struct drm_gem_object *obj,
|
|||||||
|
|
||||||
int rockchip_gem_prime_end_cpu_access(struct drm_gem_object *obj,
|
int rockchip_gem_prime_end_cpu_access(struct drm_gem_object *obj,
|
||||||
enum dma_data_direction dir);
|
enum dma_data_direction dir);
|
||||||
|
|
||||||
|
int rockchip_gem_prime_begin_cpu_access_partial(struct drm_gem_object *obj,
|
||||||
|
enum dma_data_direction dir,
|
||||||
|
unsigned int offset,
|
||||||
|
unsigned int len);
|
||||||
|
|
||||||
|
int rockchip_gem_prime_end_cpu_access_partial(struct drm_gem_object *obj,
|
||||||
|
enum dma_data_direction dir,
|
||||||
|
unsigned int offset,
|
||||||
|
unsigned int len);
|
||||||
|
|
||||||
#endif /* _ROCKCHIP_DRM_GEM_H */
|
#endif /* _ROCKCHIP_DRM_GEM_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user