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