2009/12/28 Luca Tettamanti <[email protected]>:
> On Mon, Dec 28, 2009 at 01:32:24PM -0500, Alex Deucher wrote:
>> 2009/12/28 Luca Tettamanti <[email protected]>:
>> > 2009/12/28 Alex Deucher <[email protected]>:
>> >> On Mon, Dec 28, 2009 at 5:53 AM, Luca Tettamanti <[email protected]>
>> >> wrote:
>> >>> On Sun, Dec 27, 2009 at 1:55 AM, Rafał Miłecki <[email protected]> wrote:
>> >>>> W dniu 26 grudnia 2009 20:08 użytkownik Alex Deucher
>> >>>> <[email protected]> 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel