1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2019 Intel Corporation
5 #include "opae_intel_max10.h"
8 static struct intel_max10_device *g_max10;
10 struct opae_sensor_list opae_sensor_list =
11 TAILQ_HEAD_INITIALIZER(opae_sensor_list);
13 int max10_reg_read(unsigned int reg, unsigned int *val)
18 return spi_transaction_read(g_max10->spi_tran_dev,
19 reg, 4, (unsigned char *)val);
22 int max10_reg_write(unsigned int reg, unsigned int val)
24 unsigned int tmp = val;
29 return spi_transaction_write(g_max10->spi_tran_dev,
30 reg, 4, (unsigned char *)&tmp);
33 int max10_sys_read(unsigned int offset, unsigned int *val)
38 return max10_reg_read(g_max10->base + offset, val);
41 int max10_sys_write(unsigned int offset, unsigned int val)
46 return max10_reg_write(g_max10->base + offset, val);
49 static struct max10_compatible_id max10_id_table[] = {
50 {.compatible = MAX10_PAC,},
51 {.compatible = MAX10_PAC_N3000,},
52 {.compatible = MAX10_PAC_END,}
55 static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
57 struct max10_compatible_id *id = max10_id_table;
59 for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
60 if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
70 is_max10_pac_n3000(struct intel_max10_device *max10)
72 return max10->id && !strcmp(max10->id->compatible,
76 static void max10_check_capability(struct intel_max10_device *max10)
81 if (is_max10_pac_n3000(max10)) {
82 max10->flags |= MAX10_FLAGS_NO_I2C2 |
83 MAX10_FLAGS_NO_BMCIMG_FLASH;
84 dev_info(max10, "found %s card\n", max10->id->compatible);
86 max10->flags |= MAX10_FLAGS_MAC_CACHE;
89 static int altera_nor_flash_read(u32 offset,
90 void *buffer, u32 len)
94 unsigned int *buf = (unsigned int *)buffer;
98 if (!buffer || len <= 0)
103 for (i = 0; i < word_len; i++) {
104 ret = max10_reg_read(offset + i*4,
115 static int enable_nor_flash(bool on)
117 unsigned int val = 0;
120 ret = max10_sys_read(RSU_REG, &val);
122 dev_err(NULL "enabling flash error\n");
131 return max10_sys_write(RSU_REG, val);
134 static int init_max10_device_table(struct intel_max10_device *max10)
136 struct max10_compatible_id *id;
137 struct fdt_header hdr;
138 char *fdt_root = NULL;
140 u32 dt_size, dt_addr, val;
143 ret = max10_sys_read(DT_AVAIL_REG, &val);
145 dev_err(max10 "cannot read DT_AVAIL_REG\n");
149 if (!(val & DT_AVAIL)) {
150 dev_err(max10 "DT not available\n");
154 ret = max10_sys_read(DT_BASE_ADDR_REG, &dt_addr);
156 dev_info(max10 "cannot get base addr of device table\n");
160 ret = enable_nor_flash(true);
162 dev_err(max10 "fail to enable flash\n");
166 ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
168 dev_err(max10 "read fdt header fail\n");
172 ret = fdt_check_header(&hdr);
174 dev_err(max10 "check fdt header fail\n");
178 dt_size = fdt_totalsize(&hdr);
179 if (dt_size > DFT_MAX_SIZE) {
180 dev_err(max10 "invalid device table size\n");
185 fdt_root = opae_malloc(dt_size);
191 ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
193 dev_err(max10 "cannot read device table\n");
197 id = max10_match_compatible(fdt_root);
199 dev_err(max10 "max10 compatible not found\n");
204 max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
207 max10->fdt_root = fdt_root;
210 ret = enable_nor_flash(false);
218 static u64 fdt_get_number(const fdt32_t *cell, int size)
223 r = (r << 32) | fdt32_to_cpu(*cell++);
228 static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
229 u64 *start, u64 *size)
231 const fdt32_t *prop, *end;
232 int na = 0, ns = 0, len = 0, parent;
234 parent = fdt_parent_offset(fdt, node);
238 prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
239 na = prop ? fdt32_to_cpu(*prop) : 2;
241 prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
242 ns = prop ? fdt32_to_cpu(*prop) : 2;
244 prop = fdt_getprop(fdt, node, "reg", &len);
246 return -FDT_ERR_NOTFOUND;
248 end = prop + len/sizeof(*prop);
249 prop = prop + (na + ns) * idx;
251 if (prop + na + ns > end)
252 return -FDT_ERR_NOTFOUND;
254 *start = fdt_get_number(prop, na);
255 *size = fdt_get_number(prop + na, ns);
260 static int __fdt_stringlist_search(const void *fdt, int offset,
261 const char *prop, const char *string)
263 int length, len, index = 0;
264 const char *list, *end;
266 list = fdt_getprop(fdt, offset, prop, &length);
270 len = strlen(string) + 1;
274 length = strnlen(list, end - list) + 1;
276 if (list + length > end)
277 return -FDT_ERR_BADVALUE;
279 if (length == len && memcmp(list, string, length) == 0)
286 return -FDT_ERR_NOTFOUND;
289 static int fdt_get_named_reg(const void *fdt, int node, const char *name,
290 u64 *start, u64 *size)
294 idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
298 return fdt_get_reg(fdt, node, idx, start, size);
301 static void max10_sensor_uinit(void)
303 struct opae_sensor_info *info;
305 TAILQ_FOREACH(info, &opae_sensor_list, node) {
306 TAILQ_REMOVE(&opae_sensor_list, info, node);
311 static bool sensor_reg_valid(struct sensor_reg *reg)
316 static int max10_add_sensor(struct raw_sensor_info *info,
317 struct opae_sensor_info *sensor)
323 if (!info || !sensor)
326 sensor->id = info->id;
327 sensor->name = info->name;
328 sensor->type = info->type;
329 sensor->multiplier = info->multiplier;
331 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
332 if (!sensor_reg_valid(&info->regs[i]))
335 ret = max10_sys_read(info->regs[i].regoff, &val);
339 if (val == 0xdeadbeef)
342 val *= info->multiplier;
345 case SENSOR_REG_VALUE:
346 sensor->value_reg = info->regs[i].regoff;
347 sensor->flags |= OPAE_SENSOR_VALID;
349 case SENSOR_REG_HIGH_WARN:
350 sensor->high_warn = val;
351 sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
353 case SENSOR_REG_HIGH_FATAL:
354 sensor->high_fatal = val;
355 sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
357 case SENSOR_REG_LOW_WARN:
358 sensor->low_warn = val;
359 sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
361 case SENSOR_REG_LOW_FATAL:
362 sensor->low_fatal = val;
363 sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
365 case SENSOR_REG_HYSTERESIS:
366 sensor->hysteresis = val;
367 sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
376 max10_sensor_init(struct intel_max10_device *dev, int parent)
378 int i, ret = 0, offset = 0;
382 struct raw_sensor_info *raw;
383 struct opae_sensor_info *sensor;
384 char *fdt_root = dev->fdt_root;
387 dev_debug(dev, "skip sensor init as not find Device Tree\n");
391 fdt_for_each_subnode(offset, fdt_root, parent) {
392 ptr = fdt_get_name(fdt_root, offset, NULL);
394 dev_err(dev, "failed to fdt get name\n");
398 if (!strstr(ptr, "sensor")) {
399 dev_debug(dev, "%s is not a sensor node\n", ptr);
403 dev_debug(dev, "found sensor node %s\n", ptr);
405 raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
411 raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
417 raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
423 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
424 ret = fdt_get_named_reg(fdt_root, offset,
425 sensor_reg_name[i], &start,
428 dev_debug(dev, "no found %d: sensor node %s, %s\n",
429 ret, ptr, sensor_reg_name[i]);
430 if (i == SENSOR_REG_VALUE) {
438 /* This is a hack to compatible with non-secure
439 * solution. If sensors are included in root node,
440 * then it's non-secure dtb, which use absolute addr
441 * of non-secure solution.
444 raw->regs[i].regoff = start;
446 raw->regs[i].regoff = start -
448 raw->regs[i].size = size;
451 num = fdt_getprop(fdt_root, offset, "id", NULL);
457 raw->id = fdt32_to_cpu(*num);
458 num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
459 raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
461 dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
462 raw->name, raw->type,
463 raw->id, raw->multiplier);
465 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
466 dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
467 i, raw->regs[i].regoff,
470 sensor = opae_zmalloc(sizeof(*sensor));
476 if (max10_add_sensor(raw, sensor)) {
482 if (sensor->flags & OPAE_SENSOR_VALID)
483 TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
495 max10_sensor_uinit();
499 static int check_max10_version(struct intel_max10_device *dev)
503 if (!max10_reg_read(MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
505 if (v != 0xffffffff) {
506 dev_info(dev, "secure MAX10 detected\n");
507 dev->base = MAX10_SEC_BASE_ADDR;
508 dev->flags |= MAX10_FLAGS_SECURE;
510 dev_info(dev, "non-secure MAX10 detected\n");
511 dev->base = MAX10_BASE_ADDR;
520 max10_secure_hw_init(struct intel_max10_device *dev)
522 int offset, sysmgr_offset = 0;
525 fdt_root = dev->fdt_root;
527 dev_debug(dev, "skip init as not find Device Tree\n");
531 fdt_for_each_subnode(offset, fdt_root, 0) {
532 if (!fdt_node_check_compatible(fdt_root, offset,
533 "intel-max10,system-manager")) {
534 sysmgr_offset = offset;
539 max10_check_capability(dev);
541 max10_sensor_init(dev, sysmgr_offset);
547 max10_non_secure_hw_init(struct intel_max10_device *dev)
549 max10_check_capability(dev);
551 max10_sensor_init(dev, 0);
556 struct intel_max10_device *
557 intel_max10_device_probe(struct altera_spi_device *spi,
560 struct intel_max10_device *dev;
564 dev = opae_malloc(sizeof(*dev));
568 dev->spi_master = spi;
570 dev->spi_tran_dev = spi_transaction_init(spi, chipselect);
571 if (!dev->spi_tran_dev) {
572 dev_err(dev, "%s spi tran init fail\n", __func__);
576 /* set the max10 device firstly */
579 /* check the max10 version */
580 ret = check_max10_version(dev);
582 dev_err(dev, "Failed to find max10 hardware!\n");
586 /* load the MAX10 device table */
587 ret = init_max10_device_table(dev);
589 dev_err(dev, "Init max10 device table fail\n");
593 /* init max10 devices, like sensor*/
594 if (dev->flags & MAX10_FLAGS_SECURE)
595 ret = max10_secure_hw_init(dev);
597 ret = max10_non_secure_hw_init(dev);
599 dev_err(dev, "Failed to init max10 hardware!\n");
603 /* read FPGA loading information */
604 ret = max10_sys_read(FPGA_PAGE_INFO, &val);
606 dev_err(dev, "fail to get FPGA loading info\n");
607 goto release_max10_hw;
609 dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
614 max10_sensor_uinit();
617 opae_free(dev->fdt_root);
618 if (dev->spi_tran_dev)
619 spi_transaction_remove(dev->spi_tran_dev);
627 int intel_max10_device_remove(struct intel_max10_device *dev)
632 max10_sensor_uinit();
634 if (dev->spi_tran_dev)
635 spi_transaction_remove(dev->spi_tran_dev);
638 opae_free(dev->fdt_root);