Add A20 HDMI audio support. Basically the same as A31, except we need to use dedicated DMA mode here (A31 DMA controller only supports "normal DMA" mode).

This commit is contained in:
jmcneill 2014-11-12 17:38:14 +00:00
parent f55015c45a
commit 53e6b3723d
3 changed files with 51 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: awin_dma_a10.c,v 1.2 2014/10/26 15:07:33 jmcneill Exp $ */
/* $NetBSD: awin_dma_a10.c,v 1.3 2014/11/12 17:38:14 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca>
@ -29,7 +29,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: awin_dma_a10.c,v 1.2 2014/10/26 15:07:33 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: awin_dma_a10.c,v 1.3 2014/11/12 17:38:14 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -179,7 +179,8 @@ awin_dma_a10_alloc(struct awin_dma_softc *sc, const char *type,
uint32_t irqen;
uint8_t ch_count, index;
if (strcmp(type, "ddma") == 0) {
if (strcmp(type, "ddma") == 0 ||
strcmp(type, "hdmiaudio") == 0) {
ch_list = awin_ddma_channels;
ch_count = DDMA_CHANNELS;
} else {
@ -239,7 +240,11 @@ awin_dma_a10_get_config(void *priv)
{
struct awin_dma_a10_channel *ch = priv;
return DMACH_READ(ch, AWIN_NDMA_CTL_REG);
if (ch->ch_type == CH_NDMA) {
return DMACH_READ(ch, AWIN_NDMA_CTL_REG);
} else {
return DMACH_READ(ch, AWIN_DDMA_CTL_REG);
}
}
static void
@ -247,7 +252,11 @@ awin_dma_a10_set_config(void *priv, uint32_t val)
{
struct awin_dma_a10_channel *ch = priv;
DMACH_WRITE(ch, AWIN_NDMA_CTL_REG, val);
if (ch->ch_type == CH_NDMA) {
DMACH_WRITE(ch, AWIN_NDMA_CTL_REG, val);
} else {
DMACH_WRITE(ch, AWIN_DDMA_CTL_REG, val);
}
}
static int
@ -275,6 +284,11 @@ awin_dma_a10_transfer(void *priv, paddr_t src, paddr_t dst,
DMACH_WRITE(ch, AWIN_DDMA_SRC_START_ADDR_REG, src);
DMACH_WRITE(ch, AWIN_DDMA_DEST_START_ADDR_REG, dst);
DMACH_WRITE(ch, AWIN_DDMA_BC_REG, nbytes);
DMACH_WRITE(ch, AWIN_DDMA_PARA_REG,
__SHIFTIN(31, AWIN_DDMA_PARA_DST_DATA_BLK_SIZ) |
__SHIFTIN(7, AWIN_DDMA_PARA_DST_WAIT_CYC) |
__SHIFTIN(31, AWIN_DDMA_PARA_SRC_DATA_BLK_SIZ) |
__SHIFTIN(7, AWIN_DDMA_PARA_SRC_WAIT_CYC));
cfg |= AWIN_DDMA_CTL_DMA_LOADING;
awin_dma_a10_set_config(ch, cfg);

View File

@ -1,4 +1,4 @@
/* $NetBSD: awin_hdmi.c,v 1.9 2014/11/11 19:22:32 jmcneill Exp $ */
/* $NetBSD: awin_hdmi.c,v 1.10 2014/11/12 17:38:14 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca>
@ -32,7 +32,7 @@
#define AWIN_HDMI_PLL 3 /* PLL7 or PLL3 */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.9 2014/11/11 19:22:32 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: awin_hdmi.c,v 1.10 2014/11/12 17:38:14 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -681,7 +681,11 @@ awin_hdmi_set_audiomode(struct awin_hdmi_softc *sc,
/* DMA & FIFO control */
val = HDMI_READ(sc, AWIN_HDMI_ADMA_CTRL_REG);
val |= AWIN_HDMI_ADMA_CTRL_SRC_DMA_MODE; /* NDMA */
if (awin_chip_id() == AWIN_CHIP_ID_A31) {
val |= AWIN_HDMI_ADMA_CTRL_SRC_DMA_MODE; /* NDMA */
} else {
val &= ~AWIN_HDMI_ADMA_CTRL_SRC_DMA_MODE; /* DDMA */
}
val &= ~AWIN_HDMI_ADMA_CTRL_SRC_DMA_SAMPLE_RATE;
val &= ~AWIN_HDMI_ADMA_CTRL_SRC_SAMPLE_LAYOUT;
val &= ~AWIN_HDMI_ADMA_CTRL_SRC_WORD_LEN;

View File

@ -1,4 +1,4 @@
/* $NetBSD: awin_hdmiaudio.c,v 1.2 2014/11/11 17:14:38 jmcneill Exp $ */
/* $NetBSD: awin_hdmiaudio.c,v 1.3 2014/11/12 17:38:14 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca>
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: awin_hdmiaudio.c,v 1.2 2014/11/11 17:14:38 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: awin_hdmiaudio.c,v 1.3 2014/11/12 17:38:14 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -602,18 +602,33 @@ awin_hdmiaudio_trigger_output(void *priv, void *start, void *end, int blksize,
dmacfg = 0;
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_DATA_WIDTH_32,
AWIN_DMA_CTL_DST_DATA_WIDTH);
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_BURST_LEN_4,
AWIN_DMA_CTL_DST_BURST_LEN);
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_DATA_WIDTH_16,
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_DATA_WIDTH_32,
AWIN_DMA_CTL_SRC_DATA_WIDTH);
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_BURST_LEN_4,
AWIN_DMA_CTL_SRC_BURST_LEN);
dmacfg |= AWIN_DMA_CTL_BC_REMAINING;
dmacfg |= AWIN_NDMA_CTL_DST_ADDR_NOINCR;
dmacfg |= __SHIFTIN(sc->sc_drqtype_hdmiaudio,
AWIN_DMA_CTL_DST_DRQ_TYPE);
dmacfg |= __SHIFTIN(sc->sc_drqtype_sdram,
AWIN_DMA_CTL_SRC_DRQ_TYPE);
if (awin_chip_id() == AWIN_CHIP_ID_A31) {
/* NDMA */
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_BURST_LEN_4,
AWIN_DMA_CTL_DST_BURST_LEN);
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_BURST_LEN_4,
AWIN_DMA_CTL_SRC_BURST_LEN);
dmacfg |= AWIN_NDMA_CTL_DST_ADDR_NOINCR;
dmacfg |= __SHIFTIN(sc->sc_drqtype_hdmiaudio,
AWIN_DMA_CTL_DST_DRQ_TYPE);
} else {
/* DDMA */
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_BURST_LEN_8,
AWIN_DMA_CTL_DST_BURST_LEN);
dmacfg |= __SHIFTIN(AWIN_DMA_CTL_BURST_LEN_8,
AWIN_DMA_CTL_SRC_BURST_LEN);
dmacfg |= __SHIFTIN(AWIN_DDMA_CTL_DMA_ADDR_IO,
AWIN_DDMA_CTL_DST_ADDR_MODE);
dmacfg |= __SHIFTIN(AWIN_DDMA_CTL_DMA_ADDR_LINEAR,
AWIN_DDMA_CTL_SRC_ADDR_MODE);
dmacfg |= __SHIFTIN(sc->sc_drqtype_hdmiaudio,
AWIN_DDMA_CTL_DST_DRQ_TYPE);
}
awin_dma_set_config(sc->sc_pdma, dmacfg);
error = awin_hdmiaudio_play(sc);