Hung-Te Lin ([email protected]) just uploaded a new patch set to gerrit, 
which you can find at http://review.coreboot.org/2229

-gerrit

commit f2996b87dc49f7b9f37c758b751f510ae1e99a10
Author: Hung-Te Lin <[email protected]>
Date:   Wed Jan 30 20:02:02 2013 +0800

    armv7: Add SPI driver for Exynos.
    
    The SPI flash driver for Exynos chipset.
    
    Verified to boot on snow/armv7.
    
    Change-Id: I7eef67a9c57f825d09f13ea44c2b59b54345fa7b
    Signed-off-by: Hung-Te Lin <[email protected]>
---
 src/cpu/samsung/exynos5-common/spi.c  | 245 ++++++++++++++++++++++++++++++++-
 src/cpu/samsung/exynos5-common/spi.h  |  13 ++
 src/mainboard/google/snow/bootblock.c | 251 +---------------------------------
 3 files changed, 260 insertions(+), 249 deletions(-)

diff --git a/src/cpu/samsung/exynos5-common/spi.c 
b/src/cpu/samsung/exynos5-common/spi.c
index e13eadf..c4a3285 100644
--- a/src/cpu/samsung/exynos5-common/spi.c
+++ b/src/cpu/samsung/exynos5-common/spi.c
@@ -1,7 +1,246 @@
-#include <cbfs.h>
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ * Copyright (C) 2013 The Chromium OS Authors. All rights reserved.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
 
-/* TODO provide a real SPI driver here for firmware media. */
+/* FIXME(dhendrix): pulled in a lot of extra crap such as partition and string
+   libs*/
+#include <assert.h>
+#include <common.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <console/console.h>
+#include <console/loglevel.h>
+
+#include <config.h>
+#include <spi.h>
+
+#include <cpu/samsung/exynos5250/gpio.h>
+#include <cpu/samsung/exynos5250/clk.h>
+#include <cpu/samsung/exynos5250/cpu.h>
+#include <cpu/samsung/exynos5250/periph.h>
+#include <cpu/samsung/exynos5250/pinmux.h>
+
+#include <cpu/samsung/exynos5-common/cpu.h>
+#include <cpu/samsung/exynos5-common/exynos5-common.h>
+#include <cpu/samsung/exynos5-common/spi.h>
+
+#include <system.h>
+#include <arch/io.h>
+#include <lib.h>
+
+#define OM_STAT                (0x1f << 1)
+#define EXYNOS_BASE_SPI1 ((void *)0x12d30000)
+
+static void exynos_spi_rx_tx(struct exynos_spi *regs, int todo,
+                            void *dinp, void const *doutp, int i)
+{
+       int rx_lvl, tx_lvl;
+       uint *rxp = (uint *)(dinp + (i * (32 * 1024)));
+       uint out_bytes, in_bytes;
+
+       // In currrent implementation, every read/write must be aligned to 4
+       // bytes.
+       assert(todo % 4 == 0);
+
+       out_bytes = in_bytes = todo;
+       setbits_le32(&regs->ch_cfg, SPI_CH_RST);
+       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+       writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
+
+       while (in_bytes) {
+               uint32_t spi_sts;
+               int temp;
+
+               spi_sts = readl(&regs->spi_sts);
+               rx_lvl = ((spi_sts >> 15) & 0x7f);
+               tx_lvl = ((spi_sts >> 6) & 0x7f);
+               while (tx_lvl < 32 && out_bytes) {
+                       temp = 0xffffffff;
+                       writel(temp, &regs->tx_data);
+                       out_bytes -= 4;
+                       tx_lvl += 4;
+               }
+               while (rx_lvl >= 4 && in_bytes) {
+                       temp = readl(&regs->rx_data);
+                       if (rxp)
+                               *rxp++ = temp;
+                       in_bytes -= 4;
+                       rx_lvl -= 4;
+               }
+       }
+}
+
+int exynos_spi_open(struct exynos_spi *regs)
+{
+       clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
+       /* set the spi1 GPIO */
+
+       // TODO Some of these should be done in board's bootblock file.
+       // We should fix-up the mainboard-specific vs. exynos-specific parts in 
a
+       // follow-up CL.
+
+//     exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
+       gpio_cfg_pin(GPIO_A24, 0x2);
+       gpio_cfg_pin(GPIO_A25, 0x2);
+       gpio_cfg_pin(GPIO_A26, 0x2);
+       gpio_cfg_pin(GPIO_A27, 0x2);
+
+       /* set pktcnt and enable it */
+       writel(4 | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
+       /* set FB_CLK_SEL */
+       writel(SPI_FB_DELAY_180, &regs->fb_clk);
+       /* set CH_WIDTH and BUS_WIDTH as word */
+       setbits_le32(&regs->mode_cfg,
+                    SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
+       clrbits_le32(&regs->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
+
+       /* clear rx and tx channel if set priveously */
+       clrbits_le32(&regs->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
+
+       setbits_le32(&regs->swap_cfg,
+                    SPI_RX_SWAP_EN | SPI_RX_BYTE_SWAP | SPI_RX_HWORD_SWAP);
+
+       /* do a soft reset */
+       setbits_le32(&regs->ch_cfg, SPI_CH_RST);
+       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+
+       /* now set rx and tx channel ON */
+       setbits_le32(&regs->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
+       clrbits_le32(&regs->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
+       return 0;
+}
+
+int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off)
+{
+       int upto, todo;
+       int i;
+       /* Send read instruction (0x3h) followed by a 24 bit addr */
+       writel((SF_READ_DATA_CMD << 24) | off, &regs->tx_data);
+
+       /* waiting for TX done */
+       while (!(readl(&regs->spi_sts) & SPI_ST_TX_DONE));
+
+       for (upto = 0, i = 0; upto < len; upto += todo, i++) {
+               todo = MIN(len - upto, (1 << 15));
+               exynos_spi_rx_tx(regs, todo, dest, (void *)(off), i);
+       }
+
+       setbits_le32(&regs->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
+
+       /*
+        * Let put controller mode to BYTE as
+        * SPI driver does not support WORD mode yet
+        */
+       clrbits_le32(&regs->mode_cfg,
+                    SPI_MODE_CH_WIDTH_WORD | SPI_MODE_BUS_WIDTH_WORD);
+       writel(0, &regs->swap_cfg);
+
+       return len;
+}
+
+int exynos_spi_close(struct exynos_spi *regs)
+{
+       /*
+        * Flush spi tx, rx fifos and reset the SPI controller
+        * and clear rx/tx channel
+        */
+       clrsetbits_le32(&regs->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
+       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
+       clrbits_le32(&regs->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
+       return 0;
+}
+
+// SPI as CBFS media.
+struct exynos_spi_media {
+       struct exynos_spi *regs;
+       struct cbfs_simple_buffer buffer;
+};
+
+static int exynos_spi_cbfs_open(struct cbfs_media *media) {
+       struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+       printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_open\n");
+       return exynos_spi_open(spi->regs);
+}
+
+static int exynos_spi_cbfs_close(struct cbfs_media *media) {
+       struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+       printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_close\n");
+       return exynos_spi_close(spi->regs);
+}
+
+static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest,
+                                  size_t offset, size_t count) {
+       struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+       int bytes;
+       printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_read(%u)\n", count);
+       bytes = exynos_spi_read(spi->regs, dest, count, offset);
+       // Flush and re-open the device.
+       exynos_spi_close(spi->regs);
+       exynos_spi_open(spi->regs);
+       return bytes;
+}
+
+static void *exynos_spi_cbfs_map(struct cbfs_media *media, size_t offset,
+                                size_t count) {
+       struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+       printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_map\n");
+       // See exynos_spi_rx_tx for I/O alignment limitation.
+       if (count % 4)
+               count += 4 - (count % 4);
+       return cbfs_simple_buffer_map(&spi->buffer, media, offset, count);
+}
+
+static void *exynos_spi_cbfs_unmap(struct cbfs_media *media,
+                                  const void *address) {
+       struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context;
+       printk(BIOS_SPEW, "SPI: exynos_spi_cbfs_unmap\n");
+       return cbfs_simple_buffer_unmap(&spi->buffer, address);
+}
+
+int initialize_exynos_spi_cbfs_media(struct cbfs_media *media,
+                                    void *buffer_address,
+                                    size_t buffer_size) {
+       // TODO Replace static variable to support multiple streams.
+       static struct exynos_spi_media context;
+       printk(BIOS_SPEW, "SPI: initialize_exynos_spi_cbfs_media\n");
+
+       context.regs = EXYNOS_BASE_SPI1;
+       context.buffer.allocated = context.buffer.last_allocate = 0;
+       context.buffer.buffer = buffer_address;
+       context.buffer.size = buffer_size;
+       media->context = (void*)&context;
+       media->open = exynos_spi_cbfs_open;
+       media->close = exynos_spi_cbfs_close;
+       media->read = exynos_spi_cbfs_read;
+       media->map = exynos_spi_cbfs_map;
+       media->unmap = exynos_spi_cbfs_unmap;
+
+       return 0;
+}
 
 int init_default_cbfs_media(struct cbfs_media *media) {
-       return -1;
+       return initialize_exynos_spi_cbfs_media(
+                       media,
+                       (void*)CONFIG_CBFS_CACHE_ADDRESS,
+                       CONFIG_CBFS_CACHE_SIZE);
 }
diff --git a/src/cpu/samsung/exynos5-common/spi.h 
b/src/cpu/samsung/exynos5-common/spi.h
index 3f36759..e021888 100644
--- a/src/cpu/samsung/exynos5-common/spi.h
+++ b/src/cpu/samsung/exynos5-common/spi.h
@@ -22,6 +22,9 @@
 
 #ifndef __ASSEMBLER__
 
+// This driver serves as a CBFS media source.
+#include <cbfs.h>
+
 /* SPI peripheral register map; padded to 64KB */
 struct exynos_spi {
        unsigned int            ch_cfg;         /* 0x00 */
@@ -85,5 +88,15 @@ struct exynos_spi {
 #define SPI_RX_BYTE_SWAP       (1 << 6)
 #define SPI_RX_HWORD_SWAP      (1 << 7)
 
+/* API */
+int exynos_spi_open(struct exynos_spi *regs);
+int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off);
+int exynos_spi_close(struct exynos_spi *regs);
+
+/* Serve as CBFS Media */
+int initialize_exynos_spi_cbfs_media(struct cbfs_media *media,
+                                    void *buffer_address,
+                                    size_t buffer_size);
+
 #endif /* __ASSEMBLER__ */
 #endif
diff --git a/src/mainboard/google/snow/bootblock.c 
b/src/mainboard/google/snow/bootblock.c
index 5b3efa0..3887e7e 100644
--- a/src/mainboard/google/snow/bootblock.c
+++ b/src/mainboard/google/snow/bootblock.c
@@ -17,11 +17,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#define uchar unsigned char
-#define uint  unsigned int
-
 #include <stdlib.h>
 #include <types.h>
+#include <assert.h>
+#include <arch/armv7/include/common.h>
 #include <arch/io.h>
 #include "cpu/samsung/exynos5250/clk.h"
 #include "cpu/samsung/exynos5250/cpu.h"
@@ -46,87 +45,6 @@
 /* TODO Move to Makefile.inc once we support adding bootblock stage files. */
 #include "cpu/samsung/exynos5-common/spi.c"
 
-/* FIXME(dhendrix): Can we move this SPI stuff elsewhere? */
-static void spi_rx_tx(struct exynos_spi *regs, int todo,
-                       void *dinp, void const *doutp, int i)
-{
-       unsigned int *rxp = (unsigned int *)(dinp + (i * (32 * 1024)));
-       int rx_lvl, tx_lvl;
-       unsigned int out_bytes, in_bytes;
-
-       out_bytes = in_bytes = todo;
-       setbits_le32(&regs->ch_cfg, SPI_CH_RST);
-       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
-       writel(((todo * 8) / 32) | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
-
-       while (in_bytes) {
-               uint32_t spi_sts;
-               int temp;
-
-               spi_sts = readl(&regs->spi_sts);
-               rx_lvl = ((spi_sts >> 15) & 0x7f);
-               tx_lvl = ((spi_sts >> 6) & 0x7f);
-               while (tx_lvl < 32 && out_bytes) {
-                       temp = 0xffffffff;
-                       writel(temp, &regs->tx_data);
-                       out_bytes -= 4;
-                       tx_lvl += 4;
-               }
-               while (rx_lvl >= 4 && in_bytes) {
-                       temp = readl(&regs->rx_data);
-                       if (rxp)
-                               *rxp++ = temp;
-                       in_bytes -= 4;
-                       rx_lvl -= 4;
-               }
-       }
-}
-
-#if 0
-void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
-{
-       struct exynos5_clock *clk =
-               (struct exynos5_clock *)samsung_get_base_clock();
-       unsigned shift;
-       unsigned mask = 0xff;
-       u32 *reg;
-
-       /*
-        * For now we only handle a very small subset of peipherals here.
-        * Others will need to (and do) mangle the clock registers
-        * themselves, At some point it is hoped that this function can work
-        * from a table or calculated register offset / mask. For now this
-        * is at least better than spreading clock control code around
-        * U-Boot.
-        */
-       switch (periph_id) {
-       case PERIPH_ID_SPI0:
-               reg = &clk->div_peric1;
-               shift = 8;
-               break;
-       case PERIPH_ID_SPI1:
-               reg = &clk->div_peric1;
-               shift = 24;
-               break;
-       case PERIPH_ID_SPI2:
-               reg = &clk->div_peric2;
-               shift = 8;
-               break;
-       case PERIPH_ID_SPI3:
-               reg = &clk->sclk_div_isp;
-               shift = 4;
-               break;
-       case PERIPH_ID_SPI4:
-               reg = &clk->sclk_div_isp;
-               shift = 16;
-               break;
-       default:
-               debug("%s: Unsupported peripheral ID %d\n", __func__,
-                     periph_id);
-               return;
-       }
-}
-#endif
 void clock_ll_set_pre_ratio(enum periph_id periph_id, unsigned divisor)
 {
        struct exynos5_clock *clk =
@@ -140,43 +58,6 @@ void clock_ll_set_pre_ratio(enum periph_id periph_id, 
unsigned divisor)
        clrsetbits_le32(reg, mask << shift, (divisor & mask) << shift);
 }
 
-#if 0
-void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor)
-{
-       struct exynos5_clock *clk =
-               (struct exynos5_clock *)samsung_get_base_clock();
-       unsigned shift;
-       unsigned mask = 0xff;
-       u32 *reg;
-
-       switch (periph_id) {
-       case PERIPH_ID_SPI0:
-               reg = &clk->div_peric1;
-               shift = 0;
-               break;
-       case PERIPH_ID_SPI1:
-               reg = &clk->div_peric1;
-               shift = 16;
-               break;
-       case PERIPH_ID_SPI2:
-               reg = &clk->div_peric2;
-               shift = 0;
-               break;
-       case PERIPH_ID_SPI3:
-               reg = &clk->sclk_div_isp;
-               shift = 0;
-               break;
-       case PERIPH_ID_SPI4:
-               reg = &clk->sclk_div_isp;
-               shift = 12;
-               break;
-       default:
-               debug("%s: Unsupported peripheral ID %d\n", __func__,
-                     periph_id);
-               return;
-       }
-}
-#endif
 void clock_ll_set_ratio(enum periph_id periph_id, unsigned divisor)
 {
        struct exynos5_clock *clk =
@@ -253,44 +134,6 @@ static int clock_calc_best_scalar(unsigned int 
main_scaler_bits,
        return best_main_scalar;
 }
 
-#if 0
-int clock_set_rate(enum periph_id periph_id, unsigned int rate)
-{
-       int main;
-       unsigned int fine;
-
-       switch (periph_id) {
-       case PERIPH_ID_SPI0:
-       case PERIPH_ID_SPI1:
-       case PERIPH_ID_SPI2:
-       case PERIPH_ID_SPI3:
-       case PERIPH_ID_SPI4:
-               main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
-               if (main < 0) {
-                       debug("%s: Cannot set clock rate for periph %d",
-                                       __func__, periph_id);
-                       return -1;
-               }
-               clock_ll_set_ratio(periph_id, main - 1);
-               clock_ll_set_pre_ratio(periph_id, fine - 1);
-               break;
-       default:
-               debug("%s: Unsupported peripheral ID %d\n", __func__,
-                     periph_id);
-               return -1;
-       }
-       main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
-       if (main < 0) {
-               debug("%s: Cannot set clock rate for periph %d",
-                               __func__, periph_id);
-               return -1;
-       }
-       clock_ll_set_ratio(PERIPH_ID_SPI1, main - 1);
-       clock_ll_set_pre_ratio(PERIPH_ID_SPI1, fine - 1);
-
-       return 0;
-}
-#endif
 int clock_set_rate(enum periph_id periph_id, unsigned int rate)
 {
        int main;
@@ -362,77 +205,6 @@ void gpio_cfg_pin(int gpio, int cfg)
        writel(value, &bank->con);
 }
 
-//static void exynos_spi_copy(unsigned int uboot_size)
-static void copy_romstage(uint32_t spi_addr, uint32_t sram_addr, unsigned int 
len)
-{
-       int upto, todo;
-       int i;
-//     struct exynos_spi *regs = (struct exynos_spi *)samsung_get_base_spi1();
-       struct exynos_spi *regs = (struct exynos_spi *)0x12d30000;
-
-       clock_set_rate(PERIPH_ID_SPI1, 50000000); /* set spi clock to 50Mhz */
-       /* set the spi1 GPIO */
-//     exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE);
-       gpio_cfg_pin(GPIO_A24, 0x2);
-       gpio_cfg_pin(GPIO_A25, 0x2);
-       gpio_cfg_pin(GPIO_A26, 0x2);
-       gpio_cfg_pin(GPIO_A27, 0x2);
-
-       /* set pktcnt and enable it */
-       writel(4 | SPI_PACKET_CNT_EN, &regs->pkt_cnt);
-       /* set FB_CLK_SEL */
-       writel(SPI_FB_DELAY_180, &regs->fb_clk);
-       /* set CH_WIDTH and BUS_WIDTH as word */
-       setbits_le32(&regs->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
-                                       SPI_MODE_BUS_WIDTH_WORD);
-       clrbits_le32(&regs->ch_cfg, SPI_CH_CPOL_L); /* CPOL: active high */
-
-       /* clear rx and tx channel if set priveously */
-       clrbits_le32(&regs->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON);
-
-       setbits_le32(&regs->swap_cfg, SPI_RX_SWAP_EN |
-               SPI_RX_BYTE_SWAP |
-               SPI_RX_HWORD_SWAP);
-
-       /* do a soft reset */
-       setbits_le32(&regs->ch_cfg, SPI_CH_RST);
-       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
-
-       /* now set rx and tx channel ON */
-       setbits_le32(&regs->ch_cfg, SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN);
-       clrbits_le32(&regs->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */
-
-       /* Send read instruction (0x3h) followed by a 24 bit addr */
-       writel((SF_READ_DATA_CMD << 24) | spi_addr, &regs->tx_data);
-
-       /* waiting for TX done */
-       while (!(readl(&regs->spi_sts) & SPI_ST_TX_DONE));
-
-       for (upto = 0, i = 0; upto < len; upto += todo, i++) {
-               todo = MIN(len - upto, (1 << 15));
-               spi_rx_tx(regs, todo, (void *)(sram_addr),
-                                       (void *)(spi_addr), i);
-       }
-
-       setbits_le32(&regs->cs_reg, SPI_SLAVE_SIG_INACT);/* make the CS high */
-
-       /*
-        * Let put controller mode to BYTE as
-        * SPI driver does not support WORD mode yet
-        */
-       clrbits_le32(&regs->mode_cfg, SPI_MODE_CH_WIDTH_WORD |
-                                       SPI_MODE_BUS_WIDTH_WORD);
-       writel(0, &regs->swap_cfg);
-
-       /*
-        * Flush spi tx, rx fifos and reset the SPI controller
-        * and clear rx/tx channel
-        */
-       clrsetbits_le32(&regs->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
-       clrbits_le32(&regs->ch_cfg, SPI_CH_RST);
-       clrbits_le32(&regs->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
-}
-
 /* Pull mode */
 #define EXYNOS_GPIO_PULL_NONE  0x0
 #define EXYNOS_GPIO_PULL_DOWN  0x1
@@ -854,21 +626,15 @@ void do_barriers(void)
        );
 }
 
-void sdelay(unsigned long loops);
-void sdelay(unsigned long loops)
-{
-       __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
-                         "bne 1b":"=r" (loops):"0"(loops));
-}
-
 /* is this right? meh, it seems to work well enough... */
 void my_udelay(unsigned int n);
 void my_udelay(unsigned int n)
 {
-       sdelay(n * 1000);
+       n *= 1000;
+       __asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+                         "bne 1b":"=r" (n):"0"(n));
 }
 
-
 void i2c_init(int speed, int slaveadd)
 {
        struct s3c24x0_i2c_bus *i2c = &i2c0;
@@ -2145,13 +1911,6 @@ void bootblock_mainboard_init(void)
        do_serial();
        printk(BIOS_INFO, "%s: UART initialized\n", __func__);
 
-       /* Copy romstage data from SPI ROM to SRAM */
-       printk(BIOS_INFO, "Copying romstage:\n"
-                       "\tSPI offset: 0x%06x\n"
-                       "\tiRAM offset: 0x%08x\n"
-                       "\tSize: 0x%x\n",
-                       0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
-       copy_romstage(0x0, CONFIG_SPI_IMAGE_HACK, CONFIG_ROMSTAGE_SIZE);
 #if 0
        /* FIXME: dump SRAM content for sanity checking */
        uint32_t u;

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to