diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-05-26 09:40:33 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2016-08-08 11:03:33 +0100 |
commit | a0fb5e7bff0aea17038553daec796881e3872fd7 (patch) | |
tree | 644b0a7beb840e1519beebb1ee1d612efe7b6a4f | |
parent | 02ef32fdb338cc843498c74566f794a9a973b8f3 (diff) |
drm: etnaviv: add device property to control parsing of command buffers
Parsing the command buffer is an expensive operation, as the command
buffer is uncached. Work-around this by providing a control to allow
the command buffer parsing to be skipped.
A better solution would be to move to cached buffers between userspace
and kernelspace, and copying the data in kernel space to the final
command buffer.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 1 |
3 files changed, 30 insertions, 1 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index afdd55ddf821..7bae554d6315 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -377,7 +377,8 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, if (ret) goto err_submit_objects; - if (!etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4, + if (gpu->validate_cmdbuf && + !etnaviv_cmd_validate_one(gpu, stream, args->stream_size / 4, relocs, args->nr_relocs)) { ret = -EINVAL; goto err_submit_objects; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 1942e56d1ef2..0870ab01332a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1679,6 +1679,27 @@ static const struct of_device_id etnaviv_gpu_match[] = { { /* sentinel */ } }; +static ssize_t etnaviv_gpu_check_cmdbuf_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct etnaviv_gpu *gpu = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%u\n", gpu->validate_cmdbuf); +} + +static ssize_t etnaviv_gpu_check_cmdbuf_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct etnaviv_gpu *gpu = dev_get_drvdata(dev); + + if (strtobool(buf, &gpu->validate_cmdbuf)) + return -EINVAL; + + return count; +} + +static DEVICE_ATTR(check_cmdbuf, 0600, etnaviv_gpu_check_cmdbuf_show, etnaviv_gpu_check_cmdbuf_store); + static int etnaviv_gpu_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1731,6 +1752,8 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) /* TODO: figure out max mapped size */ dev_set_drvdata(dev, gpu); + gpu->validate_cmdbuf = true; + /* * We treat the device as initially suspended. The runtime PM * autosuspend delay is rather arbitary: no measurements have @@ -1740,9 +1763,12 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(gpu->dev, 200); pm_runtime_enable(gpu->dev); + device_create_file(gpu->dev, &dev_attr_check_cmdbuf); + err = component_add(&pdev->dev, &gpu_ops); if (err < 0) { dev_err(&pdev->dev, "failed to register component: %d\n", err); + device_remove_file(gpu->dev, &dev_attr_check_cmdbuf); goto fail; } @@ -1756,6 +1782,7 @@ static int etnaviv_gpu_platform_remove(struct platform_device *pdev) { component_del(&pdev->dev, &gpu_ops); pm_runtime_disable(&pdev->dev); + device_remove_file(&pdev->dev, &dev_attr_check_cmdbuf); return 0; } diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 0c7457d834dd..1332802aa831 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -150,6 +150,7 @@ struct etnaviv_gpu { u32 hangcheck_dma_addr; struct work_struct recover_work; unsigned int freq_scale; + bool validate_cmdbuf; }; struct etnaviv_cmdbuf { |