summaryrefslogtreecommitdiffstats
path: root/meta-phosphor
diff options
context:
space:
mode:
authorChristopher Bostic <cbostic@linux.vnet.ibm.com>2017-03-24 16:14:04 -0500
committerPatrick Williams <patrick@stwcx.xyz>2017-03-27 15:38:59 +0000
commit3a2a5866513cb9fea73bd6a2cb9043c7d8d4586d (patch)
treed22cddab6790c7e8455aca011777088c3085bd08 /meta-phosphor
parent1ddd805657ea2336826395f11847a3fba36050a4 (diff)
downloadtalos-openbmc-3a2a5866513cb9fea73bd6a2cb9043c7d8d4586d.tar.gz
talos-openbmc-3a2a5866513cb9fea73bd6a2cb9043c7d8d4586d.zip
Fix for Hostboot load OpenFSI SDA sampling
The delay between OpenFSI clock and input data sampling needs to be increased in order to ensure the data is read in at the correct time. Christopher Bostic (1): drivers/fsi: Increase delay before sampling input on SDA Change-Id: I75812439ad6fd7b9527a6c42a282110fced6bbad Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
Diffstat (limited to 'meta-phosphor')
-rw-r--r--meta-phosphor/common/recipes-kernel/linux/linux-obmc.inc3
-rw-r--r--meta-phosphor/common/recipes-kernel/linux/linux-obmc/v3-0001-drivers-fsi-Increase-delay-before-sampling-input-.patch195
2 files changed, 198 insertions, 0 deletions
diff --git a/meta-phosphor/common/recipes-kernel/linux/linux-obmc.inc b/meta-phosphor/common/recipes-kernel/linux/linux-obmc.inc
index 24db6f784..fc4a4f9c5 100644
--- a/meta-phosphor/common/recipes-kernel/linux/linux-obmc.inc
+++ b/meta-phosphor/common/recipes-kernel/linux/linux-obmc.inc
@@ -4,8 +4,11 @@ LICENSE = "GPLv2"
KCONFIG_MODE="--alldefconfig"
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
KSRC ?= "git://github.com/openbmc/linux;protocol=git;branch=${KBRANCH}"
SRC_URI = "${KSRC}"
+SRC_URI += "file://v3-0001-drivers-fsi-Increase-delay-before-sampling-input-.patch"
LINUX_VERSION_EXTENSION ?= "-${SRCREV}"
diff --git a/meta-phosphor/common/recipes-kernel/linux/linux-obmc/v3-0001-drivers-fsi-Increase-delay-before-sampling-input-.patch b/meta-phosphor/common/recipes-kernel/linux/linux-obmc/v3-0001-drivers-fsi-Increase-delay-before-sampling-input-.patch
new file mode 100644
index 000000000..affb74592
--- /dev/null
+++ b/meta-phosphor/common/recipes-kernel/linux/linux-obmc/v3-0001-drivers-fsi-Increase-delay-before-sampling-input-.patch
@@ -0,0 +1,195 @@
+From d100e52bdaef13d3f9aab162719919f660111479 Mon Sep 17 00:00:00 2001
+From: Christopher Bostic <cbostic@linux.vnet.ibm.com>
+Date: Fri, 17 Mar 2017 16:00:48 -0500
+Subject: [PATCH linux dev-4.7 v3] drivers/fsi: Increase delay before sampling
+ input on SDA
+To: joel@jms.id.au
+Cc: openbmc@lists.ozlabs.org
+
+During high cpu loads the SDA in line can shift relative to the
+clock signal which can corrupt the received input data. Slow
+down the time to sample input to account for this.
+
+Add sysfs files to adjust the three main openfsi protocol timing
+values: clock delay; sample delay; clock off time.
+
+Signed-off-by: Christopher Bostic <cbostic@linux.vnet.ibm.com>
+---
+v3 - Add sysfs files to adjust protocol timings
+
+v2 - Increase delay for SDA in sampling only.
+
+ - Decrease the original delay for SDA sampling from 1us to 200ns
+---
+ drivers/fsi/fsi-master-gpio.c | 107 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 103 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c
+index a8976d5..0907977 100644
+--- a/drivers/fsi/fsi-master-gpio.c
++++ b/drivers/fsi/fsi-master-gpio.c
+@@ -14,6 +14,7 @@
+ #include "fsi-master.h"
+
+ #define FSI_GPIO_STD_DLY 1 /* Standard pin delay in nS */
++#define FSI_GPIO_SDA_IN_DLY 200 /* Wait to sample SDA line, in nS */
+ #define FSI_ECHO_DELAY_CLOCKS 16 /* Number clocks for echo delay */
+ #define FSI_PRE_BREAK_CLOCKS 50 /* Number clocks to prep for break */
+ #define FSI_BREAK_CLOCKS 256 /* Number of clocks to issue break */
+@@ -65,6 +66,10 @@
+
+ static DEFINE_SPINLOCK(fsi_gpio_cmd_lock); /* lock around fsi commands */
+
++static int clock_delay = FSI_GPIO_STD_DLY;
++static int clock_off_time = FSI_GPIO_STD_DLY;
++static int sample_delay = FSI_GPIO_SDA_IN_DLY;
++
+ struct fsi_master_gpio {
+ struct fsi_master master;
+ struct gpio_desc *gpio_clk;
+@@ -86,9 +91,11 @@ static void clock_toggle(struct fsi_master_gpio *master, int count)
+ int i;
+
+ for (i = 0; i < count; i++) {
+- ndelay(FSI_GPIO_STD_DLY);
++ udelay(clock_delay / 1000);
++ ndelay(clock_delay % 1000);
+ gpiod_set_value(master->gpio_clk, 0);
+- ndelay(FSI_GPIO_STD_DLY);
++ udelay(clock_off_time / 1000);
++ ndelay(clock_off_time % 1000);
+ gpiod_set_value(master->gpio_clk, 1);
+ }
+ }
+@@ -97,7 +104,8 @@ static int sda_in(struct fsi_master_gpio *master)
+ {
+ int in;
+
+- ndelay(FSI_GPIO_STD_DLY);
++ udelay(sample_delay / 1000);
++ ndelay(sample_delay % 1000);
+ in = gpiod_get_value(master->gpio_data);
+ return in ? 1 : 0;
+ }
+@@ -497,10 +505,77 @@ static ssize_t store_scan(struct device *dev,
+
+ static DEVICE_ATTR(scan, 0200, NULL, store_scan);
+
++static ssize_t clock_delay_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return snprintf(buf, PAGE_SIZE - 1, "%u\n", clock_delay);
++}
++
++static ssize_t clock_delay_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ int rc;
++ unsigned long val = 0;
++
++ rc = kstrtoul(buf, 0, &val);
++ clock_delay = val;
++
++ return count;
++}
++
++DEVICE_ATTR(clock_delay, S_IRUGO | S_IWUSR, clock_delay_show,
++ clock_delay_store);
++
++static ssize_t clock_off_time_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return snprintf(buf, PAGE_SIZE - 1, "%u\n", clock_off_time);
++}
++
++static ssize_t clock_off_time_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ int rc;
++ unsigned long val = 0;
++
++ rc = kstrtoul(buf, 0, &val);
++ clock_off_time = val;
++
++ return count;
++}
++
++DEVICE_ATTR(clock_off_time, S_IRUGO | S_IWUSR, clock_off_time_show,
++ clock_off_time_store);
++
++static ssize_t sample_delay_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return snprintf(buf, PAGE_SIZE - 1, "%u\n", sample_delay);
++}
++
++static ssize_t sample_delay_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ int rc;
++ unsigned long val = 0;
++
++ rc = kstrtoul(buf, 0, &val);
++ sample_delay = val;
++
++ return count;
++}
++
++DEVICE_ATTR(sample_delay, S_IRUGO | S_IWUSR, sample_delay_show,
++ sample_delay_store);
++
+ static int fsi_master_gpio_probe(struct platform_device *pdev)
+ {
+ struct fsi_master_gpio *master;
+ struct gpio_desc *gpio;
++ int rc;
+
+ master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
+ if (!master)
+@@ -548,8 +623,29 @@ static int fsi_master_gpio_probe(struct platform_device *pdev)
+ master->master.send_break = fsi_master_gpio_break;
+ master->master.link_enable = fsi_master_gpio_link_enable;
+ platform_set_drvdata(pdev, master);
++ rc = device_create_file(&pdev->dev, &dev_attr_clock_off_time);
++ if (rc)
++ goto done;
++ rc = device_create_file(&pdev->dev, &dev_attr_clock_delay);
++ if (rc)
++ goto rem_clock_off;
++ rc = device_create_file(&pdev->dev, &dev_attr_sample_delay);
++ if (rc)
++ goto rem_clock_delay;
++ rc = device_create_file(&pdev->dev, &dev_attr_scan);
++ if (rc)
++ goto rem_sample_delay;
+
+- return device_create_file(&pdev->dev, &dev_attr_scan);
++ return rc;
++
++rem_sample_delay:
++ device_remove_file(&pdev->dev, &dev_attr_sample_delay);
++rem_clock_delay:
++ device_remove_file(&pdev->dev, &dev_attr_clock_delay);
++rem_clock_off:
++ device_remove_file(&pdev->dev, &dev_attr_clock_off_time);
++done:
++ return rc;
+ }
+
+
+@@ -576,6 +672,9 @@ static int fsi_master_gpio_remove(struct platform_device *pdev)
+ devm_gpiod_put(&pdev->dev, master->gpio_mux);
+ }
+ fsi_master_unregister(&master->master);
++ device_remove_file(&pdev->dev, &dev_attr_clock_off_time);
++ device_remove_file(&pdev->dev, &dev_attr_clock_delay);
++ device_remove_file(&pdev->dev, &dev_attr_sample_delay);
+ device_remove_file(&pdev->dev, &dev_attr_scan);
+
+ return 0;
+--
+1.8.2.2
+
OpenPOWER on IntegriCloud