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 static struct max10_compatible_id max10_id_table[] = {
34 {.compatible = MAX10_PAC,},
35 {.compatible = MAX10_PAC_N3000,},
36 {.compatible = MAX10_PAC_END,}
39 static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
41 struct max10_compatible_id *id = max10_id_table;
43 for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
44 if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
54 is_max10_pac_n3000(struct intel_max10_device *max10)
56 return max10->id && !strcmp(max10->id->compatible,
60 static void max10_check_capability(struct intel_max10_device *max10)
65 if (is_max10_pac_n3000(max10)) {
66 max10->flags |= MAX10_FLAGS_NO_I2C2 |
67 MAX10_FLAGS_NO_BMCIMG_FLASH;
68 dev_info(max10, "found %s card\n", max10->id->compatible);
72 static int altera_nor_flash_read(u32 offset,
73 void *buffer, u32 len)
77 unsigned int *buf = (unsigned int *)buffer;
81 if (!buffer || len <= 0)
86 for (i = 0; i < word_len; i++) {
87 ret = max10_reg_read(offset + i*4,
98 static int enable_nor_flash(bool on)
100 unsigned int val = 0;
103 ret = max10_reg_read(RSU_REG_OFF, &val);
105 dev_err(NULL "enabling flash error\n");
114 return max10_reg_write(RSU_REG_OFF, val);
117 static int init_max10_device_table(struct intel_max10_device *max10)
119 struct max10_compatible_id *id;
120 struct fdt_header hdr;
121 char *fdt_root = NULL;
123 u32 dt_size, dt_addr, val;
126 ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
128 dev_err(max10 "cannot read DT_AVAIL_REG\n");
132 if (!(val & DT_AVAIL)) {
133 dev_err(max10 "DT not available\n");
137 ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
139 dev_info(max10 "cannot get base addr of device table\n");
143 ret = enable_nor_flash(true);
145 dev_err(max10 "fail to enable flash\n");
149 ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
151 dev_err(max10 "read fdt header fail\n");
155 ret = fdt_check_header(&hdr);
157 dev_err(max10 "check fdt header fail\n");
161 dt_size = fdt_totalsize(&hdr);
162 if (dt_size > DFT_MAX_SIZE) {
163 dev_err(max10 "invalid device table size\n");
168 fdt_root = opae_malloc(dt_size);
174 ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
176 dev_err(max10 "cannot read device table\n");
180 id = max10_match_compatible(fdt_root);
182 dev_err(max10 "max10 compatible not found\n");
187 max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
190 max10->fdt_root = fdt_root;
193 ret = enable_nor_flash(false);
201 static u64 fdt_get_number(const fdt32_t *cell, int size)
206 r = (r << 32) | fdt32_to_cpu(*cell++);
211 static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
212 u64 *start, u64 *size)
214 const fdt32_t *prop, *end;
215 int na = 0, ns = 0, len = 0, parent;
217 parent = fdt_parent_offset(fdt, node);
221 prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
222 na = prop ? fdt32_to_cpu(*prop) : 2;
224 prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
225 ns = prop ? fdt32_to_cpu(*prop) : 2;
227 prop = fdt_getprop(fdt, node, "reg", &len);
229 return -FDT_ERR_NOTFOUND;
231 end = prop + len/sizeof(*prop);
232 prop = prop + (na + ns) * idx;
234 if (prop + na + ns > end)
235 return -FDT_ERR_NOTFOUND;
237 *start = fdt_get_number(prop, na);
238 *size = fdt_get_number(prop + na, ns);
243 static int __fdt_stringlist_search(const void *fdt, int offset,
244 const char *prop, const char *string)
246 int length, len, index = 0;
247 const char *list, *end;
249 list = fdt_getprop(fdt, offset, prop, &length);
253 len = strlen(string) + 1;
257 length = strnlen(list, end - list) + 1;
259 if (list + length > end)
260 return -FDT_ERR_BADVALUE;
262 if (length == len && memcmp(list, string, length) == 0)
269 return -FDT_ERR_NOTFOUND;
272 static int fdt_get_named_reg(const void *fdt, int node, const char *name,
273 u64 *start, u64 *size)
277 idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
281 return fdt_get_reg(fdt, node, idx, start, size);
284 static void max10_sensor_uinit(void)
286 struct opae_sensor_info *info;
288 TAILQ_FOREACH(info, &opae_sensor_list, node) {
289 TAILQ_REMOVE(&opae_sensor_list, info, node);
294 static bool sensor_reg_valid(struct sensor_reg *reg)
299 static int max10_add_sensor(struct raw_sensor_info *info,
300 struct opae_sensor_info *sensor)
306 if (!info || !sensor)
309 sensor->id = info->id;
310 sensor->name = info->name;
311 sensor->type = info->type;
312 sensor->multiplier = info->multiplier;
314 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
315 if (!sensor_reg_valid(&info->regs[i]))
318 ret = max10_reg_read(info->regs[i].regoff, &val);
322 if (val == 0xdeadbeef)
325 val *= info->multiplier;
328 case SENSOR_REG_VALUE:
329 sensor->value_reg = info->regs[i].regoff;
330 sensor->flags |= OPAE_SENSOR_VALID;
332 case SENSOR_REG_HIGH_WARN:
333 sensor->high_warn = val;
334 sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
336 case SENSOR_REG_HIGH_FATAL:
337 sensor->high_fatal = val;
338 sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
340 case SENSOR_REG_LOW_WARN:
341 sensor->low_warn = val;
342 sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
344 case SENSOR_REG_LOW_FATAL:
345 sensor->low_fatal = val;
346 sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
348 case SENSOR_REG_HYSTERESIS:
349 sensor->hysteresis = val;
350 sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
358 static int max10_sensor_init(struct intel_max10_device *dev)
360 int i, ret = 0, offset = 0;
364 struct raw_sensor_info *raw;
365 struct opae_sensor_info *sensor;
366 char *fdt_root = dev->fdt_root;
369 dev_debug(dev, "skip sensor init as not find Device Tree\n");
373 fdt_for_each_subnode(offset, fdt_root, 0) {
374 ptr = fdt_get_name(fdt_root, offset, NULL);
376 dev_err(dev, "failed to fdt get name\n");
380 if (!strstr(ptr, "sensor")) {
381 dev_debug(dev, "%s is not a sensor node\n", ptr);
385 dev_debug(dev, "found sensor node %s\n", ptr);
387 raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
393 raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
399 raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
405 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
406 ret = fdt_get_named_reg(fdt_root, offset,
407 sensor_reg_name[i], &start,
410 dev_debug(dev, "no found %d: sensor node %s, %s\n",
411 ret, ptr, sensor_reg_name[i]);
412 if (i == SENSOR_REG_VALUE) {
420 raw->regs[i].regoff = start;
421 raw->regs[i].size = size;
424 num = fdt_getprop(fdt_root, offset, "id", NULL);
430 raw->id = fdt32_to_cpu(*num);
431 num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
432 raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
434 dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
435 raw->name, raw->type,
436 raw->id, raw->multiplier);
438 for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
439 dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
440 i, raw->regs[i].regoff,
443 sensor = opae_zmalloc(sizeof(*sensor));
449 if (max10_add_sensor(raw, sensor)) {
455 if (sensor->flags & OPAE_SENSOR_VALID)
456 TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
468 max10_sensor_uinit();
472 struct intel_max10_device *
473 intel_max10_device_probe(struct altera_spi_device *spi,
476 struct intel_max10_device *dev;
480 dev = opae_malloc(sizeof(*dev));
484 dev->spi_master = spi;
486 dev->spi_tran_dev = spi_transaction_init(spi, chipselect);
487 if (!dev->spi_tran_dev) {
488 dev_err(dev, "%s spi tran init fail\n", __func__);
492 /* set the max10 device firstly */
495 /* init the MAX10 device table */
496 ret = init_max10_device_table(dev);
498 dev_err(dev, "init max10 device table fail\n");
502 max10_check_capability(dev);
504 /* read FPGA loading information */
505 ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
507 dev_err(dev, "fail to get FPGA loading info\n");
510 dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
513 max10_sensor_init(dev);
519 opae_free(dev->fdt_root);
520 spi_transaction_remove(dev->spi_tran_dev);
528 int intel_max10_device_remove(struct intel_max10_device *dev)
533 max10_sensor_uinit();
535 if (dev->spi_tran_dev)
536 spi_transaction_remove(dev->spi_tran_dev);
539 opae_free(dev->fdt_root);