1473c88f9SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2473c88f9SBruce Richardson * Copyright(c) 2010-2018 Intel Corporation
3473c88f9SBruce Richardson */
4473c88f9SBruce Richardson
5473c88f9SBruce Richardson #include "ifpga_feature_dev.h"
6473c88f9SBruce Richardson #include "opae_spi.h"
7473c88f9SBruce Richardson #include "opae_intel_max10.h"
8473c88f9SBruce Richardson #include "opae_i2c.h"
9473c88f9SBruce Richardson #include "opae_at24_eeprom.h"
10a05bd1b4SWei Huang #include "ifpga_sec_mgr.h"
11473c88f9SBruce Richardson
12473c88f9SBruce Richardson #define PWR_THRESHOLD_MAX 0x7F
13473c88f9SBruce Richardson
fme_get_prop(struct ifpga_fme_hw * fme,struct feature_prop * prop)14473c88f9SBruce Richardson int fme_get_prop(struct ifpga_fme_hw *fme, struct feature_prop *prop)
15473c88f9SBruce Richardson {
16473c88f9SBruce Richardson struct ifpga_feature *feature;
17473c88f9SBruce Richardson
18473c88f9SBruce Richardson if (!fme)
19473c88f9SBruce Richardson return -ENOENT;
20473c88f9SBruce Richardson
21473c88f9SBruce Richardson feature = get_fme_feature_by_id(fme, prop->feature_id);
22473c88f9SBruce Richardson
23473c88f9SBruce Richardson if (feature && feature->ops && feature->ops->get_prop)
24473c88f9SBruce Richardson return feature->ops->get_prop(feature, prop);
25473c88f9SBruce Richardson
26473c88f9SBruce Richardson return -ENOENT;
27473c88f9SBruce Richardson }
28473c88f9SBruce Richardson
fme_set_prop(struct ifpga_fme_hw * fme,struct feature_prop * prop)29473c88f9SBruce Richardson int fme_set_prop(struct ifpga_fme_hw *fme, struct feature_prop *prop)
30473c88f9SBruce Richardson {
31473c88f9SBruce Richardson struct ifpga_feature *feature;
32473c88f9SBruce Richardson
33473c88f9SBruce Richardson if (!fme)
34473c88f9SBruce Richardson return -ENOENT;
35473c88f9SBruce Richardson
36473c88f9SBruce Richardson feature = get_fme_feature_by_id(fme, prop->feature_id);
37473c88f9SBruce Richardson
38473c88f9SBruce Richardson if (feature && feature->ops && feature->ops->set_prop)
39473c88f9SBruce Richardson return feature->ops->set_prop(feature, prop);
40473c88f9SBruce Richardson
41473c88f9SBruce Richardson return -ENOENT;
42473c88f9SBruce Richardson }
43473c88f9SBruce Richardson
fme_set_irq(struct ifpga_fme_hw * fme,u32 feature_id,void * irq_set)44473c88f9SBruce Richardson int fme_set_irq(struct ifpga_fme_hw *fme, u32 feature_id, void *irq_set)
45473c88f9SBruce Richardson {
46473c88f9SBruce Richardson struct ifpga_feature *feature;
47473c88f9SBruce Richardson
48473c88f9SBruce Richardson if (!fme)
49473c88f9SBruce Richardson return -ENOENT;
50473c88f9SBruce Richardson
51473c88f9SBruce Richardson feature = get_fme_feature_by_id(fme, feature_id);
52473c88f9SBruce Richardson
53473c88f9SBruce Richardson if (feature && feature->ops && feature->ops->set_irq)
54473c88f9SBruce Richardson return feature->ops->set_irq(feature, irq_set);
55473c88f9SBruce Richardson
56473c88f9SBruce Richardson return -ENOENT;
57473c88f9SBruce Richardson }
58473c88f9SBruce Richardson
59473c88f9SBruce Richardson /* fme private feature head */
fme_hdr_init(struct ifpga_feature * feature)60473c88f9SBruce Richardson static int fme_hdr_init(struct ifpga_feature *feature)
61473c88f9SBruce Richardson {
62473c88f9SBruce Richardson struct feature_fme_header *fme_hdr;
63473c88f9SBruce Richardson
64473c88f9SBruce Richardson fme_hdr = (struct feature_fme_header *)feature->addr;
65473c88f9SBruce Richardson
66473c88f9SBruce Richardson dev_info(NULL, "FME HDR Init.\n");
67473c88f9SBruce Richardson dev_info(NULL, "FME cap %llx.\n",
68473c88f9SBruce Richardson (unsigned long long)fme_hdr->capability.csr);
69473c88f9SBruce Richardson
70473c88f9SBruce Richardson return 0;
71473c88f9SBruce Richardson }
72473c88f9SBruce Richardson
fme_hdr_uinit(struct ifpga_feature * feature)73473c88f9SBruce Richardson static void fme_hdr_uinit(struct ifpga_feature *feature)
74473c88f9SBruce Richardson {
75473c88f9SBruce Richardson UNUSED(feature);
76473c88f9SBruce Richardson
77473c88f9SBruce Richardson dev_info(NULL, "FME HDR UInit.\n");
78473c88f9SBruce Richardson }
79473c88f9SBruce Richardson
fme_hdr_get_revision(struct ifpga_fme_hw * fme,u64 * revision)80473c88f9SBruce Richardson static int fme_hdr_get_revision(struct ifpga_fme_hw *fme, u64 *revision)
81473c88f9SBruce Richardson {
82473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
83473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
84473c88f9SBruce Richardson struct feature_header header;
85473c88f9SBruce Richardson
86473c88f9SBruce Richardson header.csr = readq(&fme_hdr->header);
87473c88f9SBruce Richardson *revision = header.revision;
88473c88f9SBruce Richardson
89473c88f9SBruce Richardson return 0;
90473c88f9SBruce Richardson }
91473c88f9SBruce Richardson
fme_hdr_get_ports_num(struct ifpga_fme_hw * fme,u64 * ports_num)92473c88f9SBruce Richardson static int fme_hdr_get_ports_num(struct ifpga_fme_hw *fme, u64 *ports_num)
93473c88f9SBruce Richardson {
94473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
95473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
96473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
97473c88f9SBruce Richardson
98473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
99473c88f9SBruce Richardson *ports_num = fme_capability.num_ports;
100473c88f9SBruce Richardson
101473c88f9SBruce Richardson return 0;
102473c88f9SBruce Richardson }
103473c88f9SBruce Richardson
fme_hdr_get_port_type(struct ifpga_fme_hw * fme,u64 * port_type)104cf38bcd7SWei Huang static int fme_hdr_get_port_type(struct ifpga_fme_hw *fme, u64 *port_type)
105cf38bcd7SWei Huang {
106cf38bcd7SWei Huang struct feature_fme_header *fme_hdr
107cf38bcd7SWei Huang = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
108cf38bcd7SWei Huang struct feature_fme_port pt;
109cf38bcd7SWei Huang u32 port = (u32)((*port_type >> 32) & 0xffffffff);
110cf38bcd7SWei Huang
111cf38bcd7SWei Huang pt.csr = readq(&fme_hdr->port[port]);
112cf38bcd7SWei Huang if (!pt.port_implemented)
113cf38bcd7SWei Huang return -ENODEV;
114cf38bcd7SWei Huang if (pt.afu_access_control)
115cf38bcd7SWei Huang *port_type |= 0x1;
116cf38bcd7SWei Huang else
117cf38bcd7SWei Huang *port_type &= ~0x1;
118cf38bcd7SWei Huang
119cf38bcd7SWei Huang return 0;
120cf38bcd7SWei Huang }
121cf38bcd7SWei Huang
fme_hdr_get_cache_size(struct ifpga_fme_hw * fme,u64 * cache_size)122473c88f9SBruce Richardson static int fme_hdr_get_cache_size(struct ifpga_fme_hw *fme, u64 *cache_size)
123473c88f9SBruce Richardson {
124473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
125473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
126473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
127473c88f9SBruce Richardson
128473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
129473c88f9SBruce Richardson *cache_size = fme_capability.cache_size;
130473c88f9SBruce Richardson
131473c88f9SBruce Richardson return 0;
132473c88f9SBruce Richardson }
133473c88f9SBruce Richardson
fme_hdr_get_version(struct ifpga_fme_hw * fme,u64 * version)134473c88f9SBruce Richardson static int fme_hdr_get_version(struct ifpga_fme_hw *fme, u64 *version)
135473c88f9SBruce Richardson {
136473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
137473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
138473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
139473c88f9SBruce Richardson
140473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
141473c88f9SBruce Richardson *version = fme_capability.fabric_verid;
142473c88f9SBruce Richardson
143473c88f9SBruce Richardson return 0;
144473c88f9SBruce Richardson }
145473c88f9SBruce Richardson
fme_hdr_get_socket_id(struct ifpga_fme_hw * fme,u64 * socket_id)146473c88f9SBruce Richardson static int fme_hdr_get_socket_id(struct ifpga_fme_hw *fme, u64 *socket_id)
147473c88f9SBruce Richardson {
148473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
149473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
150473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
151473c88f9SBruce Richardson
152473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
153473c88f9SBruce Richardson *socket_id = fme_capability.socket_id;
154473c88f9SBruce Richardson
155473c88f9SBruce Richardson return 0;
156473c88f9SBruce Richardson }
157473c88f9SBruce Richardson
fme_hdr_get_bitstream_id(struct ifpga_fme_hw * fme,u64 * bitstream_id)158473c88f9SBruce Richardson static int fme_hdr_get_bitstream_id(struct ifpga_fme_hw *fme,
159473c88f9SBruce Richardson u64 *bitstream_id)
160473c88f9SBruce Richardson {
161473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
162473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
163473c88f9SBruce Richardson
164473c88f9SBruce Richardson *bitstream_id = readq(&fme_hdr->bitstream_id);
165473c88f9SBruce Richardson
166473c88f9SBruce Richardson return 0;
167473c88f9SBruce Richardson }
168473c88f9SBruce Richardson
fme_hdr_get_bitstream_metadata(struct ifpga_fme_hw * fme,u64 * bitstream_metadata)169473c88f9SBruce Richardson static int fme_hdr_get_bitstream_metadata(struct ifpga_fme_hw *fme,
170473c88f9SBruce Richardson u64 *bitstream_metadata)
171473c88f9SBruce Richardson {
172473c88f9SBruce Richardson struct feature_fme_header *fme_hdr
173473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
174473c88f9SBruce Richardson
175473c88f9SBruce Richardson *bitstream_metadata = readq(&fme_hdr->bitstream_md);
176473c88f9SBruce Richardson
177473c88f9SBruce Richardson return 0;
178473c88f9SBruce Richardson }
179473c88f9SBruce Richardson
180473c88f9SBruce Richardson static int
fme_hdr_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)181473c88f9SBruce Richardson fme_hdr_get_prop(struct ifpga_feature *feature, struct feature_prop *prop)
182473c88f9SBruce Richardson {
183473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
184473c88f9SBruce Richardson
185473c88f9SBruce Richardson switch (prop->prop_id) {
186473c88f9SBruce Richardson case FME_HDR_PROP_REVISION:
187473c88f9SBruce Richardson return fme_hdr_get_revision(fme, &prop->data);
188473c88f9SBruce Richardson case FME_HDR_PROP_PORTS_NUM:
189473c88f9SBruce Richardson return fme_hdr_get_ports_num(fme, &prop->data);
190473c88f9SBruce Richardson case FME_HDR_PROP_CACHE_SIZE:
191473c88f9SBruce Richardson return fme_hdr_get_cache_size(fme, &prop->data);
192473c88f9SBruce Richardson case FME_HDR_PROP_VERSION:
193473c88f9SBruce Richardson return fme_hdr_get_version(fme, &prop->data);
194473c88f9SBruce Richardson case FME_HDR_PROP_SOCKET_ID:
195473c88f9SBruce Richardson return fme_hdr_get_socket_id(fme, &prop->data);
196473c88f9SBruce Richardson case FME_HDR_PROP_BITSTREAM_ID:
197473c88f9SBruce Richardson return fme_hdr_get_bitstream_id(fme, &prop->data);
198473c88f9SBruce Richardson case FME_HDR_PROP_BITSTREAM_METADATA:
199473c88f9SBruce Richardson return fme_hdr_get_bitstream_metadata(fme, &prop->data);
200cf38bcd7SWei Huang case FME_HDR_PROP_PORT_TYPE:
201cf38bcd7SWei Huang return fme_hdr_get_port_type(fme, &prop->data);
202473c88f9SBruce Richardson }
203473c88f9SBruce Richardson
204473c88f9SBruce Richardson return -ENOENT;
205473c88f9SBruce Richardson }
206473c88f9SBruce Richardson
207473c88f9SBruce Richardson struct ifpga_feature_ops fme_hdr_ops = {
208473c88f9SBruce Richardson .init = fme_hdr_init,
209473c88f9SBruce Richardson .uinit = fme_hdr_uinit,
210473c88f9SBruce Richardson .get_prop = fme_hdr_get_prop,
211473c88f9SBruce Richardson };
212473c88f9SBruce Richardson
213473c88f9SBruce Richardson /* thermal management */
fme_thermal_get_threshold1(struct ifpga_fme_hw * fme,u64 * thres1)214473c88f9SBruce Richardson static int fme_thermal_get_threshold1(struct ifpga_fme_hw *fme, u64 *thres1)
215473c88f9SBruce Richardson {
216473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
217473c88f9SBruce Richardson struct feature_fme_tmp_threshold temp_threshold;
218473c88f9SBruce Richardson
219473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
220473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
221473c88f9SBruce Richardson
222473c88f9SBruce Richardson temp_threshold.csr = readq(&thermal->threshold);
223473c88f9SBruce Richardson *thres1 = temp_threshold.tmp_thshold1;
224473c88f9SBruce Richardson
225473c88f9SBruce Richardson return 0;
226473c88f9SBruce Richardson }
227473c88f9SBruce Richardson
fme_thermal_set_threshold1(struct ifpga_fme_hw * fme,u64 thres1)228473c88f9SBruce Richardson static int fme_thermal_set_threshold1(struct ifpga_fme_hw *fme, u64 thres1)
229473c88f9SBruce Richardson {
230473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
231473c88f9SBruce Richardson struct feature_fme_header *fme_hdr;
232473c88f9SBruce Richardson struct feature_fme_tmp_threshold tmp_threshold;
233473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
234473c88f9SBruce Richardson
235473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
236473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
237473c88f9SBruce Richardson fme_hdr = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
238473c88f9SBruce Richardson
239473c88f9SBruce Richardson spinlock_lock(&fme->lock);
240473c88f9SBruce Richardson tmp_threshold.csr = readq(&thermal->threshold);
241473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
242473c88f9SBruce Richardson
243473c88f9SBruce Richardson if (fme_capability.lock_bit == 1) {
244473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
245473c88f9SBruce Richardson return -EBUSY;
246473c88f9SBruce Richardson } else if (thres1 > 100) {
247473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
248473c88f9SBruce Richardson return -EINVAL;
249473c88f9SBruce Richardson } else if (thres1 == 0) {
250473c88f9SBruce Richardson tmp_threshold.tmp_thshold1_enable = 0;
251473c88f9SBruce Richardson tmp_threshold.tmp_thshold1 = thres1;
252473c88f9SBruce Richardson } else {
253473c88f9SBruce Richardson tmp_threshold.tmp_thshold1_enable = 1;
254473c88f9SBruce Richardson tmp_threshold.tmp_thshold1 = thres1;
255473c88f9SBruce Richardson }
256473c88f9SBruce Richardson
257473c88f9SBruce Richardson writeq(tmp_threshold.csr, &thermal->threshold);
258473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
259473c88f9SBruce Richardson
260473c88f9SBruce Richardson return 0;
261473c88f9SBruce Richardson }
262473c88f9SBruce Richardson
fme_thermal_get_threshold2(struct ifpga_fme_hw * fme,u64 * thres2)263473c88f9SBruce Richardson static int fme_thermal_get_threshold2(struct ifpga_fme_hw *fme, u64 *thres2)
264473c88f9SBruce Richardson {
265473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
266473c88f9SBruce Richardson struct feature_fme_tmp_threshold temp_threshold;
267473c88f9SBruce Richardson
268473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
269473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
270473c88f9SBruce Richardson
271473c88f9SBruce Richardson temp_threshold.csr = readq(&thermal->threshold);
272473c88f9SBruce Richardson *thres2 = temp_threshold.tmp_thshold2;
273473c88f9SBruce Richardson
274473c88f9SBruce Richardson return 0;
275473c88f9SBruce Richardson }
276473c88f9SBruce Richardson
fme_thermal_set_threshold2(struct ifpga_fme_hw * fme,u64 thres2)277473c88f9SBruce Richardson static int fme_thermal_set_threshold2(struct ifpga_fme_hw *fme, u64 thres2)
278473c88f9SBruce Richardson {
279473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
280473c88f9SBruce Richardson struct feature_fme_header *fme_hdr;
281473c88f9SBruce Richardson struct feature_fme_tmp_threshold tmp_threshold;
282473c88f9SBruce Richardson struct feature_fme_capability fme_capability;
283473c88f9SBruce Richardson
284473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
285473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
286473c88f9SBruce Richardson fme_hdr = get_fme_feature_ioaddr_by_index(fme, FME_FEATURE_ID_HEADER);
287473c88f9SBruce Richardson
288473c88f9SBruce Richardson spinlock_lock(&fme->lock);
289473c88f9SBruce Richardson tmp_threshold.csr = readq(&thermal->threshold);
290473c88f9SBruce Richardson fme_capability.csr = readq(&fme_hdr->capability);
291473c88f9SBruce Richardson
292473c88f9SBruce Richardson if (fme_capability.lock_bit == 1) {
293473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
294473c88f9SBruce Richardson return -EBUSY;
295473c88f9SBruce Richardson } else if (thres2 > 100) {
296473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
297473c88f9SBruce Richardson return -EINVAL;
298473c88f9SBruce Richardson } else if (thres2 == 0) {
299473c88f9SBruce Richardson tmp_threshold.tmp_thshold2_enable = 0;
300473c88f9SBruce Richardson tmp_threshold.tmp_thshold2 = thres2;
301473c88f9SBruce Richardson } else {
302473c88f9SBruce Richardson tmp_threshold.tmp_thshold2_enable = 1;
303473c88f9SBruce Richardson tmp_threshold.tmp_thshold2 = thres2;
304473c88f9SBruce Richardson }
305473c88f9SBruce Richardson
306473c88f9SBruce Richardson writeq(tmp_threshold.csr, &thermal->threshold);
307473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
308473c88f9SBruce Richardson
309473c88f9SBruce Richardson return 0;
310473c88f9SBruce Richardson }
311473c88f9SBruce Richardson
fme_thermal_get_threshold_trip(struct ifpga_fme_hw * fme,u64 * thres_trip)312473c88f9SBruce Richardson static int fme_thermal_get_threshold_trip(struct ifpga_fme_hw *fme,
313473c88f9SBruce Richardson u64 *thres_trip)
314473c88f9SBruce Richardson {
315473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
316473c88f9SBruce Richardson struct feature_fme_tmp_threshold temp_threshold;
317473c88f9SBruce Richardson
318473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
319473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
320473c88f9SBruce Richardson
321473c88f9SBruce Richardson temp_threshold.csr = readq(&thermal->threshold);
322473c88f9SBruce Richardson *thres_trip = temp_threshold.therm_trip_thshold;
323473c88f9SBruce Richardson
324473c88f9SBruce Richardson return 0;
325473c88f9SBruce Richardson }
326473c88f9SBruce Richardson
fme_thermal_get_threshold1_reached(struct ifpga_fme_hw * fme,u64 * thres1_reached)327473c88f9SBruce Richardson static int fme_thermal_get_threshold1_reached(struct ifpga_fme_hw *fme,
328473c88f9SBruce Richardson u64 *thres1_reached)
329473c88f9SBruce Richardson {
330473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
331473c88f9SBruce Richardson struct feature_fme_tmp_threshold temp_threshold;
332473c88f9SBruce Richardson
333473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
334473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
335473c88f9SBruce Richardson
336473c88f9SBruce Richardson temp_threshold.csr = readq(&thermal->threshold);
337473c88f9SBruce Richardson *thres1_reached = temp_threshold.thshold1_status;
338473c88f9SBruce Richardson
339473c88f9SBruce Richardson return 0;
340473c88f9SBruce Richardson }
341473c88f9SBruce Richardson
fme_thermal_get_threshold2_reached(struct ifpga_fme_hw * fme,u64 * thres1_reached)342473c88f9SBruce Richardson static int fme_thermal_get_threshold2_reached(struct ifpga_fme_hw *fme,
343473c88f9SBruce Richardson u64 *thres1_reached)
344473c88f9SBruce Richardson {
345473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
346473c88f9SBruce Richardson struct feature_fme_tmp_threshold temp_threshold;
347473c88f9SBruce Richardson
348473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
349473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
350473c88f9SBruce Richardson
351473c88f9SBruce Richardson temp_threshold.csr = readq(&thermal->threshold);
352473c88f9SBruce Richardson *thres1_reached = temp_threshold.thshold2_status;
353473c88f9SBruce Richardson
354473c88f9SBruce Richardson return 0;
355473c88f9SBruce Richardson }
356473c88f9SBruce Richardson
fme_thermal_get_threshold1_policy(struct ifpga_fme_hw * fme,u64 * thres1_policy)357473c88f9SBruce Richardson static int fme_thermal_get_threshold1_policy(struct ifpga_fme_hw *fme,
358473c88f9SBruce Richardson u64 *thres1_policy)
359473c88f9SBruce Richardson {
360473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
361473c88f9SBruce Richardson struct feature_fme_tmp_threshold temp_threshold;
362473c88f9SBruce Richardson
363473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
364473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
365473c88f9SBruce Richardson
366473c88f9SBruce Richardson temp_threshold.csr = readq(&thermal->threshold);
367473c88f9SBruce Richardson *thres1_policy = temp_threshold.thshold_policy;
368473c88f9SBruce Richardson
369473c88f9SBruce Richardson return 0;
370473c88f9SBruce Richardson }
371473c88f9SBruce Richardson
fme_thermal_set_threshold1_policy(struct ifpga_fme_hw * fme,u64 thres1_policy)372473c88f9SBruce Richardson static int fme_thermal_set_threshold1_policy(struct ifpga_fme_hw *fme,
373473c88f9SBruce Richardson u64 thres1_policy)
374473c88f9SBruce Richardson {
375473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
376473c88f9SBruce Richardson struct feature_fme_tmp_threshold tmp_threshold;
377473c88f9SBruce Richardson
378473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
379473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
380473c88f9SBruce Richardson
381473c88f9SBruce Richardson spinlock_lock(&fme->lock);
382473c88f9SBruce Richardson tmp_threshold.csr = readq(&thermal->threshold);
383473c88f9SBruce Richardson
384473c88f9SBruce Richardson if (thres1_policy == 0) {
385473c88f9SBruce Richardson tmp_threshold.thshold_policy = 0;
386473c88f9SBruce Richardson } else if (thres1_policy == 1) {
387473c88f9SBruce Richardson tmp_threshold.thshold_policy = 1;
388473c88f9SBruce Richardson } else {
389473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
390473c88f9SBruce Richardson return -EINVAL;
391473c88f9SBruce Richardson }
392473c88f9SBruce Richardson
393473c88f9SBruce Richardson writeq(tmp_threshold.csr, &thermal->threshold);
394473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
395473c88f9SBruce Richardson
396473c88f9SBruce Richardson return 0;
397473c88f9SBruce Richardson }
398473c88f9SBruce Richardson
fme_thermal_get_temperature(struct ifpga_fme_hw * fme,u64 * temp)399473c88f9SBruce Richardson static int fme_thermal_get_temperature(struct ifpga_fme_hw *fme, u64 *temp)
400473c88f9SBruce Richardson {
401473c88f9SBruce Richardson struct feature_fme_thermal *thermal;
402473c88f9SBruce Richardson struct feature_fme_temp_rdsensor_fmt1 temp_rdsensor_fmt1;
403473c88f9SBruce Richardson
404473c88f9SBruce Richardson thermal = get_fme_feature_ioaddr_by_index(fme,
405473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
406473c88f9SBruce Richardson
407473c88f9SBruce Richardson temp_rdsensor_fmt1.csr = readq(&thermal->rdsensor_fm1);
408473c88f9SBruce Richardson *temp = temp_rdsensor_fmt1.fpga_temp;
409473c88f9SBruce Richardson
410473c88f9SBruce Richardson return 0;
411473c88f9SBruce Richardson }
412473c88f9SBruce Richardson
fme_thermal_get_revision(struct ifpga_fme_hw * fme,u64 * revision)413473c88f9SBruce Richardson static int fme_thermal_get_revision(struct ifpga_fme_hw *fme, u64 *revision)
414473c88f9SBruce Richardson {
415473c88f9SBruce Richardson struct feature_fme_thermal *fme_thermal
416473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
417473c88f9SBruce Richardson FME_FEATURE_ID_THERMAL_MGMT);
418473c88f9SBruce Richardson struct feature_header header;
419473c88f9SBruce Richardson
420473c88f9SBruce Richardson header.csr = readq(&fme_thermal->header);
421473c88f9SBruce Richardson *revision = header.revision;
422473c88f9SBruce Richardson
423473c88f9SBruce Richardson return 0;
424473c88f9SBruce Richardson }
425473c88f9SBruce Richardson
426473c88f9SBruce Richardson #define FME_THERMAL_CAP_NO_TMP_THRESHOLD 0x1
427473c88f9SBruce Richardson
fme_thermal_mgmt_init(struct ifpga_feature * feature)428473c88f9SBruce Richardson static int fme_thermal_mgmt_init(struct ifpga_feature *feature)
429473c88f9SBruce Richardson {
430473c88f9SBruce Richardson struct feature_fme_thermal *fme_thermal;
431473c88f9SBruce Richardson struct feature_fme_tmp_threshold_cap thermal_cap;
432473c88f9SBruce Richardson
433473c88f9SBruce Richardson UNUSED(feature);
434473c88f9SBruce Richardson
435473c88f9SBruce Richardson dev_info(NULL, "FME thermal mgmt Init.\n");
436473c88f9SBruce Richardson
437473c88f9SBruce Richardson fme_thermal = (struct feature_fme_thermal *)feature->addr;
438473c88f9SBruce Richardson thermal_cap.csr = readq(&fme_thermal->threshold_cap);
439473c88f9SBruce Richardson
440473c88f9SBruce Richardson dev_info(NULL, "FME thermal cap %llx.\n",
441473c88f9SBruce Richardson (unsigned long long)fme_thermal->threshold_cap.csr);
442473c88f9SBruce Richardson
443473c88f9SBruce Richardson if (thermal_cap.tmp_thshold_disabled)
444473c88f9SBruce Richardson feature->cap |= FME_THERMAL_CAP_NO_TMP_THRESHOLD;
445473c88f9SBruce Richardson
446473c88f9SBruce Richardson return 0;
447473c88f9SBruce Richardson }
448473c88f9SBruce Richardson
fme_thermal_mgmt_uinit(struct ifpga_feature * feature)449473c88f9SBruce Richardson static void fme_thermal_mgmt_uinit(struct ifpga_feature *feature)
450473c88f9SBruce Richardson {
451473c88f9SBruce Richardson UNUSED(feature);
452473c88f9SBruce Richardson
453473c88f9SBruce Richardson dev_info(NULL, "FME thermal mgmt UInit.\n");
454473c88f9SBruce Richardson }
455473c88f9SBruce Richardson
456473c88f9SBruce Richardson static int
fme_thermal_set_prop(struct ifpga_feature * feature,struct feature_prop * prop)457473c88f9SBruce Richardson fme_thermal_set_prop(struct ifpga_feature *feature, struct feature_prop *prop)
458473c88f9SBruce Richardson {
459473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
460473c88f9SBruce Richardson
461473c88f9SBruce Richardson if (feature->cap & FME_THERMAL_CAP_NO_TMP_THRESHOLD)
462473c88f9SBruce Richardson return -ENOENT;
463473c88f9SBruce Richardson
464473c88f9SBruce Richardson switch (prop->prop_id) {
465473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD1:
466473c88f9SBruce Richardson return fme_thermal_set_threshold1(fme, prop->data);
467473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD2:
468473c88f9SBruce Richardson return fme_thermal_set_threshold2(fme, prop->data);
469473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD1_POLICY:
470473c88f9SBruce Richardson return fme_thermal_set_threshold1_policy(fme, prop->data);
471473c88f9SBruce Richardson }
472473c88f9SBruce Richardson
473473c88f9SBruce Richardson return -ENOENT;
474473c88f9SBruce Richardson }
475473c88f9SBruce Richardson
476473c88f9SBruce Richardson static int
fme_thermal_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)477473c88f9SBruce Richardson fme_thermal_get_prop(struct ifpga_feature *feature, struct feature_prop *prop)
478473c88f9SBruce Richardson {
479473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
480473c88f9SBruce Richardson
481473c88f9SBruce Richardson if (feature->cap & FME_THERMAL_CAP_NO_TMP_THRESHOLD &&
482473c88f9SBruce Richardson prop->prop_id != FME_THERMAL_PROP_TEMPERATURE &&
483473c88f9SBruce Richardson prop->prop_id != FME_THERMAL_PROP_REVISION)
484473c88f9SBruce Richardson return -ENOENT;
485473c88f9SBruce Richardson
486473c88f9SBruce Richardson switch (prop->prop_id) {
487473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD1:
488473c88f9SBruce Richardson return fme_thermal_get_threshold1(fme, &prop->data);
489473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD2:
490473c88f9SBruce Richardson return fme_thermal_get_threshold2(fme, &prop->data);
491473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD_TRIP:
492473c88f9SBruce Richardson return fme_thermal_get_threshold_trip(fme, &prop->data);
493473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD1_REACHED:
494473c88f9SBruce Richardson return fme_thermal_get_threshold1_reached(fme, &prop->data);
495473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD2_REACHED:
496473c88f9SBruce Richardson return fme_thermal_get_threshold2_reached(fme, &prop->data);
497473c88f9SBruce Richardson case FME_THERMAL_PROP_THRESHOLD1_POLICY:
498473c88f9SBruce Richardson return fme_thermal_get_threshold1_policy(fme, &prop->data);
499473c88f9SBruce Richardson case FME_THERMAL_PROP_TEMPERATURE:
500473c88f9SBruce Richardson return fme_thermal_get_temperature(fme, &prop->data);
501473c88f9SBruce Richardson case FME_THERMAL_PROP_REVISION:
502473c88f9SBruce Richardson return fme_thermal_get_revision(fme, &prop->data);
503473c88f9SBruce Richardson }
504473c88f9SBruce Richardson
505473c88f9SBruce Richardson return -ENOENT;
506473c88f9SBruce Richardson }
507473c88f9SBruce Richardson
508473c88f9SBruce Richardson struct ifpga_feature_ops fme_thermal_mgmt_ops = {
509473c88f9SBruce Richardson .init = fme_thermal_mgmt_init,
510473c88f9SBruce Richardson .uinit = fme_thermal_mgmt_uinit,
511473c88f9SBruce Richardson .get_prop = fme_thermal_get_prop,
512473c88f9SBruce Richardson .set_prop = fme_thermal_set_prop,
513473c88f9SBruce Richardson };
514473c88f9SBruce Richardson
fme_pwr_get_consumed(struct ifpga_fme_hw * fme,u64 * consumed)515473c88f9SBruce Richardson static int fme_pwr_get_consumed(struct ifpga_fme_hw *fme, u64 *consumed)
516473c88f9SBruce Richardson {
517473c88f9SBruce Richardson struct feature_fme_power *fme_power
518473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
519473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
520473c88f9SBruce Richardson struct feature_fme_pm_status pm_status;
521473c88f9SBruce Richardson
522473c88f9SBruce Richardson pm_status.csr = readq(&fme_power->status);
523473c88f9SBruce Richardson
524473c88f9SBruce Richardson *consumed = pm_status.pwr_consumed;
525473c88f9SBruce Richardson
526473c88f9SBruce Richardson return 0;
527473c88f9SBruce Richardson }
528473c88f9SBruce Richardson
fme_pwr_get_threshold1(struct ifpga_fme_hw * fme,u64 * threshold)529473c88f9SBruce Richardson static int fme_pwr_get_threshold1(struct ifpga_fme_hw *fme, u64 *threshold)
530473c88f9SBruce Richardson {
531473c88f9SBruce Richardson struct feature_fme_power *fme_power
532473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
533473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
534473c88f9SBruce Richardson struct feature_fme_pm_ap_threshold pm_ap_threshold;
535473c88f9SBruce Richardson
536473c88f9SBruce Richardson pm_ap_threshold.csr = readq(&fme_power->threshold);
537473c88f9SBruce Richardson
538473c88f9SBruce Richardson *threshold = pm_ap_threshold.threshold1;
539473c88f9SBruce Richardson
540473c88f9SBruce Richardson return 0;
541473c88f9SBruce Richardson }
542473c88f9SBruce Richardson
fme_pwr_set_threshold1(struct ifpga_fme_hw * fme,u64 threshold)543473c88f9SBruce Richardson static int fme_pwr_set_threshold1(struct ifpga_fme_hw *fme, u64 threshold)
544473c88f9SBruce Richardson {
545473c88f9SBruce Richardson struct feature_fme_power *fme_power
546473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
547473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
548473c88f9SBruce Richardson struct feature_fme_pm_ap_threshold pm_ap_threshold;
549473c88f9SBruce Richardson
550473c88f9SBruce Richardson spinlock_lock(&fme->lock);
551473c88f9SBruce Richardson pm_ap_threshold.csr = readq(&fme_power->threshold);
552473c88f9SBruce Richardson
553473c88f9SBruce Richardson if (threshold <= PWR_THRESHOLD_MAX) {
554473c88f9SBruce Richardson pm_ap_threshold.threshold1 = threshold;
555473c88f9SBruce Richardson } else {
556473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
557473c88f9SBruce Richardson return -EINVAL;
558473c88f9SBruce Richardson }
559473c88f9SBruce Richardson
560473c88f9SBruce Richardson writeq(pm_ap_threshold.csr, &fme_power->threshold);
561473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
562473c88f9SBruce Richardson
563473c88f9SBruce Richardson return 0;
564473c88f9SBruce Richardson }
565473c88f9SBruce Richardson
fme_pwr_get_threshold2(struct ifpga_fme_hw * fme,u64 * threshold)566473c88f9SBruce Richardson static int fme_pwr_get_threshold2(struct ifpga_fme_hw *fme, u64 *threshold)
567473c88f9SBruce Richardson {
568473c88f9SBruce Richardson struct feature_fme_power *fme_power
569473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
570473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
571473c88f9SBruce Richardson struct feature_fme_pm_ap_threshold pm_ap_threshold;
572473c88f9SBruce Richardson
573473c88f9SBruce Richardson pm_ap_threshold.csr = readq(&fme_power->threshold);
574473c88f9SBruce Richardson
575473c88f9SBruce Richardson *threshold = pm_ap_threshold.threshold2;
576473c88f9SBruce Richardson
577473c88f9SBruce Richardson return 0;
578473c88f9SBruce Richardson }
579473c88f9SBruce Richardson
fme_pwr_set_threshold2(struct ifpga_fme_hw * fme,u64 threshold)580473c88f9SBruce Richardson static int fme_pwr_set_threshold2(struct ifpga_fme_hw *fme, u64 threshold)
581473c88f9SBruce Richardson {
582473c88f9SBruce Richardson struct feature_fme_power *fme_power
583473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
584473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
585473c88f9SBruce Richardson struct feature_fme_pm_ap_threshold pm_ap_threshold;
586473c88f9SBruce Richardson
587473c88f9SBruce Richardson spinlock_lock(&fme->lock);
588473c88f9SBruce Richardson pm_ap_threshold.csr = readq(&fme_power->threshold);
589473c88f9SBruce Richardson
590473c88f9SBruce Richardson if (threshold <= PWR_THRESHOLD_MAX) {
591473c88f9SBruce Richardson pm_ap_threshold.threshold2 = threshold;
592473c88f9SBruce Richardson } else {
593473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
594473c88f9SBruce Richardson return -EINVAL;
595473c88f9SBruce Richardson }
596473c88f9SBruce Richardson
597473c88f9SBruce Richardson writeq(pm_ap_threshold.csr, &fme_power->threshold);
598473c88f9SBruce Richardson spinlock_unlock(&fme->lock);
599473c88f9SBruce Richardson
600473c88f9SBruce Richardson return 0;
601473c88f9SBruce Richardson }
602473c88f9SBruce Richardson
fme_pwr_get_threshold1_status(struct ifpga_fme_hw * fme,u64 * threshold_status)603473c88f9SBruce Richardson static int fme_pwr_get_threshold1_status(struct ifpga_fme_hw *fme,
604473c88f9SBruce Richardson u64 *threshold_status)
605473c88f9SBruce Richardson {
606473c88f9SBruce Richardson struct feature_fme_power *fme_power
607473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
608473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
609473c88f9SBruce Richardson struct feature_fme_pm_ap_threshold pm_ap_threshold;
610473c88f9SBruce Richardson
611473c88f9SBruce Richardson pm_ap_threshold.csr = readq(&fme_power->threshold);
612473c88f9SBruce Richardson
613473c88f9SBruce Richardson *threshold_status = pm_ap_threshold.threshold1_status;
614473c88f9SBruce Richardson
615473c88f9SBruce Richardson return 0;
616473c88f9SBruce Richardson }
617473c88f9SBruce Richardson
fme_pwr_get_threshold2_status(struct ifpga_fme_hw * fme,u64 * threshold_status)618473c88f9SBruce Richardson static int fme_pwr_get_threshold2_status(struct ifpga_fme_hw *fme,
619473c88f9SBruce Richardson u64 *threshold_status)
620473c88f9SBruce Richardson {
621473c88f9SBruce Richardson struct feature_fme_power *fme_power
622473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
623473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
624473c88f9SBruce Richardson struct feature_fme_pm_ap_threshold pm_ap_threshold;
625473c88f9SBruce Richardson
626473c88f9SBruce Richardson pm_ap_threshold.csr = readq(&fme_power->threshold);
627473c88f9SBruce Richardson
628473c88f9SBruce Richardson *threshold_status = pm_ap_threshold.threshold2_status;
629473c88f9SBruce Richardson
630473c88f9SBruce Richardson return 0;
631473c88f9SBruce Richardson }
632473c88f9SBruce Richardson
fme_pwr_get_rtl(struct ifpga_fme_hw * fme,u64 * rtl)633473c88f9SBruce Richardson static int fme_pwr_get_rtl(struct ifpga_fme_hw *fme, u64 *rtl)
634473c88f9SBruce Richardson {
635473c88f9SBruce Richardson struct feature_fme_power *fme_power
636473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
637473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
638473c88f9SBruce Richardson struct feature_fme_pm_status pm_status;
639473c88f9SBruce Richardson
640473c88f9SBruce Richardson pm_status.csr = readq(&fme_power->status);
641473c88f9SBruce Richardson
642473c88f9SBruce Richardson *rtl = pm_status.fpga_latency_report;
643473c88f9SBruce Richardson
644473c88f9SBruce Richardson return 0;
645473c88f9SBruce Richardson }
646473c88f9SBruce Richardson
fme_pwr_get_xeon_limit(struct ifpga_fme_hw * fme,u64 * limit)647473c88f9SBruce Richardson static int fme_pwr_get_xeon_limit(struct ifpga_fme_hw *fme, u64 *limit)
648473c88f9SBruce Richardson {
649473c88f9SBruce Richardson struct feature_fme_power *fme_power
650473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
651473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
652473c88f9SBruce Richardson struct feature_fme_pm_xeon_limit xeon_limit;
653473c88f9SBruce Richardson
654473c88f9SBruce Richardson xeon_limit.csr = readq(&fme_power->xeon_limit);
655473c88f9SBruce Richardson
656473c88f9SBruce Richardson if (!xeon_limit.enable)
657473c88f9SBruce Richardson xeon_limit.pwr_limit = 0;
658473c88f9SBruce Richardson
659473c88f9SBruce Richardson *limit = xeon_limit.pwr_limit;
660473c88f9SBruce Richardson
661473c88f9SBruce Richardson return 0;
662473c88f9SBruce Richardson }
663473c88f9SBruce Richardson
fme_pwr_get_fpga_limit(struct ifpga_fme_hw * fme,u64 * limit)664473c88f9SBruce Richardson static int fme_pwr_get_fpga_limit(struct ifpga_fme_hw *fme, u64 *limit)
665473c88f9SBruce Richardson {
666473c88f9SBruce Richardson struct feature_fme_power *fme_power
667473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
668473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
669473c88f9SBruce Richardson struct feature_fme_pm_fpga_limit fpga_limit;
670473c88f9SBruce Richardson
671473c88f9SBruce Richardson fpga_limit.csr = readq(&fme_power->fpga_limit);
672473c88f9SBruce Richardson
673473c88f9SBruce Richardson if (!fpga_limit.enable)
674473c88f9SBruce Richardson fpga_limit.pwr_limit = 0;
675473c88f9SBruce Richardson
676473c88f9SBruce Richardson *limit = fpga_limit.pwr_limit;
677473c88f9SBruce Richardson
678473c88f9SBruce Richardson return 0;
679473c88f9SBruce Richardson }
680473c88f9SBruce Richardson
fme_pwr_get_revision(struct ifpga_fme_hw * fme,u64 * revision)681473c88f9SBruce Richardson static int fme_pwr_get_revision(struct ifpga_fme_hw *fme, u64 *revision)
682473c88f9SBruce Richardson {
683473c88f9SBruce Richardson struct feature_fme_power *fme_power
684473c88f9SBruce Richardson = get_fme_feature_ioaddr_by_index(fme,
685473c88f9SBruce Richardson FME_FEATURE_ID_POWER_MGMT);
686473c88f9SBruce Richardson struct feature_header header;
687473c88f9SBruce Richardson
688473c88f9SBruce Richardson header.csr = readq(&fme_power->header);
689473c88f9SBruce Richardson *revision = header.revision;
690473c88f9SBruce Richardson
691473c88f9SBruce Richardson return 0;
692473c88f9SBruce Richardson }
693473c88f9SBruce Richardson
fme_power_mgmt_init(struct ifpga_feature * feature)694473c88f9SBruce Richardson static int fme_power_mgmt_init(struct ifpga_feature *feature)
695473c88f9SBruce Richardson {
696473c88f9SBruce Richardson UNUSED(feature);
697473c88f9SBruce Richardson
698473c88f9SBruce Richardson dev_info(NULL, "FME power mgmt Init.\n");
699473c88f9SBruce Richardson
700473c88f9SBruce Richardson return 0;
701473c88f9SBruce Richardson }
702473c88f9SBruce Richardson
fme_power_mgmt_uinit(struct ifpga_feature * feature)703473c88f9SBruce Richardson static void fme_power_mgmt_uinit(struct ifpga_feature *feature)
704473c88f9SBruce Richardson {
705473c88f9SBruce Richardson UNUSED(feature);
706473c88f9SBruce Richardson
707473c88f9SBruce Richardson dev_info(NULL, "FME power mgmt UInit.\n");
708473c88f9SBruce Richardson }
709473c88f9SBruce Richardson
fme_power_mgmt_get_prop(struct ifpga_feature * feature,struct feature_prop * prop)710473c88f9SBruce Richardson static int fme_power_mgmt_get_prop(struct ifpga_feature *feature,
711473c88f9SBruce Richardson struct feature_prop *prop)
712473c88f9SBruce Richardson {
713473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
714473c88f9SBruce Richardson
715473c88f9SBruce Richardson switch (prop->prop_id) {
716473c88f9SBruce Richardson case FME_PWR_PROP_CONSUMED:
717473c88f9SBruce Richardson return fme_pwr_get_consumed(fme, &prop->data);
718473c88f9SBruce Richardson case FME_PWR_PROP_THRESHOLD1:
719473c88f9SBruce Richardson return fme_pwr_get_threshold1(fme, &prop->data);
720473c88f9SBruce Richardson case FME_PWR_PROP_THRESHOLD2:
721473c88f9SBruce Richardson return fme_pwr_get_threshold2(fme, &prop->data);
722473c88f9SBruce Richardson case FME_PWR_PROP_THRESHOLD1_STATUS:
723473c88f9SBruce Richardson return fme_pwr_get_threshold1_status(fme, &prop->data);
724473c88f9SBruce Richardson case FME_PWR_PROP_THRESHOLD2_STATUS:
725473c88f9SBruce Richardson return fme_pwr_get_threshold2_status(fme, &prop->data);
726473c88f9SBruce Richardson case FME_PWR_PROP_RTL:
727473c88f9SBruce Richardson return fme_pwr_get_rtl(fme, &prop->data);
728473c88f9SBruce Richardson case FME_PWR_PROP_XEON_LIMIT:
729473c88f9SBruce Richardson return fme_pwr_get_xeon_limit(fme, &prop->data);
730473c88f9SBruce Richardson case FME_PWR_PROP_FPGA_LIMIT:
731473c88f9SBruce Richardson return fme_pwr_get_fpga_limit(fme, &prop->data);
732473c88f9SBruce Richardson case FME_PWR_PROP_REVISION:
733473c88f9SBruce Richardson return fme_pwr_get_revision(fme, &prop->data);
734473c88f9SBruce Richardson }
735473c88f9SBruce Richardson
736473c88f9SBruce Richardson return -ENOENT;
737473c88f9SBruce Richardson }
738473c88f9SBruce Richardson
fme_power_mgmt_set_prop(struct ifpga_feature * feature,struct feature_prop * prop)739473c88f9SBruce Richardson static int fme_power_mgmt_set_prop(struct ifpga_feature *feature,
740473c88f9SBruce Richardson struct feature_prop *prop)
741473c88f9SBruce Richardson {
742473c88f9SBruce Richardson struct ifpga_fme_hw *fme = feature->parent;
743473c88f9SBruce Richardson
744473c88f9SBruce Richardson switch (prop->prop_id) {
745473c88f9SBruce Richardson case FME_PWR_PROP_THRESHOLD1:
746473c88f9SBruce Richardson return fme_pwr_set_threshold1(fme, prop->data);
747473c88f9SBruce Richardson case FME_PWR_PROP_THRESHOLD2:
748473c88f9SBruce Richardson return fme_pwr_set_threshold2(fme, prop->data);
749473c88f9SBruce Richardson }
750473c88f9SBruce Richardson
751473c88f9SBruce Richardson return -ENOENT;
752473c88f9SBruce Richardson }
753473c88f9SBruce Richardson
754473c88f9SBruce Richardson struct ifpga_feature_ops fme_power_mgmt_ops = {
755473c88f9SBruce Richardson .init = fme_power_mgmt_init,
756473c88f9SBruce Richardson .uinit = fme_power_mgmt_uinit,
757473c88f9SBruce Richardson .get_prop = fme_power_mgmt_get_prop,
758473c88f9SBruce Richardson .set_prop = fme_power_mgmt_set_prop,
759473c88f9SBruce Richardson };
760473c88f9SBruce Richardson
fme_hssi_eth_init(struct ifpga_feature * feature)761473c88f9SBruce Richardson static int fme_hssi_eth_init(struct ifpga_feature *feature)
762473c88f9SBruce Richardson {
763473c88f9SBruce Richardson UNUSED(feature);
764473c88f9SBruce Richardson return 0;
765473c88f9SBruce Richardson }
766473c88f9SBruce Richardson
fme_hssi_eth_uinit(struct ifpga_feature * feature)767473c88f9SBruce Richardson static void fme_hssi_eth_uinit(struct ifpga_feature *feature)
768473c88f9SBruce Richardson {
769473c88f9SBruce Richardson UNUSED(feature);
770473c88f9SBruce Richardson }
771473c88f9SBruce Richardson
772473c88f9SBruce Richardson struct ifpga_feature_ops fme_hssi_eth_ops = {
773473c88f9SBruce Richardson .init = fme_hssi_eth_init,
774473c88f9SBruce Richardson .uinit = fme_hssi_eth_uinit,
775473c88f9SBruce Richardson };
776473c88f9SBruce Richardson
fme_emif_init(struct ifpga_feature * feature)777473c88f9SBruce Richardson static int fme_emif_init(struct ifpga_feature *feature)
778473c88f9SBruce Richardson {
779473c88f9SBruce Richardson UNUSED(feature);
780473c88f9SBruce Richardson return 0;
781473c88f9SBruce Richardson }
782473c88f9SBruce Richardson
fme_emif_uinit(struct ifpga_feature * feature)783473c88f9SBruce Richardson static void fme_emif_uinit(struct ifpga_feature *feature)
784473c88f9SBruce Richardson {
785473c88f9SBruce Richardson UNUSED(feature);
786473c88f9SBruce Richardson }
787473c88f9SBruce Richardson
788473c88f9SBruce Richardson struct ifpga_feature_ops fme_emif_ops = {
789473c88f9SBruce Richardson .init = fme_emif_init,
790473c88f9SBruce Richardson .uinit = fme_emif_uinit,
791473c88f9SBruce Richardson };
792473c88f9SBruce Richardson
board_type_to_string(u32 board,u32 type)7937c4fe2adSWei Huang static const char *board_type_to_string(u32 board, u32 type)
794473c88f9SBruce Richardson {
7957c4fe2adSWei Huang if (board == VISTA_CREEK) {
796473c88f9SBruce Richardson switch (type) {
797473c88f9SBruce Richardson case VC_8_10G:
7987c4fe2adSWei Huang return "8x10G";
799473c88f9SBruce Richardson case VC_4_25G:
8007c4fe2adSWei Huang return "4x25G";
801473c88f9SBruce Richardson case VC_2_1_25:
8027c4fe2adSWei Huang return "2x1x25G";
803473c88f9SBruce Richardson case VC_4_25G_2_25G:
8047c4fe2adSWei Huang return "4x25G+2x25G";
805473c88f9SBruce Richardson case VC_2_2_25G:
8067c4fe2adSWei Huang return "2x2x25G";
8077c4fe2adSWei Huang break;
8087c4fe2adSWei Huang }
8097c4fe2adSWei Huang } else {
8107c4fe2adSWei Huang switch (type) {
8117c4fe2adSWei Huang case FIMA_10G_ADP:
8127c4fe2adSWei Huang return "2x4x10G";
8137c4fe2adSWei Huang case FIMA_25G_ADP:
8147c4fe2adSWei Huang return "2x2x25G";
8157c4fe2adSWei Huang case FIMA_100G_ADP:
8167c4fe2adSWei Huang return "2x100G";
8177c4fe2adSWei Huang break;
8187c4fe2adSWei Huang }
819473c88f9SBruce Richardson }
820473c88f9SBruce Richardson
821473c88f9SBruce Richardson return "unknown";
822473c88f9SBruce Richardson }
823473c88f9SBruce Richardson
board_major_to_string(u32 major)824c127953fSTianfei Zhang static const char *board_major_to_string(u32 major)
825c127953fSTianfei Zhang {
826c127953fSTianfei Zhang switch (major) {
827c127953fSTianfei Zhang case VISTA_CREEK:
828c127953fSTianfei Zhang return "VISTA_CREEK";
829c127953fSTianfei Zhang case RUSH_CREEK:
830c127953fSTianfei Zhang return "RUSH_CREEK";
831c127953fSTianfei Zhang case DARBY_CREEK:
832c127953fSTianfei Zhang return "DARBY_CREEK";
8337c4fe2adSWei Huang case LIGHTNING_CREEK:
8347c4fe2adSWei Huang return "LIGHTNING_CREEK";
8357c4fe2adSWei Huang case ARROW_CREEK:
8367c4fe2adSWei Huang return "ARROW_CREEK";
8377c4fe2adSWei Huang default:
8387c4fe2adSWei Huang break;
839c127953fSTianfei Zhang }
840c127953fSTianfei Zhang
841c127953fSTianfei Zhang return "unknown";
842c127953fSTianfei Zhang }
843c127953fSTianfei Zhang
board_type_to_info(u32 type,struct opae_board_info * info)844473c88f9SBruce Richardson static int board_type_to_info(u32 type,
845c127953fSTianfei Zhang struct opae_board_info *info)
846473c88f9SBruce Richardson {
847473c88f9SBruce Richardson switch (type) {
848473c88f9SBruce Richardson case VC_8_10G:
849473c88f9SBruce Richardson info->nums_of_retimer = 2;
850473c88f9SBruce Richardson info->ports_per_retimer = 4;
851473c88f9SBruce Richardson info->nums_of_fvl = 2;
852473c88f9SBruce Richardson info->ports_per_fvl = 4;
853473c88f9SBruce Richardson break;
854473c88f9SBruce Richardson case VC_4_25G:
855473c88f9SBruce Richardson info->nums_of_retimer = 1;
856473c88f9SBruce Richardson info->ports_per_retimer = 4;
857473c88f9SBruce Richardson info->nums_of_fvl = 2;
858473c88f9SBruce Richardson info->ports_per_fvl = 2;
859473c88f9SBruce Richardson break;
860473c88f9SBruce Richardson case VC_2_1_25:
861473c88f9SBruce Richardson info->nums_of_retimer = 2;
862473c88f9SBruce Richardson info->ports_per_retimer = 1;
863473c88f9SBruce Richardson info->nums_of_fvl = 1;
864473c88f9SBruce Richardson info->ports_per_fvl = 2;
865473c88f9SBruce Richardson break;
866473c88f9SBruce Richardson case VC_2_2_25G:
867473c88f9SBruce Richardson info->nums_of_retimer = 2;
868473c88f9SBruce Richardson info->ports_per_retimer = 2;
869473c88f9SBruce Richardson info->nums_of_fvl = 2;
870473c88f9SBruce Richardson info->ports_per_fvl = 2;
871473c88f9SBruce Richardson break;
872473c88f9SBruce Richardson default:
873473c88f9SBruce Richardson return -EINVAL;
874473c88f9SBruce Richardson }
875473c88f9SBruce Richardson
876473c88f9SBruce Richardson return 0;
877473c88f9SBruce Richardson }
878473c88f9SBruce Richardson
fme_get_board_interface(struct ifpga_fme_hw * fme)879473c88f9SBruce Richardson static int fme_get_board_interface(struct ifpga_fme_hw *fme)
880473c88f9SBruce Richardson {
8817c4fe2adSWei Huang struct feature_fme_bitstream_id id;
8824a19f891STianfei Zhang struct ifpga_hw *hw;
88371da60b8STianfei Zhang u32 val;
8847c4fe2adSWei Huang const char *type = NULL;
8857c4fe2adSWei Huang int ret;
886473c88f9SBruce Richardson
8874a19f891STianfei Zhang hw = fme->parent;
8884a19f891STianfei Zhang if (!hw)
8894a19f891STianfei Zhang return -ENODEV;
8904a19f891STianfei Zhang
8917c4fe2adSWei Huang if (fme_hdr_get_bitstream_id(fme, &id.csr))
892473c88f9SBruce Richardson return -EINVAL;
893473c88f9SBruce Richardson
8947c4fe2adSWei Huang if (id.v1.major == ARROW_CREEK) {
8957c4fe2adSWei Huang fme->board_info.major = id.v2.bs_vermajor;
8967c4fe2adSWei Huang fme->board_info.minor = id.v2.bs_verminor;
8977c4fe2adSWei Huang fme->board_info.n6000_fim_type = id.v2.fim_type;
8987c4fe2adSWei Huang fme->board_info.n6000_hssi_id = id.v2.hssi_id;
8997c4fe2adSWei Huang type = board_type_to_string(fme->board_info.major,
9007c4fe2adSWei Huang fme->board_info.n6000_fim_type);
9017c4fe2adSWei Huang } else {
9027c4fe2adSWei Huang fme->board_info.major = id.v1.major;
9037c4fe2adSWei Huang fme->board_info.minor = id.v1.minor;
9047c4fe2adSWei Huang fme->board_info.type = id.v1.interface;
9057c4fe2adSWei Huang fme->board_info.fvl_bypass = id.v1.fvl_bypass;
9067c4fe2adSWei Huang fme->board_info.mac_lightweight = id.v1.mac_lightweight;
9077c4fe2adSWei Huang fme->board_info.lightweight = id.v1.lightweiht;
9087c4fe2adSWei Huang fme->board_info.disaggregate = id.v1.disagregate;
9097c4fe2adSWei Huang fme->board_info.seu = id.v1.seu;
9107c4fe2adSWei Huang fme->board_info.ptp = id.v1.ptp;
9117c4fe2adSWei Huang type = board_type_to_string(fme->board_info.major,
9127c4fe2adSWei Huang fme->board_info.type);
9137c4fe2adSWei Huang }
914473c88f9SBruce Richardson
9154a19f891STianfei Zhang dev_info(fme, "found: PCI dev: %02x:%02x:%x board: %s type: %s\n",
9164a19f891STianfei Zhang hw->pci_data->bus,
9174a19f891STianfei Zhang hw->pci_data->devid,
9184a19f891STianfei Zhang hw->pci_data->function,
919c127953fSTianfei Zhang board_major_to_string(fme->board_info.major),
9207c4fe2adSWei Huang type);
921c127953fSTianfei Zhang
9227c4fe2adSWei Huang ret = max10_get_fpga_load_info(fme->max10_dev, &val);
9237c4fe2adSWei Huang if (ret)
9247c4fe2adSWei Huang return ret;
9257c4fe2adSWei Huang fme->board_info.boot_page = val;
9267c4fe2adSWei Huang
9277c4fe2adSWei Huang if (fme->board_info.major == VISTA_CREEK) {
9287c4fe2adSWei Huang dev_info(dev, "FPGA loaded from %s Image\n",
9297c4fe2adSWei Huang val ? "User" : "Factory");
930c127953fSTianfei Zhang dev_info(fme, "support feature:\n"
931c127953fSTianfei Zhang "fvl_bypass:%s\n"
932c127953fSTianfei Zhang "mac_lightweight:%s\n"
933c127953fSTianfei Zhang "lightweight:%s\n"
934c127953fSTianfei Zhang "disaggregate:%s\n"
935c127953fSTianfei Zhang "seu:%s\n"
936c127953fSTianfei Zhang "ptp1588:%s\n",
937c127953fSTianfei Zhang check_support(fme->board_info.fvl_bypass),
938c127953fSTianfei Zhang check_support(fme->board_info.mac_lightweight),
939c127953fSTianfei Zhang check_support(fme->board_info.lightweight),
940c127953fSTianfei Zhang check_support(fme->board_info.disaggregate),
941c127953fSTianfei Zhang check_support(fme->board_info.seu),
942c127953fSTianfei Zhang check_support(fme->board_info.ptp));
943c127953fSTianfei Zhang
944473c88f9SBruce Richardson if (board_type_to_info(fme->board_info.type, &fme->board_info))
945473c88f9SBruce Richardson return -EINVAL;
946473c88f9SBruce Richardson
9477c4fe2adSWei Huang dev_info(fme, "get board info: nums_retimers %d "
9487c4fe2adSWei Huang "ports_per_retimer %d nums_fvl %d "
9497c4fe2adSWei Huang "ports_per_fvl %d\n",
950473c88f9SBruce Richardson fme->board_info.nums_of_retimer,
951473c88f9SBruce Richardson fme->board_info.ports_per_retimer,
952473c88f9SBruce Richardson fme->board_info.nums_of_fvl,
953473c88f9SBruce Richardson fme->board_info.ports_per_fvl);
9547c4fe2adSWei Huang } else {
9557c4fe2adSWei Huang dev_info(dev, "FPGA loaded from %s Image\n",
9567c4fe2adSWei Huang val ? (val == 1 ? "User1" : "User2") : "Factory");
9577c4fe2adSWei Huang }
958473c88f9SBruce Richardson
9597c4fe2adSWei Huang ret = max10_get_bmc_version(fme->max10_dev, &val);
9607c4fe2adSWei Huang if (ret)
9617c4fe2adSWei Huang return ret;
962cf38bcd7SWei Huang fme->board_info.max10_version = val;
96371da60b8STianfei Zhang
9647c4fe2adSWei Huang ret = max10_get_bmcfw_version(fme->max10_dev, &val);
9657c4fe2adSWei Huang if (ret)
9667c4fe2adSWei Huang return ret;
967cf38bcd7SWei Huang fme->board_info.nios_fw_version = val;
96871da60b8STianfei Zhang
96971da60b8STianfei Zhang dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
97071da60b8STianfei Zhang fme->board_info.max10_version,
97171da60b8STianfei Zhang fme->board_info.nios_fw_version);
97271da60b8STianfei Zhang
973473c88f9SBruce Richardson return 0;
974473c88f9SBruce Richardson }
975473c88f9SBruce Richardson
spi_self_checking(struct intel_max10_device * dev)9764a19f891STianfei Zhang static int spi_self_checking(struct intel_max10_device *dev)
977473c88f9SBruce Richardson {
978473c88f9SBruce Richardson u32 val;
979473c88f9SBruce Richardson int ret;
980473c88f9SBruce Richardson
9814a19f891STianfei Zhang ret = max10_sys_read(dev, MAX10_TEST_REG, &val);
982473c88f9SBruce Richardson if (ret)
983473c88f9SBruce Richardson return -EIO;
984473c88f9SBruce Richardson
98571da60b8STianfei Zhang dev_info(NULL, "Read MAX10 test register 0x%x\n", val);
986473c88f9SBruce Richardson
987473c88f9SBruce Richardson return 0;
988473c88f9SBruce Richardson }
989473c88f9SBruce Richardson
init_spi_share_data(struct ifpga_fme_hw * fme,struct altera_spi_device * spi)990e41856b5SWei Huang static void init_spi_share_data(struct ifpga_fme_hw *fme,
991e41856b5SWei Huang struct altera_spi_device *spi)
992e41856b5SWei Huang {
993e41856b5SWei Huang struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent;
994e41856b5SWei Huang opae_share_data *sd = NULL;
995e41856b5SWei Huang
996e41856b5SWei Huang if (hw && hw->adapter && hw->adapter->shm.ptr) {
997e41856b5SWei Huang dev_info(NULL, "transfer share data to spi\n");
998e41856b5SWei Huang sd = (opae_share_data *)hw->adapter->shm.ptr;
999e41856b5SWei Huang spi->mutex = &sd->spi_mutex;
1000e41856b5SWei Huang spi->dtb_sz_ptr = &sd->dtb_size;
1001e41856b5SWei Huang spi->dtb = sd->dtb;
1002e41856b5SWei Huang } else {
1003e41856b5SWei Huang spi->mutex = NULL;
1004e41856b5SWei Huang spi->dtb_sz_ptr = NULL;
1005e41856b5SWei Huang spi->dtb = NULL;
1006e41856b5SWei Huang }
1007e41856b5SWei Huang }
1008e41856b5SWei Huang
fme_spi_init(struct ifpga_feature * feature)1009473c88f9SBruce Richardson static int fme_spi_init(struct ifpga_feature *feature)
1010473c88f9SBruce Richardson {
1011473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1012473c88f9SBruce Richardson struct altera_spi_device *spi_master;
1013473c88f9SBruce Richardson struct intel_max10_device *max10;
1014473c88f9SBruce Richardson int ret = 0;
1015473c88f9SBruce Richardson
1016473c88f9SBruce Richardson dev_info(fme, "FME SPI Master (Max10) Init.\n");
1017473c88f9SBruce Richardson dev_debug(fme, "FME SPI base addr %p.\n",
1018473c88f9SBruce Richardson feature->addr);
1019473c88f9SBruce Richardson dev_debug(fme, "spi param=0x%llx\n",
1020473c88f9SBruce Richardson (unsigned long long)opae_readq(feature->addr + 0x8));
1021473c88f9SBruce Richardson
1022473c88f9SBruce Richardson spi_master = altera_spi_alloc(feature->addr, TYPE_SPI);
1023473c88f9SBruce Richardson if (!spi_master)
1024473c88f9SBruce Richardson return -ENODEV;
1025e41856b5SWei Huang init_spi_share_data(fme, spi_master);
1026473c88f9SBruce Richardson
1027473c88f9SBruce Richardson altera_spi_init(spi_master);
1028473c88f9SBruce Richardson
1029ca6eb0f7SWei Huang max10 = opae_zmalloc(sizeof(*max10));
1030ca6eb0f7SWei Huang if (!max10)
1031ca6eb0f7SWei Huang goto release_dev;
1032ca6eb0f7SWei Huang
1033ca6eb0f7SWei Huang max10->spi_master = spi_master;
1034ca6eb0f7SWei Huang max10->type = M10_N3000;
1035ca6eb0f7SWei Huang
1036ca6eb0f7SWei Huang max10->spi_tran_dev = spi_transaction_init(spi_master, 0);
1037ca6eb0f7SWei Huang if (!max10->spi_tran_dev) {
1038ca6eb0f7SWei Huang dev_err(fme, "%s spi tran init fail\n", __func__);
1039ca6eb0f7SWei Huang goto free_max10;
1040ca6eb0f7SWei Huang }
1041ca6eb0f7SWei Huang
1042ca6eb0f7SWei Huang /* init the max10 device */
1043ca6eb0f7SWei Huang ret = intel_max10_device_init(max10);
1044ca6eb0f7SWei Huang if (ret) {
1045473c88f9SBruce Richardson ret = -ENODEV;
1046473c88f9SBruce Richardson dev_err(fme, "max10 init fail\n");
1047ca6eb0f7SWei Huang goto release_spi_tran_dev;
1048473c88f9SBruce Richardson }
1049473c88f9SBruce Richardson
1050473c88f9SBruce Richardson fme->max10_dev = max10;
1051473c88f9SBruce Richardson
1052473c88f9SBruce Richardson /* SPI self test */
10534a19f891STianfei Zhang if (spi_self_checking(max10)) {
1054473c88f9SBruce Richardson ret = -EIO;
1055473c88f9SBruce Richardson goto max10_fail;
1056473c88f9SBruce Richardson }
1057473c88f9SBruce Richardson
1058473c88f9SBruce Richardson return ret;
1059473c88f9SBruce Richardson
1060473c88f9SBruce Richardson max10_fail:
1061473c88f9SBruce Richardson intel_max10_device_remove(fme->max10_dev);
1062ca6eb0f7SWei Huang release_spi_tran_dev:
1063ca6eb0f7SWei Huang if (max10->spi_tran_dev)
1064ca6eb0f7SWei Huang spi_transaction_remove(max10->spi_tran_dev);
1065ca6eb0f7SWei Huang free_max10:
1066ca6eb0f7SWei Huang opae_free(max10);
1067ca6eb0f7SWei Huang release_dev:
1068473c88f9SBruce Richardson altera_spi_release(spi_master);
10697c4fe2adSWei Huang return -ENODEV;
1070473c88f9SBruce Richardson }
1071473c88f9SBruce Richardson
fme_spi_uinit(struct ifpga_feature * feature)1072473c88f9SBruce Richardson static void fme_spi_uinit(struct ifpga_feature *feature)
1073473c88f9SBruce Richardson {
1074473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1075473c88f9SBruce Richardson
1076ca6eb0f7SWei Huang if (fme->max10_dev) {
1077473c88f9SBruce Richardson intel_max10_device_remove(fme->max10_dev);
1078ca6eb0f7SWei Huang opae_free(fme->max10_dev);
1079ca6eb0f7SWei Huang }
1080473c88f9SBruce Richardson }
1081473c88f9SBruce Richardson
1082473c88f9SBruce Richardson struct ifpga_feature_ops fme_spi_master_ops = {
1083473c88f9SBruce Richardson .init = fme_spi_init,
1084473c88f9SBruce Richardson .uinit = fme_spi_uinit,
1085473c88f9SBruce Richardson };
1086473c88f9SBruce Richardson
nios_spi_wait_init_done(struct altera_spi_device * dev)1087473c88f9SBruce Richardson static int nios_spi_wait_init_done(struct altera_spi_device *dev)
1088473c88f9SBruce Richardson {
1089473c88f9SBruce Richardson u32 val = 0;
1090cbcf2263STianfei Zhang unsigned long timeout = rte_get_timer_cycles() +
1091cbcf2263STianfei Zhang msecs_to_timer_cycles(10000);
1092473c88f9SBruce Richardson unsigned long ticks;
1093bc44402fSTianfei Zhang int major_version;
1094cbcf2263STianfei Zhang int fecmode = FEC_MODE_NO;
1095473c88f9SBruce Richardson
1096bc44402fSTianfei Zhang if (spi_reg_read(dev, NIOS_VERSION, &val))
1097bc44402fSTianfei Zhang return -EIO;
1098bc44402fSTianfei Zhang
1099cbcf2263STianfei Zhang major_version =
1100cbcf2263STianfei Zhang (val & NIOS_VERSION_MAJOR) >> NIOS_VERSION_MAJOR_SHIFT;
1101cbcf2263STianfei Zhang dev_info(dev, "A10 NIOS FW version %d\n", major_version);
1102bc44402fSTianfei Zhang
1103bc44402fSTianfei Zhang if (major_version >= 3) {
1104bc44402fSTianfei Zhang /* read NIOS_INIT to check if PKVL INIT done or not */
1105bc44402fSTianfei Zhang if (spi_reg_read(dev, NIOS_INIT, &val))
1106bc44402fSTianfei Zhang return -EIO;
1107bc44402fSTianfei Zhang
1108cbcf2263STianfei Zhang dev_debug(dev, "read NIOS_INIT: 0x%x\n", val);
1109cbcf2263STianfei Zhang
1110bc44402fSTianfei Zhang /* check if PKVLs are initialized already */
1111bc44402fSTianfei Zhang if (val & NIOS_INIT_DONE || val & NIOS_INIT_START)
1112bc44402fSTianfei Zhang goto nios_init_done;
1113bc44402fSTianfei Zhang
1114bc44402fSTianfei Zhang /* start to config the default FEC mode */
1115cbcf2263STianfei Zhang val = fecmode | NIOS_INIT_START;
1116bc44402fSTianfei Zhang
1117bc44402fSTianfei Zhang if (spi_reg_write(dev, NIOS_INIT, val))
1118bc44402fSTianfei Zhang return -EIO;
1119bc44402fSTianfei Zhang }
1120bc44402fSTianfei Zhang
1121bc44402fSTianfei Zhang nios_init_done:
1122473c88f9SBruce Richardson do {
1123bc44402fSTianfei Zhang if (spi_reg_read(dev, NIOS_INIT, &val))
1124473c88f9SBruce Richardson return -EIO;
1125cbcf2263STianfei Zhang if (val & NIOS_INIT_DONE)
1126473c88f9SBruce Richardson break;
1127473c88f9SBruce Richardson
1128473c88f9SBruce Richardson ticks = rte_get_timer_cycles();
1129473c88f9SBruce Richardson if (time_after(ticks, timeout))
1130473c88f9SBruce Richardson return -ETIMEDOUT;
1131473c88f9SBruce Richardson msleep(100);
1132cbcf2263STianfei Zhang } while (1);
1133cbcf2263STianfei Zhang
1134cbcf2263STianfei Zhang /* get the fecmode */
1135cbcf2263STianfei Zhang if (spi_reg_read(dev, NIOS_INIT, &val))
1136cbcf2263STianfei Zhang return -EIO;
1137cbcf2263STianfei Zhang dev_debug(dev, "read NIOS_INIT: 0x%x\n", val);
1138cbcf2263STianfei Zhang fecmode = (val & REQ_FEC_MODE) >> REQ_FEC_MODE_SHIFT;
1139cbcf2263STianfei Zhang dev_info(dev, "fecmode: 0x%x, %s\n", fecmode,
1140cbcf2263STianfei Zhang (fecmode == FEC_MODE_KR) ? "kr" :
1141cbcf2263STianfei Zhang ((fecmode == FEC_MODE_RS) ? "rs" : "no"));
1142473c88f9SBruce Richardson
1143473c88f9SBruce Richardson return 0;
1144473c88f9SBruce Richardson }
1145473c88f9SBruce Richardson
nios_spi_check_error(struct altera_spi_device * dev)1146473c88f9SBruce Richardson static int nios_spi_check_error(struct altera_spi_device *dev)
1147473c88f9SBruce Richardson {
1148473c88f9SBruce Richardson u32 value = 0;
1149473c88f9SBruce Richardson
1150bc44402fSTianfei Zhang if (spi_reg_read(dev, PKVL_A_MODE_STS, &value))
1151473c88f9SBruce Richardson return -EIO;
1152473c88f9SBruce Richardson
1153bc44402fSTianfei Zhang dev_debug(dev, "PKVL A Mode Status 0x%x\n", value);
1154473c88f9SBruce Richardson
1155bc44402fSTianfei Zhang if (value >= 0x100)
1156473c88f9SBruce Richardson return -EINVAL;
1157473c88f9SBruce Richardson
1158bc44402fSTianfei Zhang if (spi_reg_read(dev, PKVL_B_MODE_STS, &value))
1159473c88f9SBruce Richardson return -EIO;
1160473c88f9SBruce Richardson
1161bc44402fSTianfei Zhang dev_debug(dev, "PKVL B Mode Status 0x%x\n", value);
1162473c88f9SBruce Richardson
1163bc44402fSTianfei Zhang if (value >= 0x100)
1164473c88f9SBruce Richardson return -EINVAL;
1165473c88f9SBruce Richardson
1166473c88f9SBruce Richardson return 0;
1167473c88f9SBruce Richardson }
1168473c88f9SBruce Richardson
fme_nios_spi_init(struct ifpga_feature * feature)1169473c88f9SBruce Richardson static int fme_nios_spi_init(struct ifpga_feature *feature)
1170473c88f9SBruce Richardson {
1171473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1172473c88f9SBruce Richardson struct altera_spi_device *spi_master;
1173473c88f9SBruce Richardson struct intel_max10_device *max10;
11744a19f891STianfei Zhang struct ifpga_hw *hw;
11754a19f891STianfei Zhang struct opae_manager *mgr;
1176473c88f9SBruce Richardson int ret = 0;
1177473c88f9SBruce Richardson
11784a19f891STianfei Zhang hw = fme->parent;
11794a19f891STianfei Zhang if (!hw)
11804a19f891STianfei Zhang return -ENODEV;
11814a19f891STianfei Zhang
11824a19f891STianfei Zhang mgr = hw->adapter->mgr;
11834a19f891STianfei Zhang if (!mgr)
11844a19f891STianfei Zhang return -ENODEV;
11854a19f891STianfei Zhang
1186473c88f9SBruce Richardson dev_info(fme, "FME SPI Master (NIOS) Init.\n");
1187473c88f9SBruce Richardson dev_debug(fme, "FME SPI base addr %p.\n",
1188473c88f9SBruce Richardson feature->addr);
1189473c88f9SBruce Richardson dev_debug(fme, "spi param=0x%llx\n",
1190473c88f9SBruce Richardson (unsigned long long)opae_readq(feature->addr + 0x8));
1191473c88f9SBruce Richardson
1192473c88f9SBruce Richardson spi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI);
1193473c88f9SBruce Richardson if (!spi_master)
1194473c88f9SBruce Richardson return -ENODEV;
1195e41856b5SWei Huang init_spi_share_data(fme, spi_master);
1196473c88f9SBruce Richardson
1197473c88f9SBruce Richardson /**
1198473c88f9SBruce Richardson * 1. wait A10 NIOS initial finished and
1199473c88f9SBruce Richardson * release the SPI master to Host
1200473c88f9SBruce Richardson */
1201e41856b5SWei Huang if (spi_master->mutex)
1202e41856b5SWei Huang pthread_mutex_lock(spi_master->mutex);
1203e41856b5SWei Huang
1204473c88f9SBruce Richardson ret = nios_spi_wait_init_done(spi_master);
1205473c88f9SBruce Richardson if (ret != 0) {
1206473c88f9SBruce Richardson dev_err(fme, "FME NIOS_SPI init fail\n");
12072414339cSWei Huang if (spi_master->mutex)
12082414339cSWei Huang pthread_mutex_unlock(spi_master->mutex);
1209473c88f9SBruce Richardson goto release_dev;
1210473c88f9SBruce Richardson }
1211473c88f9SBruce Richardson
1212473c88f9SBruce Richardson dev_info(fme, "FME NIOS_SPI initial done\n");
1213473c88f9SBruce Richardson
1214473c88f9SBruce Richardson /* 2. check if error occur? */
1215473c88f9SBruce Richardson if (nios_spi_check_error(spi_master))
1216473c88f9SBruce Richardson dev_info(fme, "NIOS_SPI INIT done, but found some error\n");
1217473c88f9SBruce Richardson
1218e41856b5SWei Huang if (spi_master->mutex)
1219e41856b5SWei Huang pthread_mutex_unlock(spi_master->mutex);
1220e41856b5SWei Huang
1221473c88f9SBruce Richardson /* 3. init the spi master*/
1222473c88f9SBruce Richardson altera_spi_init(spi_master);
1223473c88f9SBruce Richardson
1224ca6eb0f7SWei Huang max10 = opae_zmalloc(sizeof(*max10));
1225ca6eb0f7SWei Huang if (!max10)
1226ca6eb0f7SWei Huang goto release_dev;
1227ca6eb0f7SWei Huang
1228ca6eb0f7SWei Huang max10->spi_master = spi_master;
1229ca6eb0f7SWei Huang max10->type = M10_N3000;
1230ca6eb0f7SWei Huang
1231ca6eb0f7SWei Huang max10->spi_tran_dev = spi_transaction_init(spi_master, 0);
1232ca6eb0f7SWei Huang if (!max10->spi_tran_dev) {
1233ca6eb0f7SWei Huang dev_err(fme, "%s spi tran init fail\n", __func__);
1234ca6eb0f7SWei Huang goto free_max10;
1235ca6eb0f7SWei Huang }
1236ca6eb0f7SWei Huang
1237473c88f9SBruce Richardson /* init the max10 device */
1238ca6eb0f7SWei Huang ret = intel_max10_device_init(max10);
1239ca6eb0f7SWei Huang if (ret) {
1240473c88f9SBruce Richardson ret = -ENODEV;
1241473c88f9SBruce Richardson dev_err(fme, "max10 init fail\n");
1242ca6eb0f7SWei Huang goto release_spi_tran_dev;
1243473c88f9SBruce Richardson }
1244473c88f9SBruce Richardson
1245e41856b5SWei Huang fme->max10_dev = max10;
12464a19f891STianfei Zhang max10->bus = hw->pci_data->bus;
1247473c88f9SBruce Richardson fme_get_board_interface(fme);
12484a19f891STianfei Zhang mgr->sensor_list = &max10->opae_sensor_list;
1249473c88f9SBruce Richardson
1250473c88f9SBruce Richardson /* SPI self test */
12514a19f891STianfei Zhang if (spi_self_checking(max10))
1252473c88f9SBruce Richardson goto spi_fail;
1253473c88f9SBruce Richardson
1254a05bd1b4SWei Huang ret = init_sec_mgr(fme);
1255a05bd1b4SWei Huang if (ret) {
1256a05bd1b4SWei Huang dev_err(fme, "security manager init fail\n");
1257a05bd1b4SWei Huang goto spi_fail;
1258a05bd1b4SWei Huang }
1259a05bd1b4SWei Huang
1260473c88f9SBruce Richardson return ret;
1261473c88f9SBruce Richardson
1262473c88f9SBruce Richardson spi_fail:
1263473c88f9SBruce Richardson intel_max10_device_remove(fme->max10_dev);
1264ca6eb0f7SWei Huang release_spi_tran_dev:
1265ca6eb0f7SWei Huang if (max10->spi_tran_dev)
1266ca6eb0f7SWei Huang spi_transaction_remove(max10->spi_tran_dev);
1267ca6eb0f7SWei Huang free_max10:
1268ca6eb0f7SWei Huang opae_free(max10);
1269473c88f9SBruce Richardson release_dev:
1270473c88f9SBruce Richardson altera_spi_release(spi_master);
1271473c88f9SBruce Richardson return -ENODEV;
1272473c88f9SBruce Richardson }
1273473c88f9SBruce Richardson
fme_nios_spi_uinit(struct ifpga_feature * feature)1274473c88f9SBruce Richardson static void fme_nios_spi_uinit(struct ifpga_feature *feature)
1275473c88f9SBruce Richardson {
1276473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1277473c88f9SBruce Richardson
1278a05bd1b4SWei Huang release_sec_mgr(fme);
1279ca6eb0f7SWei Huang if (fme->max10_dev) {
1280473c88f9SBruce Richardson intel_max10_device_remove(fme->max10_dev);
1281ca6eb0f7SWei Huang opae_free(fme->max10_dev);
1282ca6eb0f7SWei Huang }
1283473c88f9SBruce Richardson }
1284473c88f9SBruce Richardson
1285473c88f9SBruce Richardson struct ifpga_feature_ops fme_nios_spi_master_ops = {
1286473c88f9SBruce Richardson .init = fme_nios_spi_init,
1287473c88f9SBruce Richardson .uinit = fme_nios_spi_uinit,
1288473c88f9SBruce Richardson };
1289473c88f9SBruce Richardson
i2c_mac_rom_test(struct altera_i2c_dev * dev)1290473c88f9SBruce Richardson static int i2c_mac_rom_test(struct altera_i2c_dev *dev)
1291473c88f9SBruce Richardson {
1292473c88f9SBruce Richardson char buf[20];
1293473c88f9SBruce Richardson int ret;
1294473c88f9SBruce Richardson char read_buf[20] = {0,};
1295473c88f9SBruce Richardson const char *string = "1a2b3c4d5e";
1296473c88f9SBruce Richardson
1297473c88f9SBruce Richardson opae_memcpy(buf, string, strlen(string));
1298473c88f9SBruce Richardson
1299473c88f9SBruce Richardson ret = at24_eeprom_write(dev, AT24512_SLAVE_ADDR, 0,
1300473c88f9SBruce Richardson (u8 *)buf, strlen(string));
1301473c88f9SBruce Richardson if (ret < 0) {
1302473c88f9SBruce Richardson dev_err(NULL, "write i2c error:%d\n", ret);
1303473c88f9SBruce Richardson return ret;
1304473c88f9SBruce Richardson }
1305473c88f9SBruce Richardson
1306473c88f9SBruce Richardson ret = at24_eeprom_read(dev, AT24512_SLAVE_ADDR, 0,
1307473c88f9SBruce Richardson (u8 *)read_buf, strlen(string));
1308473c88f9SBruce Richardson if (ret < 0) {
1309473c88f9SBruce Richardson dev_err(NULL, "read i2c error:%d\n", ret);
1310473c88f9SBruce Richardson return ret;
1311473c88f9SBruce Richardson }
1312473c88f9SBruce Richardson
1313473c88f9SBruce Richardson if (memcmp(buf, read_buf, strlen(string))) {
1314ca6eb0f7SWei Huang dev_info(NULL, "%s test fail!\n", __func__);
1315473c88f9SBruce Richardson return -EFAULT;
1316473c88f9SBruce Richardson }
1317473c88f9SBruce Richardson
1318473c88f9SBruce Richardson dev_info(NULL, "%s test successful\n", __func__);
1319473c88f9SBruce Richardson
1320473c88f9SBruce Richardson return 0;
1321473c88f9SBruce Richardson }
1322473c88f9SBruce Richardson
init_i2c_mutex(struct ifpga_fme_hw * fme)1323e41856b5SWei Huang static void init_i2c_mutex(struct ifpga_fme_hw *fme)
1324e41856b5SWei Huang {
1325e41856b5SWei Huang struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent;
1326e41856b5SWei Huang struct altera_i2c_dev *i2c_dev;
1327e41856b5SWei Huang opae_share_data *sd = NULL;
1328e41856b5SWei Huang
1329e41856b5SWei Huang if (fme->i2c_master) {
1330e41856b5SWei Huang i2c_dev = (struct altera_i2c_dev *)fme->i2c_master;
1331e41856b5SWei Huang if (hw && hw->adapter && hw->adapter->shm.ptr) {
1332e41856b5SWei Huang dev_info(NULL, "use multi-process mutex in i2c\n");
1333e41856b5SWei Huang sd = (opae_share_data *)hw->adapter->shm.ptr;
1334e41856b5SWei Huang i2c_dev->mutex = &sd->i2c_mutex;
1335e41856b5SWei Huang } else {
1336e41856b5SWei Huang dev_info(NULL, "use multi-thread mutex in i2c\n");
1337e41856b5SWei Huang i2c_dev->mutex = &i2c_dev->lock;
1338e41856b5SWei Huang }
1339e41856b5SWei Huang }
1340e41856b5SWei Huang }
1341e41856b5SWei Huang
fme_i2c_init(struct ifpga_feature * feature)1342473c88f9SBruce Richardson static int fme_i2c_init(struct ifpga_feature *feature)
1343473c88f9SBruce Richardson {
1344473c88f9SBruce Richardson struct feature_fme_i2c *i2c;
1345473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1346473c88f9SBruce Richardson
1347473c88f9SBruce Richardson i2c = (struct feature_fme_i2c *)feature->addr;
1348473c88f9SBruce Richardson
1349473c88f9SBruce Richardson dev_info(NULL, "FME I2C Master Init.\n");
1350473c88f9SBruce Richardson
1351473c88f9SBruce Richardson fme->i2c_master = altera_i2c_probe(i2c);
1352473c88f9SBruce Richardson if (!fme->i2c_master)
1353473c88f9SBruce Richardson return -ENODEV;
1354473c88f9SBruce Richardson
1355e41856b5SWei Huang init_i2c_mutex(fme);
1356e41856b5SWei Huang
1357473c88f9SBruce Richardson /* MAC ROM self test */
1358473c88f9SBruce Richardson i2c_mac_rom_test(fme->i2c_master);
1359473c88f9SBruce Richardson
1360473c88f9SBruce Richardson return 0;
1361473c88f9SBruce Richardson }
1362473c88f9SBruce Richardson
fme_i2c_uninit(struct ifpga_feature * feature)1363473c88f9SBruce Richardson static void fme_i2c_uninit(struct ifpga_feature *feature)
1364473c88f9SBruce Richardson {
1365473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1366473c88f9SBruce Richardson
1367473c88f9SBruce Richardson altera_i2c_remove(fme->i2c_master);
1368473c88f9SBruce Richardson }
1369473c88f9SBruce Richardson
1370473c88f9SBruce Richardson struct ifpga_feature_ops fme_i2c_master_ops = {
1371473c88f9SBruce Richardson .init = fme_i2c_init,
1372473c88f9SBruce Richardson .uinit = fme_i2c_uninit,
1373473c88f9SBruce Richardson };
1374473c88f9SBruce Richardson
fme_eth_group_init(struct ifpga_feature * feature)1375473c88f9SBruce Richardson static int fme_eth_group_init(struct ifpga_feature *feature)
1376473c88f9SBruce Richardson {
1377473c88f9SBruce Richardson struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1378473c88f9SBruce Richardson struct eth_group_device *dev;
1379473c88f9SBruce Richardson
1380473c88f9SBruce Richardson dev = (struct eth_group_device *)eth_group_probe(feature->addr);
1381473c88f9SBruce Richardson if (!dev)
1382473c88f9SBruce Richardson return -ENODEV;
1383473c88f9SBruce Richardson
1384473c88f9SBruce Richardson fme->eth_dev[dev->group_id] = dev;
1385473c88f9SBruce Richardson
1386473c88f9SBruce Richardson fme->eth_group_region[dev->group_id].addr =
1387473c88f9SBruce Richardson feature->addr;
1388473c88f9SBruce Richardson fme->eth_group_region[dev->group_id].phys_addr =
1389473c88f9SBruce Richardson feature->phys_addr;
1390473c88f9SBruce Richardson fme->eth_group_region[dev->group_id].len =
1391473c88f9SBruce Richardson feature->size;
1392473c88f9SBruce Richardson
1393473c88f9SBruce Richardson fme->nums_eth_dev++;
1394473c88f9SBruce Richardson
1395473c88f9SBruce Richardson dev_info(NULL, "FME PHY Group %d Init.\n", dev->group_id);
1396473c88f9SBruce Richardson dev_info(NULL, "found %d eth group, addr %p phys_addr 0x%llx len %u\n",
1397473c88f9SBruce Richardson dev->group_id, feature->addr,
1398473c88f9SBruce Richardson (unsigned long long)feature->phys_addr,
1399473c88f9SBruce Richardson feature->size);
1400473c88f9SBruce Richardson
1401473c88f9SBruce Richardson return 0;
1402473c88f9SBruce Richardson }
1403473c88f9SBruce Richardson
fme_eth_group_uinit(struct ifpga_feature * feature)1404473c88f9SBruce Richardson static void fme_eth_group_uinit(struct ifpga_feature *feature)
1405473c88f9SBruce Richardson {
1406473c88f9SBruce Richardson UNUSED(feature);
1407473c88f9SBruce Richardson }
1408473c88f9SBruce Richardson
1409473c88f9SBruce Richardson struct ifpga_feature_ops fme_eth_group_ops = {
1410473c88f9SBruce Richardson .init = fme_eth_group_init,
1411473c88f9SBruce Richardson .uinit = fme_eth_group_uinit,
1412473c88f9SBruce Richardson };
1413473c88f9SBruce Richardson
fme_mgr_read_mac_rom(struct ifpga_fme_hw * fme,int offset,void * buf,int size)1414473c88f9SBruce Richardson int fme_mgr_read_mac_rom(struct ifpga_fme_hw *fme, int offset,
1415473c88f9SBruce Richardson void *buf, int size)
1416473c88f9SBruce Richardson {
1417473c88f9SBruce Richardson struct altera_i2c_dev *dev;
1418473c88f9SBruce Richardson
1419473c88f9SBruce Richardson dev = fme->i2c_master;
1420473c88f9SBruce Richardson if (!dev)
1421473c88f9SBruce Richardson return -ENODEV;
1422473c88f9SBruce Richardson
1423473c88f9SBruce Richardson return at24_eeprom_read(dev, AT24512_SLAVE_ADDR, offset, buf, size);
1424473c88f9SBruce Richardson }
1425473c88f9SBruce Richardson
fme_mgr_write_mac_rom(struct ifpga_fme_hw * fme,int offset,void * buf,int size)1426473c88f9SBruce Richardson int fme_mgr_write_mac_rom(struct ifpga_fme_hw *fme, int offset,
1427473c88f9SBruce Richardson void *buf, int size)
1428473c88f9SBruce Richardson {
1429473c88f9SBruce Richardson struct altera_i2c_dev *dev;
1430473c88f9SBruce Richardson
1431473c88f9SBruce Richardson dev = fme->i2c_master;
1432473c88f9SBruce Richardson if (!dev)
1433473c88f9SBruce Richardson return -ENODEV;
1434473c88f9SBruce Richardson
1435473c88f9SBruce Richardson return at24_eeprom_write(dev, AT24512_SLAVE_ADDR, offset, buf, size);
1436473c88f9SBruce Richardson }
1437473c88f9SBruce Richardson
get_eth_group_dev(struct ifpga_fme_hw * fme,u8 group_id)1438473c88f9SBruce Richardson static struct eth_group_device *get_eth_group_dev(struct ifpga_fme_hw *fme,
1439473c88f9SBruce Richardson u8 group_id)
1440473c88f9SBruce Richardson {
1441473c88f9SBruce Richardson struct eth_group_device *dev;
1442473c88f9SBruce Richardson
1443473c88f9SBruce Richardson if (group_id > (MAX_ETH_GROUP_DEVICES - 1))
1444473c88f9SBruce Richardson return NULL;
1445473c88f9SBruce Richardson
1446473c88f9SBruce Richardson dev = (struct eth_group_device *)fme->eth_dev[group_id];
1447473c88f9SBruce Richardson if (!dev)
1448473c88f9SBruce Richardson return NULL;
1449473c88f9SBruce Richardson
1450473c88f9SBruce Richardson if (dev->status != ETH_GROUP_DEV_ATTACHED)
1451473c88f9SBruce Richardson return NULL;
1452473c88f9SBruce Richardson
1453473c88f9SBruce Richardson return dev;
1454473c88f9SBruce Richardson }
1455473c88f9SBruce Richardson
fme_mgr_get_eth_group_nums(struct ifpga_fme_hw * fme)1456473c88f9SBruce Richardson int fme_mgr_get_eth_group_nums(struct ifpga_fme_hw *fme)
1457473c88f9SBruce Richardson {
1458473c88f9SBruce Richardson return fme->nums_eth_dev;
1459473c88f9SBruce Richardson }
1460473c88f9SBruce Richardson
fme_mgr_get_eth_group_info(struct ifpga_fme_hw * fme,u8 group_id,struct opae_eth_group_info * info)1461473c88f9SBruce Richardson int fme_mgr_get_eth_group_info(struct ifpga_fme_hw *fme,
1462473c88f9SBruce Richardson u8 group_id, struct opae_eth_group_info *info)
1463473c88f9SBruce Richardson {
1464473c88f9SBruce Richardson struct eth_group_device *dev;
1465473c88f9SBruce Richardson
1466473c88f9SBruce Richardson dev = get_eth_group_dev(fme, group_id);
1467473c88f9SBruce Richardson if (!dev)
1468473c88f9SBruce Richardson return -ENODEV;
1469473c88f9SBruce Richardson
1470473c88f9SBruce Richardson info->group_id = group_id;
1471473c88f9SBruce Richardson info->speed = dev->speed;
1472473c88f9SBruce Richardson info->nums_of_mac = dev->mac_num;
1473473c88f9SBruce Richardson info->nums_of_phy = dev->phy_num;
1474473c88f9SBruce Richardson
1475473c88f9SBruce Richardson return 0;
1476473c88f9SBruce Richardson }
1477473c88f9SBruce Richardson
fme_mgr_eth_group_read_reg(struct ifpga_fme_hw * fme,u8 group_id,u8 type,u8 index,u16 addr,u32 * data)1478473c88f9SBruce Richardson int fme_mgr_eth_group_read_reg(struct ifpga_fme_hw *fme, u8 group_id,
1479473c88f9SBruce Richardson u8 type, u8 index, u16 addr, u32 *data)
1480473c88f9SBruce Richardson {
1481473c88f9SBruce Richardson struct eth_group_device *dev;
1482473c88f9SBruce Richardson
1483473c88f9SBruce Richardson dev = get_eth_group_dev(fme, group_id);
1484473c88f9SBruce Richardson if (!dev)
1485473c88f9SBruce Richardson return -ENODEV;
1486473c88f9SBruce Richardson
1487473c88f9SBruce Richardson return eth_group_read_reg(dev, type, index, addr, data);
1488473c88f9SBruce Richardson }
1489473c88f9SBruce Richardson
fme_mgr_eth_group_write_reg(struct ifpga_fme_hw * fme,u8 group_id,u8 type,u8 index,u16 addr,u32 data)1490473c88f9SBruce Richardson int fme_mgr_eth_group_write_reg(struct ifpga_fme_hw *fme, u8 group_id,
1491473c88f9SBruce Richardson u8 type, u8 index, u16 addr, u32 data)
1492473c88f9SBruce Richardson {
1493473c88f9SBruce Richardson struct eth_group_device *dev;
1494473c88f9SBruce Richardson
1495473c88f9SBruce Richardson dev = get_eth_group_dev(fme, group_id);
1496473c88f9SBruce Richardson if (!dev)
1497473c88f9SBruce Richardson return -ENODEV;
1498473c88f9SBruce Richardson
1499473c88f9SBruce Richardson return eth_group_write_reg(dev, type, index, addr, data);
1500473c88f9SBruce Richardson }
1501473c88f9SBruce Richardson
fme_get_eth_group_speed(struct ifpga_fme_hw * fme,u8 group_id)1502473c88f9SBruce Richardson static int fme_get_eth_group_speed(struct ifpga_fme_hw *fme,
1503473c88f9SBruce Richardson u8 group_id)
1504473c88f9SBruce Richardson {
1505473c88f9SBruce Richardson struct eth_group_device *dev;
1506473c88f9SBruce Richardson
1507473c88f9SBruce Richardson dev = get_eth_group_dev(fme, group_id);
1508473c88f9SBruce Richardson if (!dev)
1509473c88f9SBruce Richardson return -ENODEV;
1510473c88f9SBruce Richardson
1511473c88f9SBruce Richardson return dev->speed;
1512473c88f9SBruce Richardson }
1513473c88f9SBruce Richardson
fme_mgr_get_retimer_info(struct ifpga_fme_hw * fme,struct opae_retimer_info * info)1514473c88f9SBruce Richardson int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
1515473c88f9SBruce Richardson struct opae_retimer_info *info)
1516473c88f9SBruce Richardson {
1517473c88f9SBruce Richardson struct intel_max10_device *dev;
1518473c88f9SBruce Richardson
1519473c88f9SBruce Richardson dev = (struct intel_max10_device *)fme->max10_dev;
1520473c88f9SBruce Richardson if (!dev)
1521473c88f9SBruce Richardson return -ENODEV;
1522473c88f9SBruce Richardson
1523473c88f9SBruce Richardson info->nums_retimer = fme->board_info.nums_of_retimer;
1524473c88f9SBruce Richardson info->ports_per_retimer = fme->board_info.ports_per_retimer;
1525473c88f9SBruce Richardson info->nums_fvl = fme->board_info.nums_of_fvl;
1526473c88f9SBruce Richardson info->ports_per_fvl = fme->board_info.ports_per_fvl;
1527473c88f9SBruce Richardson
1528473c88f9SBruce Richardson /* The speed of PKVL is identical the eth group's speed */
1529473c88f9SBruce Richardson info->support_speed = fme_get_eth_group_speed(fme,
1530473c88f9SBruce Richardson LINE_SIDE_GROUP_ID);
1531473c88f9SBruce Richardson
1532473c88f9SBruce Richardson return 0;
1533473c88f9SBruce Richardson }
1534473c88f9SBruce Richardson
fme_mgr_get_retimer_status(struct ifpga_fme_hw * fme,struct opae_retimer_status * status)1535473c88f9SBruce Richardson int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
1536473c88f9SBruce Richardson struct opae_retimer_status *status)
1537473c88f9SBruce Richardson {
1538473c88f9SBruce Richardson struct intel_max10_device *dev;
1539473c88f9SBruce Richardson unsigned int val;
1540473c88f9SBruce Richardson
1541473c88f9SBruce Richardson dev = (struct intel_max10_device *)fme->max10_dev;
1542473c88f9SBruce Richardson if (!dev)
1543473c88f9SBruce Richardson return -ENODEV;
1544473c88f9SBruce Richardson
15454a19f891STianfei Zhang if (max10_sys_read(dev, PKVL_LINK_STATUS, &val)) {
1546473c88f9SBruce Richardson dev_err(dev, "%s: read pkvl status fail\n", __func__);
1547473c88f9SBruce Richardson return -EINVAL;
1548473c88f9SBruce Richardson }
1549473c88f9SBruce Richardson
1550473c88f9SBruce Richardson /* The speed of PKVL is identical the eth group's speed */
1551473c88f9SBruce Richardson status->speed = fme_get_eth_group_speed(fme,
1552473c88f9SBruce Richardson LINE_SIDE_GROUP_ID);
1553473c88f9SBruce Richardson
1554473c88f9SBruce Richardson status->line_link_bitmap = val;
1555473c88f9SBruce Richardson
1556473c88f9SBruce Richardson dev_debug(dev, "get retimer status: speed:%d. line_link_bitmap:0x%x\n",
1557473c88f9SBruce Richardson status->speed,
1558473c88f9SBruce Richardson status->line_link_bitmap);
1559473c88f9SBruce Richardson
1560473c88f9SBruce Richardson return 0;
1561473c88f9SBruce Richardson }
156219118989STianfei Zhang
fme_mgr_get_sensor_value(struct ifpga_fme_hw * fme,struct opae_sensor_info * sensor,unsigned int * value)156319118989STianfei Zhang int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
156419118989STianfei Zhang struct opae_sensor_info *sensor,
156519118989STianfei Zhang unsigned int *value)
156619118989STianfei Zhang {
156719118989STianfei Zhang struct intel_max10_device *dev;
156819118989STianfei Zhang
156919118989STianfei Zhang dev = (struct intel_max10_device *)fme->max10_dev;
157019118989STianfei Zhang if (!dev)
157119118989STianfei Zhang return -ENODEV;
157219118989STianfei Zhang
15734a19f891STianfei Zhang if (max10_sys_read(dev, sensor->value_reg, value)) {
157419118989STianfei Zhang dev_err(dev, "%s: read sensor value register 0x%x fail\n",
157519118989STianfei Zhang __func__, sensor->value_reg);
157619118989STianfei Zhang return -EINVAL;
157719118989STianfei Zhang }
157819118989STianfei Zhang
157919118989STianfei Zhang *value *= sensor->multiplier;
158019118989STianfei Zhang
158119118989STianfei Zhang return 0;
158219118989STianfei Zhang }
1583ca6eb0f7SWei Huang
fme_pmci_init(struct ifpga_feature * feature)1584ca6eb0f7SWei Huang static int fme_pmci_init(struct ifpga_feature *feature)
1585ca6eb0f7SWei Huang {
1586ca6eb0f7SWei Huang struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1587ca6eb0f7SWei Huang struct intel_max10_device *max10;
1588ca6eb0f7SWei Huang struct ifpga_hw *hw;
1589ca6eb0f7SWei Huang struct opae_manager *mgr;
1590ca6eb0f7SWei Huang opae_share_data *sd = NULL;
1591ca6eb0f7SWei Huang int ret = 0;
1592ca6eb0f7SWei Huang
1593ca6eb0f7SWei Huang hw = fme->parent;
1594*b6e029cfSWei Huang if (!hw || !hw->adapter)
1595ca6eb0f7SWei Huang return -ENODEV;
1596ca6eb0f7SWei Huang
1597ca6eb0f7SWei Huang mgr = hw->adapter->mgr;
1598ca6eb0f7SWei Huang if (!mgr)
1599ca6eb0f7SWei Huang return -ENODEV;
1600ca6eb0f7SWei Huang
1601ca6eb0f7SWei Huang dev_info(fme, "FME PMCI Init.\n");
1602ca6eb0f7SWei Huang dev_debug(fme, "FME PMCI base addr %p.\n",
1603ca6eb0f7SWei Huang feature->addr);
1604ca6eb0f7SWei Huang
1605ca6eb0f7SWei Huang max10 = opae_zmalloc(sizeof(*max10));
1606ca6eb0f7SWei Huang if (!max10)
1607ca6eb0f7SWei Huang return -ENOMEM;
1608ca6eb0f7SWei Huang
1609ca6eb0f7SWei Huang max10->type = M10_N6000;
1610ca6eb0f7SWei Huang max10->mmio = feature->addr;
1611*b6e029cfSWei Huang if (hw->adapter->shm.ptr) {
1612ca6eb0f7SWei Huang sd = (opae_share_data *)hw->adapter->shm.ptr;
1613ca6eb0f7SWei Huang max10->bmc_ops.mutex = &sd->spi_mutex;
1614ca6eb0f7SWei Huang } else {
1615ca6eb0f7SWei Huang max10->bmc_ops.mutex = NULL;
1616ca6eb0f7SWei Huang }
1617ca6eb0f7SWei Huang
1618ca6eb0f7SWei Huang /* init the max10 device */
1619ca6eb0f7SWei Huang ret = intel_max10_device_init(max10);
1620ca6eb0f7SWei Huang if (ret) {
1621ca6eb0f7SWei Huang dev_err(fme, "max10 init fail\n");
1622ca6eb0f7SWei Huang goto free_max10;
1623ca6eb0f7SWei Huang }
1624ca6eb0f7SWei Huang
1625ca6eb0f7SWei Huang fme->max10_dev = max10;
1626ca6eb0f7SWei Huang max10->bus = hw->pci_data->bus;
1627ca6eb0f7SWei Huang fme_get_board_interface(fme);
1628ca6eb0f7SWei Huang mgr->sensor_list = &max10->opae_sensor_list;
1629ca6eb0f7SWei Huang
1630ca6eb0f7SWei Huang ret = init_sec_mgr(fme);
1631ca6eb0f7SWei Huang if (ret) {
1632ca6eb0f7SWei Huang dev_err(fme, "security manager init fail\n");
1633ca6eb0f7SWei Huang goto release_max10;
1634ca6eb0f7SWei Huang }
1635ca6eb0f7SWei Huang
1636ca6eb0f7SWei Huang return ret;
1637ca6eb0f7SWei Huang
1638ca6eb0f7SWei Huang release_max10:
1639ca6eb0f7SWei Huang intel_max10_device_remove(max10);
1640ca6eb0f7SWei Huang free_max10:
1641ca6eb0f7SWei Huang opae_free(max10);
1642ca6eb0f7SWei Huang
1643ca6eb0f7SWei Huang return ret;
1644ca6eb0f7SWei Huang }
1645ca6eb0f7SWei Huang
fme_pmci_uinit(struct ifpga_feature * feature)1646ca6eb0f7SWei Huang static void fme_pmci_uinit(struct ifpga_feature *feature)
1647ca6eb0f7SWei Huang {
1648ca6eb0f7SWei Huang struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent;
1649ca6eb0f7SWei Huang
1650ca6eb0f7SWei Huang release_sec_mgr(fme);
1651ca6eb0f7SWei Huang if (fme->max10_dev) {
1652ca6eb0f7SWei Huang intel_max10_device_remove(fme->max10_dev);
1653ca6eb0f7SWei Huang opae_free(fme->max10_dev);
1654ca6eb0f7SWei Huang }
1655ca6eb0f7SWei Huang }
1656ca6eb0f7SWei Huang
1657ca6eb0f7SWei Huang struct ifpga_feature_ops fme_pmci_ops = {
1658ca6eb0f7SWei Huang .init = fme_pmci_init,
1659ca6eb0f7SWei Huang .uinit = fme_pmci_uinit,
1660ca6eb0f7SWei Huang };
1661b74ee6c8SWei Huang
fme_mgr_read_flash(struct ifpga_fme_hw * fme,u32 address,u32 size,void * buf)1662b74ee6c8SWei Huang int fme_mgr_read_flash(struct ifpga_fme_hw *fme, u32 address,
1663b74ee6c8SWei Huang u32 size, void *buf)
1664b74ee6c8SWei Huang {
1665b74ee6c8SWei Huang struct intel_max10_device *max10 = fme->max10_dev;
1666b74ee6c8SWei Huang
1667b74ee6c8SWei Huang return opae_read_flash(max10, address, size, buf);
1668b74ee6c8SWei Huang }
1669