<p>Richard Spiegel has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/c/coreboot/+/30135">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Work in progress: Early eMMC phase 1<br><br>Global objective: Early ready of eMMC by sending CMD0 and CMD1.<br><br>This phase objective: Create bh720 driver to be used by phase 2.<br><br>BUG=b:118680303<br>TEST=<br><br>Change-Id: I9e4f356623a00bcdd75d9ee1775ebc961807696c<br>Signed-off-by: Richard Spiegel <richard.spiegel@silverbackltd.com><br>---<br>A src/drivers/emmc/README<br>A src/drivers/emmc/bh7720/Kconfig<br>A src/drivers/emmc/bh7720/Makefile.inc<br>A src/drivers/emmc/bh7720/bh720.c<br>A src/include/device/emmc/bh720.h<br>A src/include/device/emmc/emmc.h<br>6 files changed, 450 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/35/30135/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/drivers/emmc/README b/src/drivers/emmc/README</span><br><span>new file mode 100644</span><br><span>index 0000000..b95b477</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/emmc/README</span><br><span>@@ -0,0 +1,51 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Documentation for eMMC host drivers</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Silverback Ltd.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This folder has drivers for several eMMC hosts. There's a minimum set of</span><br><span style="color: hsl(120, 100%, 40%);">+commands these drivers must implement, though it can implement more:</span><br><span style="color: hsl(120, 100%, 40%);">+emmc_driver_init -> initializes all required registers of a particular host,</span><br><span style="color: hsl(120, 100%, 40%);">+                 so that commands can be send.</span><br><span style="color: hsl(120, 100%, 40%);">+emmc_send_command -> the host sends a command to the eMMC card, status is</span><br><span style="color: hsl(120, 100%, 40%);">+                    returned.</span><br><span style="color: hsl(120, 100%, 40%);">+emmc_get_ocr -> The OCR value is read.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Commands description:</span><br><span style="color: hsl(120, 100%, 40%);">+int emmc_driver_init(void *params);</span><br><span style="color: hsl(120, 100%, 40%);">+Some parameters are always the same, so they don't need to be send for code</span><br><span style="color: hsl(120, 100%, 40%);">+execution. Only parameters that are board dependent plus the base address</span><br><span style="color: hsl(120, 100%, 40%);">+should be send.</span><br><span style="color: hsl(120, 100%, 40%);">+The input is a void pointer to parameters, which is internally converted to</span><br><span style="color: hsl(120, 100%, 40%);">+a pointer to structure, defined in the chip specific header file. Inside</span><br><span style="color: hsl(120, 100%, 40%);">+this structure, the first 2 elements are common: (uint8_t) total and</span><br><span style="color: hsl(120, 100%, 40%);">+(uint16_t/uint32_t) base_address. The remaining are chip specific,.</span><br><span style="color: hsl(120, 100%, 40%);">+The return can be 0 if success, or a negative number if there's a problem.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t emmc_send_command(uint8_t command, uint32_t argument);</span><br><span style="color: hsl(120, 100%, 40%);">+Using the base address from emmc_driver_init, it sends commands to the eMMC</span><br><span style="color: hsl(120, 100%, 40%);">+and return the host status at the moment the command was issued. This is only</span><br><span style="color: hsl(120, 100%, 40%);">+for 48-bits commands (start, stop, direction,CRC77, command and argument).</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t emmc_get_ocr(uint32_t base_address);</span><br><span style="color: hsl(120, 100%, 40%);">+This function can be called before or after PCI enumeration, as it receives</span><br><span style="color: hsl(120, 100%, 40%);">+the base address to use. If the base address is IO, the upper word should</span><br><span style="color: hsl(120, 100%, 40%);">+be 0. It assumes that CMD1 was already issued, and returns the OCR received</span><br><span style="color: hsl(120, 100%, 40%);">+from the eMMC.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Generally speaking, emmc_driver_init must be used at romstage, while the</span><br><span style="color: hsl(120, 100%, 40%);">+other 2 can be romstage or ramstage, though if PCI access is needed by the</span><br><span style="color: hsl(120, 100%, 40%);">+particular chip to execute them, then they must be either romstage or have</span><br><span style="color: hsl(120, 100%, 40%);">+a device declared to be used in ramstage.</span><br><span>diff --git a/src/drivers/emmc/bh7720/Kconfig b/src/drivers/emmc/bh7720/Kconfig</span><br><span>new file mode 100644</span><br><span>index 0000000..27b5c80</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/emmc/bh7720/Kconfig</span><br><span>@@ -0,0 +1,2 @@</span><br><span style="color: hsl(120, 100%, 40%);">+config DRIVERS_EMMC_BH720</span><br><span style="color: hsl(120, 100%, 40%);">+  bool</span><br><span>diff --git a/src/drivers/emmc/bh7720/Makefile.inc b/src/drivers/emmc/bh7720/Makefile.inc</span><br><span>new file mode 100644</span><br><span>index 0000000..e282a67</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/emmc/bh7720/Makefile.inc</span><br><span>@@ -0,0 +1,2 @@</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-$(CONFIG_DRIVERS_EMMC_BH720) += bh720.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-$(CONFIG_DRIVERS_EMMC_BH720) += bh720.c</span><br><span>diff --git a/src/drivers/emmc/bh7720/bh720.c b/src/drivers/emmc/bh7720/bh720.c</span><br><span>new file mode 100644</span><br><span>index 0000000..7dbafe4</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/emmc/bh7720/bh720.c</span><br><span>@@ -0,0 +1,252 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Silverback Ltd.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <rules.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/pci_def.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/emmc/emmc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/emmc/bh720.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t *base_ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+static boolean flag = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void pci_set32(uint32_t dev, uint8_t reg, uint32_t bits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t value;</span><br><span style="color: hsl(120, 100%, 40%);">+       value = pci_read_config32(dev, reg);</span><br><span style="color: hsl(120, 100%, 40%);">+  value |= bits;</span><br><span style="color: hsl(120, 100%, 40%);">+        pci_write_config32(dev, reg, value);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void pci_clear32(uint32_t dev, uint8_t reg, uint32_t bits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t value, mask;</span><br><span style="color: hsl(120, 100%, 40%);">+ mask = ~bits;</span><br><span style="color: hsl(120, 100%, 40%);">+ value = pci_read_config32(dev, reg);</span><br><span style="color: hsl(120, 100%, 40%);">+  value &= mask;</span><br><span style="color: hsl(120, 100%, 40%);">+    pci_write_config32(dev, reg, value);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void pci_and_or32(uint32_t dev, uint8_t reg, uint32_t mask,</span><br><span style="color: hsl(120, 100%, 40%);">+                 uint32_t bits)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t value;</span><br><span style="color: hsl(120, 100%, 40%);">+       value = pci_read_config32(dev, reg);</span><br><span style="color: hsl(120, 100%, 40%);">+  value &= ~mask;</span><br><span style="color: hsl(120, 100%, 40%);">+   value |= bits;</span><br><span style="color: hsl(120, 100%, 40%);">+        pci_write_config32(dev, reg, value);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void program_base(uint32_t dev, uint32_t base)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      pci_write_config32(dev, PCI_BASE_ADDRESS_0, base);</span><br><span style="color: hsl(120, 100%, 40%);">+    pci_write_config8(dev, PCI_COMMAND,</span><br><span style="color: hsl(120, 100%, 40%);">+                           PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void clear_base(uint32_t dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_write_config8(dev, PCI_COMMAND, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint32_t host_dev_from_bridge(uint32_t dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t byte;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       byte = pci_read_config8(dev, PCI_SECONDARY_BUS);</span><br><span style="color: hsl(120, 100%, 40%);">+      return PCI_DEV(byte, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int program_bridge(uint32_t dev, uintptr_t base), uint32_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t value, limit, h_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t byte = pci_read_config8(dev, PCI_HEADER_TYPE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if ((byte & 0x7f) != PCI_HEADER_TYPE_BRIDGE)</span><br><span style="color: hsl(120, 100%, 40%);">+              return EMMC_STATUS_INVALID_PCI;</span><br><span style="color: hsl(120, 100%, 40%);">+       byte = pci_read_config8(dev, PCI_COMMAND);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* If not initialized, program bridge and device */</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((byte & 0x0f) != (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Before enumeration, primary bus 0, secondary bus 1 */</span><br><span style="color: hsl(120, 100%, 40%);">+              pci_write_config32(dev, PCI_PRIMARY_BUS, 0x00010100);</span><br><span style="color: hsl(120, 100%, 40%);">+         limit = TEMP_BASE + (TEMP_SIZE - 1);</span><br><span style="color: hsl(120, 100%, 40%);">+          limit &= 0xffff0000;</span><br><span style="color: hsl(120, 100%, 40%);">+              value = (TEMP_BASE >> 16) & 0xffff;</span><br><span style="color: hsl(120, 100%, 40%);">+         value |= limit;</span><br><span style="color: hsl(120, 100%, 40%);">+               pci_write_config32(dev, PCI_MEMORY_BASE, value);</span><br><span style="color: hsl(120, 100%, 40%);">+              pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MASTER |</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  PCI_COMMAND_MEMORY);</span><br><span style="color: hsl(120, 100%, 40%);">+              h_dev = PCI_DEV(1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+             program_base(h_dev, TEMP_BASE);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     return EMMC_STATUS_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void clear_bridge(uint32_t dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   pci_write_config8(dev, PCI_COMMAND, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_write_config32(dev, PCI_PRIMARY_BUS, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  pci_write_config32(dev, PCI_MEMORY_BASE, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void program_id(uint32_t dev, uint32_t id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_clear32(dev, BH720_PROTECT, BH720_PROTECT_ON);</span><br><span style="color: hsl(120, 100%, 40%);">+    pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, id);</span><br><span style="color: hsl(120, 100%, 40%);">+ pci_set32(dev, BH720_PROTECT, BH720_PROTECT_ON);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int read_base(uint32_t dev, uint32_t id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t emmc_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+    int status;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ status = program_bridge(dev, (uint32_t)base_ptr, TEMP_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (status != EMMC_STATUS_SUCCESS)</span><br><span style="color: hsl(120, 100%, 40%);">+            return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        emmc_dev = host_dev_from_bridge(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+ base_ptr = (uint8_t *)pci_read_config32(emmc_dev, PCI_BASE_ADDRESS_0);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (id)</span><br><span style="color: hsl(120, 100%, 40%);">+               program_id(emmc_dev, id);</span><br><span style="color: hsl(120, 100%, 40%);">+     return EMMC_STATUS_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int emmc_driver_init(void *params)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       bh720_params *param = (bh720_params *)params;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t temp;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t device = param->pci_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t subsys_id = param->subsys_vend_dev_id;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t total = param->total</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t mode = DEFAUT_MODE;</span><br><span style="color: hsl(120, 100%, 40%);">+   int status = EMMC_STATUS_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   base_ptr = (uint8_t *)param->base_address;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (total > 4)</span><br><span style="color: hsl(120, 100%, 40%);">+             mode = param->mode;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (total == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               return EMMC_STATUS_INVALID_PARAM;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (total == 1)</span><br><span style="color: hsl(120, 100%, 40%);">+               return read_base(device, subsys_id);</span><br><span style="color: hsl(120, 100%, 40%);">+  if ((total == 2) || (total == 3)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (base_ptr == NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+                 return EMMC_STATUS_INVALID_PARAM;</span><br><span style="color: hsl(120, 100%, 40%);">+             return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (subsys_id && (mode & MODE_VEND_DEV))</span><br><span style="color: hsl(120, 100%, 40%);">+          program_id(device, subsys_id);</span><br><span style="color: hsl(120, 100%, 40%);">+/* If romstage, no other action is allowed. */</span><br><span style="color: hsl(120, 100%, 40%);">+#if defined(__SIMPLE_DEVICE__)</span><br><span style="color: hsl(120, 100%, 40%);">+        if (mode > MODE_VEND_DEV)</span><br><span style="color: hsl(120, 100%, 40%);">+          return EMMC_STATUS_INVALID_STAGE;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+     pci_clear32(dev, BH720_PROTECT, BH720_PROTECT_ON);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (mode & MODE_DIS_SD) {</span><br><span style="color: hsl(120, 100%, 40%);">+         pci_and_or32(dev, BH720_PML1_TIMER,</span><br><span style="color: hsl(120, 100%, 40%);">+                        BH720_PML1_TIMER_MASK, BH720_PML1_TIMER_16US);</span><br><span style="color: hsl(120, 100%, 40%);">+           pci_set_32(dev, BH720_RTD3_L1, BH720_RTD3_L1_DISABLE_L1);</span><br><span style="color: hsl(120, 100%, 40%);">+             pci_set_32(dev, BH720_LINK_CTRL, BH720_LINK_CTRL_L0_ENABLE |</span><br><span style="color: hsl(120, 100%, 40%);">+                                           BH720_LINK_CTRL_L1_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+          pci_set_32(dev, BH720_LINK_CTRL, BH720_LINK_CTRL_CLKREQ);</span><br><span style="color: hsl(120, 100%, 40%);">+             pci_clear32(dev, BH720_ENABLES, BH_720_SD_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (mode & MODE_VCCQ_18)</span><br><span style="color: hsl(120, 100%, 40%);">+          pci_set_32(dev, BH720_PCR_EMMC_SETTING,</span><br><span style="color: hsl(120, 100%, 40%);">+                                               BH720_PCR_EMMC_SETTING_1_8V};</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mode & MODE_POWER_SAVE) {</span><br><span style="color: hsl(120, 100%, 40%);">+             pci_set_32(dev, BH720_RTD3_L1, BH720_RTD3_L1_DISABLE_L1);</span><br><span style="color: hsl(120, 100%, 40%);">+             pci_set_32(dev, BH720_LINK_CTRL, BH720_LINK_CTRL_L0_ENABLE |</span><br><span style="color: hsl(120, 100%, 40%);">+                                           BH720_LINK_CTRL_L1_ENABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+          pci_set_32(dev, BH720_LINK_CTRL, BH720_LINK_CTRL_CLKREQ);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (mode & MODE_L1_TIMER) {</span><br><span style="color: hsl(120, 100%, 40%);">+               pci_and_or32(dev, BH720_PML1_TIMER,</span><br><span style="color: hsl(120, 100%, 40%);">+                        BH720_PML1_TIMER_MASK, BH720_PML1_TIMER_16US);</span><br><span style="color: hsl(120, 100%, 40%);">+           pci_and_or32(dev, BH720_ASPM_TIMERS,</span><br><span style="color: hsl(120, 100%, 40%);">+                       BH720_L1_ENTRANCE_TIMER_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+                         BH720_L1_ENTRANCE_TIMER_512US);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (mode & MODE_IDDQ)</span><br><span style="color: hsl(120, 100%, 40%);">+             pci_set_32(dev, BH720_PCR_CSR, BH720_PCR_CSR__IDD_SEL);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (mode & MODE_TUNING)</span><br><span style="color: hsl(120, 100%, 40%);">+           pci_and_or32(dev, BH720_TUNING,</span><br><span style="color: hsl(120, 100%, 40%);">+                            BH720_TUNING_HS200_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+                      5 << BH720_TUNING_HS200_SHIFT);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (mode & MODE_DLL_CLK_PHASE)</span><br><span style="color: hsl(120, 100%, 40%);">+            pci_and_or32(dev, BH720_TUNING,</span><br><span style="color: hsl(120, 100%, 40%);">+                            BH720_TUNING_SAMPLE_CLK_MASK,</span><br><span style="color: hsl(120, 100%, 40%);">+                         6 << BH720_TUNING_SAMPLE_CLK_SHIFT);</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_set32(dev, BH720_PROTECT, BH720_PROTECT_ON);</span><br><span style="color: hsl(120, 100%, 40%);">+      return status;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t emmc_send_command(uint8_t command, uint32_t argument)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t *arg_ptr = (uint32_t *)base_ptr + 8;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t *resp_ptr = (uint32_t *)base_ptr + 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint16_t *cmd_ptr = (uint16_t *)base_ptr + 0x0e;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint16_t cmd = (command & 0x3f) << 8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     cmd |= 0x1a; /* check index and CRC, 48 bits. */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (command == 1)</span><br><span style="color: hsl(120, 100%, 40%);">+             cmd++; /* 48 bits with busy */</span><br><span style="color: hsl(120, 100%, 40%);">+        *arg_ptr = argument;</span><br><span style="color: hsl(120, 100%, 40%);">+  *cmd_ptr = cmd; /* send command */</span><br><span style="color: hsl(120, 100%, 40%);">+    udelay(5)</span><br><span style="color: hsl(120, 100%, 40%);">+     return *resp_ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Todo: need to understand if there's status for CMD1 or just OCR */</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t emmc_get_ocr(uint32_t base_address)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint32_t *ocr_ptr = (uint32_t *)base_address + 0x10;</span><br><span style="color: hsl(120, 100%, 40%);">+  return *ocr_ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * If initialized with total = 1 before PCI initialization (program base</span><br><span style="color: hsl(120, 100%, 40%);">+ * address with temporary value, then use this at the end, before PCI</span><br><span style="color: hsl(120, 100%, 40%);">+ * enumeration.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int release_base(uint32_t dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t host;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t byte = pci_read_config8(dev, PCI_HEADER_TYPE);</span><br><span style="color: hsl(120, 100%, 40%);">+        if ((byte & 0x7f) != PCI_HEADER_TYPE_BRIDGE)</span><br><span style="color: hsl(120, 100%, 40%);">+              return EMMC_STATUS_INVALID_PCI;</span><br><span style="color: hsl(120, 100%, 40%);">+       host = host_dev_from_bridge(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+     clear_base(host);</span><br><span style="color: hsl(120, 100%, 40%);">+     clear_bridge(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * If used temporary base before PCI enumeration, use this function to update</span><br><span style="color: hsl(120, 100%, 40%);">+ * eMMC base address, based on actual PCI enumeration.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int update_base(uint32_t dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t emmc_dev, base;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t byte = pci_read_config8(dev, PCI_HEADER_TYPE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if ((byte & 0x7f) != PCI_HEADER_TYPE_BRIDGE)</span><br><span style="color: hsl(120, 100%, 40%);">+              return EMMC_STATUS_INVALID_PCI;</span><br><span style="color: hsl(120, 100%, 40%);">+       emmc_dev = host_dev_from_bridge(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+ base = (0xffff & pci_read_config32(dev, PCI_MEMORY_BASE));</span><br><span style="color: hsl(120, 100%, 40%);">+        base_ptr = (uint8_t *)(base << 16);</span><br><span style="color: hsl(120, 100%, 40%);">+     program_base(emmc_dev, base << 16);</span><br><span style="color: hsl(120, 100%, 40%);">+     return EMMC_STATUS_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/include/device/emmc/bh720.h b/src/include/device/emmc/bh720.h</span><br><span>new file mode 100644</span><br><span>index 0000000..3715d0b</span><br><span>--- /dev/null</span><br><span>+++ b/src/include/device/emmc/bh720.h</span><br><span>@@ -0,0 +1,102 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Silverback Ltd.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __BH720_H__</span><br><span style="color: hsl(120, 100%, 40%);">+#define __BH720_H__</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct bh720_params {</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t total;                  /* Note 1 */</span><br><span style="color: hsl(120, 100%, 40%);">+  uintptr_t base_address;         /* memory address */</span><br><span style="color: hsl(120, 100%, 40%);">+  uint32_t pci_dev;               /* PCI_DEV(bus, slot, func) */</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t subsys_vend_dev_id;    /* if 0 or total = 3, do not set */</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t mode;                   /* optional, note 2 */</span><br><span style="color: hsl(120, 100%, 40%);">+};      /* total 5 parameters, so if all parameters, total = 5 */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note 1: The value of total shold be between 3 and 5, so use value of 1 for:</span><br><span style="color: hsl(120, 100%, 40%);">+ *   A) pci_dev is relative to the bridge the host resides.</span><br><span style="color: hsl(120, 100%, 40%);">+ *   B) If the bridge has not been programmed, then program the BAR with base</span><br><span style="color: hsl(120, 100%, 40%);">+ *      adress.</span><br><span style="color: hsl(120, 100%, 40%);">+ *   C) If bridge is programmed, then read BAR0 into base_address.</span><br><span style="color: hsl(120, 100%, 40%);">+ *   D) If subsys_vend_dev_id is provided and (B) than program subsystem vendor</span><br><span style="color: hsl(120, 100%, 40%);">+ *      and device IDs.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note 2: MODE_DIS_SD, MODE_VCCQ_18, MODE_POWER_SAVE, MODE_IDDQ, MODE_TUNNING,</span><br><span style="color: hsl(120, 100%, 40%);">+ * MODE_DLL_CLK_PHASE can only be set in ramstage, with a BH720 device defined,</span><br><span style="color: hsl(120, 100%, 40%);">+ * because they access PCI config space above 0xff.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_LINK_CTRL                 0x90</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_LINK_CTRL_L0_ENABLE     BIT(0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_LINK_CTRL_L1_ENABLE     BIT(1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_LINK_CTRL_CLKREQ        BIT(8)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_PROTECT                   0xd0</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PROTECT_LOCK_ON         BIT(0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PROTECT_ON              BIT(31)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_ENABLES                   0xdc</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH_720_SD_ENABLE              BIT(0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_PML1_TIMER         0xe0</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PML1_TIMER_SHIFT  28</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PML1_TIMER_MASK         (0xf << BH720_PML1_TIMER_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PML1_TIMER_16US         (0x3 << BH720_PML1_TIMER_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_MISC2                     0xf0</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_MISC2_ASPM_DISABLE      BIT(0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_MISC2_APSM_CLKREQ_L1    BIT(7)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_MISC2_APSM_PHY_L1       BIT(10)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_MISC2_APSM_MORE         BIT(12)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_ASPM_TIMERS               0xfc</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_L1_ENTR_TIMER_SHIFT     16</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_L1_ENTRANCE_TIMER_MASK  (0xf << BH720_L1_ENTR_TIMER_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_L1_ENTRANCE_TIMER_512US (0x1000 << BH720_L1_ENTR_TIMER_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_MEM_RW_DATA               0x200</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_MEM_RW_ADR                0x204</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_MEM_RW_READ             BIT(30)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_MEM_RW_WRITE            BIT(31)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_MEM_ACCESS_EN             0x208</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_TUNING                    0x300</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_TUNING_HS200_SHIFT      4</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_TUNING_HS200_MASK       (0xf << BH720_TUNING_HS200_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_TUNING_SAMPLE_CLK_SHIFT 12</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_TUNING_SAMPLE_CLK_MASK  (0xf << BH720_TUNING_SAMPLE_CLK_SHIFT)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_PCR_DRV_STRENGHT_PLL      0x304</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PCR_DATA_CMD_DRV_MAX    7</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PCR_CLK_DRV_MAX         7</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_PCR_EMMC_SETTING          0x308</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PCR_EMMC_SETTING_1_8V   BIT(4)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_RTD3_L1                   0x3e0</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_RTD3_L1_DISABLE_L1      BIT(28)</span><br><span style="color: hsl(120, 100%, 40%);">+#define BH720_PCR_CSR                   0x3e4</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PCR_CSR__IDD_SEL        BIT(19)</span><br><span style="color: hsl(120, 100%, 40%);">+#define   BH720_PCR_CSR_EMMC_MODE_SEL   BIT(22)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TEMP_BASE                 0xf4a00000</span><br><span style="color: hsl(120, 100%, 40%);">+#define TEMP_SIZE                   0x1000</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_VEND_DEV                 BIT(0)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_DIS_SD                     BIT(1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_VCCQ_18                    BIT(2)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_POWER_SAVE                 BIT(3)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_L1_TIMER                   BIT(4)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_IDDQ                       BIT(5)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_TUNING                     BIT(6)</span><br><span style="color: hsl(120, 100%, 40%);">+#define MODE_DLL_CLK_PHASE              BIT(7)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define DEFAUT_MODE                   MODE_VEND_DEV</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Input is bridge device/func */</span><br><span style="color: hsl(120, 100%, 40%);">+int release_base(uint32_t dev);</span><br><span style="color: hsl(120, 100%, 40%);">+int update_base(uint32_t dev);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span>diff --git a/src/include/device/emmc/emmc.h b/src/include/device/emmc/emmc.h</span><br><span>new file mode 100644</span><br><span>index 0000000..0826f53</span><br><span>--- /dev/null</span><br><span>+++ b/src/include/device/emmc/emmc.h</span><br><span>@@ -0,0 +1,41 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Silverback Ltd.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef __EMMC_H__</span><br><span style="color: hsl(120, 100%, 40%);">+#define __EMMC_H__</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_PARAM_BYTE                         1</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_PARAM_WORD                      2</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_PARAM_DWORD             3</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_PARAM_QWORD             4</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_PARAM_PCI_DEV           5</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_SUCCESS                0</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_INVALID_PARAM   -1</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_NO_BASE_ADDRESS -2 /* drive not initialized */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_INVALID_BASE_ADDR   -3 /* invalid base size */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_INVALID_PCI             -4 /* invalid pci */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_HOST_BUSY             -5 /* bit 31 of OCR 0b */</span><br><span style="color: hsl(120, 100%, 40%);">+#define EMMC_STATUS_INVALID_STAGE    -6 /* PCI reg > 0xff in romstage */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int emmc_driver_init(void *params);</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t emmc_send_command(uint8_t command, uint32_t argument);</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t emmc_get_ocr(uint32_t base_address);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int emmc_go_idle(void);</span><br><span style="color: hsl(120, 100%, 40%);">+int emmc_go_ready(uint32_t argument); /* CMD1 argument depends on board/host */</span><br><span style="color: hsl(120, 100%, 40%);">+int emmc_check_ready{uint32_t *ocr, uint32_t base_address);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/c/coreboot/+/30135">change 30135</a>. To unsubscribe, or for help writing mail filters, 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/c/coreboot/+/30135"/><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-Change-Id: I9e4f356623a00bcdd75d9ee1775ebc961807696c </div>
<div style="display:none"> Gerrit-Change-Number: 30135 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Spiegel <richard.spiegel@silverbackltd.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>