Path: blob/master/arch/cris/arch-v32/mach-a3/dma.c
15125 views
/* Wrapper for DMA channel allocator that starts clocks etc */12#include <linux/kernel.h>3#include <linux/spinlock.h>4#include <mach/dma.h>5#include <hwregs/reg_map.h>6#include <hwregs/reg_rdwr.h>7#include <hwregs/marb_defs.h>8#include <hwregs/clkgen_defs.h>9#include <hwregs/strmux_defs.h>10#include <linux/errno.h>11#include <asm/system.h>12#include <arbiter.h>1314static char used_dma_channels[MAX_DMA_CHANNELS];15static const char *used_dma_channels_users[MAX_DMA_CHANNELS];1617static DEFINE_SPINLOCK(dma_lock);1819int crisv32_request_dma(unsigned int dmanr, const char *device_id,20unsigned options, unsigned int bandwidth, enum dma_owner owner)21{22unsigned long flags;23reg_clkgen_rw_clk_ctrl clk_ctrl;24reg_strmux_rw_cfg strmux_cfg;2526if (crisv32_arbiter_allocate_bandwidth(dmanr,27options & DMA_INT_MEM ? INT_REGION : EXT_REGION,28bandwidth))29return -ENOMEM;3031spin_lock_irqsave(&dma_lock, flags);3233if (used_dma_channels[dmanr]) {34spin_unlock_irqrestore(&dma_lock, flags);35if (options & DMA_VERBOSE_ON_ERROR)36printk(KERN_ERR "Failed to request DMA %i for %s, "37"already allocated by %s\n",38dmanr,39device_id,40used_dma_channels_users[dmanr]);4142if (options & DMA_PANIC_ON_ERROR)43panic("request_dma error!");44spin_unlock_irqrestore(&dma_lock, flags);45return -EBUSY;46}47clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);48strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);4950switch (dmanr) {51case 0:52case 1:53clk_ctrl.dma0_1_eth = 1;54break;55case 2:56case 3:57clk_ctrl.dma2_3_strcop = 1;58break;59case 4:60case 5:61clk_ctrl.dma4_5_iop = 1;62break;63case 6:64case 7:65clk_ctrl.sser_ser_dma6_7 = 1;66break;67case 9:68case 11:69clk_ctrl.dma9_11 = 1;70break;71#if MAX_DMA_CHANNELS-1 != 1172#error Check dma.c73#endif74default:75spin_unlock_irqrestore(&dma_lock, flags);76if (options & DMA_VERBOSE_ON_ERROR)77printk(KERN_ERR "Failed to request DMA %i for %s, "78"only 0-%i valid)\n",79dmanr, device_id, MAX_DMA_CHANNELS-1);8081if (options & DMA_PANIC_ON_ERROR)82panic("request_dma error!");83return -EINVAL;84}8586switch (owner) {87case dma_eth:88if (dmanr == 0)89strmux_cfg.dma0 = regk_strmux_eth;90else if (dmanr == 1)91strmux_cfg.dma1 = regk_strmux_eth;92else93panic("Invalid DMA channel for eth\n");94break;95case dma_ser0:96if (dmanr == 0)97strmux_cfg.dma0 = regk_strmux_ser0;98else if (dmanr == 1)99strmux_cfg.dma1 = regk_strmux_ser0;100else101panic("Invalid DMA channel for ser0\n");102break;103case dma_ser3:104if (dmanr == 2)105strmux_cfg.dma2 = regk_strmux_ser3;106else if (dmanr == 3)107strmux_cfg.dma3 = regk_strmux_ser3;108else109panic("Invalid DMA channel for ser3\n");110break;111case dma_strp:112if (dmanr == 2)113strmux_cfg.dma2 = regk_strmux_strcop;114else if (dmanr == 3)115strmux_cfg.dma3 = regk_strmux_strcop;116else117panic("Invalid DMA channel for strp\n");118break;119case dma_ser1:120if (dmanr == 4)121strmux_cfg.dma4 = regk_strmux_ser1;122else if (dmanr == 5)123strmux_cfg.dma5 = regk_strmux_ser1;124else125panic("Invalid DMA channel for ser1\n");126break;127case dma_iop:128if (dmanr == 4)129strmux_cfg.dma4 = regk_strmux_iop;130else if (dmanr == 5)131strmux_cfg.dma5 = regk_strmux_iop;132else133panic("Invalid DMA channel for iop\n");134break;135case dma_ser2:136if (dmanr == 6)137strmux_cfg.dma6 = regk_strmux_ser2;138else if (dmanr == 7)139strmux_cfg.dma7 = regk_strmux_ser2;140else141panic("Invalid DMA channel for ser2\n");142break;143case dma_sser:144if (dmanr == 6)145strmux_cfg.dma6 = regk_strmux_sser;146else if (dmanr == 7)147strmux_cfg.dma7 = regk_strmux_sser;148else149panic("Invalid DMA channel for sser\n");150break;151case dma_ser4:152if (dmanr == 9)153strmux_cfg.dma9 = regk_strmux_ser4;154else155panic("Invalid DMA channel for ser4\n");156break;157case dma_jpeg:158if (dmanr == 9)159strmux_cfg.dma9 = regk_strmux_jpeg;160else161panic("Invalid DMA channel for JPEG\n");162break;163case dma_h264:164if (dmanr == 11)165strmux_cfg.dma11 = regk_strmux_h264;166else167panic("Invalid DMA channel for H264\n");168break;169}170171used_dma_channels[dmanr] = 1;172used_dma_channels_users[dmanr] = device_id;173REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);174REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);175spin_unlock_irqrestore(&dma_lock, flags);176return 0;177}178179void crisv32_free_dma(unsigned int dmanr)180{181spin_lock(&dma_lock);182used_dma_channels[dmanr] = 0;183spin_unlock(&dma_lock);184}185186187