aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h6
-rw-r--r--arch/arm/plat-s3c24xx/dma.c60
-rw-r--r--drivers/mmc/host/s3cmci.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c21
4 files changed, 57 insertions, 32 deletions
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
index 13358ce2128c..acaef6784e95 100644
--- a/arch/arm/mach-s3c2410/include/mach/dma.h
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -206,10 +206,10 @@ struct s3c2410_dma_chan {
206 206
207 /* channel configuration */ 207 /* channel configuration */
208 enum s3c2410_dmasrc source; 208 enum s3c2410_dmasrc source;
209 enum dma_ch req_ch;
209 unsigned long dev_addr; 210 unsigned long dev_addr;
210 unsigned long load_timeout; 211 unsigned long load_timeout;
211 unsigned int flags; /* channel flags */ 212 unsigned int flags; /* channel flags */
212 unsigned int hw_cfg; /* last hw config */
213 213
214 struct s3c24xx_dma_map *map; /* channel hw maps */ 214 struct s3c24xx_dma_map *map; /* channel hw maps */
215 215
@@ -290,7 +290,7 @@ extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
290 * configure the dma channel 290 * configure the dma channel
291*/ 291*/
292 292
293extern int s3c2410_dma_config(unsigned int channel, int xferunit, int dcon); 293extern int s3c2410_dma_config(unsigned int channel, int xferunit);
294 294
295/* s3c2410_dma_devconfig 295/* s3c2410_dma_devconfig
296 * 296 *
@@ -298,7 +298,7 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit, int dcon);
298*/ 298*/
299 299
300extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source, 300extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
301 int hwcfg, unsigned long devaddr); 301 unsigned long devaddr);
302 302
303/* s3c2410_dma_getposition 303/* s3c2410_dma_getposition
304 * 304 *
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index d3d1375d95b3..dc58a0ddc9f6 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1038,14 +1038,13 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl);
1038/* s3c2410_dma_config 1038/* s3c2410_dma_config
1039 * 1039 *
1040 * xfersize: size of unit in bytes (1,2,4) 1040 * xfersize: size of unit in bytes (1,2,4)
1041 * dcon: base value of the DCONx register
1042*/ 1041*/
1043 1042
1044int s3c2410_dma_config(unsigned int channel, 1043int s3c2410_dma_config(unsigned int channel,
1045 int xferunit, 1044 int xferunit)
1046 int dcon)
1047{ 1045{
1048 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 1046 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1047 unsigned int dcon;
1049 1048
1050 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", 1049 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
1051 __func__, channel, xferunit, dcon); 1050 __func__, channel, xferunit, dcon);
@@ -1055,10 +1054,33 @@ int s3c2410_dma_config(unsigned int channel,
1055 1054
1056 pr_debug("%s: Initial dcon is %08x\n", __func__, dcon); 1055 pr_debug("%s: Initial dcon is %08x\n", __func__, dcon);
1057 1056
1058 dcon |= chan->dcon & dma_sel.dcon_mask; 1057 dcon = chan->dcon & dma_sel.dcon_mask;
1059 1058
1060 pr_debug("%s: New dcon is %08x\n", __func__, dcon); 1059 pr_debug("%s: New dcon is %08x\n", __func__, dcon);
1061 1060
1061 switch (chan->req_ch) {
1062 case DMACH_I2S_IN:
1063 case DMACH_I2S_OUT:
1064 case DMACH_PCM_IN:
1065 case DMACH_PCM_OUT:
1066 case DMACH_MIC_IN:
1067 default:
1068 dcon |= S3C2410_DCON_HANDSHAKE;
1069 dcon |= S3C2410_DCON_SYNC_PCLK;
1070 break;
1071
1072 case DMACH_SDI:
1073 /* note, ensure if need HANDSHAKE or not */
1074 dcon |= S3C2410_DCON_SYNC_PCLK;
1075 break;
1076
1077 case DMACH_XD0:
1078 case DMACH_XD1:
1079 dcon |= S3C2410_DCON_HANDSHAKE;
1080 dcon |= S3C2410_DCON_SYNC_HCLK;
1081 break;
1082 }
1083
1062 switch (xferunit) { 1084 switch (xferunit) {
1063 case 1: 1085 case 1:
1064 dcon |= S3C2410_DCON_BYTE; 1086 dcon |= S3C2410_DCON_BYTE;
@@ -1150,29 +1172,38 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
1150 * source: S3C2410_DMASRC_HW: source is hardware 1172 * source: S3C2410_DMASRC_HW: source is hardware
1151 * S3C2410_DMASRC_MEM: source is memory 1173 * S3C2410_DMASRC_MEM: source is memory
1152 * 1174 *
1153 * hwcfg: the value for xxxSTCn register,
1154 * bit 0: 0=increment pointer, 1=leave pointer
1155 * bit 1: 0=source is AHB, 1=source is APB
1156 *
1157 * devaddr: physical address of the source 1175 * devaddr: physical address of the source
1158*/ 1176*/
1159 1177
1160int s3c2410_dma_devconfig(int channel, 1178int s3c2410_dma_devconfig(int channel,
1161 enum s3c2410_dmasrc source, 1179 enum s3c2410_dmasrc source,
1162 int hwcfg,
1163 unsigned long devaddr) 1180 unsigned long devaddr)
1164{ 1181{
1165 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 1182 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1183 unsigned int hwcfg;
1166 1184
1167 if (chan == NULL) 1185 if (chan == NULL)
1168 return -EINVAL; 1186 return -EINVAL;
1169 1187
1170 pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", 1188 pr_debug("%s: source=%d, devaddr=%08lx\n",
1171 __func__, (int)source, hwcfg, devaddr); 1189 __func__, (int)source, devaddr);
1172 1190
1173 chan->source = source; 1191 chan->source = source;
1174 chan->dev_addr = devaddr; 1192 chan->dev_addr = devaddr;
1175 chan->hw_cfg = hwcfg; 1193
1194 switch (chan->req_ch) {
1195 case DMACH_XD0:
1196 case DMACH_XD1:
1197 hwcfg = 0; /* AHB */
1198 break;
1199
1200 default:
1201 hwcfg = S3C2410_DISRCC_APB;
1202 }
1203
1204 /* always assume our peripheral desintation is a fixed
1205 * address in memory. */
1206 hwcfg |= S3C2410_DISRCC_INC;
1176 1207
1177 switch (source) { 1208 switch (source) {
1178 case S3C2410_DMASRC_HW: 1209 case S3C2410_DMASRC_HW:
@@ -1278,8 +1309,8 @@ static int s3c2410_dma_resume(struct sys_device *dev)
1278 1309
1279 printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); 1310 printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
1280 1311
1281 s3c2410_dma_config(no, cp->xfer_unit, cp->dcon); 1312 s3c2410_dma_config(no, cp->xfer_unit);
1282 s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr); 1313 s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
1283 1314
1284 /* re-select the dma source for this channel */ 1315 /* re-select the dma source for this channel */
1285 1316
@@ -1476,6 +1507,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1476 found: 1507 found:
1477 dmach = &s3c2410_chans[ch]; 1508 dmach = &s3c2410_chans[ch];
1478 dmach->map = ch_map; 1509 dmach->map = ch_map;
1510 dmach->req_ch = channel;
1479 dma_chan_map[channel] = dmach; 1511 dma_chan_map[channel] = dmach;
1480 1512
1481 /* select the channel */ 1513 /* select the channel */
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 2db166b7096f..889f35047a52 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -789,7 +789,7 @@ static void s3cmci_dma_setup(struct s3cmci_host *host,
789 789
790 last_source = source; 790 last_source = source;
791 791
792 s3c2410_dma_devconfig(host->dma, source, 3, 792 s3c2410_dma_devconfig(host->dma, source,
793 host->mem->start + host->sdidata); 793 host->mem->start + host->sdidata);
794 794
795 if (!setup_ok) { 795 if (!setup_ok) {
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index 169ddad31575..eecfa5eba06b 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -218,24 +218,17 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
218 * sync to pclk, half-word transfers to the IIS-FIFO. */ 218 * sync to pclk, half-word transfers to the IIS-FIFO. */
219 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 219 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
220 s3c2410_dma_devconfig(prtd->params->channel, 220 s3c2410_dma_devconfig(prtd->params->channel,
221 S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | 221 S3C2410_DMASRC_MEM,
222 S3C2410_DISRCC_APB, prtd->params->dma_addr); 222 prtd->params->dma_addr);
223
224 s3c2410_dma_config(prtd->params->channel,
225 prtd->params->dma_size,
226 S3C2410_DCON_SYNC_PCLK |
227 S3C2410_DCON_HANDSHAKE);
228 } else { 223 } else {
229 s3c2410_dma_config(prtd->params->channel,
230 prtd->params->dma_size,
231 S3C2410_DCON_HANDSHAKE |
232 S3C2410_DCON_SYNC_PCLK);
233
234 s3c2410_dma_devconfig(prtd->params->channel, 224 s3c2410_dma_devconfig(prtd->params->channel,
235 S3C2410_DMASRC_HW, 0x3, 225 S3C2410_DMASRC_HW,
236 prtd->params->dma_addr); 226 prtd->params->dma_addr);
237 } 227 }
238 228
229 s3c2410_dma_config(prtd->params->channel,
230 prtd->params->dma_size);
231
239 /* flush the DMA channel */ 232 /* flush the DMA channel */
240 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); 233 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
241 prtd->dma_loaded = 0; 234 prtd->dma_loaded = 0;