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
max10_reg_read(struct intel_max10_device * dev,unsigned int reg,unsigned int * val)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
max10_reg_write(struct intel_max10_device * dev,unsigned int reg,unsigned int val)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
max10_sys_read(struct intel_max10_device * dev,unsigned int offset,unsigned int * val)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
max10_sys_write(struct intel_max10_device * dev,unsigned int offset,unsigned int val)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
max10_match_compatible(const char * fdt_root)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
is_max10_pac_n3000(struct intel_max10_device * max10)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
max10_check_capability(struct intel_max10_device * max10)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
altera_nor_flash_read(struct intel_max10_device * dev,u32 offset,void * buffer,u32 len)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
enable_nor_flash(struct intel_max10_device * dev,bool on)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
init_max10_device_table(struct intel_max10_device * max10)139 static int init_max10_device_table(struct intel_max10_device *max10)
140 {
141 struct altera_spi_device *spi = NULL;
142 struct max10_compatible_id *id;
143 struct fdt_header hdr;
144 char *fdt_root = NULL;
145 u32 dtb_magic = 0;
146 u32 dt_size, dt_addr, val;
147 int ret = 0;
148
149 spi = (struct altera_spi_device *)max10->spi_master;
150 if (!spi) {
151 dev_err(max10, "spi master is not set\n");
152 return -EINVAL;
153 }
154 if (spi->dtb)
155 dtb_magic = *(u32 *)spi->dtb;
156
157 if (dtb_magic != 0xEDFE0DD0) {
158 dev_info(max10, "read DTB from NOR flash\n");
159 ret = max10_sys_read(max10, DT_AVAIL_REG, &val);
160 if (ret) {
161 dev_err(max10 "cannot read DT_AVAIL_REG\n");
162 return ret;
163 }
164
165 if (!(val & DT_AVAIL)) {
166 dev_err(max10 "DT not available\n");
167 return -EINVAL;
168 }
169
170 ret = max10_sys_read(max10, DT_BASE_ADDR_REG, &dt_addr);
171 if (ret) {
172 dev_info(max10 "cannot get base addr of device table\n");
173 return ret;
174 }
175
176 ret = enable_nor_flash(max10, true);
177 if (ret) {
178 dev_err(max10 "fail to enable flash\n");
179 return ret;
180 }
181
182 ret = altera_nor_flash_read(max10, dt_addr, &hdr, sizeof(hdr));
183 if (ret) {
184 dev_err(max10 "read fdt header fail\n");
185 goto disable_nor_flash;
186 }
187
188 ret = fdt_check_header(&hdr);
189 if (ret) {
190 dev_err(max10 "check fdt header fail\n");
191 goto disable_nor_flash;
192 }
193
194 dt_size = fdt_totalsize(&hdr);
195 if (dt_size > DFT_MAX_SIZE) {
196 dev_err(max10 "invalid device table size\n");
197 ret = -EINVAL;
198 goto disable_nor_flash;
199 }
200
201 fdt_root = opae_malloc(dt_size);
202 if (!fdt_root) {
203 ret = -ENOMEM;
204 goto disable_nor_flash;
205 }
206
207 ret = altera_nor_flash_read(max10, dt_addr, fdt_root, dt_size);
208 if (ret) {
209 opae_free(fdt_root);
210 fdt_root = NULL;
211 dev_err(max10 "cannot read device table\n");
212 goto disable_nor_flash;
213 }
214
215 if (spi->dtb) {
216 if (*spi->dtb_sz_ptr < dt_size) {
217 dev_warn(max10,
218 "share memory for dtb is smaller than required %u\n",
219 dt_size);
220 } else {
221 *spi->dtb_sz_ptr = dt_size;
222 }
223 /* store dtb data into share memory */
224 memcpy(spi->dtb, fdt_root, *spi->dtb_sz_ptr);
225 }
226
227 disable_nor_flash:
228 enable_nor_flash(max10, false);
229 } else {
230 if (*spi->dtb_sz_ptr > 0) {
231 dev_info(max10, "read DTB from shared memory\n");
232 fdt_root = opae_malloc(*spi->dtb_sz_ptr);
233 if (fdt_root)
234 memcpy(fdt_root, spi->dtb, *spi->dtb_sz_ptr);
235 else
236 ret = -ENOMEM;
237 }
238 }
239
240 if (fdt_root) {
241 id = max10_match_compatible(fdt_root);
242 if (!id) {
243 dev_err(max10 "max10 compatible not found\n");
244 ret = -ENODEV;
245 } else {
246 max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
247 max10->id = id;
248 max10->fdt_root = fdt_root;
249 }
250 }
251
252 return ret;
253 }
254
fdt_get_number(const fdt32_t * cell,int size)255 static u64 fdt_get_number(const fdt32_t *cell, int size)
256 {
257 u64 r = 0;
258
259 while (size--)
260 r = (r << 32) | fdt32_to_cpu(*cell++);
261
262 return r;
263 }
264
fdt_get_reg(const void * fdt,int node,unsigned int idx,u64 * start,u64 * size)265 static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
266 u64 *start, u64 *size)
267 {
268 const fdt32_t *prop, *end;
269 int na = 0, ns = 0, len = 0, parent;
270
271 parent = fdt_parent_offset(fdt, node);
272 if (parent < 0)
273 return parent;
274
275 prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
276 na = prop ? fdt32_to_cpu(*prop) : 2;
277
278 prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
279 ns = prop ? fdt32_to_cpu(*prop) : 2;
280
281 prop = fdt_getprop(fdt, node, "reg", &len);
282 if (!prop)
283 return -FDT_ERR_NOTFOUND;
284
285 end = prop + len/sizeof(*prop);
286 prop = prop + (na + ns) * idx;
287
288 if (prop + na + ns > end)
289 return -FDT_ERR_NOTFOUND;
290
291 *start = fdt_get_number(prop, na);
292 *size = fdt_get_number(prop + na, ns);
293
294 return 0;
295 }
296
__fdt_stringlist_search(const void * fdt,int offset,const char * prop,const char * string)297 static int __fdt_stringlist_search(const void *fdt, int offset,
298 const char *prop, const char *string)
299 {
300 int length, len, index = 0;
301 const char *list, *end;
302
303 list = fdt_getprop(fdt, offset, prop, &length);
304 if (!list)
305 return length;
306
307 len = strlen(string) + 1;
308 end = list + length;
309
310 while (list < end) {
311 length = strnlen(list, end - list) + 1;
312
313 if (list + length > end)
314 return -FDT_ERR_BADVALUE;
315
316 if (length == len && memcmp(list, string, length) == 0)
317 return index;
318
319 list += length;
320 index++;
321 }
322
323 return -FDT_ERR_NOTFOUND;
324 }
325
fdt_get_named_reg(const void * fdt,int node,const char * name,u64 * start,u64 * size)326 static int fdt_get_named_reg(const void *fdt, int node, const char *name,
327 u64 *start, u64 *size)
328 {
329 int idx;
330
331 idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
332 if (idx < 0)
333 return idx;
334
335 return fdt_get_reg(fdt, node, idx, start, size);
336 }
337
max10_sensor_uinit(struct intel_max10_device * dev)338 static void max10_sensor_uinit(struct intel_max10_device *dev)
339 {
340 struct opae_sensor_info *info;
341
342 TAILQ_FOREACH(info, &dev->opae_sensor_list, node) {
343 TAILQ_REMOVE(&dev->opae_sensor_list, info, node);
344 opae_free(info);
345 }
346 }
347
sensor_reg_valid(struct sensor_reg * reg)348 static bool sensor_reg_valid(struct sensor_reg *reg)
349 {
350 return !!reg->size;
351 }
352
max10_add_sensor(struct intel_max10_device * dev,struct raw_sensor_info * info,struct opae_sensor_info * sensor)353 static int max10_add_sensor(struct intel_max10_device *dev,
354 struct raw_sensor_info *info, struct opae_sensor_info *sensor)
355 {
356 int i;
357 int ret = 0;
358 unsigned int val;
359
360 if (!info || !sensor)
361 return -ENODEV;
362
363 sensor->id = info->id;
364 sensor->name = info->name;
365 sensor->type = info->type;
366 sensor->multiplier = info->multiplier;
367
368 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
369 if (!sensor_reg_valid(&info->regs[i]))
370 continue;
371
372 ret = max10_sys_read(dev, info->regs[i].regoff, &val);
373 if (ret)
374 break;
375
376 if (val == 0xdeadbeef) {
377 dev_debug(dev, "%s: sensor:%s invalid 0x%x at:%d\n",
378 __func__, sensor->name, val, i);
379 continue;
380 }
381
382 val *= info->multiplier;
383
384 switch (i) {
385 case SENSOR_REG_VALUE:
386 sensor->value_reg = info->regs[i].regoff;
387 sensor->flags |= OPAE_SENSOR_VALID;
388 break;
389 case SENSOR_REG_HIGH_WARN:
390 sensor->high_warn = val;
391 sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
392 break;
393 case SENSOR_REG_HIGH_FATAL:
394 sensor->high_fatal = val;
395 sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
396 break;
397 case SENSOR_REG_LOW_WARN:
398 sensor->low_warn = val;
399 sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
400 break;
401 case SENSOR_REG_LOW_FATAL:
402 sensor->low_fatal = val;
403 sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
404 break;
405 case SENSOR_REG_HYSTERESIS:
406 sensor->hysteresis = val;
407 sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
408 break;
409 }
410 }
411
412 return ret;
413 }
414
415 static int
max10_sensor_init(struct intel_max10_device * dev,int parent)416 max10_sensor_init(struct intel_max10_device *dev, int parent)
417 {
418 int i, ret = 0, offset = 0;
419 const fdt32_t *num;
420 const char *ptr;
421 u64 start, size;
422 struct raw_sensor_info *raw;
423 struct opae_sensor_info *sensor;
424 char *fdt_root = dev->fdt_root;
425
426 if (!fdt_root) {
427 dev_debug(dev, "skip sensor init as not find Device Tree\n");
428 return 0;
429 }
430
431 fdt_for_each_subnode(offset, fdt_root, parent) {
432 ptr = fdt_get_name(fdt_root, offset, NULL);
433 if (!ptr) {
434 dev_err(dev, "failed to fdt get name\n");
435 continue;
436 }
437
438 if (!strstr(ptr, "sensor")) {
439 dev_debug(dev, "%s is not a sensor node\n", ptr);
440 continue;
441 }
442
443 dev_debug(dev, "found sensor node %s\n", ptr);
444
445 raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
446 if (!raw) {
447 ret = -ENOMEM;
448 goto free_sensor;
449 }
450
451 raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
452 if (!raw->name) {
453 ret = -EINVAL;
454 goto free_sensor;
455 }
456
457 raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
458 if (!raw->type) {
459 ret = -EINVAL;
460 goto free_sensor;
461 }
462
463 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
464 ret = fdt_get_named_reg(fdt_root, offset,
465 sensor_reg_name[i], &start,
466 &size);
467 if (ret) {
468 dev_debug(dev, "no found %d: sensor node %s, %s\n",
469 ret, ptr, sensor_reg_name[i]);
470 if (i == SENSOR_REG_VALUE) {
471 ret = -EINVAL;
472 goto free_sensor;
473 }
474
475 continue;
476 }
477
478 /* This is a hack to compatible with non-secure
479 * solution. If sensors are included in root node,
480 * then it's non-secure dtb, which use absolute addr
481 * of non-secure solution.
482 */
483 if (parent)
484 raw->regs[i].regoff = start;
485 else
486 raw->regs[i].regoff = start -
487 MAX10_BASE_ADDR;
488 raw->regs[i].size = size;
489 }
490
491 num = fdt_getprop(fdt_root, offset, "id", NULL);
492 if (!num) {
493 ret = -EINVAL;
494 goto free_sensor;
495 }
496
497 raw->id = fdt32_to_cpu(*num);
498 num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
499 raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
500
501 dev_debug(dev, "found sensor from DTB: %s: %s: %u: %u\n",
502 raw->name, raw->type,
503 raw->id, raw->multiplier);
504
505 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
506 dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
507 i, raw->regs[i].regoff,
508 raw->regs[i].size);
509
510 sensor = opae_zmalloc(sizeof(*sensor));
511 if (!sensor) {
512 ret = -EINVAL;
513 goto free_sensor;
514 }
515
516 if (max10_add_sensor(dev, raw, sensor)) {
517 ret = -EINVAL;
518 opae_free(sensor);
519 goto free_sensor;
520 }
521
522 if (sensor->flags & OPAE_SENSOR_VALID) {
523 TAILQ_INSERT_TAIL(&dev->opae_sensor_list, sensor, node);
524 dev_info(dev, "found valid sensor: %s\n", sensor->name);
525 } else
526 opae_free(sensor);
527
528 opae_free(raw);
529 }
530
531 return 0;
532
533 free_sensor:
534 if (raw)
535 opae_free(raw);
536 max10_sensor_uinit(dev);
537 return ret;
538 }
539
check_max10_version(struct intel_max10_device * dev)540 static int check_max10_version(struct intel_max10_device *dev)
541 {
542 unsigned int v;
543
544 if (!max10_reg_read(dev, MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
545 &v)) {
546 if (v != 0xffffffff) {
547 dev_info(dev, "secure MAX10 detected\n");
548 dev->base = MAX10_SEC_BASE_ADDR;
549 dev->flags |= MAX10_FLAGS_SECURE;
550 } else {
551 dev_info(dev, "non-secure MAX10 detected\n");
552 dev->base = MAX10_BASE_ADDR;
553 }
554 return 0;
555 }
556
557 return -ENODEV;
558 }
559
560 static int
max10_secure_hw_init(struct intel_max10_device * dev)561 max10_secure_hw_init(struct intel_max10_device *dev)
562 {
563 int offset, sysmgr_offset = 0;
564 char *fdt_root;
565
566 fdt_root = dev->fdt_root;
567 if (!fdt_root) {
568 dev_debug(dev, "skip init as not find Device Tree\n");
569 return 0;
570 }
571
572 fdt_for_each_subnode(offset, fdt_root, 0) {
573 if (!fdt_node_check_compatible(fdt_root, offset,
574 "intel-max10,system-manager")) {
575 sysmgr_offset = offset;
576 break;
577 }
578 }
579
580 max10_check_capability(dev);
581
582 max10_sensor_init(dev, sysmgr_offset);
583
584 return 0;
585 }
586
587 static int
max10_non_secure_hw_init(struct intel_max10_device * dev)588 max10_non_secure_hw_init(struct intel_max10_device *dev)
589 {
590 max10_check_capability(dev);
591
592 max10_sensor_init(dev, 0);
593
594 return 0;
595 }
596
597 struct intel_max10_device *
intel_max10_device_probe(struct altera_spi_device * spi,int chipselect)598 intel_max10_device_probe(struct altera_spi_device *spi,
599 int chipselect)
600 {
601 struct intel_max10_device *dev;
602 int ret;
603 unsigned int val;
604
605 dev = opae_malloc(sizeof(*dev));
606 if (!dev)
607 return NULL;
608
609 TAILQ_INIT(&dev->opae_sensor_list);
610
611 dev->spi_master = spi;
612
613 dev->spi_tran_dev = spi_transaction_init(spi, chipselect);
614 if (!dev->spi_tran_dev) {
615 dev_err(dev, "%s spi tran init fail\n", __func__);
616 goto free_dev;
617 }
618
619 /* check the max10 version */
620 ret = check_max10_version(dev);
621 if (ret) {
622 dev_err(dev, "Failed to find max10 hardware!\n");
623 goto free_dev;
624 }
625
626 /* load the MAX10 device table */
627 ret = init_max10_device_table(dev);
628 if (ret) {
629 dev_err(dev, "Init max10 device table fail\n");
630 goto free_dev;
631 }
632
633 /* init max10 devices, like sensor*/
634 if (dev->flags & MAX10_FLAGS_SECURE)
635 ret = max10_secure_hw_init(dev);
636 else
637 ret = max10_non_secure_hw_init(dev);
638 if (ret) {
639 dev_err(dev, "Failed to init max10 hardware!\n");
640 goto free_dtb;
641 }
642
643 /* read FPGA loading information */
644 ret = max10_sys_read(dev, FPGA_PAGE_INFO, &val);
645 if (ret) {
646 dev_err(dev, "fail to get FPGA loading info\n");
647 goto release_max10_hw;
648 }
649 dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
650
651 return dev;
652
653 release_max10_hw:
654 max10_sensor_uinit(dev);
655 free_dtb:
656 if (dev->fdt_root)
657 opae_free(dev->fdt_root);
658 if (dev->spi_tran_dev)
659 spi_transaction_remove(dev->spi_tran_dev);
660 free_dev:
661 opae_free(dev);
662
663 return NULL;
664 }
665
intel_max10_device_remove(struct intel_max10_device * dev)666 int intel_max10_device_remove(struct intel_max10_device *dev)
667 {
668 if (!dev)
669 return 0;
670
671 max10_sensor_uinit(dev);
672
673 if (dev->spi_tran_dev)
674 spi_transaction_remove(dev->spi_tran_dev);
675
676 if (dev->fdt_root)
677 opae_free(dev->fdt_root);
678
679 opae_free(dev);
680
681 return 0;
682 }
683