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

Merge tag 'drivers_soc_for_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into arm/drivers

SOC: TI Keystone Ring Accelerator driver

The Ring Accelerator (RINGACC or RA) provides hardware acceleration to
enable straightforward passing of work between a producer and a consumer.
There is one RINGACC module per NAVSS on TI AM65x SoCs.

* tag 'drivers_soc_for_5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone:
soc: ti: k3: add navss ringacc driver
bindings: soc: ti: add documentation for k3 ringacc

Link: https://lore.kernel.org/r/1579205259-4845-1-git-send-email-santosh.shilimkar@oracle.com
Signed-off-by: Olof Johansson <olof@lixom.net>

+1472
+59
Documentation/devicetree/bindings/soc/ti/k3-ringacc.txt
··· 1 + * Texas Instruments K3 NavigatorSS Ring Accelerator 2 + 3 + The Ring Accelerator (RA) is a machine which converts read/write accesses 4 + from/to a constant address into corresponding read/write accesses from/to a 5 + circular data structure in memory. The RA eliminates the need for each DMA 6 + controller which needs to access ring elements from having to know the current 7 + state of the ring (base address, current offset). The DMA controller 8 + performs a read or write access to a specific address range (which maps to the 9 + source interface on the RA) and the RA replaces the address for the transaction 10 + with a new address which corresponds to the head or tail element of the ring 11 + (head for reads, tail for writes). 12 + 13 + The Ring Accelerator is a hardware module that is responsible for accelerating 14 + management of the packet queues. The K3 SoCs can have more than one RA instances 15 + 16 + Required properties: 17 + - compatible : Must be "ti,am654-navss-ringacc"; 18 + - reg : Should contain register location and length of the following 19 + named register regions. 20 + - reg-names : should be 21 + "rt" - The RA Ring Real-time Control/Status Registers 22 + "fifos" - The RA Queues Registers 23 + "proxy_gcfg" - The RA Proxy Global Config Registers 24 + "proxy_target" - The RA Proxy Datapath Registers 25 + - ti,num-rings : Number of rings supported by RA 26 + - ti,sci-rm-range-gp-rings : TI-SCI RM subtype for GP ring range 27 + - ti,sci : phandle on TI-SCI compatible System controller node 28 + - ti,sci-dev-id : TI-SCI device id of the ring accelerator 29 + - msi-parent : phandle for "ti,sci-inta" interrupt controller 30 + 31 + Optional properties: 32 + -- ti,dma-ring-reset-quirk : enable ringacc / udma ring state interoperability 33 + issue software w/a 34 + 35 + Example: 36 + 37 + ringacc: ringacc@3c000000 { 38 + compatible = "ti,am654-navss-ringacc"; 39 + reg = <0x0 0x3c000000 0x0 0x400000>, 40 + <0x0 0x38000000 0x0 0x400000>, 41 + <0x0 0x31120000 0x0 0x100>, 42 + <0x0 0x33000000 0x0 0x40000>; 43 + reg-names = "rt", "fifos", 44 + "proxy_gcfg", "proxy_target"; 45 + ti,num-rings = <818>; 46 + ti,sci-rm-range-gp-rings = <0x2>; /* GP ring range */ 47 + ti,dma-ring-reset-quirk; 48 + ti,sci = <&dmsc>; 49 + ti,sci-dev-id = <187>; 50 + msi-parent = <&inta_main_udmass>; 51 + }; 52 + 53 + client: 54 + 55 + dma_ipx: dma_ipx@<addr> { 56 + ... 57 + ti,ringacc = <&ringacc>; 58 + ... 59 + }
+11
drivers/soc/ti/Kconfig
··· 80 80 called ti_sci_pm_domains. Note this is needed early in boot before 81 81 rootfs may be available. 82 82 83 + config TI_K3_RINGACC 84 + bool "K3 Ring accelerator Sub System" 85 + depends on ARCH_K3 || COMPILE_TEST 86 + depends on TI_SCI_INTA_IRQCHIP 87 + help 88 + Say y here to support the K3 Ring accelerator module. 89 + The Ring Accelerator (RINGACC or RA) provides hardware acceleration 90 + to enable straightforward passing of work between a producer 91 + and a consumer. There is one RINGACC module per NAVSS on TI AM65x SoCs 92 + If unsure, say N. 93 + 83 94 endif # SOC_TI 84 95 85 96 config TI_SCI_INTA_MSI_DOMAIN
+1
drivers/soc/ti/Makefile
··· 10 10 obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o 11 11 obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o 12 12 obj-$(CONFIG_TI_SCI_INTA_MSI_DOMAIN) += ti_sci_inta_msi.o 13 + obj-$(CONFIG_TI_K3_RINGACC) += k3-ringacc.o
+1157
drivers/soc/ti/k3-ringacc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * TI K3 NAVSS Ring Accelerator subsystem driver 4 + * 5 + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com 6 + */ 7 + 8 + #include <linux/dma-mapping.h> 9 + #include <linux/io.h> 10 + #include <linux/init.h> 11 + #include <linux/of.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/soc/ti/k3-ringacc.h> 14 + #include <linux/soc/ti/ti_sci_protocol.h> 15 + #include <linux/soc/ti/ti_sci_inta_msi.h> 16 + #include <linux/of_irq.h> 17 + #include <linux/irqdomain.h> 18 + 19 + static LIST_HEAD(k3_ringacc_list); 20 + static DEFINE_MUTEX(k3_ringacc_list_lock); 21 + 22 + #define K3_RINGACC_CFG_RING_SIZE_ELCNT_MASK GENMASK(19, 0) 23 + 24 + /** 25 + * struct k3_ring_rt_regs - The RA realtime Control/Status Registers region 26 + * 27 + * @resv_16: Reserved 28 + * @db: Ring Doorbell Register 29 + * @resv_4: Reserved 30 + * @occ: Ring Occupancy Register 31 + * @indx: Ring Current Index Register 32 + * @hwocc: Ring Hardware Occupancy Register 33 + * @hwindx: Ring Hardware Current Index Register 34 + */ 35 + struct k3_ring_rt_regs { 36 + u32 resv_16[4]; 37 + u32 db; 38 + u32 resv_4[1]; 39 + u32 occ; 40 + u32 indx; 41 + u32 hwocc; 42 + u32 hwindx; 43 + }; 44 + 45 + #define K3_RINGACC_RT_REGS_STEP 0x1000 46 + 47 + /** 48 + * struct k3_ring_fifo_regs - The Ring Accelerator Queues Registers region 49 + * 50 + * @head_data: Ring Head Entry Data Registers 51 + * @tail_data: Ring Tail Entry Data Registers 52 + * @peek_head_data: Ring Peek Head Entry Data Regs 53 + * @peek_tail_data: Ring Peek Tail Entry Data Regs 54 + */ 55 + struct k3_ring_fifo_regs { 56 + u32 head_data[128]; 57 + u32 tail_data[128]; 58 + u32 peek_head_data[128]; 59 + u32 peek_tail_data[128]; 60 + }; 61 + 62 + /** 63 + * struct k3_ringacc_proxy_gcfg_regs - RA Proxy Global Config MMIO Region 64 + * 65 + * @revision: Revision Register 66 + * @config: Config Register 67 + */ 68 + struct k3_ringacc_proxy_gcfg_regs { 69 + u32 revision; 70 + u32 config; 71 + }; 72 + 73 + #define K3_RINGACC_PROXY_CFG_THREADS_MASK GENMASK(15, 0) 74 + 75 + /** 76 + * struct k3_ringacc_proxy_target_regs - Proxy Datapath MMIO Region 77 + * 78 + * @control: Proxy Control Register 79 + * @status: Proxy Status Register 80 + * @resv_512: Reserved 81 + * @data: Proxy Data Register 82 + */ 83 + struct k3_ringacc_proxy_target_regs { 84 + u32 control; 85 + u32 status; 86 + u8 resv_512[504]; 87 + u32 data[128]; 88 + }; 89 + 90 + #define K3_RINGACC_PROXY_TARGET_STEP 0x1000 91 + #define K3_RINGACC_PROXY_NOT_USED (-1) 92 + 93 + enum k3_ringacc_proxy_access_mode { 94 + PROXY_ACCESS_MODE_HEAD = 0, 95 + PROXY_ACCESS_MODE_TAIL = 1, 96 + PROXY_ACCESS_MODE_PEEK_HEAD = 2, 97 + PROXY_ACCESS_MODE_PEEK_TAIL = 3, 98 + }; 99 + 100 + #define K3_RINGACC_FIFO_WINDOW_SIZE_BYTES (512U) 101 + #define K3_RINGACC_FIFO_REGS_STEP 0x1000 102 + #define K3_RINGACC_MAX_DB_RING_CNT (127U) 103 + 104 + struct k3_ring_ops { 105 + int (*push_tail)(struct k3_ring *ring, void *elm); 106 + int (*push_head)(struct k3_ring *ring, void *elm); 107 + int (*pop_tail)(struct k3_ring *ring, void *elm); 108 + int (*pop_head)(struct k3_ring *ring, void *elm); 109 + }; 110 + 111 + /** 112 + * struct k3_ring - RA Ring descriptor 113 + * 114 + * @rt: Ring control/status registers 115 + * @fifos: Ring queues registers 116 + * @proxy: Ring Proxy Datapath registers 117 + * @ring_mem_dma: Ring buffer dma address 118 + * @ring_mem_virt: Ring buffer virt address 119 + * @ops: Ring operations 120 + * @size: Ring size in elements 121 + * @elm_size: Size of the ring element 122 + * @mode: Ring mode 123 + * @flags: flags 124 + * @free: Number of free elements 125 + * @occ: Ring occupancy 126 + * @windex: Write index (only for @K3_RINGACC_RING_MODE_RING) 127 + * @rindex: Read index (only for @K3_RINGACC_RING_MODE_RING) 128 + * @ring_id: Ring Id 129 + * @parent: Pointer on struct @k3_ringacc 130 + * @use_count: Use count for shared rings 131 + * @proxy_id: RA Ring Proxy Id (only if @K3_RINGACC_RING_USE_PROXY) 132 + */ 133 + struct k3_ring { 134 + struct k3_ring_rt_regs __iomem *rt; 135 + struct k3_ring_fifo_regs __iomem *fifos; 136 + struct k3_ringacc_proxy_target_regs __iomem *proxy; 137 + dma_addr_t ring_mem_dma; 138 + void *ring_mem_virt; 139 + struct k3_ring_ops *ops; 140 + u32 size; 141 + enum k3_ring_size elm_size; 142 + enum k3_ring_mode mode; 143 + u32 flags; 144 + #define K3_RING_FLAG_BUSY BIT(1) 145 + #define K3_RING_FLAG_SHARED BIT(2) 146 + u32 free; 147 + u32 occ; 148 + u32 windex; 149 + u32 rindex; 150 + u32 ring_id; 151 + struct k3_ringacc *parent; 152 + u32 use_count; 153 + int proxy_id; 154 + }; 155 + 156 + /** 157 + * struct k3_ringacc - Rings accelerator descriptor 158 + * 159 + * @dev: pointer on RA device 160 + * @proxy_gcfg: RA proxy global config registers 161 + * @proxy_target_base: RA proxy datapath region 162 + * @num_rings: number of ring in RA 163 + * @rings_inuse: bitfield for ring usage tracking 164 + * @rm_gp_range: general purpose rings range from tisci 165 + * @dma_ring_reset_quirk: DMA reset w/a enable 166 + * @num_proxies: number of RA proxies 167 + * @proxy_inuse: bitfield for proxy usage tracking 168 + * @rings: array of rings descriptors (struct @k3_ring) 169 + * @list: list of RAs in the system 170 + * @req_lock: protect rings allocation 171 + * @tisci: pointer ti-sci handle 172 + * @tisci_ring_ops: ti-sci rings ops 173 + * @tisci_dev_id: ti-sci device id 174 + */ 175 + struct k3_ringacc { 176 + struct device *dev; 177 + struct k3_ringacc_proxy_gcfg_regs __iomem *proxy_gcfg; 178 + void __iomem *proxy_target_base; 179 + u32 num_rings; /* number of rings in Ringacc module */ 180 + unsigned long *rings_inuse; 181 + struct ti_sci_resource *rm_gp_range; 182 + 183 + bool dma_ring_reset_quirk; 184 + u32 num_proxies; 185 + unsigned long *proxy_inuse; 186 + 187 + struct k3_ring *rings; 188 + struct list_head list; 189 + struct mutex req_lock; /* protect rings allocation */ 190 + 191 + const struct ti_sci_handle *tisci; 192 + const struct ti_sci_rm_ringacc_ops *tisci_ring_ops; 193 + u32 tisci_dev_id; 194 + }; 195 + 196 + static long k3_ringacc_ring_get_fifo_pos(struct k3_ring *ring) 197 + { 198 + return K3_RINGACC_FIFO_WINDOW_SIZE_BYTES - 199 + (4 << ring->elm_size); 200 + } 201 + 202 + static void *k3_ringacc_get_elm_addr(struct k3_ring *ring, u32 idx) 203 + { 204 + return (ring->ring_mem_virt + idx * (4 << ring->elm_size)); 205 + } 206 + 207 + static int k3_ringacc_ring_push_mem(struct k3_ring *ring, void *elem); 208 + static int k3_ringacc_ring_pop_mem(struct k3_ring *ring, void *elem); 209 + 210 + static struct k3_ring_ops k3_ring_mode_ring_ops = { 211 + .push_tail = k3_ringacc_ring_push_mem, 212 + .pop_head = k3_ringacc_ring_pop_mem, 213 + }; 214 + 215 + static int k3_ringacc_ring_push_io(struct k3_ring *ring, void *elem); 216 + static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem); 217 + static int k3_ringacc_ring_push_head_io(struct k3_ring *ring, void *elem); 218 + static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem); 219 + 220 + static struct k3_ring_ops k3_ring_mode_msg_ops = { 221 + .push_tail = k3_ringacc_ring_push_io, 222 + .push_head = k3_ringacc_ring_push_head_io, 223 + .pop_tail = k3_ringacc_ring_pop_tail_io, 224 + .pop_head = k3_ringacc_ring_pop_io, 225 + }; 226 + 227 + static int k3_ringacc_ring_push_head_proxy(struct k3_ring *ring, void *elem); 228 + static int k3_ringacc_ring_push_tail_proxy(struct k3_ring *ring, void *elem); 229 + static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void *elem); 230 + static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void *elem); 231 + 232 + static struct k3_ring_ops k3_ring_mode_proxy_ops = { 233 + .push_tail = k3_ringacc_ring_push_tail_proxy, 234 + .push_head = k3_ringacc_ring_push_head_proxy, 235 + .pop_tail = k3_ringacc_ring_pop_tail_proxy, 236 + .pop_head = k3_ringacc_ring_pop_head_proxy, 237 + }; 238 + 239 + static void k3_ringacc_ring_dump(struct k3_ring *ring) 240 + { 241 + struct device *dev = ring->parent->dev; 242 + 243 + dev_dbg(dev, "dump ring: %d\n", ring->ring_id); 244 + dev_dbg(dev, "dump mem virt %p, dma %pad\n", ring->ring_mem_virt, 245 + &ring->ring_mem_dma); 246 + dev_dbg(dev, "dump elmsize %d, size %d, mode %d, proxy_id %d\n", 247 + ring->elm_size, ring->size, ring->mode, ring->proxy_id); 248 + 249 + dev_dbg(dev, "dump ring_rt_regs: db%08x\n", readl(&ring->rt->db)); 250 + dev_dbg(dev, "dump occ%08x\n", readl(&ring->rt->occ)); 251 + dev_dbg(dev, "dump indx%08x\n", readl(&ring->rt->indx)); 252 + dev_dbg(dev, "dump hwocc%08x\n", readl(&ring->rt->hwocc)); 253 + dev_dbg(dev, "dump hwindx%08x\n", readl(&ring->rt->hwindx)); 254 + 255 + if (ring->ring_mem_virt) 256 + print_hex_dump_debug("dump ring_mem_virt ", DUMP_PREFIX_NONE, 257 + 16, 1, ring->ring_mem_virt, 16 * 8, false); 258 + } 259 + 260 + struct k3_ring *k3_ringacc_request_ring(struct k3_ringacc *ringacc, 261 + int id, u32 flags) 262 + { 263 + int proxy_id = K3_RINGACC_PROXY_NOT_USED; 264 + 265 + mutex_lock(&ringacc->req_lock); 266 + 267 + if (id == K3_RINGACC_RING_ID_ANY) { 268 + /* Request for any general purpose ring */ 269 + struct ti_sci_resource_desc *gp_rings = 270 + &ringacc->rm_gp_range->desc[0]; 271 + unsigned long size; 272 + 273 + size = gp_rings->start + gp_rings->num; 274 + id = find_next_zero_bit(ringacc->rings_inuse, size, 275 + gp_rings->start); 276 + if (id == size) 277 + goto error; 278 + } else if (id < 0) { 279 + goto error; 280 + } 281 + 282 + if (test_bit(id, ringacc->rings_inuse) && 283 + !(ringacc->rings[id].flags & K3_RING_FLAG_SHARED)) 284 + goto error; 285 + else if (ringacc->rings[id].flags & K3_RING_FLAG_SHARED) 286 + goto out; 287 + 288 + if (flags & K3_RINGACC_RING_USE_PROXY) { 289 + proxy_id = find_next_zero_bit(ringacc->proxy_inuse, 290 + ringacc->num_proxies, 0); 291 + if (proxy_id == ringacc->num_proxies) 292 + goto error; 293 + } 294 + 295 + if (proxy_id != K3_RINGACC_PROXY_NOT_USED) { 296 + set_bit(proxy_id, ringacc->proxy_inuse); 297 + ringacc->rings[id].proxy_id = proxy_id; 298 + dev_dbg(ringacc->dev, "Giving ring#%d proxy#%d\n", id, 299 + proxy_id); 300 + } else { 301 + dev_dbg(ringacc->dev, "Giving ring#%d\n", id); 302 + } 303 + 304 + set_bit(id, ringacc->rings_inuse); 305 + out: 306 + ringacc->rings[id].use_count++; 307 + mutex_unlock(&ringacc->req_lock); 308 + return &ringacc->rings[id]; 309 + 310 + error: 311 + mutex_unlock(&ringacc->req_lock); 312 + return NULL; 313 + } 314 + EXPORT_SYMBOL_GPL(k3_ringacc_request_ring); 315 + 316 + static void k3_ringacc_ring_reset_sci(struct k3_ring *ring) 317 + { 318 + struct k3_ringacc *ringacc = ring->parent; 319 + int ret; 320 + 321 + ret = ringacc->tisci_ring_ops->config( 322 + ringacc->tisci, 323 + TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID, 324 + ringacc->tisci_dev_id, 325 + ring->ring_id, 326 + 0, 327 + 0, 328 + ring->size, 329 + 0, 330 + 0, 331 + 0); 332 + if (ret) 333 + dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx %d\n", 334 + ret, ring->ring_id); 335 + } 336 + 337 + void k3_ringacc_ring_reset(struct k3_ring *ring) 338 + { 339 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 340 + return; 341 + 342 + ring->occ = 0; 343 + ring->free = 0; 344 + ring->rindex = 0; 345 + ring->windex = 0; 346 + 347 + k3_ringacc_ring_reset_sci(ring); 348 + } 349 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_reset); 350 + 351 + static void k3_ringacc_ring_reconfig_qmode_sci(struct k3_ring *ring, 352 + enum k3_ring_mode mode) 353 + { 354 + struct k3_ringacc *ringacc = ring->parent; 355 + int ret; 356 + 357 + ret = ringacc->tisci_ring_ops->config( 358 + ringacc->tisci, 359 + TI_SCI_MSG_VALUE_RM_RING_MODE_VALID, 360 + ringacc->tisci_dev_id, 361 + ring->ring_id, 362 + 0, 363 + 0, 364 + 0, 365 + mode, 366 + 0, 367 + 0); 368 + if (ret) 369 + dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx %d\n", 370 + ret, ring->ring_id); 371 + } 372 + 373 + void k3_ringacc_ring_reset_dma(struct k3_ring *ring, u32 occ) 374 + { 375 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 376 + return; 377 + 378 + if (!ring->parent->dma_ring_reset_quirk) 379 + goto reset; 380 + 381 + if (!occ) 382 + occ = readl(&ring->rt->occ); 383 + 384 + if (occ) { 385 + u32 db_ring_cnt, db_ring_cnt_cur; 386 + 387 + dev_dbg(ring->parent->dev, "%s %u occ: %u\n", __func__, 388 + ring->ring_id, occ); 389 + /* TI-SCI ring reset */ 390 + k3_ringacc_ring_reset_sci(ring); 391 + 392 + /* 393 + * Setup the ring in ring/doorbell mode (if not already in this 394 + * mode) 395 + */ 396 + if (ring->mode != K3_RINGACC_RING_MODE_RING) 397 + k3_ringacc_ring_reconfig_qmode_sci( 398 + ring, K3_RINGACC_RING_MODE_RING); 399 + /* 400 + * Ring the doorbell 2**22 – ringOcc times. 401 + * This will wrap the internal UDMAP ring state occupancy 402 + * counter (which is 21-bits wide) to 0. 403 + */ 404 + db_ring_cnt = (1U << 22) - occ; 405 + 406 + while (db_ring_cnt != 0) { 407 + /* 408 + * Ring the doorbell with the maximum count each 409 + * iteration if possible to minimize the total 410 + * of writes 411 + */ 412 + if (db_ring_cnt > K3_RINGACC_MAX_DB_RING_CNT) 413 + db_ring_cnt_cur = K3_RINGACC_MAX_DB_RING_CNT; 414 + else 415 + db_ring_cnt_cur = db_ring_cnt; 416 + 417 + writel(db_ring_cnt_cur, &ring->rt->db); 418 + db_ring_cnt -= db_ring_cnt_cur; 419 + } 420 + 421 + /* Restore the original ring mode (if not ring mode) */ 422 + if (ring->mode != K3_RINGACC_RING_MODE_RING) 423 + k3_ringacc_ring_reconfig_qmode_sci(ring, ring->mode); 424 + } 425 + 426 + reset: 427 + /* Reset the ring */ 428 + k3_ringacc_ring_reset(ring); 429 + } 430 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_reset_dma); 431 + 432 + static void k3_ringacc_ring_free_sci(struct k3_ring *ring) 433 + { 434 + struct k3_ringacc *ringacc = ring->parent; 435 + int ret; 436 + 437 + ret = ringacc->tisci_ring_ops->config( 438 + ringacc->tisci, 439 + TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER, 440 + ringacc->tisci_dev_id, 441 + ring->ring_id, 442 + 0, 443 + 0, 444 + 0, 445 + 0, 446 + 0, 447 + 0); 448 + if (ret) 449 + dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n", 450 + ret, ring->ring_id); 451 + } 452 + 453 + int k3_ringacc_ring_free(struct k3_ring *ring) 454 + { 455 + struct k3_ringacc *ringacc; 456 + 457 + if (!ring) 458 + return -EINVAL; 459 + 460 + ringacc = ring->parent; 461 + 462 + dev_dbg(ring->parent->dev, "flags: 0x%08x\n", ring->flags); 463 + 464 + if (!test_bit(ring->ring_id, ringacc->rings_inuse)) 465 + return -EINVAL; 466 + 467 + mutex_lock(&ringacc->req_lock); 468 + 469 + if (--ring->use_count) 470 + goto out; 471 + 472 + if (!(ring->flags & K3_RING_FLAG_BUSY)) 473 + goto no_init; 474 + 475 + k3_ringacc_ring_free_sci(ring); 476 + 477 + dma_free_coherent(ringacc->dev, 478 + ring->size * (4 << ring->elm_size), 479 + ring->ring_mem_virt, ring->ring_mem_dma); 480 + ring->flags = 0; 481 + ring->ops = NULL; 482 + if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) { 483 + clear_bit(ring->proxy_id, ringacc->proxy_inuse); 484 + ring->proxy = NULL; 485 + ring->proxy_id = K3_RINGACC_PROXY_NOT_USED; 486 + } 487 + 488 + no_init: 489 + clear_bit(ring->ring_id, ringacc->rings_inuse); 490 + 491 + out: 492 + mutex_unlock(&ringacc->req_lock); 493 + return 0; 494 + } 495 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_free); 496 + 497 + u32 k3_ringacc_get_ring_id(struct k3_ring *ring) 498 + { 499 + if (!ring) 500 + return -EINVAL; 501 + 502 + return ring->ring_id; 503 + } 504 + EXPORT_SYMBOL_GPL(k3_ringacc_get_ring_id); 505 + 506 + u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring) 507 + { 508 + if (!ring) 509 + return -EINVAL; 510 + 511 + return ring->parent->tisci_dev_id; 512 + } 513 + EXPORT_SYMBOL_GPL(k3_ringacc_get_tisci_dev_id); 514 + 515 + int k3_ringacc_get_ring_irq_num(struct k3_ring *ring) 516 + { 517 + int irq_num; 518 + 519 + if (!ring) 520 + return -EINVAL; 521 + 522 + irq_num = ti_sci_inta_msi_get_virq(ring->parent->dev, ring->ring_id); 523 + if (irq_num <= 0) 524 + irq_num = -EINVAL; 525 + return irq_num; 526 + } 527 + EXPORT_SYMBOL_GPL(k3_ringacc_get_ring_irq_num); 528 + 529 + static int k3_ringacc_ring_cfg_sci(struct k3_ring *ring) 530 + { 531 + struct k3_ringacc *ringacc = ring->parent; 532 + u32 ring_idx; 533 + int ret; 534 + 535 + if (!ringacc->tisci) 536 + return -EINVAL; 537 + 538 + ring_idx = ring->ring_id; 539 + ret = ringacc->tisci_ring_ops->config( 540 + ringacc->tisci, 541 + TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER, 542 + ringacc->tisci_dev_id, 543 + ring_idx, 544 + lower_32_bits(ring->ring_mem_dma), 545 + upper_32_bits(ring->ring_mem_dma), 546 + ring->size, 547 + ring->mode, 548 + ring->elm_size, 549 + 0); 550 + if (ret) 551 + dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx %d\n", 552 + ret, ring_idx); 553 + 554 + return ret; 555 + } 556 + 557 + int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg) 558 + { 559 + struct k3_ringacc *ringacc = ring->parent; 560 + int ret = 0; 561 + 562 + if (!ring || !cfg) 563 + return -EINVAL; 564 + if (cfg->elm_size > K3_RINGACC_RING_ELSIZE_256 || 565 + cfg->mode >= K3_RINGACC_RING_MODE_INVALID || 566 + cfg->size & ~K3_RINGACC_CFG_RING_SIZE_ELCNT_MASK || 567 + !test_bit(ring->ring_id, ringacc->rings_inuse)) 568 + return -EINVAL; 569 + 570 + if (cfg->mode == K3_RINGACC_RING_MODE_MESSAGE && 571 + ring->proxy_id == K3_RINGACC_PROXY_NOT_USED && 572 + cfg->elm_size > K3_RINGACC_RING_ELSIZE_8) { 573 + dev_err(ringacc->dev, 574 + "Message mode must use proxy for %u element size\n", 575 + 4 << ring->elm_size); 576 + return -EINVAL; 577 + } 578 + 579 + /* 580 + * In case of shared ring only the first user (master user) can 581 + * configure the ring. The sequence should be by the client: 582 + * ring = k3_ringacc_request_ring(ringacc, ring_id, 0); # master user 583 + * k3_ringacc_ring_cfg(ring, cfg); # master configuration 584 + * k3_ringacc_request_ring(ringacc, ring_id, K3_RING_FLAG_SHARED); 585 + * k3_ringacc_request_ring(ringacc, ring_id, K3_RING_FLAG_SHARED); 586 + */ 587 + if (ring->use_count != 1) 588 + return 0; 589 + 590 + ring->size = cfg->size; 591 + ring->elm_size = cfg->elm_size; 592 + ring->mode = cfg->mode; 593 + ring->occ = 0; 594 + ring->free = 0; 595 + ring->rindex = 0; 596 + ring->windex = 0; 597 + 598 + if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) 599 + ring->proxy = ringacc->proxy_target_base + 600 + ring->proxy_id * K3_RINGACC_PROXY_TARGET_STEP; 601 + 602 + switch (ring->mode) { 603 + case K3_RINGACC_RING_MODE_RING: 604 + ring->ops = &k3_ring_mode_ring_ops; 605 + break; 606 + case K3_RINGACC_RING_MODE_MESSAGE: 607 + if (ring->proxy) 608 + ring->ops = &k3_ring_mode_proxy_ops; 609 + else 610 + ring->ops = &k3_ring_mode_msg_ops; 611 + break; 612 + default: 613 + ring->ops = NULL; 614 + ret = -EINVAL; 615 + goto err_free_proxy; 616 + }; 617 + 618 + ring->ring_mem_virt = dma_alloc_coherent(ringacc->dev, 619 + ring->size * (4 << ring->elm_size), 620 + &ring->ring_mem_dma, GFP_KERNEL); 621 + if (!ring->ring_mem_virt) { 622 + dev_err(ringacc->dev, "Failed to alloc ring mem\n"); 623 + ret = -ENOMEM; 624 + goto err_free_ops; 625 + } 626 + 627 + ret = k3_ringacc_ring_cfg_sci(ring); 628 + 629 + if (ret) 630 + goto err_free_mem; 631 + 632 + ring->flags |= K3_RING_FLAG_BUSY; 633 + ring->flags |= (cfg->flags & K3_RINGACC_RING_SHARED) ? 634 + K3_RING_FLAG_SHARED : 0; 635 + 636 + k3_ringacc_ring_dump(ring); 637 + 638 + return 0; 639 + 640 + err_free_mem: 641 + dma_free_coherent(ringacc->dev, 642 + ring->size * (4 << ring->elm_size), 643 + ring->ring_mem_virt, 644 + ring->ring_mem_dma); 645 + err_free_ops: 646 + ring->ops = NULL; 647 + err_free_proxy: 648 + ring->proxy = NULL; 649 + return ret; 650 + } 651 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_cfg); 652 + 653 + u32 k3_ringacc_ring_get_size(struct k3_ring *ring) 654 + { 655 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 656 + return -EINVAL; 657 + 658 + return ring->size; 659 + } 660 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_size); 661 + 662 + u32 k3_ringacc_ring_get_free(struct k3_ring *ring) 663 + { 664 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 665 + return -EINVAL; 666 + 667 + if (!ring->free) 668 + ring->free = ring->size - readl(&ring->rt->occ); 669 + 670 + return ring->free; 671 + } 672 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_free); 673 + 674 + u32 k3_ringacc_ring_get_occ(struct k3_ring *ring) 675 + { 676 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 677 + return -EINVAL; 678 + 679 + return readl(&ring->rt->occ); 680 + } 681 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_occ); 682 + 683 + u32 k3_ringacc_ring_is_full(struct k3_ring *ring) 684 + { 685 + return !k3_ringacc_ring_get_free(ring); 686 + } 687 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_is_full); 688 + 689 + enum k3_ringacc_access_mode { 690 + K3_RINGACC_ACCESS_MODE_PUSH_HEAD, 691 + K3_RINGACC_ACCESS_MODE_POP_HEAD, 692 + K3_RINGACC_ACCESS_MODE_PUSH_TAIL, 693 + K3_RINGACC_ACCESS_MODE_POP_TAIL, 694 + K3_RINGACC_ACCESS_MODE_PEEK_HEAD, 695 + K3_RINGACC_ACCESS_MODE_PEEK_TAIL, 696 + }; 697 + 698 + #define K3_RINGACC_PROXY_MODE(x) (((x) & 0x3) << 16) 699 + #define K3_RINGACC_PROXY_ELSIZE(x) (((x) & 0x7) << 24) 700 + static int k3_ringacc_ring_cfg_proxy(struct k3_ring *ring, 701 + enum k3_ringacc_proxy_access_mode mode) 702 + { 703 + u32 val; 704 + 705 + val = ring->ring_id; 706 + val |= K3_RINGACC_PROXY_MODE(mode); 707 + val |= K3_RINGACC_PROXY_ELSIZE(ring->elm_size); 708 + writel(val, &ring->proxy->control); 709 + return 0; 710 + } 711 + 712 + static int k3_ringacc_ring_access_proxy(struct k3_ring *ring, void *elem, 713 + enum k3_ringacc_access_mode access_mode) 714 + { 715 + void __iomem *ptr; 716 + 717 + ptr = (void __iomem *)&ring->proxy->data; 718 + 719 + switch (access_mode) { 720 + case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: 721 + case K3_RINGACC_ACCESS_MODE_POP_HEAD: 722 + k3_ringacc_ring_cfg_proxy(ring, PROXY_ACCESS_MODE_HEAD); 723 + break; 724 + case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: 725 + case K3_RINGACC_ACCESS_MODE_POP_TAIL: 726 + k3_ringacc_ring_cfg_proxy(ring, PROXY_ACCESS_MODE_TAIL); 727 + break; 728 + default: 729 + return -EINVAL; 730 + } 731 + 732 + ptr += k3_ringacc_ring_get_fifo_pos(ring); 733 + 734 + switch (access_mode) { 735 + case K3_RINGACC_ACCESS_MODE_POP_HEAD: 736 + case K3_RINGACC_ACCESS_MODE_POP_TAIL: 737 + dev_dbg(ring->parent->dev, 738 + "proxy:memcpy_fromio(x): --> ptr(%p), mode:%d\n", ptr, 739 + access_mode); 740 + memcpy_fromio(elem, ptr, (4 << ring->elm_size)); 741 + ring->occ--; 742 + break; 743 + case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: 744 + case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: 745 + dev_dbg(ring->parent->dev, 746 + "proxy:memcpy_toio(x): --> ptr(%p), mode:%d\n", ptr, 747 + access_mode); 748 + memcpy_toio(ptr, elem, (4 << ring->elm_size)); 749 + ring->free--; 750 + break; 751 + default: 752 + return -EINVAL; 753 + } 754 + 755 + dev_dbg(ring->parent->dev, "proxy: free%d occ%d\n", ring->free, 756 + ring->occ); 757 + return 0; 758 + } 759 + 760 + static int k3_ringacc_ring_push_head_proxy(struct k3_ring *ring, void *elem) 761 + { 762 + return k3_ringacc_ring_access_proxy(ring, elem, 763 + K3_RINGACC_ACCESS_MODE_PUSH_HEAD); 764 + } 765 + 766 + static int k3_ringacc_ring_push_tail_proxy(struct k3_ring *ring, void *elem) 767 + { 768 + return k3_ringacc_ring_access_proxy(ring, elem, 769 + K3_RINGACC_ACCESS_MODE_PUSH_TAIL); 770 + } 771 + 772 + static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void *elem) 773 + { 774 + return k3_ringacc_ring_access_proxy(ring, elem, 775 + K3_RINGACC_ACCESS_MODE_POP_HEAD); 776 + } 777 + 778 + static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void *elem) 779 + { 780 + return k3_ringacc_ring_access_proxy(ring, elem, 781 + K3_RINGACC_ACCESS_MODE_POP_HEAD); 782 + } 783 + 784 + static int k3_ringacc_ring_access_io(struct k3_ring *ring, void *elem, 785 + enum k3_ringacc_access_mode access_mode) 786 + { 787 + void __iomem *ptr; 788 + 789 + switch (access_mode) { 790 + case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: 791 + case K3_RINGACC_ACCESS_MODE_POP_HEAD: 792 + ptr = (void __iomem *)&ring->fifos->head_data; 793 + break; 794 + case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: 795 + case K3_RINGACC_ACCESS_MODE_POP_TAIL: 796 + ptr = (void __iomem *)&ring->fifos->tail_data; 797 + break; 798 + default: 799 + return -EINVAL; 800 + } 801 + 802 + ptr += k3_ringacc_ring_get_fifo_pos(ring); 803 + 804 + switch (access_mode) { 805 + case K3_RINGACC_ACCESS_MODE_POP_HEAD: 806 + case K3_RINGACC_ACCESS_MODE_POP_TAIL: 807 + dev_dbg(ring->parent->dev, 808 + "memcpy_fromio(x): --> ptr(%p), mode:%d\n", ptr, 809 + access_mode); 810 + memcpy_fromio(elem, ptr, (4 << ring->elm_size)); 811 + ring->occ--; 812 + break; 813 + case K3_RINGACC_ACCESS_MODE_PUSH_TAIL: 814 + case K3_RINGACC_ACCESS_MODE_PUSH_HEAD: 815 + dev_dbg(ring->parent->dev, 816 + "memcpy_toio(x): --> ptr(%p), mode:%d\n", ptr, 817 + access_mode); 818 + memcpy_toio(ptr, elem, (4 << ring->elm_size)); 819 + ring->free--; 820 + break; 821 + default: 822 + return -EINVAL; 823 + } 824 + 825 + dev_dbg(ring->parent->dev, "free%d index%d occ%d index%d\n", ring->free, 826 + ring->windex, ring->occ, ring->rindex); 827 + return 0; 828 + } 829 + 830 + static int k3_ringacc_ring_push_head_io(struct k3_ring *ring, void *elem) 831 + { 832 + return k3_ringacc_ring_access_io(ring, elem, 833 + K3_RINGACC_ACCESS_MODE_PUSH_HEAD); 834 + } 835 + 836 + static int k3_ringacc_ring_push_io(struct k3_ring *ring, void *elem) 837 + { 838 + return k3_ringacc_ring_access_io(ring, elem, 839 + K3_RINGACC_ACCESS_MODE_PUSH_TAIL); 840 + } 841 + 842 + static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem) 843 + { 844 + return k3_ringacc_ring_access_io(ring, elem, 845 + K3_RINGACC_ACCESS_MODE_POP_HEAD); 846 + } 847 + 848 + static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void *elem) 849 + { 850 + return k3_ringacc_ring_access_io(ring, elem, 851 + K3_RINGACC_ACCESS_MODE_POP_HEAD); 852 + } 853 + 854 + static int k3_ringacc_ring_push_mem(struct k3_ring *ring, void *elem) 855 + { 856 + void *elem_ptr; 857 + 858 + elem_ptr = k3_ringacc_get_elm_addr(ring, ring->windex); 859 + 860 + memcpy(elem_ptr, elem, (4 << ring->elm_size)); 861 + 862 + ring->windex = (ring->windex + 1) % ring->size; 863 + ring->free--; 864 + writel(1, &ring->rt->db); 865 + 866 + dev_dbg(ring->parent->dev, "ring_push_mem: free%d index%d\n", 867 + ring->free, ring->windex); 868 + 869 + return 0; 870 + } 871 + 872 + static int k3_ringacc_ring_pop_mem(struct k3_ring *ring, void *elem) 873 + { 874 + void *elem_ptr; 875 + 876 + elem_ptr = k3_ringacc_get_elm_addr(ring, ring->rindex); 877 + 878 + memcpy(elem, elem_ptr, (4 << ring->elm_size)); 879 + 880 + ring->rindex = (ring->rindex + 1) % ring->size; 881 + ring->occ--; 882 + writel(-1, &ring->rt->db); 883 + 884 + dev_dbg(ring->parent->dev, "ring_pop_mem: occ%d index%d pos_ptr%p\n", 885 + ring->occ, ring->rindex, elem_ptr); 886 + return 0; 887 + } 888 + 889 + int k3_ringacc_ring_push(struct k3_ring *ring, void *elem) 890 + { 891 + int ret = -EOPNOTSUPP; 892 + 893 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 894 + return -EINVAL; 895 + 896 + dev_dbg(ring->parent->dev, "ring_push: free%d index%d\n", ring->free, 897 + ring->windex); 898 + 899 + if (k3_ringacc_ring_is_full(ring)) 900 + return -ENOMEM; 901 + 902 + if (ring->ops && ring->ops->push_tail) 903 + ret = ring->ops->push_tail(ring, elem); 904 + 905 + return ret; 906 + } 907 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_push); 908 + 909 + int k3_ringacc_ring_push_head(struct k3_ring *ring, void *elem) 910 + { 911 + int ret = -EOPNOTSUPP; 912 + 913 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 914 + return -EINVAL; 915 + 916 + dev_dbg(ring->parent->dev, "ring_push_head: free%d index%d\n", 917 + ring->free, ring->windex); 918 + 919 + if (k3_ringacc_ring_is_full(ring)) 920 + return -ENOMEM; 921 + 922 + if (ring->ops && ring->ops->push_head) 923 + ret = ring->ops->push_head(ring, elem); 924 + 925 + return ret; 926 + } 927 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_push_head); 928 + 929 + int k3_ringacc_ring_pop(struct k3_ring *ring, void *elem) 930 + { 931 + int ret = -EOPNOTSUPP; 932 + 933 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 934 + return -EINVAL; 935 + 936 + if (!ring->occ) 937 + ring->occ = k3_ringacc_ring_get_occ(ring); 938 + 939 + dev_dbg(ring->parent->dev, "ring_pop: occ%d index%d\n", ring->occ, 940 + ring->rindex); 941 + 942 + if (!ring->occ) 943 + return -ENODATA; 944 + 945 + if (ring->ops && ring->ops->pop_head) 946 + ret = ring->ops->pop_head(ring, elem); 947 + 948 + return ret; 949 + } 950 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_pop); 951 + 952 + int k3_ringacc_ring_pop_tail(struct k3_ring *ring, void *elem) 953 + { 954 + int ret = -EOPNOTSUPP; 955 + 956 + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY)) 957 + return -EINVAL; 958 + 959 + if (!ring->occ) 960 + ring->occ = k3_ringacc_ring_get_occ(ring); 961 + 962 + dev_dbg(ring->parent->dev, "ring_pop_tail: occ%d index%d\n", ring->occ, 963 + ring->rindex); 964 + 965 + if (!ring->occ) 966 + return -ENODATA; 967 + 968 + if (ring->ops && ring->ops->pop_tail) 969 + ret = ring->ops->pop_tail(ring, elem); 970 + 971 + return ret; 972 + } 973 + EXPORT_SYMBOL_GPL(k3_ringacc_ring_pop_tail); 974 + 975 + struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np, 976 + const char *property) 977 + { 978 + struct device_node *ringacc_np; 979 + struct k3_ringacc *ringacc = ERR_PTR(-EPROBE_DEFER); 980 + struct k3_ringacc *entry; 981 + 982 + ringacc_np = of_parse_phandle(np, property, 0); 983 + if (!ringacc_np) 984 + return ERR_PTR(-ENODEV); 985 + 986 + mutex_lock(&k3_ringacc_list_lock); 987 + list_for_each_entry(entry, &k3_ringacc_list, list) 988 + if (entry->dev->of_node == ringacc_np) { 989 + ringacc = entry; 990 + break; 991 + } 992 + mutex_unlock(&k3_ringacc_list_lock); 993 + of_node_put(ringacc_np); 994 + 995 + return ringacc; 996 + } 997 + EXPORT_SYMBOL_GPL(of_k3_ringacc_get_by_phandle); 998 + 999 + static int k3_ringacc_probe_dt(struct k3_ringacc *ringacc) 1000 + { 1001 + struct device_node *node = ringacc->dev->of_node; 1002 + struct device *dev = ringacc->dev; 1003 + struct platform_device *pdev = to_platform_device(dev); 1004 + int ret; 1005 + 1006 + if (!node) { 1007 + dev_err(dev, "device tree info unavailable\n"); 1008 + return -ENODEV; 1009 + } 1010 + 1011 + ret = of_property_read_u32(node, "ti,num-rings", &ringacc->num_rings); 1012 + if (ret) { 1013 + dev_err(dev, "ti,num-rings read failure %d\n", ret); 1014 + return ret; 1015 + } 1016 + 1017 + ringacc->dma_ring_reset_quirk = 1018 + of_property_read_bool(node, "ti,dma-ring-reset-quirk"); 1019 + 1020 + ringacc->tisci = ti_sci_get_by_phandle(node, "ti,sci"); 1021 + if (IS_ERR(ringacc->tisci)) { 1022 + ret = PTR_ERR(ringacc->tisci); 1023 + if (ret != -EPROBE_DEFER) 1024 + dev_err(dev, "ti,sci read fail %d\n", ret); 1025 + ringacc->tisci = NULL; 1026 + return ret; 1027 + } 1028 + 1029 + ret = of_property_read_u32(node, "ti,sci-dev-id", 1030 + &ringacc->tisci_dev_id); 1031 + if (ret) { 1032 + dev_err(dev, "ti,sci-dev-id read fail %d\n", ret); 1033 + return ret; 1034 + } 1035 + 1036 + pdev->id = ringacc->tisci_dev_id; 1037 + 1038 + ringacc->rm_gp_range = devm_ti_sci_get_of_resource(ringacc->tisci, dev, 1039 + ringacc->tisci_dev_id, 1040 + "ti,sci-rm-range-gp-rings"); 1041 + if (IS_ERR(ringacc->rm_gp_range)) { 1042 + dev_err(dev, "Failed to allocate MSI interrupts\n"); 1043 + return PTR_ERR(ringacc->rm_gp_range); 1044 + } 1045 + 1046 + return ti_sci_inta_msi_domain_alloc_irqs(ringacc->dev, 1047 + ringacc->rm_gp_range); 1048 + } 1049 + 1050 + static int k3_ringacc_probe(struct platform_device *pdev) 1051 + { 1052 + struct k3_ringacc *ringacc; 1053 + void __iomem *base_fifo, *base_rt; 1054 + struct device *dev = &pdev->dev; 1055 + struct resource *res; 1056 + int ret, i; 1057 + 1058 + ringacc = devm_kzalloc(dev, sizeof(*ringacc), GFP_KERNEL); 1059 + if (!ringacc) 1060 + return -ENOMEM; 1061 + 1062 + ringacc->dev = dev; 1063 + mutex_init(&ringacc->req_lock); 1064 + 1065 + dev->msi_domain = of_msi_get_domain(dev, dev->of_node, 1066 + DOMAIN_BUS_TI_SCI_INTA_MSI); 1067 + if (!dev->msi_domain) { 1068 + dev_err(dev, "Failed to get MSI domain\n"); 1069 + return -EPROBE_DEFER; 1070 + } 1071 + 1072 + ret = k3_ringacc_probe_dt(ringacc); 1073 + if (ret) 1074 + return ret; 1075 + 1076 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rt"); 1077 + base_rt = devm_ioremap_resource(dev, res); 1078 + if (IS_ERR(base_rt)) 1079 + return PTR_ERR(base_rt); 1080 + 1081 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fifos"); 1082 + base_fifo = devm_ioremap_resource(dev, res); 1083 + if (IS_ERR(base_fifo)) 1084 + return PTR_ERR(base_fifo); 1085 + 1086 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "proxy_gcfg"); 1087 + ringacc->proxy_gcfg = devm_ioremap_resource(dev, res); 1088 + if (IS_ERR(ringacc->proxy_gcfg)) 1089 + return PTR_ERR(ringacc->proxy_gcfg); 1090 + 1091 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 1092 + "proxy_target"); 1093 + ringacc->proxy_target_base = devm_ioremap_resource(dev, res); 1094 + if (IS_ERR(ringacc->proxy_target_base)) 1095 + return PTR_ERR(ringacc->proxy_target_base); 1096 + 1097 + ringacc->num_proxies = readl(&ringacc->proxy_gcfg->config) & 1098 + K3_RINGACC_PROXY_CFG_THREADS_MASK; 1099 + 1100 + ringacc->rings = devm_kzalloc(dev, 1101 + sizeof(*ringacc->rings) * 1102 + ringacc->num_rings, 1103 + GFP_KERNEL); 1104 + ringacc->rings_inuse = devm_kcalloc(dev, 1105 + BITS_TO_LONGS(ringacc->num_rings), 1106 + sizeof(unsigned long), GFP_KERNEL); 1107 + ringacc->proxy_inuse = devm_kcalloc(dev, 1108 + BITS_TO_LONGS(ringacc->num_proxies), 1109 + sizeof(unsigned long), GFP_KERNEL); 1110 + 1111 + if (!ringacc->rings || !ringacc->rings_inuse || !ringacc->proxy_inuse) 1112 + return -ENOMEM; 1113 + 1114 + for (i = 0; i < ringacc->num_rings; i++) { 1115 + ringacc->rings[i].rt = base_rt + 1116 + K3_RINGACC_RT_REGS_STEP * i; 1117 + ringacc->rings[i].fifos = base_fifo + 1118 + K3_RINGACC_FIFO_REGS_STEP * i; 1119 + ringacc->rings[i].parent = ringacc; 1120 + ringacc->rings[i].ring_id = i; 1121 + ringacc->rings[i].proxy_id = K3_RINGACC_PROXY_NOT_USED; 1122 + } 1123 + dev_set_drvdata(dev, ringacc); 1124 + 1125 + ringacc->tisci_ring_ops = &ringacc->tisci->ops.rm_ring_ops; 1126 + 1127 + mutex_lock(&k3_ringacc_list_lock); 1128 + list_add_tail(&ringacc->list, &k3_ringacc_list); 1129 + mutex_unlock(&k3_ringacc_list_lock); 1130 + 1131 + dev_info(dev, "Ring Accelerator probed rings:%u, gp-rings[%u,%u] sci-dev-id:%u\n", 1132 + ringacc->num_rings, 1133 + ringacc->rm_gp_range->desc[0].start, 1134 + ringacc->rm_gp_range->desc[0].num, 1135 + ringacc->tisci_dev_id); 1136 + dev_info(dev, "dma-ring-reset-quirk: %s\n", 1137 + ringacc->dma_ring_reset_quirk ? "enabled" : "disabled"); 1138 + dev_info(dev, "RA Proxy rev. %08x, num_proxies:%u\n", 1139 + readl(&ringacc->proxy_gcfg->revision), ringacc->num_proxies); 1140 + return 0; 1141 + } 1142 + 1143 + /* Match table for of_platform binding */ 1144 + static const struct of_device_id k3_ringacc_of_match[] = { 1145 + { .compatible = "ti,am654-navss-ringacc", }, 1146 + {}, 1147 + }; 1148 + 1149 + static struct platform_driver k3_ringacc_driver = { 1150 + .probe = k3_ringacc_probe, 1151 + .driver = { 1152 + .name = "k3-ringacc", 1153 + .of_match_table = k3_ringacc_of_match, 1154 + .suppress_bind_attrs = true, 1155 + }, 1156 + }; 1157 + builtin_platform_driver(k3_ringacc_driver);
+244
include/linux/soc/ti/k3-ringacc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * K3 Ring Accelerator (RA) subsystem interface 4 + * 5 + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com 6 + */ 7 + 8 + #ifndef __SOC_TI_K3_RINGACC_API_H_ 9 + #define __SOC_TI_K3_RINGACC_API_H_ 10 + 11 + #include <linux/types.h> 12 + 13 + struct device_node; 14 + 15 + /** 16 + * enum k3_ring_mode - &struct k3_ring_cfg mode 17 + * 18 + * RA ring operational modes 19 + * 20 + * @K3_RINGACC_RING_MODE_RING: Exposed Ring mode for SW direct access 21 + * @K3_RINGACC_RING_MODE_MESSAGE: Messaging mode. Messaging mode requires 22 + * that all accesses to the queue must go through this IP so that all 23 + * accesses to the memory are controlled and ordered. This IP then 24 + * controls the entire state of the queue, and SW has no directly control, 25 + * such as through doorbells and cannot access the storage memory directly. 26 + * This is particularly useful when more than one SW or HW entity can be 27 + * the producer and/or consumer at the same time 28 + * @K3_RINGACC_RING_MODE_CREDENTIALS: Credentials mode is message mode plus 29 + * stores credentials with each message, requiring the element size to be 30 + * doubled to fit the credentials. Any exposed memory should be protected 31 + * by a firewall from unwanted access 32 + */ 33 + enum k3_ring_mode { 34 + K3_RINGACC_RING_MODE_RING = 0, 35 + K3_RINGACC_RING_MODE_MESSAGE, 36 + K3_RINGACC_RING_MODE_CREDENTIALS, 37 + K3_RINGACC_RING_MODE_INVALID 38 + }; 39 + 40 + /** 41 + * enum k3_ring_size - &struct k3_ring_cfg elm_size 42 + * 43 + * RA ring element's sizes in bytes. 44 + */ 45 + enum k3_ring_size { 46 + K3_RINGACC_RING_ELSIZE_4 = 0, 47 + K3_RINGACC_RING_ELSIZE_8, 48 + K3_RINGACC_RING_ELSIZE_16, 49 + K3_RINGACC_RING_ELSIZE_32, 50 + K3_RINGACC_RING_ELSIZE_64, 51 + K3_RINGACC_RING_ELSIZE_128, 52 + K3_RINGACC_RING_ELSIZE_256, 53 + K3_RINGACC_RING_ELSIZE_INVALID 54 + }; 55 + 56 + struct k3_ringacc; 57 + struct k3_ring; 58 + 59 + /** 60 + * enum k3_ring_cfg - RA ring configuration structure 61 + * 62 + * @size: Ring size, number of elements 63 + * @elm_size: Ring element size 64 + * @mode: Ring operational mode 65 + * @flags: Ring configuration flags. Possible values: 66 + * @K3_RINGACC_RING_SHARED: when set allows to request the same ring 67 + * few times. It's usable when the same ring is used as Free Host PD ring 68 + * for different flows, for example. 69 + * Note: Locking should be done by consumer if required 70 + */ 71 + struct k3_ring_cfg { 72 + u32 size; 73 + enum k3_ring_size elm_size; 74 + enum k3_ring_mode mode; 75 + #define K3_RINGACC_RING_SHARED BIT(1) 76 + u32 flags; 77 + }; 78 + 79 + #define K3_RINGACC_RING_ID_ANY (-1) 80 + 81 + /** 82 + * of_k3_ringacc_get_by_phandle - find a RA by phandle property 83 + * @np: device node 84 + * @propname: property name containing phandle on RA node 85 + * 86 + * Returns pointer on the RA - struct k3_ringacc 87 + * or -ENODEV if not found, 88 + * or -EPROBE_DEFER if not yet registered 89 + */ 90 + struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np, 91 + const char *property); 92 + 93 + #define K3_RINGACC_RING_USE_PROXY BIT(1) 94 + 95 + /** 96 + * k3_ringacc_request_ring - request ring from ringacc 97 + * @ringacc: pointer on ringacc 98 + * @id: ring id or K3_RINGACC_RING_ID_ANY for any general purpose ring 99 + * @flags: 100 + * @K3_RINGACC_RING_USE_PROXY: if set - proxy will be allocated and 101 + * used to access ring memory. Sopported only for rings in 102 + * Message/Credentials/Queue mode. 103 + * 104 + * Returns pointer on the Ring - struct k3_ring 105 + * or NULL in case of failure. 106 + */ 107 + struct k3_ring *k3_ringacc_request_ring(struct k3_ringacc *ringacc, 108 + int id, u32 flags); 109 + 110 + /** 111 + * k3_ringacc_ring_reset - ring reset 112 + * @ring: pointer on Ring 113 + * 114 + * Resets ring internal state ((hw)occ, (hw)idx). 115 + */ 116 + void k3_ringacc_ring_reset(struct k3_ring *ring); 117 + /** 118 + * k3_ringacc_ring_reset - ring reset for DMA rings 119 + * @ring: pointer on Ring 120 + * 121 + * Resets ring internal state ((hw)occ, (hw)idx). Should be used for rings 122 + * which are read by K3 UDMA, like TX or Free Host PD rings. 123 + */ 124 + void k3_ringacc_ring_reset_dma(struct k3_ring *ring, u32 occ); 125 + 126 + /** 127 + * k3_ringacc_ring_free - ring free 128 + * @ring: pointer on Ring 129 + * 130 + * Resets ring and free all alocated resources. 131 + */ 132 + int k3_ringacc_ring_free(struct k3_ring *ring); 133 + 134 + /** 135 + * k3_ringacc_get_ring_id - Get the Ring ID 136 + * @ring: pointer on ring 137 + * 138 + * Returns the Ring ID 139 + */ 140 + u32 k3_ringacc_get_ring_id(struct k3_ring *ring); 141 + 142 + /** 143 + * k3_ringacc_get_ring_irq_num - Get the irq number for the ring 144 + * @ring: pointer on ring 145 + * 146 + * Returns the interrupt number which can be used to request the interrupt 147 + */ 148 + int k3_ringacc_get_ring_irq_num(struct k3_ring *ring); 149 + 150 + /** 151 + * k3_ringacc_ring_cfg - ring configure 152 + * @ring: pointer on ring 153 + * @cfg: Ring configuration parameters (see &struct k3_ring_cfg) 154 + * 155 + * Configures ring, including ring memory allocation. 156 + * Returns 0 on success, errno otherwise. 157 + */ 158 + int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg); 159 + 160 + /** 161 + * k3_ringacc_ring_get_size - get ring size 162 + * @ring: pointer on ring 163 + * 164 + * Returns ring size in number of elements. 165 + */ 166 + u32 k3_ringacc_ring_get_size(struct k3_ring *ring); 167 + 168 + /** 169 + * k3_ringacc_ring_get_free - get free elements 170 + * @ring: pointer on ring 171 + * 172 + * Returns number of free elements in the ring. 173 + */ 174 + u32 k3_ringacc_ring_get_free(struct k3_ring *ring); 175 + 176 + /** 177 + * k3_ringacc_ring_get_occ - get ring occupancy 178 + * @ring: pointer on ring 179 + * 180 + * Returns total number of valid entries on the ring 181 + */ 182 + u32 k3_ringacc_ring_get_occ(struct k3_ring *ring); 183 + 184 + /** 185 + * k3_ringacc_ring_is_full - checks if ring is full 186 + * @ring: pointer on ring 187 + * 188 + * Returns true if the ring is full 189 + */ 190 + u32 k3_ringacc_ring_is_full(struct k3_ring *ring); 191 + 192 + /** 193 + * k3_ringacc_ring_push - push element to the ring tail 194 + * @ring: pointer on ring 195 + * @elem: pointer on ring element buffer 196 + * 197 + * Push one ring element to the ring tail. Size of the ring element is 198 + * determined by ring configuration &struct k3_ring_cfg elm_size. 199 + * 200 + * Returns 0 on success, errno otherwise. 201 + */ 202 + int k3_ringacc_ring_push(struct k3_ring *ring, void *elem); 203 + 204 + /** 205 + * k3_ringacc_ring_pop - pop element from the ring head 206 + * @ring: pointer on ring 207 + * @elem: pointer on ring element buffer 208 + * 209 + * Push one ring element from the ring head. Size of the ring element is 210 + * determined by ring configuration &struct k3_ring_cfg elm_size.. 211 + * 212 + * Returns 0 on success, errno otherwise. 213 + */ 214 + int k3_ringacc_ring_pop(struct k3_ring *ring, void *elem); 215 + 216 + /** 217 + * k3_ringacc_ring_push_head - push element to the ring head 218 + * @ring: pointer on ring 219 + * @elem: pointer on ring element buffer 220 + * 221 + * Push one ring element to the ring head. Size of the ring element is 222 + * determined by ring configuration &struct k3_ring_cfg elm_size. 223 + * 224 + * Returns 0 on success, errno otherwise. 225 + * Not Supported by ring modes: K3_RINGACC_RING_MODE_RING 226 + */ 227 + int k3_ringacc_ring_push_head(struct k3_ring *ring, void *elem); 228 + 229 + /** 230 + * k3_ringacc_ring_pop_tail - pop element from the ring tail 231 + * @ring: pointer on ring 232 + * @elem: pointer on ring element buffer 233 + * 234 + * Push one ring element from the ring tail. Size of the ring element is 235 + * determined by ring configuration &struct k3_ring_cfg elm_size. 236 + * 237 + * Returns 0 on success, errno otherwise. 238 + * Not Supported by ring modes: K3_RINGACC_RING_MODE_RING 239 + */ 240 + int k3_ringacc_ring_pop_tail(struct k3_ring *ring, void *elem); 241 + 242 + u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring); 243 + 244 + #endif /* __SOC_TI_K3_RINGACC_API_H_ */