2009/12/28 Luca Tettamanti <kronos...@gmail.com>: > On Mon, Dec 28, 2009 at 01:32:24PM -0500, Alex Deucher wrote: >> 2009/12/28 Luca Tettamanti <kronos...@gmail.com>: >> > 2009/12/28 Alex Deucher <alexdeuc...@gmail.com>: >> >> On Mon, Dec 28, 2009 at 5:53 AM, Luca Tettamanti <kronos...@gmail.com> >> >> wrote: >> >>> On Sun, Dec 27, 2009 at 1:55 AM, Rafał Miłecki <zaj...@gmail.com> wrote: >> >>>> W dniu 26 grudnia 2009 20:08 użytkownik Alex Deucher >> >>>> <alexdeuc...@gmail.com> napisał: >> >>>>> It may be that the engine doesn't like to be reclocked while it's >> >>>>> running. Perhaps we should use the GUI idle interrupt rather than >> >>>>> vblanks to reclock the engine. >> >>>> >> >>>> Could you say something more about GUI idle interrupt, please? >> >>> >> >>> It's mentioned in the documentation of the IH (see r600.c); I guess >> >>> it's enabled by GUI_IDLE_INT_ENABLE. >> >>> >> >>>> What is this, do we already have code for that? >> >>> >> >>> Unless there are more subtleties all is needed it to enabled the >> >>> interrupt and catch it in r600_irq_process. >> >> >> >> That's pretty much it. Pre-r6xx asics have a GUI interrupt as well. >> >> I can look up the details for that if they are not already documented. >> > >> > I can't find a way to ack the interrupt; I see >> > RADEON_GUI_IDLE_INT_TEST_ACK but I think it's for pre-r6xx cards, >> > right? >> >> You don't have to ACK it as the CP generates the interrupt in >> software; similar to the sw interrupts used for fences. > > Ok, good: I've got the stub running on my M76. r100 and rs600 parts are > untested. Comments? >
Looks pretty good. I've included the proper defines from the register database below and you'll need to ack the gui idle interrupts on pre-r600 chips. Now you just have to do something when you get the idle interrupt. > --- linux-2.6.git.orig/drivers/gpu/drm/radeon/r600.c 2009-12-28 > 16:38:38.388825742 +0100 > +++ linux-2.6.git/drivers/gpu/drm/radeon/r600.c 2009-12-28 22:03:12.936157804 > +0100 > @@ -2458,6 +2458,7 @@ > int r600_irq_set(struct radeon_device *rdev) > { > u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; > + u32 grbm_int_cntl; > u32 mode_int = 0; > u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; > > @@ -2465,6 +2466,8 @@ > if (!rdev->ih.enabled) > return 0; > > + grbm_int_cntl = RREG32(GRBM_INT_CNTL) & ~GUI_IDLE_INT_ENABLE; > + > if (ASIC_IS_DCE3(rdev)) { > hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; > hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; > @@ -2484,6 +2487,10 @@ > DRM_DEBUG("r600_irq_set: sw int\n"); > cp_int_cntl |= RB_INT_ENABLE; > } > + if (rdev->irq.idle_int) { > + DRM_DEBUG("r600_irq_set: GUI idle int\n"); > + grbm_int_cntl |= GUI_IDLE_INT_ENABLE; > + } > if (rdev->irq.crtc_vblank_int[0]) { > DRM_DEBUG("r600_irq_set: vblank 0\n"); > mode_int |= D1MODE_VBLANK_INT_MASK; > @@ -2518,6 +2525,7 @@ > } > > WREG32(CP_INT_CNTL, cp_int_cntl); > + WREG32(GRBM_INT_CNTL, grbm_int_cntl); > WREG32(DxMODE_INT_MASK, mode_int); > if (ASIC_IS_DCE3(rdev)) { > WREG32(DC_HPD1_INT_CONTROL, hpd1); > @@ -2806,6 +2814,9 @@ > case 181: /* CP EOP event */ > DRM_DEBUG("IH: CP EOP\n"); > break; > + case 233: /* GUI idle event */ > + DRM_DEBUG("IH: GUI idle\n"); > + break; > default: > DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, > src_data); > break; > --- linux-2.6.git.orig/drivers/gpu/drm/radeon/radeon.h 2009-12-28 > 16:38:13.945836481 +0100 > +++ linux-2.6.git/drivers/gpu/drm/radeon/radeon.h 2009-12-28 > 22:02:48.964001788 +0100 > @@ -343,6 +343,7 @@ > struct radeon_irq { > bool installed; > bool sw_int; > + bool idle_int; > /* FIXME: use a define max crtc rather than hardcode it */ > bool crtc_vblank_int[2]; > /* FIXME: use defines for max hpd/dacs */ > --- linux-2.6.git.orig/drivers/gpu/drm/radeon/radeon_irq_kms.c 2009-12-28 > 16:37:10.669823739 +0100 > +++ linux-2.6.git/drivers/gpu/drm/radeon/radeon_irq_kms.c 2009-12-28 > 22:03:01.508077338 +0100 > @@ -67,6 +67,7 @@ > > /* Disable *all* interrupts */ > rdev->irq.sw_int = false; > + rdev->irq.idle_int = false; > for (i = 0; i < 2; i++) { > rdev->irq.crtc_vblank_int[i] = false; > } > @@ -81,6 +82,7 @@ > > dev->max_vblank_count = 0x001fffff; > rdev->irq.sw_int = true; > + rdev->irq.idle_int = true; > radeon_irq_set(rdev); > return 0; > } > @@ -95,6 +97,7 @@ > } > /* Disable *all* interrupts */ > rdev->irq.sw_int = false; > + rdev->irq.idle_int = false; > for (i = 0; i < 2; i++) { > rdev->irq.crtc_vblank_int[i] = false; > } > --- linux-2.6.git.orig/drivers/gpu/drm/radeon/r100.c 2009-12-28 > 22:30:59.079748392 +0100 > +++ linux-2.6.git/drivers/gpu/drm/radeon/r100.c 2009-12-28 22:41:07.803741755 > +0100 > @@ -246,6 +246,9 @@ > if (rdev->irq.sw_int) { > tmp |= RADEON_SW_INT_ENABLE; > } > + if (rdev->irq.idle_int) { > + tmp |= RADEON_GUI_IDLE_INT_ENABLE; > + } > if (rdev->irq.crtc_vblank_int[0]) { > tmp |= RADEON_CRTC_VBLANK_MASK; > } > @@ -278,7 +281,8 @@ > uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); > uint32_t irq_mask = RADEON_SW_INT_TEST | > RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | > - RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; > + RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT | > + RADEON_GUI_IDLE_INT_TEST_ACK; > > if (irqs) { > WREG32(RADEON_GEN_INT_STATUS, irqs); > @@ -318,6 +322,9 @@ > queue_hotplug = true; > DRM_DEBUG("HPD2\n"); > } > + if (status & RADEON_GUI_IDLE_INT_TEST_ACK) { > + DRM_DEBUG("GUI idle\n"); > + } You'll need to ack this on pre-r6xx. > status = r100_irq_ack(rdev); > } > if (queue_hotplug) > --- linux-2.6.git.orig/drivers/gpu/drm/radeon/rs600.c 2009-12-28 > 22:32:30.927884090 +0100 > +++ linux-2.6.git/drivers/gpu/drm/radeon/rs600.c 2009-12-28 > 22:46:23.211897501 +0100 > @@ -318,6 +318,9 @@ > if (rdev->irq.sw_int) { > tmp |= S_000040_SW_INT_EN(1); > } > + if (rdev->irq.idle_int) { > + tmp |= S_000040_GUI_IDLE(1); > + } > if (rdev->irq.crtc_vblank_int[0]) { > mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); > } > @@ -411,6 +414,9 @@ > queue_hotplug = true; > DRM_DEBUG("HPD2\n"); > } > + if (G_000044_GUI_IDLE_STAT(status)) { > + DRM_DEBUG("GUI idle\n"); > + } You'll need to ACK this on pre-r6xx chips. > status = rs600_irq_ack(rdev, &r500_disp_int); > } > if (queue_hotplug) > --- linux-2.6.git.orig/drivers/gpu/drm/radeon/radeon_reg.h 2009-12-28 > 22:44:44.080738247 +0100 > +++ linux-2.6.git/drivers/gpu/drm/radeon/radeon_reg.h 2009-12-28 > 22:45:50.579740220 +0100 > @@ -994,6 +994,7 @@ > # define RADEON_FP_DETECT_MASK (1 << 4) > # define RADEON_CRTC2_VBLANK_MASK (1 << 9) > # define RADEON_FP2_DETECT_MASK (1 << 10) > +# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19) For correctness this should be: # define RADEON_GUI_IDLE_INT_MASK (1 << 19) > # define RADEON_SW_INT_ENABLE (1 << 25) > #define RADEON_GEN_INT_STATUS 0x0044 > # define AVIVO_DISPLAY_INT_STATUS (1 << 0) > @@ -1005,6 +1006,7 @@ > # define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9) > # define RADEON_FP2_DETECT_STAT (1 << 10) > # define RADEON_FP2_DETECT_STAT_ACK (1 << 10) > +# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19) and: # define RADEON_GUI_IDLE_STAT (1 << 19) # define RADEON_GUI_IDLE_STAT_ACK (1 << 19) > # define RADEON_SW_INT_FIRE (1 << 26) > # define RADEON_SW_INT_TEST (1 << 25) > # define RADEON_SW_INT_TEST_ACK (1 << 25) > > > Luca > ------------------------------------------------------------------------------ This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel