ARM: OMAP: Add DMA support for chaining and 3430

Add DMA support for chaining and 3430.

Also remove old DEBUG_PRINTS as noted by Russell King.

Signed-off-by: Anand Gadiyar <gadiyar@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

authored by Anand Gadiyar and committed by Tony Lindgren f8151e5c 5eb3bb9c

+905 -74
+804 -40
arch/arm/plat-omap/dma.c
··· 6 6 * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> 7 7 * Graphics DMA and LCD DMA graphics tranformations 8 8 * by Imre Deak <imre.deak@nokia.com> 9 - * OMAP2 support Copyright (C) 2004-2005 Texas Instruments, Inc. 9 + * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. 10 10 * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com> 11 11 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 12 12 * ··· 33 33 34 34 #include <asm/arch/tc.h> 35 35 36 - #define DEBUG_PRINTS 37 - #undef DEBUG_PRINTS 38 - #ifdef DEBUG_PRINTS 39 - #define debug_printk(x) printk x 40 - #else 41 - #define debug_printk(x) 36 + #undef DEBUG 37 + 38 + #ifndef CONFIG_ARCH_OMAP1 39 + enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED, 40 + DMA_CH_QUEUED, DMA_CH_NOTSTARTED, DMA_CH_PAUSED, DMA_CH_LINK_ENABLED 41 + }; 42 + 43 + enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED }; 42 44 #endif 43 45 44 46 #define OMAP_DMA_ACTIVE 0x01 ··· 59 57 const char *dev_name; 60 58 void (* callback)(int lch, u16 ch_status, void *data); 61 59 void *data; 60 + 61 + #ifndef CONFIG_ARCH_OMAP1 62 + /* required for Dynamic chaining */ 63 + int prev_linked_ch; 64 + int next_linked_ch; 65 + int state; 66 + int chain_id; 67 + 68 + int status; 69 + #endif 62 70 long flags; 63 71 }; 64 72 73 + #ifndef CONFIG_ARCH_OMAP1 74 + struct dma_link_info { 75 + int *linked_dmach_q; 76 + int no_of_lchs_linked; 77 + 78 + int q_count; 79 + int q_tail; 80 + int q_head; 81 + 82 + int chain_state; 83 + int chain_mode; 84 + 85 + }; 86 + 87 + static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT]; 88 + 89 + /* Chain handling macros */ 90 + #define OMAP_DMA_CHAIN_QINIT(chain_id) \ 91 + do { \ 92 + dma_linked_lch[chain_id].q_head = \ 93 + dma_linked_lch[chain_id].q_tail = \ 94 + dma_linked_lch[chain_id].q_count = 0; \ 95 + } while (0) 96 + #define OMAP_DMA_CHAIN_QFULL(chain_id) \ 97 + (dma_linked_lch[chain_id].no_of_lchs_linked == \ 98 + dma_linked_lch[chain_id].q_count) 99 + #define OMAP_DMA_CHAIN_QLAST(chain_id) \ 100 + do { \ 101 + ((dma_linked_lch[chain_id].no_of_lchs_linked-1) == \ 102 + dma_linked_lch[chain_id].q_count) \ 103 + } while (0) 104 + #define OMAP_DMA_CHAIN_QEMPTY(chain_id) \ 105 + (0 == dma_linked_lch[chain_id].q_count) 106 + #define __OMAP_DMA_CHAIN_INCQ(end) \ 107 + ((end) = ((end)+1) % dma_linked_lch[chain_id].no_of_lchs_linked) 108 + #define OMAP_DMA_CHAIN_INCQHEAD(chain_id) \ 109 + do { \ 110 + __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_head); \ 111 + dma_linked_lch[chain_id].q_count--; \ 112 + } while (0) 113 + 114 + #define OMAP_DMA_CHAIN_INCQTAIL(chain_id) \ 115 + do { \ 116 + __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_tail); \ 117 + dma_linked_lch[chain_id].q_count++; \ 118 + } while (0) 119 + #endif 65 120 static int dma_chan_count; 66 121 67 122 static spinlock_t dma_chan_lock; ··· 131 72 INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13, 132 73 INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD 133 74 }; 75 + 76 + static inline void disable_lnk(int lch); 77 + static void omap_disable_channel_irq(int lch); 78 + static inline void omap_enable_channel_irq(int lch); 134 79 135 80 #define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \ 136 81 __FUNCTION__); ··· 211 148 omap_writel(l, reg); 212 149 } 213 150 214 - if (cpu_is_omap24xx()) { 151 + if (cpu_class_is_omap2()) { 215 152 if (priority) 216 153 OMAP_DMA_CCR_REG(lch) |= (1 << 6); 217 154 else ··· 236 173 OMAP1_DMA_CCR2_REG(lch) |= 1 << 2; 237 174 } 238 175 239 - if (cpu_is_omap24xx() && dma_trigger) { 176 + if (cpu_class_is_omap2() && dma_trigger) { 240 177 u32 val = OMAP_DMA_CCR_REG(lch); 241 178 242 179 val &= ~(3 << 19); ··· 276 213 277 214 BUG_ON(omap_dma_in_1510_mode()); 278 215 279 - if (cpu_is_omap24xx()) { 216 + if (cpu_class_is_omap2()) { 280 217 REVISIT_24XX(); 281 218 return; 282 219 } ··· 308 245 309 246 void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) 310 247 { 311 - if (cpu_is_omap24xx()) { 248 + if (cpu_class_is_omap2()) { 312 249 OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); 313 250 OMAP_DMA_CSDP_REG(lch) |= (mode << 16); 314 251 } ··· 332 269 OMAP1_DMA_CSSA_L_REG(lch) = src_start; 333 270 } 334 271 335 - if (cpu_is_omap24xx()) 272 + if (cpu_class_is_omap2()) 336 273 OMAP2_DMA_CSSA_REG(lch) = src_start; 337 274 338 275 OMAP_DMA_CSEI_REG(lch) = src_ei; ··· 352 289 omap_set_dma_dest_params(lch, params->dst_port, 353 290 params->dst_amode, params->dst_start, 354 291 params->dst_ei, params->dst_fi); 292 + if (params->read_prio || params->write_prio) 293 + omap_dma_set_prio_lch(lch, params->read_prio, 294 + params->write_prio); 355 295 } 356 296 357 297 void omap_set_dma_src_index(int lch, int eidx, int fidx) 358 298 { 359 - if (cpu_is_omap24xx()) { 299 + if (cpu_class_is_omap2()) { 360 300 REVISIT_24XX(); 361 301 return; 362 302 } ··· 383 317 case OMAP_DMA_DATA_BURST_DIS: 384 318 break; 385 319 case OMAP_DMA_DATA_BURST_4: 386 - if (cpu_is_omap24xx()) 320 + if (cpu_class_is_omap2()) 387 321 burst = 0x1; 388 322 else 389 323 burst = 0x2; 390 324 break; 391 325 case OMAP_DMA_DATA_BURST_8: 392 - if (cpu_is_omap24xx()) { 326 + if (cpu_class_is_omap2()) { 393 327 burst = 0x2; 394 328 break; 395 329 } ··· 398 332 * fall through 399 333 */ 400 334 case OMAP_DMA_DATA_BURST_16: 401 - if (cpu_is_omap24xx()) { 335 + if (cpu_class_is_omap2()) { 402 336 burst = 0x3; 403 337 break; 404 338 } ··· 429 363 OMAP1_DMA_CDSA_L_REG(lch) = dest_start; 430 364 } 431 365 432 - if (cpu_is_omap24xx()) 366 + if (cpu_class_is_omap2()) 433 367 OMAP2_DMA_CDSA_REG(lch) = dest_start; 434 368 435 369 OMAP_DMA_CDEI_REG(lch) = dst_ei; ··· 438 372 439 373 void omap_set_dma_dest_index(int lch, int eidx, int fidx) 440 374 { 441 - if (cpu_is_omap24xx()) { 375 + if (cpu_class_is_omap2()) { 442 376 REVISIT_24XX(); 443 377 return; 444 378 } ··· 462 396 case OMAP_DMA_DATA_BURST_DIS: 463 397 break; 464 398 case OMAP_DMA_DATA_BURST_4: 465 - if (cpu_is_omap24xx()) 399 + if (cpu_class_is_omap2()) 466 400 burst = 0x1; 467 401 else 468 402 burst = 0x2; 469 403 break; 470 404 case OMAP_DMA_DATA_BURST_8: 471 - if (cpu_is_omap24xx()) 405 + if (cpu_class_is_omap2()) 472 406 burst = 0x2; 473 407 else 474 408 burst = 0x3; 475 409 break; 476 410 case OMAP_DMA_DATA_BURST_16: 477 - if (cpu_is_omap24xx()) { 411 + if (cpu_class_is_omap2()) { 478 412 burst = 0x3; 479 413 break; 480 414 } ··· 496 430 /* Clear CSR */ 497 431 if (cpu_class_is_omap1()) 498 432 status = OMAP_DMA_CSR_REG(lch); 499 - else if (cpu_is_omap24xx()) 433 + else if (cpu_class_is_omap2()) 500 434 OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; 501 435 502 436 /* Enable some nice interrupts. */ ··· 507 441 508 442 static void omap_disable_channel_irq(int lch) 509 443 { 510 - if (cpu_is_omap24xx()) 444 + if (cpu_class_is_omap2()) 511 445 OMAP_DMA_CICR_REG(lch) = 0; 512 446 } 513 447 ··· 530 464 if (dma_chan[lch].next_lch != -1) 531 465 OMAP_DMA_CLNK_CTRL_REG(lch) = 532 466 dma_chan[lch].next_lch | (1 << 15); 467 + 468 + #ifndef CONFIG_ARCH_OMAP1 469 + if (dma_chan[lch].next_linked_ch != -1) 470 + OMAP_DMA_CLNK_CTRL_REG(lch) = 471 + dma_chan[lch].next_linked_ch | (1 << 15); 472 + #endif 533 473 } 534 474 535 475 static inline void disable_lnk(int lch) ··· 547 475 OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14; 548 476 } 549 477 550 - if (cpu_is_omap24xx()) { 478 + if (cpu_class_is_omap2()) { 551 479 omap_disable_channel_irq(lch); 552 480 /* Clear the ENABLE_LNK bit */ 553 481 OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15); ··· 560 488 { 561 489 u32 val; 562 490 563 - if (!cpu_is_omap24xx()) 491 + if (!cpu_class_is_omap2()) 564 492 return; 565 493 566 494 val = omap_readl(OMAP_DMA4_IRQENABLE_L0); ··· 594 522 if (cpu_class_is_omap1()) 595 523 clear_lch_regs(free_ch); 596 524 597 - if (cpu_is_omap24xx()) 525 + if (cpu_class_is_omap2()) 598 526 omap_clear_dma(free_ch); 599 527 600 528 spin_unlock_irqrestore(&dma_chan_lock, flags); ··· 602 530 chan->dev_name = dev_name; 603 531 chan->callback = callback; 604 532 chan->data = data; 533 + #ifndef CONFIG_ARCH_OMAP1 534 + chan->chain_id = -1; 535 + #endif 605 536 chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; 606 537 607 538 if (cpu_class_is_omap1()) 608 539 chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ; 609 - else if (cpu_is_omap24xx()) 540 + else if (cpu_class_is_omap2()) 610 541 chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ | 611 542 OMAP2_DMA_TRANS_ERR_IRQ; 612 543 ··· 626 551 OMAP_DMA_CCR_REG(free_ch) = dev_id; 627 552 } 628 553 629 - if (cpu_is_omap24xx()) { 554 + if (cpu_class_is_omap2()) { 630 555 omap2_enable_irq_lch(free_ch); 631 556 632 557 omap_enable_channel_irq(free_ch); ··· 663 588 OMAP_DMA_CCR_REG(lch) = 0; 664 589 } 665 590 666 - if (cpu_is_omap24xx()) { 591 + if (cpu_class_is_omap2()) { 667 592 u32 val; 668 593 /* Disable interrupts */ 669 594 val = omap_readl(OMAP_DMA4_IRQENABLE_L0); ··· 683 608 } 684 609 } 685 610 611 + /** 612 + * @brief omap_dma_set_global_params : Set global priority settings for dma 613 + * 614 + * @param arb_rate 615 + * @param max_fifo_depth 616 + * @param tparams - Number of thereads to reserve : DMA_THREAD_RESERVE_NORM 617 + * DMA_THREAD_RESERVE_ONET 618 + * DMA_THREAD_RESERVE_TWOT 619 + * DMA_THREAD_RESERVE_THREET 620 + */ 621 + void 622 + omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) 623 + { 624 + u32 reg; 625 + 626 + if (!cpu_class_is_omap2()) { 627 + printk(KERN_ERR "FIXME: no %s on 15xx/16xx\n", __FUNCTION__); 628 + return; 629 + } 630 + 631 + if (arb_rate == 0) 632 + arb_rate = 1; 633 + 634 + reg = (arb_rate & 0xff) << 16; 635 + reg |= (0xff & max_fifo_depth); 636 + 637 + omap_writel(reg, OMAP_DMA4_GCR_REG); 638 + } 639 + EXPORT_SYMBOL(omap_dma_set_global_params); 640 + 641 + /** 642 + * @brief omap_dma_set_prio_lch : Set channel wise priority settings 643 + * 644 + * @param lch 645 + * @param read_prio - Read priority 646 + * @param write_prio - Write priority 647 + * Both of the above can be set with one of the following values : 648 + * DMA_CH_PRIO_HIGH/DMA_CH_PRIO_LOW 649 + */ 650 + int 651 + omap_dma_set_prio_lch(int lch, unsigned char read_prio, 652 + unsigned char write_prio) 653 + { 654 + u32 w; 655 + 656 + if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) { 657 + printk(KERN_ERR "Invalid channel id\n"); 658 + return -EINVAL; 659 + } 660 + w = OMAP_DMA_CCR_REG(lch); 661 + w &= ~((1 << 6) | (1 << 26)); 662 + if (cpu_is_omap2430() || cpu_is_omap34xx()) 663 + w |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26); 664 + else 665 + w |= ((read_prio & 0x1) << 6); 666 + 667 + OMAP_DMA_CCR_REG(lch) = w; 668 + return 0; 669 + } 670 + EXPORT_SYMBOL(omap_dma_set_prio_lch); 671 + 686 672 /* 687 673 * Clears any DMA state so the DMA engine is ready to restart with new buffers 688 674 * through omap_start_dma(). Any buffers in flight are discarded. ··· 762 626 status = OMAP_DMA_CSR_REG(lch); 763 627 } 764 628 765 - if (cpu_is_omap24xx()) { 629 + if (cpu_class_is_omap2()) { 766 630 int i; 767 - u32 lch_base = OMAP24XX_DMA_BASE + lch * 0x60 + 0x80; 631 + u32 lch_base = OMAP_DMA4_BASE + lch * 0x60 + 0x80; 768 632 for (i = 0; i < 0x44; i += 4) 769 633 omap_writel(0, lch_base + i); 770 634 } ··· 798 662 799 663 cur_lch = next_lch; 800 664 } while (next_lch != -1); 801 - } else if (cpu_is_omap24xx()) { 665 + } else if (cpu_class_is_omap2()) { 802 666 /* Errata: Need to write lch even if not using chaining */ 803 667 OMAP_DMA_CLNK_CTRL_REG(lch) = lch; 804 668 } ··· 889 753 offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) | 890 754 (OMAP1_DMA_CSSA_U_REG(lch) << 16)); 891 755 892 - if (cpu_is_omap24xx()) 756 + if (cpu_class_is_omap2()) 893 757 offset = OMAP_DMA_CSAC_REG(lch); 894 758 895 759 return offset; ··· 911 775 offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) | 912 776 (OMAP1_DMA_CDSA_U_REG(lch) << 16)); 913 777 914 - if (cpu_is_omap24xx()) 915 - offset = OMAP2_DMA_CDSA_REG(lch); 778 + if (cpu_class_is_omap2()) 779 + offset = OMAP_DMA_CDAC_REG(lch); 916 780 917 781 return offset; 918 782 } ··· 995 859 dma_chan[lch_head].next_lch = -1; 996 860 } 997 861 862 + #ifndef CONFIG_ARCH_OMAP1 863 + /* Create chain of DMA channesls */ 864 + static void create_dma_lch_chain(int lch_head, int lch_queue) 865 + { 866 + u32 w; 867 + 868 + /* Check if this is the first link in chain */ 869 + if (dma_chan[lch_head].next_linked_ch == -1) { 870 + dma_chan[lch_head].next_linked_ch = lch_queue; 871 + dma_chan[lch_head].prev_linked_ch = lch_queue; 872 + dma_chan[lch_queue].next_linked_ch = lch_head; 873 + dma_chan[lch_queue].prev_linked_ch = lch_head; 874 + } 875 + 876 + /* a link exists, link the new channel in circular chain */ 877 + else { 878 + dma_chan[lch_queue].next_linked_ch = 879 + dma_chan[lch_head].next_linked_ch; 880 + dma_chan[lch_queue].prev_linked_ch = lch_head; 881 + dma_chan[lch_head].next_linked_ch = lch_queue; 882 + dma_chan[dma_chan[lch_queue].next_linked_ch].prev_linked_ch = 883 + lch_queue; 884 + } 885 + 886 + w = OMAP_DMA_CLNK_CTRL_REG(lch_head); 887 + w &= ~(0x0f); 888 + w |= lch_queue; 889 + OMAP_DMA_CLNK_CTRL_REG(lch_head) = w; 890 + 891 + w = OMAP_DMA_CLNK_CTRL_REG(lch_queue); 892 + w &= ~(0x0f); 893 + w |= (dma_chan[lch_queue].next_linked_ch); 894 + OMAP_DMA_CLNK_CTRL_REG(lch_queue) = w; 895 + } 896 + 897 + /** 898 + * @brief omap_request_dma_chain : Request a chain of DMA channels 899 + * 900 + * @param dev_id - Device id using the dma channel 901 + * @param dev_name - Device name 902 + * @param callback - Call back function 903 + * @chain_id - 904 + * @no_of_chans - Number of channels requested 905 + * @chain_mode - Dynamic or static chaining : OMAP_DMA_STATIC_CHAIN 906 + * OMAP_DMA_DYNAMIC_CHAIN 907 + * @params - Channel parameters 908 + * 909 + * @return - Succes : 0 910 + * Failure: -EINVAL/-ENOMEM 911 + */ 912 + int omap_request_dma_chain(int dev_id, const char *dev_name, 913 + void (*callback) (int chain_id, u16 ch_status, 914 + void *data), 915 + int *chain_id, int no_of_chans, int chain_mode, 916 + struct omap_dma_channel_params params) 917 + { 918 + int *channels; 919 + int i, err; 920 + 921 + /* Is the chain mode valid ? */ 922 + if (chain_mode != OMAP_DMA_STATIC_CHAIN 923 + && chain_mode != OMAP_DMA_DYNAMIC_CHAIN) { 924 + printk(KERN_ERR "Invalid chain mode requested\n"); 925 + return -EINVAL; 926 + } 927 + 928 + if (unlikely((no_of_chans < 1 929 + || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) { 930 + printk(KERN_ERR "Invalid Number of channels requested\n"); 931 + return -EINVAL; 932 + } 933 + 934 + /* Allocate a queue to maintain the status of the channels 935 + * in the chain */ 936 + channels = kmalloc(sizeof(*channels) * no_of_chans, GFP_KERNEL); 937 + if (channels == NULL) { 938 + printk(KERN_ERR "omap_dma: No memory for channel queue\n"); 939 + return -ENOMEM; 940 + } 941 + 942 + /* request and reserve DMA channels for the chain */ 943 + for (i = 0; i < no_of_chans; i++) { 944 + err = omap_request_dma(dev_id, dev_name, 945 + callback, 0, &channels[i]); 946 + if (err < 0) { 947 + int j; 948 + for (j = 0; j < i; j++) 949 + omap_free_dma(channels[j]); 950 + kfree(channels); 951 + printk(KERN_ERR "omap_dma: Request failed %d\n", err); 952 + return err; 953 + } 954 + dma_chan[channels[i]].next_linked_ch = -1; 955 + dma_chan[channels[i]].prev_linked_ch = -1; 956 + dma_chan[channels[i]].state = DMA_CH_NOTSTARTED; 957 + 958 + /* 959 + * Allowing client drivers to set common parameters now, 960 + * so that later only relevant (src_start, dest_start 961 + * and element count) can be set 962 + */ 963 + omap_set_dma_params(channels[i], &params); 964 + } 965 + 966 + *chain_id = channels[0]; 967 + dma_linked_lch[*chain_id].linked_dmach_q = channels; 968 + dma_linked_lch[*chain_id].chain_mode = chain_mode; 969 + dma_linked_lch[*chain_id].chain_state = DMA_CHAIN_NOTSTARTED; 970 + dma_linked_lch[*chain_id].no_of_lchs_linked = no_of_chans; 971 + 972 + for (i = 0; i < no_of_chans; i++) 973 + dma_chan[channels[i]].chain_id = *chain_id; 974 + 975 + /* Reset the Queue pointers */ 976 + OMAP_DMA_CHAIN_QINIT(*chain_id); 977 + 978 + /* Set up the chain */ 979 + if (no_of_chans == 1) 980 + create_dma_lch_chain(channels[0], channels[0]); 981 + else { 982 + for (i = 0; i < (no_of_chans - 1); i++) 983 + create_dma_lch_chain(channels[i], channels[i + 1]); 984 + } 985 + return 0; 986 + } 987 + EXPORT_SYMBOL(omap_request_dma_chain); 988 + 989 + /** 990 + * @brief omap_modify_dma_chain_param : Modify the chain's params - Modify the 991 + * params after setting it. Dont do this while dma is running!! 992 + * 993 + * @param chain_id - Chained logical channel id. 994 + * @param params 995 + * 996 + * @return - Success : 0 997 + * Failure : -EINVAL 998 + */ 999 + int omap_modify_dma_chain_params(int chain_id, 1000 + struct omap_dma_channel_params params) 1001 + { 1002 + int *channels; 1003 + u32 i; 1004 + 1005 + /* Check for input params */ 1006 + if (unlikely((chain_id < 0 1007 + || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1008 + printk(KERN_ERR "Invalid chain id\n"); 1009 + return -EINVAL; 1010 + } 1011 + 1012 + /* Check if the chain exists */ 1013 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1014 + printk(KERN_ERR "Chain doesn't exists\n"); 1015 + return -EINVAL; 1016 + } 1017 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1018 + 1019 + for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) { 1020 + /* 1021 + * Allowing client drivers to set common parameters now, 1022 + * so that later only relevant (src_start, dest_start 1023 + * and element count) can be set 1024 + */ 1025 + omap_set_dma_params(channels[i], &params); 1026 + } 1027 + return 0; 1028 + } 1029 + EXPORT_SYMBOL(omap_modify_dma_chain_params); 1030 + 1031 + /** 1032 + * @brief omap_free_dma_chain - Free all the logical channels in a chain. 1033 + * 1034 + * @param chain_id 1035 + * 1036 + * @return - Success : 0 1037 + * Failure : -EINVAL 1038 + */ 1039 + int omap_free_dma_chain(int chain_id) 1040 + { 1041 + int *channels; 1042 + u32 i; 1043 + 1044 + /* Check for input params */ 1045 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1046 + printk(KERN_ERR "Invalid chain id\n"); 1047 + return -EINVAL; 1048 + } 1049 + 1050 + /* Check if the chain exists */ 1051 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1052 + printk(KERN_ERR "Chain doesn't exists\n"); 1053 + return -EINVAL; 1054 + } 1055 + 1056 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1057 + for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) { 1058 + dma_chan[channels[i]].next_linked_ch = -1; 1059 + dma_chan[channels[i]].prev_linked_ch = -1; 1060 + dma_chan[channels[i]].chain_id = -1; 1061 + dma_chan[channels[i]].state = DMA_CH_NOTSTARTED; 1062 + omap_free_dma(channels[i]); 1063 + } 1064 + 1065 + kfree(channels); 1066 + 1067 + dma_linked_lch[chain_id].linked_dmach_q = NULL; 1068 + dma_linked_lch[chain_id].chain_mode = -1; 1069 + dma_linked_lch[chain_id].chain_state = -1; 1070 + return (0); 1071 + } 1072 + EXPORT_SYMBOL(omap_free_dma_chain); 1073 + 1074 + /** 1075 + * @brief omap_dma_chain_status - Check if the chain is in 1076 + * active / inactive state. 1077 + * @param chain_id 1078 + * 1079 + * @return - Success : OMAP_DMA_CHAIN_ACTIVE/OMAP_DMA_CHAIN_INACTIVE 1080 + * Failure : -EINVAL 1081 + */ 1082 + int omap_dma_chain_status(int chain_id) 1083 + { 1084 + /* Check for input params */ 1085 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1086 + printk(KERN_ERR "Invalid chain id\n"); 1087 + return -EINVAL; 1088 + } 1089 + 1090 + /* Check if the chain exists */ 1091 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1092 + printk(KERN_ERR "Chain doesn't exists\n"); 1093 + return -EINVAL; 1094 + } 1095 + pr_debug("CHAINID=%d, qcnt=%d\n", chain_id, 1096 + dma_linked_lch[chain_id].q_count); 1097 + 1098 + if (OMAP_DMA_CHAIN_QEMPTY(chain_id)) 1099 + return OMAP_DMA_CHAIN_INACTIVE; 1100 + return OMAP_DMA_CHAIN_ACTIVE; 1101 + } 1102 + EXPORT_SYMBOL(omap_dma_chain_status); 1103 + 1104 + /** 1105 + * @brief omap_dma_chain_a_transfer - Get a free channel from a chain, 1106 + * set the params and start the transfer. 1107 + * 1108 + * @param chain_id 1109 + * @param src_start - buffer start address 1110 + * @param dest_start - Dest address 1111 + * @param elem_count 1112 + * @param frame_count 1113 + * @param callbk_data - channel callback parameter data. 1114 + * 1115 + * @return - Success : start_dma status 1116 + * Failure: -EINVAL/-EBUSY 1117 + */ 1118 + int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start, 1119 + int elem_count, int frame_count, void *callbk_data) 1120 + { 1121 + int *channels; 1122 + u32 w, lch; 1123 + int start_dma = 0; 1124 + 1125 + /* if buffer size is less than 1 then there is 1126 + * no use of starting the chain */ 1127 + if (elem_count < 1) { 1128 + printk(KERN_ERR "Invalid buffer size\n"); 1129 + return -EINVAL; 1130 + } 1131 + 1132 + /* Check for input params */ 1133 + if (unlikely((chain_id < 0 1134 + || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1135 + printk(KERN_ERR "Invalid chain id\n"); 1136 + return -EINVAL; 1137 + } 1138 + 1139 + /* Check if the chain exists */ 1140 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1141 + printk(KERN_ERR "Chain doesn't exist\n"); 1142 + return -EINVAL; 1143 + } 1144 + 1145 + /* Check if all the channels in chain are in use */ 1146 + if (OMAP_DMA_CHAIN_QFULL(chain_id)) 1147 + return -EBUSY; 1148 + 1149 + /* Frame count may be negative in case of indexed transfers */ 1150 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1151 + 1152 + /* Get a free channel */ 1153 + lch = channels[dma_linked_lch[chain_id].q_tail]; 1154 + 1155 + /* Store the callback data */ 1156 + dma_chan[lch].data = callbk_data; 1157 + 1158 + /* Increment the q_tail */ 1159 + OMAP_DMA_CHAIN_INCQTAIL(chain_id); 1160 + 1161 + /* Set the params to the free channel */ 1162 + if (src_start != 0) 1163 + OMAP2_DMA_CSSA_REG(lch) = src_start; 1164 + if (dest_start != 0) 1165 + OMAP2_DMA_CDSA_REG(lch) = dest_start; 1166 + 1167 + /* Write the buffer size */ 1168 + OMAP_DMA_CEN_REG(lch) = elem_count; 1169 + OMAP_DMA_CFN_REG(lch) = frame_count; 1170 + 1171 + /* If the chain is dynamically linked, 1172 + * then we may have to start the chain if its not active */ 1173 + if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_DYNAMIC_CHAIN) { 1174 + 1175 + /* In Dynamic chain, if the chain is not started, 1176 + * queue the channel */ 1177 + if (dma_linked_lch[chain_id].chain_state == 1178 + DMA_CHAIN_NOTSTARTED) { 1179 + /* Enable the link in previous channel */ 1180 + if (dma_chan[dma_chan[lch].prev_linked_ch].state == 1181 + DMA_CH_QUEUED) 1182 + enable_lnk(dma_chan[lch].prev_linked_ch); 1183 + dma_chan[lch].state = DMA_CH_QUEUED; 1184 + } 1185 + 1186 + /* Chain is already started, make sure its active, 1187 + * if not then start the chain */ 1188 + else { 1189 + start_dma = 1; 1190 + 1191 + if (dma_chan[dma_chan[lch].prev_linked_ch].state == 1192 + DMA_CH_STARTED) { 1193 + enable_lnk(dma_chan[lch].prev_linked_ch); 1194 + dma_chan[lch].state = DMA_CH_QUEUED; 1195 + start_dma = 0; 1196 + if (0 == ((1 << 7) & (OMAP_DMA_CCR_REG 1197 + (dma_chan[lch].prev_linked_ch)))) { 1198 + disable_lnk(dma_chan[lch]. 1199 + prev_linked_ch); 1200 + pr_debug("\n prev ch is stopped\n"); 1201 + start_dma = 1; 1202 + } 1203 + } 1204 + 1205 + else if (dma_chan[dma_chan[lch].prev_linked_ch].state 1206 + == DMA_CH_QUEUED) { 1207 + enable_lnk(dma_chan[lch].prev_linked_ch); 1208 + dma_chan[lch].state = DMA_CH_QUEUED; 1209 + start_dma = 0; 1210 + } 1211 + omap_enable_channel_irq(lch); 1212 + 1213 + w = OMAP_DMA_CCR_REG(lch); 1214 + 1215 + if ((0 == (w & (1 << 24)))) 1216 + w &= ~(1 << 25); 1217 + else 1218 + w |= (1 << 25); 1219 + if (start_dma == 1) { 1220 + if (0 == (w & (1 << 7))) { 1221 + w |= (1 << 7); 1222 + dma_chan[lch].state = DMA_CH_STARTED; 1223 + pr_debug("starting %d\n", lch); 1224 + OMAP_DMA_CCR_REG(lch) = w; 1225 + } else 1226 + start_dma = 0; 1227 + } else { 1228 + if (0 == (w & (1 << 7))) 1229 + OMAP_DMA_CCR_REG(lch) = w; 1230 + } 1231 + dma_chan[lch].flags |= OMAP_DMA_ACTIVE; 1232 + } 1233 + } 1234 + return start_dma; 1235 + } 1236 + EXPORT_SYMBOL(omap_dma_chain_a_transfer); 1237 + 1238 + /** 1239 + * @brief omap_start_dma_chain_transfers - Start the chain 1240 + * 1241 + * @param chain_id 1242 + * 1243 + * @return - Success : 0 1244 + * Failure : -EINVAL/-EBUSY 1245 + */ 1246 + int omap_start_dma_chain_transfers(int chain_id) 1247 + { 1248 + int *channels; 1249 + u32 w, i; 1250 + 1251 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1252 + printk(KERN_ERR "Invalid chain id\n"); 1253 + return -EINVAL; 1254 + } 1255 + 1256 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1257 + 1258 + if (dma_linked_lch[channels[0]].chain_state == DMA_CHAIN_STARTED) { 1259 + printk(KERN_ERR "Chain is already started\n"); 1260 + return -EBUSY; 1261 + } 1262 + 1263 + if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_STATIC_CHAIN) { 1264 + for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; 1265 + i++) { 1266 + enable_lnk(channels[i]); 1267 + omap_enable_channel_irq(channels[i]); 1268 + } 1269 + } else { 1270 + omap_enable_channel_irq(channels[0]); 1271 + } 1272 + 1273 + w = OMAP_DMA_CCR_REG(channels[0]); 1274 + w |= (1 << 7); 1275 + dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED; 1276 + dma_chan[channels[0]].state = DMA_CH_STARTED; 1277 + 1278 + if ((0 == (w & (1 << 24)))) 1279 + w &= ~(1 << 25); 1280 + else 1281 + w |= (1 << 25); 1282 + OMAP_DMA_CCR_REG(channels[0]) = w; 1283 + 1284 + dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE; 1285 + return 0; 1286 + } 1287 + EXPORT_SYMBOL(omap_start_dma_chain_transfers); 1288 + 1289 + /** 1290 + * @brief omap_stop_dma_chain_transfers - Stop the dma transfer of a chain. 1291 + * 1292 + * @param chain_id 1293 + * 1294 + * @return - Success : 0 1295 + * Failure : EINVAL 1296 + */ 1297 + int omap_stop_dma_chain_transfers(int chain_id) 1298 + { 1299 + int *channels; 1300 + u32 w, i; 1301 + u32 sys_cf; 1302 + 1303 + /* Check for input params */ 1304 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1305 + printk(KERN_ERR "Invalid chain id\n"); 1306 + return -EINVAL; 1307 + } 1308 + 1309 + /* Check if the chain exists */ 1310 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1311 + printk(KERN_ERR "Chain doesn't exists\n"); 1312 + return -EINVAL; 1313 + } 1314 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1315 + 1316 + /* DMA Errata: 1317 + * Special programming model needed to disable DMA before end of block 1318 + */ 1319 + sys_cf = omap_readl(OMAP_DMA4_OCP_SYSCONFIG); 1320 + w = sys_cf; 1321 + /* Middle mode reg set no Standby */ 1322 + w &= ~((1 << 12)|(1 << 13)); 1323 + omap_writel(w, OMAP_DMA4_OCP_SYSCONFIG); 1324 + 1325 + for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) { 1326 + 1327 + /* Stop the Channel transmission */ 1328 + w = OMAP_DMA_CCR_REG(channels[i]); 1329 + w &= ~(1 << 7); 1330 + OMAP_DMA_CCR_REG(channels[i]) = w; 1331 + 1332 + /* Disable the link in all the channels */ 1333 + disable_lnk(channels[i]); 1334 + dma_chan[channels[i]].state = DMA_CH_NOTSTARTED; 1335 + 1336 + } 1337 + dma_linked_lch[chain_id].chain_state = DMA_CHAIN_NOTSTARTED; 1338 + 1339 + /* Reset the Queue pointers */ 1340 + OMAP_DMA_CHAIN_QINIT(chain_id); 1341 + 1342 + /* Errata - put in the old value */ 1343 + omap_writel(sys_cf, OMAP_DMA4_OCP_SYSCONFIG); 1344 + return 0; 1345 + } 1346 + EXPORT_SYMBOL(omap_stop_dma_chain_transfers); 1347 + 1348 + /* Get the index of the ongoing DMA in chain */ 1349 + /** 1350 + * @brief omap_get_dma_chain_index - Get the element and frame index 1351 + * of the ongoing DMA in chain 1352 + * 1353 + * @param chain_id 1354 + * @param ei - Element index 1355 + * @param fi - Frame index 1356 + * 1357 + * @return - Success : 0 1358 + * Failure : -EINVAL 1359 + */ 1360 + int omap_get_dma_chain_index(int chain_id, int *ei, int *fi) 1361 + { 1362 + int lch; 1363 + int *channels; 1364 + 1365 + /* Check for input params */ 1366 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1367 + printk(KERN_ERR "Invalid chain id\n"); 1368 + return -EINVAL; 1369 + } 1370 + 1371 + /* Check if the chain exists */ 1372 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1373 + printk(KERN_ERR "Chain doesn't exists\n"); 1374 + return -EINVAL; 1375 + } 1376 + if ((!ei) || (!fi)) 1377 + return -EINVAL; 1378 + 1379 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1380 + 1381 + /* Get the current channel */ 1382 + lch = channels[dma_linked_lch[chain_id].q_head]; 1383 + 1384 + *ei = OMAP2_DMA_CCEN_REG(lch); 1385 + *fi = OMAP2_DMA_CCFN_REG(lch); 1386 + 1387 + return 0; 1388 + } 1389 + EXPORT_SYMBOL(omap_get_dma_chain_index); 1390 + 1391 + /** 1392 + * @brief omap_get_dma_chain_dst_pos - Get the destination position of the 1393 + * ongoing DMA in chain 1394 + * 1395 + * @param chain_id 1396 + * 1397 + * @return - Success : Destination position 1398 + * Failure : -EINVAL 1399 + */ 1400 + int omap_get_dma_chain_dst_pos(int chain_id) 1401 + { 1402 + int lch; 1403 + int *channels; 1404 + 1405 + /* Check for input params */ 1406 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1407 + printk(KERN_ERR "Invalid chain id\n"); 1408 + return -EINVAL; 1409 + } 1410 + 1411 + /* Check if the chain exists */ 1412 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1413 + printk(KERN_ERR "Chain doesn't exists\n"); 1414 + return -EINVAL; 1415 + } 1416 + 1417 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1418 + 1419 + /* Get the current channel */ 1420 + lch = channels[dma_linked_lch[chain_id].q_head]; 1421 + 1422 + return (OMAP_DMA_CDAC_REG(lch)); 1423 + } 1424 + EXPORT_SYMBOL(omap_get_dma_chain_dst_pos); 1425 + 1426 + /** 1427 + * @brief omap_get_dma_chain_src_pos - Get the source position 1428 + * of the ongoing DMA in chain 1429 + * @param chain_id 1430 + * 1431 + * @return - Success : Destination position 1432 + * Failure : -EINVAL 1433 + */ 1434 + int omap_get_dma_chain_src_pos(int chain_id) 1435 + { 1436 + int lch; 1437 + int *channels; 1438 + 1439 + /* Check for input params */ 1440 + if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) { 1441 + printk(KERN_ERR "Invalid chain id\n"); 1442 + return -EINVAL; 1443 + } 1444 + 1445 + /* Check if the chain exists */ 1446 + if (dma_linked_lch[chain_id].linked_dmach_q == NULL) { 1447 + printk(KERN_ERR "Chain doesn't exists\n"); 1448 + return -EINVAL; 1449 + } 1450 + 1451 + channels = dma_linked_lch[chain_id].linked_dmach_q; 1452 + 1453 + /* Get the current channel */ 1454 + lch = channels[dma_linked_lch[chain_id].q_head]; 1455 + 1456 + return (OMAP_DMA_CSAC_REG(lch)); 1457 + } 1458 + EXPORT_SYMBOL(omap_get_dma_chain_src_pos); 1459 + #endif 1460 + 998 1461 /*----------------------------------------------------------------------------*/ 999 1462 1000 1463 #ifdef CONFIG_ARCH_OMAP1 ··· 1654 919 #define omap1_dma_irq_handler NULL 1655 920 #endif 1656 921 1657 - #ifdef CONFIG_ARCH_OMAP2 922 + #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 1658 923 1659 924 static int omap2_dma_handle_ch(int ch) 1660 925 { ··· 1688 953 OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK; 1689 954 omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0); 1690 955 1691 - if (likely(dma_chan[ch].callback != NULL)) 1692 - dma_chan[ch].callback(ch, status, dma_chan[ch].data); 956 + /* If the ch is not chained then chain_id will be -1 */ 957 + if (dma_chan[ch].chain_id != -1) { 958 + int chain_id = dma_chan[ch].chain_id; 959 + dma_chan[ch].state = DMA_CH_NOTSTARTED; 960 + if (OMAP_DMA_CLNK_CTRL_REG(ch) & (1 << 15)) 961 + dma_chan[dma_chan[ch].next_linked_ch].state = 962 + DMA_CH_STARTED; 963 + if (dma_linked_lch[chain_id].chain_mode == 964 + OMAP_DMA_DYNAMIC_CHAIN) 965 + disable_lnk(ch); 966 + 967 + if (!OMAP_DMA_CHAIN_QEMPTY(chain_id)) 968 + OMAP_DMA_CHAIN_INCQHEAD(chain_id); 969 + 970 + status = OMAP_DMA_CSR_REG(ch); 971 + } 972 + 973 + if (likely(dma_chan[ch].callback != NULL)) { 974 + if (dma_chan[ch].chain_id != -1) 975 + dma_chan[ch].callback(dma_chan[ch].chain_id, status, 976 + dma_chan[ch].data); 977 + else 978 + dma_chan[ch].callback(ch, status, dma_chan[ch].data); 979 + 980 + } 981 + 982 + OMAP_DMA_CSR_REG(ch) = status; 1693 983 1694 984 return 0; 1695 985 } ··· 2145 1385 w &= ~(1 << 8); 2146 1386 omap_writew(w, OMAP1610_DMA_LCD_CTRL); 2147 1387 } 2148 - } else if (cpu_is_omap24xx()) { 1388 + } else if (cpu_class_is_omap2()) { 2149 1389 u8 revision = omap_readb(OMAP_DMA4_REVISION); 2150 1390 printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", 2151 1391 revision >> 4, revision & 0xf); ··· 2188 1428 } 2189 1429 } 2190 1430 2191 - if (cpu_is_omap24xx()) 1431 + if (cpu_is_omap2430() || cpu_is_omap34xx()) 1432 + omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 1433 + DMA_DEFAULT_FIFO_DEPTH, 0); 1434 + 1435 + if (cpu_class_is_omap2()) 2192 1436 setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq); 2193 1437 2194 1438 /* FIXME: Update LCD DMA to work on 24xx */
+101 -34
include/asm-arm/arch-omap/dma.h
··· 45 45 #define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0) 46 46 47 47 /* Hardware registers for omap2 */ 48 - #define OMAP24XX_DMA_BASE (L4_24XX_BASE + 0x56000) 49 - #define OMAP_DMA4_REVISION (OMAP24XX_DMA_BASE + 0x00) 50 - #define OMAP_DMA4_GCR_REG (OMAP24XX_DMA_BASE + 0x78) 51 - #define OMAP_DMA4_IRQSTATUS_L0 (OMAP24XX_DMA_BASE + 0x08) 52 - #define OMAP_DMA4_IRQSTATUS_L1 (OMAP24XX_DMA_BASE + 0x0c) 53 - #define OMAP_DMA4_IRQSTATUS_L2 (OMAP24XX_DMA_BASE + 0x10) 54 - #define OMAP_DMA4_IRQSTATUS_L3 (OMAP24XX_DMA_BASE + 0x14) 55 - #define OMAP_DMA4_IRQENABLE_L0 (OMAP24XX_DMA_BASE + 0x18) 56 - #define OMAP_DMA4_IRQENABLE_L1 (OMAP24XX_DMA_BASE + 0x1c) 57 - #define OMAP_DMA4_IRQENABLE_L2 (OMAP24XX_DMA_BASE + 0x20) 58 - #define OMAP_DMA4_IRQENABLE_L3 (OMAP24XX_DMA_BASE + 0x24) 59 - #define OMAP_DMA4_SYSSTATUS (OMAP24XX_DMA_BASE + 0x28) 60 - #define OMAP_DMA4_CAPS_0 (OMAP24XX_DMA_BASE + 0x64) 61 - #define OMAP_DMA4_CAPS_2 (OMAP24XX_DMA_BASE + 0x6c) 62 - #define OMAP_DMA4_CAPS_3 (OMAP24XX_DMA_BASE + 0x70) 63 - #define OMAP_DMA4_CAPS_4 (OMAP24XX_DMA_BASE + 0x74) 48 + #if defined(CONFIG_ARCH_OMAP3) 49 + #define OMAP_DMA4_BASE (L4_34XX_BASE + 0x56000) 50 + #else /* CONFIG_ARCH_OMAP2 */ 51 + #define OMAP_DMA4_BASE (L4_24XX_BASE + 0x56000) 52 + #endif 53 + 54 + #define OMAP_DMA4_REVISION (OMAP_DMA4_BASE + 0x00) 55 + #define OMAP_DMA4_GCR_REG (OMAP_DMA4_BASE + 0x78) 56 + #define OMAP_DMA4_IRQSTATUS_L0 (OMAP_DMA4_BASE + 0x08) 57 + #define OMAP_DMA4_IRQSTATUS_L1 (OMAP_DMA4_BASE + 0x0c) 58 + #define OMAP_DMA4_IRQSTATUS_L2 (OMAP_DMA4_BASE + 0x10) 59 + #define OMAP_DMA4_IRQSTATUS_L3 (OMAP_DMA4_BASE + 0x14) 60 + #define OMAP_DMA4_IRQENABLE_L0 (OMAP_DMA4_BASE + 0x18) 61 + #define OMAP_DMA4_IRQENABLE_L1 (OMAP_DMA4_BASE + 0x1c) 62 + #define OMAP_DMA4_IRQENABLE_L2 (OMAP_DMA4_BASE + 0x20) 63 + #define OMAP_DMA4_IRQENABLE_L3 (OMAP_DMA4_BASE + 0x24) 64 + #define OMAP_DMA4_SYSSTATUS (OMAP_DMA4_BASE + 0x28) 65 + #define OMAP_DMA4_OCP_SYSCONFIG (OMAP_DMA4_BASE + 0x2c) 66 + #define OMAP_DMA4_CAPS_0 (OMAP_DMA4_BASE + 0x64) 67 + #define OMAP_DMA4_CAPS_2 (OMAP_DMA4_BASE + 0x6c) 68 + #define OMAP_DMA4_CAPS_3 (OMAP_DMA4_BASE + 0x70) 69 + #define OMAP_DMA4_CAPS_4 (OMAP_DMA4_BASE + 0x74) 64 70 65 71 #ifdef CONFIG_ARCH_OMAP1 66 72 ··· 92 86 #define OMAP_LOGICAL_DMA_CH_COUNT 32 /* REVISIT: Is this 32 + 2? */ 93 87 94 88 /* Common channel specific registers for omap2 */ 95 - #define OMAP_DMA_CCR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x80) 96 - #define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x84) 97 - #define OMAP_DMA_CICR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x88) 98 - #define OMAP_DMA_CSR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x8c) 99 - #define OMAP_DMA_CSDP_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x90) 100 - #define OMAP_DMA_CEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x94) 101 - #define OMAP_DMA_CFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x98) 102 - #define OMAP_DMA_CSEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa4) 103 - #define OMAP_DMA_CSFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa8) 104 - #define OMAP_DMA_CDEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xac) 105 - #define OMAP_DMA_CDFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb0) 106 - #define OMAP_DMA_CSAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb4) 107 - #define OMAP_DMA_CDAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb8) 89 + #define OMAP_DMA_CCR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x80) 90 + #define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x84) 91 + #define OMAP_DMA_CICR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x88) 92 + #define OMAP_DMA_CSR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x8c) 93 + #define OMAP_DMA_CSDP_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x90) 94 + #define OMAP_DMA_CEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x94) 95 + #define OMAP_DMA_CFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x98) 96 + #define OMAP_DMA_CSEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa4) 97 + #define OMAP_DMA_CSFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa8) 98 + #define OMAP_DMA_CDEI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xac) 99 + #define OMAP_DMA_CDFI_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb0) 100 + #define OMAP_DMA_CSAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb4) 101 + #define OMAP_DMA_CDAC_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xb8) 108 102 109 103 #endif 110 104 ··· 119 113 #define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a) 120 114 121 115 /* Channel specific registers only on omap2 */ 122 - #define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x9c) 123 - #define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa0) 124 - #define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xbc) 125 - #define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc0) 126 - #define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc4) 116 + #define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0x9c) 117 + #define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xa0) 118 + #define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xbc) 119 + #define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc0) 120 + #define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP_DMA4_BASE + 0x60 * (n) + 0xc4) 127 121 128 122 /*----------------------------------------------------------------------------*/ 129 123 ··· 303 297 #define OMAP_DMA_SYNC_ELEMENT 0x00 304 298 #define OMAP_DMA_SYNC_FRAME 0x01 305 299 #define OMAP_DMA_SYNC_BLOCK 0x02 300 + #define OMAP_DMA_SYNC_PACKET 0x03 301 + 302 + #define OMAP_DMA_SRC_SYNC 0x01 303 + #define OMAP_DMA_DST_SYNC 0x00 306 304 307 305 #define OMAP_DMA_PORT_EMIFF 0x00 308 306 #define OMAP_DMA_PORT_EMIFS 0x01 ··· 319 309 #define OMAP_DMA_AMODE_POST_INC 0x01 320 310 #define OMAP_DMA_AMODE_SINGLE_IDX 0x02 321 311 #define OMAP_DMA_AMODE_DOUBLE_IDX 0x03 312 + 313 + #define DMA_DEFAULT_FIFO_DEPTH 0x10 314 + #define DMA_DEFAULT_ARB_RATE 0x01 315 + /* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */ 316 + #define DMA_THREAD_RESERVE_NORM (0x00 << 12) /* Def */ 317 + #define DMA_THREAD_RESERVE_ONET (0x01 << 12) 318 + #define DMA_THREAD_RESERVE_TWOT (0x02 << 12) 319 + #define DMA_THREAD_RESERVE_THREET (0x03 << 12) 320 + #define DMA_THREAD_FIFO_NONE (0x00 << 14) /* Def */ 321 + #define DMA_THREAD_FIFO_75 (0x01 << 14) 322 + #define DMA_THREAD_FIFO_25 (0x02 << 14) 323 + #define DMA_THREAD_FIFO_50 (0x03 << 14) 324 + 325 + /* Chaining modes*/ 326 + #ifndef CONFIG_ARCH_OMAP1 327 + #define OMAP_DMA_STATIC_CHAIN 0x1 328 + #define OMAP_DMA_DYNAMIC_CHAIN 0x2 329 + #define OMAP_DMA_CHAIN_ACTIVE 0x1 330 + #define OMAP_DMA_CHAIN_INACTIVE 0x0 331 + #endif 332 + 333 + #define DMA_CH_PRIO_HIGH 0x1 334 + #define DMA_CH_PRIO_LOW 0x0 /* Def */ 322 335 323 336 /* LCD DMA block numbers */ 324 337 enum { ··· 392 359 int src_or_dst_synch; /* source synch(1) or destination synch(0) */ 393 360 394 361 int ie; /* interrupt enabled */ 362 + 363 + unsigned char read_prio;/* read priority */ 364 + unsigned char write_prio;/* write priority */ 365 + 366 + #ifndef CONFIG_ARCH_OMAP1 367 + enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */ 368 + #endif 395 369 }; 396 370 397 371 ··· 449 409 extern int omap_get_dma_src_addr_counter(int lch); 450 410 extern void omap_clear_dma(int lch); 451 411 extern int omap_dma_running(void); 412 + extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth, 413 + int tparams); 414 + extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio, 415 + unsigned char write_prio); 416 + 417 + /* Chaining APIs */ 418 + #ifndef CONFIG_ARCH_OMAP1 419 + extern int omap_request_dma_chain(int dev_id, const char *dev_name, 420 + void (*callback) (int chain_id, u16 ch_status, 421 + void *data), 422 + int *chain_id, int no_of_chans, 423 + int chain_mode, 424 + struct omap_dma_channel_params params); 425 + extern int omap_free_dma_chain(int chain_id); 426 + extern int omap_dma_chain_a_transfer(int chain_id, int src_start, 427 + int dest_start, int elem_count, 428 + int frame_count, void *callbk_data); 429 + extern int omap_start_dma_chain_transfers(int chain_id); 430 + extern int omap_stop_dma_chain_transfers(int chain_id); 431 + extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi); 432 + extern int omap_get_dma_chain_dst_pos(int chain_id); 433 + extern int omap_get_dma_chain_src_pos(int chain_id); 434 + 435 + extern int omap_modify_dma_chain_params(int chain_id, 436 + struct omap_dma_channel_params params); 437 + extern int omap_dma_chain_status(int chain_id); 438 + #endif 452 439 453 440 /* LCD DMA functions */ 454 441 extern int omap_request_lcd_dma(void (* callback)(u16 status, void *data),