In preparation for making the GPU supporting code optional split the debugfs code into three main pieces: GEM (always enabled), KMS (only enabled if KMS driver parts are enabled) and GPU (currently always enabled, will become optional later).
Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@oss.qualcomm.com> --- drivers/gpu/drm/msm/Makefile | 4 +- drivers/gpu/drm/msm/msm_debugfs.c | 420 ---------------------------------- drivers/gpu/drm/msm/msm_debugfs.h | 14 -- drivers/gpu/drm/msm/msm_drv.c | 21 +- drivers/gpu/drm/msm/msm_drv.h | 4 +- drivers/gpu/drm/msm/msm_gem.h | 8 + drivers/gpu/drm/msm/msm_gem_debugfs.c | 96 ++++++++ drivers/gpu/drm/msm/msm_gpu_debugfs.c | 213 +++++++++++++++++ drivers/gpu/drm/msm/msm_kms.h | 8 + drivers/gpu/drm/msm/msm_kms_debugfs.c | 129 +++++++++++ 10 files changed, 476 insertions(+), 441 deletions(-) diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 0ac977a6ed01d91111d706995f341ced29f5ca8d..a475479fe201cb03937d30ee913c2e178675384e 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -107,10 +107,10 @@ msm-display-$(CONFIG_DRM_MSM_KMS) += \ disp/msm_disp_snapshot_util.o \ msm-y += \ - msm_debugfs.o \ msm_drv.o \ msm_fence.o \ msm_gem.o \ + msm_gem_debugfs.o \ msm_gem_prime.o \ msm_gem_shrinker.o \ msm_gem_submit.o \ @@ -118,6 +118,7 @@ msm-y += \ msm_gem_vm_bind.o \ msm_gpu.o \ msm_gpu_devfreq.o \ + msm_gpu_debugfs.o \ msm_io_utils.o \ msm_ioctl.o \ msm_iommu.o \ @@ -133,6 +134,7 @@ msm-$(CONFIG_DRM_MSM_KMS) += \ msm_atomic_tracepoints.o \ msm_fb.o \ msm_kms.o \ + msm_kms_debugfs.o \ msm-$(CONFIG_DRM_MSM_KMS_FBDEV) += msm_fbdev.o diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c deleted file mode 100644 index 97dc70876442f9aa932677edbed5d26f6095e7ee..0000000000000000000000000000000000000000 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ /dev/null @@ -1,420 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2013-2016 Red Hat - * Author: Rob Clark <robdcl...@gmail.com> - */ - -#ifdef CONFIG_DEBUG_FS - -#include <linux/debugfs.h> -#include <linux/fault-inject.h> - -#include <drm/drm_debugfs.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_file.h> -#include <drm/drm_framebuffer.h> - -#include "msm_drv.h" -#include "msm_gpu.h" -#include "msm_kms.h" -#include "msm_debugfs.h" -#include "disp/msm_disp_snapshot.h" - -/* - * GPU Snapshot: - */ - -struct msm_gpu_show_priv { - struct msm_gpu_state *state; - struct drm_device *dev; -}; - -static int msm_gpu_show(struct seq_file *m, void *arg) -{ - struct drm_printer p = drm_seq_file_printer(m); - struct msm_gpu_show_priv *show_priv = m->private; - struct msm_drm_private *priv = show_priv->dev->dev_private; - struct msm_gpu *gpu = priv->gpu; - int ret; - - ret = mutex_lock_interruptible(&gpu->lock); - if (ret) - return ret; - - drm_printf(&p, "%s Status:\n", gpu->name); - gpu->funcs->show(gpu, show_priv->state, &p); - - mutex_unlock(&gpu->lock); - - return 0; -} - -static int msm_gpu_release(struct inode *inode, struct file *file) -{ - struct seq_file *m = file->private_data; - struct msm_gpu_show_priv *show_priv = m->private; - struct msm_drm_private *priv = show_priv->dev->dev_private; - struct msm_gpu *gpu = priv->gpu; - - mutex_lock(&gpu->lock); - gpu->funcs->gpu_state_put(show_priv->state); - mutex_unlock(&gpu->lock); - - kfree(show_priv); - - return single_release(inode, file); -} - -static int msm_gpu_open(struct inode *inode, struct file *file) -{ - struct drm_device *dev = inode->i_private; - struct msm_drm_private *priv = dev->dev_private; - struct msm_gpu *gpu = priv->gpu; - struct msm_gpu_show_priv *show_priv; - int ret; - - if (!gpu || !gpu->funcs->gpu_state_get) - return -ENODEV; - - show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL); - if (!show_priv) - return -ENOMEM; - - ret = mutex_lock_interruptible(&gpu->lock); - if (ret) - goto free_priv; - - pm_runtime_get_sync(&gpu->pdev->dev); - msm_gpu_hw_init(gpu); - show_priv->state = gpu->funcs->gpu_state_get(gpu); - pm_runtime_put_sync(&gpu->pdev->dev); - - mutex_unlock(&gpu->lock); - - if (IS_ERR(show_priv->state)) { - ret = PTR_ERR(show_priv->state); - goto free_priv; - } - - show_priv->dev = dev; - - ret = single_open(file, msm_gpu_show, show_priv); - if (ret) - goto free_priv; - - return 0; - -free_priv: - kfree(show_priv); - return ret; -} - -static const struct file_operations msm_gpu_fops = { - .owner = THIS_MODULE, - .open = msm_gpu_open, - .read = seq_read, - .llseek = seq_lseek, - .release = msm_gpu_release, -}; - -#ifdef CONFIG_DRM_MSM_KMS -static int msm_fb_show(struct seq_file *m, void *arg) -{ - struct drm_info_node *node = m->private; - struct drm_device *dev = node->minor->dev; - struct drm_framebuffer *fb, *fbdev_fb = NULL; - - if (dev->fb_helper && dev->fb_helper->fb) { - seq_puts(m, "fbcon "); - fbdev_fb = dev->fb_helper->fb; - msm_framebuffer_describe(fbdev_fb, m); - } - - mutex_lock(&dev->mode_config.fb_lock); - list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - if (fb == fbdev_fb) - continue; - - seq_puts(m, "user "); - msm_framebuffer_describe(fb, m); - } - mutex_unlock(&dev->mode_config.fb_lock); - - return 0; -} - -static struct drm_info_list msm_kms_debugfs_list[] = { - { "fb", msm_fb_show }, -}; - -/* - * Display Snapshot: - */ - -static int msm_kms_show(struct seq_file *m, void *arg) -{ - struct drm_printer p = drm_seq_file_printer(m); - struct msm_disp_state *state = m->private; - - msm_disp_state_print(state, &p); - - return 0; -} - -static int msm_kms_release(struct inode *inode, struct file *file) -{ - struct seq_file *m = file->private_data; - struct msm_disp_state *state = m->private; - - msm_disp_state_free(state); - - return single_release(inode, file); -} - -static int msm_kms_open(struct inode *inode, struct file *file) -{ - struct drm_device *dev = inode->i_private; - struct msm_drm_private *priv = dev->dev_private; - struct msm_disp_state *state; - int ret; - - if (!priv->kms) - return -ENODEV; - - ret = mutex_lock_interruptible(&priv->kms->dump_mutex); - if (ret) - return ret; - - state = msm_disp_snapshot_state_sync(priv->kms); - - mutex_unlock(&priv->kms->dump_mutex); - - if (IS_ERR(state)) { - return PTR_ERR(state); - } - - ret = single_open(file, msm_kms_show, state); - if (ret) { - msm_disp_state_free(state); - return ret; - } - - return 0; -} - -static const struct file_operations msm_kms_fops = { - .owner = THIS_MODULE, - .open = msm_kms_open, - .read = seq_read, - .llseek = seq_lseek, - .release = msm_kms_release, -}; - -static void msm_debugfs_kms_init(struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct msm_drm_private *priv = dev->dev_private; - - drm_debugfs_create_files(msm_kms_debugfs_list, - ARRAY_SIZE(msm_kms_debugfs_list), - minor->debugfs_root, minor); - debugfs_create_file("kms", 0400, minor->debugfs_root, - dev, &msm_kms_fops); - - if (priv->kms->funcs->debugfs_init) - priv->kms->funcs->debugfs_init(priv->kms, minor); - -} -#else /* ! CONFIG_DRM_MSM_KMS */ -static void msm_debugfs_kms_init(struct drm_minor *minor) -{ -} -#endif - -/* - * Other debugfs: - */ - -static unsigned long last_shrink_freed; - -static int -shrink_get(void *data, u64 *val) -{ - *val = last_shrink_freed; - - return 0; -} - -static int -shrink_set(void *data, u64 val) -{ - struct drm_device *dev = data; - - last_shrink_freed = msm_gem_shrinker_shrink(dev, val); - - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops, - shrink_get, shrink_set, - "0x%08llx\n"); - -/* - * Return the number of microseconds to wait until stall-on-fault is - * re-enabled. If 0 then it is already enabled or will be re-enabled on the - * next submit (unless there's a leftover devcoredump). This is useful for - * kernel tests that intentionally produce a fault and check the devcoredump to - * wait until the cooldown period is over. - */ - -static int -stall_reenable_time_get(void *data, u64 *val) -{ - struct msm_drm_private *priv = data; - unsigned long irq_flags; - - spin_lock_irqsave(&priv->fault_stall_lock, irq_flags); - - if (priv->stall_enabled) - *val = 0; - else - *val = max(ktime_us_delta(priv->stall_reenable_time, ktime_get()), 0); - - spin_unlock_irqrestore(&priv->fault_stall_lock, irq_flags); - - return 0; -} - -DEFINE_DEBUGFS_ATTRIBUTE(stall_reenable_time_fops, - stall_reenable_time_get, NULL, - "%lld\n"); - -static int msm_gem_show(struct seq_file *m, void *arg) -{ - struct drm_info_node *node = m->private; - struct drm_device *dev = node->minor->dev; - struct msm_drm_private *priv = dev->dev_private; - int ret; - - ret = mutex_lock_interruptible(&priv->obj_lock); - if (ret) - return ret; - - msm_gem_describe_objects(&priv->objects, m); - - mutex_unlock(&priv->obj_lock); - - return 0; -} - -static int msm_mm_show(struct seq_file *m, void *arg) -{ - struct drm_info_node *node = m->private; - struct drm_device *dev = node->minor->dev; - struct drm_printer p = drm_seq_file_printer(m); - - drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); - - return 0; -} - -static struct drm_info_list msm_debugfs_list[] = { - {"gem", msm_gem_show}, - { "mm", msm_mm_show }, -}; - -static int late_init_minor(struct drm_minor *minor) -{ - struct drm_device *dev; - struct msm_drm_private *priv; - int ret; - - if (!minor) - return 0; - - dev = minor->dev; - priv = dev->dev_private; - - if (!priv->gpu_pdev) - return 0; - - ret = msm_rd_debugfs_init(minor); - if (ret) { - DRM_DEV_ERROR(dev->dev, "could not install rd debugfs\n"); - return ret; - } - - ret = msm_perf_debugfs_init(minor); - if (ret) { - DRM_DEV_ERROR(dev->dev, "could not install perf debugfs\n"); - return ret; - } - - return 0; -} - -int msm_debugfs_late_init(struct drm_device *dev) -{ - int ret; - ret = late_init_minor(dev->primary); - if (ret) - return ret; - ret = late_init_minor(dev->render); - return ret; -} - -static void msm_debugfs_gpu_init(struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct msm_drm_private *priv = dev->dev_private; - struct dentry *gpu_devfreq; - - debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root, - dev, &msm_gpu_fops); - - debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, - &priv->hangcheck_period); - - debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root, - &priv->disable_err_irq); - - debugfs_create_file("stall_reenable_time_us", 0400, minor->debugfs_root, - priv, &stall_reenable_time_fops); - - gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root); - - debugfs_create_bool("idle_clamp",0600, gpu_devfreq, - &priv->gpu_clamp_to_idle); - - debugfs_create_u32("upthreshold",0600, gpu_devfreq, - &priv->gpu_devfreq_config.upthreshold); - - debugfs_create_u32("downdifferential",0600, gpu_devfreq, - &priv->gpu_devfreq_config.downdifferential); -} - -void msm_debugfs_init(struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct msm_drm_private *priv = dev->dev_private; - - drm_debugfs_create_files(msm_debugfs_list, - ARRAY_SIZE(msm_debugfs_list), - minor->debugfs_root, minor); - - if (priv->gpu_pdev) - msm_debugfs_gpu_init(minor); - - if (priv->kms) - msm_debugfs_kms_init(minor); - - debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root, - dev, &shrink_fops); - - fault_create_debugfs_attr("fail_gem_alloc", minor->debugfs_root, - &fail_gem_alloc); - fault_create_debugfs_attr("fail_gem_iova", minor->debugfs_root, - &fail_gem_iova); -} -#endif - diff --git a/drivers/gpu/drm/msm/msm_debugfs.h b/drivers/gpu/drm/msm/msm_debugfs.h deleted file mode 100644 index ef58f66abbb341eccfbfeff9d759141e30ccc937..0000000000000000000000000000000000000000 --- a/drivers/gpu/drm/msm/msm_debugfs.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2016 Red Hat - * Author: Rob Clark <robdcl...@gmail.com> - */ - -#ifndef __MSM_DEBUGFS_H__ -#define __MSM_DEBUGFS_H__ - -#ifdef CONFIG_DEBUG_FS -void msm_debugfs_init(struct drm_minor *minor); -#endif - -#endif /* __MSM_DEBUGFS_H__ */ diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index ba984cc71d1d3aa341e0f4532b7093adcd25d3b0..28a5da1d1391f6c3cb2bfd175154016f8987b752 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -15,7 +15,6 @@ #include <drm/drm_of.h> #include "msm_drv.h" -#include "msm_debugfs.h" #include "msm_gpu.h" #include "msm_ioctl.h" #include "msm_kms.h" @@ -64,6 +63,22 @@ bool msm_gpu_no_components(void) return separate_gpu_kms; } +#ifdef CONFIG_DEBUG_FS +static void msm_debugfs_late_init(struct drm_device *dev) +{ + msm_gpu_debugfs_late_init(dev); +} + +static void msm_debugfs_init(struct drm_minor *minor) +{ + msm_gpu_debugfs_init(minor); + + msm_kms_debugfs_init(minor); + + msm_gem_debugfs_init(minor); +} +#endif + static int msm_drm_uninit(struct device *dev, const struct component_ops *gpu_ops) { struct platform_device *pdev = to_platform_device(dev); @@ -171,9 +186,7 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv, if (ret) goto err_msm_uninit; - ret = msm_debugfs_late_init(ddev); - if (ret) - goto err_msm_uninit; + msm_debugfs_late_init(ddev); if (priv->kms_init) msm_drm_kms_post_init(dev); diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 6d847d593f1aebdf90e4389ef7ecdf5721d910a5..646ddf2c320ac94ff7b0f5c21dab60fe777a10bf 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -436,7 +436,8 @@ static inline void msm_mdss_unregister(void) {} #ifdef CONFIG_DEBUG_FS void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m); -int msm_debugfs_late_init(struct drm_device *dev); +void msm_gpu_debugfs_init(struct drm_minor *minor); +void msm_gpu_debugfs_late_init(struct drm_device *dev); int msm_rd_debugfs_init(struct drm_minor *minor); void msm_rd_debugfs_cleanup(struct msm_drm_private *priv); __printf(3, 4) @@ -445,7 +446,6 @@ void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, int msm_perf_debugfs_init(struct drm_minor *minor); void msm_perf_debugfs_cleanup(struct msm_drm_private *priv); #else -static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; } __printf(3, 4) static inline void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit, diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h index a4cf31853c5008e171c3ad72cde1004c60fe5212..3a0086a883a2c2e57b01a5add17be852f2877865 100644 --- a/drivers/gpu/drm/msm/msm_gem.h +++ b/drivers/gpu/drm/msm/msm_gem.h @@ -498,4 +498,12 @@ static inline void msm_gem_submit_put(struct msm_gem_submit *submit) void msm_submit_retire(struct msm_gem_submit *submit); +#ifdef CONFIG_DEBUG_FS +void msm_gem_debugfs_init(struct drm_minor *minor); +#else +static inline void msm_gem_debugfs_init(struct drm_minor *minor) +{ +} +#endif + #endif /* __MSM_GEM_H__ */ diff --git a/drivers/gpu/drm/msm/msm_gem_debugfs.c b/drivers/gpu/drm/msm/msm_gem_debugfs.c new file mode 100644 index 0000000000000000000000000000000000000000..1e7fccb17479d80cb6fae90490f53148190a4417 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gem_debugfs.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013-2016 Red Hat + * Author: Rob Clark <robdcl...@gmail.com> + */ + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/fault-inject.h> + +#include <drm/drm_debugfs.h> +#include <drm/drm_file.h> + +#include "msm_gem.h" + +/* + * Other debugfs: + */ + +static unsigned long last_shrink_freed; + +static int +shrink_get(void *data, u64 *val) +{ + *val = last_shrink_freed; + + return 0; +} + +static int +shrink_set(void *data, u64 val) +{ + struct drm_device *dev = data; + + last_shrink_freed = msm_gem_shrinker_shrink(dev, val); + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops, + shrink_get, shrink_set, + "0x%08llx\n"); + +static int msm_gem_show(struct seq_file *m, void *arg) +{ + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct msm_drm_private *priv = dev->dev_private; + int ret; + + ret = mutex_lock_interruptible(&priv->obj_lock); + if (ret) + return ret; + + msm_gem_describe_objects(&priv->objects, m); + + mutex_unlock(&priv->obj_lock); + + return 0; +} + +static int msm_mm_show(struct seq_file *m, void *arg) +{ + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct drm_printer p = drm_seq_file_printer(m); + + drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p); + + return 0; +} + +static struct drm_info_list msm_debugfs_list[] = { + {"gem", msm_gem_show}, + { "mm", msm_mm_show }, +}; + +void msm_gem_debugfs_init(struct drm_minor *minor) +{ + struct drm_device *dev = minor->dev; + + drm_debugfs_create_files(msm_debugfs_list, + ARRAY_SIZE(msm_debugfs_list), + minor->debugfs_root, minor); + + debugfs_create_file("shrink", 0700, minor->debugfs_root, + dev, &shrink_fops); + + fault_create_debugfs_attr("fail_gem_alloc", minor->debugfs_root, + &fail_gem_alloc); + fault_create_debugfs_attr("fail_gem_iova", minor->debugfs_root, + &fail_gem_iova); +} +#endif + diff --git a/drivers/gpu/drm/msm/msm_gpu_debugfs.c b/drivers/gpu/drm/msm/msm_gpu_debugfs.c new file mode 100644 index 0000000000000000000000000000000000000000..7a070160ddac711a1c731a4fb7fb099b8dfcdc01 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_gpu_debugfs.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013-2016 Red Hat + * Author: Rob Clark <robdcl...@gmail.com> + */ + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> +#include <linux/fault-inject.h> + +#include <drm/drm_debugfs.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_file.h> +#include <drm/drm_framebuffer.h> + +#include "msm_drv.h" +#include "msm_gpu.h" +#include "msm_kms.h" +#include "disp/msm_disp_snapshot.h" + +/* + * GPU Snapshot: + */ + +struct msm_gpu_show_priv { + struct msm_gpu_state *state; + struct drm_device *dev; +}; + +static int msm_gpu_show(struct seq_file *m, void *arg) +{ + struct drm_printer p = drm_seq_file_printer(m); + struct msm_gpu_show_priv *show_priv = m->private; + struct msm_drm_private *priv = show_priv->dev->dev_private; + struct msm_gpu *gpu = priv->gpu; + int ret; + + ret = mutex_lock_interruptible(&gpu->lock); + if (ret) + return ret; + + drm_printf(&p, "%s Status:\n", gpu->name); + gpu->funcs->show(gpu, show_priv->state, &p); + + mutex_unlock(&gpu->lock); + + return 0; +} + +static int msm_gpu_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + struct msm_gpu_show_priv *show_priv = m->private; + struct msm_drm_private *priv = show_priv->dev->dev_private; + struct msm_gpu *gpu = priv->gpu; + + mutex_lock(&gpu->lock); + gpu->funcs->gpu_state_put(show_priv->state); + mutex_unlock(&gpu->lock); + + kfree(show_priv); + + return single_release(inode, file); +} + +static int msm_gpu_open(struct inode *inode, struct file *file) +{ + struct drm_device *dev = inode->i_private; + struct msm_drm_private *priv = dev->dev_private; + struct msm_gpu *gpu = priv->gpu; + struct msm_gpu_show_priv *show_priv; + int ret; + + if (!gpu || !gpu->funcs->gpu_state_get) + return -ENODEV; + + show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL); + if (!show_priv) + return -ENOMEM; + + ret = mutex_lock_interruptible(&gpu->lock); + if (ret) + goto free_priv; + + pm_runtime_get_sync(&gpu->pdev->dev); + msm_gpu_hw_init(gpu); + show_priv->state = gpu->funcs->gpu_state_get(gpu); + pm_runtime_put_sync(&gpu->pdev->dev); + + mutex_unlock(&gpu->lock); + + if (IS_ERR(show_priv->state)) { + ret = PTR_ERR(show_priv->state); + goto free_priv; + } + + show_priv->dev = dev; + + ret = single_open(file, msm_gpu_show, show_priv); + if (ret) + goto free_priv; + + return 0; + +free_priv: + kfree(show_priv); + return ret; +} + +static const struct file_operations msm_gpu_fops = { + .owner = THIS_MODULE, + .open = msm_gpu_open, + .read = seq_read, + .llseek = seq_lseek, + .release = msm_gpu_release, +}; + +/* + * Return the number of microseconds to wait until stall-on-fault is + * re-enabled. If 0 then it is already enabled or will be re-enabled on the + * next submit (unless there's a leftover devcoredump). This is useful for + * kernel tests that intentionally produce a fault and check the devcoredump to + * wait until the cooldown period is over. + */ + +static int +stall_reenable_time_get(void *data, u64 *val) +{ + struct msm_drm_private *priv = data; + unsigned long irq_flags; + + spin_lock_irqsave(&priv->fault_stall_lock, irq_flags); + + if (priv->stall_enabled) + *val = 0; + else + *val = max(ktime_us_delta(priv->stall_reenable_time, ktime_get()), 0); + + spin_unlock_irqrestore(&priv->fault_stall_lock, irq_flags); + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(stall_reenable_time_fops, + stall_reenable_time_get, NULL, + "%lld\n"); + +void msm_gpu_debugfs_init(struct drm_minor *minor) +{ + struct drm_device *dev = minor->dev; + struct msm_drm_private *priv = dev->dev_private; + struct dentry *gpu_devfreq; + + if (!priv->gpu_pdev) + return; + + debugfs_create_file("gpu", 0400, minor->debugfs_root, + dev, &msm_gpu_fops); + + debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root, + &priv->hangcheck_period); + + debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root, + &priv->disable_err_irq); + + debugfs_create_file("stall_reenable_time_us", 0400, minor->debugfs_root, + priv, &stall_reenable_time_fops); + + gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root); + + debugfs_create_bool("idle_clamp", 0600, gpu_devfreq, + &priv->gpu_clamp_to_idle); + + debugfs_create_u32("upthreshold", 0600, gpu_devfreq, + &priv->gpu_devfreq_config.upthreshold); + + debugfs_create_u32("downdifferential", 0600, gpu_devfreq, + &priv->gpu_devfreq_config.downdifferential); +} + +static void late_init_minor(struct drm_minor *minor) +{ + int ret; + + if (!minor) + return; + + ret = msm_rd_debugfs_init(minor); + if (ret) { + drm_err(minor->dev, "could not install rd debugfs\n"); + return; + } + + ret = msm_perf_debugfs_init(minor); + if (ret) { + drm_err(minor->dev, "could not install perf debugfs\n"); + return; + } +} + +void msm_gpu_debugfs_late_init(struct drm_device *dev) +{ + struct msm_drm_private *priv = dev->dev_private; + + if (!priv->gpu_pdev) + return; + + late_init_minor(dev->primary); + + late_init_minor(dev->render); +} +#endif diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 8a7be7b854deea9b763ec45df275fab77d806e44..ce7d73e57ee7e23272ef23a06ae5bc3d35b5bf98 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -240,4 +240,12 @@ static inline void msm_drm_kms_uninit(struct device *dev) #endif +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_DRM_MSM_KMS) +void msm_kms_debugfs_init(struct drm_minor *minor); +#else +static inline void msm_kms_debugfs_init(struct drm_minor *minor) +{ +} +#endif + #endif /* __MSM_KMS_H__ */ diff --git a/drivers/gpu/drm/msm/msm_kms_debugfs.c b/drivers/gpu/drm/msm/msm_kms_debugfs.c new file mode 100644 index 0000000000000000000000000000000000000000..58975ee220b6f2b2dc581b864b2f22e6c12e7583 --- /dev/null +++ b/drivers/gpu/drm/msm/msm_kms_debugfs.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013-2016 Red Hat + * Author: Rob Clark <robdcl...@gmail.com> + */ + +#ifdef CONFIG_DEBUG_FS + +#include <linux/debugfs.h> + +#include <drm/drm_debugfs.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_file.h> +#include <drm/drm_framebuffer.h> + +#include "msm_drv.h" +#include "msm_kms.h" +#include "disp/msm_disp_snapshot.h" + +static int msm_fb_show(struct seq_file *m, void *arg) +{ + struct drm_info_node *node = m->private; + struct drm_device *dev = node->minor->dev; + struct drm_framebuffer *fb, *fbdev_fb = NULL; + + if (dev->fb_helper && dev->fb_helper->fb) { + seq_puts(m, "fbcon "); + fbdev_fb = dev->fb_helper->fb; + msm_framebuffer_describe(fbdev_fb, m); + } + + mutex_lock(&dev->mode_config.fb_lock); + list_for_each_entry(fb, &dev->mode_config.fb_list, head) { + if (fb == fbdev_fb) + continue; + + seq_puts(m, "user "); + msm_framebuffer_describe(fb, m); + } + mutex_unlock(&dev->mode_config.fb_lock); + + return 0; +} + +static struct drm_info_list msm_kms_debugfs_list[] = { + { "fb", msm_fb_show }, +}; + +/* + * Display Snapshot: + */ + +static int msm_kms_show(struct seq_file *m, void *arg) +{ + struct drm_printer p = drm_seq_file_printer(m); + struct msm_disp_state *state = m->private; + + msm_disp_state_print(state, &p); + + return 0; +} + +static int msm_kms_release(struct inode *inode, struct file *file) +{ + struct seq_file *m = file->private_data; + struct msm_disp_state *state = m->private; + + msm_disp_state_free(state); + + return single_release(inode, file); +} + +static int msm_kms_open(struct inode *inode, struct file *file) +{ + struct drm_device *dev = inode->i_private; + struct msm_drm_private *priv = dev->dev_private; + struct msm_disp_state *state; + int ret; + + if (!priv->kms) + return -ENODEV; + + ret = mutex_lock_interruptible(&priv->kms->dump_mutex); + if (ret) + return ret; + + state = msm_disp_snapshot_state_sync(priv->kms); + + mutex_unlock(&priv->kms->dump_mutex); + + if (IS_ERR(state)) + return PTR_ERR(state); + + ret = single_open(file, msm_kms_show, state); + if (ret) { + msm_disp_state_free(state); + return ret; + } + + return 0; +} + +static const struct file_operations msm_kms_fops = { + .owner = THIS_MODULE, + .open = msm_kms_open, + .read = seq_read, + .llseek = seq_lseek, + .release = msm_kms_release, +}; + +void msm_kms_debugfs_init(struct drm_minor *minor) +{ + struct drm_device *dev = minor->dev; + struct msm_drm_private *priv = dev->dev_private; + + if (!priv->kms) + return; + + drm_debugfs_create_files(msm_kms_debugfs_list, + ARRAY_SIZE(msm_kms_debugfs_list), + minor->debugfs_root, minor); + debugfs_create_file("kms", 0400, minor->debugfs_root, + dev, &msm_kms_fops); + + if (priv->kms->funcs->debugfs_init) + priv->kms->funcs->debugfs_init(priv->kms, minor); + +} +#endif -- 2.47.3