cb03f6503ffd4bdc7c30c001288bbeb36bf7c663
[dpdk.git] / drivers / common / octeontx2 / otx2_mbox.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #include <rte_atomic.h>
11 #include <rte_cycles.h>
12
13 #include "otx2_mbox.h"
14
15 #define RVU_AF_AFPF_MBOX0       (0x02000)
16 #define RVU_AF_AFPF_MBOX1       (0x02008)
17
18 #define RVU_PF_PFAF_MBOX0       (0xC00)
19 #define RVU_PF_PFAF_MBOX1       (0xC08)
20
21 #define RVU_PF_VFX_PFVF_MBOX0   (0x0000)
22 #define RVU_PF_VFX_PFVF_MBOX1   (0x0008)
23
24 #define RVU_VF_VFPF_MBOX0       (0x0000)
25 #define RVU_VF_VFPF_MBOX1       (0x0008)
26
27 void
28 otx2_mbox_fini(struct otx2_mbox *mbox)
29 {
30         mbox->reg_base = 0;
31         mbox->hwbase = 0;
32         free(mbox->dev);
33         mbox->dev = NULL;
34 }
35
36 void
37 otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
38 {
39         struct otx2_mbox_dev *mdev = &mbox->dev[devid];
40         struct mbox_hdr *tx_hdr =
41                 (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->tx_start);
42         struct mbox_hdr *rx_hdr =
43                 (struct mbox_hdr *)((uintptr_t)mdev->mbase + mbox->rx_start);
44
45         rte_spinlock_lock(&mdev->mbox_lock);
46         mdev->msg_size = 0;
47         mdev->rsp_size = 0;
48         tx_hdr->msg_size = 0;
49         tx_hdr->num_msgs = 0;
50         rx_hdr->msg_size = 0;
51         rx_hdr->num_msgs = 0;
52         rte_spinlock_unlock(&mdev->mbox_lock);
53 }
54
55 int
56 otx2_mbox_init(struct otx2_mbox *mbox, uintptr_t hwbase,
57                uintptr_t reg_base, int direction, int ndevs)
58 {
59         struct otx2_mbox_dev *mdev;
60         int devid;
61
62         mbox->reg_base = reg_base;
63         mbox->hwbase = hwbase;
64
65         switch (direction) {
66         case MBOX_DIR_AFPF:
67         case MBOX_DIR_PFVF:
68                 mbox->tx_start = MBOX_DOWN_TX_START;
69                 mbox->rx_start = MBOX_DOWN_RX_START;
70                 mbox->tx_size  = MBOX_DOWN_TX_SIZE;
71                 mbox->rx_size  = MBOX_DOWN_RX_SIZE;
72                 break;
73         case MBOX_DIR_PFAF:
74         case MBOX_DIR_VFPF:
75                 mbox->tx_start = MBOX_DOWN_RX_START;
76                 mbox->rx_start = MBOX_DOWN_TX_START;
77                 mbox->tx_size  = MBOX_DOWN_RX_SIZE;
78                 mbox->rx_size  = MBOX_DOWN_TX_SIZE;
79                 break;
80         case MBOX_DIR_AFPF_UP:
81         case MBOX_DIR_PFVF_UP:
82                 mbox->tx_start = MBOX_UP_TX_START;
83                 mbox->rx_start = MBOX_UP_RX_START;
84                 mbox->tx_size  = MBOX_UP_TX_SIZE;
85                 mbox->rx_size  = MBOX_UP_RX_SIZE;
86                 break;
87         case MBOX_DIR_PFAF_UP:
88         case MBOX_DIR_VFPF_UP:
89                 mbox->tx_start = MBOX_UP_RX_START;
90                 mbox->rx_start = MBOX_UP_TX_START;
91                 mbox->tx_size  = MBOX_UP_RX_SIZE;
92                 mbox->rx_size  = MBOX_UP_TX_SIZE;
93                 break;
94         default:
95                 return -ENODEV;
96         }
97
98         switch (direction) {
99         case MBOX_DIR_AFPF:
100         case MBOX_DIR_AFPF_UP:
101                 mbox->trigger = RVU_AF_AFPF_MBOX0;
102                 mbox->tr_shift = 4;
103                 break;
104         case MBOX_DIR_PFAF:
105         case MBOX_DIR_PFAF_UP:
106                 mbox->trigger = RVU_PF_PFAF_MBOX1;
107                 mbox->tr_shift = 0;
108                 break;
109         case MBOX_DIR_PFVF:
110         case MBOX_DIR_PFVF_UP:
111                 mbox->trigger = RVU_PF_VFX_PFVF_MBOX0;
112                 mbox->tr_shift = 12;
113                 break;
114         case MBOX_DIR_VFPF:
115         case MBOX_DIR_VFPF_UP:
116                 mbox->trigger = RVU_VF_VFPF_MBOX1;
117                 mbox->tr_shift = 0;
118                 break;
119         default:
120                 return -ENODEV;
121         }
122
123         mbox->dev = malloc(ndevs * sizeof(struct otx2_mbox_dev));
124         if (!mbox->dev) {
125                 otx2_mbox_fini(mbox);
126                 return -ENOMEM;
127         }
128         mbox->ndevs = ndevs;
129         for (devid = 0; devid < ndevs; devid++) {
130                 mdev = &mbox->dev[devid];
131                 mdev->mbase = (void *)(mbox->hwbase + (devid * MBOX_SIZE));
132                 rte_spinlock_init(&mdev->mbox_lock);
133                 /* Init header to reset value */
134                 otx2_mbox_reset(mbox, devid);
135         }
136
137         return 0;
138 }