diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_debugfs.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_debugfs.c | 127 | 
1 files changed, 96 insertions, 31 deletions
| diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index dee13fedee3b..0804c31e8962 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -15,6 +15,11 @@  #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; @@ -29,14 +34,14 @@ static int msm_gpu_show(struct seq_file *m, void *arg)  	struct msm_gpu *gpu = priv->gpu;  	int ret; -	ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex); +	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(&show_priv->dev->struct_mutex); +	mutex_unlock(&gpu->lock);  	return 0;  } @@ -48,9 +53,9 @@ static int msm_gpu_release(struct inode *inode, struct file *file)  	struct msm_drm_private *priv = show_priv->dev->dev_private;  	struct msm_gpu *gpu = priv->gpu; -	mutex_lock(&show_priv->dev->struct_mutex); +	mutex_lock(&gpu->lock);  	gpu->funcs->gpu_state_put(show_priv->state); -	mutex_unlock(&show_priv->dev->struct_mutex); +	mutex_unlock(&gpu->lock);  	kfree(show_priv); @@ -72,7 +77,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)  	if (!show_priv)  		return -ENOMEM; -	ret = mutex_lock_interruptible(&dev->struct_mutex); +	ret = mutex_lock_interruptible(&gpu->lock);  	if (ret)  		goto free_priv; @@ -81,7 +86,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)  	show_priv->state = gpu->funcs->gpu_state_get(gpu);  	pm_runtime_put_sync(&gpu->pdev->dev); -	mutex_unlock(&dev->struct_mutex); +	mutex_unlock(&gpu->lock);  	if (IS_ERR(show_priv->state)) {  		ret = PTR_ERR(show_priv->state); @@ -109,6 +114,73 @@ static const struct file_operations msm_gpu_fops = {  	.release = msm_gpu_release,  }; +/* + * 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, +}; + +/* + * Other debugfs: + */ +  static unsigned long last_shrink_freed;  static int @@ -134,8 +206,10 @@ DEFINE_SIMPLE_ATTRIBUTE(shrink_fops,  			"0x%08llx\n"); -static int msm_gem_show(struct drm_device *dev, struct seq_file *m) +static int msm_gem_show(struct seq_file *m, void *arg)  { +	struct drm_info_node *node = (struct drm_info_node *) m->private; +	struct drm_device *dev = node->minor->dev;  	struct msm_drm_private *priv = dev->dev_private;  	int ret; @@ -150,8 +224,10 @@ static int msm_gem_show(struct drm_device *dev, struct seq_file *m)  	return 0;  } -static int msm_mm_show(struct drm_device *dev, struct seq_file *m) +static int msm_mm_show(struct seq_file *m, void *arg)  { +	struct drm_info_node *node = (struct drm_info_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); @@ -159,8 +235,10 @@ static int msm_mm_show(struct drm_device *dev, struct seq_file *m)  	return 0;  } -static int msm_fb_show(struct drm_device *dev, struct seq_file *m) +static int msm_fb_show(struct seq_file *m, void *arg)  { +	struct drm_info_node *node = (struct drm_info_node *) m->private; +	struct drm_device *dev = node->minor->dev;  	struct msm_drm_private *priv = dev->dev_private;  	struct drm_framebuffer *fb, *fbdev_fb = NULL; @@ -183,29 +261,10 @@ static int msm_fb_show(struct drm_device *dev, struct seq_file *m)  	return 0;  } -static int show_locked(struct seq_file *m, void *arg) -{ -	struct drm_info_node *node = (struct drm_info_node *) m->private; -	struct drm_device *dev = node->minor->dev; -	int (*show)(struct drm_device *dev, struct seq_file *m) = -			node->info_ent->data; -	int ret; - -	ret = mutex_lock_interruptible(&dev->struct_mutex); -	if (ret) -		return ret; - -	ret = show(dev, m); - -	mutex_unlock(&dev->struct_mutex); - -	return ret; -} -  static struct drm_info_list msm_debugfs_list[] = { -		{"gem", show_locked, 0, msm_gem_show}, -		{ "mm", show_locked, 0, msm_mm_show }, -		{ "fb", show_locked, 0, msm_fb_show }, +		{"gem", msm_gem_show}, +		{ "mm", msm_mm_show }, +		{ "fb", msm_fb_show },  };  static int late_init_minor(struct drm_minor *minor) @@ -252,9 +311,15 @@ void msm_debugfs_init(struct drm_minor *minor)  	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,  		dev, &msm_gpu_fops); +	debugfs_create_file("kms", S_IRUSR, minor->debugfs_root, +		dev, &msm_kms_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("shrink", S_IRWXU, minor->debugfs_root,  		dev, &shrink_fops); |