[coreboot] New patch to review for coreboot: 9849fe7 armv7: Add SPI driver for Exynos.

Hung-Te Lin (hungte@chromium.org) gerrit at coreboot.org
Wed Jan 30 12:43:17 CET 2013


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

-gerrit

commit 9849fe7d5da88d1d890717b9f4a3438b32a59d6f
Author: Hung-Te Lin <hungte at chromium.org>
Date:   Wed Jan 30 19:32:53 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 <hungte at chromium.org>
---
 src/cpu/samsung/exynos5-common/spi.c  | 245 +++++++++++++++++++++++++++++++-
 src/cpu/samsung/exynos5-common/spi.h  |  13 ++
 src/mainboard/google/snow/bootblock.c | 253 ++--------------------------------
 3 files changed, 263 insertions(+), 248 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 d5ee0a3..e9fc13e 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"
@@ -34,6 +33,7 @@
 #include "cpu/samsung/s5p-common/s3c24x0_i2c.h"
 #include "cpu/samsung/exynos5-common/spi.h"
 #include "cpu/samsung/exynos5-common/uart.h"
+#include "cbfs_core.h"
 
 #include <device/i2c.h>
 #include <drivers/maxim/max77686/max77686.h>
@@ -42,87 +42,9 @@
 
 #define EXYNOS5_CLOCK_BASE		0x10010000
 
-/* 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;
-		}
-	}
-}
+// TODO Move this to Makefile.inc once we support adding bootblock stage files.
+#include "cpu/samsung/exynos5-common/spi.c"
 
-#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 =
@@ -136,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 =
@@ -249,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;
@@ -358,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
@@ -850,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;
@@ -2141,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;



More information about the coreboot mailing list