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