diff options
author | Neelesh Gupta <neelegup@linux.vnet.ibm.com> | 2014-11-14 22:10:39 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2014-11-28 16:28:45 +1100 |
commit | 209611863a21e335daff50a94257d0f7fd145cdc (patch) | |
tree | 2e0c194b60ca0ee87f28b9380ea2d4e7f6c90f29 /platforms | |
parent | a6f009080c20981a7952bbb65f181a542f6d00c7 (diff) | |
download | skiboot-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.c | 128 | ||||
-rw-r--r-- | platforms/ibm-fsp/lxvpd.h | 6 |
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 { |