1 /* Copyright 2013-2014 IBM Corp.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <device.h>
18 #include "spira.h"
19 #include <cpu.h>
20 #include <vpd.h>
21 #include <ccan/str/str.h>
22 #include <interrupts.h>
23 #include <inttypes.h>
24 #include <phys-map.h>
25 #include <chip.h>
26 #include <ipmi.h>
27
28 #include "hdata.h"
29
30 enum sp_type {
31 SP_BAD = 0,
32 SP_UNKNOWN,
33 SP_FSP,
34 SP_BMC,
35 };
36
37 static const char * const sp_names[] = {
38 "Broken", "Unknown", "FSP", "BMC",
39 };
40
find_service_proc_type(const struct HDIF_common_hdr * spss,int index)41 static enum sp_type find_service_proc_type(const struct HDIF_common_hdr *spss,
42 int index)
43 {
44 const struct spss_sp_impl *sp_impl;
45 int hw_ver, sw_ver, flags;
46 enum sp_type sp_type;
47 bool functional, installed;
48
49 /* Find an check the SP Implementation structure */
50 sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);
51 if (!CHECK_SPPTR(sp_impl)) {
52 prerror("SP #%d: SPSS/SP_Implementation not found !\n", index);
53 return SP_BAD;
54 }
55
56 hw_ver = be16_to_cpu(sp_impl->hw_version);
57 sw_ver = be16_to_cpu(sp_impl->sw_version);
58 flags = be16_to_cpu(sp_impl->func_flags);
59
60 switch (hw_ver) {
61 case 0x1:
62 case 0x2: /* We only support FSP2 */
63 sp_type = SP_FSP;
64 break;
65 case 0x3:
66 sp_type = SP_BMC;
67 break;
68 default:
69 sp_type = SP_UNKNOWN;
70 }
71
72 if (sp_type == SP_UNKNOWN)
73 return SP_UNKNOWN;
74
75 installed = !!(flags & SPSS_SP_IMPL_FLAGS_INSTALLED);
76 functional = !!(flags & SPSS_SP_IMPL_FLAGS_FUNCTIONAL);
77
78 if (!installed || !functional) {
79 prerror("%s #%d not usable: %sinstalled, %sfunctional\n",
80 sp_names[sp_type], index,
81 installed ? "" : "not ",
82 functional ? "" : "not ");
83
84 return SP_BAD;
85 }
86
87 prlog(PR_INFO, "%s #%d: HW version %d, SW version %d, chip DD%d.%d\n",
88 sp_names[sp_type], index, hw_ver, sw_ver,
89 sp_impl->chip_version >> 4,
90 sp_impl->chip_version & 0xf);
91
92 return sp_type;
93 }
94
95 /*
96 * Note on DT representation of the PSI links and FSPs:
97 *
98 * We create a XSCOM node for each PSI host bridge(one per chip),
99 *
100 * This is done in spira.c
101 *
102 * We do not create the /psi MMIO variant at this stage, it will
103 * be added by the psi driver in skiboot.
104 *
105 * We do not put the FSP(s) as children of these. Instead, we create
106 * a top-level /fsps node with the FSPs as children.
107 *
108 * Each FSP then has a "links" property which is an array of chip IDs
109 */
110
fsp_create_node(const void * spss,int i,struct dt_node * parent)111 static struct dt_node *fsp_create_node(const void *spss, int i,
112 struct dt_node *parent)
113 {
114 const struct spss_sp_impl *sp_impl;
115 struct dt_node *node;
116
117 sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);
118
119 node = dt_new_addr(parent, "fsp", i);
120 assert(node);
121
122 dt_add_property_cells(node, "reg", i);
123
124 if (be16_to_cpu(sp_impl->hw_version) == 1) {
125 dt_add_property_strings(node, "compatible", "ibm,fsp",
126 "ibm,fsp1");
127 /* Offset into the FSP MMIO space where the mailbox
128 * registers are */
129 /* seen in the FSP1 spec */
130 dt_add_property_cells(node, "reg-offset", 0xb0016000);
131 } else if (be16_to_cpu(sp_impl->hw_version) == 2) {
132 dt_add_property_strings(node, "compatible", "ibm,fsp",
133 "ibm,fsp2");
134 dt_add_property_cells(node, "reg-offset", 0xb0011000);
135 }
136 dt_add_property_cells(node, "hw-version", be16_to_cpu(sp_impl->hw_version));
137 dt_add_property_cells(node, "sw-version", be16_to_cpu(sp_impl->sw_version));
138
139 if (be16_to_cpu(sp_impl->func_flags) & SPSS_SP_IMPL_FLAGS_PRIMARY)
140 dt_add_property(node, "primary", NULL, 0);
141
142 return node;
143 }
144
fsp_create_link(const struct spss_iopath * iopath,int index,int fsp_index)145 static uint32_t fsp_create_link(const struct spss_iopath *iopath, int index,
146 int fsp_index)
147 {
148 struct dt_node *node;
149 const char *ststr;
150 bool current = false;
151 bool working = false;
152 uint32_t chip_id;
153
154 switch(be16_to_cpu(iopath->psi.link_status)) {
155 case SPSS_IO_PATH_PSI_LINK_BAD_FRU:
156 ststr = "Broken";
157 break;
158 case SPSS_IO_PATH_PSI_LINK_CURRENT:
159 ststr = "Active";
160 current = working = true;
161 break;
162 case SPSS_IO_PATH_PSI_LINK_BACKUP:
163 ststr = "Backup";
164 working = true;
165 break;
166 default:
167 ststr = "Unknown";
168 }
169 prlog(PR_DEBUG, "FSP #%d: IO PATH %d is %s PSI Link, GXHB at %" PRIx64 "\n",
170 fsp_index, index, ststr, be64_to_cpu(iopath->psi.gxhb_base));
171
172 chip_id = pcid_to_chip_id(be32_to_cpu(iopath->psi.proc_chip_id));
173 node = dt_find_compatible_node_on_chip(dt_root, NULL, "ibm,psihb-x",
174 chip_id);
175 if (!node) {
176 prerror("FSP #%d: Can't find psihb node for link %d\n",
177 fsp_index, index);
178 } else {
179 if (current)
180 dt_add_property(node, "boot-link", NULL, 0);
181 dt_add_property_strings(node, "status", working ? "ok" : "bad");
182 }
183
184 return chip_id;
185 }
186
fsp_create_links(const void * spss,int index,struct dt_node * fsp_node)187 static void fsp_create_links(const void *spss, int index,
188 struct dt_node *fsp_node)
189 {
190 uint32_t *links = NULL;
191 unsigned int i, lp, lcount = 0;
192 int count;
193
194 count = HDIF_get_iarray_size(spss, SPSS_IDATA_SP_IOPATH);
195 if (count < 0) {
196 prerror("FSP #%d: Can't find IO PATH array size !\n", index);
197 return;
198 }
199 prlog(PR_DEBUG, "FSP #%d: Found %d IO PATH\n", index, count);
200
201 /* Iterate all links */
202 for (i = 0; i < count; i++) {
203 const struct spss_iopath *iopath;
204 unsigned int iopath_sz;
205 uint32_t chip;
206
207 iopath = HDIF_get_iarray_item(spss, SPSS_IDATA_SP_IOPATH,
208 i, &iopath_sz);
209 if (!CHECK_SPPTR(iopath)) {
210 prerror("FSP #%d: Can't find IO PATH %d\n", index, i);
211 break;
212 }
213 if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_PSI) {
214 prerror("FSP #%d: Unsupported IO PATH %d type 0x%04x\n",
215 index, i, iopath->iopath_type);
216 continue;
217 }
218
219 chip = fsp_create_link(iopath, i, index);
220 lp = lcount++;
221 links = realloc(links, 4 * lcount);
222 links[lp] = chip;
223 }
224 if (links)
225 dt_add_property(fsp_node, "ibm,psi-links", links, lcount * 4);
226
227 free(links);
228 }
229
add_lpc_io_node(struct dt_node * parent,const char * name,u32 offset,u32 size)230 static struct dt_node *add_lpc_io_node(struct dt_node *parent,
231 const char *name, u32 offset, u32 size)
232 {
233 struct dt_node *n;
234 char buffer[32];
235
236 /*
237 * LPC bus addresses have strange DT names, they have the
238 * Bus address space embedded into the unit address e.g.
239 * serial@i3f8 - refers to offset 0x3f8 in the IO space
240 */
241
242 snprintf(buffer, sizeof(buffer), "%s@i%x", name, offset);
243 n = dt_new(parent, buffer);
244 assert(n);
245
246 /* first address cell of 1 indicates the LPC IO space */
247 dt_add_property_cells(n, "reg", 1, offset, size);
248
249 return n;
250 }
251
add_uart(const struct spss_iopath * iopath,struct dt_node * lpc)252 static void add_uart(const struct spss_iopath *iopath, struct dt_node *lpc)
253 {
254 struct dt_node *serial;
255 u64 base;
256
257 /* XXX: The spec says this is supposed to be a MMIO address.
258 * However, in practice we get an LPC IO Space offset.
259 */
260 base = be64_to_cpu(iopath->lpc.uart_base);
261
262 serial = add_lpc_io_node(lpc, "serial", base,
263 be32_to_cpu(iopath->lpc.uart_size));
264
265 dt_add_property_string(serial, "compatible", "ns16550");
266
267 dt_add_property_cells(serial, "current-speed",
268 be32_to_cpu(iopath->lpc.uart_baud));
269 dt_add_property_cells(serial, "clock-frequency",
270 be32_to_cpu(iopath->lpc.uart_clk));
271 dt_add_property_cells(serial, "interrupts",
272 be32_to_cpu(iopath->lpc.uart_int_number));
273 dt_add_property_string(serial, "device_type", "serial");
274
275
276 prlog(PR_DEBUG, "LPC UART: base addr = %#" PRIx64" (%#" PRIx64 ") size = %#x clk = %u, baud = %u\n",
277 be64_to_cpu(iopath->lpc.uart_base),
278 base,
279 be32_to_cpu(iopath->lpc.uart_size),
280 be32_to_cpu(iopath->lpc.uart_clk),
281 be32_to_cpu(iopath->lpc.uart_baud));
282 }
283
add_chip_id_to_sensors(struct dt_node * sensor_node,__be32 slca_index)284 static void add_chip_id_to_sensors(struct dt_node *sensor_node, __be32 slca_index)
285 {
286 unsigned int i;
287 const void *hdif;
288 const struct slca_entry *slca;
289 const struct spira_fru_id *fru_id;
290 const struct sppcrd_chip_info *cinfo;
291
292 slca = slca_get_entry(slca_index);
293 if (slca == NULL) {
294 prlog(PR_WARNING, "SENSORS: Invalid slca index\n");
295 return;
296 }
297
298 for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i, SPPCRD_HDIF_SIG) {
299 fru_id = HDIF_get_idata(hdif, SPPCRD_IDATA_FRU_ID, NULL);
300 if (!fru_id)
301 return;
302
303 if (fru_id->rsrc_id != slca->rsrc_id)
304 continue;
305
306 cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
307 if (!CHECK_SPPTR(cinfo)) {
308 prlog(PR_ERR, "SENSORS: Bad ChipID data %d\n", i);
309 return;
310 }
311
312 dt_add_property_cells(sensor_node,
313 "ibm,chip-id", be32_to_cpu(cinfo->xscom_id));
314 return;
315 }
316 }
317
add_ipmi_sensors(struct dt_node * bmc_node)318 static void add_ipmi_sensors(struct dt_node *bmc_node)
319 {
320 int i;
321 const struct HDIF_common_hdr *hdif_sensor;
322 const struct ipmi_sensors *ipmi_sensors;
323 struct dt_node *sensors_node, *sensor_node;
324
325 hdif_sensor = get_hdif(&spira.ntuples.ipmi_sensor, IPMI_SENSORS_HDIF_SIG);
326 if (!hdif_sensor) {
327 prlog(PR_DEBUG, "SENSORS: Missing IPMI sensors mappings tuple\n");
328 return;
329 }
330
331 ipmi_sensors = HDIF_get_idata(hdif_sensor, IPMI_SENSORS_IDATA_SENSORS, NULL);
332 if (!ipmi_sensors) {
333 prlog(PR_DEBUG, "SENSORS: bad data\n");
334 return;
335 }
336
337 sensors_node = dt_new(bmc_node, "sensors");
338 assert(sensors_node);
339
340 dt_add_property_cells(sensors_node, "#address-cells", 1);
341 dt_add_property_cells(sensors_node, "#size-cells", 0);
342
343 for (i = 0; i < be32_to_cpu(ipmi_sensors->count); i++) {
344 if(dt_find_by_name_addr(sensors_node, "sensor",
345 ipmi_sensors->data[i].id)) {
346 prlog(PR_WARNING, "SENSORS: Duplicate sensor ID : %x\n",
347 ipmi_sensors->data[i].id);
348 continue;
349 }
350
351 /* We support only < MAX_IPMI_SENSORS sensors */
352 if (!(ipmi_sensors->data[i].type < MAX_IPMI_SENSORS))
353 continue;
354
355 sensor_node = dt_new_addr(sensors_node, "sensor",
356 ipmi_sensors->data[i].id);
357 assert(sensor_node);
358 dt_add_property_string(sensor_node, "compatible", "ibm,ipmi-sensor");
359 dt_add_property_cells(sensor_node, "reg", ipmi_sensors->data[i].id);
360 dt_add_property_cells(sensor_node, "ipmi-sensor-type",
361 ipmi_sensors->data[i].type);
362
363 add_chip_id_to_sensors(sensor_node, ipmi_sensors->data[i].slca_index);
364 }
365 }
366
bmc_create_node(const struct HDIF_common_hdr * sp)367 static void bmc_create_node(const struct HDIF_common_hdr *sp)
368 {
369 struct dt_node *bmc_node;
370 u32 fw_bar, io_bar, mem_bar, internal_bar;
371 const struct spss_iopath *iopath;
372 const struct spss_sp_impl *sp_impl;
373 struct dt_node *lpcm, *lpc, *n;
374 u64 lpcm_base, lpcm_end;
375 uint32_t chip_id;
376 int size;
377
378 bmc_node = dt_new(dt_root, "bmc");
379 assert(bmc_node);
380
381 dt_add_property_cells(bmc_node, "#address-cells", 1);
382 dt_add_property_cells(bmc_node, "#size-cells", 0);
383
384 /* Add sensor info under /bmc */
385 add_ipmi_sensors(bmc_node);
386
387 sp_impl = HDIF_get_idata(sp, SPSS_IDATA_SP_IMPL, &size);
388 if (CHECK_SPPTR(sp_impl) && (size > 8)) {
389 dt_add_property_strings(bmc_node, "compatible", sp_impl->sp_family);
390 prlog(PR_INFO, "SP Family is %s\n", sp_impl->sp_family);
391 }
392
393 iopath = HDIF_get_iarray_item(sp, SPSS_IDATA_SP_IOPATH, 0, NULL);
394
395 if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_LPC) {
396 prerror("BMC: Non-LPC IOPATH, this is probably broken\n");
397 return;
398 }
399
400 /*
401 * For now we only instantiate the LPC node for the LPC that is used
402 * for Host <-> BMC comms. The secondary LPCs can be skipped.
403 */
404 if (be16_to_cpu(iopath->lpc.link_status) != LPC_STATUS_ACTIVE)
405 return;
406
407 #define GB (1024ul * 1024ul * 1024ul)
408 /*
409 * convert the hdat chip ID the HW chip id so we get the right
410 * phys map offset
411 */
412 chip_id = pcid_to_chip_id(be32_to_cpu(iopath->lpc.chip_id));
413
414 phys_map_get(chip_id, LPC_BUS, 0, &lpcm_base, NULL);
415 lpcm = dt_new_addr(dt_root, "lpcm-opb", lpcm_base);
416 assert(lpcm);
417
418 dt_add_property_cells(lpcm, "#address-cells", 1);
419 dt_add_property_cells(lpcm, "#size-cells", 1);
420 dt_add_property_strings(lpcm, "compatible",
421 "ibm,power9-lpcm-opb", "simple-bus");
422 dt_add_property_u64s(lpcm, "reg", lpcm_base, 0x100000000ul);
423
424 dt_add_property_cells(lpcm, "ibm,chip-id", chip_id);
425
426 /* Setup the ranges for the MMIO LPC */
427 lpcm_end = lpcm_base + 2 * GB;
428 dt_add_property_cells(lpcm, "ranges",
429 0x00000000, hi32(lpcm_base), lo32(lpcm_base), 2 * GB,
430 0x80000000, hi32(lpcm_end), lo32(lpcm_end), 2 * GB);
431
432 /*
433 * Despite the name the "BAR" values provided through the HDAT are
434 * the base addresses themselves rather than the BARs
435 */
436 fw_bar = be32_to_cpu(iopath->lpc.firmware_bar);
437 mem_bar = be32_to_cpu(iopath->lpc.memory_bar);
438 io_bar = be32_to_cpu(iopath->lpc.io_bar);
439 internal_bar = be32_to_cpu(iopath->lpc.internal_bar);
440
441 prlog(PR_DEBUG, "LPC: IOPATH chip id = %x\n", chip_id);
442 prlog(PR_DEBUG, "LPC: FW BAR = %#x\n", fw_bar);
443 prlog(PR_DEBUG, "LPC: MEM BAR = %#x\n", mem_bar);
444 prlog(PR_DEBUG, "LPC: IO BAR = %#x\n", io_bar);
445 prlog(PR_DEBUG, "LPC: Internal BAR = %#x\n", internal_bar);
446
447 /*
448 * The internal address space BAR actually points to the LPC master
449 * registers. So we "fix" it by masking off the low bits.
450 *
451 * XXX: we probably need separate base addresses for all these things
452 */
453 internal_bar &= 0xf0000000;
454
455 /* Add the various internal bus devices */
456 n = dt_new_addr(lpcm, "opb-master", internal_bar + 0x10000);
457 dt_add_property_string(n, "compatible", "ibm,power9-lpcm-opb-master");
458 dt_add_property_cells(n, "reg", internal_bar + 0x10000, 0x60);
459
460 n = dt_new_addr(lpcm, "opb-arbiter", internal_bar + 0x11000);
461 dt_add_property_string(n, "compatible", "ibm,power9-lpcm-opb-arbiter");
462 dt_add_property_cells(n, "reg", internal_bar + 0x11000, 0x8);
463
464 n = dt_new_addr(lpcm, "lpc-controller", internal_bar + 0x12000);
465 dt_add_property_string(n, "compatible", "ibm,power9-lpc-controller");
466 dt_add_property_cells(n, "reg", internal_bar + 0x12000, 0x100);
467
468 /*
469 * FIXME: lpc@0 might not be accurate, but i'm pretty sure
470 * lpc@f0000000 isn't right either.
471 */
472 lpc = dt_new_addr(lpcm, "lpc", 0x0);
473 dt_add_property_cells(lpc, "#address-cells", 2);
474 dt_add_property_cells(lpc, "#size-cells", 1);
475 dt_add_property_strings(lpc, "compatible",
476 "ibm,power9-lpc", "ibm,power8-lpc");
477
478 dt_add_property_cells(lpc, "ranges",
479 0, 0, mem_bar, 0x10000000, /* MEM space */
480 1, 0, io_bar, 0x00010000, /* IO space */
481 /* we don't expose the internal space */
482 3, 0, fw_bar, 0x10000000 /* FW space */
483 );
484
485 add_uart(iopath, lpc);
486
487 /* BT device info isn't currently populated */
488 prlog(PR_DEBUG, "LPC: BT [%#"PRIx64", %#x] sms_int: %u, bmc_int: %u\n",
489 iopath->lpc.bt_base, iopath->lpc.bt_size,
490 iopath->lpc.bt_sms_int_num, iopath->lpc.bt_bmc_response_int_num
491 );
492 }
493
494 /*
495 * Search for and instanciate BMC nodes. This is mostly the same as fsp_parse()
496 * below, but it can be called earlier since BMCs don't depend on the psihb
497 * nodes being added.
498 */
bmc_parse(void)499 void bmc_parse(void)
500 {
501 bool found = false;
502 const void *sp;
503 int i;
504
505 sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
506 if (!sp)
507 return;
508
509 for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, i, SPSS_HDIF_SIG) {
510 if (find_service_proc_type(sp, i) == SP_BMC) {
511 bmc_create_node(sp);
512 found = true;
513 }
514 }
515
516 if (found)
517 early_uart_init();
518 }
519
fsp_parse(void)520 void fsp_parse(void)
521 {
522 struct dt_node *fsp_root = NULL, *fsp_node;
523 const void *sp;
524 int index;
525
526 /* Find SPSS tuple in SPIRA */
527 sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
528 if (!sp) {
529 prlog(PR_WARNING, "HDAT: No FSP/BMC found!\n");
530 return;
531 }
532
533 for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, index, SPSS_HDIF_SIG) {
534 switch (find_service_proc_type(sp, index)) {
535 case SP_FSP:
536 if (!fsp_root) {
537 fsp_root = dt_new(dt_root, "fsps");
538 assert(fsp_root);
539
540 dt_add_property_cells(fsp_root,
541 "#address-cells", 1);
542 dt_add_property_cells(fsp_root,
543 "#size-cells", 0);
544 }
545
546 fsp_node = fsp_create_node(sp, index, fsp_root);
547 if (fsp_node)
548 fsp_create_links(sp, index, fsp_node);
549
550 break;
551
552 case SP_BMC:
553 /* Handled above */
554 break;
555
556 case SP_BAD:
557 break;
558
559 default:
560 prerror("SP #%d: This service processor is not supported\n", index);
561 break;
562 }
563 }
564 }
565