2 * Copyright (C) 2009 Red Hat <bskeggs@redhat.com>
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Ben Skeggs <bskeggs@redhat.com>
31 #include <linux/debugfs.h>
34 #include "nouveau_drv.h"
36 #include <ttm/ttm_page_alloc.h>
39 nouveau_debugfs_channel_info(struct seq_file
*m
, void *data
)
41 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
42 struct nouveau_channel
*chan
= node
->info_ent
->data
;
44 seq_printf(m
, "channel id : %d\n", chan
->id
);
46 seq_printf(m
, "cpu fifo state:\n");
47 seq_printf(m
, " base: 0x%08x\n", chan
->pushbuf_base
);
48 seq_printf(m
, " max: 0x%08x\n", chan
->dma
.max
<< 2);
49 seq_printf(m
, " cur: 0x%08x\n", chan
->dma
.cur
<< 2);
50 seq_printf(m
, " put: 0x%08x\n", chan
->dma
.put
<< 2);
51 seq_printf(m
, " free: 0x%08x\n", chan
->dma
.free
<< 2);
52 if (chan
->dma
.ib_max
) {
53 seq_printf(m
, " ib max: 0x%08x\n", chan
->dma
.ib_max
);
54 seq_printf(m
, " ib put: 0x%08x\n", chan
->dma
.ib_put
);
55 seq_printf(m
, " ib free: 0x%08x\n", chan
->dma
.ib_free
);
58 seq_printf(m
, "gpu fifo state:\n");
59 seq_printf(m
, " get: 0x%08x\n",
60 nvchan_rd32(chan
, chan
->user_get
));
61 seq_printf(m
, " put: 0x%08x\n",
62 nvchan_rd32(chan
, chan
->user_put
));
63 if (chan
->dma
.ib_max
) {
64 seq_printf(m
, " ib get: 0x%08x\n",
65 nvchan_rd32(chan
, 0x88));
66 seq_printf(m
, " ib put: 0x%08x\n",
67 nvchan_rd32(chan
, 0x8c));
70 seq_printf(m
, "last fence : %d\n", chan
->fence
.sequence
);
71 seq_printf(m
, "last signalled: %d\n", chan
->fence
.sequence_ack
);
76 nouveau_debugfs_channel_init(struct nouveau_channel
*chan
)
78 struct drm_nouveau_private
*dev_priv
= chan
->dev
->dev_private
;
79 struct drm_minor
*minor
= chan
->dev
->primary
;
82 if (!dev_priv
->debugfs
.channel_root
) {
83 dev_priv
->debugfs
.channel_root
=
84 debugfs_create_dir("channel", minor
->debugfs_root
);
85 if (!dev_priv
->debugfs
.channel_root
)
89 snprintf(chan
->debugfs
.name
, 32, "%d", chan
->id
);
90 chan
->debugfs
.info
.name
= chan
->debugfs
.name
;
91 chan
->debugfs
.info
.show
= nouveau_debugfs_channel_info
;
92 chan
->debugfs
.info
.driver_features
= 0;
93 chan
->debugfs
.info
.data
= chan
;
95 ret
= drm_debugfs_create_files(&chan
->debugfs
.info
, 1,
96 dev_priv
->debugfs
.channel_root
,
99 chan
->debugfs
.active
= true;
104 nouveau_debugfs_channel_fini(struct nouveau_channel
*chan
)
106 struct drm_nouveau_private
*dev_priv
= chan
->dev
->dev_private
;
108 if (!chan
->debugfs
.active
)
111 drm_debugfs_remove_files(&chan
->debugfs
.info
, 1, chan
->dev
->primary
);
112 chan
->debugfs
.active
= false;
114 if (chan
== dev_priv
->channel
) {
115 debugfs_remove(dev_priv
->debugfs
.channel_root
);
116 dev_priv
->debugfs
.channel_root
= NULL
;
121 nouveau_debugfs_chipset_info(struct seq_file
*m
, void *data
)
123 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
124 struct drm_minor
*minor
= node
->minor
;
125 struct drm_device
*dev
= minor
->dev
;
126 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
129 ppci_0
= nv_rd32(dev
, dev_priv
->chipset
>= 0x40 ? 0x88000 : 0x1800);
131 seq_printf(m
, "PMC_BOOT_0: 0x%08x\n", nv_rd32(dev
, NV03_PMC_BOOT_0
));
132 seq_printf(m
, "PCI ID : 0x%04x:0x%04x\n",
133 ppci_0
& 0xffff, ppci_0
>> 16);
138 nouveau_debugfs_memory_info(struct seq_file
*m
, void *data
)
140 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
141 struct drm_minor
*minor
= node
->minor
;
142 struct drm_nouveau_private
*dev_priv
= minor
->dev
->dev_private
;
144 seq_printf(m
, "VRAM total: %dKiB\n", (int)(dev_priv
->vram_size
>> 10));
149 nouveau_debugfs_vbios_image(struct seq_file
*m
, void *data
)
151 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
152 struct drm_nouveau_private
*dev_priv
= node
->minor
->dev
->dev_private
;
155 for (i
= 0; i
< dev_priv
->vbios
.length
; i
++)
156 seq_printf(m
, "%c", dev_priv
->vbios
.data
[i
]);
161 nouveau_debugfs_evict_vram(struct seq_file
*m
, void *data
)
163 struct drm_info_node
*node
= (struct drm_info_node
*) m
->private;
164 struct drm_nouveau_private
*dev_priv
= node
->minor
->dev
->dev_private
;
167 ret
= ttm_bo_evict_mm(&dev_priv
->ttm
.bdev
, TTM_PL_VRAM
);
169 seq_printf(m
, "failed: %d", ret
);
171 seq_printf(m
, "succeeded\n");
175 static struct drm_info_list nouveau_debugfs_list
[] = {
176 { "evict_vram", nouveau_debugfs_evict_vram
, 0, NULL
},
177 { "chipset", nouveau_debugfs_chipset_info
, 0, NULL
},
178 { "memory", nouveau_debugfs_memory_info
, 0, NULL
},
179 { "vbios.rom", nouveau_debugfs_vbios_image
, 0, NULL
},
180 { "ttm_page_pool", ttm_page_alloc_debugfs
, 0, NULL
},
182 #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
185 nouveau_debugfs_init(struct drm_minor
*minor
)
187 drm_debugfs_create_files(nouveau_debugfs_list
, NOUVEAU_DEBUGFS_ENTRIES
,
188 minor
->debugfs_root
, minor
);
193 nouveau_debugfs_takedown(struct drm_minor
*minor
)
195 drm_debugfs_remove_files(nouveau_debugfs_list
, NOUVEAU_DEBUGFS_ENTRIES
,