Merge tag 'ti-v2020.07-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti
[oweals/u-boot.git] / drivers / net / fsl-mc / dpio / qbman_portal.c
index 449ff8a8ba3235515c07120df4b35b788743d6bd..44ce00041ee00241bd22f17db82e32404f5595e0 100644 (file)
@@ -1,9 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2014 Freescale Semiconductor
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <log.h>
+#include <malloc.h>
+#include <asm/arch/clock.h>
+#include <linux/bug.h>
 #include "qbman_portal.h"
 
 /* QBMan portal management command codes */
@@ -25,7 +28,7 @@
 #define QBMAN_CENA_SWP_VDQCR   0x780
 
 /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
-#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0xff) >> 6)
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0x1ff) >> 6)
 
 /*******************************/
 /* Pre-defined attribute codes */
@@ -65,6 +68,7 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
 {
        int ret;
        struct qbman_swp *p = malloc(sizeof(struct qbman_swp));
+       u32 major = 0, minor = 0;
 
        if (!p)
                return NULL;
@@ -80,8 +84,20 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
        atomic_set(&p->vdq.busy, 1);
        p->vdq.valid_bit = QB_VALID_BIT;
        p->dqrr.next_idx = 0;
+
+       qbman_version(&major, &minor);
+       if (!major) {
+               printf("invalid qbman version\n");
+               return NULL;
+       }
+
+       if (major >= 4 && minor >= 1)
+               p->dqrr.dqrr_size = QBMAN_VER_4_1_DQRR_SIZE;
+       else
+               p->dqrr.dqrr_size = QBMAN_VER_4_0_DQRR_SIZE;
+
        p->dqrr.valid_bit = QB_VALID_BIT;
-       ret = qbman_swp_sys_init(&p->sys, d);
+       ret = qbman_swp_sys_init(&p->sys, d, p->dqrr.dqrr_size);
        if (ret) {
                free(p);
                printf("qbman_swp_sys_init() failed %d\n", ret);
@@ -102,12 +118,14 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
 void *qbman_swp_mc_start(struct qbman_swp *p)
 {
        void *ret;
+       int *return_val;
 #ifdef QBMAN_CHECKING
        BUG_ON(p->mc.check != swp_mc_can_start);
 #endif
        ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
 #ifdef QBMAN_CHECKING
-       if (!ret)
+       return_val = (int *)ret;
+       if (!(*return_val))
                p->mc.check = swp_mc_can_submit;
 #endif
        return ret;
@@ -378,7 +396,7 @@ const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
        /* There's something there. Move "next_idx" attention to the next ring
         * entry (and prefetch it) before returning what we found. */
        s->dqrr.next_idx++;
-       s->dqrr.next_idx &= QBMAN_DQRR_SIZE - 1; /* Wrap around at 4 */
+       s->dqrr.next_idx &= s->dqrr.dqrr_size - 1;/* Wrap around at dqrr_size */
        /* TODO: it's possible to do all this without conditionals, optimise it
         * later. */
        if (!s->dqrr.next_idx)