1 // SPDX-License-Identifier:    GPL-2.0
2 /*
3  * Copyright (C) 2018 Marvell International Ltd.
4  */
5 
6 #include <dm.h>
7 #include <errno.h>
8 #include <malloc.h>
9 #include <misc.h>
10 #include <net.h>
11 #include <pci_ids.h>
12 #include <linux/list.h>
13 #include <asm/io.h>
14 #include <asm/arch/board.h>
15 #include <asm/arch/csrs/csrs-npa.h>
16 
17 #include "nix.h"
18 
19 struct udevice *rvu_af_dev;
20 
get_af(void)21 inline struct rvu_af *get_af(void)
22 {
23 	return rvu_af_dev ? dev_get_priv(rvu_af_dev) : NULL;
24 }
25 
rvu_get_lfid_for_pf(int pf,int * nixid,int * npaid)26 void rvu_get_lfid_for_pf(int pf, int *nixid, int *npaid)
27 {
28 	union nixx_af_rvu_lf_cfg_debug nix_lf_dbg;
29 	union npa_af_rvu_lf_cfg_debug npa_lf_dbg;
30 	union rvu_pf_func_s pf_func;
31 	struct rvu_af *af = dev_get_priv(rvu_af_dev);
32 	struct nix_af *nix_af = af->nix_af;
33 
34 	pf_func.u = 0;
35 	pf_func.s.pf = pf;
36 
37 	nix_lf_dbg.u = 0;
38 	nix_lf_dbg.s.pf_func = pf_func.u & 0xFFFF;
39 	nix_lf_dbg.s.exec = 1;
40 	nix_af_reg_write(nix_af, NIXX_AF_RVU_LF_CFG_DEBUG(),
41 			 nix_lf_dbg.u);
42 	do {
43 		nix_lf_dbg.u = nix_af_reg_read(nix_af,
44 					       NIXX_AF_RVU_LF_CFG_DEBUG());
45 	} while (nix_lf_dbg.s.exec);
46 
47 	if (nix_lf_dbg.s.lf_valid)
48 		*nixid = nix_lf_dbg.s.lf;
49 
50 	debug("%s: nix lf_valid %d lf %d nixid %d\n", __func__,
51 	      nix_lf_dbg.s.lf_valid, nix_lf_dbg.s.lf, *nixid);
52 
53 	npa_lf_dbg.u = 0;
54 	npa_lf_dbg.s.pf_func = pf_func.u & 0xFFFF;
55 	npa_lf_dbg.s.exec = 1;
56 	npa_af_reg_write(nix_af->npa_af, NPA_AF_RVU_LF_CFG_DEBUG(),
57 			 npa_lf_dbg.u);
58 	do {
59 		npa_lf_dbg.u = npa_af_reg_read(nix_af->npa_af,
60 					       NPA_AF_RVU_LF_CFG_DEBUG());
61 	} while (npa_lf_dbg.s.exec);
62 
63 	if (npa_lf_dbg.s.lf_valid)
64 		*npaid = npa_lf_dbg.s.lf;
65 	debug("%s: npa lf_valid %d lf %d npaid %d\n", __func__,
66 	      npa_lf_dbg.s.lf_valid, npa_lf_dbg.s.lf, *npaid);
67 }
68 
rvu_af_init(struct rvu_af * rvu_af)69 struct nix_af *rvu_af_init(struct rvu_af *rvu_af)
70 {
71 	struct nix_af *nix_af;
72 	union rvu_af_addr_s block_addr;
73 	int err;
74 
75 	nix_af = (struct nix_af *)calloc(1, sizeof(struct nix_af));
76 	if (!nix_af) {
77 		printf("%s: out of memory\n", __func__);
78 		goto error;
79 	}
80 
81 	nix_af->dev = rvu_af->dev;
82 
83 	block_addr.u = 0;
84 	block_addr.s.block = RVU_BLOCK_ADDR_E_NIXX(0);
85 	nix_af->nix_af_base = rvu_af->af_base + block_addr.u;
86 
87 	nix_af->npa_af = (struct npa_af *)calloc(1, sizeof(struct npa_af));
88 	if (!nix_af->npa_af) {
89 		printf("%s: out of memory\n", __func__);
90 		goto error;
91 	}
92 
93 	block_addr.u = 0;
94 	block_addr.s.block = RVU_BLOCK_ADDR_E_NPA;
95 	nix_af->npa_af->npa_af_base = rvu_af->af_base + block_addr.u;
96 
97 	block_addr.u = 0;
98 	block_addr.s.block = RVU_BLOCK_ADDR_E_NPC;
99 	nix_af->npc_af_base = rvu_af->af_base + block_addr.u;
100 
101 	debug("%s: Setting up npa admin\n", __func__);
102 	err = npa_af_setup(nix_af->npa_af);
103 	if (err) {
104 		printf("%s: Error %d setting up NPA admin\n", __func__, err);
105 		goto error;
106 	}
107 	debug("%s: Setting up nix af\n", __func__);
108 	err = nix_af_setup(nix_af);
109 	if (err) {
110 		printf("%s: Error %d setting up NIX admin\n", __func__, err);
111 		goto error;
112 	}
113 	debug("%s: nix_af: %p\n", __func__, nix_af);
114 	return nix_af;
115 
116 error:
117 	if (nix_af->npa_af) {
118 		free(nix_af->npa_af);
119 		memset(nix_af, 0, sizeof(*nix_af));
120 	}
121 	if (nix_af)
122 		free(nix_af);
123 	return NULL;
124 }
125 
rvu_af_probe(struct udevice * dev)126 int rvu_af_probe(struct udevice *dev)
127 {
128 	struct rvu_af *af_ptr = dev_get_priv(dev);
129 
130 	af_ptr->af_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
131 					 PCI_REGION_MEM);
132 	debug("%s RVU AF BAR %p\n", __func__, af_ptr->af_base);
133 	af_ptr->dev = dev;
134 	rvu_af_dev = dev;
135 
136 	af_ptr->nix_af = rvu_af_init(af_ptr);
137 	if (!af_ptr->nix_af) {
138 		printf("%s: Error: could not initialize NIX AF\n", __func__);
139 		return -1;
140 	}
141 	debug("%s: Done\n", __func__);
142 
143 	return 0;
144 }
145 
rvu_af_remove(struct udevice * dev)146 int rvu_af_remove(struct udevice *dev)
147 {
148 	struct rvu_af *rvu_af = dev_get_priv(dev);
149 
150 	nix_af_shutdown(rvu_af->nix_af);
151 	npa_af_shutdown(rvu_af->nix_af->npa_af);
152 	npc_af_shutdown(rvu_af->nix_af);
153 
154 	debug("%s: rvu af down --\n", __func__);
155 	return 0;
156 }
157 
158 U_BOOT_DRIVER(rvu_af) = {
159 	.name   = "rvu_af",
160 	.id     = UCLASS_MISC,
161 	.probe  = rvu_af_probe,
162 	.remove = rvu_af_remove,
163 	.priv_auto	= sizeof(struct rvu_af),
164 };
165 
166 static struct pci_device_id rvu_af_supported[] = {
167 	{ PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_CAVIUM_RVU_AF) },
168 	{}
169 };
170 
171 U_BOOT_PCI_DEVICE(rvu_af, rvu_af_supported);
172