<p>Lee Leahy has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/20422">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/quark: Add I2C debugging<br><br>Add I2C debugging support:<br>* Add I2C_DEBUG Kconfig value to enable debugging<br>* Display I2C segments before the transfer<br>* Display errors that occur during the transfer<br>* Display the number of bytes transferred for successful transfers<br><br>TEST=Build and run on Galileo Gen2<br><br>Change-Id: Ia17be8b4213b13fd6c6a367d081414d0f21fbb0f<br>Signed-off-by: Lee Leahy <Leroy.P.Leahy@intel.com><br>---<br>M src/soc/intel/quark/Kconfig<br>M src/soc/intel/quark/i2c.c<br>2 files changed, 83 insertions(+), 7 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/22/20422/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/intel/quark/Kconfig b/src/soc/intel/quark/Kconfig<br>index bbb1927..d1950a3 100644<br>--- a/src/soc/intel/quark/Kconfig<br>+++ b/src/soc/intel/quark/Kconfig<br>@@ -316,4 +316,14 @@<br>    default n<br>     depends on STORAGE_TEST<br> <br>+#####<br>+# I2C debug support<br>+#####<br>+<br>+config I2C_DEBUG<br>+       bool "Enable I2C debugging"<br>+        default n<br>+    help<br>+   Display the I2C segments and controller errors<br>+<br> endif # SOC_INTEL_QUARK<br>diff --git a/src/soc/intel/quark/i2c.c b/src/soc/intel/quark/i2c.c<br>index 3988bbe..bc4451b 100644<br>--- a/src/soc/intel/quark/i2c.c<br>+++ b/src/soc/intel/quark/i2c.c<br>@@ -68,12 +68,21 @@<br>               if (status & (IC_INTR_RX_OVER | IC_INTR_RX_UNDER<br>                          | IC_INTR_TX_ABRT | IC_INTR_TX_OVER)) {<br>                       i2c_disable(regs);<br>+                   if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+                            printk(BIOS_ERR,<br>+                                     "0x%08x: ic_raw_intr_stat, I2C write error!\n",<br>+                                    status);<br>                      return -1;<br>            }<br> <br>          /* Check for timeout */<br>-              if (stopwatch_expired(timeout))<br>+              if (stopwatch_expired(timeout)) {<br>+                    if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+                            printk(BIOS_ERR,<br>+                                     "0x%08x: ic_raw_intr_stat, I2C write timeout!\n",<br>+                                  status);<br>                      return -1;<br>+           }<br> <br>          /* Receive any available data */<br>              status = regs->ic_status;<br>@@ -134,12 +143,21 @@<br>           if (status & (IC_INTR_RX_OVER | IC_INTR_RX_UNDER<br>                          | IC_INTR_TX_ABRT | IC_INTR_TX_OVER)) {<br>                       i2c_disable(regs);<br>+                   if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+                            printk(BIOS_ERR,<br>+                                     "0x%08x: ic_raw_intr_stat, I2C read error!\n",<br>+                                     status);<br>                      return -1;<br>            }<br> <br>          /* Check for timeout */<br>-              if (stopwatch_expired(timeout))<br>+              if (stopwatch_expired(timeout)) {<br>+                    if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+                            printk(BIOS_ERR,<br>+                                     "0x%08x: ic_raw_intr_stat, I2C read timeout!\n",<br>+                                   status);<br>                      return -1;<br>+           }<br> <br>          /* Receive any available data */<br>              status = regs->ic_status;<br>@@ -175,6 +193,7 @@<br>     uint8_t chip;<br>         uint32_t cmd;<br>         int data_bytes;<br>+      int index;<br>    int length;<br>   I2C_REGS *regs;<br>       uint32_t restart;<br>@@ -185,6 +204,22 @@<br>       int total_bytes;<br>      uint8_t *tx_buffer;<br>   int tx_bytes;<br>+<br>+     if (IS_ENABLED(CONFIG_I2C_DEBUG)) {<br>+          for (index = 0; index < seg_count;) {<br>+                     if (index == 0)<br>+                              printk(BIOS_ERR, "I2C Start\n");<br>+                   printk(BIOS_ERR, "I2C segment[%d]:\n", index);<br>+                     printk(BIOS_ERR, "  0x%08x: read\n",<br>+                               segment[index].read);<br>+                        printk(BIOS_ERR, "  0x%08x: chip\n",<br>+                               segment[index].chip);<br>+                        printk(BIOS_ERR, "  0x%p: buf\n", segment[index].buf);<br>+                     printk(BIOS_ERR, "  0x%08x: len\n", segment[index].len);<br>+                   printk(BIOS_ERR, "I2C %s\n",<br>+                               (++index >= seg_count) ? "Stop" : "Restart");<br>+         }<br>+    }<br> <br>  regs = get_i2c_address();<br> <br>@@ -228,7 +263,8 @@<br>     bytes_transferred = 0;<br>        rx_buffer = NULL;<br>     restart = 0;<br>- while (seg_count-- > 0) {<br>+ index = 0;<br>+   while (index++ < seg_count) {<br>              length = segment->len;<br>             total_bytes += length;<br>                ASSERT(segment->buf != NULL);<br>@@ -236,7 +272,7 @@<br>                 ASSERT(segment->chip == chip);<br> <br>          /* Determine if this is the last segment of the transaction */<br>-               stop = (seg_count == 0) ? IC_DATA_CMD_STOP : 0;<br>+              stop = (index == seg_count) ? IC_DATA_CMD_STOP : 0;<br> <br>                /* Fill the FIFO with the necessary command bytes */<br>          if (segment->read) {<br>@@ -246,8 +282,13 @@<br>                                 length, stop, &timeout);<br> <br>                       /* Return any detected error */<br>-                      if (data_bytes < 0)<br>+                       if (data_bytes < 0) {<br>+                             if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+                                    printk(BIOS_ERR,<br>+                                             "I2C segment[%d] failed\n",<br>+                                                index);<br>                               return data_bytes;<br>+                   }<br>                     bytes_transferred += data_bytes;<br>              } else {<br>                      /* Write the data into the FIFO */<br>@@ -257,8 +298,13 @@<br>                              length, stop, rx_buffer, &timeout);<br> <br>                    /* Return any detected error */<br>-                      if (data_bytes < 0)<br>+                       if (data_bytes < 0) {<br>+                             if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+                                    printk(BIOS_ERR,<br>+                                             "I2C segment[%d] failed\n",<br>+                                                index);<br>                               return data_bytes;<br>+                   }<br>                     bytes_transferred += data_bytes;<br>              }<br>             segment++;<br>@@ -284,12 +330,29 @@<br>                     if (status & (IC_INTR_RX_OVER | IC_INTR_RX_UNDER<br>                                  | IC_INTR_TX_ABRT | IC_INTR_TX_OVER)) {<br>                               i2c_disable(regs);<br>+                           if (IS_ENABLED(CONFIG_I2C_DEBUG)) {<br>+                                  printk(BIOS_ERR,<br>+                                             "0x%08x: ic_raw_intr_stat, I2C read error!\n",<br>+                                             status);<br>+                                     printk(BIOS_ERR,<br>+                                             "I2C segment[%d] failed\n",<br>+                                                seg_count - 1);<br>+                              }<br>                             return -1;<br>                    }<br> <br>                  /* Check for timeout */<br>-                      if (stopwatch_expired(&timeout))<br>+                 if (stopwatch_expired(&timeout)) {<br>+                               if (IS_ENABLED(CONFIG_I2C_DEBUG)) {<br>+                                  printk(BIOS_ERR,<br>+                                             "0x%08x: ic_raw_intr_stat, I2C read timeout!\n",<br>+                                           status);<br>+                                     printk(BIOS_ERR,<br>+                                             "I2C segment[%d] failed\n",<br>+                                                seg_count - 1);<br>+                              }<br>                             return -1;<br>+                   }<br> <br>                  /* Delay for a while */<br>                       udelay(1);<br>@@ -299,5 +362,8 @@<br>       regs->ic_tar = 0;<br> <br>       /* Return the number of bytes transferred */<br>+ if (IS_ENABLED(CONFIG_I2C_DEBUG))<br>+            printk(BIOS_ERR, "0x%08x: bytes transferred\n",<br>+                    bytes_transferred);<br>   return bytes_transferred;<br> }<br></pre><p>To view, visit <a href="https://review.coreboot.org/20422">change 20422</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/20422"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ia17be8b4213b13fd6c6a367d081414d0f21fbb0f </div>
<div style="display:none"> Gerrit-Change-Number: 20422 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Lee Leahy <leroy.p.leahy@intel.com> </div>