1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Omnitek Scatter-Gather DMA Controller 4 * 5 * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. 6 * All rights reserved. 7 */ 8 9 #include <linux/string.h> 10 #include <linux/io.h> 11 #include <linux/pci_regs.h> 12 #include <linux/spinlock.h> 13 14 #include "cobalt-driver.h" 15 #include "cobalt-omnitek.h" 16 17 /* descriptor */ 18 #define END_OF_CHAIN (1 << 1) 19 #define INTERRUPT_ENABLE (1 << 2) 20 #define WRITE_TO_PCI (1 << 3) 21 #define READ_FROM_PCI (0 << 3) 22 #define DESCRIPTOR_FLAG_MSK (END_OF_CHAIN | INTERRUPT_ENABLE | WRITE_TO_PCI) 23 #define NEXT_ADRS_MSK 0xffffffe0 24 25 /* control/status register */ 26 #define ENABLE (1 << 0) 27 #define START (1 << 1) 28 #define ABORT (1 << 2) 29 #define DONE (1 << 4) 30 #define SG_INTERRUPT (1 << 5) 31 #define EVENT_INTERRUPT (1 << 6) 32 #define SCATTER_GATHER_MODE (1 << 8) 33 #define DISABLE_VIDEO_RESYNC (1 << 9) 34 #define EVENT_INTERRUPT_ENABLE (1 << 10) 35 #define DIRECTIONAL_MSK (3 << 16) 36 #define INPUT_ONLY (0 << 16) 37 #define OUTPUT_ONLY (1 << 16) 38 #define BIDIRECTIONAL (2 << 16) 39 #define DMA_TYPE_MEMORY (0 << 18) 40 #define DMA_TYPE_FIFO (1 << 18) 41 42 #define BASE (cobalt->bar0) 43 #define CAPABILITY_HEADER (BASE) 44 #define CAPABILITY_REGISTER (BASE + 0x04) 45 #define PCI_64BIT (1 << 8) 46 #define LOCAL_64BIT (1 << 9) 47 #define INTERRUPT_STATUS (BASE + 0x08) 48 #define PCI(c) (BASE + 0x40 + ((c) * 0x40)) 49 #define SIZE(c) (BASE + 0x58 + ((c) * 0x40)) 50 #define DESCRIPTOR(c) (BASE + 0x50 + ((c) * 0x40)) 51 #define CS_REG(c) (BASE + 0x60 + ((c) * 0x40)) 52 #define BYTES_TRANSFERRED(c) (BASE + 0x64 + ((c) * 0x40)) 53 54 55 static char *get_dma_direction(u32 status) 56 { 57 switch (status & DIRECTIONAL_MSK) { 58 case INPUT_ONLY: return "Input"; 59 case OUTPUT_ONLY: return "Output"; 60 case BIDIRECTIONAL: return "Bidirectional"; 61 } 62 return ""; 63 } 64 65 static void show_dma_capability(struct cobalt *cobalt) 66 { 67 u32 header = ioread32(CAPABILITY_HEADER); 68 u32 capa = ioread32(CAPABILITY_REGISTER); 69 u32 i; 70 71 cobalt_info("Omnitek DMA capability: ID 0x%02x Version 0x%02x Next 0x%x Size 0x%x\n", 72 header & 0xff, (header >> 8) & 0xff, 73 (header >> 16) & 0xffff, (capa >> 24) & 0xff); 74 75 switch ((capa >> 8) & 0x3) { 76 case 0: 77 cobalt_info("Omnitek DMA: 32 bits PCIe and Local\n"); 78 break; 79 case 1: 80 cobalt_info("Omnitek DMA: 64 bits PCIe, 32 bits Local\n"); 81 break; 82 case 3: 83 cobalt_info("Omnitek DMA: 64 bits PCIe and Local\n"); 84 break; 85 } 86 87 for (i = 0; i < (capa & 0xf); i++) { 88 u32 status = ioread32(CS_REG(i)); 89 90 cobalt_info("Omnitek DMA channel #%d: %s %s\n", i, 91 status & DMA_TYPE_FIFO ? "FIFO" : "MEMORY", 92 get_dma_direction(status)); 93 } 94 } 95 96 void omni_sg_dma_start(struct cobalt_stream *s, struct sg_dma_desc_info *desc) 97 { 98 struct cobalt *cobalt = s->cobalt; 99 100 iowrite32((u32)((u64)desc->bus >> 32), DESCRIPTOR(s->dma_channel) + 4); 101 iowrite32((u32)desc->bus & NEXT_ADRS_MSK, DESCRIPTOR(s->dma_channel)); 102 iowrite32(ENABLE | SCATTER_GATHER_MODE | START, CS_REG(s->dma_channel)); 103 } 104 105 bool is_dma_done(struct cobalt_stream *s) 106 { 107 struct cobalt *cobalt = s->cobalt; 108 109 if (ioread32(CS_REG(s->dma_channel)) & DONE) 110 return true; 111 112 return false; 113 } 114 115 void omni_sg_dma_abort_channel(struct cobalt_stream *s) 116 { 117 struct cobalt *cobalt = s->cobalt; 118 119 if (!is_dma_done(s)) 120 iowrite32(ABORT, CS_REG(s->dma_channel)); 121 } 122 123 int omni_sg_dma_init(struct cobalt *cobalt) 124 { 125 u32 capa = ioread32(CAPABILITY_REGISTER); 126 int i; 127 128 cobalt->first_fifo_channel = 0; 129 cobalt->dma_channels = capa & 0xf; 130 if (capa & PCI_64BIT) 131 cobalt->pci_32_bit = false; 132 else 133 cobalt->pci_32_bit = true; 134 135 for (i = 0; i < cobalt->dma_channels; i++) { 136 u32 status = ioread32(CS_REG(i)); 137 u32 ctrl = ioread32(CS_REG(i)); 138 139 if (!(ctrl & DONE)) 140 iowrite32(ABORT, CS_REG(i)); 141 142 if (!(status & DMA_TYPE_FIFO)) 143 cobalt->first_fifo_channel++; 144 } 145 show_dma_capability(cobalt); 146 return 0; 147 } 148 149 int descriptor_list_create(struct cobalt *cobalt, 150 struct scatterlist *scatter_list, bool to_pci, unsigned sglen, 151 unsigned size, unsigned width, unsigned stride, 152 struct sg_dma_desc_info *desc) 153 { 154 struct sg_dma_descriptor *d = (struct sg_dma_descriptor *)desc->virt; 155 dma_addr_t next = desc->bus; 156 unsigned offset = 0; 157 unsigned copy_bytes = width; 158 unsigned copied = 0; 159 bool first = true; 160 161 /* Must be 4-byte aligned */ 162 WARN_ON(sg_dma_address(scatter_list) & 3); 163 WARN_ON(size & 3); 164 WARN_ON(next & 3); 165 WARN_ON(stride & 3); 166 WARN_ON(stride < width); 167 if (width >= stride) 168 copy_bytes = stride = size; 169 170 while (size) { 171 dma_addr_t addr = sg_dma_address(scatter_list) + offset; 172 unsigned bytes; 173 174 if (addr == 0) 175 return -EFAULT; 176 if (cobalt->pci_32_bit) { 177 WARN_ON((u64)addr >> 32); 178 if ((u64)addr >> 32) 179 return -EFAULT; 180 } 181 182 /* PCIe address */ 183 d->pci_l = addr & 0xffffffff; 184 /* If dma_addr_t is 32 bits, then addr >> 32 is actually the 185 equivalent of addr >> 0 in gcc. So must cast to u64. */ 186 d->pci_h = (u64)addr >> 32; 187 188 /* Sync to start of streaming frame */ 189 d->local = 0; 190 d->reserved0 = 0; 191 192 /* Transfer bytes */ 193 bytes = min(sg_dma_len(scatter_list) - offset, 194 copy_bytes - copied); 195 196 if (first) { 197 if (to_pci) 198 d->local = 0x11111111; 199 first = false; 200 if (sglen == 1) { 201 /* Make sure there are always at least two 202 * descriptors */ 203 d->bytes = (bytes / 2) & ~3; 204 d->reserved1 = 0; 205 size -= d->bytes; 206 copied += d->bytes; 207 offset += d->bytes; 208 addr += d->bytes; 209 next += sizeof(struct sg_dma_descriptor); 210 d->next_h = (u32)((u64)next >> 32); 211 d->next_l = (u32)next | 212 (to_pci ? WRITE_TO_PCI : 0); 213 bytes -= d->bytes; 214 d++; 215 /* PCIe address */ 216 d->pci_l = addr & 0xffffffff; 217 /* If dma_addr_t is 32 bits, then addr >> 32 218 * is actually the equivalent of addr >> 0 in 219 * gcc. So must cast to u64. */ 220 d->pci_h = (u64)addr >> 32; 221 222 /* Sync to start of streaming frame */ 223 d->local = 0; 224 d->reserved0 = 0; 225 } 226 } 227 228 d->bytes = bytes; 229 d->reserved1 = 0; 230 size -= bytes; 231 copied += bytes; 232 offset += bytes; 233 234 if (copied == copy_bytes) { 235 while (copied < stride) { 236 bytes = min(sg_dma_len(scatter_list) - offset, 237 stride - copied); 238 copied += bytes; 239 offset += bytes; 240 size -= bytes; 241 if (sg_dma_len(scatter_list) == offset) { 242 offset = 0; 243 scatter_list = sg_next(scatter_list); 244 } 245 } 246 copied = 0; 247 } else { 248 offset = 0; 249 scatter_list = sg_next(scatter_list); 250 } 251 252 /* Next descriptor + control bits */ 253 next += sizeof(struct sg_dma_descriptor); 254 if (size == 0) { 255 /* Loopback to the first descriptor */ 256 d->next_h = (u32)((u64)desc->bus >> 32); 257 d->next_l = (u32)desc->bus | 258 (to_pci ? WRITE_TO_PCI : 0) | INTERRUPT_ENABLE; 259 if (!to_pci) 260 d->local = 0x22222222; 261 desc->last_desc_virt = d; 262 } else { 263 d->next_h = (u32)((u64)next >> 32); 264 d->next_l = (u32)next | (to_pci ? WRITE_TO_PCI : 0); 265 } 266 d++; 267 } 268 return 0; 269 } 270 271 void descriptor_list_chain(struct sg_dma_desc_info *this, 272 struct sg_dma_desc_info *next) 273 { 274 struct sg_dma_descriptor *d = this->last_desc_virt; 275 u32 direction = d->next_l & WRITE_TO_PCI; 276 277 if (next == NULL) { 278 d->next_h = 0; 279 d->next_l = direction | INTERRUPT_ENABLE | END_OF_CHAIN; 280 } else { 281 d->next_h = (u32)((u64)next->bus >> 32); 282 d->next_l = (u32)next->bus | direction | INTERRUPT_ENABLE; 283 } 284 } 285 286 void *descriptor_list_allocate(struct sg_dma_desc_info *desc, size_t bytes) 287 { 288 desc->size = bytes; 289 desc->virt = dma_alloc_coherent(desc->dev, bytes, 290 &desc->bus, GFP_KERNEL); 291 return desc->virt; 292 } 293 294 void descriptor_list_free(struct sg_dma_desc_info *desc) 295 { 296 if (desc->virt) 297 dma_free_coherent(desc->dev, desc->size, 298 desc->virt, desc->bus); 299 desc->virt = NULL; 300 } 301 302 void descriptor_list_interrupt_enable(struct sg_dma_desc_info *desc) 303 { 304 struct sg_dma_descriptor *d = desc->last_desc_virt; 305 306 d->next_l |= INTERRUPT_ENABLE; 307 } 308 309 void descriptor_list_interrupt_disable(struct sg_dma_desc_info *desc) 310 { 311 struct sg_dma_descriptor *d = desc->last_desc_virt; 312 313 d->next_l &= ~INTERRUPT_ENABLE; 314 } 315 316 void descriptor_list_loopback(struct sg_dma_desc_info *desc) 317 { 318 struct sg_dma_descriptor *d = desc->last_desc_virt; 319 320 d->next_h = (u32)((u64)desc->bus >> 32); 321 d->next_l = (u32)desc->bus | (d->next_l & DESCRIPTOR_FLAG_MSK); 322 } 323 324 void descriptor_list_end_of_chain(struct sg_dma_desc_info *desc) 325 { 326 struct sg_dma_descriptor *d = desc->last_desc_virt; 327 328 d->next_l |= END_OF_CHAIN; 329 } 330