.gitignore                       |    2 
 INSTALL                          |    2 
 Makefile.am                      |    2 
 README                           |   44 
 README.coding                    |  124 +
 acinclude.m4                     |   77 
 autogen.sh                       |    4 
 configure.ac                     |   31 
 man/radeonhd.man                 |  238 +--
 shave-libtool.in                 |   69 
 shave.in                         |   79 
 src/Makefile.am                  |   26 
 src/atombios_rev.h               |  199 ++
 src/r5xx_accel.c                 |    9 
 src/r5xx_accel.h                 |    4 
 src/r5xx_exa.c                   |   12 
 src/r5xx_xaa.c                   |    2 
 src/r600_exa.c                   | 2164 +++++++++++++++++++++++++++
 src/r600_reg.h                   |  132 +
 src/r600_reg_auto_r6xx.h         | 3087 +++++++++++++++++++++++++++++++++++++++
 src/r600_reg_r6xx.h              |  504 ++++++
 src/r600_reg_r7xx.h              |  149 +
 src/r600_shader.c                | 1848 +++++++++++++++++++++++
 src/r600_shader.h                |  359 ++++
 src/r600_state.h                 |  293 +++
 src/r600_textured_videofuncs.c   |  558 +++++++
 src/r6xx_accel.c                 | 1202 +++++++++++++++
 src/r6xx_accel.h                 |   89 +
 src/radeon_3d.c                  |   52 
 src/radeon_drm.h                 |    2 
 src/radeon_exa_render.c          |   25 
 src/radeon_textured_videofuncs.c |    4 
 src/rhd.h                        |   77 
 src/rhd_acpi.c                   |  150 +
 src/rhd_acpi.h                   |   31 
 src/rhd_atombios.c               |  735 +++++++--
 src/rhd_atombios.h               |   72 
 src/rhd_atomcrtc.c               |   15 
 src/rhd_atomout.c                |  217 +-
 src/rhd_atomout.h                |    2 
 src/rhd_atompll.c                |    2 
 src/rhd_atomwrapper.c            |    2 
 src/rhd_atomwrapper.h            |    2 
 src/rhd_audio.c                  |   56 
 src/rhd_audio.h                  |    3 
 src/rhd_biosscratch.c            |    9 
 src/rhd_biosscratch.h            |    2 
 src/rhd_card.h                   |    2 
 src/rhd_connector.c              |    4 
 src/rhd_connector.h              |    2 
 src/rhd_crtc.c                   |   47 
 src/rhd_crtc.h                   |    4 
 src/rhd_cs.c                     |   29 
 src/rhd_cs.h                     |    2 
 src/rhd_cursor.c                 |  206 +-
 src/rhd_cursor.h                 |    4 
 src/rhd_dac.c                    |    6 
 src/rhd_ddia.c                   |    2 
 src/rhd_dig.c                    |  302 ++-
 src/rhd_dri.c                    |  228 +-
 src/rhd_dri.h                    |    2 
 src/rhd_driver.c                 |  609 ++++---
 src/rhd_edid.c                   |    2 
 src/rhd_hdmi.c                   |  148 +
 src/rhd_hdmi.h                   |   14 
 src/rhd_helper.c                 |   32 
 src/rhd_i2c.c                    |   32 
 src/rhd_i2c.h                    |    2 
 src/rhd_id.c                     |  230 ++
 src/rhd_lut.c                    |  153 -
 src/rhd_lut.h                    |    7 
 src/rhd_lvtma.c                  |  156 +
 src/rhd_mc.c                     |  952 +++++-------
 src/rhd_mc.h                     |   20 
 src/rhd_modes.c                  |    2 
 src/rhd_modes.h                  |    2 
 src/rhd_monitor.c                |   21 
 src/rhd_monitor.h                |    2 
 src/rhd_output.c                 |  115 +
 src/rhd_output.h                 |   10 
 src/rhd_pll.c                    |   26 
 src/rhd_pll.h                    |    2 
 src/rhd_pm.c                     |  475 ++++++
 src/rhd_pm.h                     |   78 
 src/rhd_randr.c                  |  470 ++++-
 src/rhd_randr.h                  |    2 
 src/rhd_regs.h                   |   85 -
 src/rhd_shadow.c                 |    2 
 src/rhd_shadow.h                 |    2 
 src/rhd_tmds.c                   |   67 
 src/rhd_vga.c                    |  133 -
 src/rhd_vga.h                    |   21 
 src/rhd_video.c                  |  270 +++
 src/rhd_video.h                  |   21 
 utils/conntest/Makefile.am       |   10 
 utils/conntest/rhd_conntest.c    |  393 ++++
 utils/conntest/rhd_dump.c        |  137 +
 97 files changed, 16092 insertions(+), 2218 deletions(-)

New commits:
commit 8cbff7bfa1201faa1e5dbf7019f17c2f4b1d2b7f
Author: Matthias Hopf <mh...@suse.de>
Date:   Fri Oct 9 17:42:45 2009 +0200

    Bump to 1.3.0. Update README.

diff --git a/README b/README
index 37ae8ab..ddfb2b5 100644
--- a/README
+++ b/README
@@ -92,6 +92,23 @@ Major Changes
 
 Read ChangeLog for a complete list.
 
+- Version 1.3.0
+
+  - Added support for RV740, M92, M93, M97.
+  - Added support for HDMI audio on RS690 and R700.
+  - Added support for power management.
+  - Implemented almost correct analysis of PowerPlay AtomBIOS tables.
+  - 2D acceleration (EXA) is enabled by default now, except on RV740.
+  - Backlight handling finally fixed - compatible with xbacklight 1.1.1.
+  - Overhaul of memory controller setup. Fixes many "MC not idle" issues.
+  - Overhaul of cursor handling. Fixes most cursor bugs.
+  - Selectable color space for XVideo on R6xx/R7xx.
+  - Tons of bug fixes (DDC, EXA, LUT, RandR, AtomBIOS).
+  - More quirk table entries.
+  - Shave support (cleaner compilation output).
+  - All warnings fixed.
+  - Some start of Developer's documentation in README.coding.
+
 - Version 1.2.5
 
   - Added 2D acceleration for R6xx and R7xx.
diff --git a/configure.ac b/configure.ac
index c12da87..3615a9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-radeonhd],
-        1.2.5,
+        1.3.0,
         
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/radeonhd],
         xf86-video-radeonhd)
 

commit bd2145d8fab854fb5617abd09f7517321d2b35be
Author: Matthias Hopf <mh...@suse.de>
Date:   Fri Oct 9 17:42:30 2009 +0200

    pm: Comment out currently unused variable.

diff --git a/src/rhd_pm.c b/src/rhd_pm.c
index 7f3b27c..26433aa 100644
--- a/src/rhd_pm.c
+++ b/src/rhd_pm.c
@@ -66,7 +66,7 @@ rhdPmPrint (struct rhdPm *Pm, char *name, struct 
rhdPowerState *state)
 /* TODO: So far we only know few safe points. Interpolate? */
 static void rhdPmValidateSetting (struct rhdPm *Pm, struct rhdPowerState 
*setting, int forceVoltage)
 {
-    CARD32 compare = setting->VDDCVoltage ? setting->VDDCVoltage : 
Pm->Current.VDDCVoltage;
+    /* CARD32 compare = setting->VDDCVoltage ? setting->VDDCVoltage : 
Pm->Current.VDDCVoltage; */
     if (! setting->EngineClock)
        setting->EngineClock = Pm->Current.EngineClock;
     if (setting->EngineClock < Pm->Minimum.EngineClock)

commit 5c437ecd5d06e1b214d2a309dfed60fadf071829
Author: Matthias Hopf <mh...@suse.de>
Date:   Fri Oct 9 17:31:29 2009 +0200

    README.coding: Add rhd_acpi.[ch] and atombios_rev.h

diff --git a/README.coding b/README.coding
index cbc9be2..a2691b2 100644
--- a/README.coding
+++ b/README.coding
@@ -22,6 +22,7 @@ General Stuff
 -------------
 
 rhd.h
+rhd_acpi.[ch]
 rhd_audio.[ch]
 rhd_card.h
 rhd_connector.[ch]
@@ -58,6 +59,7 @@ rhd_regs.h
 AtomBIOS related
 ----------------
 
+atombios_rev.h:                Reverse engineered AtomBIOS table definitions
 AtomBios/
 rhd_atombios.[ch]
 rhd_atomcrtc.c

commit 0c8cc053741d7113254776d6c64745ecc5a1256e
Author: Matthias Hopf <mh...@suse.de>
Date:   Fri Oct 9 11:25:06 2009 +0200

    i2c: Hardware may need a while to indicate availability to the host
    
    Fixes fdo #24330.

diff --git a/src/rhd_i2c.c b/src/rhd_i2c.c
index dbf00d0..d5b698a 100644
--- a/src/rhd_i2c.c
+++ b/src/rhd_i2c.c
@@ -462,6 +462,7 @@ rhd5xxWriteReadChunk(I2CDevPtr i2cDevPtr, int line, I2CByte 
*WriteBuffer,
     I2CBusPtr I2CPtr = i2cDevPtr->pI2CBus;
     rhdI2CPtr I2C = (rhdI2CPtr)(I2CPtr->DriverPrivate.ptr);
     int prescale = I2C->prescale;
+    int i;
     CARD32 save_I2C_CONTROL1, save_494;
     CARD32  tmp32;
     Bool ret = TRUE;
@@ -476,8 +477,13 @@ rhd5xxWriteReadChunk(I2CDevPtr i2cDevPtr, int line, 
I2CByte *WriteBuffer,
               R5_DC_I2C_SW_WANTS_TO_USE_I2C,
               R5_DC_I2C_SW_WANTS_TO_USE_I2C);
 
-    if (! (RHDRegRead(I2CPtr, R5_DC_I2C_ARBITRATION) & 
R5_DC_I2C_SW_CAN_USE_I2C)) {
-       RHDDebug(I2CPtr->scrnIndex, "%s SW cannot use I2C line 
%i\n",__func__,line);
+    for (i = 0; i < 50; i++) {
+       if (RHDRegRead(I2CPtr, R5_DC_I2C_ARBITRATION) & 
R5_DC_I2C_SW_CAN_USE_I2C)
+           break;
+       usleep(1);
+    }
+    if (i >= 50) {
+       xf86DrvMsg(I2CPtr->scrnIndex,X_ERROR, "%s: SW cannot use I2C line 
%i\n",__func__,line);
        ret = FALSE;
     } else {
 

commit 57b97e0fefd7e5a0069573befabdb28ee0094f8d
Author: Matthias Hopf <mh...@suse.de>
Date:   Thu Oct 8 17:10:05 2009 +0200

    pm: Improve wording of lowPowerModeEngineClock logging.

diff --git a/src/rhd_pm.c b/src/rhd_pm.c
index f64ba2f..7f3b27c 100644
--- a/src/rhd_pm.c
+++ b/src/rhd_pm.c
@@ -205,7 +205,7 @@ static void rhdPmSelectSettings (RHDPtr rhdPtr)
            /* TODO: this should actually set the user mode */
             Pm->States[RHD_PM_IDLE].EngineClock = 
rhdPtr->lowPowerModeEngineClock.val.integer;
             xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
-                      "ForceLowPowerMode: forced engine clock at %dkHz\n",
+                      "ForceLowPowerMode: set idle engine clock to %dkHz\n",
                       (int) Pm->States[RHD_PM_IDLE].EngineClock);
         }
 
@@ -217,7 +217,7 @@ static void rhdPmSelectSettings (RHDPtr rhdPtr)
         } else {
             Pm->States[RHD_PM_IDLE].MemoryClock = 
rhdPtr->lowPowerModeMemoryClock.val.integer;
             xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
-                      "ForceLowPowerMode: forced memory clock at %dkHz\n",
+                      "ForceLowPowerMode: set idle memory clock to %dkHz\n",
                       (int) Pm->States[RHD_PM_IDLE].MemoryClock);
         }
 

commit a1cd56ddd2955ce74cccc4adcd482feda0985b72
Author: Matthias Hopf <mh...@suse.de>
Date:   Thu Oct 8 16:59:55 2009 +0200

    pm: Ignore validation when setting negative engine/mem frequencies.

diff --git a/man/radeonhd.man b/man/radeonhd.man
index e1e8e84..7a1641a 100644
--- a/man/radeonhd.man
+++ b/man/radeonhd.man
@@ -496,7 +496,8 @@ can help reduce power consumption. The default is
 .TP
 .BI "Option \*qLowPowerModeEngineClock\*q \*q" integer \*q
 Engine clock frequency to use when ForceLowPowerMode is enabled, in Hz. If not
-set, the minimum known working frequency is used.
+set, the minimum known working frequency is used.  If integer is negative,
+validation is skipped, and the absolute value is used for the engine clock.
 .\"
 .\"
 .SH RANDR OUTPUT PROPERTIES
diff --git a/src/rhd_pm.c b/src/rhd_pm.c
index 0d467b3..f64ba2f 100644
--- a/src/rhd_pm.c
+++ b/src/rhd_pm.c
@@ -222,6 +222,17 @@ static void rhdPmSelectSettings (RHDPtr rhdPtr)
         }
 
        rhdPmValidateSetting (Pm, &Pm->States[RHD_PM_IDLE], 1);
+
+        if (rhdPtr->lowPowerModeEngineClock.val.integer < 0) {
+            Pm->States[RHD_PM_IDLE].EngineClock = - 
rhdPtr->lowPowerModeEngineClock.val.integer;
+           xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING,
+                      "ForceLowPowerMode: user requested to ignore validation 
for engine clock\n");
+       }
+        if (rhdPtr->lowPowerModeMemoryClock.val.integer < 0) {
+            Pm->States[RHD_PM_IDLE].MemoryClock = - 
rhdPtr->lowPowerModeMemoryClock.val.integer;
+           xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING,
+                      "ForceLowPowerMode: user requested to ignore validation 
for memory clock\n");
+       }
     }
 
     memcpy (&Pm->States[RHD_PM_MAX_3D], &Pm->Maximum, sizeof (struct 
rhdPowerState));

commit 5d5d8e3d8655a7adbc17a548372bc0fad6d67cb7
Author: Matthias Hopf <mh...@suse.de>
Date:   Thu Oct 8 16:57:21 2009 +0200

    pm: Use minimum known working frequency instead of default/2.

diff --git a/man/radeonhd.man b/man/radeonhd.man
index 3d3a508..e1e8e84 100644
--- a/man/radeonhd.man
+++ b/man/radeonhd.man
@@ -496,7 +496,7 @@ can help reduce power consumption. The default is
 .TP
 .BI "Option \*qLowPowerModeEngineClock\*q \*q" integer \*q
 Engine clock frequency to use when ForceLowPowerMode is enabled, in Hz. If not
-set, half of default clock frequency is used.
+set, the minimum known working frequency is used.
 .\"
 .\"
 .SH RANDR OUTPUT PROPERTIES
diff --git a/src/rhd_pm.c b/src/rhd_pm.c
index f67af05..0d467b3 100644
--- a/src/rhd_pm.c
+++ b/src/rhd_pm.c
@@ -195,13 +195,12 @@ static void rhdPmSelectSettings (RHDPtr rhdPtr)
     memcpy (&Pm->States[RHD_PM_OFF], &Pm->Minimum, sizeof (struct 
rhdPowerState));
 
     if (rhdPtr->lowPowerMode.val.bool) {
-       /* Idle: !!!HACK!!! Take half the default */
        /* TODO: copy lowest config with default Voltage/Mem setting? */
         if (!rhdPtr->lowPowerModeEngineClock.val.integer) {
-           Pm->States[RHD_PM_IDLE].EngineClock = Pm->Default.EngineClock / 2;
-                xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
-                          "ForceLowPowerMode: calculated engine clock at 
%dkHz\n",
-                          (int) Pm->States[RHD_PM_IDLE].EngineClock);
+           Pm->States[RHD_PM_IDLE].EngineClock = 
Pm->States[RHD_PM_OFF].EngineClock;
+           xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
+                      "ForceLowPowerMode: calculated engine clock at %dkHz\n",
+                      (int) Pm->States[RHD_PM_IDLE].EngineClock);
         } else {
            /* TODO: this should actually set the user mode */
             Pm->States[RHD_PM_IDLE].EngineClock = 
rhdPtr->lowPowerModeEngineClock.val.integer;
@@ -211,7 +210,7 @@ static void rhdPmSelectSettings (RHDPtr rhdPtr)
         }
 
         if (!rhdPtr->lowPowerModeMemoryClock.val.integer) {
-           Pm->States[RHD_PM_IDLE].MemoryClock = Pm->Default.MemoryClock / 2;
+           Pm->States[RHD_PM_IDLE].MemoryClock = 
Pm->States[RHD_PM_OFF].MemoryClock;
                 xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
                           "ForceLowPowerMode: calculated memory clock at 
%dkHz\n",
                           (int) Pm->States[RHD_PM_IDLE].MemoryClock);

commit 0a94f8eb56ec0155864858f8aefc4c64d3e1bf77
Author: Matthias Hopf <mh...@suse.de>
Date:   Thu Oct 8 16:02:46 2009 +0200

    pm: Do NOT set idle engine clocks to default/2 unless ForceLowPowerMode is 
used.
    
    Accidentally, we set this by default since commit fedddb7.
    Using different engine clocks has side effects that are not handled yet.

diff --git a/src/rhd_pm.c b/src/rhd_pm.c
index 9efa1b0..f67af05 100644
--- a/src/rhd_pm.c
+++ b/src/rhd_pm.c
@@ -194,17 +194,16 @@ static void rhdPmSelectSettings (RHDPtr rhdPtr)
     /* RHD_PM_OFF: minimum */
     memcpy (&Pm->States[RHD_PM_OFF], &Pm->Minimum, sizeof (struct 
rhdPowerState));
 
-    /* Idle: !!!HACK!!! Take half the default */
-    /* TODO: copy lowest config with default Voltage/Mem setting? */
-    /* TODO: this should actually set the user mode */
-    Pm->States[RHD_PM_IDLE].EngineClock = Pm->Default.EngineClock / 2;
     if (rhdPtr->lowPowerMode.val.bool) {
+       /* Idle: !!!HACK!!! Take half the default */
+       /* TODO: copy lowest config with default Voltage/Mem setting? */
         if (!rhdPtr->lowPowerModeEngineClock.val.integer) {
            Pm->States[RHD_PM_IDLE].EngineClock = Pm->Default.EngineClock / 2;
                 xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
                           "ForceLowPowerMode: calculated engine clock at 
%dkHz\n",
                           (int) Pm->States[RHD_PM_IDLE].EngineClock);
         } else {
+           /* TODO: this should actually set the user mode */
             Pm->States[RHD_PM_IDLE].EngineClock = 
rhdPtr->lowPowerModeEngineClock.val.integer;
             xf86DrvMsg(rhdPtr->scrnIndex, X_INFO,
                       "ForceLowPowerMode: forced engine clock at %dkHz\n",

commit eebdbf0a9723c79975015354830550f7dfb57509
Author: Egbert Eich <e...@freedesktop.org>
Date:   Thu Oct 8 09:15:32 2009 +0200

    Improve DAC load detection on RS780.
    
    Increase delay before reading out DAC autodetect status.

diff --git a/src/rhd_dac.c b/src/rhd_dac.c
index bfed38c..8d05fe5 100644
--- a/src/rhd_dac.c
+++ b/src/rhd_dac.c
@@ -648,7 +648,7 @@ DACSenseRV620(struct rhdOutput *Output, CARD32 offset, Bool 
TV)
     /* enable comparators for R/G/B, disable DDET and SDET reference */
     RHDRegMask(Output, offset + RV620_DACA_COMPARATOR_ENABLE, 0x70000, 
0x070101);
     RHDRegMask(Output, offset + RV620_DACA_AUTODETECT_CONTROL, 0x01, 0xff);
-    usleep(32);
+    usleep(50);
     ret = RHDRegRead(Output, offset + RV620_DACA_AUTODETECT_STATUS);
     RHDRegWrite(Output, offset + RV620_DACA_AUTODETECT_CONTROL, DetectControl);
     RHDRegWrite(Output, offset + RV620_DACA_MACRO_CNTL, Control1);
diff --git a/utils/conntest/rhd_conntest.c b/utils/conntest/rhd_conntest.c
index c7ecd41..f1db552 100644
--- a/utils/conntest/rhd_conntest.c
+++ b/utils/conntest/rhd_conntest.c
@@ -898,10 +898,10 @@ RV620DACLoadDetect(void *map, Bool tv, int dac)
     RegMask(map, offset + RV620_DACA_CONTROL2, 0x1, 0x1);
     /* enable r/g/b comparators, disable D/SDET ref */
     RegMask(map, offset + RV620_DACA_COMPARATOR_ENABLE, 0x70000, 0x070101);
-    usleep(100);
+    //usleep(100);
     /* check for connection */
     RegMask(map, offset + RV620_DACA_AUTODETECT_CONTROL, 0x01, 0xff);
-    usleep(32);
+    usleep(50);
 
     ret = RegRead(map, offset + RV620_DACA_AUTODETECT_STATUS);
 

commit 422ac06b69cfcbfbaa802fdc916d3b87f40eeb41
Author: Christian König <deathsim...@vodafone.de>
Date:   Thu Oct 8 00:04:01 2009 +0200

    Silence audio stream option.
    
    This patch adds an option to play silence instead of playing no sound at 
all.
    This fixes some issues where a receiver needs 1-2 seconds to adjust to a 
new audio stream.
    This option can be enabled by setting AudioStreamSilence in xorg.conf or by 
xrandr.

diff --git a/src/rhd.h b/src/rhd.h
index 43adb30..efa6bc2 100644
--- a/src/rhd.h
+++ b/src/rhd.h
@@ -247,6 +247,7 @@ typedef struct RHDRec {
     RHDOpt             scaleTypeOpt;
     RHDOpt             unverifiedFeatures;
     RHDOpt             audio;
+    RHDOpt             audioWorkaround;
     RHDOpt             hdmi;
     RHDOpt             coherent;
     RHDOpt              lowPowerMode;
diff --git a/src/rhd_atomout.c b/src/rhd_atomout.c
index b88b1bd..9d50ade 100644
--- a/src/rhd_atomout.c
+++ b/src/rhd_atomout.c
@@ -745,6 +745,7 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
            switch (Property) {
                case RHD_OUTPUT_COHERENT:
                case RHD_OUTPUT_HDMI:
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
                    return TRUE;
                default:
                    return FALSE;
@@ -757,6 +758,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
                case RHD_OUTPUT_HDMI:
                    val->Bool = atomIsHdmiEnabled(Output);
                    return TRUE;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi);
+                   return TRUE;
                default:
                    return FALSE;
            }
@@ -769,6 +773,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
                case RHD_OUTPUT_HDMI:
                    atomSetHdmiEnabled(Output, val->Bool);
                    break;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool);
+                   break;
                default:
                    return FALSE;
            }
@@ -780,6 +787,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
                    Output->Mode(Output, Private->Mode);
                    Output->Power(Output, RHD_POWER_ON);
                    break;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   RHDHdmiCommitAudioWorkaround(Private->Hdmi);
+                   break;
                default:
                    return FALSE;
            }
diff --git a/src/rhd_audio.c b/src/rhd_audio.c
index de5f5ce..5e3c4e2 100644
--- a/src/rhd_audio.c
+++ b/src/rhd_audio.c
@@ -90,14 +90,16 @@ AudioRate(struct rhdAudio* Audio)
     return result;
 }
 
+#if 0
 /*
- * something playing ?
+ * something playing ? (not used anymore)
  */
 static Bool
 AudioPlaying(struct rhdAudio* Audio)
 {
     return (RHDRegRead(Audio, AUDIO_PLAYING) >> 4) & 1;
 }
+#endif
 
 /*
  * iec 60958 status bits
@@ -124,35 +126,36 @@ static CARD32
 AudioUpdateHdmi(OsTimerPtr timer, CARD32 time, pointer ptr)
 {
     struct rhdAudio *Audio = (struct rhdAudio*)ptr;
-    Bool playing = AudioPlaying(Audio);
     int channels = AudioChannels(Audio);
     int rate = AudioRate(Audio);
     int bps = AudioBitsPerSample(Audio);
     CARD8 status_bits = AudioStatusBits(Audio);
     CARD8 category_code = AudioCategoryCode(Audio);
 
+    Bool changes = FALSE;
+
     struct rhdHdmi* hdmi;
 
-    if(playing != Audio->SavedPlaying ||
-       channels != Audio->SavedChannels ||
-       rate != Audio->SavedRate ||
-       bps != Audio->SavedBitsPerSample ||
-       status_bits != Audio->SavedStatusBits ||
-       category_code != Audio->SavedCategoryCode) {
+    changes |= channels != Audio->SavedChannels;
+    changes |= rate != Audio->SavedRate;
+    changes |= bps != Audio->SavedBitsPerSample;
+    changes |= status_bits != Audio->SavedStatusBits;
+    changes |= category_code != Audio->SavedCategoryCode;
 
-       Audio->SavedPlaying = playing;
+    if(changes) {
        Audio->SavedChannels = channels;
        Audio->SavedRate = rate;
        Audio->SavedBitsPerSample = bps;
        Audio->SavedStatusBits = status_bits;
        Audio->SavedCategoryCode = category_code;
+    }
 
-       for(hdmi=Audio->Registered; hdmi != NULL; hdmi=hdmi->Next)
+    for(hdmi=Audio->Registered; hdmi != NULL; hdmi=hdmi->Next)
+       if(changes || RHDHdmiBufferStatusChanged(hdmi))
            RHDHdmiUpdateAudioSettings(
-               hdmi, playing, channels,
+               hdmi, channels,
                rate, bps, status_bits,
                category_code);
-    }
 
     return AUDIO_TIMER_INTERVALL;
 }
@@ -303,6 +306,9 @@ RHDAudioRegisterHdmi(RHDPtr rhdPtr, struct rhdHdmi* rhdHdmi)
     if(!rhdHdmi)
        return;
 
+    /* make shure the HDMI interface is not registered */
+    RHDAudioUnregisterHdmi(rhdPtr, rhdHdmi);
+
     rhdHdmi->Next = Audio->Registered;
     Audio->Registered = rhdHdmi;
 }
@@ -318,7 +324,7 @@ void RHDAudioUnregisterHdmi(RHDPtr rhdPtr, struct rhdHdmi* 
rhdHdmi)
     if (!Audio)        return;
     RHDFUNC(Audio);
 
-    for(hdmiPtr=&Audio->Registered; hdmiPtr!=NULL;hdmiPtr=&(*hdmiPtr)->Next)
+    for(hdmiPtr=&Audio->Registered; *hdmiPtr!=NULL;hdmiPtr=&(*hdmiPtr)->Next)
        if(*hdmiPtr == rhdHdmi) {
            *hdmiPtr = rhdHdmi->Next;
            rhdHdmi->Next = NULL;
diff --git a/src/rhd_audio.h b/src/rhd_audio.h
index d74016c..82932e9 100644
--- a/src/rhd_audio.h
+++ b/src/rhd_audio.h
@@ -34,7 +34,6 @@ struct rhdAudio {
        struct rhdHdmi* Registered;
        OsTimerPtr      Timer;
 
-       Bool    SavedPlaying;
        int     SavedChannels;
        int     SavedRate;
        int     SavedBitsPerSample;
diff --git a/src/rhd_dig.c b/src/rhd_dig.c
index 6e75fd0..782c8db 100644
--- a/src/rhd_dig.c
+++ b/src/rhd_dig.c
@@ -262,6 +262,7 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output,
            switch (Property) {
                case RHD_OUTPUT_COHERENT:
                case RHD_OUTPUT_HDMI:
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
                    return TRUE;
                default:
                    return FALSE;
@@ -274,6 +275,9 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output,
                case RHD_OUTPUT_HDMI:
                    val->Bool = Private->EncoderMode == TMDS_HDMI;
                    return TRUE;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi);
+                   return TRUE;
                default:
                    return FALSE;
            }
@@ -286,6 +290,9 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output,
                case RHD_OUTPUT_HDMI:
                    Private->EncoderMode = val->Bool ? TMDS_HDMI : TMDS_DVI;
                    break;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool);
+                   break;
                default:
                    return FALSE;
            }
@@ -297,6 +304,9 @@ TMDSTransmitterPropertyControl(struct rhdOutput *Output,
                    Output->Mode(Output, Private->Mode);
                    Output->Power(Output, RHD_POWER_ON);
                    break;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   RHDHdmiCommitAudioWorkaround(Private->Hdmi);
+                   break;
                default:
                    return FALSE;
            }
@@ -1472,6 +1482,7 @@ DigPropertyControl(struct rhdOutput *Output,
        case RHD_OUTPUT_COHERENT:
        case RHD_OUTPUT_BACKLIGHT:
        case RHD_OUTPUT_HDMI:
+       case RHD_OUTPUT_AUDIO_WORKAROUND:
        {
            if (!Private->Transmitter.Property)
                return FALSE;
diff --git a/src/rhd_driver.c b/src/rhd_driver.c
index 649cadb..e502c5f 100644
--- a/src/rhd_driver.c
+++ b/src/rhd_driver.c
@@ -261,6 +261,7 @@ typedef enum {
 #endif
     OPTION_UNVERIFIED_FEAT,
     OPTION_AUDIO,
+    OPTION_AUDIO_WORKAROUND,
     OPTION_HDMI,
     OPTION_COHERENT,
     OPTION_FORCE_LOW_POWER,
@@ -292,6 +293,7 @@ static const OptionInfoRec RHDOptions[] = {
 #endif
     { OPTION_UNVERIFIED_FEAT,     "UnverifiedFeatures",   OPTV_BOOLEAN, {0}, 
FALSE },
     { OPTION_AUDIO,               "Audio",                OPTV_BOOLEAN, {0}, 
FALSE },
+    { OPTION_AUDIO_WORKAROUND,    "AudioStreamSilence",   OPTV_ANYSTR,  {0}, 
FALSE },
     { OPTION_HDMI,                "HDMI",                 OPTV_ANYSTR,  {0}, 
FALSE },
     { OPTION_COHERENT,             "COHERENT",            OPTV_ANYSTR,  {0}, 
FALSE },
     { OPTION_FORCE_LOW_POWER,      "ForceLowPowerMode",    OPTV_BOOLEAN, {0}, 
FALSE },
@@ -2844,6 +2846,8 @@ rhdProcessOptions(ScrnInfoPtr pScrn)
                        &rhdPtr->unverifiedFeatures, FALSE);
     RhdGetOptValBool   (rhdPtr->Options, OPTION_AUDIO,
                        &rhdPtr->audio, TRUE);
+    RhdGetOptValString (rhdPtr->Options, OPTION_AUDIO_WORKAROUND,
+                       &rhdPtr->audioWorkaround, "none");
     RhdGetOptValString (rhdPtr->Options, OPTION_HDMI,
                        &rhdPtr->hdmi, "none");
     RhdGetOptValString(rhdPtr->Options, OPTION_COHERENT,
diff --git a/src/rhd_hdmi.c b/src/rhd_hdmi.c
index 62ab861..c786fcd 100644
--- a/src/rhd_hdmi.c
+++ b/src/rhd_hdmi.c
@@ -229,26 +229,16 @@ HdmiAudioInfoFrame(
 }
 
 /*
- * it's unknown what these bits do excatly, but it's indeed quite usefull for 
debugging
+ * test if audio buffer is filled enough to start playing
  */
-static void
-HdmiAudioDebugWorkaround(struct rhdHdmi* hdmi, Bool Enable)
+static Bool
+IsAudioBufferFilled(struct rhdHdmi *hdmi)
 {
-    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
-    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
-    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2, 0x00000001);
-    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3, 0x00000001);
-
-    if(Enable) {
-       RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x1000, 0x1000);
-    } else {
-       RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0, 0x1000);
-    }
+    return (RHDRegRead(hdmi, hdmi->Offset+HDMI_STATUS) & 0x10) != 0;
 }
 
 /*
  * allocate/initialize the HDMI structure
- * and register with audio engine
  * output selects which engine is used
  */
 struct rhdHdmi*
@@ -291,7 +281,6 @@ RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output)
                break;
        }
        hdmi->Stored = FALSE;
-       RHDAudioRegisterHdmi(rhdPtr, hdmi);
        return hdmi;
     } else
        return NULL;
@@ -308,8 +297,6 @@ RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode)
 
     RHDAudioSetClock(RHDPTRI(hdmi), hdmi->Output, Mode->Clock);
 
-    HdmiAudioDebugWorkaround(hdmi, FALSE);
-
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, 0x1000);
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x0);
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x1000);
@@ -323,20 +310,45 @@ RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode)
     HdmiVideoInfoFrame(hdmi, RGB, FALSE, 0, 0, 0,
        0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
+    /* it's unknown what these bits do excatly, but it's indeed quite usefull 
for debugging */
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2, 0x00000001);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3, 0x00000001);
+
+    RHDHdmiCommitAudioWorkaround(hdmi);
+
     /* audio packets per line, does anyone know how to calc this ? */
-    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x020000, 0x1F0000);
+    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00040000, 0x001F0000);
 
     /* update? reset? don't realy know */
     RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x14000000, 0x14000000);
 }
 
 /*
+ * have buffer status changed since last call?
+ */
+Bool
+RHDHdmiBufferStatusChanged(struct rhdHdmi* hdmi)
+{
+    Bool status, result;
+
+    if(!hdmi) return FALSE;
+    RHDFUNC(hdmi);
+
+    status = IsAudioBufferFilled(hdmi);
+    result = hdmi->SavedBufferStatus != status;
+    hdmi->SavedBufferStatus = status;
+
+    return result;
+}
+
+/*
  * update settings with current parameters from audio engine
  */
 void
 RHDHdmiUpdateAudioSettings(
     struct rhdHdmi* hdmi,
-    Bool playing,
     int channels,
     int rate,
     int bps,
@@ -351,13 +363,11 @@ RHDHdmiUpdateAudioSettings(
 
     xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: %s with "
        "%d channels, %d Hz sampling rate, %d bits per sample,\n",
-        __func__, playing ? "playing" : "stopped", channels, rate, bps);
+       __func__, IsAudioBufferFilled(hdmi) ? "playing" : "stopped",
+       channels, rate, bps);
     xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: "
        "0x%02x IEC60958 status bits and 0x%02x category code\n",
-        __func__, (int)status_bits, (int)category_code);
-
-    /* start delivering audio frames */
-    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, playing ? 1 : 0, 0x1);
+       __func__, (int)status_bits, (int)category_code);
 
     iec = 0;
     if(status_bits & AUDIO_STATUS_PROFESSIONAL)        iec |= 1 << 0;
@@ -395,12 +405,15 @@ RHDHdmiUpdateAudioSettings(
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, 0x31);
     HdmiAudioInfoFrame(hdmi, channels-1, 0, 0, 0, 0, 0, 0, FALSE);
 
-    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x4000000, 0x4000000); */
-    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x400000, 0x400000);
+    RHDHdmiCommitAudioWorkaround(hdmi);
+
+    /* update? reset? don't realy know */
+    RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x04000000, 0x04000000);
 }
 
 /*
  * enable/disable the HDMI engine
+ * and register with audio engine
  */
 void
 RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable)
@@ -432,6 +445,57 @@ RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable)
            xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output 
type\n", __func__);
            break;
     }
+    if(Enable)
+       RHDAudioRegisterHdmi(RHDPTRI(hdmi), hdmi);
+    else
+       RHDAudioUnregisterHdmi(RHDPTRI(hdmi), hdmi);
+}
+
+/*
+ * enable/disable the audio workaround function
+ */
+void
+RHDHdmiSetAudioWorkaround(struct rhdHdmi* hdmi, Bool Enable)
+{
+    if(!hdmi) return;
+    RHDFUNC(hdmi);
+
+    hdmi->AudioDebugWorkaround = Enable;
+}
+
+/*
+ * get status of the audio workaround function
+ */
+Bool
+RHDHdmiGetAudioWorkaround(struct rhdHdmi* hdmi)
+{
+    if(!hdmi) return FALSE;
+    RHDFUNC(hdmi);
+
+    return hdmi->AudioDebugWorkaround;
+}
+
+/*
+ * commit the audio workaround status to the hardware
+ */
+void
+RHDHdmiCommitAudioWorkaround(struct rhdHdmi* hdmi)
+{
+    if(!hdmi) return;
+    RHDFUNC(hdmi);
+
+    if(IsAudioBufferFilled(hdmi)) {
+       /* disable audio workaround and start delivering of audio frames */
+       RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00000001, 0x00001001);
+
+    } else if(hdmi->AudioDebugWorkaround) {
+       /* enable audio workaround and start delivering of audio frames */
+       RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00001001, 0x00001001);
+
+    } else {
+       /* disable audio workaround and stop delivering of audio frames */
+       RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x00000000, 0x00001001);
+    }
 }
 
 /*
diff --git a/src/rhd_hdmi.h b/src/rhd_hdmi.h
index 5b1e8f0..e86b5e2 100644
--- a/src/rhd_hdmi.h
+++ b/src/rhd_hdmi.h
@@ -35,6 +35,9 @@ struct rhdHdmi {
        struct rhdOutput* Output;
        CARD16 Offset;
 
+       Bool SavedBufferStatus;
+       Bool AudioDebugWorkaround;
+
        Bool Stored;
        CARD32 StoreEnable;
        CARD32 StoreControl;
@@ -63,9 +66,10 @@ struct rhdHdmi* RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* 
Output);
 
 void RHDHdmiSetMode(struct rhdHdmi* rhdHdmi, DisplayModePtr Mode);
 void RHDHdmiEnable(struct rhdHdmi* rhdHdmi, Bool Enable);
+
+Bool RHDHdmiBufferStatusChanged(struct rhdHdmi* hdmi);
 void RHDHdmiUpdateAudioSettings(
        struct rhdHdmi* rhdHdmi,
-       Bool playing,
        int channels,
        int rate,
        int bps,
@@ -73,6 +77,10 @@ void RHDHdmiUpdateAudioSettings(
        CARD8 catgory_code
 );
 
+void RHDHdmiSetAudioWorkaround(struct rhdHdmi* rhdHdmi, Bool Enabled);
+Bool RHDHdmiGetAudioWorkaround(struct rhdHdmi* rhdHdmi);
+void RHDHdmiCommitAudioWorkaround(struct rhdHdmi* rhdHdmi);
+
 void RHDHdmiSave(struct rhdHdmi* rhdHdmi);
 void RHDHdmiRestore(struct rhdHdmi* rhdHdmi);
 
diff --git a/src/rhd_lvtma.c b/src/rhd_lvtma.c
index 685aef6..a4aeb9e 100644
--- a/src/rhd_lvtma.c
+++ b/src/rhd_lvtma.c
@@ -1069,6 +1069,7 @@ TMDSBPropertyControl(struct rhdOutput *Output,
            switch (Property) {
                case RHD_OUTPUT_COHERENT:
                case RHD_OUTPUT_HDMI:
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
                    return TRUE;
                default:
                    return FALSE;
@@ -1081,6 +1082,9 @@ TMDSBPropertyControl(struct rhdOutput *Output,
                case RHD_OUTPUT_HDMI:
                    val->Bool = Private->HdmiEnabled;
                    return TRUE;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi);
+                   return TRUE;
                default:
                    return FALSE;
            }
@@ -1093,6 +1097,9 @@ TMDSBPropertyControl(struct rhdOutput *Output,
                case RHD_OUTPUT_HDMI:
                    Private->HdmiEnabled = val->Bool;
                    break;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool);
+                   break;
                default:
                    return FALSE;
            }
@@ -1104,6 +1111,9 @@ TMDSBPropertyControl(struct rhdOutput *Output,
                    Output->Mode(Output, Private->Mode);
                    Output->Power(Output, RHD_POWER_ON);
                    break;
+               case RHD_OUTPUT_AUDIO_WORKAROUND:
+                   RHDHdmiCommitAudioWorkaround(Private->Hdmi);
+                   break;
                default:
                    return FALSE;
            }
diff --git a/src/rhd_output.c b/src/rhd_output.c
index 2219582..0e33d4e 100644
--- a/src/rhd_output.c
+++ b/src/rhd_output.c
@@ -260,6 +260,25 @@ RHDOutputAttachConnector(struct rhdOutput *Output, struct 
rhdConnector *Connecto
        if(!Output->Property(Output, rhdPropertySet, RHD_OUTPUT_HDMI, &val))
            xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "Failed to %s HDMI on 
%s\n", val.Bool ? "disable" : "enable", Output->Name);
     }
+
+    /* check config option if we should enable audio workaround */
+    if (Output->Property(Output, rhdPropertyCheck, 
RHD_OUTPUT_AUDIO_WORKAROUND, NULL)) {
+       union rhdPropertyData val;
+       switch(RhdParseBooleanOption(&rhdPtr->audioWorkaround, 
Connector->Name)) {
+           case RHD_OPTION_NOT_SET:
+           case RHD_OPTION_OFF:
+               val.Bool = FALSE;
+               break;
+           case RHD_OPTION_ON:
+           case RHD_OPTION_DEFAULT:
+               val.Bool = TRUE;
+               break;
+       }
+       if(!Output->Property(Output, rhdPropertySet, 
RHD_OUTPUT_AUDIO_WORKAROUND, &val))
+           xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING,
+               "Failed to %s audio workaorund on %s\n",
+               val.Bool ? "disable" : "enable", Output->Name);
+    }
 }
 
 /*
diff --git a/src/rhd_output.h b/src/rhd_output.h
index 0e7b6a2..4862478 100644
--- a/src/rhd_output.h
+++ b/src/rhd_output.h
@@ -59,7 +59,8 @@ typedef enum rhdSensedOutput {
 enum rhdOutputProperty {
     RHD_OUTPUT_BACKLIGHT,
     RHD_OUTPUT_COHERENT,
-    RHD_OUTPUT_HDMI
+    RHD_OUTPUT_HDMI,
+    RHD_OUTPUT_AUDIO_WORKAROUND
 };
 
 enum rhdOutputAllocation {
diff --git a/src/rhd_randr.c b/src/rhd_randr.c
index 568c0cd..956119b 100644
--- a/src/rhd_randr.c
+++ b/src/rhd_randr.c
@@ -130,11 +130,12 @@ struct rhdRandrCrtc {
 #define ATOM_BACKLIGHT        "Backlight"
 #define ATOM_COHERENT         "_Coherent"
 #define ATOM_HDMI             "_HDMI"
+#define ATOM_AUDIO_WORKAROUND "_AudioStreamSilence"
 #define ATOM_ATOMBIOS         "_AtomBIOS"
 


-- 
To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to