linux/arch/cris/arch-v32/mach-a3/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 <mach/dma.h>
   6#include <hwregs/reg_map.h>
   7#include <hwregs/reg_rdwr.h>
   8#include <hwregs/marb_defs.h>
   9#include <hwregs/clkgen_defs.h>
  10#include <hwregs/strmux_defs.h>
  11#include <linux/errno.h>
  12#include <asm/system.h>
  13#include <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, enum dma_owner owner)
  22{
  23        unsigned long flags;
  24        reg_clkgen_rw_clk_ctrl clk_ctrl;
  25        reg_strmux_rw_cfg strmux_cfg;
  26
  27        if (crisv32_arbiter_allocate_bandwidth(dmanr,
  28                        options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
  29                        bandwidth))
  30                return -ENOMEM;
  31
  32        spin_lock_irqsave(&dma_lock, flags);
  33
  34        if (used_dma_channels[dmanr]) {
  35                spin_unlock_irqrestore(&dma_lock, flags);
  36                if (options & DMA_VERBOSE_ON_ERROR)
  37                        printk(KERN_ERR "Failed to request DMA %i for %s, "
  38                                "already allocated by %s\n",
  39                                dmanr,
  40                                device_id,
  41                                used_dma_channels_users[dmanr]);
  42
  43                if (options & DMA_PANIC_ON_ERROR)
  44                        panic("request_dma error!");
  45                spin_unlock_irqrestore(&dma_lock, flags);
  46                return -EBUSY;
  47        }
  48        clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
  49        strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
  50
  51        switch (dmanr) {
  52        case 0:
  53        case 1:
  54                clk_ctrl.dma0_1_eth = 1;
  55                break;
  56        case 2:
  57        case 3:
  58                clk_ctrl.dma2_3_strcop = 1;
  59                break;
  60        case 4:
  61        case 5:
  62                clk_ctrl.dma4_5_iop = 1;
  63                break;
  64        case 6:
  65        case 7:
  66                clk_ctrl.sser_ser_dma6_7 = 1;
  67                break;
  68        case 9:
  69        case 11:
  70                clk_ctrl.dma9_11 = 1;
  71                break;
  72#if MAX_DMA_CHANNELS-1 != 11
  73#error Check dma.c
  74#endif
  75        default:
  76                spin_unlock_irqrestore(&dma_lock, flags);
  77                if (options & DMA_VERBOSE_ON_ERROR)
  78                        printk(KERN_ERR "Failed to request DMA %i for %s, "
  79                                "only 0-%i valid)\n",
  80                                dmanr, device_id, MAX_DMA_CHANNELS-1);
  81
  82                if (options & DMA_PANIC_ON_ERROR)
  83                        panic("request_dma error!");
  84                return -EINVAL;
  85        }
  86
  87        switch (owner) {
  88        case dma_eth:
  89                if (dmanr == 0)
  90                        strmux_cfg.dma0 = regk_strmux_eth;
  91                else if (dmanr == 1)
  92                        strmux_cfg.dma1 = regk_strmux_eth;
  93                else
  94                        panic("Invalid DMA channel for eth\n");
  95                break;
  96        case dma_ser0:
  97                if (dmanr == 0)
  98                        strmux_cfg.dma0 = regk_strmux_ser0;
  99                else if (dmanr == 1)
 100                        strmux_cfg.dma1 = regk_strmux_ser0;
 101                else
 102                        panic("Invalid DMA channel for ser0\n");
 103                break;
 104        case dma_ser3:
 105                if (dmanr == 2)
 106                        strmux_cfg.dma2 = regk_strmux_ser3;
 107                else if (dmanr == 3)
 108                        strmux_cfg.dma3 = regk_strmux_ser3;
 109                else
 110                        panic("Invalid DMA channel for ser3\n");
 111                break;
 112        case dma_strp:
 113                if (dmanr == 2)
 114                        strmux_cfg.dma2 = regk_strmux_strcop;
 115                else if (dmanr == 3)
 116                        strmux_cfg.dma3 = regk_strmux_strcop;
 117                else
 118                        panic("Invalid DMA channel for strp\n");
 119                break;
 120        case dma_ser1:
 121                if (dmanr == 4)
 122                        strmux_cfg.dma4 = regk_strmux_ser1;
 123                else if (dmanr == 5)
 124                        strmux_cfg.dma5 = regk_strmux_ser1;
 125                else
 126                        panic("Invalid DMA channel for ser1\n");
 127                break;
 128        case dma_iop:
 129                if (dmanr == 4)
 130                        strmux_cfg.dma4 = regk_strmux_iop;
 131                else if (dmanr == 5)
 132                        strmux_cfg.dma5 = regk_strmux_iop;
 133                else
 134                        panic("Invalid DMA channel for iop\n");
 135                break;
 136        case dma_ser2:
 137                if (dmanr == 6)
 138                        strmux_cfg.dma6 = regk_strmux_ser2;
 139                else if (dmanr == 7)
 140                        strmux_cfg.dma7 = regk_strmux_ser2;
 141                else
 142                        panic("Invalid DMA channel for ser2\n");
 143                break;
 144        case dma_sser:
 145                if (dmanr == 6)
 146                        strmux_cfg.dma6 = regk_strmux_sser;
 147                else if (dmanr == 7)
 148                        strmux_cfg.dma7 = regk_strmux_sser;
 149                else
 150                        panic("Invalid DMA channel for sser\n");
 151                break;
 152        case dma_ser4:
 153                if (dmanr == 9)
 154                        strmux_cfg.dma9 = regk_strmux_ser4;
 155                else
 156                        panic("Invalid DMA channel for ser4\n");
 157                break;
 158        case dma_jpeg:
 159                if (dmanr == 9)
 160                        strmux_cfg.dma9 = regk_strmux_jpeg;
 161                else
 162                        panic("Invalid DMA channel for JPEG\n");
 163                break;
 164        case dma_h264:
 165                if (dmanr == 11)
 166                        strmux_cfg.dma11 = regk_strmux_h264;
 167                else
 168                        panic("Invalid DMA channel for H264\n");
 169                break;
 170        }
 171
 172        used_dma_channels[dmanr] = 1;
 173        used_dma_channels_users[dmanr] = device_id;
 174        REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
 175        REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
 176        spin_unlock_irqrestore(&dma_lock, flags);
 177        return 0;
 178}
 179
 180void crisv32_free_dma(unsigned int dmanr)
 181{
 182        spin_lock(&dma_lock);
 183        used_dma_channels[dmanr] = 0;
 184        spin_unlock(&dma_lock);
 185}
 186