linux/arch/cris/arch-v32/mach-fs/dma.c
<<
>>
Prefs
   1/* Wrapper for DMA channel allocator that starts clocks etc */
   2
   3#include <linux/kernel.h>
   4#include <linux/spinlock.h>
   5#include <asm/dma.h>
   6#include <hwregs/reg_map.h>
   7#include <hwregs/reg_rdwr.h>
   8#include <hwregs/marb_defs.h>
   9#include <hwregs/config_defs.h>
  10#include <hwregs/strmux_defs.h>
  11#include <linux/errno.h>
  12#include <asm/system.h>
  13#include <mach/arbiter.h>
  14
  15static char used_dma_channels[MAX_DMA_CHANNELS];
  16static const char *used_dma_channels_users[MAX_DMA_CHANNELS];
  17
  18static DEFINE_SPINLOCK(dma_lock);
  19
  20int crisv32_request_dma(unsigned int dmanr, const char *device_id,
  21                        unsigned options, unsigned int bandwidth,
  22                        enum dma_owner owner)
  23{
  24        unsigned long flags;
  25        reg_config_rw_clk_ctrl clk_ctrl;
  26        reg_strmux_rw_cfg strmux_cfg;
  27
  28        if (crisv32_arbiter_allocate_bandwidth(dmanr,
  29                                               options & DMA_INT_MEM ?
  30                                               INT_REGION : EXT_REGION,
  31                                               bandwidth))
  32                return -ENOMEM;
  33
  34        spin_lock_irqsave(&dma_lock, flags);
  35
  36        if (used_dma_channels[dmanr]) {
  37                spin_unlock_irqrestore(&dma_lock, flags);
  38                if (options & DMA_VERBOSE_ON_ERROR) {
  39                        printk(KERN_ERR "Failed to request DMA %i for %s, "
  40                                "already allocated by %s\n",
  41                                dmanr,
  42                                device_id,
  43                                used_dma_channels_users[dmanr]);
  44                }
  45                if (options & DMA_PANIC_ON_ERROR)
  46                        panic("request_dma error!");
  47                spin_unlock_irqrestore(&dma_lock, flags);
  48                return -EBUSY;
  49        }
  50        clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
  51        strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
  52
  53        switch (dmanr) {
  54        case 0:
  55        case 1:
  56                clk_ctrl.dma01_eth0 = 1;
  57                break;
  58        case 2:
  59        case 3:
  60                clk_ctrl.dma23 = 1;
  61                break;
  62        case 4:
  63        case 5:
  64                clk_ctrl.dma45 = 1;
  65                break;
  66        case 6:
  67        case 7:
  68                clk_ctrl.dma67 = 1;
  69                break;
  70        case 8:
  71        case 9:
  72                clk_ctrl.dma89_strcop = 1;
  73                break;
  74#if MAX_DMA_CHANNELS-1 != 9
  75#error Check dma.c
  76#endif
  77        default:
  78                spin_unlock_irqrestore(&dma_lock, flags);
  79                if (options & DMA_VERBOSE_ON_ERROR) {
  80                        printk(KERN_ERR "Failed to request DMA %i for %s, "
  81                                "only 0-%i valid)\n",
  82                                dmanr, device_id, MAX_DMA_CHANNELS - 1);
  83                }
  84
  85                if (options & DMA_PANIC_ON_ERROR)
  86                        panic("request_dma error!");
  87                return -EINVAL;
  88        }
  89
  90        switch (owner) {
  91        case dma_eth0:
  92                if (dmanr == 0)
  93                        strmux_cfg.dma0 = regk_strmux_eth0;
  94                else if (dmanr == 1)
  95                        strmux_cfg.dma1 = regk_strmux_eth0;
  96                else
  97                        panic("Invalid DMA channel for eth0\n");
  98                break;
  99        case dma_eth1:
 100                if (dmanr == 6)
 101                        strmux_cfg.dma6 = regk_strmux_eth1;
 102                else if (dmanr == 7)
 103                        strmux_cfg.dma7 = regk_strmux_eth1;
 104                else
 105                        panic("Invalid DMA channel for eth1\n");
 106                break;
 107        case dma_iop0:
 108                if (dmanr == 2)
 109                        strmux_cfg.dma2 = regk_strmux_iop0;
 110                else if (dmanr == 3)
 111                        strmux_cfg.dma3 = regk_strmux_iop0;
 112                else
 113                        panic("Invalid DMA channel for iop0\n");
 114                break;
 115        case dma_iop1:
 116                if (dmanr == 4)
 117                        strmux_cfg.dma4 = regk_strmux_iop1;
 118                else if (dmanr == 5)
 119                        strmux_cfg.dma5 = regk_strmux_iop1;
 120                else
 121                        panic("Invalid DMA channel for iop1\n");
 122                break;
 123        case dma_ser0:
 124                if (dmanr == 6)
 125                        strmux_cfg.dma6 = regk_strmux_ser0;
 126                else if (dmanr == 7)
 127                        strmux_cfg.dma7 = regk_strmux_ser0;
 128                else
 129                        panic("Invalid DMA channel for ser0\n");
 130                break;
 131        case dma_ser1:
 132                if (dmanr == 4)
 133                        strmux_cfg.dma4 = regk_strmux_ser1;
 134                else if (dmanr == 5)
 135                        strmux_cfg.dma5 = regk_strmux_ser1;
 136                else
 137                        panic("Invalid DMA channel for ser1\n");
 138                break;
 139        case dma_ser2:
 140                if (dmanr == 2)
 141                        strmux_cfg.dma2 = regk_strmux_ser2;
 142                else if (dmanr == 3)
 143                        strmux_cfg.dma3 = regk_strmux_ser2;
 144                else
 145                        panic("Invalid DMA channel for ser2\n");
 146                break;
 147        case dma_ser3:
 148                if (dmanr == 8)
 149                        strmux_cfg.dma8 = regk_strmux_ser3;
 150                else if (dmanr == 9)
 151                        strmux_cfg.dma9 = regk_strmux_ser3;
 152                else
 153                        panic("Invalid DMA channel for ser3\n");
 154                break;
 155        case dma_sser0:
 156                if (dmanr == 4)
 157                        strmux_cfg.dma4 = regk_strmux_sser0;
 158                else if (dmanr == 5)
 159                        strmux_cfg.dma5 = regk_strmux_sser0;
 160                else
 161                        panic("Invalid DMA channel for sser0\n");
 162                break;
 163        case dma_sser1:
 164                if (dmanr == 6)
 165                        strmux_cfg.dma6 = regk_strmux_sser1;
 166                else if (dmanr == 7)
 167                        strmux_cfg.dma7 = regk_strmux_sser1;
 168                else
 169                        panic("Invalid DMA channel for sser1\n");
 170                break;
 171        case dma_ata:
 172                if (dmanr == 2)
 173                        strmux_cfg.dma2 = regk_strmux_ata;
 174                else if (dmanr == 3)
 175                        strmux_cfg.dma3 = regk_strmux_ata;
 176                else
 177                        panic("Invalid DMA channel for ata\n");
 178                break;
 179        case dma_strp:
 180                if (dmanr == 8)
 181                        strmux_cfg.dma8 = regk_strmux_strcop;
 182                else if (dmanr == 9)
 183                        strmux_cfg.dma9 = regk_strmux_strcop;
 184                else
 185                        panic("Invalid DMA channel for strp\n");
 186                break;
 187        case dma_ext0:
 188                if (dmanr == 6)
 189                        strmux_cfg.dma6 = regk_strmux_ext0;
 190                else
 191                        panic("Invalid DMA channel for ext0\n");
 192                break;
 193        case dma_ext1:
 194                if (dmanr == 7)
 195                        strmux_cfg.dma7 = regk_strmux_ext1;
 196                else
 197                        panic("Invalid DMA channel for ext1\n");
 198                break;
 199        case dma_ext2:
 200                if (dmanr == 2)
 201                        strmux_cfg.dma2 = regk_strmux_ext2;
 202                else if (dmanr == 8)
 203                        strmux_cfg.dma8 = regk_strmux_ext2;
 204                else
 205                        panic("Invalid DMA channel for ext2\n");
 206                break;
 207        case dma_ext3:
 208                if (dmanr == 3)
 209                        strmux_cfg.dma3 = regk_strmux_ext3;
 210                else if (dmanr == 9)
 211                        strmux_cfg.dma9 = regk_strmux_ext2;
 212                else
 213                        panic("Invalid DMA channel for ext2\n");
 214                break;
 215        }
 216
 217        used_dma_channels[dmanr] = 1;
 218        used_dma_channels_users[dmanr] = device_id;
 219        REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
 220        REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
 221        spin_unlock_irqrestore(&dma_lock, flags);
 222        return 0;
 223}
 224
 225void crisv32_free_dma(unsigned int dmanr)
 226{
 227        spin_lock(&dma_lock);
 228        used_dma_channels[dmanr] = 0;
 229        spin_unlock(&dma_lock);
 230}
 231