Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpi-4.1.y pull: vc4: kernel-side fix for X rendering lag, plus 3D testing fix #1268

Merged
merged 8 commits into from
Jan 27, 2016
6 changes: 3 additions & 3 deletions drivers/gpu/drm/drm_fb_cma_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
if (!fbi) {
dev_err(dev->dev, "Failed to allocate framebuffer info.\n");
ret = -ENOMEM;
goto err_drm_gem_cma_free_object;
goto err_gem_free_object;
}

fbdev_cma->fb = drm_fb_cma_alloc(dev, &mode_cmd, &obj, 1);
Expand Down Expand Up @@ -322,8 +322,8 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
drm_fb_cma_destroy(fb);
err_framebuffer_release:
framebuffer_release(fbi);
err_drm_gem_cma_free_object:
drm_gem_cma_free_object(&obj->base);
err_gem_free_object:
dev->driver->gem_free_object(&obj->base);
return ret;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/drm_gem_cma_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
return cma_obj;

error:
drm_gem_cma_free_object(&cma_obj->base);
drm->driver->gem_free_object(&cma_obj->base);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(drm_gem_cma_create);
Expand Down Expand Up @@ -171,7 +171,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
return cma_obj;

err_handle_create:
drm_gem_cma_free_object(gem_obj);
drm->driver->gem_free_object(gem_obj);

return ERR_PTR(ret);
}
Expand Down
23 changes: 13 additions & 10 deletions drivers/gpu/drm/vc4/vc4_bo.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
size_t size = roundup(unaligned_size, PAGE_SIZE);
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_gem_cma_object *cma_obj;
int pass;
int pass, ret;

if (size == 0)
return NULL;
return ERR_PTR(-EINVAL);

/* First, try to get a vc4_bo from the kernel BO cache. */
if (from_cache) {
Expand Down Expand Up @@ -247,14 +247,17 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
* unreferenced BOs to the cache, and then
* free the cache.
*/
vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull, true);
ret = vc4_wait_for_seqno(dev, vc4->emit_seqno, ~0ull,
true);
if (ret)
return ERR_PTR(ret);
vc4_job_handle_completed(vc4);
vc4_bo_cache_purge(dev);
break;
case 3:
DRM_ERROR("Failed to allocate from CMA:\n");
vc4_bo_stats_dump(vc4);
return NULL;
return ERR_PTR(-ENOMEM);
}
}

Expand All @@ -276,8 +279,8 @@ int vc4_dumb_create(struct drm_file *file_priv,
args->size = args->pitch * args->height;

bo = vc4_bo_create(dev, args->size, false);
if (!bo)
return -ENOMEM;
if (IS_ERR(bo))
return PTR_ERR(bo);

ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
drm_gem_object_unreference_unlocked(&bo->base.base);
Expand Down Expand Up @@ -460,8 +463,8 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
* get zeroed, and that might leak data between users.
*/
bo = vc4_bo_create(dev, args->size, false);
if (!bo)
return -ENOMEM;
if (IS_ERR(bo))
return PTR_ERR(bo);

ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
drm_gem_object_unreference_unlocked(&bo->base.base);
Expand Down Expand Up @@ -513,8 +516,8 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
}

bo = vc4_bo_create(dev, args->size, true);
if (!bo)
return -ENOMEM;
if (IS_ERR(bo))
return PTR_ERR(bo);

ret = copy_from_user(bo->base.vaddr,
(void __user *)(uintptr_t)args->data,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/vc4/vc4_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

static const struct drm_info_list vc4_debugfs_list[] = {
{"bo_stats", vc4_bo_stats_debugfs, 0},
{"gem_exec", vc4_gem_exec_debugfs, 0},
{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
{"hvs_regs", vc4_hvs_debugfs_regs, 0},
{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/vc4/vc4_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ void vc4_job_handle_completed(struct vc4_dev *vc4);
int vc4_queue_seqno_cb(struct drm_device *dev,
struct vc4_seqno_cb *cb, uint64_t seqno,
void (*func)(struct vc4_seqno_cb *cb));
int vc4_gem_exec_debugfs(struct seq_file *m, void *arg);

/* vc4_hdmi.c */
extern struct platform_driver vc4_hdmi_driver;
Expand Down
28 changes: 20 additions & 8 deletions drivers/gpu/drm/vc4/vc4_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@
#include "vc4_regs.h"
#include "vc4_trace.h"

#ifdef CONFIG_DEBUG_FS
int vc4_gem_exec_debugfs(struct seq_file *m, void *unused)
{
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct drm_device *dev = node->minor->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);

seq_printf(m, "Emitted seqno: 0x%016llx\n", vc4->emit_seqno);
seq_printf(m, "Finished seqno: 0x%016llx\n", vc4->finished_seqno);

return 0;
}
#endif /* CONFIG_DEBUG_FS */

static void
vc4_queue_hangcheck(struct drm_device *dev)
{
Expand Down Expand Up @@ -338,12 +352,7 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns,
finish_wait(&vc4->job_wait_queue, &wait);
trace_vc4_wait_for_seqno_end(dev, seqno);

if (ret && ret != -ERESTARTSYS) {
DRM_ERROR("timeout waiting for render thread idle\n");
return ret;
}

return 0;
return ret;
}

static void
Expand Down Expand Up @@ -579,9 +588,9 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
}

bo = vc4_bo_create(dev, exec_size, true);
if (!bo) {
if (IS_ERR(bo)) {
DRM_ERROR("Couldn't allocate BO for binning\n");
ret = PTR_ERR(exec->exec_bo);
ret = PTR_ERR(bo);
goto fail;
}
exec->exec_bo = &bo->base;
Expand Down Expand Up @@ -747,6 +756,9 @@ vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
struct drm_gem_object *gem_obj;
struct vc4_bo *bo;

if (args->pad != 0)
return -EINVAL;

gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle);
if (!gem_obj) {
DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/vc4/vc4_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ vc4_overflow_mem_work(struct work_struct *work)
struct vc4_bo *bo;

bo = vc4_bo_create(dev, 256 * 1024, true);
if (!bo) {
if (IS_ERR(bo)) {
DRM_ERROR("Couldn't allocate binner overflow mem\n");
return;
}
Expand Down
22 changes: 11 additions & 11 deletions drivers/gpu/drm/vc4/vc4_render_cl.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,20 +316,11 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
size += xtiles * ytiles * loop_body_size;

setup->rcl = &vc4_bo_create(dev, size, true)->base;
if (!setup->rcl)
return -ENOMEM;
if (IS_ERR(setup->rcl))
return PTR_ERR(setup->rcl);
list_add_tail(&to_vc4_bo(&setup->rcl->base)->unref_head,
&exec->unref_list);

rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
rcl_u32(setup,
(setup->color_write ? (setup->color_write->paddr +
args->color_write.offset) :
0));
rcl_u16(setup, args->width);
rcl_u16(setup, args->height);
rcl_u16(setup, args->color_write.bits);

/* The tile buffer gets cleared when the previous tile is stored. If
* the clear values changed between frames, then the tile buffer has
* stale clear values in it, so we have to do a store in None mode (no
Expand All @@ -349,6 +340,15 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
rcl_u32(setup, 0); /* no address, since we're in None mode */
}

rcl_u8(setup, VC4_PACKET_TILE_RENDERING_MODE_CONFIG);
rcl_u32(setup,
(setup->color_write ? (setup->color_write->paddr +
args->color_write.offset) :
0));
rcl_u16(setup, args->width);
rcl_u16(setup, args->height);
rcl_u16(setup, args->color_write.bits);

for (y = min_y_tile; y <= max_y_tile; y++) {
for (x = min_x_tile; x <= max_x_tile; x++) {
bool first = (x == min_x_tile && y == min_y_tile);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/vc4/vc4_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ validate_tile_binning_config(VALIDATE_ARGS)
tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size,
true);
exec->tile_bo = &tile_bo->base;
if (!exec->tile_bo)
return -ENOMEM;
if (IS_ERR(exec->tile_bo))
return PTR_ERR(exec->tile_bo);
list_add_tail(&tile_bo->unref_head, &exec->unref_list);

/* tile alloc address. */
Expand Down
1 change: 1 addition & 0 deletions include/uapi/drm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ header-y += radeon_drm.h
header-y += savage_drm.h
header-y += sis_drm.h
header-y += tegra_drm.h
header-y += vc4_drm.h
header-y += via_drm.h
header-y += vmwgfx_drm.h
header-y += msm_drm.h