static int sh_dmac_xfer_dma(struct dma_channel *chan) { /* * If we haven't pre-configured the channel with special flags, use * the defaults. */ if (unlikely(!(chan->flags & DMA_CONFIGURED))) sh_dmac_configure_channel(chan, 0); sh_dmac_disable_dma(chan); /* * Single-address mode usage note! * * It's important that we don't accidentally write any value to SAR/DAR * (this includes 0) that hasn't been directly specified by the user if * we're in single-address mode. * * In this case, only one address can be defined, anything else will * result in a DMA address error interrupt (at least on the SH-4), * which will subsequently halt the transfer. * * Channel 2 on the Dreamcast is a special case, as this is used for * cascading to the PVR2 DMAC. In this case, we still need to write * SAR and DAR, regardless of value, in order for cascading to work. */ if (chan->sar || (mach_is_dreamcast() && chan->chan == PVR2_CASCADE_CHAN)) ctrl_outl(chan->sar, SAR[chan->chan]); if (chan->dar || (mach_is_dreamcast() && chan->chan == PVR2_CASCADE_CHAN)) ctrl_outl(chan->dar, DAR[chan->chan]); ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]); sh_dmac_enable_dma(chan); return 0; }
static int sh_dmac_xfer_dma(struct dma_info *info) { /* * If we haven't pre-configured the channel with special flags, use * the defaults. */ if (!info->configured) sh_dmac_configure_channel(info, 0); sh_dmac_disable_dma(info); /* * Single-address mode usage note! * * It's important that we don't accidentally write any value to SAR/DAR * (this includes 0) that hasn't been directly specified by the user if * we're in single-address mode. * * In this case, only one address can be defined, anything else will * result in a DMA address error interrupt (at least on the SH-4), * which will subsequently halt the transfer. * * Channel 2 on the Dreamcast is a special case, as this is used for * cascading to the PVR2 DMAC. In this case, we still need to write * SAR and DAR, regardless of value, in order for cascading to work. */ if (info->sar || (mach_is_dreamcast() && info->chan == 2)) sh_dmac->channel[info->chan].sar = info->sar; if (info->dar || (mach_is_dreamcast() && info->chan == 2)) sh_dmac->channel[info->chan].dar = info->dar; sh_dmac->channel[info->chan].dmatcr = info->count >> calc_xmit_shift(info); sh_dmac_enable_dma(info); return 0; }