mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-22 09:22:37 +00:00
arm-soc: samsung dma changes
Some platforms are not yet converted to use the dmaengine framework, including some of the samsung SoCs. In the meantime, we treat this as platform code and merge the patches through the arm-soc tree. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIVAwUAUA2da2CrR//JCVInAQIwehAA3GPguLehDaYaySrPWJYWlE1IKBrQJA+u MIsUBo8wEzd6Hz5XiKG8s6HvplZn6bhEjVESFTuIwaDWaBSAw1npLYZ4gHE3wVvZ msHLkeqwwCbBnnUkRUDoF/S2nONjgItgsndpNu9ejXaUNZ3Cw2lHsECptd/v+LEN hggF9WebKSaQ6XP2nDLy0R2VH/6EgJnF3Ubq/kP9LvtOpW/LH8s8PcCZHbnlKzNN nTnA6VMt2wwAyLGLn7O9n9OCOWwcOOcaJEBTJ3g7o0DnAFtWm9UV0vKF4yKu+THV h+eaY8f29PFPrY6zs/qcaBxXm7nSNZP1R+ZPtymRyHe+7Mas7DVAhCz5M0hcftae I8bM8zVpQkNiVn1TBY+8XBA0vsJg6AIS20XfMgEO93RtyZKCI94ZFoGq+N+6akPi vMU8GIoMKiAyTlCS4EdEQbYvPlAyiwJxUz//nc+HWf3qp87gYDKkSC1NmLDiRRCg GtDjPX+WRtjHC0esqFMGfcXkN60X/daIA1RWESH6z51H8qw26yapeEs5oTaG9HSo dtkn/lUGn8aax1obRamb8mlTOaPZOAjyhIWRx2ubMMZ8XFyZB5NxkszNo/jdlVQk 3tIwT+p34zmEEe+iTiGrsFUDAFNIXn5rPixJVBjBZzaxRgrL065cdG+gmbEjfgQ+ ThKU/fbxmM4= =/JNK -----END PGP SIGNATURE----- Merge tag 'dma' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull samsung arm-soc dma changes from Arnd Bergmann: "Some platforms are not yet converted to use the dmaengine framework, including some of the samsung SoCs. In the meantime, we treat this as platform code and merge the patches through the arm-soc tree." * tag 'dma' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: ARM: SAMSUNG: Fix compiler warning in dma-ops.c file ASoC: follow the updated samsung DMA common operations spi/s3c64xx: Add the use of DMA config operation ARM: SAMSUNG: Add config() function in DMA common operations
This commit is contained in:
commit
e66d637134
@ -19,72 +19,79 @@
|
||||
#include <mach/dma.h>
|
||||
|
||||
static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
|
||||
struct samsung_dma_info *info)
|
||||
struct samsung_dma_req *param)
|
||||
{
|
||||
struct dma_chan *chan;
|
||||
dma_cap_mask_t mask;
|
||||
struct dma_slave_config slave_config;
|
||||
void *filter_param;
|
||||
|
||||
dma_cap_zero(mask);
|
||||
dma_cap_set(info->cap, mask);
|
||||
dma_cap_set(param->cap, mask);
|
||||
|
||||
/*
|
||||
* If a dma channel property of a device node from device tree is
|
||||
* specified, use that as the fliter parameter.
|
||||
*/
|
||||
filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
|
||||
(void *)dma_ch;
|
||||
chan = dma_request_channel(mask, pl330_filter, filter_param);
|
||||
|
||||
if (info->direction == DMA_DEV_TO_MEM) {
|
||||
memset(&slave_config, 0, sizeof(struct dma_slave_config));
|
||||
slave_config.direction = info->direction;
|
||||
slave_config.src_addr = info->fifo;
|
||||
slave_config.src_addr_width = info->width;
|
||||
slave_config.src_maxburst = 1;
|
||||
dmaengine_slave_config(chan, &slave_config);
|
||||
} else if (info->direction == DMA_MEM_TO_DEV) {
|
||||
memset(&slave_config, 0, sizeof(struct dma_slave_config));
|
||||
slave_config.direction = info->direction;
|
||||
slave_config.dst_addr = info->fifo;
|
||||
slave_config.dst_addr_width = info->width;
|
||||
slave_config.dst_maxburst = 1;
|
||||
dmaengine_slave_config(chan, &slave_config);
|
||||
}
|
||||
|
||||
return (unsigned)chan;
|
||||
filter_param = (dma_ch == DMACH_DT_PROP) ?
|
||||
(void *)param->dt_dmach_prop : (void *)dma_ch;
|
||||
return (unsigned)dma_request_channel(mask, pl330_filter, filter_param);
|
||||
}
|
||||
|
||||
static int samsung_dmadev_release(unsigned ch,
|
||||
struct s3c2410_dma_client *client)
|
||||
static int samsung_dmadev_release(unsigned ch, void *param)
|
||||
{
|
||||
dma_release_channel((struct dma_chan *)ch);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int samsung_dmadev_config(unsigned ch,
|
||||
struct samsung_dma_config *param)
|
||||
{
|
||||
struct dma_chan *chan = (struct dma_chan *)ch;
|
||||
struct dma_slave_config slave_config;
|
||||
|
||||
if (param->direction == DMA_DEV_TO_MEM) {
|
||||
memset(&slave_config, 0, sizeof(struct dma_slave_config));
|
||||
slave_config.direction = param->direction;
|
||||
slave_config.src_addr = param->fifo;
|
||||
slave_config.src_addr_width = param->width;
|
||||
slave_config.src_maxburst = 1;
|
||||
dmaengine_slave_config(chan, &slave_config);
|
||||
} else if (param->direction == DMA_MEM_TO_DEV) {
|
||||
memset(&slave_config, 0, sizeof(struct dma_slave_config));
|
||||
slave_config.direction = param->direction;
|
||||
slave_config.dst_addr = param->fifo;
|
||||
slave_config.dst_addr_width = param->width;
|
||||
slave_config.dst_maxburst = 1;
|
||||
dmaengine_slave_config(chan, &slave_config);
|
||||
} else {
|
||||
pr_warn("unsupported direction\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int samsung_dmadev_prepare(unsigned ch,
|
||||
struct samsung_dma_prep_info *info)
|
||||
struct samsung_dma_prep *param)
|
||||
{
|
||||
struct scatterlist sg;
|
||||
struct dma_chan *chan = (struct dma_chan *)ch;
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
|
||||
switch (info->cap) {
|
||||
switch (param->cap) {
|
||||
case DMA_SLAVE:
|
||||
sg_init_table(&sg, 1);
|
||||
sg_dma_len(&sg) = info->len;
|
||||
sg_set_page(&sg, pfn_to_page(PFN_DOWN(info->buf)),
|
||||
info->len, offset_in_page(info->buf));
|
||||
sg_dma_address(&sg) = info->buf;
|
||||
sg_dma_len(&sg) = param->len;
|
||||
sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)),
|
||||
param->len, offset_in_page(param->buf));
|
||||
sg_dma_address(&sg) = param->buf;
|
||||
|
||||
desc = dmaengine_prep_slave_sg(chan,
|
||||
&sg, 1, info->direction, DMA_PREP_INTERRUPT);
|
||||
&sg, 1, param->direction, DMA_PREP_INTERRUPT);
|
||||
break;
|
||||
case DMA_CYCLIC:
|
||||
desc = dmaengine_prep_dma_cyclic(chan,
|
||||
info->buf, info->len, info->period, info->direction);
|
||||
desc = dmaengine_prep_dma_cyclic(chan, param->buf,
|
||||
param->len, param->period, param->direction);
|
||||
break;
|
||||
default:
|
||||
dev_err(&chan->dev->device, "unsupported format\n");
|
||||
@ -96,8 +103,8 @@ static int samsung_dmadev_prepare(unsigned ch,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
desc->callback = info->fp;
|
||||
desc->callback_param = info->fp_param;
|
||||
desc->callback = param->fp;
|
||||
desc->callback_param = param->fp_param;
|
||||
|
||||
dmaengine_submit((struct dma_async_tx_descriptor *)desc);
|
||||
|
||||
@ -119,6 +126,7 @@ static inline int samsung_dmadev_flush(unsigned ch)
|
||||
static struct samsung_dma_ops dmadev_ops = {
|
||||
.request = samsung_dmadev_request,
|
||||
.release = samsung_dmadev_release,
|
||||
.config = samsung_dmadev_config,
|
||||
.prepare = samsung_dmadev_prepare,
|
||||
.trigger = samsung_dmadev_trigger,
|
||||
.started = NULL,
|
||||
|
@ -16,7 +16,13 @@
|
||||
#include <linux/dmaengine.h>
|
||||
#include <mach/dma.h>
|
||||
|
||||
struct samsung_dma_prep_info {
|
||||
struct samsung_dma_req {
|
||||
enum dma_transaction_type cap;
|
||||
struct property *dt_dmach_prop;
|
||||
struct s3c2410_dma_client *client;
|
||||
};
|
||||
|
||||
struct samsung_dma_prep {
|
||||
enum dma_transaction_type cap;
|
||||
enum dma_transfer_direction direction;
|
||||
dma_addr_t buf;
|
||||
@ -26,19 +32,17 @@ struct samsung_dma_prep_info {
|
||||
void *fp_param;
|
||||
};
|
||||
|
||||
struct samsung_dma_info {
|
||||
enum dma_transaction_type cap;
|
||||
struct samsung_dma_config {
|
||||
enum dma_transfer_direction direction;
|
||||
enum dma_slave_buswidth width;
|
||||
dma_addr_t fifo;
|
||||
struct s3c2410_dma_client *client;
|
||||
struct property *dt_dmach_prop;
|
||||
};
|
||||
|
||||
struct samsung_dma_ops {
|
||||
unsigned (*request)(enum dma_ch ch, struct samsung_dma_info *info);
|
||||
int (*release)(unsigned ch, struct s3c2410_dma_client *client);
|
||||
int (*prepare)(unsigned ch, struct samsung_dma_prep_info *info);
|
||||
unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param);
|
||||
int (*release)(unsigned ch, void *param);
|
||||
int (*config)(unsigned ch, struct samsung_dma_config *param);
|
||||
int (*prepare)(unsigned ch, struct samsung_dma_prep *param);
|
||||
int (*trigger)(unsigned ch);
|
||||
int (*started)(unsigned ch);
|
||||
int (*flush)(unsigned ch);
|
||||
|
@ -36,30 +36,26 @@ static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
|
||||
}
|
||||
|
||||
static unsigned s3c_dma_request(enum dma_ch dma_ch,
|
||||
struct samsung_dma_info *info)
|
||||
struct samsung_dma_req *param)
|
||||
{
|
||||
struct cb_data *data;
|
||||
|
||||
if (s3c2410_dma_request(dma_ch, info->client, NULL) < 0) {
|
||||
s3c2410_dma_free(dma_ch, info->client);
|
||||
if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) {
|
||||
s3c2410_dma_free(dma_ch, param->client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (param->cap == DMA_CYCLIC)
|
||||
s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
|
||||
|
||||
data = kzalloc(sizeof(struct cb_data), GFP_KERNEL);
|
||||
data->ch = dma_ch;
|
||||
list_add_tail(&data->node, &dma_list);
|
||||
|
||||
s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo);
|
||||
|
||||
if (info->cap == DMA_CYCLIC)
|
||||
s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
|
||||
|
||||
s3c2410_dma_config(dma_ch, info->width);
|
||||
|
||||
return (unsigned)dma_ch;
|
||||
}
|
||||
|
||||
static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client)
|
||||
static int s3c_dma_release(unsigned ch, void *param)
|
||||
{
|
||||
struct cb_data *data;
|
||||
|
||||
@ -68,16 +64,24 @@ static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client)
|
||||
break;
|
||||
list_del(&data->node);
|
||||
|
||||
s3c2410_dma_free(ch, client);
|
||||
s3c2410_dma_free(ch, param);
|
||||
kfree(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info)
|
||||
static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param)
|
||||
{
|
||||
s3c2410_dma_devconfig(ch, param->direction, param->fifo);
|
||||
s3c2410_dma_config(ch, param->width);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param)
|
||||
{
|
||||
struct cb_data *data;
|
||||
int len = (info->cap == DMA_CYCLIC) ? info->period : info->len;
|
||||
int len = (param->cap == DMA_CYCLIC) ? param->period : param->len;
|
||||
|
||||
list_for_each_entry(data, &dma_list, node)
|
||||
if (data->ch == ch)
|
||||
@ -85,11 +89,11 @@ static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info)
|
||||
|
||||
if (!data->fp) {
|
||||
s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb);
|
||||
data->fp = info->fp;
|
||||
data->fp_param = info->fp_param;
|
||||
data->fp = param->fp;
|
||||
data->fp_param = param->fp_param;
|
||||
}
|
||||
|
||||
s3c2410_dma_enqueue(ch, (void *)data, info->buf, len);
|
||||
s3c2410_dma_enqueue(ch, (void *)data, param->buf, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -117,6 +121,7 @@ static inline int s3c_dma_stop(unsigned ch)
|
||||
static struct samsung_dma_ops s3c_dma_ops = {
|
||||
.request = s3c_dma_request,
|
||||
.release = s3c_dma_release,
|
||||
.config = s3c_dma_config,
|
||||
.prepare = s3c_dma_prepare,
|
||||
.trigger = s3c_dma_trigger,
|
||||
.started = s3c_dma_started,
|
||||
|
@ -262,14 +262,24 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
|
||||
unsigned len, dma_addr_t buf)
|
||||
{
|
||||
struct s3c64xx_spi_driver_data *sdd;
|
||||
struct samsung_dma_prep_info info;
|
||||
struct samsung_dma_prep info;
|
||||
struct samsung_dma_config config;
|
||||
|
||||
if (dma->direction == DMA_DEV_TO_MEM)
|
||||
if (dma->direction == DMA_DEV_TO_MEM) {
|
||||
sdd = container_of((void *)dma,
|
||||
struct s3c64xx_spi_driver_data, rx_dma);
|
||||
else
|
||||
config.direction = sdd->rx_dma.direction;
|
||||
config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
|
||||
config.width = sdd->cur_bpw / 8;
|
||||
sdd->ops->config(sdd->rx_dma.ch, &config);
|
||||
} else {
|
||||
sdd = container_of((void *)dma,
|
||||
struct s3c64xx_spi_driver_data, tx_dma);
|
||||
config.direction = sdd->tx_dma.direction;
|
||||
config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
|
||||
config.width = sdd->cur_bpw / 8;
|
||||
sdd->ops->config(sdd->tx_dma.ch, &config);
|
||||
}
|
||||
|
||||
info.cap = DMA_SLAVE;
|
||||
info.len = len;
|
||||
@ -284,20 +294,15 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
|
||||
|
||||
static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
|
||||
{
|
||||
struct samsung_dma_info info;
|
||||
struct samsung_dma_req req;
|
||||
|
||||
sdd->ops = samsung_dma_get_ops();
|
||||
|
||||
info.cap = DMA_SLAVE;
|
||||
info.client = &s3c64xx_spi_dma_client;
|
||||
info.width = sdd->cur_bpw / 8;
|
||||
req.cap = DMA_SLAVE;
|
||||
req.client = &s3c64xx_spi_dma_client;
|
||||
|
||||
info.direction = sdd->rx_dma.direction;
|
||||
info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
|
||||
sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info);
|
||||
info.direction = sdd->tx_dma.direction;
|
||||
info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
|
||||
sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info);
|
||||
sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req);
|
||||
sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
|
||||
struct runtime_data *prtd = substream->runtime->private_data;
|
||||
dma_addr_t pos = prtd->dma_pos;
|
||||
unsigned int limit;
|
||||
struct samsung_dma_prep_info dma_info;
|
||||
struct samsung_dma_prep dma_info;
|
||||
|
||||
pr_debug("Entered %s\n", __func__);
|
||||
|
||||
@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
|
||||
unsigned long totbytes = params_buffer_bytes(params);
|
||||
struct s3c_dma_params *dma =
|
||||
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
|
||||
struct samsung_dma_info dma_info;
|
||||
struct samsung_dma_req req;
|
||||
struct samsung_dma_config config;
|
||||
|
||||
pr_debug("Entered %s\n", __func__);
|
||||
|
||||
@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
|
||||
|
||||
prtd->params->ops = samsung_dma_get_ops();
|
||||
|
||||
dma_info.cap = (samsung_dma_has_circular() ?
|
||||
req.cap = (samsung_dma_has_circular() ?
|
||||
DMA_CYCLIC : DMA_SLAVE);
|
||||
dma_info.client = prtd->params->client;
|
||||
dma_info.direction =
|
||||
req.client = prtd->params->client;
|
||||
config.direction =
|
||||
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK
|
||||
? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
|
||||
dma_info.width = prtd->params->dma_size;
|
||||
dma_info.fifo = prtd->params->dma_addr;
|
||||
config.width = prtd->params->dma_size;
|
||||
config.fifo = prtd->params->dma_addr;
|
||||
prtd->params->ch = prtd->params->ops->request(
|
||||
prtd->params->channel, &dma_info);
|
||||
prtd->params->channel, &req);
|
||||
prtd->params->ops->config(prtd->params->ch, &config);
|
||||
}
|
||||
|
||||
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
|
||||
|
Loading…
Reference in New Issue
Block a user