Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0 2 : : // Copyright (C) 2013,2018 Intel Corporation 3 : : 4 : : #include <linux/bitops.h> 5 : : #include <linux/dmaengine.h> 6 : : #include <linux/errno.h> 7 : : #include <linux/slab.h> 8 : : #include <linux/types.h> 9 : : 10 : : #include "internal.h" 11 : : 12 : 0 : static void idma32_initialize_chan(struct dw_dma_chan *dwc) 13 : : { 14 : 0 : u32 cfghi = 0; 15 : 0 : u32 cfglo = 0; 16 : : 17 : : /* Set default burst alignment */ 18 : 0 : cfglo |= IDMA32C_CFGL_DST_BURST_ALIGN | IDMA32C_CFGL_SRC_BURST_ALIGN; 19 : : 20 : : /* Low 4 bits of the request lines */ 21 : 0 : cfghi |= IDMA32C_CFGH_DST_PER(dwc->dws.dst_id & 0xf); 22 : 0 : cfghi |= IDMA32C_CFGH_SRC_PER(dwc->dws.src_id & 0xf); 23 : : 24 : : /* Request line extension (2 bits) */ 25 : 0 : cfghi |= IDMA32C_CFGH_DST_PER_EXT(dwc->dws.dst_id >> 4 & 0x3); 26 : 0 : cfghi |= IDMA32C_CFGH_SRC_PER_EXT(dwc->dws.src_id >> 4 & 0x3); 27 : : 28 : 0 : channel_writel(dwc, CFG_LO, cfglo); 29 : 0 : channel_writel(dwc, CFG_HI, cfghi); 30 : 0 : } 31 : : 32 : 0 : static void idma32_suspend_chan(struct dw_dma_chan *dwc, bool drain) 33 : : { 34 : 0 : u32 cfglo = channel_readl(dwc, CFG_LO); 35 : : 36 [ # # ]: 0 : if (drain) 37 : 0 : cfglo |= IDMA32C_CFGL_CH_DRAIN; 38 : : 39 : 0 : channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP); 40 : 0 : } 41 : : 42 : 0 : static void idma32_resume_chan(struct dw_dma_chan *dwc, bool drain) 43 : : { 44 : 0 : u32 cfglo = channel_readl(dwc, CFG_LO); 45 : : 46 [ # # ]: 0 : if (drain) 47 : 0 : cfglo &= ~IDMA32C_CFGL_CH_DRAIN; 48 : : 49 : 0 : channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP); 50 : 0 : } 51 : : 52 : 0 : static u32 idma32_bytes2block(struct dw_dma_chan *dwc, 53 : : size_t bytes, unsigned int width, size_t *len) 54 : : { 55 : 0 : u32 block; 56 : : 57 [ # # ]: 0 : if (bytes > dwc->block_size) { 58 : 0 : block = dwc->block_size; 59 : 0 : *len = dwc->block_size; 60 : : } else { 61 : 0 : block = bytes; 62 : 0 : *len = bytes; 63 : : } 64 : : 65 : 0 : return block; 66 : : } 67 : : 68 : 0 : static size_t idma32_block2bytes(struct dw_dma_chan *dwc, u32 block, u32 width) 69 : : { 70 : 0 : return IDMA32C_CTLH_BLOCK_TS(block); 71 : : } 72 : : 73 : 0 : static u32 idma32_prepare_ctllo(struct dw_dma_chan *dwc) 74 : : { 75 : 0 : struct dma_slave_config *sconfig = &dwc->dma_sconfig; 76 [ # # ]: 0 : bool is_slave = is_slave_direction(dwc->direction); 77 [ # # ]: 0 : u8 smsize = is_slave ? sconfig->src_maxburst : IDMA32_MSIZE_8; 78 [ # # ]: 0 : u8 dmsize = is_slave ? sconfig->dst_maxburst : IDMA32_MSIZE_8; 79 : : 80 : 0 : return DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN | 81 : 0 : DWC_CTLL_DST_MSIZE(dmsize) | DWC_CTLL_SRC_MSIZE(smsize); 82 : : } 83 : : 84 : 0 : static void idma32_encode_maxburst(struct dw_dma_chan *dwc, u32 *maxburst) 85 : : { 86 [ # # ]: 0 : *maxburst = *maxburst > 1 ? fls(*maxburst) - 1 : 0; 87 : 0 : } 88 : : 89 : 0 : static void idma32_set_device_name(struct dw_dma *dw, int id) 90 : : { 91 : 0 : snprintf(dw->name, sizeof(dw->name), "idma32:dmac%d", id); 92 : 0 : } 93 : : 94 : : /* 95 : : * Program FIFO size of channels. 96 : : * 97 : : * By default full FIFO (512 bytes) is assigned to channel 0. Here we 98 : : * slice FIFO on equal parts between channels. 99 : : */ 100 : 0 : static void idma32_fifo_partition(struct dw_dma *dw) 101 : : { 102 : 0 : u64 value = IDMA32C_FP_PSIZE_CH0(64) | IDMA32C_FP_PSIZE_CH1(64) | 103 : : IDMA32C_FP_UPDATE; 104 : 0 : u64 fifo_partition = 0; 105 : : 106 : : /* Fill FIFO_PARTITION low bits (Channels 0..1, 4..5) */ 107 : 0 : fifo_partition |= value << 0; 108 : : 109 : : /* Fill FIFO_PARTITION high bits (Channels 2..3, 6..7) */ 110 : 0 : fifo_partition |= value << 32; 111 : : 112 : : /* Program FIFO Partition registers - 64 bytes per channel */ 113 : 0 : idma32_writeq(dw, FIFO_PARTITION1, fifo_partition); 114 : 0 : idma32_writeq(dw, FIFO_PARTITION0, fifo_partition); 115 : : } 116 : : 117 : 0 : static void idma32_disable(struct dw_dma *dw) 118 : : { 119 : 0 : do_dw_dma_off(dw); 120 : 0 : idma32_fifo_partition(dw); 121 : 0 : } 122 : : 123 : 0 : static void idma32_enable(struct dw_dma *dw) 124 : : { 125 : 0 : idma32_fifo_partition(dw); 126 : 0 : do_dw_dma_on(dw); 127 : 0 : } 128 : : 129 : 0 : int idma32_dma_probe(struct dw_dma_chip *chip) 130 : : { 131 : 0 : struct dw_dma *dw; 132 : : 133 : 0 : dw = devm_kzalloc(chip->dev, sizeof(*dw), GFP_KERNEL); 134 [ # # ]: 0 : if (!dw) 135 : : return -ENOMEM; 136 : : 137 : : /* Channel operations */ 138 : 0 : dw->initialize_chan = idma32_initialize_chan; 139 : 0 : dw->suspend_chan = idma32_suspend_chan; 140 : 0 : dw->resume_chan = idma32_resume_chan; 141 : 0 : dw->prepare_ctllo = idma32_prepare_ctllo; 142 : 0 : dw->encode_maxburst = idma32_encode_maxburst; 143 : 0 : dw->bytes2block = idma32_bytes2block; 144 : 0 : dw->block2bytes = idma32_block2bytes; 145 : : 146 : : /* Device operations */ 147 : 0 : dw->set_device_name = idma32_set_device_name; 148 : 0 : dw->disable = idma32_disable; 149 : 0 : dw->enable = idma32_enable; 150 : : 151 : 0 : chip->dw = dw; 152 : 0 : return do_dma_probe(chip); 153 : : } 154 : : EXPORT_SYMBOL_GPL(idma32_dma_probe); 155 : : 156 : 0 : int idma32_dma_remove(struct dw_dma_chip *chip) 157 : : { 158 : 0 : return do_dma_remove(chip); 159 : : } 160 : : EXPORT_SYMBOL_GPL(idma32_dma_remove);