diff options
author | Dave Airlie <airlied@redhat.com> | 2016-12-13 14:27:41 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-12-13 14:27:41 +1000 |
commit | a77a1ad11ef3dc6dd0ae6601eb055495374bdce5 (patch) | |
tree | 29cf8ae34fa31bf42e3a17723d04a23d472ead8e | |
parent | bdda9dd67445707a39ebb6d2be84dfb89ef0dea1 (diff) | |
parent | 585ee0f27ef7b8db46807b960388b7e58b60766d (diff) |
Merge tag 'drm/tegra/for-4.10-rc1' of git://anongit.freedesktop.org/tegra/linux into drm-next
drm/tegra: Changes for v4.10-rc1
This has a couple of fixes for IOMMU support and some fixes for error
handling.
* tag 'drm/tegra/for-4.10-rc1' of git://anongit.freedesktop.org/tegra/linux:
drm/tegra: Set sgt pointer in BO pin
drm/tegra: Support kernel mappings with IOMMU
gpu: host1x: Add locking to syncpt
gpu: host1x: Store device address to all bufs
drm/tegra: gem: Remove some dead code
drm/tegra: sor: No need to free devm_ allocated memory
drm/tegra: Fix error handling
drm/tegra: dpaux: Fix error handling
-rw-r--r-- | drivers/gpu/drm/tegra/dpaux.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/gem.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/gr3d.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/sor.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/dev.h | 3 | ||||
-rw-r--r-- | drivers/gpu/host1x/job.c | 9 | ||||
-rw-r--r-- | drivers/gpu/host1x/syncpt.c | 23 |
7 files changed, 64 insertions, 22 deletions
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 059f409556d5..2fde44c3a1b3 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -539,9 +539,9 @@ static int tegra_dpaux_probe(struct platform_device *pdev) dpaux->desc.owner = THIS_MODULE; dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux); - if (!dpaux->pinctrl) { + if (IS_ERR(dpaux->pinctrl)) { dev_err(&pdev->dev, "failed to register pincontrol\n"); - return -ENODEV; + return PTR_ERR(dpaux->pinctrl); } #endif /* enable and clear all interrupts */ diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 95e622e31931..c08e5279eeac 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -2,7 +2,7 @@ * NVIDIA Tegra DRM GEM helper functions * * Copyright (C) 2012 Sascha Hauer, Pengutronix - * Copyright (C) 2013 NVIDIA CORPORATION, All rights reserved. + * Copyright (C) 2013-2015 NVIDIA CORPORATION, All rights reserved. * * Based on the GEM/CMA helpers * @@ -36,6 +36,8 @@ static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); + *sgt = obj->sgt; + return obj->paddr; } @@ -47,23 +49,51 @@ static void *tegra_bo_mmap(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); - return obj->vaddr; + if (obj->vaddr) + return obj->vaddr; + else if (obj->gem.import_attach) + return dma_buf_vmap(obj->gem.import_attach->dmabuf); + else + return vmap(obj->pages, obj->num_pages, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); } static void tegra_bo_munmap(struct host1x_bo *bo, void *addr) { + struct tegra_bo *obj = host1x_to_tegra_bo(bo); + + if (obj->vaddr) + return; + else if (obj->gem.import_attach) + dma_buf_vunmap(obj->gem.import_attach->dmabuf, addr); + else + vunmap(addr); } static void *tegra_bo_kmap(struct host1x_bo *bo, unsigned int page) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); - return obj->vaddr + page * PAGE_SIZE; + if (obj->vaddr) + return obj->vaddr + page * PAGE_SIZE; + else if (obj->gem.import_attach) + return dma_buf_kmap(obj->gem.import_attach->dmabuf, page); + else + return vmap(obj->pages + page, 1, VM_MAP, + pgprot_writecombine(PAGE_KERNEL)); } static void tegra_bo_kunmap(struct host1x_bo *bo, unsigned int page, void *addr) { + struct tegra_bo *obj = host1x_to_tegra_bo(bo); + + if (obj->vaddr) + return; + else if (obj->gem.import_attach) + dma_buf_kunmap(obj->gem.import_attach->dmabuf, page, addr); + else + vunmap(addr); } static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo) @@ -318,11 +348,6 @@ static struct tegra_bo *tegra_bo_import(struct drm_device *drm, get_dma_buf(buf); bo->sgt = dma_buf_map_attachment(attach, DMA_TO_DEVICE); - if (!bo->sgt) { - err = -ENOMEM; - goto detach; - } - if (IS_ERR(bo->sgt)) { err = PTR_ERR(bo->sgt); goto detach; diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 0b3f2b977ba0..13f0d1b7cd98 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -268,9 +268,9 @@ static int gr3d_probe(struct platform_device *pdev) if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) { gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2"); - if (IS_ERR(gr3d->clk)) { + if (IS_ERR(gr3d->clk_secondary)) { dev_err(&pdev->dev, "cannot get secondary clock\n"); - return PTR_ERR(gr3d->clk); + return PTR_ERR(gr3d->clk_secondary); } gr3d->rst_secondary = devm_reset_control_get(&pdev->dev, diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 74d0540b8d4c..a8f528925009 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -349,8 +349,6 @@ static struct clk *tegra_clk_sor_brick_register(struct tegra_sor *sor, brick->hw.init = &init; clk = devm_clk_register(sor->dev, &brick->hw); - if (IS_ERR(clk)) - kfree(brick); return clk; } diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h index 5220510f39da..06dd4f85125f 100644 --- a/drivers/gpu/host1x/dev.h +++ b/drivers/gpu/host1x/dev.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, NVIDIA Corporation. + * Copyright (c) 2012-2015, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -120,6 +120,7 @@ struct host1x { struct host1x_syncpt *nop_sp; + struct mutex syncpt_mutex; struct mutex chlist_mutex; struct host1x_channel chlist; unsigned long allocated_channels; diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index a91b7c4a6110..92c3df933303 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -1,7 +1,7 @@ /* * Tegra host1x Job * - * Copyright (c) 2010-2013, NVIDIA Corporation. + * Copyright (c) 2010-2015, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -539,9 +539,12 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev) g->base = job->gather_addr_phys[i]; - for (j = i + 1; j < job->num_gathers; j++) - if (job->gathers[j].bo == g->bo) + for (j = i + 1; j < job->num_gathers; j++) { + if (job->gathers[j].bo == g->bo) { job->gathers[j].handled = true; + job->gathers[j].base = g->base; + } + } err = do_relocs(job, g->bo); if (err) diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c index 95589328ad52..25c11a85050b 100644 --- a/drivers/gpu/host1x/syncpt.c +++ b/drivers/gpu/host1x/syncpt.c @@ -1,7 +1,7 @@ /* * Tegra host1x Syncpoints * - * Copyright (c) 2010-2013, NVIDIA Corporation. + * Copyright (c) 2010-2015, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -61,22 +61,24 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, struct host1x_syncpt *sp = host->syncpt; char *name; + mutex_lock(&host->syncpt_mutex); + for (i = 0; i < host->info->nb_pts && sp->name; i++, sp++) ; if (i >= host->info->nb_pts) - return NULL; + goto unlock; if (flags & HOST1X_SYNCPT_HAS_BASE) { sp->base = host1x_syncpt_base_request(host); if (!sp->base) - return NULL; + goto unlock; } name = kasprintf(GFP_KERNEL, "%02u-%s", sp->id, dev ? dev_name(dev) : NULL); if (!name) - return NULL; + goto free_base; sp->dev = dev; sp->name = name; @@ -86,7 +88,15 @@ static struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host, else sp->client_managed = false; + mutex_unlock(&host->syncpt_mutex); return sp; + +free_base: + host1x_syncpt_base_free(sp->base); + sp->base = NULL; +unlock: + mutex_unlock(&host->syncpt_mutex); + return NULL; } u32 host1x_syncpt_id(struct host1x_syncpt *sp) @@ -378,6 +388,7 @@ int host1x_syncpt_init(struct host1x *host) for (i = 0; i < host->info->nb_bases; i++) bases[i].id = i; + mutex_init(&host->syncpt_mutex); host->syncpt = syncpt; host->bases = bases; @@ -405,12 +416,16 @@ void host1x_syncpt_free(struct host1x_syncpt *sp) if (!sp) return; + mutex_lock(&sp->host->syncpt_mutex); + host1x_syncpt_base_free(sp->base); kfree(sp->name); sp->base = NULL; sp->dev = NULL; sp->name = NULL; sp->client_managed = false; + + mutex_unlock(&sp->host->syncpt_mutex); } EXPORT_SYMBOL(host1x_syncpt_free); |