aboutsummaryrefslogtreecommitdiff
path: root/platforms
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2019-11-27 15:47:58 +1100
committerOliver O'Halloran <oohall@gmail.com>2019-12-04 14:19:09 +1100
commitdc85bd46d20db4d878216283f818573cb0c8c05b (patch)
tree878938bc5fec2a15457175cbaabceb066d6ce852 /platforms
parent0990e822666b65b50fb577c0389a972637249896 (diff)
downloadskiboot-dc85bd46d20db4d878216283f818573cb0c8c05b.zip
skiboot-dc85bd46d20db4d878216283f818573cb0c8c05b.tar.gz
skiboot-dc85bd46d20db4d878216283f818573cb0c8c05b.tar.bz2
witherspoon: Squash spurious I2C errors
On witherspoon there's an I2C bus connecting the each chip to the GPUs connected to that chip via NVLink. That bus has a 750kOhm pullup on the system planar with prevents the bus from operating correctly. Each GPU has a smaller pullup which makes the bus usable when a GPU is plugged in, but on systems without GPUs we get a lot of spurious I2C master errors. Specificly, because of the oversized pullup the SDA and SCL for that bus cannot return to '1' fast enough, so the master assumes that another master is driving the bus and that it should stop. Work around this by disabling the affected port when there's no GPUs detected in the system. Reviewed-by: Andrew Donnellan <ajd@linux.ibm.com> Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Diffstat (limited to 'platforms')
-rw-r--r--platforms/astbmc/witherspoon.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/platforms/astbmc/witherspoon.c b/platforms/astbmc/witherspoon.c
index 8aaed97..c576a17 100644
--- a/platforms/astbmc/witherspoon.c
+++ b/platforms/astbmc/witherspoon.c
@@ -465,6 +465,7 @@ static void npu2_phb_nvlink_dt(struct phb *npuphb)
static void witherspoon_finalise_dt(bool is_reboot)
{
struct dt_node *np;
+ struct proc_chip *c;
if (is_reboot)
return;
@@ -479,6 +480,30 @@ static void witherspoon_finalise_dt(bool is_reboot)
continue;
npu2_phb_nvlink_dt(npphb);
}
+
+ /*
+ * The I2C bus on used to talk to the GPUs has a 750K pullup
+ * which is way too big. If there's no GPUs connected to the
+ * chip all I2C transactions fail with an Arb loss error since
+ * SCL/SDA don't return to the idle state fast enough. Disable
+ * the port to squash the errors.
+ */
+ for (c = next_chip(0); c; c = next_chip(c)) {
+ bool detected = false;
+ int i;
+
+ np = dt_find_by_path(c->devnode, "i2cm@a1000/i2c-bus@4");
+ if (!np)
+ continue;
+
+ for (i = 0; i < 3; i++)
+ detected |= occ_get_gpu_presence(c, i);
+
+ if (!detected) {
+ dt_check_del_prop(np, "status");
+ dt_add_property_string(np, "status", "disabled");
+ }
+ }
}
/* The only difference between these is the PCI slot handling */