aboutsummaryrefslogtreecommitdiff
path: root/platforms
diff options
context:
space:
mode:
authorNeelesh Gupta <neelegup@linux.vnet.ibm.com>2014-11-14 22:10:39 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2014-11-28 16:28:45 +1100
commit209611863a21e335daff50a94257d0f7fd145cdc (patch)
tree2e0c194b60ca0ee87f28b9380ea2d4e7f6c90f29 /platforms
parenta6f009080c20981a7952bbb65f181a542f6d00c7 (diff)
downloadskiboot-209611863a21e335daff50a94257d0f7fd145cdc.zip
skiboot-209611863a21e335daff50a94257d0f7fd145cdc.tar.gz
skiboot-209611863a21e335daff50a94257d0f7fd145cdc.tar.bz2
PLAT: Add i2c busses on firenze
Set up the device tree nodes of i2c masters and their busses, eventually all this has to come from hostboot. Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'platforms')
-rw-r--r--platforms/ibm-fsp/firenze.c128
-rw-r--r--platforms/ibm-fsp/lxvpd.h6
2 files changed, 133 insertions, 1 deletions
diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c
index 29cbde0..331b48a 100644
--- a/platforms/ibm-fsp/firenze.c
+++ b/platforms/ibm-fsp/firenze.c
@@ -48,9 +48,135 @@ static struct fsp_pcie_inventory *fsp_pcie_inv;
static unsigned int fsp_pcie_inv_alloc_count;
#define FSP_PCIE_INV_ALLOC_CHUNK 4
+static struct dt_node *dt_create_i2c_master(struct dt_node *n, uint32_t eng_id)
+{
+ struct dt_node *i2cm;
+
+ /* 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, "clock-frequency", 50000000);
+ 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);
+
+ 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;
+ 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);
+ assert(c);
+
+ /* Engine 1 */
+ master = dt_create_i2c_master(c->devnode, 1);
+ assert(master);
+ sprintf(name,"p8_%08x_e%dp%d", c->id, 1, 0);
+ bus = dt_create_i2c_bus(master, name, 0);
+ assert(bus);
+ dt_create_i2c_device(bus, 0x39, "slot-C4-C5", "maxim,5961",
+ "pcie-hotplug");
+ dt_create_i2c_device(bus, 0x3a, "slot-C2-C3", "maxim,5961",
+ "pcie-hotplug");
+ /* Fall through */
+ case LX_VPD_1S4U_BACKPLANE:
+ case LX_VPD_1S2U_BACKPLANE:
+ /* i2c nodes on chip 0 */
+ c = get_chip(0);
+ assert(c);
+
+ /* Engine 1*/
+ master = dt_create_i2c_master(c->devnode, 1);
+ assert(master);
+ sprintf(name,"p8_%08x_e%dp%d", c->id, 1, 0);
+ bus = dt_create_i2c_bus(master, name, 0);
+ assert(bus);
+ dt_create_i2c_device(bus, 0x32, "slot-C10-C11", "maxim,5961",
+ "pcie-hotplug");
+ dt_create_i2c_device(bus, 0x35, "slot-C6-C7", "maxim,5961",
+ "pcie-hotplug");
+ dt_create_i2c_device(bus, 0x36, "slot-C8-C9", "maxim,5961",
+ "pcie-hotplug");
+ dt_create_i2c_device(bus, 0x39, "slot-C12", "maxim,5961",
+ "pcie-hotplug");
+ break;
+ default:
+ break;
+ }
+}
+
static bool firenze_probe(void)
{
- return dt_node_is_compatible(dt_root, "ibm,firenze");
+ if (!dt_node_is_compatible(dt_root, "ibm,firenze"))
+ return false;
+
+ firenze_dt_fixup_i2cm();
+
+ return true;
}
static void firenze_send_pci_inventory(void)
diff --git a/platforms/ibm-fsp/lxvpd.h b/platforms/ibm-fsp/lxvpd.h
index ce70502..dbb9513 100644
--- a/platforms/ibm-fsp/lxvpd.h
+++ b/platforms/ibm-fsp/lxvpd.h
@@ -17,6 +17,12 @@
#ifndef __LXVPD_H
#define __LXVPD_H
+#define LX_VPD_1S2U_BACKPLANE 0x3100040100300041ull
+#define LX_VPD_2S2U_BACKPLANE 0x3100040100300042ull
+#define LX_VPD_SHARK_BACKPLANE 0x3100040100300942ull
+#define LX_VPD_1S4U_BACKPLANE 0x3100040100300043ull
+#define LX_VPD_2S4U_BACKPLANE 0x3100040100300044ull
+
/* P8 PCI Slot Entry Definitions -- 1005 */
struct slot_p0 {