diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/tegra/Kconfig | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dpaux.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/drm.c | 102 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/drm.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/dsi.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/fb.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/gem.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/hdmi.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/sor.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/trace.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/trace.h | 68 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/vic.c | 15 | ||||
-rw-r--r-- | drivers/gpu/host1x/bus.c | 18 | ||||
-rw-r--r-- | drivers/gpu/host1x/dev.c | 4 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/intr_hw.c | 24 | ||||
-rw-r--r-- | drivers/gpu/host1x/hw/syncpt_hw.c | 2 | ||||
-rw-r--r-- | drivers/gpu/host1x/job.c | 8 |
18 files changed, 276 insertions, 97 deletions
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index 2db29d67193d..dc58ab140151 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -3,6 +3,7 @@ config DRM_TEGRA depends on ARCH_TEGRA || (ARM && COMPILE_TEST) depends on COMMON_CLK depends on DRM + depends on OF select DRM_KMS_HELPER select DRM_MIPI_DSI select DRM_PANEL diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile index 6af3a9ad6565..8927784396e8 100644 --- a/drivers/gpu/drm/tegra/Makefile +++ b/drivers/gpu/drm/tegra/Makefile @@ -17,4 +17,6 @@ tegra-drm-y := \ falcon.o \ vic.o +tegra-drm-y += trace.o + obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index 2fde44c3a1b3..e4da041ba89b 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -25,6 +25,7 @@ #include "dpaux.h" #include "drm.h" +#include "trace.h" static DEFINE_MUTEX(dpaux_lock); static LIST_HEAD(dpaux_list); @@ -65,14 +66,19 @@ static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work) } static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux, - unsigned long offset) + unsigned int offset) { - return readl(dpaux->regs + (offset << 2)); + u32 value = readl(dpaux->regs + (offset << 2)); + + trace_dpaux_readl(dpaux->dev, offset, value); + + return value; } static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux, - u32 value, unsigned long offset) + u32 value, unsigned int offset) { + trace_dpaux_writel(dpaux->dev, offset, value); writel(value, dpaux->regs + (offset << 2)); } diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 224ce1dbb1cb..597d563d636a 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -306,8 +306,6 @@ host1x_bo_lookup(struct drm_file *file, u32 handle) if (!gem) return NULL; - drm_gem_object_unreference_unlocked(gem); - bo = to_tegra_bo(gem); return &bo->base; } @@ -396,8 +394,10 @@ int tegra_drm_submit(struct tegra_drm_context *context, (void __user *)(uintptr_t)args->waitchks; struct drm_tegra_syncpt syncpt; struct host1x *host1x = dev_get_drvdata(drm->dev->parent); + struct drm_gem_object **refs; struct host1x_syncpt *sp; struct host1x_job *job; + unsigned int num_refs; int err; /* We don't yet support other than one syncpt_incr struct per submit */ @@ -419,6 +419,21 @@ int tegra_drm_submit(struct tegra_drm_context *context, job->class = context->client->base.class; job->serialize = true; + /* + * Track referenced BOs so that they can be unreferenced after the + * submission is complete. + */ + num_refs = num_cmdbufs + num_relocs * 2 + num_waitchks; + + refs = kmalloc_array(num_refs, sizeof(*refs), GFP_KERNEL); + if (!refs) { + err = -ENOMEM; + goto put; + } + + /* reuse as an iterator later */ + num_refs = 0; + while (num_cmdbufs) { struct drm_tegra_cmdbuf cmdbuf; struct host1x_bo *bo; @@ -447,6 +462,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32); obj = host1x_to_tegra_bo(bo); + refs[num_refs++] = &obj->gem; /* * Gather buffer base address must be 4-bytes aligned, @@ -476,6 +492,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, reloc = &job->relocarray[num_relocs]; obj = host1x_to_tegra_bo(reloc->cmdbuf.bo); + refs[num_refs++] = &obj->gem; /* * The unaligned cmdbuf offset will cause an unaligned write @@ -489,6 +506,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, } obj = host1x_to_tegra_bo(reloc->target.bo); + refs[num_refs++] = &obj->gem; if (reloc->target.offset >= obj->gem.size) { err = -EINVAL; @@ -508,6 +526,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, goto fail; obj = host1x_to_tegra_bo(wait->bo); + refs[num_refs++] = &obj->gem; /* * The unaligned offset will cause an unaligned write during @@ -547,17 +566,20 @@ int tegra_drm_submit(struct tegra_drm_context *context, goto fail; err = host1x_job_submit(job); - if (err) - goto fail_submit; + if (err) { + host1x_job_unpin(job); + goto fail; + } args->fence = job->syncpt_end; - host1x_job_put(job); - return 0; - -fail_submit: - host1x_job_unpin(job); fail: + while (num_refs--) + drm_gem_object_put_unlocked(refs[num_refs]); + + kfree(refs); + +put: host1x_job_put(job); return err; } @@ -593,7 +615,7 @@ static int tegra_gem_mmap(struct drm_device *drm, void *data, args->offset = drm_vma_node_offset_addr(&bo->gem.vma_node); - drm_gem_object_unreference_unlocked(gem); + drm_gem_object_put_unlocked(gem); return 0; } @@ -860,7 +882,7 @@ static int tegra_gem_set_tiling(struct drm_device *drm, void *data, bo->tiling.mode = mode; bo->tiling.value = value; - drm_gem_object_unreference_unlocked(gem); + drm_gem_object_put_unlocked(gem); return 0; } @@ -900,7 +922,7 @@ static int tegra_gem_get_tiling(struct drm_device *drm, void *data, break; } - drm_gem_object_unreference_unlocked(gem); + drm_gem_object_put_unlocked(gem); return err; } @@ -925,7 +947,7 @@ static int tegra_gem_set_flags(struct drm_device *drm, void *data, if (args->flags & DRM_TEGRA_GEM_BOTTOM_UP) bo->flags |= TEGRA_BO_BOTTOM_UP; - drm_gem_object_unreference_unlocked(gem); + drm_gem_object_put_unlocked(gem); return 0; } @@ -947,7 +969,7 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data, if (bo->flags & TEGRA_BO_BOTTOM_UP) args->flags |= DRM_TEGRA_GEM_BOTTOM_UP; - drm_gem_object_unreference_unlocked(gem); + drm_gem_object_put_unlocked(gem); return 0; } @@ -955,20 +977,34 @@ static int tegra_gem_get_flags(struct drm_device *drm, void *data, static const struct drm_ioctl_desc tegra_drm_ioctls[] = { #ifdef CONFIG_DRM_TEGRA_STAGING - DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, 0), - DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, 0), - DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, 0), - DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, 0), - DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, 0), - DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, 0), - DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, 0), - DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, 0), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_CREATE, tegra_gem_create, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_MMAP, tegra_gem_mmap, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_READ, tegra_syncpt_read, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_INCR, tegra_syncpt_incr, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_SYNCPT_WAIT, tegra_syncpt_wait, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_OPEN_CHANNEL, tegra_open_channel, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_CLOSE_CHANNEL, tegra_close_channel, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT, tegra_get_syncpt, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_SUBMIT, tegra_submit, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GET_SYNCPT_BASE, tegra_get_syncpt_base, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_TILING, tegra_gem_set_tiling, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_TILING, tegra_gem_get_tiling, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_SET_FLAGS, tegra_gem_set_flags, + DRM_UNLOCKED | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(TEGRA_GEM_GET_FLAGS, tegra_gem_get_flags, + DRM_UNLOCKED | DRM_RENDER_ALLOW), #endif }; @@ -1035,9 +1071,11 @@ static int tegra_debugfs_iova(struct seq_file *s, void *data) struct tegra_drm *tegra = drm->dev_private; struct drm_printer p = drm_seq_file_printer(s); - mutex_lock(&tegra->mm_lock); - drm_mm_print(&tegra->mm, &p); - mutex_unlock(&tegra->mm_lock); + if (tegra->domain) { + mutex_lock(&tegra->mm_lock); + drm_mm_print(&tegra->mm, &p); + mutex_unlock(&tegra->mm_lock); + } return 0; } @@ -1057,7 +1095,7 @@ static int tegra_debugfs_init(struct drm_minor *minor) static struct drm_driver tegra_drm_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | - DRIVER_ATOMIC, + DRIVER_ATOMIC | DRIVER_RENDER, .load = tegra_drm_load, .unload = tegra_drm_unload, .open = tegra_drm_open, diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 6d6da01282f3..063f5d397526 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -23,6 +23,7 @@ #include <drm/drm_fixed.h> #include "gem.h" +#include "trace.h" struct reset_control; @@ -172,14 +173,19 @@ static inline struct tegra_dc *to_tegra_dc(struct drm_crtc *crtc) } static inline void tegra_dc_writel(struct tegra_dc *dc, u32 value, - unsigned long offset) + unsigned int offset) { + trace_dc_writel(dc->dev, offset, value); writel(value, dc->regs + (offset << 2)); } -static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned long offset) +static inline u32 tegra_dc_readl(struct tegra_dc *dc, unsigned int offset) { - return readl(dc->regs + (offset << 2)); + u32 value = readl(dc->regs + (offset << 2)); + + trace_dc_readl(dc->dev, offset, value); + + return value; } struct tegra_dc_window { diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index e4b5aedfdbd4..046649ec9441 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -28,6 +28,7 @@ #include "drm.h" #include "dsi.h" #include "mipi-phy.h" +#include "trace.h" struct tegra_dsi_state { struct drm_connector_state base; @@ -105,15 +106,20 @@ static struct tegra_dsi_state *tegra_dsi_get_state(struct tegra_dsi *dsi) return to_dsi_state(dsi->output.connector.state); } -static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned long reg) +static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned int offset) { - return readl(dsi->regs + (reg << 2)); + u32 value = readl(dsi->regs + (offset << 2)); + + trace_dsi_readl(dsi->dev, offset, value); + + return value; } static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value, - unsigned long reg) + unsigned int offset) { - writel(value, dsi->regs + (reg << 2)); + trace_dsi_writel(dsi->dev, offset, value); + writel(value, dsi->regs + (offset << 2)); } static int tegra_dsi_show_regs(struct seq_file *s, void *data) diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 25acb73ee728..80540c1c66dc 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -88,7 +88,7 @@ static void tegra_fb_destroy(struct drm_framebuffer *framebuffer) if (bo->pages) vunmap(bo->vaddr); - drm_gem_object_unreference_unlocked(&bo->gem); + drm_gem_object_put_unlocked(&bo->gem); } } @@ -195,7 +195,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, unreference: while (i--) - drm_gem_object_unreference_unlocked(&planes[i]->gem); + drm_gem_object_put_unlocked(&planes[i]->gem); return ERR_PTR(err); } @@ -242,7 +242,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, info = drm_fb_helper_alloc_fbi(helper); if (IS_ERR(info)) { dev_err(drm->dev, "failed to allocate framebuffer info\n"); - drm_gem_object_unreference_unlocked(&bo->gem); + drm_gem_object_put_unlocked(&bo->gem); return PTR_ERR(info); } @@ -251,7 +251,7 @@ static int tegra_fbdev_probe(struct drm_fb_helper *helper, err = PTR_ERR(fbdev->fb); dev_err(drm->dev, "failed to allocate DRM framebuffer: %d\n", err); - drm_gem_object_unreference_unlocked(&bo->gem); + drm_gem_object_put_unlocked(&bo->gem); return PTR_ERR(fbdev->fb); } diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index c6079affe642..ab1e53d434e8 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -24,7 +24,7 @@ static void tegra_bo_put(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); - drm_gem_object_unreference_unlocked(&obj->gem); + drm_gem_object_put_unlocked(&obj->gem); } static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt) @@ -95,7 +95,7 @@ static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); - drm_gem_object_reference(&obj->gem); + drm_gem_object_get(&obj->gem); return bo; } @@ -325,7 +325,7 @@ struct tegra_bo *tegra_bo_create_with_handle(struct drm_file *file, return ERR_PTR(err); } - drm_gem_object_unreference_unlocked(&bo->gem); + drm_gem_object_put_unlocked(&bo->gem); return bo; } @@ -460,30 +460,28 @@ const struct vm_operations_struct tegra_bo_vm_ops = { .close = drm_gem_vm_close, }; -int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) +static int tegra_gem_mmap(struct drm_gem_object *gem, + struct vm_area_struct *vma) { - struct drm_gem_object *gem; - struct tegra_bo *bo; - int ret; - - ret = drm_gem_mmap(file, vma); - if (ret) - return ret; - - gem = vma->vm_private_data; - bo = to_tegra_bo(gem); + struct tegra_bo *bo = to_tegra_bo(gem); if (!bo->pages) { unsigned long vm_pgoff = vma->vm_pgoff; + int err; + /* + * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), + * and set the vm_pgoff (used as a fake buffer offset by DRM) + * to 0 as we want to map the whole buffer. + */ vma->vm_flags &= ~VM_PFNMAP; vma->vm_pgoff = 0; - ret = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr, + err = dma_mmap_wc(gem->dev->dev, vma, bo->vaddr, bo->paddr, gem->size); - if (ret) { + if (err < 0) { drm_gem_vm_close(vma); - return ret; + return err; } vma->vm_pgoff = vm_pgoff; @@ -499,6 +497,20 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) return 0; } +int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct drm_gem_object *gem; + int err; + + err = drm_gem_mmap(file, vma); + if (err < 0) + return err; + + gem = vma->vm_private_data; + + return tegra_gem_mmap(gem, vma); +} + static struct sg_table * tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) @@ -582,7 +594,14 @@ static void tegra_gem_prime_kunmap(struct dma_buf *buf, unsigned long page, static int tegra_gem_prime_mmap(struct dma_buf *buf, struct vm_area_struct *vma) { - return -EINVAL; + struct drm_gem_object *gem = buf->priv; + int err; + + err = drm_gem_mmap_obj(gem, gem->size, vma); + if (err < 0) + return err; + + return tegra_gem_mmap(gem, vma); } static void *tegra_gem_prime_vmap(struct dma_buf *buf) @@ -633,7 +652,7 @@ struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm, struct drm_gem_object *gem = buf->priv; if (gem->dev == drm) { - drm_gem_object_reference(gem); + drm_gem_object_get(gem); return gem; } } diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c index a621b0da4092..5b9d83b71943 100644 --- a/drivers/gpu/drm/tegra/hdmi.c +++ b/drivers/gpu/drm/tegra/hdmi.c @@ -24,6 +24,7 @@ #include "hdmi.h" #include "drm.h" #include "dc.h" +#include "trace.h" #define HDMI_ELD_BUFFER_SIZE 96 @@ -100,14 +101,19 @@ enum { }; static inline u32 tegra_hdmi_readl(struct tegra_hdmi *hdmi, - unsigned long offset) + unsigned int offset) { - return readl(hdmi->regs + (offset << 2)); + u32 value = readl(hdmi->regs + (offset << 2)); + + trace_hdmi_readl(hdmi->dev, offset, value); + + return value; } static inline void tegra_hdmi_writel(struct tegra_hdmi *hdmi, u32 value, - unsigned long offset) + unsigned int offset) { + trace_hdmi_writel(hdmi->dev, offset, value); writel(value, hdmi->regs + (offset << 2)); } diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index e0642d05a8d3..7ab1d1dc7cd7 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -26,6 +26,7 @@ #include "dc.h" #include "drm.h" #include "sor.h" +#include "trace.h" #define SOR_REKEY 0x38 @@ -232,14 +233,19 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output) return container_of(output, struct tegra_sor, output); } -static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned long offset) +static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned int offset) { - return readl(sor->regs + (offset << 2)); + u32 value = readl(sor->regs + (offset << 2)); + + trace_sor_readl(sor->dev, offset, value); + + return value; } static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value, - unsigned long offset) + unsigned int offset) { + trace_sor_writel(sor->dev, offset, value); writel(value, sor->regs + (offset << 2)); } diff --git a/drivers/gpu/drm/tegra/trace.c b/drivers/gpu/drm/tegra/trace.c new file mode 100644 index 000000000000..006f65c72a34 --- /dev/null +++ b/drivers/gpu/drm/tegra/trace.c @@ -0,0 +1,2 @@ +#define CREATE_TRACE_POINTS +#include "trace.h" diff --git a/drivers/gpu/drm/tegra/trace.h b/drivers/gpu/drm/tegra/trace.h new file mode 100644 index 000000000000..e9b7cdad5c4c --- /dev/null +++ b/drivers/gpu/drm/tegra/trace.h @@ -0,0 +1,68 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM tegra + +#if !defined(DRM_TEGRA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define DRM_TEGRA_TRACE_H 1 + +#include <linux/device.h> +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(register_access, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value), + TP_STRUCT__entry( + __field(struct device *, dev) + __field(unsigned int, offset) + __field(u32, value) + ), + TP_fast_assign( + __entry->dev = dev; + __entry->offset = offset; + __entry->value = value; + ), + TP_printk("%s %04x %08x", dev_name(__entry->dev), __entry->offset, + __entry->value) +); + +DEFINE_EVENT(register_access, dc_writel, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); +DEFINE_EVENT(register_access, dc_readl, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); + +DEFINE_EVENT(register_access, hdmi_writel, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); +DEFINE_EVENT(register_access, hdmi_readl, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); + +DEFINE_EVENT(register_access, dsi_writel, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); +DEFINE_EVENT(register_access, dsi_readl, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); + +DEFINE_EVENT(register_access, dpaux_writel, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); +DEFINE_EVENT(register_access, dpaux_readl, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); + +DEFINE_EVENT(register_access, sor_writel, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); +DEFINE_EVENT(register_access, sor_readl, + TP_PROTO(struct device *dev, unsigned int offset, u32 value), + TP_ARGS(dev, offset, value)); + +#endif /* DRM_TEGRA_TRACE_H */ + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace +#include <trace/define_trace.h> diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index 47cb1aaa58b1..2448229fa653 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -258,12 +258,16 @@ static const struct tegra_drm_client_ops vic_ops = { .submit = tegra_drm_submit, }; +#define NVIDIA_TEGRA_124_VIC_FIRMWARE "nvidia/tegra124/vic03_ucode.bin" + static const struct vic_config vic_t124_config = { - .firmware = "nvidia/tegra124/vic03_ucode.bin", + .firmware = NVIDIA_TEGRA_124_VIC_FIRMWARE, }; +#define NVIDIA_TEGRA_210_VIC_FIRMWARE "nvidia/tegra210/vic04_ucode.bin" + static const struct vic_config vic_t210_config = { - .firmware = "nvidia/tegra210/vic04_ucode.bin", + .firmware = NVIDIA_TEGRA_210_VIC_FIRMWARE, }; static const struct of_device_id vic_match[] = { @@ -394,3 +398,10 @@ struct platform_driver tegra_vic_driver = { .probe = vic_probe, .remove = vic_remove, }; + +#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) +MODULE_FIRMWARE(NVIDIA_TEGRA_124_VIC_FIRMWARE); +#endif +#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) +MODULE_FIRMWARE(NVIDIA_TEGRA_210_VIC_FIRMWARE); +#endif diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 7ece0e9058c6..f9cde03030fd 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -44,9 +44,12 @@ struct host1x_subdev { * @np: device node */ static int host1x_subdev_add(struct host1x_device *device, + struct host1x_driver *driver, struct device_node *np) { struct host1x_subdev *subdev; + struct device_node *child; + int err; subdev = kzalloc(sizeof(*subdev), GFP_KERNEL); if (!subdev) @@ -59,6 +62,19 @@ static int host1x_subdev_add(struct host1x_device *device, list_add_tail(&subdev->list, &device->subdevs); mutex_unlock(&device->subdevs_lock); + /* recursively add children */ + for_each_child_of_node(np, child) { + if (of_match_node(driver->subdevs, child) && + of_device_is_available(child)) { + err = host1x_subdev_add(device, driver, child); + if (err < 0) { + /* XXX cleanup? */ + of_node_put(child); + return err; + } + } + } + return 0; } @@ -87,7 +103,7 @@ static int host1x_device_parse_dt(struct host1x_device *device, for_each_child_of_node(device->dev.parent->of_node, np) { if (of_match_node(driver->subdevs, np) && of_device_is_available(np)) { - err = host1x_subdev_add(device, np); + err = host1x_subdev_add(device, driver, np); if (err < 0) { of_node_put(np); return err; diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index 778272514164..7f22c5c37660 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -134,8 +134,8 @@ static int host1x_probe(struct platform_device *pdev) syncpt_irq = platform_get_irq(pdev, 0); if (syncpt_irq < 0) { - dev_err(&pdev->dev, "failed to get IRQ\n"); - return -ENXIO; + dev_err(&pdev->dev, "failed to get IRQ: %d\n", syncpt_irq); + return syncpt_irq; } host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c index dacb8009a605..37ebb51703fa 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -33,10 +33,10 @@ static void host1x_intr_syncpt_handle(struct host1x_syncpt *syncpt) unsigned int id = syncpt->id; struct host1x *host = syncpt->host; - host1x_sync_writel(host, BIT_MASK(id), - HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id))); - host1x_sync_writel(host, BIT_MASK(id), - HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id))); + host1x_sync_writel(host, BIT(id % 32), + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32)); + host1x_sync_writel(host, BIT(id % 32), + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32)); schedule_work(&syncpt->intr.work); } @@ -50,9 +50,9 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id) for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) { reg = host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i)); - for_each_set_bit(id, ®, BITS_PER_LONG) { + for_each_set_bit(id, ®, 32) { struct host1x_syncpt *syncpt = - host->syncpt + (i * BITS_PER_LONG + id); + host->syncpt + (i * 32 + id); host1x_intr_syncpt_handle(syncpt); } } @@ -117,17 +117,17 @@ static void _host1x_intr_set_syncpt_threshold(struct host1x *host, static void _host1x_intr_enable_syncpt_intr(struct host1x *host, unsigned int id) { - host1x_sync_writel(host, BIT_MASK(id), - HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(BIT_WORD(id))); + host1x_sync_writel(host, BIT(id % 32), + HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id / 32)); } static void _host1x_intr_disable_syncpt_intr(struct host1x *host, unsigned int id) { - host1x_sync_writel(host, BIT_MASK(id), - HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(BIT_WORD(id))); - host1x_sync_writel(host, BIT_MASK(id), - HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(BIT_WORD(id))); + host1x_sync_writel(host, BIT(id % 32), + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id / 32)); + host1x_sync_writel(host, BIT(id % 32), + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id / 32)); } static int _host1x_free_syncpt_irq(struct host1x *host) diff --git a/drivers/gpu/host1x/hw/syncpt_hw.c b/drivers/gpu/host1x/hw/syncpt_hw.c index c93f74fcce72..7b0270d60742 100644 --- a/drivers/gpu/host1x/hw/syncpt_hw.c +++ b/drivers/gpu/host1x/hw/syncpt_hw.c @@ -89,7 +89,7 @@ static int syncpt_cpu_incr(struct host1x_syncpt *sp) host1x_syncpt_idle(sp)) return -EINVAL; - host1x_sync_writel(host, BIT_MASK(sp->id), + host1x_sync_writel(host, BIT(sp->id % 32), HOST1X_SYNC_SYNCPT_CPU_INCR(reg_offset)); wmb(); diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index bee504406cfc..db509ab8874e 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -197,10 +197,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) } phys_addr = host1x_bo_pin(reloc->target.bo, &sgt); - if (!phys_addr) { - err = -EINVAL; - goto unpin; - } job->addr_phys[job->num_unpins] = phys_addr; job->unpins[job->num_unpins].bo = reloc->target.bo; @@ -225,10 +221,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) } phys_addr = host1x_bo_pin(g->bo, &sgt); - if (!phys_addr) { - err = -EINVAL; - goto unpin; - } if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) { for_each_sg(sgt->sgl, sg, sgt->nents, j) |