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