[haiku-commits] r34684 - haiku/trunk/src/add-ons/kernel/drivers/audio/hda

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 16 Dec 2009 21:39:54 +0100 (CET)

Author: bonefish
Date: 2009-12-16 21:39:54 +0100 (Wed, 16 Dec 2009)
New Revision: 34684
Changeset: http://dev.haiku-os.org/changeset/34684/haiku

Modified:
   haiku/trunk/src/add-ons/kernel/drivers/audio/hda/driver.h
   haiku/trunk/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp
Log:
Try to detect whether the stream's DMA position is broken and switch to using
the LPIB, if it is.


Modified: haiku/trunk/src/add-ons/kernel/drivers/audio/hda/driver.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/audio/hda/driver.h   2009-12-16 
20:13:14 UTC (rev 34683)
+++ haiku/trunk/src/add-ons/kernel/drivers/audio/hda/driver.h   2009-12-16 
20:39:54 UTC (rev 34684)
@@ -164,6 +164,9 @@
        area_id         buffer_descriptors_area;
        uint32          physical_buffer_descriptors;    /* BDL physical address 
*/
 
+       int32           incorrect_position_count;
+       bool            use_dma_position;
+
        uint8 Read8(uint32 reg)
        {
                return controller->Read8(HDAC_STREAM_BASE + offset + reg);

Modified: haiku/trunk/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp 
2009-12-16 20:13:14 UTC (rev 34683)
+++ haiku/trunk/src/add-ons/kernel/drivers/audio/hda/hda_controller.cpp 
2009-12-16 20:39:54 UTC (rev 34684)
@@ -111,12 +111,25 @@
                return false;
        }
 
+       // Normally we should use the DMA position for the stream. Apparently 
there
+       // are broken chipsets, which don't support it correctly. If we detect 
this,
+       // we switch to using the LPIB instead. The link position is ahead of 
the
+       // DMA position for recording and behind for playback streams, but just
+       // for determining the currently active buffer, it should be good 
enough.
+       if (stream->use_dma_position && stream->incorrect_position_count >= 32) 
{
+               dprintf("hda: DMA position for stream (id:%ld) seems to be 
broken. "
+                       "Switching to using LPIB.\n", stream->id);
+               stream->use_dma_position = false;
+       }
+
        // Determine the buffer we're switching to. Some chipsets seem to 
trigger
        // the interrupt before the DMA position in memory has been updated. We
        // round it, so we still get the right buffer.
-       uint32 dmaPosition = controller->stream_positions[index * 2];
-       uint32 bufferIndex = (dmaPosition + stream->buffer_size / 2)
-               / stream->buffer_size;
+       uint32 dmaPosition = stream->use_dma_position
+               ? controller->stream_positions[index * 2]
+               : stream->Read32(HDAC_STREAM_POSITION);
+       uint32 bufferIndex = ((dmaPosition + stream->buffer_size / 2)
+               / stream->buffer_size) % stream->num_buffers;
 
        // get the current recording/playing position and the system time
        uint32 linkBytePosition = stream->Read32(HDAC_STREAM_POSITION);
@@ -142,6 +155,11 @@
        // update stream playing/recording state and notify buffer_exchange()
        acquire_spinlock(&stream->lock);
 
+       if (bufferIndex == (stream->buffer_cycle + 1) % stream->num_buffers)
+               stream->incorrect_position_count = 0;
+       else
+               stream->incorrect_position_count++;
+
        stream->real_time = now;
        stream->frames_count += framesProcessed;
        stream->buffer_cycle = bufferIndex;
@@ -464,6 +482,8 @@
        stream->type = type;
        stream->controller = controller;
        stream->warn_count = 0;
+       stream->incorrect_position_count = 0;
+       stream->use_dma_position = true;
 
        switch (type) {
                case STREAM_PLAYBACK:


Other related posts:

  • » [haiku-commits] r34684 - haiku/trunk/src/add-ons/kernel/drivers/audio/hda - ingo_weinhold