Loading drivers/gpu/drm/tegra/drm.c +129 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,135 @@ static void tegra_drm_lastclose(struct drm_device *drm) tegra_fbdev_restore_mode(tegra->fbdev); } static struct host1x_bo * host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) { struct drm_gem_object *gem; struct tegra_bo *bo; gem = drm_gem_object_lookup(drm, file, handle); if (!gem) return NULL; mutex_lock(&drm->struct_mutex); drm_gem_object_unreference(gem); mutex_unlock(&drm->struct_mutex); bo = to_tegra_bo(gem); return &bo->base; } int tegra_drm_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file) { unsigned int num_cmdbufs = args->num_cmdbufs; unsigned int num_relocs = args->num_relocs; unsigned int num_waitchks = args->num_waitchks; struct drm_tegra_cmdbuf __user *cmdbufs = (void * __user)(uintptr_t)args->cmdbufs; struct drm_tegra_reloc __user *relocs = (void * __user)(uintptr_t)args->relocs; struct drm_tegra_waitchk __user *waitchks = (void * __user)(uintptr_t)args->waitchks; struct drm_tegra_syncpt syncpt; struct host1x_job *job; int err; /* We don't yet support other than one syncpt_incr struct per submit */ if (args->num_syncpts != 1) return -EINVAL; job = host1x_job_alloc(context->channel, args->num_cmdbufs, args->num_relocs, args->num_waitchks); if (!job) return -ENOMEM; job->num_relocs = args->num_relocs; job->num_waitchk = args->num_waitchks; job->client = (u32)args->context; job->class = context->client->base.class; job->serialize = true; while (num_cmdbufs) { struct drm_tegra_cmdbuf cmdbuf; struct host1x_bo *bo; err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf)); if (err) goto fail; bo = host1x_bo_lookup(drm, file, cmdbuf.handle); if (!bo) { err = -ENOENT; goto fail; } host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; cmdbufs++; } err = copy_from_user(job->relocarray, relocs, sizeof(*relocs) * num_relocs); if (err) goto fail; while (num_relocs--) { struct host1x_reloc *reloc = &job->relocarray[num_relocs]; struct host1x_bo *cmdbuf, *target; cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf); target = host1x_bo_lookup(drm, file, (u32)reloc->target); reloc->cmdbuf = cmdbuf; reloc->target = target; if (!reloc->target || !reloc->cmdbuf) { err = -ENOENT; goto fail; } } err = copy_from_user(job->waitchk, waitchks, sizeof(*waitchks) * num_waitchks); if (err) goto fail; err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts, sizeof(syncpt)); if (err) goto fail; job->is_addr_reg = context->client->ops->is_addr_reg; job->syncpt_incrs = syncpt.incrs; job->syncpt_id = syncpt.id; job->timeout = 10000; if (args->timeout && args->timeout < 10000) job->timeout = args->timeout; err = host1x_job_pin(job, context->client->base.dev); if (err) goto fail; err = host1x_job_submit(job); if (err) goto fail_submit; args->fence = job->syncpt_end; host1x_job_put(job); return 0; fail_submit: host1x_job_unpin(job); fail: host1x_job_put(job); return err; } #ifdef CONFIG_DRM_TEGRA_STAGING static struct tegra_drm_context *tegra_drm_get_context(__u64 context) { Loading drivers/gpu/drm/tegra/drm.h +5 −0 Original line number Diff line number Diff line Loading @@ -51,11 +51,16 @@ struct tegra_drm_client_ops { int (*open_channel)(struct tegra_drm_client *client, struct tegra_drm_context *context); void (*close_channel)(struct tegra_drm_context *context); int (*is_addr_reg)(struct device *dev, u32 class, u32 offset); int (*submit)(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file); }; int tegra_drm_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file); struct tegra_drm_client { struct host1x_client base; struct list_head list; Loading drivers/gpu/drm/tegra/gr2d.c +2 −130 Original line number Diff line number Diff line Loading @@ -91,25 +91,6 @@ static void gr2d_close_channel(struct tegra_drm_context *context) host1x_channel_put(context->channel); } static struct host1x_bo *host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) { struct drm_gem_object *gem; struct tegra_bo *bo; gem = drm_gem_object_lookup(drm, file, handle); if (!gem) return NULL; mutex_lock(&drm->struct_mutex); drm_gem_object_unreference(gem); mutex_unlock(&drm->struct_mutex); bo = to_tegra_bo(gem); return &bo->base; } static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset) { struct gr2d *gr2d = dev_get_drvdata(dev); Loading @@ -135,120 +116,11 @@ static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset) return 0; } static int gr2d_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file) { unsigned int num_cmdbufs = args->num_cmdbufs; unsigned int num_relocs = args->num_relocs; unsigned int num_waitchks = args->num_waitchks; struct drm_tegra_cmdbuf __user *cmdbufs = (void * __user)(uintptr_t)args->cmdbufs; struct drm_tegra_reloc __user *relocs = (void * __user)(uintptr_t)args->relocs; struct drm_tegra_waitchk __user *waitchks = (void * __user)(uintptr_t)args->waitchks; struct drm_tegra_syncpt syncpt; struct host1x_job *job; int err; /* We don't yet support other than one syncpt_incr struct per submit */ if (args->num_syncpts != 1) return -EINVAL; job = host1x_job_alloc(context->channel, args->num_cmdbufs, args->num_relocs, args->num_waitchks); if (!job) return -ENOMEM; job->num_relocs = args->num_relocs; job->num_waitchk = args->num_waitchks; job->client = (u32)args->context; job->class = context->client->base.class; job->serialize = true; while (num_cmdbufs) { struct drm_tegra_cmdbuf cmdbuf; struct host1x_bo *bo; err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf)); if (err) goto fail; bo = host1x_bo_lookup(drm, file, cmdbuf.handle); if (!bo) { err = -ENOENT; goto fail; } host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; cmdbufs++; } err = copy_from_user(job->relocarray, relocs, sizeof(*relocs) * num_relocs); if (err) goto fail; while (num_relocs--) { struct host1x_reloc *reloc = &job->relocarray[num_relocs]; struct host1x_bo *cmdbuf, *target; cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf); target = host1x_bo_lookup(drm, file, (u32)reloc->target); reloc->cmdbuf = cmdbuf; reloc->target = target; if (!reloc->target || !reloc->cmdbuf) { err = -ENOENT; goto fail; } } err = copy_from_user(job->waitchk, waitchks, sizeof(*waitchks) * num_waitchks); if (err) goto fail; err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts, sizeof(syncpt)); if (err) goto fail; job->syncpt_id = syncpt.id; job->syncpt_incrs = syncpt.incrs; job->timeout = 10000; job->is_addr_reg = gr2d_is_addr_reg; if (args->timeout && args->timeout < 10000) job->timeout = args->timeout; err = host1x_job_pin(job, context->client->base.dev); if (err) goto fail; err = host1x_job_submit(job); if (err) goto fail_submit; args->fence = job->syncpt_end; host1x_job_put(job); return 0; fail_submit: host1x_job_unpin(job); fail: host1x_job_put(job); return err; } static const struct tegra_drm_client_ops gr2d_ops = { .open_channel = gr2d_open_channel, .close_channel = gr2d_close_channel, .submit = gr2d_submit, .is_addr_reg = gr2d_is_addr_reg, .submit = tegra_drm_submit, }; static const struct of_device_id gr2d_match[] = { Loading Loading
drivers/gpu/drm/tegra/drm.c +129 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,135 @@ static void tegra_drm_lastclose(struct drm_device *drm) tegra_fbdev_restore_mode(tegra->fbdev); } static struct host1x_bo * host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) { struct drm_gem_object *gem; struct tegra_bo *bo; gem = drm_gem_object_lookup(drm, file, handle); if (!gem) return NULL; mutex_lock(&drm->struct_mutex); drm_gem_object_unreference(gem); mutex_unlock(&drm->struct_mutex); bo = to_tegra_bo(gem); return &bo->base; } int tegra_drm_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file) { unsigned int num_cmdbufs = args->num_cmdbufs; unsigned int num_relocs = args->num_relocs; unsigned int num_waitchks = args->num_waitchks; struct drm_tegra_cmdbuf __user *cmdbufs = (void * __user)(uintptr_t)args->cmdbufs; struct drm_tegra_reloc __user *relocs = (void * __user)(uintptr_t)args->relocs; struct drm_tegra_waitchk __user *waitchks = (void * __user)(uintptr_t)args->waitchks; struct drm_tegra_syncpt syncpt; struct host1x_job *job; int err; /* We don't yet support other than one syncpt_incr struct per submit */ if (args->num_syncpts != 1) return -EINVAL; job = host1x_job_alloc(context->channel, args->num_cmdbufs, args->num_relocs, args->num_waitchks); if (!job) return -ENOMEM; job->num_relocs = args->num_relocs; job->num_waitchk = args->num_waitchks; job->client = (u32)args->context; job->class = context->client->base.class; job->serialize = true; while (num_cmdbufs) { struct drm_tegra_cmdbuf cmdbuf; struct host1x_bo *bo; err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf)); if (err) goto fail; bo = host1x_bo_lookup(drm, file, cmdbuf.handle); if (!bo) { err = -ENOENT; goto fail; } host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; cmdbufs++; } err = copy_from_user(job->relocarray, relocs, sizeof(*relocs) * num_relocs); if (err) goto fail; while (num_relocs--) { struct host1x_reloc *reloc = &job->relocarray[num_relocs]; struct host1x_bo *cmdbuf, *target; cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf); target = host1x_bo_lookup(drm, file, (u32)reloc->target); reloc->cmdbuf = cmdbuf; reloc->target = target; if (!reloc->target || !reloc->cmdbuf) { err = -ENOENT; goto fail; } } err = copy_from_user(job->waitchk, waitchks, sizeof(*waitchks) * num_waitchks); if (err) goto fail; err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts, sizeof(syncpt)); if (err) goto fail; job->is_addr_reg = context->client->ops->is_addr_reg; job->syncpt_incrs = syncpt.incrs; job->syncpt_id = syncpt.id; job->timeout = 10000; if (args->timeout && args->timeout < 10000) job->timeout = args->timeout; err = host1x_job_pin(job, context->client->base.dev); if (err) goto fail; err = host1x_job_submit(job); if (err) goto fail_submit; args->fence = job->syncpt_end; host1x_job_put(job); return 0; fail_submit: host1x_job_unpin(job); fail: host1x_job_put(job); return err; } #ifdef CONFIG_DRM_TEGRA_STAGING static struct tegra_drm_context *tegra_drm_get_context(__u64 context) { Loading
drivers/gpu/drm/tegra/drm.h +5 −0 Original line number Diff line number Diff line Loading @@ -51,11 +51,16 @@ struct tegra_drm_client_ops { int (*open_channel)(struct tegra_drm_client *client, struct tegra_drm_context *context); void (*close_channel)(struct tegra_drm_context *context); int (*is_addr_reg)(struct device *dev, u32 class, u32 offset); int (*submit)(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file); }; int tegra_drm_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file); struct tegra_drm_client { struct host1x_client base; struct list_head list; Loading
drivers/gpu/drm/tegra/gr2d.c +2 −130 Original line number Diff line number Diff line Loading @@ -91,25 +91,6 @@ static void gr2d_close_channel(struct tegra_drm_context *context) host1x_channel_put(context->channel); } static struct host1x_bo *host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle) { struct drm_gem_object *gem; struct tegra_bo *bo; gem = drm_gem_object_lookup(drm, file, handle); if (!gem) return NULL; mutex_lock(&drm->struct_mutex); drm_gem_object_unreference(gem); mutex_unlock(&drm->struct_mutex); bo = to_tegra_bo(gem); return &bo->base; } static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset) { struct gr2d *gr2d = dev_get_drvdata(dev); Loading @@ -135,120 +116,11 @@ static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset) return 0; } static int gr2d_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file) { unsigned int num_cmdbufs = args->num_cmdbufs; unsigned int num_relocs = args->num_relocs; unsigned int num_waitchks = args->num_waitchks; struct drm_tegra_cmdbuf __user *cmdbufs = (void * __user)(uintptr_t)args->cmdbufs; struct drm_tegra_reloc __user *relocs = (void * __user)(uintptr_t)args->relocs; struct drm_tegra_waitchk __user *waitchks = (void * __user)(uintptr_t)args->waitchks; struct drm_tegra_syncpt syncpt; struct host1x_job *job; int err; /* We don't yet support other than one syncpt_incr struct per submit */ if (args->num_syncpts != 1) return -EINVAL; job = host1x_job_alloc(context->channel, args->num_cmdbufs, args->num_relocs, args->num_waitchks); if (!job) return -ENOMEM; job->num_relocs = args->num_relocs; job->num_waitchk = args->num_waitchks; job->client = (u32)args->context; job->class = context->client->base.class; job->serialize = true; while (num_cmdbufs) { struct drm_tegra_cmdbuf cmdbuf; struct host1x_bo *bo; err = copy_from_user(&cmdbuf, cmdbufs, sizeof(cmdbuf)); if (err) goto fail; bo = host1x_bo_lookup(drm, file, cmdbuf.handle); if (!bo) { err = -ENOENT; goto fail; } host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); num_cmdbufs--; cmdbufs++; } err = copy_from_user(job->relocarray, relocs, sizeof(*relocs) * num_relocs); if (err) goto fail; while (num_relocs--) { struct host1x_reloc *reloc = &job->relocarray[num_relocs]; struct host1x_bo *cmdbuf, *target; cmdbuf = host1x_bo_lookup(drm, file, (u32)reloc->cmdbuf); target = host1x_bo_lookup(drm, file, (u32)reloc->target); reloc->cmdbuf = cmdbuf; reloc->target = target; if (!reloc->target || !reloc->cmdbuf) { err = -ENOENT; goto fail; } } err = copy_from_user(job->waitchk, waitchks, sizeof(*waitchks) * num_waitchks); if (err) goto fail; err = copy_from_user(&syncpt, (void * __user)(uintptr_t)args->syncpts, sizeof(syncpt)); if (err) goto fail; job->syncpt_id = syncpt.id; job->syncpt_incrs = syncpt.incrs; job->timeout = 10000; job->is_addr_reg = gr2d_is_addr_reg; if (args->timeout && args->timeout < 10000) job->timeout = args->timeout; err = host1x_job_pin(job, context->client->base.dev); if (err) goto fail; err = host1x_job_submit(job); if (err) goto fail_submit; args->fence = job->syncpt_end; host1x_job_put(job); return 0; fail_submit: host1x_job_unpin(job); fail: host1x_job_put(job); return err; } static const struct tegra_drm_client_ops gr2d_ops = { .open_channel = gr2d_open_channel, .close_channel = gr2d_close_channel, .submit = gr2d_submit, .is_addr_reg = gr2d_is_addr_reg, .submit = tegra_drm_submit, }; static const struct of_device_id gr2d_match[] = { Loading