r2283 - trunk/src/host/qemu-neo1973/hw
andrew at sita.openmoko.org
andrew at sita.openmoko.org
Sun Jun 17 03:19:49 CEST 2007
Author: andrew
Date: 2007-06-17 03:19:47 +0200 (Sun, 17 Jun 2007)
New Revision: 2283
Modified:
trunk/src/host/qemu-neo1973/hw/s3c2410.c
trunk/src/host/qemu-neo1973/hw/wm8753.c
Log:
Rewrite DMA queuing. Enhance buffering of audio data in WM8753.
Modified: trunk/src/host/qemu-neo1973/hw/s3c2410.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c2410.c 2007-06-16 15:23:39 UTC (rev 2282)
+++ trunk/src/host/qemu-neo1973/hw/s3c2410.c 2007-06-17 01:19:47 UTC (rev 2283)
@@ -696,7 +696,7 @@
} ch[S3C_DMA_CH_N];
};
-static void s3c_dma_ch_run(struct s3c_dma_state_s *s,
+static inline void s3c_dma_ch_run(struct s3c_dma_state_s *s,
struct s3c_dma_ch_state_s *ch)
{
int width, burst, t;
@@ -704,12 +704,12 @@
width = 1 << ((ch->con >> 20) & 3); /* DSZ */
burst = (ch->con & (1 << 28)) ? 4 : 1; /* TSZ */
- while (!ch->running && ch->req && (ch->mask & (1 << 1))) { /* ON_OFF */
+ while (!ch->running && ch->curr_tc > 0 && ch->req &&
+ (ch->mask & (1 << 1))) { /* ON_OFF */
if (width > sizeof(buffer)) {
printf("%s: wrong access width\n", __FUNCTION__);
return;
}
- ch->curr_tc = ch->con & 0xfffff; /* TC */
ch->running = 1;
while (ch->curr_tc --) {
for (t = 0; t < burst; t ++) {
@@ -726,24 +726,35 @@
break;
}
ch->running = 0;
- if (!ch->curr_tc && (ch->con & (1 << 29))) /* INT */
- qemu_irq_raise(ch->intr);
- if (ch->con & (1 << 22)) { /* RELOAD */
- if (!(ch->con & (1 << 23))) { /* SWHW_SEL */
- printf("%s: auto-reload software controlled transfer\n",
- __FUNCTION__);
+ if (!(ch->con & (1 << 23))) { /* SWHW_SEL */
+ ch->req = 0;
+ }
+
+ if (ch->curr_tc <= 0) {
+ if (ch->con & (1 << 22)) /* RELOAD */
+ ch->mask &= ~(1 << 1); /* ON_OFF */
+ else {
+ if (!(ch->con & (1 << 23))) { /* SWHW_SEL */
+ printf("%s: auto-reload software controlled transfer\n",
+ __FUNCTION__);
+ break;
+ }
+ ch->csrc = ch->isrc; /* S_ADDR */
+ ch->cdst = ch->idst; /* D_ADDR */
+ ch->curr_tc = ch->con & 0xfffff; /* TC */
+ ch->con |= 1 << 22; /* ON_OFF */
+ }
+
+ if (ch->con & (1 << 31)) /* DMD_HS */
+ ch->req = 0;
+
+ if (ch->con & (1 << 29)) { /* INT */
+ qemu_irq_raise(ch->intr);
+ /* Give the system a chance to respond. */
break;
}
- ch->csrc = ch->isrc; /* S_ADDR */
- ch->cdst = ch->idst; /* D_ADDR */
- ch->curr_tc = ch->con & 0xfffff; /* TC */
}
- if (!(ch->con & (1 << 23))) { /* SWHW_SEL */
- ch->req = 0;
- }
- if (!ch->curr_tc && !(ch->con & (1 << 22))) /* RELOAD */
- ch->mask &= ~(1 << 1); /* ON_OFF */
}
}
@@ -839,22 +850,27 @@
ch->con = value;
break;
case S3C_DISRC:
- ch->csrc = ch->isrc = value;
+ ch->isrc = value;
break;
case S3C_DISRCC:
ch->isrcc = value;
break;
case S3C_DIDST:
- ch->cdst = ch->idst = value;
+ ch->idst = value;
break;
case S3C_DIDSTC:
ch->idstc = value;
break;
case S3C_DMASKTRIG:
+ if (~ch->mask & value & (1 << 1)) { /* ON_OFF */
+ ch->curr_tc = ch->con & 0xfffff; /* TC */
+ ch->csrc = ch->isrc; /* S_ADDR */
+ ch->cdst = ch->idst; /* D_ADDR */
+ }
+
ch->mask = value;
if (value & (1 << 2)) { /* STOP */
- ch->curr_tc = 0;
- ch->mask &= ~(1 << 1); /* ON_OFF */
+ ch->mask &= ~(3 << 1); /* ON_OFF */
} else if (!(ch->con & (1 << 23))) { /* SWHW_SEL */
ch->req = value & 1; /* SW_TRIG */
s3c_dma_ch_run(s, ch);
Modified: trunk/src/host/qemu-neo1973/hw/wm8753.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/wm8753.c 2007-06-16 15:23:39 UTC (rev 2282)
+++ trunk/src/host/qemu-neo1973/hw/wm8753.c 2007-06-17 01:19:47 UTC (rev 2283)
@@ -74,10 +74,10 @@
static inline void wm8753_out_flush(struct wm8753_s *s)
{
- int sent;
- if (!s->idx_out)
- return;
- sent = AUD_write(*s->out[0], s->data_out, s->idx_out);
+ int sent = 0;
+ while (sent < s->idx_out)
+ sent += AUD_write(*s->out[0], s->data_out + sent, s->idx_out - sent)
+ ?: s->idx_out;
s->idx_out = 0;
}
@@ -91,10 +91,14 @@
static void wm8753_audio_out_cb(void *opaque, int free_b)
{
struct wm8753_s *s = (struct wm8753_s *) opaque;
- wm8753_out_flush(s);
+ if (s->idx_out >= free_b) {
+ s->idx_out = free_b;
+ s->req_out = 0;
+ wm8753_out_flush(s);
+ } else
+ s->req_out = free_b - s->idx_out;
- s->req_out = free_b;
- s->data_req(s->opaque, free_b >> 2, s->req_in >> 2);
+ s->data_req(s->opaque, s->req_out >> 2, s->req_in >> 2);
}
struct wm_rate_s {
More information about the commitlog
mailing list