197 lines
6 KiB
C
197 lines
6 KiB
C
/* Copyright 2016-2019 IBM Corp.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#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 <npu2.h>
|
|
|
|
#include "ibm-fsp.h"
|
|
#include "lxvpd.h"
|
|
|
|
/* We don't yet create NPU device nodes on ZZ, but these values are correct */
|
|
static const struct platform_ocapi zz_ocapi = {
|
|
.i2c_engine = 1,
|
|
.i2c_port = 4,
|
|
.i2c_reset_addr = 0x20,
|
|
.i2c_reset_brick2 = (1 << 1),
|
|
.i2c_reset_brick3 = (1 << 6),
|
|
.i2c_reset_brick4 = 0, /* unused */
|
|
.i2c_reset_brick5 = 0, /* unused */
|
|
.i2c_presence_addr = 0x20,
|
|
.i2c_presence_brick2 = (1 << 2), /* bottom connector */
|
|
.i2c_presence_brick3 = (1 << 7), /* top connector */
|
|
.i2c_presence_brick4 = 0, /* unused */
|
|
.i2c_presence_brick5 = 0, /* unused */
|
|
.odl_phy_swap = true,
|
|
};
|
|
|
|
#define NPU_BASE 0x5011000
|
|
#define NPU_SIZE 0x2c
|
|
#define NPU_INDIRECT0 0x8000000009010c3f /* OB0 - no OB3 on ZZ */
|
|
|
|
static void create_link(struct dt_node *npu, int group, int index)
|
|
{
|
|
struct dt_node *link;
|
|
uint32_t lane_mask;
|
|
|
|
switch (index) {
|
|
case 2:
|
|
lane_mask = 0xf1e000; /* 0-3, 7-10 */
|
|
break;
|
|
case 3:
|
|
lane_mask = 0x00078f; /* 13-16, 20-23 */
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
|
|
link = dt_new_addr(npu, "link", index);
|
|
dt_add_property_string(link, "compatible", "ibm,npu-link");
|
|
dt_add_property_cells(link, "ibm,npu-link-index", index);
|
|
dt_add_property_u64s(link, "ibm,npu-phy", NPU_INDIRECT0);
|
|
dt_add_property_cells(link, "ibm,npu-lane-mask", lane_mask);
|
|
dt_add_property_cells(link, "ibm,npu-group-id", group);
|
|
dt_add_property_u64s(link, "ibm,link-speed", 25000000000ul);
|
|
}
|
|
|
|
static void add_opencapi_dt_nodes(void)
|
|
{
|
|
struct dt_node *npu, *xscom;
|
|
int npu_index = 0;
|
|
int phb_index = 7;
|
|
|
|
/*
|
|
* In an ideal world, we should get all the NPU links
|
|
* information from HDAT. But after some effort, HDAT is still
|
|
* giving incorrect information for opencapi. As of this
|
|
* writing:
|
|
* 1. link usage is wrong for most FPGA cards (0xFFFF vs. 2)
|
|
* 2. the 24-bit lane mask is aligned differently than on
|
|
* other platforms (witherspoon)
|
|
* 3. connecting a link entry in HDAT to the real physical
|
|
* link will need extra work:
|
|
* - HDAT does presence detection and only lists links with
|
|
* an adapter, so we cannot use default ordering like on
|
|
* witherspoon
|
|
* - best option is probably the brick ID field (offset 8).
|
|
* It's coming straight from the MRW, but seems to match
|
|
* what we expect (2 or 3). Would need to be checked.
|
|
*
|
|
* To make things more fun, any change in the HDAT data needs
|
|
* to be coordinated with PHYP, which is using (some of) those
|
|
* fields.
|
|
*
|
|
* As a consequence:
|
|
* 1. the hdat parsing code in skiboot remains disabled (for
|
|
* opencapi)
|
|
* 2. we hard-code the NPU and links entries in the device
|
|
* tree.
|
|
*
|
|
* Getting the data from HDAT would have the advantage of
|
|
* providing the real link speed (20.0 vs. 25.78125 gbps),
|
|
* which is useful as there's one speed-dependent setting we
|
|
* need to do when initializing the NPU. Our hard coded
|
|
* definition assumes the higher speed and may need tuning in
|
|
* debug scenario using a lower link speed.
|
|
*/
|
|
dt_for_each_compatible(dt_root, xscom, "ibm,xscom") {
|
|
/*
|
|
* our hdat parsing code may create NPU nodes with no
|
|
* links, so let's make sure we start from a clean
|
|
* state
|
|
*/
|
|
npu = dt_find_by_name_addr(xscom, "npu", NPU_BASE);
|
|
if (npu)
|
|
dt_free(npu);
|
|
|
|
npu = dt_new_addr(xscom, "npu", NPU_BASE);
|
|
dt_add_property_cells(npu, "reg", NPU_BASE, NPU_SIZE);
|
|
dt_add_property_strings(npu, "compatible", "ibm,power9-npu");
|
|
dt_add_property_cells(npu, "ibm,npu-index", npu_index++);
|
|
dt_add_property_cells(npu, "ibm,phb-index", phb_index++);
|
|
dt_add_property_cells(npu, "ibm,npu-links", 2);
|
|
|
|
create_link(npu, 1, 2);
|
|
create_link(npu, 2, 3);
|
|
}
|
|
}
|
|
|
|
static bool zz_probe(void)
|
|
{
|
|
/* FIXME: make this neater when the dust settles */
|
|
if (dt_node_is_compatible(dt_root, "ibm,zz-1s2u") ||
|
|
dt_node_is_compatible(dt_root, "ibm,zz-1s4u") ||
|
|
dt_node_is_compatible(dt_root, "ibm,zz-2s2u") ||
|
|
dt_node_is_compatible(dt_root, "ibm,zz-2s4u") ||
|
|
dt_node_is_compatible(dt_root, "ibm,zz-1s4u+gen4") ||
|
|
dt_node_is_compatible(dt_root, "ibm,zz-2s2u+gen4") ||
|
|
dt_node_is_compatible(dt_root, "ibm,zz-2s4u+gen4")) {
|
|
|
|
add_opencapi_dt_nodes();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static uint32_t ibm_fsp_occ_timeout(void)
|
|
{
|
|
/* Use a fixed 60s value for now */
|
|
return 60;
|
|
}
|
|
|
|
static void zz_init(void)
|
|
{
|
|
ibm_fsp_init();
|
|
hservice_fsp_init();
|
|
}
|
|
|
|
DECLARE_PLATFORM(zz) = {
|
|
.name = "ZZ",
|
|
.psi = &fsp_platform_psi,
|
|
.prd = &fsp_platform_prd,
|
|
.probe = zz_probe,
|
|
.init = zz_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_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,
|
|
.ocapi = &zz_ocapi,
|
|
.npu2_device_detect = npu2_i2c_presence_detect,
|
|
.op_display = fsp_op_display,
|
|
.vpd_iohub_load = vpd_iohub_load,
|
|
.heartbeat_time = fsp_heartbeat_time,
|
|
};
|