1 /* 2 * Enhanced Direct Memory Access (EDMA3) Controller 3 * 4 * (C) Copyright 2014 5 * Texas Instruments Incorporated, <www.ti.com> 6 * 7 * Author: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> 8 * 9 * SPDX-License-Identifier: GPL-2.0+ 10 */ 11 12 #include <asm/io.h> 13 #include <common.h> 14 #include <asm/ti-common/ti-edma3.h> 15 16 #define EDMA3_SL_BASE(slot) (0x4000 + ((slot) << 5)) 17 #define EDMA3_SL_MAX_NUM 512 18 #define EDMA3_SLOPT_FIFO_WIDTH_MASK (0x7 << 8) 19 20 #define EDMA3_QCHMAP(ch) 0x0200 + ((ch) << 2) 21 #define EDMA3_CHMAP_PARSET_MASK 0x1ff 22 #define EDMA3_CHMAP_PARSET_SHIFT 0x5 23 #define EDMA3_CHMAP_TRIGWORD_SHIFT 0x2 24 25 #define EDMA3_QEMCR 0x314 26 #define EDMA3_IPR 0x1068 27 #define EDMA3_IPRH 0x106c 28 #define EDMA3_ICR 0x1070 29 #define EDMA3_ICRH 0x1074 30 #define EDMA3_QEECR 0x1088 31 #define EDMA3_QEESR 0x108c 32 #define EDMA3_QSECR 0x1094 33 34 /** 35 * qedma3_start - start qdma on a channel 36 * @base: base address of edma 37 * @cfg: pinter to struct edma3_channel_config where you can set 38 * the slot number to associate with, the chnum, which corresponds 39 * your quick channel number 0-7, complete code - transfer complete code 40 * and trigger slot word - which has to correspond to the word number in 41 * edma3_slot_layout struct for generating event. 42 * 43 */ 44 void qedma3_start(u32 base, struct edma3_channel_config *cfg) 45 { 46 u32 qchmap; 47 48 /* Clear the pending int bit */ 49 if (cfg->complete_code < 32) 50 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICR); 51 else 52 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH); 53 54 /* Map parameter set and trigger word 7 to quick channel */ 55 qchmap = ((EDMA3_CHMAP_PARSET_MASK & cfg->slot) 56 << EDMA3_CHMAP_PARSET_SHIFT) | 57 (cfg->trigger_slot_word << EDMA3_CHMAP_TRIGWORD_SHIFT); 58 59 __raw_writel(qchmap, base + EDMA3_QCHMAP(cfg->chnum)); 60 61 /* Clear missed event if set*/ 62 __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR); 63 __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR); 64 65 /* Enable qdma channel event */ 66 __raw_writel(1 << cfg->chnum, base + EDMA3_QEESR); 67 } 68 69 /** 70 * edma3_set_dest - set initial DMA destination address in parameter RAM slot 71 * @base: base address of edma 72 * @slot: parameter RAM slot being configured 73 * @dst: physical address of destination (memory, controller FIFO, etc) 74 * @addressMode: INCR, except in very rare cases 75 * @width: ignored unless @addressMode is FIFO, else specifies the 76 * width to use when addressing the fifo (e.g. W8BIT, W32BIT) 77 * 78 * Note that the destination address is modified during the DMA transfer 79 * according to edma3_set_dest_index(). 80 */ 81 void edma3_set_dest(u32 base, int slot, u32 dst, enum edma3_address_mode mode, 82 enum edma3_fifo_width width) 83 { 84 u32 opt; 85 struct edma3_slot_layout *rg; 86 87 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 88 89 opt = __raw_readl(&rg->opt); 90 if (mode == FIFO) 91 opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) | 92 (EDMA3_SLOPT_DST_ADDR_CONST_MODE | 93 EDMA3_SLOPT_FIFO_WIDTH_SET(width)); 94 else 95 opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE; 96 97 __raw_writel(opt, &rg->opt); 98 __raw_writel(dst, &rg->dst); 99 } 100 101 /** 102 * edma3_set_dest_index - configure DMA destination address indexing 103 * @base: base address of edma 104 * @slot: parameter RAM slot being configured 105 * @bidx: byte offset between destination arrays in a frame 106 * @cidx: byte offset between destination frames in a block 107 * 108 * Offsets are specified to support either contiguous or discontiguous 109 * memory transfers, or repeated access to a hardware register, as needed. 110 * When accessing hardware registers, both offsets are normally zero. 111 */ 112 void edma3_set_dest_index(u32 base, unsigned slot, int bidx, int cidx) 113 { 114 u32 src_dst_bidx; 115 u32 src_dst_cidx; 116 struct edma3_slot_layout *rg; 117 118 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 119 120 src_dst_bidx = __raw_readl(&rg->src_dst_bidx); 121 src_dst_cidx = __raw_readl(&rg->src_dst_cidx); 122 123 __raw_writel((src_dst_bidx & 0x0000ffff) | (bidx << 16), 124 &rg->src_dst_bidx); 125 __raw_writel((src_dst_cidx & 0x0000ffff) | (cidx << 16), 126 &rg->src_dst_cidx); 127 } 128 129 /** 130 * edma3_set_dest_addr - set destination address for slot only 131 */ 132 void edma3_set_dest_addr(u32 base, int slot, u32 dst) 133 { 134 struct edma3_slot_layout *rg; 135 136 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 137 __raw_writel(dst, &rg->dst); 138 } 139 140 /** 141 * edma3_set_src - set initial DMA source address in parameter RAM slot 142 * @base: base address of edma 143 * @slot: parameter RAM slot being configured 144 * @src_port: physical address of source (memory, controller FIFO, etc) 145 * @mode: INCR, except in very rare cases 146 * @width: ignored unless @addressMode is FIFO, else specifies the 147 * width to use when addressing the fifo (e.g. W8BIT, W32BIT) 148 * 149 * Note that the source address is modified during the DMA transfer 150 * according to edma3_set_src_index(). 151 */ 152 void edma3_set_src(u32 base, int slot, u32 src, enum edma3_address_mode mode, 153 enum edma3_fifo_width width) 154 { 155 u32 opt; 156 struct edma3_slot_layout *rg; 157 158 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 159 160 opt = __raw_readl(&rg->opt); 161 if (mode == FIFO) 162 opt = (opt & EDMA3_SLOPT_FIFO_WIDTH_MASK) | 163 (EDMA3_SLOPT_DST_ADDR_CONST_MODE | 164 EDMA3_SLOPT_FIFO_WIDTH_SET(width)); 165 else 166 opt &= ~EDMA3_SLOPT_DST_ADDR_CONST_MODE; 167 168 __raw_writel(opt, &rg->opt); 169 __raw_writel(src, &rg->src); 170 } 171 172 /** 173 * edma3_set_src_index - configure DMA source address indexing 174 * @base: base address of edma 175 * @slot: parameter RAM slot being configured 176 * @bidx: byte offset between source arrays in a frame 177 * @cidx: byte offset between source frames in a block 178 * 179 * Offsets are specified to support either contiguous or discontiguous 180 * memory transfers, or repeated access to a hardware register, as needed. 181 * When accessing hardware registers, both offsets are normally zero. 182 */ 183 void edma3_set_src_index(u32 base, unsigned slot, int bidx, int cidx) 184 { 185 u32 src_dst_bidx; 186 u32 src_dst_cidx; 187 struct edma3_slot_layout *rg; 188 189 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 190 191 src_dst_bidx = __raw_readl(&rg->src_dst_bidx); 192 src_dst_cidx = __raw_readl(&rg->src_dst_cidx); 193 194 __raw_writel((src_dst_bidx & 0xffff0000) | bidx, 195 &rg->src_dst_bidx); 196 __raw_writel((src_dst_cidx & 0xffff0000) | cidx, 197 &rg->src_dst_cidx); 198 } 199 200 /** 201 * edma3_set_src_addr - set source address for slot only 202 */ 203 void edma3_set_src_addr(u32 base, int slot, u32 src) 204 { 205 struct edma3_slot_layout *rg; 206 207 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 208 __raw_writel(src, &rg->src); 209 } 210 211 /** 212 * edma3_set_transfer_params - configure DMA transfer parameters 213 * @base: base address of edma 214 * @slot: parameter RAM slot being configured 215 * @acnt: how many bytes per array (at least one) 216 * @bcnt: how many arrays per frame (at least one) 217 * @ccnt: how many frames per block (at least one) 218 * @bcnt_rld: used only for A-Synchronized transfers; this specifies 219 * the value to reload into bcnt when it decrements to zero 220 * @sync_mode: ASYNC or ABSYNC 221 * 222 * See the EDMA3 documentation to understand how to configure and link 223 * transfers using the fields in PaRAM slots. If you are not doing it 224 * all at once with edma3_write_slot(), you will use this routine 225 * plus two calls each for source and destination, setting the initial 226 * address and saying how to index that address. 227 * 228 * An example of an A-Synchronized transfer is a serial link using a 229 * single word shift register. In that case, @acnt would be equal to 230 * that word size; the serial controller issues a DMA synchronization 231 * event to transfer each word, and memory access by the DMA transfer 232 * controller will be word-at-a-time. 233 * 234 * An example of an AB-Synchronized transfer is a device using a FIFO. 235 * In that case, @acnt equals the FIFO width and @bcnt equals its depth. 236 * The controller with the FIFO issues DMA synchronization events when 237 * the FIFO threshold is reached, and the DMA transfer controller will 238 * transfer one frame to (or from) the FIFO. It will probably use 239 * efficient burst modes to access memory. 240 */ 241 void edma3_set_transfer_params(u32 base, int slot, int acnt, 242 int bcnt, int ccnt, u16 bcnt_rld, 243 enum edma3_sync_dimension sync_mode) 244 { 245 u32 opt; 246 u32 link_bcntrld; 247 struct edma3_slot_layout *rg; 248 249 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 250 251 link_bcntrld = __raw_readl(&rg->link_bcntrld); 252 253 __raw_writel((bcnt_rld << 16) | (0x0000ffff & link_bcntrld), 254 &rg->link_bcntrld); 255 256 opt = __raw_readl(&rg->opt); 257 if (sync_mode == ASYNC) 258 __raw_writel(opt & ~EDMA3_SLOPT_AB_SYNC, &rg->opt); 259 else 260 __raw_writel(opt | EDMA3_SLOPT_AB_SYNC, &rg->opt); 261 262 /* Set the acount, bcount, ccount registers */ 263 __raw_writel((bcnt << 16) | (acnt & 0xffff), &rg->a_b_cnt); 264 __raw_writel(0xffff & ccnt, &rg->ccnt); 265 } 266 267 /** 268 * edma3_write_slot - write parameter RAM data for slot 269 * @base: base address of edma 270 * @slot: number of parameter RAM slot being modified 271 * @param: data to be written into parameter RAM slot 272 * 273 * Use this to assign all parameters of a transfer at once. This 274 * allows more efficient setup of transfers than issuing multiple 275 * calls to set up those parameters in small pieces, and provides 276 * complete control over all transfer options. 277 */ 278 void edma3_write_slot(u32 base, int slot, struct edma3_slot_layout *param) 279 { 280 int i; 281 u32 *p = (u32 *)param; 282 u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot)); 283 284 for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4) 285 __raw_writel(*p++, addr++); 286 } 287 288 /** 289 * edma3_read_slot - read parameter RAM data from slot 290 * @base: base address of edma 291 * @slot: number of parameter RAM slot being copied 292 * @param: where to store copy of parameter RAM data 293 * 294 * Use this to read data from a parameter RAM slot, perhaps to 295 * save them as a template for later reuse. 296 */ 297 void edma3_read_slot(u32 base, int slot, struct edma3_slot_layout *param) 298 { 299 int i; 300 u32 *p = (u32 *)param; 301 u32 *addr = (u32 *)(base + EDMA3_SL_BASE(slot)); 302 303 for (i = 0; i < sizeof(struct edma3_slot_layout)/4; i += 4) 304 *p++ = __raw_readl(addr++); 305 } 306 307 void edma3_slot_configure(u32 base, int slot, struct edma3_slot_config *cfg) 308 { 309 struct edma3_slot_layout *rg; 310 311 rg = (struct edma3_slot_layout *)(base + EDMA3_SL_BASE(slot)); 312 313 __raw_writel(cfg->opt, &rg->opt); 314 __raw_writel(cfg->src, &rg->src); 315 __raw_writel((cfg->bcnt << 16) | (cfg->acnt & 0xffff), &rg->a_b_cnt); 316 __raw_writel(cfg->dst, &rg->dst); 317 __raw_writel((cfg->dst_bidx << 16) | 318 (cfg->src_bidx & 0xffff), &rg->src_dst_bidx); 319 __raw_writel((cfg->bcntrld << 16) | 320 (cfg->link & 0xffff), &rg->link_bcntrld); 321 __raw_writel((cfg->dst_cidx << 16) | 322 (cfg->src_cidx & 0xffff), &rg->src_dst_cidx); 323 __raw_writel(0xffff & cfg->ccnt, &rg->ccnt); 324 } 325 326 /** 327 * edma3_check_for_transfer - check if transfer coplete by checking 328 * interrupt pending bit. Clear interrupt pending bit if complete. 329 * @base: base address of edma 330 * @cfg: pinter to struct edma3_channel_config which was passed 331 * to qedma3_start when you started qdma channel 332 * 333 * Return 0 if complete, 1 if not. 334 */ 335 int edma3_check_for_transfer(u32 base, struct edma3_channel_config *cfg) 336 { 337 u32 inum; 338 u32 ipr_base; 339 u32 icr_base; 340 341 if (cfg->complete_code < 32) { 342 ipr_base = base + EDMA3_IPR; 343 icr_base = base + EDMA3_ICR; 344 inum = 1 << cfg->complete_code; 345 } else { 346 ipr_base = base + EDMA3_IPRH; 347 icr_base = base + EDMA3_ICRH; 348 inum = 1 << (cfg->complete_code - 32); 349 } 350 351 /* check complete interrupt */ 352 if (!(__raw_readl(ipr_base) & inum)) 353 return 1; 354 355 /* clean up the pending int bit */ 356 __raw_writel(inum, icr_base); 357 358 return 0; 359 } 360 361 /** 362 * qedma3_stop - stops dma on the channel passed 363 * @base: base address of edma 364 * @cfg: pinter to struct edma3_channel_config which was passed 365 * to qedma3_start when you started qdma channel 366 */ 367 void qedma3_stop(u32 base, struct edma3_channel_config *cfg) 368 { 369 /* Disable qdma channel event */ 370 __raw_writel(1 << cfg->chnum, base + EDMA3_QEECR); 371 372 /* clean up the interrupt indication */ 373 if (cfg->complete_code < 32) 374 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICR); 375 else 376 __raw_writel(1 << cfg->complete_code, base + EDMA3_ICRH); 377 378 /* Clear missed event if set*/ 379 __raw_writel(1 << cfg->chnum, base + EDMA3_QSECR); 380 __raw_writel(1 << cfg->chnum, base + EDMA3_QEMCR); 381 382 /* Clear the channel map */ 383 __raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum)); 384 } 385