Chris Ball
2010-Aug-19 17:55 UTC
[Nouveau] [PATCH] drm/nouveau/kms: Implement KDB debug hooks for nouveau KMS.
Hi,
Here's a patch to add support for KMS debugging to Nouveau, along the
style of the previous patches for Intel? and Radeon?. I'm only able
to test on nv50 here, so a test on nv04 would be much appreciated,
and I've published instructions on how to test here?. Thanks!
- Chris.
?: http://lkml.org/lkml/2010/8/5/280
?: http://dev.laptop.org/~cjb/kdb-radeon.patch
?: http://blog.printf.net/articles/2010/08/19/kdb-kms-for-nouveau-radeon
From: Chris Ball <cjb at laptop.org>
Date: Thu, 19 Aug 2010 12:55:34 -0400
Subject: [PATCH] drm/nouveau/kms: Implement KDB debug hooks for nouveau KMS.
Signed-off-by: Chris Ball <cjb at laptop.org>
---
drivers/gpu/drm/nouveau/nouveau_fbcon.c | 6 ++++
drivers/gpu/drm/nouveau/nv04_crtc.c | 46 ++++++++++++++++++++++++-----
drivers/gpu/drm/nouveau/nv50_crtc.c | 49 ++++++++++++++++++++++--------
3 files changed, 80 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 2fb2444..aac1460 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -104,6 +104,8 @@ static struct fb_ops nouveau_fbcon_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
static struct fb_ops nv04_fbcon_ops = {
@@ -117,6 +119,8 @@ static struct fb_ops nv04_fbcon_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
static struct fb_ops nv50_fbcon_ops = {
@@ -130,6 +134,8 @@ static struct fb_ops nv50_fbcon_ops = {
.fb_pan_display = drm_fb_helper_pan_display,
.fb_blank = drm_fb_helper_blank,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_debug_enter = drm_fb_helper_debug_enter,
+ .fb_debug_leave = drm_fb_helper_debug_leave,
};
static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c
b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 1c20c08..4205daf 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -767,8 +767,9 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16
*b, uint32_t size)
}
static int
-nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb)
+nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *passed_fb,
+ int x, int y, bool atomic)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -779,13 +780,26 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int
y,
int arb_burst, arb_lwm;
int ret;
- ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
- if (ret)
- return ret;
+ /* If atomic, we want to switch to the fb we were passed, so
+ * now we update pointers to do that. (We don't pin; just
+ * assume we're already pinned and update the base address.)
+ */
+ if (atomic) {
+ drm_fb = passed_fb;
+ fb = nouveau_framebuffer(passed_fb);
+ }
+ else {
+ /* If not atomic, we can go ahead and pin, and unpin the
+ * old fb we were passed.
+ */
+ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+ if (ret)
+ return ret;
- if (old_fb) {
- struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
- nouveau_bo_unpin(ofb->nvbo);
+ if (passed_fb) {
+ struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+ nouveau_bo_unpin(ofb->nvbo);
+ }
}
nv_crtc->fb.offset = fb->nvbo->bo.offset;
@@ -833,6 +847,21 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int
y,
return 0;
}
+static int
+nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
+}
+
+static int
+nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y)
+{
+ return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
+}
+
static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
struct nouveau_bo *dst)
{
@@ -961,6 +990,7 @@ static const struct drm_crtc_helper_funcs
nv04_crtc_helper_funcs = {
.mode_fixup = nv_crtc_mode_fixup,
.mode_set = nv_crtc_mode_set,
.mode_set_base = nv04_crtc_mode_set_base,
+ .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
.load_lut = nv_crtc_gamma_load,
};
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c
b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 5d11ea1..9ec7952 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -477,8 +477,9 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct
drm_display_mode *mode,
}
static int
-nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb, bool update)
+nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *passed_fb,
+ int x, int y, bool update, bool atomic)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
@@ -490,6 +491,28 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x,
int y,
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ /* If atomic, we want to switch to the fb we were passed, so
+ * now we update pointers to do that. (We don't pin; just
+ * assume we're already pinned and update the base address.)
+ */
+ if (atomic) {
+ drm_fb = passed_fb;
+ fb = nouveau_framebuffer(passed_fb);
+ }
+ else {
+ /* If not atomic, we can go ahead and pin, and unpin the
+ * old fb we were passed.
+ */
+ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+ if (ret)
+ return ret;
+
+ if (passed_fb) {
+ struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+ nouveau_bo_unpin(ofb->nvbo);
+ }
+ }
+
switch (drm_fb->depth) {
case 8:
format = NV50_EVO_CRTC_FB_DEPTH_8;
@@ -512,15 +535,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x,
int y,
return -EINVAL;
}
- ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
- if (ret)
- return ret;
-
- if (old_fb) {
- struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
- nouveau_bo_unpin(ofb->nvbo);
- }
-
nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@@ -671,14 +685,22 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct
drm_display_mode *mode,
nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
- return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false);
+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false);
}
static int
nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
- return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true);
+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false);
+}
+
+static int
+nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y)
+{
+ return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true);
}
static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
@@ -688,6 +710,7 @@ static const struct drm_crtc_helper_funcs
nv50_crtc_helper_funcs = {
.mode_fixup = nv50_crtc_mode_fixup,
.mode_set = nv50_crtc_mode_set,
.mode_set_base = nv50_crtc_mode_set_base,
+ .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
.load_lut = nv50_crtc_lut_load,
};
--
1.6.2.5
Francisco Jerez
2010-Aug-21 02:22 UTC
[Nouveau] [PATCH] drm/nouveau/kms: Implement KDB debug hooks for nouveau KMS.
Chris Ball <cjb at laptop.org> writes:> Hi, > > Here's a patch to add support for KMS debugging to Nouveau, along the > style of the previous patches for Intel? and Radeon?. I'm only able > to test on nv50 here, so a test on nv04 would be much appreciated, > and I've published instructions on how to test here?. Thanks! >There is a problem with this on pre-nv20 cards. Fbcon acceleration won't work properly with IRQs disabled because you miss the context switching interrupts: You'll get a locked up fbcon if you hit sysrq-g when there's some process using the GPU. I'd suggest disabling acceleration while in debug mode (e.g. using nouveau_fbcon_save_disable_accel()). That aside the patch looks good to me.> - Chris. > > ?: http://lkml.org/lkml/2010/8/5/280 > ?: http://dev.laptop.org/~cjb/kdb-radeon.patch > ?: http://blog.printf.net/articles/2010/08/19/kdb-kms-for-nouveau-radeon > > > [...]-------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 229 bytes Desc: not available URL: <http://lists.freedesktop.org/archives/nouveau/attachments/20100821/c4df3deb/attachment.pgp>
Maxim Levitsky
2010-Sep-01 09:56 UTC
[Nouveau] [PATCH] drm/nouveau/kms: Implement KDB debug hooks for nouveau KMS.
On Thu, 2010-08-19 at 13:55 -0400, Chris Ball wrote:> Hi, > > Here's a patch to add support for KMS debugging to Nouveau, along the > style of the previous patches for Intel? and Radeon?. I'm only able > to test on nv50 here, so a test on nv04 would be much appreciated, > and I've published instructions on how to test here?. Thanks! > > - Chris.Hi, I just tried that patch, but unfortunately nether with nor without it kdb seems not to work. It could be id10t error from my side, but I did test the kdb in the past with few KMS patches, and it seemed to work. Now I can't even get its prompt on the console. This is what I do: echo kbd | sudo tee /sys/module/kgdboc/parameters/kgdboc (also tried booting with kgdboc=kbd) Both seems to start kdb, because maxim at maxim-laptop:~$ cat /sys/module/kgdboc/parameters/kgdboc kbd maxim at maxim-laptop:~$ dmesg | grep kgdb [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-2.6.36-rc3+ root=UUID=52341b68-74f3-4c96-aaf8-7586a06c4b4e ro splash video=nouveau nmi_watchdog=lapic kgdboc=kbd [ 0.000000] Kernel command line: BOOT_IMAGE=/boot/vmlinuz-2.6.36-rc3+ root=UUID=52341b68-74f3-4c96-aaf8-7586a06c4b4e ro splash video=nouveau nmi_watchdog=lapic kgdboc=kbd [ 2.671914] kgdb: Registered I/O driver kgdboc. Now when I first switch to console and then press Alt+SysRQ+G, I just get SYSRQ: DEBUG, and system hangs. It could be printk level, but that should be ok, no? maxim at maxim-laptop:~$ cat /proc/sys/kernel/printk 7 4 1 7 Also if I remember correct inputting 'g' then ENTER should resume the system, but it doesn't. So I think kdb doesn't work at all here Best regards, Maxim Levitsky