raw/ifpga/base: support multiple cards
[dpdk.git] / drivers / raw / ifpga / base / opae_intel_max10.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2019 Intel Corporation
3  */
4
5 #include "opae_intel_max10.h"
6 #include <libfdt.h>
7
8 int max10_reg_read(struct intel_max10_device *dev,
9         unsigned int reg, unsigned int *val)
10 {
11         if (!dev)
12                 return -ENODEV;
13
14         dev_debug(dev, "%s: bus:0x%x, reg:0x%x\n", __func__, dev->bus, reg);
15
16         return spi_transaction_read(dev->spi_tran_dev,
17                         reg, 4, (unsigned char *)val);
18 }
19
20 int max10_reg_write(struct intel_max10_device *dev,
21         unsigned int reg, unsigned int val)
22 {
23         unsigned int tmp = val;
24
25         if (!dev)
26                 return -ENODEV;
27
28         dev_debug(dev, "%s: bus:0x%x, reg:0x%x, val:0x%x\n", __func__,
29                         dev->bus, reg, val);
30
31         return spi_transaction_write(dev->spi_tran_dev,
32                         reg, 4, (unsigned char *)&tmp);
33 }
34
35 int max10_sys_read(struct intel_max10_device *dev,
36         unsigned int offset, unsigned int *val)
37 {
38         if (!dev)
39                 return -ENODEV;
40
41
42         return max10_reg_read(dev, dev->base + offset, val);
43 }
44
45 int max10_sys_write(struct intel_max10_device *dev,
46         unsigned int offset, unsigned int val)
47 {
48         if (!dev)
49                 return -ENODEV;
50
51         return max10_reg_write(dev, dev->base + offset, val);
52 }
53
54 static struct max10_compatible_id max10_id_table[] = {
55         {.compatible = MAX10_PAC,},
56         {.compatible = MAX10_PAC_N3000,},
57         {.compatible = MAX10_PAC_END,}
58 };
59
60 static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
61 {
62         struct max10_compatible_id *id = max10_id_table;
63
64         for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
65                 if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
66                         continue;
67
68                 return id;
69         }
70
71         return NULL;
72 }
73
74 static inline bool
75 is_max10_pac_n3000(struct intel_max10_device *max10)
76 {
77         return max10->id && !strcmp(max10->id->compatible,
78                         MAX10_PAC_N3000);
79 }
80
81 static void max10_check_capability(struct intel_max10_device *max10)
82 {
83         if (!max10->fdt_root)
84                 return;
85
86         if (is_max10_pac_n3000(max10)) {
87                 max10->flags |= MAX10_FLAGS_NO_I2C2 |
88                                 MAX10_FLAGS_NO_BMCIMG_FLASH;
89                 dev_info(max10, "found %s card\n", max10->id->compatible);
90         } else
91                 max10->flags |= MAX10_FLAGS_MAC_CACHE;
92 }
93
94 static int altera_nor_flash_read(struct intel_max10_device *dev,
95         u32 offset, void *buffer, u32 len)
96 {
97         int word_len;
98         int i;
99         unsigned int *buf = (unsigned int *)buffer;
100         unsigned int value;
101         int ret;
102
103         if (!dev || !buffer || len <= 0)
104                 return -ENODEV;
105
106         word_len = len/4;
107
108         for (i = 0; i < word_len; i++) {
109                 ret = max10_reg_read(dev, offset + i*4,
110                                 &value);
111                 if (ret)
112                         return -EBUSY;
113
114                 *buf++ = value;
115         }
116
117         return 0;
118 }
119
120 static int enable_nor_flash(struct intel_max10_device *dev, bool on)
121 {
122         unsigned int val = 0;
123         int ret;
124
125         ret = max10_sys_read(dev, RSU_REG, &val);
126         if (ret) {
127                 dev_err(NULL "enabling flash error\n");
128                 return ret;
129         }
130
131         if (on)
132                 val |= RSU_ENABLE;
133         else
134                 val &= ~RSU_ENABLE;
135
136         return max10_sys_write(dev, RSU_REG, val);
137 }
138
139 static int init_max10_device_table(struct intel_max10_device *max10)
140 {
141         struct max10_compatible_id *id;
142         struct fdt_header hdr;
143         char *fdt_root = NULL;
144
145         u32 dt_size, dt_addr, val;
146         int ret;
147
148         ret = max10_sys_read(max10, DT_AVAIL_REG, &val);
149         if (ret) {
150                 dev_err(max10 "cannot read DT_AVAIL_REG\n");
151                 return ret;
152         }
153
154         if (!(val & DT_AVAIL)) {
155                 dev_err(max10 "DT not available\n");
156                 return -EINVAL;
157         }
158
159         ret = max10_sys_read(max10, DT_BASE_ADDR_REG, &dt_addr);
160         if (ret) {
161                 dev_info(max10 "cannot get base addr of device table\n");
162                 return ret;
163         }
164
165         ret = enable_nor_flash(max10, true);
166         if (ret) {
167                 dev_err(max10 "fail to enable flash\n");
168                 return ret;
169         }
170
171         ret = altera_nor_flash_read(max10, dt_addr, &hdr, sizeof(hdr));
172         if (ret) {
173                 dev_err(max10 "read fdt header fail\n");
174                 goto done;
175         }
176
177         ret = fdt_check_header(&hdr);
178         if (ret) {
179                 dev_err(max10 "check fdt header fail\n");
180                 goto done;
181         }
182
183         dt_size = fdt_totalsize(&hdr);
184         if (dt_size > DFT_MAX_SIZE) {
185                 dev_err(max10 "invalid device table size\n");
186                 ret = -EINVAL;
187                 goto done;
188         }
189
190         fdt_root = opae_malloc(dt_size);
191         if (!fdt_root) {
192                 ret = -ENOMEM;
193                 goto done;
194         }
195
196         ret = altera_nor_flash_read(max10, dt_addr, fdt_root, dt_size);
197         if (ret) {
198                 dev_err(max10 "cannot read device table\n");
199                 goto done;
200         }
201
202         id = max10_match_compatible(fdt_root);
203         if (!id) {
204                 dev_err(max10 "max10 compatible not found\n");
205                 ret = -ENODEV;
206                 goto done;
207         }
208
209         max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
210
211         max10->id = id;
212         max10->fdt_root = fdt_root;
213
214 done:
215         ret = enable_nor_flash(max10, false);
216
217         if (ret && fdt_root)
218                 opae_free(fdt_root);
219
220         return ret;
221 }
222
223 static u64 fdt_get_number(const fdt32_t *cell, int size)
224 {
225         u64 r = 0;
226
227         while (size--)
228                 r = (r << 32) | fdt32_to_cpu(*cell++);
229
230         return r;
231 }
232
233 static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
234                 u64 *start, u64 *size)
235 {
236         const fdt32_t *prop, *end;
237         int na = 0, ns = 0, len = 0, parent;
238
239         parent = fdt_parent_offset(fdt, node);
240         if (parent < 0)
241                 return parent;
242
243         prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
244         na = prop ? fdt32_to_cpu(*prop) : 2;
245
246         prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
247         ns = prop ? fdt32_to_cpu(*prop) : 2;
248
249         prop = fdt_getprop(fdt, node, "reg", &len);
250         if (!prop)
251                 return -FDT_ERR_NOTFOUND;
252
253         end = prop + len/sizeof(*prop);
254         prop = prop + (na + ns) * idx;
255
256         if (prop + na + ns > end)
257                 return -FDT_ERR_NOTFOUND;
258
259         *start = fdt_get_number(prop, na);
260         *size = fdt_get_number(prop + na, ns);
261
262         return 0;
263 }
264
265 static int __fdt_stringlist_search(const void *fdt, int offset,
266                 const char *prop, const char *string)
267 {
268         int length, len, index = 0;
269         const char *list, *end;
270
271         list = fdt_getprop(fdt, offset, prop, &length);
272         if (!list)
273                 return length;
274
275         len = strlen(string) + 1;
276         end = list + length;
277
278         while (list < end) {
279                 length = strnlen(list, end - list) + 1;
280
281                 if (list + length > end)
282                         return -FDT_ERR_BADVALUE;
283
284                 if (length == len && memcmp(list, string, length) == 0)
285                         return index;
286
287                 list += length;
288                 index++;
289         }
290
291         return -FDT_ERR_NOTFOUND;
292 }
293
294 static int fdt_get_named_reg(const void *fdt, int node, const char *name,
295                 u64 *start, u64 *size)
296 {
297         int idx;
298
299         idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
300         if (idx < 0)
301                 return idx;
302
303         return fdt_get_reg(fdt, node, idx, start, size);
304 }
305
306 static void max10_sensor_uinit(struct intel_max10_device *dev)
307 {
308         struct opae_sensor_info *info;
309
310         TAILQ_FOREACH(info, &dev->opae_sensor_list, node) {
311                 TAILQ_REMOVE(&dev->opae_sensor_list, info, node);
312                 opae_free(info);
313         }
314 }
315
316 static bool sensor_reg_valid(struct sensor_reg *reg)
317 {
318         return !!reg->size;
319 }
320
321 static int max10_add_sensor(struct intel_max10_device *dev,
322         struct raw_sensor_info *info, struct opae_sensor_info *sensor)
323 {
324         int i;
325         int ret = 0;
326         unsigned int val;
327
328         if (!info || !sensor)
329                 return -ENODEV;
330
331         sensor->id = info->id;
332         sensor->name = info->name;
333         sensor->type = info->type;
334         sensor->multiplier = info->multiplier;
335
336         for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
337                 if (!sensor_reg_valid(&info->regs[i]))
338                         continue;
339
340                 ret = max10_sys_read(dev, info->regs[i].regoff, &val);
341                 if (ret)
342                         break;
343
344                 if (val == 0xdeadbeef) {
345                         dev_debug(dev, "%s: sensor:%s invalid 0x%x at:%d\n",
346                                 __func__, sensor->name, val, i);
347                         continue;
348                 }
349
350                 val *= info->multiplier;
351
352                 switch (i) {
353                 case SENSOR_REG_VALUE:
354                         sensor->value_reg = info->regs[i].regoff;
355                         sensor->flags |= OPAE_SENSOR_VALID;
356                         break;
357                 case SENSOR_REG_HIGH_WARN:
358                         sensor->high_warn = val;
359                         sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
360                         break;
361                 case SENSOR_REG_HIGH_FATAL:
362                         sensor->high_fatal = val;
363                         sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
364                         break;
365                 case SENSOR_REG_LOW_WARN:
366                         sensor->low_warn = val;
367                         sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
368                         break;
369                 case SENSOR_REG_LOW_FATAL:
370                         sensor->low_fatal = val;
371                         sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
372                         break;
373                 case SENSOR_REG_HYSTERESIS:
374                         sensor->hysteresis = val;
375                         sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
376                         break;
377                 }
378         }
379
380         return ret;
381 }
382
383 static int
384 max10_sensor_init(struct intel_max10_device *dev, int parent)
385 {
386         int i, ret = 0, offset = 0;
387         const fdt32_t *num;
388         const char *ptr;
389         u64 start, size;
390         struct raw_sensor_info *raw;
391         struct opae_sensor_info *sensor;
392         char *fdt_root = dev->fdt_root;
393
394         if (!fdt_root) {
395                 dev_debug(dev, "skip sensor init as not find Device Tree\n");
396                 return 0;
397         }
398
399         fdt_for_each_subnode(offset, fdt_root, parent) {
400                 ptr = fdt_get_name(fdt_root, offset, NULL);
401                 if (!ptr) {
402                         dev_err(dev, "failed to fdt get name\n");
403                         continue;
404                 }
405
406                 if (!strstr(ptr, "sensor")) {
407                         dev_debug(dev, "%s is not a sensor node\n", ptr);
408                         continue;
409                 }
410
411                 dev_debug(dev, "found sensor node %s\n", ptr);
412
413                 raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
414                 if (!raw) {
415                         ret = -ENOMEM;
416                         goto free_sensor;
417                 }
418
419                 raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
420                 if (!raw->name) {
421                         ret = -EINVAL;
422                         goto free_sensor;
423                 }
424
425                 raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
426                 if (!raw->type) {
427                         ret = -EINVAL;
428                         goto free_sensor;
429                 }
430
431                 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
432                         ret = fdt_get_named_reg(fdt_root, offset,
433                                         sensor_reg_name[i], &start,
434                                         &size);
435                         if (ret) {
436                                 dev_debug(dev, "no found %d: sensor node %s, %s\n",
437                                                 ret, ptr, sensor_reg_name[i]);
438                                 if (i == SENSOR_REG_VALUE) {
439                                         ret = -EINVAL;
440                                         goto free_sensor;
441                                 }
442
443                                 continue;
444                         }
445
446                         /* This is a hack to compatible with non-secure
447                          * solution. If sensors are included in root node,
448                          * then it's non-secure dtb, which use absolute addr
449                          * of non-secure solution.
450                          */
451                         if (parent)
452                                 raw->regs[i].regoff = start;
453                         else
454                                 raw->regs[i].regoff = start -
455                                         MAX10_BASE_ADDR;
456                         raw->regs[i].size = size;
457                 }
458
459                 num = fdt_getprop(fdt_root, offset, "id", NULL);
460                 if (!num) {
461                         ret = -EINVAL;
462                         goto free_sensor;
463                 }
464
465                 raw->id = fdt32_to_cpu(*num);
466                 num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
467                 raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
468
469                 dev_debug(dev, "found sensor from DTB: %s: %s: %u: %u\n",
470                                 raw->name, raw->type,
471                                 raw->id, raw->multiplier);
472
473                 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
474                         dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
475                                         i, raw->regs[i].regoff,
476                                         raw->regs[i].size);
477
478                 sensor = opae_zmalloc(sizeof(*sensor));
479                 if (!sensor) {
480                         ret = -EINVAL;
481                         goto free_sensor;
482                 }
483
484                 if (max10_add_sensor(dev, raw, sensor)) {
485                         ret = -EINVAL;
486                         opae_free(sensor);
487                         goto free_sensor;
488                 }
489
490                 if (sensor->flags & OPAE_SENSOR_VALID) {
491                         TAILQ_INSERT_TAIL(&dev->opae_sensor_list, sensor, node);
492                         dev_info(dev, "found valid sensor: %s\n", sensor->name);
493                 } else
494                         opae_free(sensor);
495
496                 opae_free(raw);
497         }
498
499         return 0;
500
501 free_sensor:
502         if (raw)
503                 opae_free(raw);
504         max10_sensor_uinit(dev);
505         return ret;
506 }
507
508 static int check_max10_version(struct intel_max10_device *dev)
509 {
510         unsigned int v;
511
512         if (!max10_reg_read(dev, MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
513                                 &v)) {
514                 if (v != 0xffffffff) {
515                         dev_info(dev, "secure MAX10 detected\n");
516                         dev->base = MAX10_SEC_BASE_ADDR;
517                         dev->flags |= MAX10_FLAGS_SECURE;
518                 } else {
519                         dev_info(dev, "non-secure MAX10 detected\n");
520                         dev->base = MAX10_BASE_ADDR;
521                 }
522                 return 0;
523         }
524
525         return -ENODEV;
526 }
527
528 static int
529 max10_secure_hw_init(struct intel_max10_device *dev)
530 {
531         int offset, sysmgr_offset = 0;
532         char *fdt_root;
533
534         fdt_root = dev->fdt_root;
535         if (!fdt_root) {
536                 dev_debug(dev, "skip init as not find Device Tree\n");
537                 return 0;
538         }
539
540         fdt_for_each_subnode(offset, fdt_root, 0) {
541                 if (!fdt_node_check_compatible(fdt_root, offset,
542                                         "intel-max10,system-manager")) {
543                         sysmgr_offset = offset;
544                         break;
545                 }
546         }
547
548         max10_check_capability(dev);
549
550         max10_sensor_init(dev, sysmgr_offset);
551
552         return 0;
553 }
554
555 static int
556 max10_non_secure_hw_init(struct intel_max10_device *dev)
557 {
558         max10_check_capability(dev);
559
560         max10_sensor_init(dev, 0);
561
562         return 0;
563 }
564
565 struct intel_max10_device *
566 intel_max10_device_probe(struct altera_spi_device *spi,
567                 int chipselect)
568 {
569         struct intel_max10_device *dev;
570         int ret;
571         unsigned int val;
572
573         dev = opae_malloc(sizeof(*dev));
574         if (!dev)
575                 return NULL;
576
577         TAILQ_INIT(&dev->opae_sensor_list);
578
579         dev->spi_master = spi;
580
581         dev->spi_tran_dev = spi_transaction_init(spi, chipselect);
582         if (!dev->spi_tran_dev) {
583                 dev_err(dev, "%s spi tran init fail\n", __func__);
584                 goto free_dev;
585         }
586
587         /* check the max10 version */
588         ret = check_max10_version(dev);
589         if (ret) {
590                 dev_err(dev, "Failed to find max10 hardware!\n");
591                 goto free_dev;
592         }
593
594         /* load the MAX10 device table */
595         ret = init_max10_device_table(dev);
596         if (ret) {
597                 dev_err(dev, "Init max10 device table fail\n");
598                 goto free_dev;
599         }
600
601         /* init max10 devices, like sensor*/
602         if (dev->flags & MAX10_FLAGS_SECURE)
603                 ret = max10_secure_hw_init(dev);
604         else
605                 ret = max10_non_secure_hw_init(dev);
606         if (ret) {
607                 dev_err(dev, "Failed to init max10 hardware!\n");
608                 goto free_dtb;
609         }
610
611         /* read FPGA loading information */
612         ret = max10_sys_read(dev, FPGA_PAGE_INFO, &val);
613         if (ret) {
614                 dev_err(dev, "fail to get FPGA loading info\n");
615                 goto release_max10_hw;
616         }
617         dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
618
619         return dev;
620
621 release_max10_hw:
622         max10_sensor_uinit(dev);
623 free_dtb:
624         if (dev->fdt_root)
625                 opae_free(dev->fdt_root);
626         if (dev->spi_tran_dev)
627                 spi_transaction_remove(dev->spi_tran_dev);
628 free_dev:
629         opae_free(dev);
630
631         return NULL;
632 }
633
634 int intel_max10_device_remove(struct intel_max10_device *dev)
635 {
636         if (!dev)
637                 return 0;
638
639         max10_sensor_uinit(dev);
640
641         if (dev->spi_tran_dev)
642                 spi_transaction_remove(dev->spi_tran_dev);
643
644         if (dev->fdt_root)
645                 opae_free(dev->fdt_root);
646
647         opae_free(dev);
648
649         return 0;
650 }