uboot/drivers/soc/ti/k3-navss-ringacc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * TI K3 AM65x NAVSS Ring accelerator Manager (RA) subsystem driver
   4 *
   5 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com
   6 */
   7
   8#include <common.h>
   9#include <cpu_func.h>
  10#include <log.h>
  11#include <asm/cache.h>
  12#include <asm/io.h>
  13#include <malloc.h>
  14#include <asm/bitops.h>
  15#include <dm.h>
  16#include <dm/device_compat.h>
  17#include <dm/devres.h>
  18#include <dm/read.h>
  19#include <dm/uclass.h>
  20#include <linux/bitops.h>
  21#include <linux/compat.h>
  22#include <linux/dma-mapping.h>
  23#include <linux/err.h>
  24#include <linux/soc/ti/k3-navss-ringacc.h>
  25#include <linux/soc/ti/ti_sci_protocol.h>
  26#include <linux/soc/ti/cppi5.h>
  27
  28#define set_bit(bit, bitmap)    __set_bit(bit, bitmap)
  29#define clear_bit(bit, bitmap)  __clear_bit(bit, bitmap)
  30#define dma_free_coherent(dev, size, cpu_addr, dma_handle) \
  31        dma_free_coherent(cpu_addr)
  32#define dma_zalloc_coherent(dev, size, dma_handle, flag) \
  33({ \
  34        void    *ring_mem_virt; \
  35        ring_mem_virt = dma_alloc_coherent((size), \
  36                                           (unsigned long *)(dma_handle)); \
  37        if (ring_mem_virt) \
  38                memset(ring_mem_virt, 0, (size)); \
  39        ring_mem_virt; \
  40})
  41
  42static LIST_HEAD(k3_nav_ringacc_list);
  43
  44static  void ringacc_writel(u32 v, void __iomem *reg)
  45{
  46        pr_debug("WRITEL(32): v(%08X)-->reg(%p)\n", v, reg);
  47        writel(v, reg);
  48}
  49
  50static  u32 ringacc_readl(void __iomem *reg)
  51{
  52        u32 v;
  53
  54        v = readl(reg);
  55        pr_debug("READL(32): v(%08X)<--reg(%p)\n", v, reg);
  56        return v;
  57}
  58
  59#define KNAV_RINGACC_CFG_RING_SIZE_ELCNT_MASK           GENMASK(19, 0)
  60#define K3_DMARING_RING_CFG_RING_SIZE_ELCNT_MASK                GENMASK(15, 0)
  61
  62/**
  63 * struct k3_nav_ring_rt_regs -  The RA Control/Status Registers region
  64 */
  65struct k3_nav_ring_rt_regs {
  66        u32     resv_16[4];
  67        u32     db;             /* RT Ring N Doorbell Register */
  68        u32     resv_4[1];
  69        u32     occ;            /* RT Ring N Occupancy Register */
  70        u32     indx;           /* RT Ring N Current Index Register */
  71        u32     hwocc;          /* RT Ring N Hardware Occupancy Register */
  72        u32     hwindx;         /* RT Ring N Current Index Register */
  73};
  74
  75#define KNAV_RINGACC_RT_REGS_STEP       0x1000
  76#define K3_DMARING_RING_RT_REGS_STEP                    0x2000
  77#define K3_DMARING_RING_RT_REGS_REVERSE_OFS             0x1000
  78#define KNAV_RINGACC_RT_OCC_MASK                GENMASK(20, 0)
  79#define K3_DMARING_RING_RT_OCC_TDOWN_COMPLETE           BIT(31)
  80#define K3_DMARING_RING_RT_DB_ENTRY_MASK                GENMASK(7, 0)
  81#define K3_DMARING_RING_RT_DB_TDOWN_ACK         BIT(31)
  82
  83
  84/**
  85 * struct k3_nav_ring_fifo_regs -  The Ring Accelerator Queues Registers region
  86 */
  87struct k3_nav_ring_fifo_regs {
  88        u32     head_data[128];         /* Ring Head Entry Data Registers */
  89        u32     tail_data[128];         /* Ring Tail Entry Data Registers */
  90        u32     peek_head_data[128];    /* Ring Peek Head Entry Data Regs */
  91        u32     peek_tail_data[128];    /* Ring Peek Tail Entry Data Regs */
  92};
  93
  94#define KNAV_RINGACC_FIFO_WINDOW_SIZE_BYTES  (512U)
  95#define KNAV_RINGACC_FIFO_REGS_STEP     0x1000
  96#define KNAV_RINGACC_MAX_DB_RING_CNT    (127U)
  97
  98/**
  99 * struct k3_nav_ring_ops -  Ring operations
 100 */
 101struct k3_nav_ring_ops {
 102        int (*push_tail)(struct k3_nav_ring *ring, void *elm);
 103        int (*push_head)(struct k3_nav_ring *ring, void *elm);
 104        int (*pop_tail)(struct k3_nav_ring *ring, void *elm);
 105        int (*pop_head)(struct k3_nav_ring *ring, void *elm);
 106};
 107
 108/**
 109 * struct k3_nav_ring_state - Internal state tracking structure
 110 *
 111 * @free: Number of free entries
 112 * @occ: Occupancy
 113 * @windex: Write index
 114 * @rindex: Read index
 115 */
 116struct k3_nav_ring_state {
 117        u32 free;
 118        u32 occ;
 119        u32 windex;
 120        u32 rindex;
 121        u32 tdown_complete:1;
 122};
 123
 124/**
 125 * struct k3_nav_ring - RA Ring descriptor
 126 *
 127 * @cfg - Ring configuration registers
 128 * @rt - Ring control/status registers
 129 * @fifos - Ring queues registers
 130 * @ring_mem_dma - Ring buffer dma address
 131 * @ring_mem_virt - Ring buffer virt address
 132 * @ops - Ring operations
 133 * @size - Ring size in elements
 134 * @elm_size - Size of the ring element
 135 * @mode - Ring mode
 136 * @flags - flags
 137 * @ring_id - Ring Id
 138 * @parent - Pointer on struct @k3_nav_ringacc
 139 * @use_count - Use count for shared rings
 140 */
 141struct k3_nav_ring {
 142        struct k3_nav_ring_cfg_regs __iomem *cfg;
 143        struct k3_nav_ring_rt_regs __iomem *rt;
 144        struct k3_nav_ring_fifo_regs __iomem *fifos;
 145        dma_addr_t      ring_mem_dma;
 146        void            *ring_mem_virt;
 147        struct k3_nav_ring_ops *ops;
 148        u32             size;
 149        enum k3_nav_ring_size elm_size;
 150        enum k3_nav_ring_mode mode;
 151        u32             flags;
 152#define KNAV_RING_FLAG_BUSY     BIT(1)
 153#define K3_NAV_RING_FLAG_SHARED BIT(2)
 154#define K3_NAV_RING_FLAG_REVERSE BIT(3)
 155        struct k3_nav_ring_state state;
 156        u32             ring_id;
 157        struct k3_nav_ringacc   *parent;
 158        u32             use_count;
 159};
 160
 161struct k3_nav_ringacc_ops {
 162        int (*init)(struct udevice *dev, struct k3_nav_ringacc *ringacc);
 163};
 164
 165/**
 166 * struct k3_nav_ringacc - Rings accelerator descriptor
 167 *
 168 * @dev - pointer on RA device
 169 * @num_rings - number of ring in RA
 170 * @rm_gp_range - general purpose rings range from tisci
 171 * @dma_ring_reset_quirk - DMA reset w/a enable
 172 * @num_proxies - number of RA proxies
 173 * @rings - array of rings descriptors (struct @k3_nav_ring)
 174 * @list - list of RAs in the system
 175 * @tisci - pointer ti-sci handle
 176 * @tisci_ring_ops - ti-sci rings ops
 177 * @tisci_dev_id - ti-sci device id
 178 * @ops: SoC specific ringacc operation
 179 * @dual_ring: indicate k3_dmaring dual ring support
 180 */
 181struct k3_nav_ringacc {
 182        struct udevice *dev;
 183        u32 num_rings; /* number of rings in Ringacc module */
 184        unsigned long *rings_inuse;
 185        struct ti_sci_resource *rm_gp_range;
 186        bool dma_ring_reset_quirk;
 187        u32 num_proxies;
 188
 189        struct k3_nav_ring *rings;
 190        struct list_head list;
 191
 192        const struct ti_sci_handle *tisci;
 193        const struct ti_sci_rm_ringacc_ops *tisci_ring_ops;
 194        u32  tisci_dev_id;
 195
 196        const struct k3_nav_ringacc_ops *ops;
 197        bool dual_ring;
 198};
 199
 200#include "k3-navss-ringacc-u-boot.c"
 201
 202static int k3_nav_ringacc_ring_read_occ(struct k3_nav_ring *ring)
 203{
 204        return readl(&ring->rt->occ) & KNAV_RINGACC_RT_OCC_MASK;
 205}
 206
 207static void k3_nav_ringacc_ring_update_occ(struct k3_nav_ring *ring)
 208{
 209        u32 val;
 210
 211        val = readl(&ring->rt->occ);
 212
 213        ring->state.occ = val & KNAV_RINGACC_RT_OCC_MASK;
 214        ring->state.tdown_complete = !!(val & K3_DMARING_RING_RT_OCC_TDOWN_COMPLETE);
 215}
 216
 217static void *k3_nav_ringacc_get_elm_addr(struct k3_nav_ring *ring, u32 idx)
 218{
 219        return (idx * (4 << ring->elm_size) + ring->ring_mem_virt);
 220}
 221
 222static int k3_nav_ringacc_ring_push_mem(struct k3_nav_ring *ring, void *elem);
 223static int k3_nav_ringacc_ring_pop_mem(struct k3_nav_ring *ring, void *elem);
 224static int k3_dmaring_ring_fwd_pop_mem(struct k3_nav_ring *ring, void *elem);
 225static int k3_dmaring_ring_reverse_pop_mem(struct k3_nav_ring *ring, void *elem);
 226
 227static struct k3_nav_ring_ops k3_nav_mode_ring_ops = {
 228                .push_tail = k3_nav_ringacc_ring_push_mem,
 229                .pop_head = k3_nav_ringacc_ring_pop_mem,
 230};
 231
 232static struct k3_nav_ring_ops k3_dmaring_fwd_ring_ops = {
 233                .push_tail = k3_nav_ringacc_ring_push_mem,
 234                .pop_head = k3_dmaring_ring_fwd_pop_mem,
 235};
 236
 237static struct k3_nav_ring_ops k3_dmaring_reverse_ring_ops = {
 238                .pop_head = k3_dmaring_ring_reverse_pop_mem,
 239};
 240
 241struct udevice *k3_nav_ringacc_get_dev(struct k3_nav_ringacc *ringacc)
 242{
 243        return ringacc->dev;
 244}
 245
 246struct k3_nav_ring *k3_nav_ringacc_request_ring(struct k3_nav_ringacc *ringacc,
 247                                                int id)
 248{
 249        if (id == K3_NAV_RINGACC_RING_ID_ANY) {
 250                /* Request for any general purpose ring */
 251                struct ti_sci_resource_desc *gp_rings =
 252                                        &ringacc->rm_gp_range->desc[0];
 253                unsigned long size;
 254
 255                size = gp_rings->start + gp_rings->num;
 256                id = find_next_zero_bit(ringacc->rings_inuse,
 257                                        size, gp_rings->start);
 258                if (id == size)
 259                        goto error;
 260        } else if (id < 0) {
 261                goto error;
 262        }
 263
 264        if (test_bit(id, ringacc->rings_inuse) &&
 265            !(ringacc->rings[id].flags & K3_NAV_RING_FLAG_SHARED))
 266                goto error;
 267        else if (ringacc->rings[id].flags & K3_NAV_RING_FLAG_SHARED)
 268                goto out;
 269
 270        if (!try_module_get(ringacc->dev->driver->owner))
 271                goto error;
 272
 273        pr_debug("Giving ring#%d\n", id);
 274
 275        set_bit(id, ringacc->rings_inuse);
 276out:
 277        ringacc->rings[id].use_count++;
 278        return &ringacc->rings[id];
 279
 280error:
 281        return NULL;
 282}
 283
 284static int k3_dmaring_ring_request_rings_pair(struct k3_nav_ringacc *ringacc,
 285                                              int fwd_id, int compl_id,
 286                                              struct k3_nav_ring **fwd_ring,
 287                                              struct k3_nav_ring **compl_ring)
 288{
 289        /* k3_dmaring: fwd_id == compl_id, so we ignore compl_id */
 290        if (fwd_id < 0)
 291                return -EINVAL;
 292
 293        if (test_bit(fwd_id, ringacc->rings_inuse))
 294                return -EBUSY;
 295
 296        *fwd_ring = &ringacc->rings[fwd_id];
 297        *compl_ring = &ringacc->rings[fwd_id + ringacc->num_rings];
 298        set_bit(fwd_id, ringacc->rings_inuse);
 299        ringacc->rings[fwd_id].use_count++;
 300        dev_dbg(ringacc->dev, "Giving ring#%d\n", fwd_id);
 301
 302        return 0;
 303}
 304
 305int k3_nav_ringacc_request_rings_pair(struct k3_nav_ringacc *ringacc,
 306                                      int fwd_id, int compl_id,
 307                                      struct k3_nav_ring **fwd_ring,
 308                                      struct k3_nav_ring **compl_ring)
 309{
 310        int ret = 0;
 311
 312        if (!fwd_ring || !compl_ring)
 313                return -EINVAL;
 314
 315        if (ringacc->dual_ring)
 316                return k3_dmaring_ring_request_rings_pair(ringacc, fwd_id, compl_id,
 317                                                    fwd_ring, compl_ring);
 318
 319        *fwd_ring = k3_nav_ringacc_request_ring(ringacc, fwd_id);
 320        if (!(*fwd_ring))
 321                return -ENODEV;
 322
 323        *compl_ring = k3_nav_ringacc_request_ring(ringacc, compl_id);
 324        if (!(*compl_ring)) {
 325                k3_nav_ringacc_ring_free(*fwd_ring);
 326                ret = -ENODEV;
 327        }
 328
 329        return ret;
 330}
 331
 332static void k3_ringacc_ring_reset_sci(struct k3_nav_ring *ring)
 333{
 334        struct k3_nav_ringacc *ringacc = ring->parent;
 335        int ret;
 336
 337        if (IS_ENABLED(CONFIG_K3_DM_FW))
 338                return k3_ringacc_ring_reset_raw(ring);
 339
 340        ret = ringacc->tisci_ring_ops->config(
 341                        ringacc->tisci,
 342                        TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID,
 343                        ringacc->tisci_dev_id,
 344                        ring->ring_id,
 345                        0,
 346                        0,
 347                        ring->size,
 348                        0,
 349                        0,
 350                        0);
 351        if (ret)
 352                dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx %d\n",
 353                        ret, ring->ring_id);
 354}
 355
 356void k3_nav_ringacc_ring_reset(struct k3_nav_ring *ring)
 357{
 358        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 359                return;
 360
 361        memset(&ring->state, 0, sizeof(ring->state));
 362
 363        k3_ringacc_ring_reset_sci(ring);
 364}
 365
 366static void k3_ringacc_ring_reconfig_qmode_sci(struct k3_nav_ring *ring,
 367                                               enum k3_nav_ring_mode mode)
 368{
 369        struct k3_nav_ringacc *ringacc = ring->parent;
 370        int ret;
 371
 372        if (IS_ENABLED(CONFIG_K3_DM_FW))
 373                return k3_ringacc_ring_reconfig_qmode_raw(ring, mode);
 374
 375        ret = ringacc->tisci_ring_ops->config(
 376                        ringacc->tisci,
 377                        TI_SCI_MSG_VALUE_RM_RING_MODE_VALID,
 378                        ringacc->tisci_dev_id,
 379                        ring->ring_id,
 380                        0,
 381                        0,
 382                        0,
 383                        mode,
 384                        0,
 385                        0);
 386        if (ret)
 387                dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx %d\n",
 388                        ret, ring->ring_id);
 389}
 390
 391void k3_nav_ringacc_ring_reset_dma(struct k3_nav_ring *ring, u32 occ)
 392{
 393        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 394                return;
 395
 396        if (!ring->parent->dma_ring_reset_quirk) {
 397                k3_nav_ringacc_ring_reset(ring);
 398                return;
 399        }
 400
 401        if (!occ)
 402                occ = ringacc_readl(&ring->rt->occ);
 403
 404        if (occ) {
 405                u32 db_ring_cnt, db_ring_cnt_cur;
 406
 407                pr_debug("%s %u occ: %u\n", __func__,
 408                         ring->ring_id, occ);
 409                /* 2. Reset the ring */
 410                k3_ringacc_ring_reset_sci(ring);
 411
 412                /*
 413                 * 3. Setup the ring in ring/doorbell mode
 414                 * (if not already in this mode)
 415                 */
 416                if (ring->mode != K3_NAV_RINGACC_RING_MODE_RING)
 417                        k3_ringacc_ring_reconfig_qmode_sci(
 418                                        ring, K3_NAV_RINGACC_RING_MODE_RING);
 419                /*
 420                 * 4. Ring the doorbell 2**22 – ringOcc times.
 421                 * This will wrap the internal UDMAP ring state occupancy
 422                 * counter (which is 21-bits wide) to 0.
 423                 */
 424                db_ring_cnt = (1U << 22) - occ;
 425
 426                while (db_ring_cnt != 0) {
 427                        /*
 428                         * Ring the doorbell with the maximum count each
 429                         * iteration if possible to minimize the total
 430                         * of writes
 431                         */
 432                        if (db_ring_cnt > KNAV_RINGACC_MAX_DB_RING_CNT)
 433                                db_ring_cnt_cur = KNAV_RINGACC_MAX_DB_RING_CNT;
 434                        else
 435                                db_ring_cnt_cur = db_ring_cnt;
 436
 437                        writel(db_ring_cnt_cur, &ring->rt->db);
 438                        db_ring_cnt -= db_ring_cnt_cur;
 439                }
 440
 441                /* 5. Restore the original ring mode (if not ring mode) */
 442                if (ring->mode != K3_NAV_RINGACC_RING_MODE_RING)
 443                        k3_ringacc_ring_reconfig_qmode_sci(ring, ring->mode);
 444        }
 445
 446        /* 2. Reset the ring */
 447        k3_nav_ringacc_ring_reset(ring);
 448}
 449
 450static void k3_ringacc_ring_free_sci(struct k3_nav_ring *ring)
 451{
 452        struct k3_nav_ringacc *ringacc = ring->parent;
 453        int ret;
 454
 455        if (IS_ENABLED(CONFIG_K3_DM_FW))
 456                return k3_ringacc_ring_free_raw(ring);
 457
 458        ret = ringacc->tisci_ring_ops->config(
 459                        ringacc->tisci,
 460                        TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER,
 461                        ringacc->tisci_dev_id,
 462                        ring->ring_id,
 463                        0,
 464                        0,
 465                        0,
 466                        0,
 467                        0,
 468                        0);
 469        if (ret)
 470                dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n",
 471                        ret, ring->ring_id);
 472}
 473
 474int k3_nav_ringacc_ring_free(struct k3_nav_ring *ring)
 475{
 476        struct k3_nav_ringacc *ringacc;
 477
 478        if (!ring)
 479                return -EINVAL;
 480
 481        ringacc = ring->parent;
 482
 483        /*
 484         * k3_dmaring: rings shared memory and configuration, only forward ring is
 485         * configured and reverse ring considered as slave.
 486         */
 487        if (ringacc->dual_ring && (ring->flags & K3_NAV_RING_FLAG_REVERSE))
 488                return 0;
 489
 490        pr_debug("%s flags: 0x%08x\n", __func__, ring->flags);
 491
 492        if (!test_bit(ring->ring_id, ringacc->rings_inuse))
 493                return -EINVAL;
 494
 495        if (--ring->use_count)
 496                goto out;
 497
 498        if (!(ring->flags & KNAV_RING_FLAG_BUSY))
 499                goto no_init;
 500
 501        k3_ringacc_ring_free_sci(ring);
 502
 503        dma_free_coherent(ringacc->dev,
 504                          ring->size * (4 << ring->elm_size),
 505                          ring->ring_mem_virt, ring->ring_mem_dma);
 506        ring->flags &= ~KNAV_RING_FLAG_BUSY;
 507        ring->ops = NULL;
 508
 509no_init:
 510        clear_bit(ring->ring_id, ringacc->rings_inuse);
 511
 512        module_put(ringacc->dev->driver->owner);
 513
 514out:
 515        return 0;
 516}
 517
 518u32 k3_nav_ringacc_get_ring_id(struct k3_nav_ring *ring)
 519{
 520        if (!ring)
 521                return -EINVAL;
 522
 523        return ring->ring_id;
 524}
 525
 526static int k3_nav_ringacc_ring_cfg_sci(struct k3_nav_ring *ring)
 527{
 528        struct k3_nav_ringacc *ringacc = ring->parent;
 529        u32 ring_idx;
 530        int ret;
 531
 532        if (!ringacc->tisci)
 533                return -EINVAL;
 534
 535        ring_idx = ring->ring_id;
 536        ret = ringacc->tisci_ring_ops->config(
 537                        ringacc->tisci,
 538                        TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER,
 539                        ringacc->tisci_dev_id,
 540                        ring_idx,
 541                        lower_32_bits(ring->ring_mem_dma),
 542                        upper_32_bits(ring->ring_mem_dma),
 543                        ring->size,
 544                        ring->mode,
 545                        ring->elm_size,
 546                        0);
 547        if (ret) {
 548                dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx %d\n",
 549                        ret, ring_idx);
 550                return ret;
 551        }
 552
 553        /*
 554         * Above TI SCI call handles firewall configuration, cfg
 555         * register configuration still has to be done locally in
 556         * absence of RM services.
 557         */
 558        if (IS_ENABLED(CONFIG_K3_DM_FW))
 559                k3_nav_ringacc_ring_cfg_raw(ring);
 560
 561        return 0;
 562}
 563
 564static int k3_dmaring_ring_cfg(struct k3_nav_ring *ring, struct k3_nav_ring_cfg *cfg)
 565{
 566        struct k3_nav_ringacc *ringacc;
 567        struct k3_nav_ring *reverse_ring;
 568        int ret = 0;
 569
 570        if (cfg->elm_size != K3_NAV_RINGACC_RING_ELSIZE_8 ||
 571            cfg->mode != K3_NAV_RINGACC_RING_MODE_RING ||
 572            cfg->size & ~K3_DMARING_RING_CFG_RING_SIZE_ELCNT_MASK)
 573                return -EINVAL;
 574
 575        ringacc = ring->parent;
 576
 577        /*
 578         * k3_dmaring: rings shared memory and configuration, only forward ring is
 579         * configured and reverse ring considered as slave.
 580         */
 581        if (ringacc->dual_ring && (ring->flags & K3_NAV_RING_FLAG_REVERSE))
 582                return 0;
 583
 584        if (!test_bit(ring->ring_id, ringacc->rings_inuse))
 585                return -EINVAL;
 586
 587        ring->size = cfg->size;
 588        ring->elm_size = cfg->elm_size;
 589        ring->mode = cfg->mode;
 590        memset(&ring->state, 0, sizeof(ring->state));
 591
 592        ring->ops = &k3_dmaring_fwd_ring_ops;
 593
 594        ring->ring_mem_virt =
 595                dma_alloc_coherent(ring->size * (4 << ring->elm_size),
 596                                   (unsigned long *)&ring->ring_mem_dma);
 597        if (!ring->ring_mem_virt) {
 598                dev_err(ringacc->dev, "Failed to alloc ring mem\n");
 599                ret = -ENOMEM;
 600                goto err_free_ops;
 601        }
 602
 603        ret = k3_nav_ringacc_ring_cfg_sci(ring);
 604        if (ret)
 605                goto err_free_mem;
 606
 607        ring->flags |= KNAV_RING_FLAG_BUSY;
 608
 609        /* k3_dmaring: configure reverse ring */
 610        reverse_ring = &ringacc->rings[ring->ring_id + ringacc->num_rings];
 611        reverse_ring->size = cfg->size;
 612        reverse_ring->elm_size = cfg->elm_size;
 613        reverse_ring->mode = cfg->mode;
 614        memset(&reverse_ring->state, 0, sizeof(reverse_ring->state));
 615        reverse_ring->ops = &k3_dmaring_reverse_ring_ops;
 616
 617        reverse_ring->ring_mem_virt = ring->ring_mem_virt;
 618        reverse_ring->ring_mem_dma = ring->ring_mem_dma;
 619        reverse_ring->flags |= KNAV_RING_FLAG_BUSY;
 620
 621        return 0;
 622
 623err_free_mem:
 624        dma_free_coherent(ringacc->dev,
 625                          ring->size * (4 << ring->elm_size),
 626                          ring->ring_mem_virt,
 627                          ring->ring_mem_dma);
 628err_free_ops:
 629        ring->ops = NULL;
 630        return ret;
 631}
 632
 633int k3_nav_ringacc_ring_cfg(struct k3_nav_ring *ring,
 634                            struct k3_nav_ring_cfg *cfg)
 635{
 636        struct k3_nav_ringacc *ringacc = ring->parent;
 637        int ret = 0;
 638
 639        if (!ring || !cfg)
 640                return -EINVAL;
 641
 642        if (ringacc->dual_ring)
 643                return k3_dmaring_ring_cfg(ring, cfg);
 644
 645        if (cfg->elm_size > K3_NAV_RINGACC_RING_ELSIZE_256 ||
 646            cfg->mode > K3_NAV_RINGACC_RING_MODE_QM ||
 647            cfg->size & ~KNAV_RINGACC_CFG_RING_SIZE_ELCNT_MASK ||
 648            !test_bit(ring->ring_id, ringacc->rings_inuse))
 649                return -EINVAL;
 650
 651        if (ring->use_count != 1)
 652                return 0;
 653
 654        ring->size = cfg->size;
 655        ring->elm_size = cfg->elm_size;
 656        ring->mode = cfg->mode;
 657        memset(&ring->state, 0, sizeof(ring->state));
 658
 659        switch (ring->mode) {
 660        case K3_NAV_RINGACC_RING_MODE_RING:
 661                ring->ops = &k3_nav_mode_ring_ops;
 662                break;
 663        default:
 664                ring->ops = NULL;
 665                ret = -EINVAL;
 666                goto err_free_ops;
 667        };
 668
 669        ring->ring_mem_virt =
 670                        dma_zalloc_coherent(ringacc->dev,
 671                                            ring->size * (4 << ring->elm_size),
 672                                            &ring->ring_mem_dma, GFP_KERNEL);
 673        if (!ring->ring_mem_virt) {
 674                dev_err(ringacc->dev, "Failed to alloc ring mem\n");
 675                ret = -ENOMEM;
 676                goto err_free_ops;
 677        }
 678
 679        ret = k3_nav_ringacc_ring_cfg_sci(ring);
 680
 681        if (ret)
 682                goto err_free_mem;
 683
 684        ring->flags |= KNAV_RING_FLAG_BUSY;
 685        ring->flags |= (cfg->flags & K3_NAV_RINGACC_RING_SHARED) ?
 686                        K3_NAV_RING_FLAG_SHARED : 0;
 687
 688        return 0;
 689
 690err_free_mem:
 691        dma_free_coherent(ringacc->dev,
 692                          ring->size * (4 << ring->elm_size),
 693                          ring->ring_mem_virt,
 694                          ring->ring_mem_dma);
 695err_free_ops:
 696        ring->ops = NULL;
 697        return ret;
 698}
 699
 700u32 k3_nav_ringacc_ring_get_size(struct k3_nav_ring *ring)
 701{
 702        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 703                return -EINVAL;
 704
 705        return ring->size;
 706}
 707
 708u32 k3_nav_ringacc_ring_get_free(struct k3_nav_ring *ring)
 709{
 710        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 711                return -EINVAL;
 712
 713        if (!ring->state.free)
 714                ring->state.free = ring->size - ringacc_readl(&ring->rt->occ);
 715
 716        return ring->state.free;
 717}
 718
 719u32 k3_nav_ringacc_ring_get_occ(struct k3_nav_ring *ring)
 720{
 721        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 722                return -EINVAL;
 723
 724        return ringacc_readl(&ring->rt->occ);
 725}
 726
 727u32 k3_nav_ringacc_ring_is_full(struct k3_nav_ring *ring)
 728{
 729        return !k3_nav_ringacc_ring_get_free(ring);
 730}
 731
 732enum k3_ringacc_access_mode {
 733        K3_RINGACC_ACCESS_MODE_PUSH_HEAD,
 734        K3_RINGACC_ACCESS_MODE_POP_HEAD,
 735        K3_RINGACC_ACCESS_MODE_PUSH_TAIL,
 736        K3_RINGACC_ACCESS_MODE_POP_TAIL,
 737        K3_RINGACC_ACCESS_MODE_PEEK_HEAD,
 738        K3_RINGACC_ACCESS_MODE_PEEK_TAIL,
 739};
 740
 741static int k3_dmaring_ring_fwd_pop_mem(struct k3_nav_ring *ring, void *elem)
 742{
 743        void *elem_ptr;
 744        u32 elem_idx;
 745
 746        /*
 747         * k3_dmaring: forward ring is always tied DMA channel and HW does not
 748         * maintain any state data required for POP operation and its unknown
 749         * how much elements were consumed by HW. So, to actually
 750         * do POP, the read pointer has to be recalculated every time.
 751         */
 752        ring->state.occ = k3_nav_ringacc_ring_read_occ(ring);
 753        if (ring->state.windex >= ring->state.occ)
 754                elem_idx = ring->state.windex - ring->state.occ;
 755        else
 756                elem_idx = ring->size - (ring->state.occ - ring->state.windex);
 757
 758        elem_ptr = k3_nav_ringacc_get_elm_addr(ring, elem_idx);
 759        invalidate_dcache_range((unsigned long)ring->ring_mem_virt,
 760                                ALIGN((unsigned long)ring->ring_mem_virt +
 761                                      ring->size * (4 << ring->elm_size),
 762                                      ARCH_DMA_MINALIGN));
 763
 764        memcpy(elem, elem_ptr, (4 << ring->elm_size));
 765
 766        ring->state.occ--;
 767        writel(-1, &ring->rt->db);
 768
 769        dev_dbg(ring->parent->dev, "%s: occ%d Windex%d Rindex%d pos_ptr%px\n",
 770                __func__, ring->state.occ, ring->state.windex, elem_idx,
 771                elem_ptr);
 772        return 0;
 773}
 774
 775static int k3_dmaring_ring_reverse_pop_mem(struct k3_nav_ring *ring, void *elem)
 776{
 777        void *elem_ptr;
 778
 779        elem_ptr = k3_nav_ringacc_get_elm_addr(ring, ring->state.rindex);
 780
 781        if (ring->state.occ) {
 782                invalidate_dcache_range((unsigned long)ring->ring_mem_virt,
 783                                        ALIGN((unsigned long)ring->ring_mem_virt +
 784                                        ring->size * (4 << ring->elm_size),
 785                                        ARCH_DMA_MINALIGN));
 786
 787                memcpy(elem, elem_ptr, (4 << ring->elm_size));
 788                ring->state.rindex = (ring->state.rindex + 1) % ring->size;
 789                ring->state.occ--;
 790                writel(-1 & K3_DMARING_RING_RT_DB_ENTRY_MASK, &ring->rt->db);
 791        }
 792
 793        dev_dbg(ring->parent->dev, "%s: occ%d index%d pos_ptr%px\n",
 794                __func__, ring->state.occ, ring->state.rindex, elem_ptr);
 795        return 0;
 796}
 797
 798static int k3_nav_ringacc_ring_push_mem(struct k3_nav_ring *ring, void *elem)
 799{
 800        void *elem_ptr;
 801
 802        elem_ptr = k3_nav_ringacc_get_elm_addr(ring, ring->state.windex);
 803
 804        memcpy(elem_ptr, elem, (4 << ring->elm_size));
 805
 806        flush_dcache_range((unsigned long)ring->ring_mem_virt,
 807                           ALIGN((unsigned long)ring->ring_mem_virt +
 808                                 ring->size * (4 << ring->elm_size),
 809                                 ARCH_DMA_MINALIGN));
 810
 811        ring->state.windex = (ring->state.windex + 1) % ring->size;
 812        ring->state.free--;
 813        ringacc_writel(1, &ring->rt->db);
 814
 815        pr_debug("ring_push_mem: free%d index%d\n",
 816                 ring->state.free, ring->state.windex);
 817
 818        return 0;
 819}
 820
 821static int k3_nav_ringacc_ring_pop_mem(struct k3_nav_ring *ring, void *elem)
 822{
 823        void *elem_ptr;
 824
 825        elem_ptr = k3_nav_ringacc_get_elm_addr(ring, ring->state.rindex);
 826
 827        invalidate_dcache_range((unsigned long)ring->ring_mem_virt,
 828                                ALIGN((unsigned long)ring->ring_mem_virt +
 829                                      ring->size * (4 << ring->elm_size),
 830                                      ARCH_DMA_MINALIGN));
 831
 832        memcpy(elem, elem_ptr, (4 << ring->elm_size));
 833
 834        ring->state.rindex = (ring->state.rindex + 1) % ring->size;
 835        ring->state.occ--;
 836        ringacc_writel(-1, &ring->rt->db);
 837
 838        pr_debug("ring_pop_mem: occ%d index%d pos_ptr%p\n",
 839                 ring->state.occ, ring->state.rindex, elem_ptr);
 840        return 0;
 841}
 842
 843int k3_nav_ringacc_ring_push(struct k3_nav_ring *ring, void *elem)
 844{
 845        int ret = -EOPNOTSUPP;
 846
 847        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 848                return -EINVAL;
 849
 850        pr_debug("ring_push%d: free%d index%d\n",
 851                 ring->ring_id, ring->state.free, ring->state.windex);
 852
 853        if (k3_nav_ringacc_ring_is_full(ring))
 854                return -ENOMEM;
 855
 856        if (ring->ops && ring->ops->push_tail)
 857                ret = ring->ops->push_tail(ring, elem);
 858
 859        return ret;
 860}
 861
 862int k3_nav_ringacc_ring_push_head(struct k3_nav_ring *ring, void *elem)
 863{
 864        int ret = -EOPNOTSUPP;
 865
 866        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 867                return -EINVAL;
 868
 869        pr_debug("ring_push_head: free%d index%d\n",
 870                 ring->state.free, ring->state.windex);
 871
 872        if (k3_nav_ringacc_ring_is_full(ring))
 873                return -ENOMEM;
 874
 875        if (ring->ops && ring->ops->push_head)
 876                ret = ring->ops->push_head(ring, elem);
 877
 878        return ret;
 879}
 880
 881int k3_nav_ringacc_ring_pop(struct k3_nav_ring *ring, void *elem)
 882{
 883        int ret = -EOPNOTSUPP;
 884
 885        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 886                return -EINVAL;
 887
 888        if (!ring->state.occ)
 889                k3_nav_ringacc_ring_update_occ(ring);
 890
 891        pr_debug("ring_pop%d: occ%d index%d\n",
 892                 ring->ring_id, ring->state.occ, ring->state.rindex);
 893
 894        if (!ring->state.occ && !ring->state.tdown_complete)
 895                return -ENODATA;
 896
 897        if (ring->ops && ring->ops->pop_head)
 898                ret = ring->ops->pop_head(ring, elem);
 899
 900        return ret;
 901}
 902
 903int k3_nav_ringacc_ring_pop_tail(struct k3_nav_ring *ring, void *elem)
 904{
 905        int ret = -EOPNOTSUPP;
 906
 907        if (!ring || !(ring->flags & KNAV_RING_FLAG_BUSY))
 908                return -EINVAL;
 909
 910        if (!ring->state.occ)
 911                k3_nav_ringacc_ring_update_occ(ring);
 912
 913        pr_debug("ring_pop_tail: occ%d index%d\n",
 914                 ring->state.occ, ring->state.rindex);
 915
 916        if (!ring->state.occ)
 917                return -ENODATA;
 918
 919        if (ring->ops && ring->ops->pop_tail)
 920                ret = ring->ops->pop_tail(ring, elem);
 921
 922        return ret;
 923}
 924
 925static int k3_nav_ringacc_probe_dt(struct k3_nav_ringacc *ringacc)
 926{
 927        struct udevice *dev = ringacc->dev;
 928        struct udevice *devp = dev;
 929        struct udevice *tisci_dev = NULL;
 930        int ret;
 931
 932        ringacc->num_rings = dev_read_u32_default(dev, "ti,num-rings", 0);
 933        if (!ringacc->num_rings) {
 934                dev_err(dev, "ti,num-rings read failure %d\n", ret);
 935                return -EINVAL;
 936        }
 937
 938        ringacc->dma_ring_reset_quirk =
 939                        dev_read_bool(dev, "ti,dma-ring-reset-quirk");
 940
 941        ret = uclass_get_device_by_phandle(UCLASS_FIRMWARE, devp,
 942                                           "ti,sci", &tisci_dev);
 943        if (ret) {
 944                pr_debug("TISCI RA RM get failed (%d)\n", ret);
 945                ringacc->tisci = NULL;
 946                return -ENODEV;
 947        }
 948        ringacc->tisci = (struct ti_sci_handle *)
 949                         (ti_sci_get_handle_from_sysfw(tisci_dev));
 950
 951        ret = dev_read_u32_default(devp, "ti,sci", 0);
 952        if (!ret) {
 953                dev_err(dev, "TISCI RA RM disabled\n");
 954                ringacc->tisci = NULL;
 955                return ret;
 956        }
 957
 958        ret = dev_read_u32(devp, "ti,sci-dev-id", &ringacc->tisci_dev_id);
 959        if (ret) {
 960                dev_err(dev, "ti,sci-dev-id read failure %d\n", ret);
 961                ringacc->tisci = NULL;
 962                return ret;
 963        }
 964
 965        ringacc->rm_gp_range = devm_ti_sci_get_of_resource(
 966                                        ringacc->tisci, dev,
 967                                        ringacc->tisci_dev_id,
 968                                        "ti,sci-rm-range-gp-rings");
 969        if (IS_ERR(ringacc->rm_gp_range))
 970                ret = PTR_ERR(ringacc->rm_gp_range);
 971
 972        return 0;
 973}
 974
 975static int k3_nav_ringacc_init(struct udevice *dev, struct k3_nav_ringacc *ringacc)
 976{
 977        void __iomem *base_cfg, *base_rt;
 978        int ret, i;
 979
 980        ret = k3_nav_ringacc_probe_dt(ringacc);
 981        if (ret)
 982                return ret;
 983
 984        base_cfg = dev_remap_addr_name(dev, "cfg");
 985        pr_debug("cfg %p\n", base_cfg);
 986        if (!base_cfg)
 987                return -EINVAL;
 988
 989        base_rt = (uint32_t *)devfdt_get_addr_name(dev, "rt");
 990        pr_debug("rt %p\n", base_rt);
 991        if (IS_ERR(base_rt))
 992                return PTR_ERR(base_rt);
 993
 994        ringacc->rings = devm_kzalloc(dev,
 995                                      sizeof(*ringacc->rings) *
 996                                      ringacc->num_rings,
 997                                      GFP_KERNEL);
 998        ringacc->rings_inuse = devm_kcalloc(dev,
 999                                            BITS_TO_LONGS(ringacc->num_rings),
1000                                            sizeof(unsigned long), GFP_KERNEL);
1001
1002        if (!ringacc->rings || !ringacc->rings_inuse)
1003                return -ENOMEM;
1004
1005        for (i = 0; i < ringacc->num_rings; i++) {
1006                ringacc->rings[i].cfg = base_cfg +
1007                                        KNAV_RINGACC_CFG_REGS_STEP * i;
1008                ringacc->rings[i].rt = base_rt +
1009                                       KNAV_RINGACC_RT_REGS_STEP * i;
1010                ringacc->rings[i].parent = ringacc;
1011                ringacc->rings[i].ring_id = i;
1012        }
1013        dev_set_drvdata(dev, ringacc);
1014
1015        ringacc->tisci_ring_ops = &ringacc->tisci->ops.rm_ring_ops;
1016
1017        list_add_tail(&ringacc->list, &k3_nav_ringacc_list);
1018
1019        dev_info(dev, "Ring Accelerator probed rings:%u, gp-rings[%u,%u] sci-dev-id:%u\n",
1020                 ringacc->num_rings,
1021                 ringacc->rm_gp_range->desc[0].start,
1022                 ringacc->rm_gp_range->desc[0].num,
1023                 ringacc->tisci_dev_id);
1024        dev_info(dev, "dma-ring-reset-quirk: %s\n",
1025                 ringacc->dma_ring_reset_quirk ? "enabled" : "disabled");
1026        return 0;
1027}
1028
1029struct k3_nav_ringacc *k3_ringacc_dmarings_init(struct udevice *dev,
1030                                                struct k3_ringacc_init_data *data)
1031{
1032        struct k3_nav_ringacc *ringacc;
1033        void __iomem *base_rt;
1034        int i;
1035
1036        ringacc = devm_kzalloc(dev, sizeof(*ringacc), GFP_KERNEL);
1037        if (!ringacc)
1038                return ERR_PTR(-ENOMEM);
1039
1040        ringacc->dual_ring = true;
1041
1042        ringacc->dev = dev;
1043        ringacc->num_rings = data->num_rings;
1044        ringacc->tisci = data->tisci;
1045        ringacc->tisci_dev_id = data->tisci_dev_id;
1046
1047        base_rt = (uint32_t *)devfdt_get_addr_name(dev, "ringrt");
1048        if (IS_ERR(base_rt))
1049                return base_rt;
1050
1051        ringacc->rings = devm_kzalloc(dev,
1052                                      sizeof(*ringacc->rings) *
1053                                      ringacc->num_rings * 2,
1054                                      GFP_KERNEL);
1055        ringacc->rings_inuse = devm_kcalloc(dev,
1056                                            BITS_TO_LONGS(ringacc->num_rings),
1057                                            sizeof(unsigned long), GFP_KERNEL);
1058
1059        if (!ringacc->rings || !ringacc->rings_inuse)
1060                return ERR_PTR(-ENOMEM);
1061
1062        for (i = 0; i < ringacc->num_rings; i++) {
1063                struct k3_nav_ring *ring = &ringacc->rings[i];
1064
1065                ring->rt = base_rt + K3_DMARING_RING_RT_REGS_STEP * i;
1066                ring->parent = ringacc;
1067                ring->ring_id = i;
1068
1069                ring = &ringacc->rings[ringacc->num_rings + i];
1070                ring->rt = base_rt + K3_DMARING_RING_RT_REGS_STEP * i +
1071                           K3_DMARING_RING_RT_REGS_REVERSE_OFS;
1072                ring->parent = ringacc;
1073                ring->ring_id = i;
1074                ring->flags = K3_NAV_RING_FLAG_REVERSE;
1075        }
1076
1077        ringacc->tisci_ring_ops = &ringacc->tisci->ops.rm_ring_ops;
1078
1079        dev_info(dev, "k3_dmaring Ring probed rings:%u, sci-dev-id:%u\n",
1080                 ringacc->num_rings,
1081                 ringacc->tisci_dev_id);
1082        dev_info(dev, "dma-ring-reset-quirk: %s\n",
1083                 ringacc->dma_ring_reset_quirk ? "enabled" : "disabled");
1084
1085        return ringacc;
1086}
1087
1088struct ringacc_match_data {
1089        struct k3_nav_ringacc_ops ops;
1090};
1091
1092static struct ringacc_match_data k3_nav_ringacc_data = {
1093        .ops = {
1094                .init = k3_nav_ringacc_init,
1095        },
1096};
1097
1098static const struct udevice_id knav_ringacc_ids[] = {
1099        { .compatible = "ti,am654-navss-ringacc", .data = (ulong)&k3_nav_ringacc_data, },
1100        {},
1101};
1102
1103static int k3_nav_ringacc_probe(struct udevice *dev)
1104{
1105        struct k3_nav_ringacc *ringacc;
1106        int ret;
1107        const struct ringacc_match_data *match_data;
1108
1109        match_data = (struct ringacc_match_data *)dev_get_driver_data(dev);
1110
1111        ringacc = dev_get_priv(dev);
1112        if (!ringacc)
1113                return -ENOMEM;
1114
1115        ringacc->dev = dev;
1116        ringacc->ops = &match_data->ops;
1117        ret = ringacc->ops->init(dev, ringacc);
1118        if (ret)
1119                return ret;
1120
1121        return 0;
1122}
1123
1124U_BOOT_DRIVER(k3_navss_ringacc) = {
1125        .name   = "k3-navss-ringacc",
1126        .id     = UCLASS_MISC,
1127        .of_match = knav_ringacc_ids,
1128        .probe = k3_nav_ringacc_probe,
1129        .priv_auto      = sizeof(struct k3_nav_ringacc),
1130};
1131