aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/platforms/ibm-fsp/firenze.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/platforms/ibm-fsp/firenze.c')
-rw-r--r--roms/skiboot/platforms/ibm-fsp/firenze.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/roms/skiboot/platforms/ibm-fsp/firenze.c b/roms/skiboot/platforms/ibm-fsp/firenze.c
new file mode 100644
index 000000000..887a9c0ac
--- /dev/null
+++ b/roms/skiboot/platforms/ibm-fsp/firenze.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2013-2019 IBM Corp. */
+
+#include <skiboot.h>
+#include <device.h>
+#include <fsp.h>
+#include <pci.h>
+#include <pci-cfg.h>
+#include <chip.h>
+#include <i2c.h>
+#include <timebase.h>
+#include <hostservices.h>
+
+#include "ibm-fsp.h"
+#include "lxvpd.h"
+
+static struct dt_node *dt_create_i2c_master(struct dt_node *n, uint32_t eng_id)
+{
+ struct dt_node *i2cm;
+ uint64_t freq;
+ uint32_t clock;
+
+ /* Each master registers set is of length 0x20 */
+ i2cm = dt_new_addr(n, "i2cm", 0xa0000 + eng_id * 0x20);
+ if (!i2cm)
+ return NULL;
+
+ dt_add_property_string(i2cm, "compatible",
+ "ibm,power8-i2cm");
+ dt_add_property_cells(i2cm, "reg", 0xa0000 + eng_id * 0x20,
+ 0x20);
+ dt_add_property_cells(i2cm, "chip-engine#", eng_id);
+ dt_add_property_cells(i2cm, "#address-cells", 1);
+ dt_add_property_cells(i2cm, "#size-cells", 0);
+
+ /* Derive the clock source frequency */
+ freq = dt_prop_get_u64_def(n, "bus-frequency", 0);
+ clock = (u32)(freq / 4);
+ if (clock)
+ dt_add_property_cells(i2cm, "clock-frequency", clock);
+ else
+ dt_add_property_cells(i2cm, "clock-frequency", 125000000);
+ return i2cm;
+}
+
+static struct dt_node *dt_create_i2c_bus(struct dt_node *i2cm,
+ const char *port_name, uint32_t port_id)
+{
+ static struct dt_node *port;
+
+ port = dt_new_addr(i2cm, "i2c-bus", port_id);
+ if (!port)
+ return NULL;
+
+ dt_add_property_strings(port, "compatible", "ibm,power8-i2c-port",
+ "ibm,opal-i2c");
+ dt_add_property_string(port, "ibm,port-name", port_name);
+ dt_add_property_cells(port, "reg", port_id);
+ dt_add_property_cells(port, "bus-frequency", 400000);
+ dt_add_property_cells(port, "#address-cells", 1);
+ dt_add_property_cells(port, "#size-cells", 0);
+
+ return port;
+}
+
+static struct dt_node *dt_create_i2c_device(struct dt_node *bus, uint8_t addr,
+ const char *name, const char *compat,
+ const char *label)
+{
+ struct dt_node *dev;
+
+ dev = dt_new_addr(bus, name, addr);
+ if (!dev)
+ return NULL;
+
+ dt_add_property_string(dev, "compatible", compat);
+ dt_add_property_string(dev, "label", label);
+ dt_add_property_cells(dev, "reg", addr);
+ dt_add_property_string(dev, "status", "reserved");
+
+ return dev;
+}
+
+static void firenze_dt_fixup_i2cm(void)
+{
+ struct dt_node *master, *bus, *dev;
+ struct proc_chip *c;
+ const uint32_t *p;
+ char name[32];
+ uint64_t lx;
+
+ if (dt_find_compatible_node(dt_root, NULL, "ibm,power8-i2cm"))
+ return;
+
+ p = dt_prop_get_def(dt_root, "ibm,vpd-lx-info", NULL);
+ if (!p)
+ return;
+
+ lx = ((uint64_t)p[1] << 32) | p[2];
+
+ switch (lx) {
+ case LX_VPD_2S4U_BACKPLANE:
+ case LX_VPD_2S2U_BACKPLANE:
+ case LX_VPD_SHARK_BACKPLANE: /* XXX confirm ? */
+ /* i2c nodes on chip 0x10 */
+ c = get_chip(0x10);
+ if (c) {
+ /* Engine 1 */
+ master = dt_create_i2c_master(c->devnode, 1);
+ assert(master);
+ snprintf(name, sizeof(name), "p8_%08x_e%dp%d", c->id, 1, 0);
+ bus = dt_create_i2c_bus(master, name, 0);
+ assert(bus);
+ dev = dt_create_i2c_device(bus, 0x39, "power-control",
+ "maxim,5961", "pcie-hotplug");
+ assert(dev);
+ dt_add_property_strings(dev, "target-list", "slot-C4",
+ "slot-C5");
+
+ dev = dt_create_i2c_device(bus, 0x3a, "power-control",
+ "maxim,5961", "pcie-hotplug");
+ assert(dev);
+ dt_add_property_strings(dev, "target-list", "slot-C2",
+ "slot-C3");
+ } else {
+ prlog(PR_INFO, "PLAT: Chip not found for the id 0x10\n");
+ }
+
+ /* Fall through */
+ case LX_VPD_1S4U_BACKPLANE:
+ case LX_VPD_1S2U_BACKPLANE:
+ /* i2c nodes on chip 0 */
+ c = get_chip(0);
+ if (!c) {
+ prlog(PR_INFO, "PLAT: Chip not found for the id 0x0\n");
+ break;
+ }
+
+ /* Engine 1*/
+ master = dt_create_i2c_master(c->devnode, 1);
+ assert(master);
+ snprintf(name, sizeof(name), "p8_%08x_e%dp%d", c->id, 1, 0);
+ bus = dt_create_i2c_bus(master, name, 0);
+ assert(bus);
+ dev = dt_create_i2c_device(bus, 0x32, "power-control",
+ "maxim,5961", "pcie-hotplug");
+ assert(dev);
+ dt_add_property_strings(dev, "target-list", "slot-C10", "slot-C11");
+
+ dev = dt_create_i2c_device(bus, 0x35, "power-control",
+ "maxim,5961", "pcie-hotplug");
+ assert(dev);
+ dt_add_property_strings(dev, "target-list", "slot-C6", "slot-C7");
+
+ dev = dt_create_i2c_device(bus, 0x36, "power-control",
+ "maxim,5961", "pcie-hotplug");
+ assert(dev);
+ dt_add_property_strings(dev, "target-list", "slot-C8", "slot-C9");
+
+ dev = dt_create_i2c_device(bus, 0x39, "power-control", "maxim,5961",
+ "pcie-hotplug");
+ assert(dev);
+ dt_add_property_strings(dev, "target-list", "slot-C12");
+ break;
+ default:
+ break;
+ }
+}
+
+static bool firenze_probe(void)
+{
+ if (!dt_node_is_compatible(dt_root, "ibm,firenze"))
+ return false;
+
+ firenze_dt_fixup_i2cm();
+
+ return true;
+}
+
+static uint32_t ibm_fsp_occ_timeout(void)
+{
+ /* Use a fixed 60s value for now */
+ return 60;
+}
+
+static void firenze_init(void)
+{
+ /* We call hservices_init to relocate the hbrt image now, as the FSP
+ * may request an OCC load any time after ibm_fsp_init.
+ */
+ hservices_init();
+
+ ibm_fsp_init();
+}
+
+DECLARE_PLATFORM(firenze) = {
+ .name = "Firenze",
+ .psi = &fsp_platform_psi,
+ .prd = &fsp_platform_prd,
+ .probe = firenze_probe,
+ .init = firenze_init,
+ .fast_reboot_init = fsp_console_reset,
+ .finalise_dt = ibm_fsp_finalise_dt,
+ .exit = ibm_fsp_exit,
+ .cec_power_down = ibm_fsp_cec_power_down,
+ .cec_reboot = ibm_fsp_cec_reboot,
+ .pci_setup_phb = firenze_pci_setup_phb,
+ .pci_get_slot_info = firenze_pci_get_slot_info,
+ .pci_add_loc_code = firenze_pci_add_loc_code,
+ .pci_probe_complete = firenze_pci_send_inventory,
+ .nvram_info = fsp_nvram_info,
+ .nvram_start_read = fsp_nvram_start_read,
+ .nvram_write = fsp_nvram_write,
+ .occ_timeout = ibm_fsp_occ_timeout,
+ .elog_commit = elog_fsp_commit,
+ .start_preload_resource = fsp_start_preload_resource,
+ .resource_loaded = fsp_resource_loaded,
+ .sensor_read = ibm_fsp_sensor_read,
+ .terminate = ibm_fsp_terminate,
+ .op_display = fsp_op_display,
+ .vpd_iohub_load = vpd_iohub_load,
+ .heartbeat_time = fsp_heartbeat_time,
+};