2 * Copyright (C) 2012 Russell King
3 * Rewritten from the dovefb driver, and Armada510 manuals.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 #include <linux/ctype.h>
10 #include <linux/debugfs.h>
11 #include <linux/module.h>
12 #include <linux/seq_file.h>
14 #include "armada_crtc.h"
15 #include "armada_drm.h"
17 static int armada_debugfs_gem_linear_show(struct seq_file
*m
, void *data
)
19 struct drm_info_node
*node
= m
->private;
20 struct drm_device
*dev
= node
->minor
->dev
;
21 struct armada_private
*priv
= dev
->dev_private
;
24 mutex_lock(&dev
->struct_mutex
);
25 ret
= drm_mm_dump_table(m
, &priv
->linear
);
26 mutex_unlock(&dev
->struct_mutex
);
31 static int armada_debugfs_reg_show(struct seq_file
*m
, void *data
)
33 struct drm_device
*dev
= m
->private;
34 struct armada_private
*priv
= dev
->dev_private
;
38 for (n
= 0; n
< ARRAY_SIZE(priv
->dcrtc
); n
++) {
39 struct armada_crtc
*dcrtc
= priv
->dcrtc
[n
];
43 for (i
= 0x84; i
<= 0x1c4; i
+= 4) {
44 uint32_t v
= readl_relaxed(dcrtc
->base
+ i
);
45 seq_printf(m
, "%u: 0x%04x: 0x%08x\n", n
, i
, v
);
53 static int armada_debugfs_reg_r_open(struct inode
*inode
, struct file
*file
)
55 return single_open(file
, armada_debugfs_reg_show
, inode
->i_private
);
58 static const struct file_operations fops_reg_r
= {
60 .open
= armada_debugfs_reg_r_open
,
63 .release
= single_release
,
66 static int armada_debugfs_write(struct file
*file
, const char __user
*ptr
,
67 size_t len
, loff_t
*off
)
69 struct drm_device
*dev
= file
->private_data
;
70 struct armada_private
*priv
= dev
->dev_private
;
71 struct armada_crtc
*dcrtc
= priv
->dcrtc
[0];
79 if (len
> sizeof(buf
) - 1)
80 len
= sizeof(buf
) - 1;
82 ret
= strncpy_from_user(buf
, ptr
, len
);
87 reg
= simple_strtoul(buf
, &p
, 16);
90 val
= simple_strtoul(p
+ 1, NULL
, 16);
92 if (reg
>= 0x84 && reg
<= 0x1c4)
93 writel(val
, dcrtc
->base
+ reg
);
98 static const struct file_operations fops_reg_w
= {
101 .write
= armada_debugfs_write
,
102 .llseek
= noop_llseek
,
105 static struct drm_info_list armada_debugfs_list
[] = {
106 { "gem_linear", armada_debugfs_gem_linear_show
, 0 },
108 #define ARMADA_DEBUGFS_ENTRIES ARRAY_SIZE(armada_debugfs_list)
110 static int drm_add_fake_info_node(struct drm_minor
*minor
, struct dentry
*ent
,
113 struct drm_info_node
*node
;
115 node
= kmalloc(sizeof(struct drm_info_node
), GFP_KERNEL
);
123 node
->info_ent
= (void *) key
;
125 mutex_lock(&minor
->debugfs_lock
);
126 list_add(&node
->list
, &minor
->debugfs_list
);
127 mutex_unlock(&minor
->debugfs_lock
);
132 static int armada_debugfs_create(struct dentry
*root
, struct drm_minor
*minor
,
133 const char *name
, umode_t mode
, const struct file_operations
*fops
)
137 de
= debugfs_create_file(name
, mode
, root
, minor
->dev
, fops
);
139 return drm_add_fake_info_node(minor
, de
, fops
);
142 int armada_drm_debugfs_init(struct drm_minor
*minor
)
146 ret
= drm_debugfs_create_files(armada_debugfs_list
,
147 ARMADA_DEBUGFS_ENTRIES
,
148 minor
->debugfs_root
, minor
);
152 ret
= armada_debugfs_create(minor
->debugfs_root
, minor
,
153 "reg", S_IFREG
| S_IRUSR
, &fops_reg_r
);
157 ret
= armada_debugfs_create(minor
->debugfs_root
, minor
,
158 "reg_wr", S_IFREG
| S_IWUSR
, &fops_reg_w
);
164 drm_debugfs_remove_files((struct drm_info_list
*)&fops_reg_r
, 1, minor
);
166 drm_debugfs_remove_files(armada_debugfs_list
, ARMADA_DEBUGFS_ENTRIES
,
171 void armada_drm_debugfs_cleanup(struct drm_minor
*minor
)
173 drm_debugfs_remove_files((struct drm_info_list
*)&fops_reg_w
, 1, minor
);
174 drm_debugfs_remove_files((struct drm_info_list
*)&fops_reg_r
, 1, minor
);
175 drm_debugfs_remove_files(armada_debugfs_list
, ARMADA_DEBUGFS_ENTRIES
,