Path: blob/master/arch/cris/arch-v32/mach-fs/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 <asm/dma.h>5#include <hwregs/reg_map.h>6#include <hwregs/reg_rdwr.h>7#include <hwregs/marb_defs.h>8#include <hwregs/config_defs.h>9#include <hwregs/strmux_defs.h>10#include <linux/errno.h>11#include <asm/system.h>12#include <mach/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,21enum dma_owner owner)22{23unsigned long flags;24reg_config_rw_clk_ctrl clk_ctrl;25reg_strmux_rw_cfg strmux_cfg;2627if (crisv32_arbiter_allocate_bandwidth(dmanr,28options & DMA_INT_MEM ?29INT_REGION : EXT_REGION,30bandwidth))31return -ENOMEM;3233spin_lock_irqsave(&dma_lock, flags);3435if (used_dma_channels[dmanr]) {36spin_unlock_irqrestore(&dma_lock, flags);37if (options & DMA_VERBOSE_ON_ERROR) {38printk(KERN_ERR "Failed to request DMA %i for %s, "39"already allocated by %s\n",40dmanr,41device_id,42used_dma_channels_users[dmanr]);43}44if (options & DMA_PANIC_ON_ERROR)45panic("request_dma error!");46spin_unlock_irqrestore(&dma_lock, flags);47return -EBUSY;48}49clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);50strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);5152switch (dmanr) {53case 0:54case 1:55clk_ctrl.dma01_eth0 = 1;56break;57case 2:58case 3:59clk_ctrl.dma23 = 1;60break;61case 4:62case 5:63clk_ctrl.dma45 = 1;64break;65case 6:66case 7:67clk_ctrl.dma67 = 1;68break;69case 8:70case 9:71clk_ctrl.dma89_strcop = 1;72break;73#if MAX_DMA_CHANNELS-1 != 974#error Check dma.c75#endif76default:77spin_unlock_irqrestore(&dma_lock, flags);78if (options & DMA_VERBOSE_ON_ERROR) {79printk(KERN_ERR "Failed to request DMA %i for %s, "80"only 0-%i valid)\n",81dmanr, device_id, MAX_DMA_CHANNELS - 1);82}8384if (options & DMA_PANIC_ON_ERROR)85panic("request_dma error!");86return -EINVAL;87}8889switch (owner) {90case dma_eth0:91if (dmanr == 0)92strmux_cfg.dma0 = regk_strmux_eth0;93else if (dmanr == 1)94strmux_cfg.dma1 = regk_strmux_eth0;95else96panic("Invalid DMA channel for eth0\n");97break;98case dma_eth1:99if (dmanr == 6)100strmux_cfg.dma6 = regk_strmux_eth1;101else if (dmanr == 7)102strmux_cfg.dma7 = regk_strmux_eth1;103else104panic("Invalid DMA channel for eth1\n");105break;106case dma_iop0:107if (dmanr == 2)108strmux_cfg.dma2 = regk_strmux_iop0;109else if (dmanr == 3)110strmux_cfg.dma3 = regk_strmux_iop0;111else112panic("Invalid DMA channel for iop0\n");113break;114case dma_iop1:115if (dmanr == 4)116strmux_cfg.dma4 = regk_strmux_iop1;117else if (dmanr == 5)118strmux_cfg.dma5 = regk_strmux_iop1;119else120panic("Invalid DMA channel for iop1\n");121break;122case dma_ser0:123if (dmanr == 6)124strmux_cfg.dma6 = regk_strmux_ser0;125else if (dmanr == 7)126strmux_cfg.dma7 = regk_strmux_ser0;127else128panic("Invalid DMA channel for ser0\n");129break;130case dma_ser1:131if (dmanr == 4)132strmux_cfg.dma4 = regk_strmux_ser1;133else if (dmanr == 5)134strmux_cfg.dma5 = regk_strmux_ser1;135else136panic("Invalid DMA channel for ser1\n");137break;138case dma_ser2:139if (dmanr == 2)140strmux_cfg.dma2 = regk_strmux_ser2;141else if (dmanr == 3)142strmux_cfg.dma3 = regk_strmux_ser2;143else144panic("Invalid DMA channel for ser2\n");145break;146case dma_ser3:147if (dmanr == 8)148strmux_cfg.dma8 = regk_strmux_ser3;149else if (dmanr == 9)150strmux_cfg.dma9 = regk_strmux_ser3;151else152panic("Invalid DMA channel for ser3\n");153break;154case dma_sser0:155if (dmanr == 4)156strmux_cfg.dma4 = regk_strmux_sser0;157else if (dmanr == 5)158strmux_cfg.dma5 = regk_strmux_sser0;159else160panic("Invalid DMA channel for sser0\n");161break;162case dma_sser1:163if (dmanr == 6)164strmux_cfg.dma6 = regk_strmux_sser1;165else if (dmanr == 7)166strmux_cfg.dma7 = regk_strmux_sser1;167else168panic("Invalid DMA channel for sser1\n");169break;170case dma_ata:171if (dmanr == 2)172strmux_cfg.dma2 = regk_strmux_ata;173else if (dmanr == 3)174strmux_cfg.dma3 = regk_strmux_ata;175else176panic("Invalid DMA channel for ata\n");177break;178case dma_strp:179if (dmanr == 8)180strmux_cfg.dma8 = regk_strmux_strcop;181else if (dmanr == 9)182strmux_cfg.dma9 = regk_strmux_strcop;183else184panic("Invalid DMA channel for strp\n");185break;186case dma_ext0:187if (dmanr == 6)188strmux_cfg.dma6 = regk_strmux_ext0;189else190panic("Invalid DMA channel for ext0\n");191break;192case dma_ext1:193if (dmanr == 7)194strmux_cfg.dma7 = regk_strmux_ext1;195else196panic("Invalid DMA channel for ext1\n");197break;198case dma_ext2:199if (dmanr == 2)200strmux_cfg.dma2 = regk_strmux_ext2;201else if (dmanr == 8)202strmux_cfg.dma8 = regk_strmux_ext2;203else204panic("Invalid DMA channel for ext2\n");205break;206case dma_ext3:207if (dmanr == 3)208strmux_cfg.dma3 = regk_strmux_ext3;209else if (dmanr == 9)210strmux_cfg.dma9 = regk_strmux_ext2;211else212panic("Invalid DMA channel for ext2\n");213break;214}215216used_dma_channels[dmanr] = 1;217used_dma_channels_users[dmanr] = device_id;218REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);219REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);220spin_unlock_irqrestore(&dma_lock, flags);221return 0;222}223224void crisv32_free_dma(unsigned int dmanr)225{226spin_lock(&dma_lock);227used_dma_channels[dmanr] = 0;228spin_unlock(&dma_lock);229}230231232