Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x68k/dev - Revert temporary local conversion introd...



details:   https://anonhg.NetBSD.org/src/rev/fcc88cc86368
branches:  trunk
changeset: 826412:fcc88cc86368
user:      isaki <isaki%NetBSD.org@localhost>
date:      Sat Sep 02 12:52:55 2017 +0000

description:
- Revert temporary local conversion introduced at rev 1.43.
- But does not revert to trigger method.  trigger method is not suitable for
  x68k ADPCM+DMA mechanism.
- Don't (re)start ADPCM when DMA is running.  This solves the noise.
  From Y.Sugahara.
- Cache dmac xfer.

diffstat:

 sys/arch/x68k/dev/vs.c    |  169 ++++++++++++++++++++-------------------------
 sys/arch/x68k/dev/vsvar.h |   15 +---
 2 files changed, 77 insertions(+), 107 deletions(-)

diffs (truncated from 354 to 300 lines):

diff -r 6d584410bd75 -r fcc88cc86368 sys/arch/x68k/dev/vs.c
--- a/sys/arch/x68k/dev/vs.c    Sat Sep 02 12:24:39 2017 +0000
+++ b/sys/arch/x68k/dev/vs.c    Sat Sep 02 12:52:55 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vs.c,v 1.46 2017/08/11 07:08:40 isaki Exp $    */
+/*     $NetBSD: vs.c,v 1.47 2017/09/02 12:52:55 isaki Exp $    */
 
 /*
  * Copyright (c) 2001 Tetsuya Isaki. All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.46 2017/08/11 07:08:40 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vs.c,v 1.47 2017/09/02 12:52:55 isaki Exp $");
 
 #include "audio.h"
 #include "vs.h"
@@ -101,7 +101,6 @@
 static int vs_round_sr(u_long);
 static void vs_set_sr(struct vs_softc *, int);
 static inline void vs_set_po(struct vs_softc *, u_long);
-static void *vs_realloc_hwbuf(struct vs_softc *, int);
 
 extern struct cfdriver vs_cd;
 
@@ -130,8 +129,8 @@
        vs_set_port,
        vs_get_port,
        vs_query_devinfo,
-       NULL,                   /* allocm */
-       NULL,                   /* freem */
+       vs_allocm,
+       vs_freem,
        vs_round_buffersize,
        NULL,                   /* mappage */
        vs_get_props,
@@ -161,6 +160,8 @@
 
 #define NUM_RATE       (sizeof(vs_l2r)/sizeof(vs_l2r[0]))
 
+extern stream_filter_factory_t null_filter;
+
 static int
 vs_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -220,10 +221,8 @@
        sc->sc_hw_if = &vs_hw_if;
        sc->sc_addr = (void *) ia->ia_addr;
        sc->sc_dmas = NULL;
+       sc->sc_prev_vd = NULL;
        sc->sc_active = 0;
-       sc->sc_hwbuf = NULL;
-       sc->sc_hwbufsize = 0;
-       sc->sc_codec = vs_alloc_msm6258codec();
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
 
@@ -257,13 +256,9 @@
 
        mutex_spin_enter(&sc->sc_intr_lock);
 
-       sc->sc_active = 0;
        if (sc->sc_pintr) {
                sc->sc_pintr(sc->sc_parg);
        } else if (sc->sc_rintr) {
-               /* convert ADPCM to slinear */
-               sc->sc_rconv(sc->sc_codec, sc->sc_current.rblock,
-                   sc->sc_current.blksize, sc->sc_hwbuf);
                sc->sc_rintr(sc->sc_rarg);
        } else {
                printf("vs_dmaintr: spurious interrupt\n");
@@ -301,6 +296,7 @@
        sc = hdl;
        sc->sc_pintr = NULL;
        sc->sc_rintr = NULL;
+       sc->sc_active = 0;
 
        return 0;
 }
@@ -369,6 +365,8 @@
        stream_filter_list_t *pfil, stream_filter_list_t *rfil)
 {
        struct vs_softc *sc;
+       stream_filter_factory_t *pconv;
+       stream_filter_factory_t *rconv;
        int rate;
 
        sc = hdl;
@@ -391,16 +389,12 @@
        }
 
        if (play->precision == 8 && play->encoding == AUDIO_ENCODING_SLINEAR) {
-               sc->sc_current.precision = 8;
-               sc->sc_pconv = vs_slinear8_to_adpcm;
-               sc->sc_rconv = vs_adpcm_to_slinear8;
-
+               pconv = msm6258_linear8_to_adpcm;
+               rconv = msm6258_adpcm_to_linear8;
        } else if (play->precision == 16 &&
                   play->encoding == AUDIO_ENCODING_SLINEAR_BE) {
-               sc->sc_current.precision = 16;
-               sc->sc_pconv = vs_slinear16be_to_adpcm;
-               sc->sc_rconv = vs_adpcm_to_slinear16be;
-
+               pconv = msm6258_slinear16_to_adpcm;
+               rconv = msm6258_adpcm_to_slinear16;
        } else {
                DPRINTF(1, ("prec/enc not matched\n"));
                return EINVAL;
@@ -410,11 +404,20 @@
 
        /* pfil and rfil are independent even if !AUDIO_PROP_INDEPENDENT */
 
-       /*
-        * XXX MI audio(4) layer does not seem to support non SLINEAR devices.
-        * So vs(4) behaves as SLINEAR device completely against MI layer
-        * and converts SLINEAR <-> ADPCM by myself.
-        */
+       if ((setmode & AUMODE_PLAY) != 0) {
+               pfil->append(pfil, null_filter, play);
+               play->encoding = AUDIO_ENCODING_ADPCM;
+               play->validbits = 4;
+               play->precision = 4;
+               pfil->append(pfil, pconv, play);
+       }
+       if ((setmode & AUMODE_RECORD) != 0) {
+               rfil->append(rfil, null_filter, rec);
+               rec->encoding = AUDIO_ENCODING_ADPCM;
+               rec->validbits = 4;
+               rec->precision = 4;
+               rfil->append(rfil, rconv, rec);
+       }
 
        DPRINTF(1, ("accepted\n"));
        return 0;
@@ -470,22 +473,6 @@
        return 0;
 }
 
-/* (re)allocate sc_hwbuf with hwbufsize */
-static void *
-vs_realloc_hwbuf(struct vs_softc *sc, int hwbufsize)
-{
-       if (sc->sc_hwbuf != NULL) {
-               vs_freem(sc, sc->sc_hwbuf, sc->sc_hwbufsize);
-       }
-       sc->sc_hwbufsize = hwbufsize;
-       sc->sc_hwbuf = vs_allocm(sc, 0, sc->sc_hwbufsize);
-       if (sc->sc_hwbuf == NULL) {
-               sc->sc_hwbufsize = 0;
-               return NULL;
-       }
-       return sc->sc_hwbuf;
-}
-
 static int
 vs_start_output(void *hdl, void *block, int blksize, void (*intr)(void *),
        void *arg)
@@ -493,42 +480,40 @@
        struct vs_softc *sc;
        struct vs_dma *vd;
        struct dmac_channel_stat *chan;
-       int hwblksize;
 
        DPRINTF(2, ("%s: block=%p blksize=%d\n", __func__, block, blksize));
        sc = hdl;
 
-       hwblksize = blksize / (sc->sc_current.precision / 4);
-       if (hwblksize > sc->sc_hwbufsize) {
-               if (vs_realloc_hwbuf(sc, hwblksize) == NULL) {
-                       DPRINTF(1, ("%s: alloc hwbuf failed\n", __func__));
-                       return ENOMEM;
-               }
-       }
-
-       /* Convert slinear to ADPCM */
-       sc->sc_pconv(sc->sc_codec, sc->sc_hwbuf, block, blksize);
-
        sc->sc_pintr = intr;
        sc->sc_parg  = arg;
-       sc->sc_current.blksize = hwblksize;
-       sc->sc_current.bufsize = hwblksize;
-       sc->sc_current.dmap = 0;
 
-       /* vd is always first of sc_dmas */
-       vd = sc->sc_dmas;
+       /* Find DMA buffer. */
+       for (vd = sc->sc_dmas; vd != NULL; vd = vd->vd_next) {
+               if (KVADDR(vd) <= block && block < KVADDR_END(vd)
+                       break;
+       }
+       if (vd == NULL) {
+               printf("%s: start_output: bad addr %p\n",
+                   device_xname(sc->sc_dev), block);
+               return EINVAL;
+       }
 
        chan = sc->sc_dma_ch;
 
-       sc->sc_current.xfer = dmac_prepare_xfer(chan, sc->sc_dmat, vd->vd_map,
-           DMAC_OCR_DIR_MTD,
-           (DMAC_SCR_MAC_COUNT_UP | DMAC_SCR_DAC_NO_COUNT),
-           sc->sc_addr + MSM6258_DATA * 2 + 1);
+       if (vd != sc->sc_prev_vd) {
+               sc->sc_current.xfer = dmac_prepare_xfer(chan, sc->sc_dmat,
+                   vd->vd_map, DMAC_OCR_DIR_MTD,
+                   (DMAC_SCR_MAC_COUNT_UP | DMAC_SCR_DAC_NO_COUNT),
+                   sc->sc_addr + MSM6258_DATA * 2 + 1);
+               sc->sc_prev_vd = vd;
+       }
+       dmac_start_xfer_offset(chan->ch_softc, sc->sc_current.xfer,
+           (int)block - (int)KVADDR(vd), blksize);
 
-       dmac_start_xfer_offset(chan->ch_softc, sc->sc_current.xfer, 0,
-           sc->sc_current.blksize);
-       bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSM6258_STAT, 2);
-       sc->sc_active = 1;
+       if (sc->sc_active == 0) {
+               bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSM6258_STAT, 2);
+               sc->sc_active = 1;
+       }
 
        return 0;
 }
@@ -540,40 +525,40 @@
        struct vs_softc *sc;
        struct vs_dma *vd;
        struct dmac_channel_stat *chan;
-       int hwblksize;
 
        DPRINTF(2, ("%s: block=%p blksize=%d\n", __func__, block, blksize));
        sc = hdl;
 
-       hwblksize = blksize / (sc->sc_current.precision / 4);
-       if (hwblksize > sc->sc_hwbufsize) {
-               if (vs_realloc_hwbuf(sc, hwblksize) == NULL) {
-                       DPRINTF(1, ("%s: alloc hwbuf failed\n", __func__));
-                       return ENOMEM;
-               }
-       }
-
        sc->sc_rintr = intr;
        sc->sc_rarg  = arg;
-       sc->sc_current.rblock = block;
-       sc->sc_current.blksize = hwblksize;
-       sc->sc_current.bufsize = hwblksize;
-       sc->sc_current.dmap = 0;
 
-       /* vd is always first of sc_dmas */
-       vd = sc->sc_dmas;
+       /* Find DMA buffer. */
+       for (vd = sc->sc_dmas; vd != NULL; vd = vd->vd_next) {
+               if (KVADDR(vd) <= block && block < KVADDR_END(vd)
+                       break;
+       }
+       if (vd == NULL) {
+               printf("%s: start_output: bad addr %p\n",
+                   device_xname(sc->sc_dev), block);
+               return EINVAL;
+       }
 
        chan = sc->sc_dma_ch;
 
-       sc->sc_current.xfer = dmac_prepare_xfer(chan, sc->sc_dmat, vd->vd_map,
-           DMAC_OCR_DIR_DTM,
-           (DMAC_SCR_MAC_COUNT_UP | DMAC_SCR_DAC_NO_COUNT),
-           sc->sc_addr + MSM6258_DATA * 2 + 1);
+       if (vd != sc->sc_prev_vd) {
+               sc->sc_current.xfer = dmac_prepare_xfer(chan, sc->sc_dmat,
+                   vd->vd_map, DMAC_OCR_DIR_DTM,
+                   (DMAC_SCR_MAC_COUNT_UP | DMAC_SCR_DAC_NO_COUNT),
+                   sc->sc_addr + MSM6258_DATA * 2 + 1);
+               sc->sc_prev_vd = vd;
+       }
+       dmac_start_xfer_offset(chan->ch_softc, sc->sc_current.xfer,
+           (int)block - (int)KVADDR(vd), blksize);
 
-       dmac_start_xfer_offset(chan->ch_softc, sc->sc_current.xfer, 0,
-           sc->sc_current.blksize);
-       bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSM6258_STAT, 4);
-       sc->sc_active = 1;
+       if (sc->sc_active == 0) {
+               bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSM6258_STAT, 4);
+               sc->sc_active = 1;
+       }
 
        return 0;
 }
@@ -591,9 +576,6 @@
                bus_space_write_1(sc->sc_iot, sc->sc_ioh, MSM6258_STAT, 1);
                sc->sc_active = 0;
        }
-       vs_freem(sc, sc->sc_hwbuf, sc->sc_hwbufsize);
-       sc->sc_hwbuf = NULL;
-       sc->sc_hwbufsize = 0;
 
        return 0;
 }
@@ -611,9 +593,6 @@



Home | Main Index | Thread Index | Old Index