1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) ST-Ericsson SA 2007-2010 4 * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson 5 * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson 6 */ 7 8 9#ifndef STE_DMA40_H 10#define STE_DMA40_H 11 12#include <linux/dmaengine.h> 13#include <linux/scatterlist.h> 14#include <linux/workqueue.h> 15#include <linux/interrupt.h> 16 17/* 18 * Maxium size for a single dma descriptor 19 * Size is limited to 16 bits. 20 * Size is in the units of addr-widths (1,2,4,8 bytes) 21 * Larger transfers will be split up to multiple linked desc 22 */ 23#define STEDMA40_MAX_SEG_SIZE 0xFFFF 24 25/* dev types for memcpy */ 26#define STEDMA40_DEV_DST_MEMORY (-1) 27#define STEDMA40_DEV_SRC_MEMORY (-1) 28 29enum stedma40_mode { 30 STEDMA40_MODE_LOGICAL = 0, 31 STEDMA40_MODE_PHYSICAL, 32 STEDMA40_MODE_OPERATION, 33}; 34 35enum stedma40_mode_opt { 36 STEDMA40_PCHAN_BASIC_MODE = 0, 37 STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0, 38 STEDMA40_PCHAN_MODULO_MODE, 39 STEDMA40_PCHAN_DOUBLE_DST_MODE, 40 STEDMA40_LCHAN_SRC_PHY_DST_LOG, 41 STEDMA40_LCHAN_SRC_LOG_DST_PHY, 42}; 43 44#define STEDMA40_ESIZE_8_BIT 0x0 45#define STEDMA40_ESIZE_16_BIT 0x1 46#define STEDMA40_ESIZE_32_BIT 0x2 47#define STEDMA40_ESIZE_64_BIT 0x3 48 49/* The value 4 indicates that PEN-reg shall be set to 0 */ 50#define STEDMA40_PSIZE_PHY_1 0x4 51#define STEDMA40_PSIZE_PHY_2 0x0 52#define STEDMA40_PSIZE_PHY_4 0x1 53#define STEDMA40_PSIZE_PHY_8 0x2 54#define STEDMA40_PSIZE_PHY_16 0x3 55 56/* 57 * The number of elements differ in logical and 58 * physical mode 59 */ 60#define STEDMA40_PSIZE_LOG_1 STEDMA40_PSIZE_PHY_2 61#define STEDMA40_PSIZE_LOG_4 STEDMA40_PSIZE_PHY_4 62#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8 63#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16 64 65/* Maximum number of possible physical channels */ 66#define STEDMA40_MAX_PHYS 32 67 68enum stedma40_flow_ctrl { 69 STEDMA40_NO_FLOW_CTRL, 70 STEDMA40_FLOW_CTRL, 71}; 72 73/** 74 * struct stedma40_half_channel_info - dst/src channel configuration 75 * 76 * @big_endian: true if the src/dst should be read as big endian 77 * @data_width: Data width of the src/dst hardware 78 * @p_size: Burst size 79 * @flow_ctrl: Flow control on/off. 80 */ 81struct stedma40_half_channel_info { 82 bool big_endian; 83 enum dma_slave_buswidth data_width; 84 int psize; 85 enum stedma40_flow_ctrl flow_ctrl; 86}; 87 88/** 89 * struct stedma40_chan_cfg - Structure to be filled by client drivers. 90 * 91 * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH 92 * @high_priority: true if high-priority 93 * @realtime: true if realtime mode is to be enabled. Only available on DMA40 94 * version 3+, i.e DB8500v2+ 95 * @mode: channel mode: physical, logical, or operation 96 * @mode_opt: options for the chosen channel mode 97 * @dev_type: src/dst device type (driver uses dir to figure out which) 98 * @src_info: Parameters for dst half channel 99 * @dst_info: Parameters for dst half channel 100 * @use_fixed_channel: if true, use physical channel specified by phy_channel 101 * @phy_channel: physical channel to use, only if use_fixed_channel is true 102 * 103 * This structure has to be filled by the client drivers. 104 * It is recommended to do all dma configurations for clients in the machine. 105 * 106 */ 107struct stedma40_chan_cfg { 108 enum dma_transfer_direction dir; 109 bool high_priority; 110 bool realtime; 111 enum stedma40_mode mode; 112 enum stedma40_mode_opt mode_opt; 113 int dev_type; 114 struct stedma40_half_channel_info src_info; 115 struct stedma40_half_channel_info dst_info; 116 117 bool use_fixed_channel; 118 int phy_channel; 119}; 120 121/** 122 * struct stedma40_platform_data - Configuration struct for the dma device. 123 * 124 * @dev_tx: mapping between destination event line and io address 125 * @dev_rx: mapping between source event line and io address 126 * @disabled_channels: A vector, ending with -1, that marks physical channels 127 * that are for different reasons not available for the driver. 128 * @soft_lli_chans: A vector, that marks physical channels will use LLI by SW 129 * which avoids HW bug that exists in some versions of the controller. 130 * SoftLLI introduces relink overhead that could impact performace for 131 * certain use cases. 132 * @num_of_soft_lli_chans: The number of channels that needs to be configured 133 * to use SoftLLI. 134 * @use_esram_lcla: flag for mapping the lcla into esram region 135 * @num_of_memcpy_chans: The number of channels reserved for memcpy. 136 * @num_of_phy_chans: The number of physical channels implemented in HW. 137 * 0 means reading the number of channels from DMA HW but this is only valid 138 * for 'multiple of 4' channels, like 8. 139 */ 140struct stedma40_platform_data { 141 int disabled_channels[STEDMA40_MAX_PHYS]; 142 int *soft_lli_chans; 143 int num_of_soft_lli_chans; 144 bool use_esram_lcla; 145 int num_of_memcpy_chans; 146 int num_of_phy_chans; 147}; 148 149#ifdef CONFIG_STE_DMA40 150 151/** 152 * stedma40_filter() - Provides stedma40_chan_cfg to the 153 * ste_dma40 dma driver via the dmaengine framework. 154 * does some checking of what's provided. 155 * 156 * Never directly called by client. It used by dmaengine. 157 * @chan: dmaengine handle. 158 * @data: Must be of type: struct stedma40_chan_cfg and is 159 * the configuration of the framework. 160 * 161 * 162 */ 163 164bool stedma40_filter(struct dma_chan *chan, void *data); 165 166/** 167 * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave 168 * (=device) 169 * 170 * @chan: dmaengine handle 171 * @addr: source or destination physicall address. 172 * @size: bytes to transfer 173 * @direction: direction of transfer 174 * @flags: is actually enum dma_ctrl_flags. See dmaengine.h 175 */ 176 177static inline struct 178dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, 179 dma_addr_t addr, 180 unsigned int size, 181 enum dma_transfer_direction direction, 182 unsigned long flags) 183{ 184 struct scatterlist sg; 185 sg_init_table(&sg, 1); 186 sg.dma_address = addr; 187 sg.length = size; 188 189 return dmaengine_prep_slave_sg(chan, &sg, 1, direction, flags); 190} 191 192#else 193static inline bool stedma40_filter(struct dma_chan *chan, void *data) 194{ 195 return false; 196} 197 198static inline struct 199dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan, 200 dma_addr_t addr, 201 unsigned int size, 202 enum dma_transfer_direction direction, 203 unsigned long flags) 204{ 205 return NULL; 206} 207#endif 208 209#endif 210