Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: omap-dma: Support for slave devices with data port window

Based on the src/dst_port_window_size - if it is set - configure the DMA
channel to use double indexing in order to be able to loop within the
address window.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>

authored by

Peter Ujfalusi and committed by
Vinod Koul
201ac486 54cd2558

+61 -2
+61 -2
drivers/dma/omap-dma.c
··· 166 166 CSDP_DST_BURST_16 = 1 << 14, 167 167 CSDP_DST_BURST_32 = 2 << 14, 168 168 CSDP_DST_BURST_64 = 3 << 14, 169 + CSDP_WRITE_NON_POSTED = 0 << 16, 170 + CSDP_WRITE_POSTED = 1 << 16, 171 + CSDP_WRITE_LAST_NON_POSTED = 2 << 16, 169 172 170 173 CICR_TOUT_IE = BIT(0), /* OMAP1 only */ 171 174 CICR_DROP_IE = BIT(1), ··· 884 881 unsigned i, es, en, frame_bytes; 885 882 bool ll_failed = false; 886 883 u32 burst; 884 + u32 port_window, port_window_bytes; 887 885 888 886 if (dir == DMA_DEV_TO_MEM) { 889 887 dev_addr = c->cfg.src_addr; 890 888 dev_width = c->cfg.src_addr_width; 891 889 burst = c->cfg.src_maxburst; 890 + port_window = c->cfg.src_port_window_size; 892 891 } else if (dir == DMA_MEM_TO_DEV) { 893 892 dev_addr = c->cfg.dst_addr; 894 893 dev_width = c->cfg.dst_addr_width; 895 894 burst = c->cfg.dst_maxburst; 895 + port_window = c->cfg.dst_port_window_size; 896 896 } else { 897 897 dev_err(chan->device->dev, "%s: bad direction?\n", __func__); 898 898 return NULL; ··· 916 910 return NULL; 917 911 } 918 912 913 + /* When the port_window is used, one frame must cover the window */ 914 + if (port_window) { 915 + burst = port_window; 916 + port_window_bytes = port_window * es_bytes[es]; 917 + } 918 + 919 919 /* Now allocate and setup the descriptor. */ 920 920 d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC); 921 921 if (!d) ··· 933 921 934 922 d->ccr = c->ccr | CCR_SYNC_FRAME; 935 923 if (dir == DMA_DEV_TO_MEM) { 936 - d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_CONSTANT; 937 924 d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED; 925 + 926 + d->ccr |= CCR_DST_AMODE_POSTINC; 927 + if (port_window) { 928 + d->ccr |= CCR_SRC_AMODE_DBLIDX; 929 + d->ei = 1; 930 + /* 931 + * One frame covers the port_window and by configure 932 + * the source frame index to be -1 * (port_window - 1) 933 + * we instruct the sDMA that after a frame is processed 934 + * it should move back to the start of the window. 935 + */ 936 + d->fi = -(port_window_bytes - 1); 937 + 938 + if (port_window_bytes >= 64) 939 + d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED; 940 + else if (port_window_bytes >= 32) 941 + d->csdp = CSDP_SRC_BURST_32 | CSDP_SRC_PACKED; 942 + else if (port_window_bytes >= 16) 943 + d->csdp = CSDP_SRC_BURST_16 | CSDP_SRC_PACKED; 944 + } else { 945 + d->ccr |= CCR_SRC_AMODE_CONSTANT; 946 + } 938 947 } else { 939 - d->ccr |= CCR_DST_AMODE_CONSTANT | CCR_SRC_AMODE_POSTINC; 940 948 d->csdp = CSDP_SRC_BURST_64 | CSDP_SRC_PACKED; 949 + 950 + d->ccr |= CCR_SRC_AMODE_POSTINC; 951 + if (port_window) { 952 + d->ccr |= CCR_DST_AMODE_DBLIDX; 953 + 954 + if (port_window_bytes >= 64) 955 + d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED; 956 + else if (port_window_bytes >= 32) 957 + d->csdp = CSDP_DST_BURST_32 | CSDP_DST_PACKED; 958 + else if (port_window_bytes >= 16) 959 + d->csdp = CSDP_DST_BURST_16 | CSDP_DST_PACKED; 960 + } else { 961 + d->ccr |= CCR_DST_AMODE_CONSTANT; 962 + } 941 963 } 942 964 943 965 d->cicr = CICR_DROP_IE | CICR_BLOCK_IE; ··· 989 943 d->ccr |= CCR_TRIGGER_SRC; 990 944 991 945 d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE; 946 + 947 + if (port_window) 948 + d->csdp |= CSDP_WRITE_LAST_NON_POSTED; 992 949 } 993 950 if (od->plat->errata & DMA_ERRATA_PARALLEL_CHANNELS) 994 951 d->clnk_ctrl = c->dma_ch; ··· 1017 968 osg->addr = sg_dma_address(sgent); 1018 969 osg->en = en; 1019 970 osg->fn = sg_dma_len(sgent) / frame_bytes; 971 + if (port_window && dir == DMA_MEM_TO_DEV) { 972 + osg->ei = 1; 973 + /* 974 + * One frame covers the port_window and by configure 975 + * the source frame index to be -1 * (port_window - 1) 976 + * we instruct the sDMA that after a frame is processed 977 + * it should move back to the start of the window. 978 + */ 979 + osg->fi = -(port_window_bytes - 1); 980 + } 1020 981 1021 982 if (d->using_ll) { 1022 983 osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,