From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Benjamin Berg <benjamin@sipsolutions.net>
Cc: linuxppc-dev@ozlabs.org, debian-powerpc@lists.debian.org,
charles-debian-nospam@plessy.org
Subject: Re: snd-aoa status update / automatic driver loading
Date: Sun, 21 May 2006 09:59:46 +1000 [thread overview]
Message-ID: <1148169587.13249.48.camel@localhost.localdomain> (raw)
In-Reply-To: <1148137032.3407.12.camel@localhost>
On Sat, 2006-05-20 at 16:57 +0200, Benjamin Berg wrote:
> On Thu, 2006-18-05 at 09:41 +0900, Charles Plessy wrote:
> > Hi all,
> >
> > just a "me too" mail:
> >
> > Le Thu, May 18, 2006 at 12:02:01AM +0200, Børge Holen a écrit :
> > > I can also remember half way throught a ogg/mp3 playlist when it also
> > > scrambled the output, this has only happened ONCE.
> >
> > I experience the same on my 8,1 powermac, but more systematically. It
> > takes usually more than one hour of continuous listening before it
> > happens, and then it happens sort of stochastically. I am not using
> > anything else than xmms, so I did not figure out if it is a xmms or a
> > driver problem. Stop/Starting the listening stops the scrambling.
>
> This is exactly the problem that I have experienced since a while now.
> The problem is that some interrupts get lost. This results in a broken
> address calculation and the new data is written to the wrong place.
See my other mail about that. Worth tracking down. As far as the DBDMA
handling is concerned, I think walking the descriptors and harvesting
status bits is a better approach as it also allows you to get error
status if you ever get any. Now, if you can have some reliable frame
counter, that's definitely something to look into passing userland too.
> The attached patch fixes this by checking the 'frame_count'.
> What I don't really understand is, that the first time the interrupt
> gets executed, the frame_count is 8 _less_ of what I would have expected
> My guess is that the dma controller reads the last 32 bytes, and then
> the interrupt gets fired.
The DBDMA definitely has a fifo. By the time you get the IRQ, it may
have started pumping the "next" packet. 32 bytes sounds about right for
the DBDMA fifo... old DBDMAs had 16 bits iirc but I could imagine Apple
improving that.
> diff --git a/soundbus/i2sbus/i2sbus-pcm.c b/soundbus/i2sbus/i2sbus-pcm.c
> index 9eadf83..8511234 100644
> --- a/soundbus/i2sbus/i2sbus-pcm.c
> +++ b/soundbus/i2sbus/i2sbus-pcm.c
> @@ -440,6 +440,11 @@ static int i2sbus_pcm_trigger(struct i2s
> return -ENXIO;
> }
>
> + /* get the current frame_count - 32 bytes. This is just guessed,
> + but it seems that the interrupt triggers as soon as the last 32 bytes
> + are cached or something. */
> + pi->frame_count = in_le32(&i2sdev->intfregs->frame_count) - 0x20 / (pi->substream->runtime->sample_bits / 8);
> +
> /* wake up the chip with the next descriptor */
> out_le32(&pi->dbdma->control, (RUN|WAKE) | ((RUN|WAKE)<<16));
> /* off you go! */
> @@ -488,13 +493,29 @@ static snd_pcm_uframes_t i2sbus_pcm_poin
> static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
> {
> struct pcm_info *pi;
> + u32 fc;
> + u32 delta;
>
> get_pcm_info(i2sdev, in, &pi, NULL);
> if (!pi->substream) {
> printk(KERN_INFO "i2sbus: got %s irq while not active!\n", in?"rx":"tx");
> return;
> }
> - pi->current_period = (pi->current_period+1) % (pi->periods);
> +
> + fc = in_le32(&i2sdev->intfregs->frame_count);
> + /* a counter overflow does not change the calculation. */
> + delta = fc - pi->frame_count;
> +
> + if (delta <= pi->substream->runtime->period_size) {
> + pi->current_period = pi->current_period + 1;
> + delta = 0;
> + } else while (delta >= pi->substream->runtime->period_size) {
> + pi->current_period = pi->current_period + 1;
> + delta = delta - pi->substream->runtime->period_size;
> + }
> +
> + pi->frame_count = fc - delta;
> + pi->current_period = pi->current_period % pi->periods;
> snd_pcm_period_elapsed(pi->substream);
> }
>
> diff --git a/soundbus/i2sbus/i2sbus.h b/soundbus/i2sbus/i2sbus.h
> index b054e02..f5d16aa 100644
> --- a/soundbus/i2sbus/i2sbus.h
> +++ b/soundbus/i2sbus/i2sbus.h
> @@ -41,6 +41,7 @@ struct pcm_info {
> struct snd_pcm_substream *substream;
> int current_period;
> int periods;
> + u32 frame_count;
> struct dbdma_command_mem dbdma_ring;
> volatile struct dbdma_regs __iomem *dbdma;
> };
>
>
next prev parent reply other threads:[~2006-05-21 0:00 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-17 10:09 snd-aoa status update / automatic driver loading Johannes Berg
2006-05-17 18:57 ` Tony Vroon
2006-05-19 10:22 ` Johannes Berg
2006-05-20 23:56 ` Benjamin Herrenschmidt
2006-05-22 6:42 ` Johannes Berg
2006-05-23 22:15 ` Benjamin Herrenschmidt
2006-05-24 9:42 ` Johannes Berg
2006-05-25 8:00 ` Benjamin Herrenschmidt
2006-05-25 9:42 ` Johannes Berg
2006-05-26 1:30 ` Benjamin Herrenschmidt
2006-05-17 19:53 ` Andreas Schwab
2006-05-18 10:14 ` Johannes Berg
2006-05-17 21:54 ` Wolfgang Pfeiffer
2006-05-17 22:19 ` Wolfgang Pfeiffer
2006-05-18 10:13 ` Johannes Berg
2006-05-18 18:17 ` Wolfgang Pfeiffer
2006-05-18 22:06 ` Andreas Schwab
2006-05-19 12:50 ` Johannes Berg
2006-05-19 14:40 ` Wolfgang Pfeiffer
2006-05-19 14:40 ` Johannes Berg
2006-05-17 22:30 ` Dean Hamstead
2006-05-18 0:28 ` Wolfgang Pfeiffer
2006-05-18 0:39 ` Dean Hamstead
2006-05-18 1:01 ` Wolfgang Pfeiffer
2006-05-18 1:08 ` Benjamin Herrenschmidt
2006-05-18 7:25 ` Eddy Petrişor
2006-05-18 10:23 ` Johannes Berg
2006-05-19 13:20 ` Paul Collins
2006-05-19 13:46 ` Johannes Berg
2006-05-19 14:40 ` Paul Collins
2006-05-19 14:49 ` Johannes Berg
2006-05-19 15:13 ` Paul Collins
2006-05-19 14:33 ` Andreas Schwab
2006-05-19 14:37 ` Johannes Berg
2006-05-23 15:41 ` Sjoerd Simons
2006-05-25 7:21 ` Eddy Petrişor
2006-05-25 7:21 ` Eddy Petrişor
2006-05-25 9:43 ` Johannes Berg
2006-05-25 17:44 ` Eddy Petrişor
2006-05-25 18:47 ` Johannes Berg
2006-05-18 8:56 ` Rene Rebe
2006-05-18 10:08 ` Johannes Berg
[not found] ` <200605180002.01669.borge@arivene.net>
[not found] ` <20060518004141.GC1552@kunpuu.plessy.org>
2006-05-20 14:57 ` Benjamin Berg
2006-05-20 23:59 ` Benjamin Herrenschmidt [this message]
2006-05-23 3:11 ` Hollis Blanchard
2006-05-23 12:27 ` Johannes Berg
2006-05-23 14:46 ` Hollis Blanchard
2006-05-23 15:25 ` Hollis Blanchard
2006-05-24 9:41 ` Johannes Berg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1148169587.13249.48.camel@localhost.localdomain \
--to=benh@kernel.crashing.org \
--cc=benjamin@sipsolutions.net \
--cc=charles-debian-nospam@plessy.org \
--cc=debian-powerpc@lists.debian.org \
--cc=linuxppc-dev@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).