1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2016 Intel Corporation. All rights reserved. 4 * 5 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 6 * Keyon Jie <yang.jie@linux.intel.com> 7 */ 8 9 #ifndef __SOF_DRIVERS_DW_DMA_H__ 10 #define __SOF_DRIVERS_DW_DMA_H__ 11 12 #include <platform/drivers/dw-dma.h> 13 #include <sof/bit.h> 14 #include <sof/common.h> 15 #include <sof/lib/dma.h> 16 #include <sof/trace/trace.h> 17 #include <user/trace.h> 18 #include <stdint.h> 19 20 /* channel registers */ 21 #define DW_MAX_CHAN 8 22 #define DW_FIFO_SIZE 0x80 23 #define DW_CHAN_SIZE 0x58 24 #define DW_CHAN_OFFSET(chan) (DW_CHAN_SIZE * (chan)) 25 26 #define DW_SAR(chan) (0x00 + DW_CHAN_OFFSET(chan)) 27 #define DW_DAR(chan) (0x08 + DW_CHAN_OFFSET(chan)) 28 #define DW_LLP(chan) (0x10 + DW_CHAN_OFFSET(chan)) 29 #define DW_CTRL_LOW(chan) (0x18 + DW_CHAN_OFFSET(chan)) 30 #define DW_CTRL_HIGH(chan) (0x1C + DW_CHAN_OFFSET(chan)) 31 #define DW_CFG_LOW(chan) (0x40 + DW_CHAN_OFFSET(chan)) 32 #define DW_CFG_HIGH(chan) (0x44 + DW_CHAN_OFFSET(chan)) 33 #define DW_DSR(chan) (0x50 + DW_CHAN_OFFSET(chan)) 34 35 /* common registers */ 36 #define DW_RAW_TFR 0x2C0 37 #define DW_RAW_BLOCK 0x2C8 38 #define DW_RAW_SRC_TRAN 0x2D0 39 #define DW_RAW_DST_TRAN 0x2D8 40 #define DW_RAW_ERR 0x2E0 41 #define DW_STATUS_TFR 0x2E8 42 #define DW_STATUS_BLOCK 0x2F0 43 #define DW_STATUS_SRC_TRAN 0x2F8 44 #define DW_STATUS_DST_TRAN 0x300 45 #define DW_STATUS_ERR 0x308 46 #define DW_MASK_TFR 0x310 47 #define DW_MASK_BLOCK 0x318 48 #define DW_MASK_SRC_TRAN 0x320 49 #define DW_MASK_DST_TRAN 0x328 50 #define DW_MASK_ERR 0x330 51 #define DW_CLEAR_TFR 0x338 52 #define DW_CLEAR_BLOCK 0x340 53 #define DW_CLEAR_SRC_TRAN 0x348 54 #define DW_CLEAR_DST_TRAN 0x350 55 #define DW_CLEAR_ERR 0x358 56 #define DW_INTR_STATUS 0x360 57 #define DW_DMA_CFG 0x398 58 #define DW_DMA_CHAN_EN 0x3A0 59 #define DW_FIFO_PART0_LO 0x400 60 #define DW_FIFO_PART0_HI 0x404 61 #define DW_FIFO_PART1_LO 0x408 62 #define DW_FIFO_PART1_HI 0x40C 63 64 /* channel bits */ 65 #define DW_CHAN_WRITE_EN_ALL MASK(2 * DW_MAX_CHAN - 1, DW_MAX_CHAN) 66 #define DW_CHAN_WRITE_EN(chan) BIT((chan) + DW_MAX_CHAN) 67 #define DW_CHAN_ALL MASK(DW_MAX_CHAN - 1, 0) 68 #define DW_CHAN(chan) BIT(chan) 69 #define DW_CHAN_MASK_ALL DW_CHAN_WRITE_EN_ALL 70 #define DW_CHAN_MASK(chan) DW_CHAN_WRITE_EN(chan) 71 #define DW_CHAN_UNMASK_ALL (DW_CHAN_WRITE_EN_ALL | DW_CHAN_ALL) 72 #define DW_CHAN_UNMASK(chan) (DW_CHAN_WRITE_EN(chan) | DW_CHAN(chan)) 73 74 /* CFG_LO */ 75 #define DW_CFGL_DRAIN BIT(10) 76 #define DW_CFGL_FIFO_EMPTY BIT(9) 77 #define DW_CFGL_SUSPEND BIT(8) 78 79 /* CTL_LO */ 80 #define DW_CTLL_RELOAD_DST BIT(31) 81 #define DW_CTLL_RELOAD_SRC BIT(30) 82 #define DW_CTLL_LLP_S_EN BIT(28) 83 #define DW_CTLL_LLP_D_EN BIT(27) 84 #define DW_CTLL_SMS(x) SET_BIT(25, x) 85 #define DW_CTLL_DMS(x) SET_BIT(23, x) 86 #define DW_CTLL_FC_P2P SET_BITS(21, 20, 3) 87 #define DW_CTLL_FC_P2M SET_BITS(21, 20, 2) 88 #define DW_CTLL_FC_M2P SET_BITS(21, 20, 1) 89 #define DW_CTLL_FC_M2M SET_BITS(21, 20, 0) 90 #define DW_CTLL_D_SCAT_EN BIT(18) 91 #define DW_CTLL_S_GATH_EN BIT(17) 92 #define DW_CTLL_SRC_MSIZE(x) SET_BITS(16, 14, x) 93 #define DW_CTLL_DST_MSIZE(x) SET_BITS(13, 11, x) 94 #define DW_CTLL_SRC_FIX SET_BITS(10, 9, 2) 95 #define DW_CTLL_SRC_DEC SET_BITS(10, 9, 1) 96 #define DW_CTLL_SRC_INC SET_BITS(10, 9, 0) 97 #define DW_CTLL_DST_FIX SET_BITS(8, 7, 2) 98 #define DW_CTLL_DST_DEC SET_BITS(8, 7, 1) 99 #define DW_CTLL_DST_INC SET_BITS(8, 7, 0) 100 #define DW_CTLL_SRC_WIDTH(x) SET_BITS(6, 4, x) 101 #define DW_CTLL_DST_WIDTH(x) SET_BITS(3, 1, x) 102 #define DW_CTLL_INT_EN BIT(0) 103 #define DW_CTLL_SRC_WIDTH_MASK MASK(6, 4) 104 #define DW_CTLL_SRC_WIDTH_SHIFT 4 105 #define DW_CTLL_DST_WIDTH_MASK MASK(3, 1) 106 #define DW_CTLL_DST_WIDTH_SHIFT 1 107 108 /* DSR */ 109 #define DW_DSR_DSC(x) SET_BITS(31, 20, x) 110 #define DW_DSR_DSI(x) SET_BITS(19, 0, x) 111 112 /* FIFO_PART */ 113 #define DW_FIFO_UPD BIT(26) 114 #define DW_FIFO_CHx(x) SET_BITS(25, 13, x) 115 #define DW_FIFO_CHy(x) SET_BITS(12, 0, x) 116 117 /* number of tries to wait for reset */ 118 #define DW_DMA_CFG_TRIES 10000 119 120 /* channel drain timeout in microseconds */ 121 #define DW_DMA_TIMEOUT 1333 122 123 /* min number of elems for config with irq disabled */ 124 #define DW_DMA_CFG_NO_IRQ_MIN_ELEMS 3 125 126 /* linked list item address */ 127 #define DW_DMA_LLI_ADDRESS(lli, dir) \ 128 (((dir) == DMA_DIR_MEM_TO_DEV) ? ((lli)->sar) : ((lli)->dar)) 129 130 #define DW_DMA_BUFFER_ALIGNMENT 0x4 131 #define DW_DMA_COPY_ALIGNMENT 0x4 132 133 /* LLI address alignment, in Bytes */ 134 #ifndef DW_DMA_LLI_ALIGN 135 #define DW_DMA_LLI_ALIGN 32 136 #endif 137 138 /* TODO: add FIFO sizes */ 139 struct dw_chan_data { 140 uint16_t class; 141 uint16_t weight; 142 }; 143 144 struct dw_drv_plat_data { 145 struct dw_chan_data chan[DW_MAX_CHAN]; 146 }; 147 148 /* DMA descriptor used by HW */ 149 struct dw_lli { 150 uint32_t sar; 151 uint32_t dar; 152 uint32_t llp; 153 uint32_t ctrl_lo; 154 uint32_t ctrl_hi; 155 uint32_t sstat; 156 uint32_t dstat; 157 158 /* align to required bytes to make sure every item 159 * is aligned in case of more than two items 160 */ 161 uint8_t reserved[DW_DMA_LLI_ALIGN - sizeof(uint32_t) * 7]; 162 } __packed; 163 164 extern const struct dma_ops dw_dma_ops; 165 166 #endif /* __SOF_DRIVERS_DW_DMA_H__ */ 167