From d8b4cff390da46395aad7f45f0cad93844a3fe2c Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Tue, 30 Jun 2015 10:30:41 +0300 Subject: [PATCH 1/4] dtc: Fix cross compilation Flex and Bison are need to be executable by the build system. --- pkgs/development/compilers/dtc/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/compilers/dtc/default.nix b/pkgs/development/compilers/dtc/default.nix index 84673dfc724..59c85d03d4b 100644 --- a/pkgs/development/compilers/dtc/default.nix +++ b/pkgs/development/compilers/dtc/default.nix @@ -10,7 +10,7 @@ stdenv.mkDerivation rec { sha256 = "0z7yrv0sdhsh5wwy7yd1fvs4pqaq0n9m5i8w65lyibg77ahkasdg"; }; - buildInputs = [ flex bison ]; + nativeBuildInputs = [ flex bison ]; installFlags = [ "INSTALL=install" "PREFIX=$(out)" ]; From 1793fdbfb196b3af8f0fe17021b5873daffd3e33 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Sun, 7 Jun 2015 21:07:45 +0300 Subject: [PATCH 2/4] platforms.nix: Remove IntegratorCP and Versatile These ARM boards are very old and quite likely used only for booting in QEMU emulation. I'll focus on making the multiplatform image easy to boot in QEMU instead. --- pkgs/top-level/platforms.nix | 74 ------------------------------------ 1 file changed, 74 deletions(-) diff --git a/pkgs/top-level/platforms.nix b/pkgs/top-level/platforms.nix index 4a6dc5aacf6..c331278046c 100644 --- a/pkgs/top-level/platforms.nix +++ b/pkgs/top-level/platforms.nix @@ -303,80 +303,6 @@ rec { #kernelHeadersBaseConfig = "guruplug_defconfig"; }; - versatileARM = { - name = "versatileARM"; - kernelMajor = "2.6"; - kernelHeadersBaseConfig = "versatile_defconfig"; - kernelBaseConfig = "versatile_defconfig"; - kernelArch = "arm"; - kernelAutoModules = false; - kernelTarget = "zImage"; - kernelExtraConfig = - '' - MMC_ARMMMCI y - #MMC_SDHCI y - SERIO_AMBAKMI y - - AEABI y - RTC_CLASS y - RTC_DRV_PL031 y - PCI y - SCSI y - SCSI_DMA y - SCSI_ATA y - BLK_DEV_SD y - BLK_DEV_SR y - SCSI_SYM53C8XX_2 y - - TMPFS y - IPV6 m - REISERFS_FS m - EXT4_FS m - - IP_PNP y - IP_PNP_DHCP y - IP_PNP_BOOTP y - ROOT_NFS y - ''; - uboot = null; - }; - - integratorCP = { - name = "integratorCP"; - kernelMajor = "2.6"; - kernelHeadersBaseConfig = "integrator_defconfig"; - kernelBaseConfig = "integrator_defconfig"; - kernelArch = "arm"; - kernelAutoModules = false; - kernelTarget = "zImage"; - kernelExtraConfig = - '' - # needed for qemu integrator/cp - SERIAL_AMBA_PL011 y - SERIAL_AMBA_PL011_CONSOLE y - SERIAL_AMBA_PL010 n - SERIAL_AMBA_PL010_CONSOLE n - - MMC_ARMMMCI y - MMC_SDHCI y - SERIO_AMBAKMI y - - CPU_ARM926T y - ARCH_INTEGRATOR_CP y - VGA_CONSOLE n - AEABI y - ''; - uboot = null; - ubootConfig = "integratorcp_config"; - }; - - integratorCPuboot = integratorCP // { - name = "integratorCPuboot"; - kernelTarget = "uImage"; - uboot = "upstream"; - ubootConfig = "integratorcp_config"; - }; - fuloong2f_n32 = { name = "fuloong2f_n32"; kernelMajor = "2.6"; From d013de6d32fa315a100c11150965f83edb0f794a Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Sun, 7 Jun 2015 22:12:18 +0300 Subject: [PATCH 3/4] U-Boot: Update to 2015.04 and major refactor Instead of selecting the defconfig based on stdenv.platform.uboot, provide different ubootFoo packages. Otherwise we couldn't easily build U-Boots for different platforms than what we are currently running on. All users of the ubootChooser function appear to be using only CLI tools like mkimage, whose behaviour is not affected by the defconfig (their build outputs are bitwise-identical). So add a separate package for the CLI tools. Of the removed patches, some version of sheevaplug-sdio.patch has apparently been applied upstream (with at least mv_sdio.c renamed to mvebu_mmc.c). sheevaplug-config.patch needs rebasing & re-testing on real hardware. Tested boards and input/output methods that upstream supports: - Raspberry Pi: - HDMI works, USB keyboard not yet supported - Serial via the 26-pin connector (3.3V) - pcDuino3 Nano: - HDMI + USB keyboard (only if attached to a hub) - Serial via the 3-pin connector (3.3V) - Jetson TK1: RS-232 serial port only - Versatile Express CA9 (for QEMU only): Serial via '-serial stdio' --- pkgs/misc/uboot/default.nix | 89 +- pkgs/misc/uboot/sheevaplug-config.patch | 57 -- pkgs/misc/uboot/sheevaplug-sdio.patch | 1091 ----------------------- pkgs/top-level/all-packages.nix | 40 +- 4 files changed, 73 insertions(+), 1204 deletions(-) delete mode 100644 pkgs/misc/uboot/sheevaplug-config.patch delete mode 100644 pkgs/misc/uboot/sheevaplug-sdio.patch diff --git a/pkgs/misc/uboot/default.nix b/pkgs/misc/uboot/default.nix index 5928406eb54..5f4bab9138f 100644 --- a/pkgs/misc/uboot/default.nix +++ b/pkgs/misc/uboot/default.nix @@ -1,71 +1,60 @@ -{stdenv, fetchurl, unzip}: +{ stdenv, fetchurl, bc, dtc +, toolsOnly ? false +, defconfig ? "allnoconfig" +, targetPlatforms +, filesToInstall +}: let platform = stdenv.platform; - configureFun = ubootConfig : + crossPlatform = stdenv.cross.platform; + makeTarget = if toolsOnly then "tools NO_SDL=1" else "all"; + installDir = if toolsOnly then "$out/bin" else "$out"; + buildFun = kernelArch: '' - make mrproper - make ${ubootConfig} NBOOT=1 LE=1 - ''; - - buildFun = kernelArch : - '' - unset src if test -z "$crossConfig"; then - make clean all + make ${makeTarget} else - make clean all ARCH=${kernelArch} CROSS_COMPILE=$crossConfig- + make ${makeTarget} ARCH=${kernelArch} CROSS_COMPILE=$crossConfig- fi ''; in -stdenv.mkDerivation { - name = "uboot-2012.07"; - +stdenv.mkDerivation rec { + name = "uboot-${defconfig}-${version}"; + version = "2015.04"; + src = fetchurl { - url = "ftp://ftp.denx.de/pub/u-boot/u-boot-2012.07.tar.bz2"; - sha256 = "15nli6h9a127ldizsck3g4ysy5j4m910wawspgpadz4vjyk213p0"; + url = "ftp://ftp.denx.de/pub/u-boot/u-boot-${version}.tar.bz2"; + sha256 = "0q2x1wh1f6rjh9rmcnkf28dxcvp9hkhi4vzspqkzamb6b3gp06ha"; }; - nativeBuildInputs = [ unzip ]; + nativeBuildInputs = [ bc dtc ]; - dontStrip = true; - - installPhase = '' - mkdir -p $out - cp u-boot.bin $out - cp u-boot u-boot.map $out - - mkdir -p $out/bin - cp tools/{envcrc,mkimage} $out/bin + configurePhase = '' + make ${defconfig} ''; - # They have 'errno.h' included by a "-idirafter". As the gcc - # wrappers add the glibc include as "-idirafter", the only way - # we can make the glibc take priority is to -include errno.h. - postPatch = if stdenv ? glibc && stdenv.glibc != null then '' - sed -i 's,$(HOSTCPPFLAGS),-include ${stdenv.glibc}/include/errno.h $(HOSTCPPFLAGS),' config.mk - '' else ""; - - patches = [ ./sheevaplug-sdio.patch ./sheevaplug-config.patch ]; - - configurePhase = - assert platform ? uboot && platform.uboot != null; - assert (platform ? ubootConfig); - configureFun platform.ubootConfig; - buildPhase = assert (platform ? kernelArch); buildFun platform.kernelArch; - crossAttrs = let - cp = stdenv.cross.platform; - in - assert cp ? uboot && cp.uboot != null; - { - configurePhase = assert (cp ? ubootConfig); - configureFun cp.ubootConfig; + installPhase = '' + mkdir -p ${installDir} + cp ${stdenv.lib.concatStringsSep " " filesToInstall} ${installDir} + ''; - buildPhase = assert (cp ? kernelArch); - buildFun cp.kernelArch; - }; + dontStrip = !toolsOnly; + + crossAttrs = { + buildPhase = assert (crossPlatform ? kernelArch); + buildFun crossPlatform.kernelArch; + }; + + meta = with stdenv.lib; { + homepage = "http://www.denx.de/wiki/U-Boot/"; + description = "Boot loader for embedded systems"; + license = licenses.gpl2; + maintainers = [ maintainers.dezgeg ]; + platforms = targetPlatforms; + }; } diff --git a/pkgs/misc/uboot/sheevaplug-config.patch b/pkgs/misc/uboot/sheevaplug-config.patch deleted file mode 100644 index 487756217bf..00000000000 --- a/pkgs/misc/uboot/sheevaplug-config.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h -index 7c8497c..b0da1e5 100644 ---- a/include/configs/sheevaplug.h -+++ b/include/configs/sheevaplug.h -@@ -50,7 +50,6 @@ - #define CONFIG_CMD_MII - #define CONFIG_CMD_MMC - #define CONFIG_CMD_NAND --#define CONFIG_JFFS2_NAND - #define CONFIG_CMD_PING - #define CONFIG_CMD_USB - /* -@@ -73,25 +72,36 @@ - * it has to be rounded to sector size - */ - #define CONFIG_ENV_SIZE 0x20000 /* 128k */ --#define CONFIG_ENV_ADDR 0xa0000 --#define CONFIG_ENV_OFFSET 0xa0000 /* env starts here */ -+#define CONFIG_ENV_ADDR 0x60000 -+#define CONFIG_ENV_OFFSET 0x60000 /* env starts here */ - - /* - * Default environment variables - */ --#define CONFIG_BOOTCOMMAND "${x_bootcmd_kernel}; " \ -+#define CONFIG_BOOTCOMMAND "${x_bootcmd_ubi0}; " \ -+ "${x_bootcmd_ubi1}; " \ -+ "${x_bootcmd_ubi2}; " \ -+ "${x_bootcmd_ubi3}; " \ - "setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \ -- "${x_bootcmd_usb}; bootm 0x6400000;" -+ "${x_bootcmd_usb}; bootm 0x200000 0x1100000;" - - #define CONFIG_MTDPARTS "orion_nand:512k(uboot)," \ -- "0x1ff00000@512k(rootfs) rw\0" -+ "0x1ff00000@512k(rootfs)\0" -+#define CONFIG_MTDPARTSK "orion_nand:512k(uboot)," \ -+ "0x1ff00000@512k(rootfs)rw\0" - - #define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console" \ -- "=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ -+ "=ttyS0,115200 mtdparts="CONFIG_MTDPARTSK \ -+ "mtdparts=mtdparts="CONFIG_MTDPARTS \ - "mtdids=nand0=orion_nand\0" \ -- "x_bootcmd_kernel=nand read 0x6400000 0x100000 0x300000\0" \ -+ "ipaddr=192.168.1.4\0" \ -+ "x_bootcmd_ubi0=ubi part nand0,1\0" \ -+ "x_bootcmd_ubi1=ubifsmount rootfs\0" \ -+ "x_bootcmd_ubi2=ubifsload 0x200000 /nixos-kernel\0" \ -+ "x_bootcmd_ubi3=ubifsload 0x1100000 /nixos-initrd\0" \ - "x_bootcmd_usb=usb start\0" \ -- "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" -+ "x_bootargs_root=ubi.mtd=rootfs root=ubi0:rootfs rw rootfstype=ubifs " \ -+ "init=/boot/nixos-init systemConfig=/boot/default/system\0" - - /* - * Ethernet Driver configuration diff --git a/pkgs/misc/uboot/sheevaplug-sdio.patch b/pkgs/misc/uboot/sheevaplug-sdio.patch deleted file mode 100644 index 3a4ea2933a3..00000000000 --- a/pkgs/misc/uboot/sheevaplug-sdio.patch +++ /dev/null @@ -1,1091 +0,0 @@ -diff --git a/arch/arm/include/asm/arch-kirkwood/config.h b/arch/arm/include/asm/arch-kirkwood/config.h -index a9499b7..1294d7f 100644 ---- a/arch/arm/include/asm/arch-kirkwood/config.h -+++ b/arch/arm/include/asm/arch-kirkwood/config.h -@@ -66,6 +66,7 @@ - #define MV_SATA_BASE KW_SATA_BASE - #define MV_SATA_PORT0_OFFSET KW_SATA_PORT0_OFFSET - #define MV_SATA_PORT1_OFFSET KW_SATA_PORT1_OFFSET -+#define MV_SDIO_BASE KW_SDIO_BASE - - /* - * NAND configuration -@@ -107,6 +108,14 @@ - #endif /* CONFIG_CMD_NET */ - - /* -+ * SDIO/MMC Card Configuration -+ */ -+#ifdef CONFIG_CMD_MMC -+#define CONFIG_MMC -+#define CONFIG_MV_SDIO -+#endif /* CONFIG_CMD_MMC */ -+ -+/* - * USB/EHCI - */ - #ifdef CONFIG_CMD_USB -diff --git a/arch/arm/include/asm/arch-kirkwood/kirkwood.h b/arch/arm/include/asm/arch-kirkwood/kirkwood.h -index 47771d5..343214b 100644 ---- a/arch/arm/include/asm/arch-kirkwood/kirkwood.h -+++ b/arch/arm/include/asm/arch-kirkwood/kirkwood.h -@@ -55,6 +55,7 @@ - #define KW_EGIGA0_BASE (KW_REGISTER(0x72000)) - #define KW_EGIGA1_BASE (KW_REGISTER(0x76000)) - #define KW_SATA_BASE (KW_REGISTER(0x80000)) -+#define KW_SDIO_BASE (KW_REGISTER(0x90000)) - - /* Kirkwood Sata controller has two ports */ - #define KW_SATA_PORT0_OFFSET 0x2000 -diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile -index c567737..081d5f4 100644 ---- a/drivers/mmc/Makefile -+++ b/drivers/mmc/Makefile -@@ -34,6 +34,7 @@ COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o - COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o - COBJS-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o - COBJS-$(CONFIG_MV_SDHCI) += mv_sdhci.o -+COBJS-$(CONFIG_MV_SDIO) += mv_sdio.o - COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o - COBJS-$(CONFIG_MXS_MMC) += mxsmmc.o - COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o -diff --git a/drivers/mmc/mv_sdio.c b/drivers/mmc/mv_sdio.c -new file mode 100644 -index 0000000..35969d3 ---- /dev/null -+++ b/drivers/mmc/mv_sdio.c -@@ -0,0 +1,675 @@ -+/* -+ * (C) Copyright 2009 -+ * Marvell Semiconductor -+ * Written-by: Gérald Kerma -+ * -+ * (C) Copyright 2003 -+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net -+ * -+ * 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., 51 Franklin Street, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_KIRKWOOD -+#include -+#endif -+#include "mv_sdio.h" -+ -+#ifdef CONFIG_MMC -+ -+#define DRIVER_NAME "mv-sdio" -+ -+#ifdef DEBUG -+#define pr_debug(fmt, args...) printf(fmt, ##args) -+#else -+#define pr_debug(...) do { } while(0) -+#endif -+ -+//static mv_sdio_t *mvsd = (mv_sdio_t *)mmc->priv; -+static mv_sdio_t *mvsd = (mv_sdio_t *)MV_SDIO_BASE; -+ -+static int is_sdhc; -+extern int fat_register_device(block_dev_desc_t *dev_desc, int part_no); -+static block_dev_desc_t mmc_dev; -+block_dev_desc_t * mmc_get_dev(int dev) -+{ -+ return ((block_dev_desc_t *)&mmc_dev); -+} -+ -+/* -+ * FIXME needs to read cid and csd info to determine block size -+ * and other parameters -+ */ -+static uchar mmc_buf[MMC_BLOCK_SIZE]; -+static mv_mmc_csd_t mv_mmc_csd; -+static int mmc_ready = 0; -+ -+/* MMC_DEFAULT_RCA should probably be just 1, but this may break other code -+ that expects it to be shifted. */ -+static u_int16_t rca = 0; -+ -+/* used for debug */ -+static u_int32_t mv_mmc_size(const struct mv_mmc_csd *csd) -+{ -+ u_int32_t block_len, mult, blocknr; -+ -+ block_len = csd->read_bl_len << 12; -+ mult = csd->c_size_mult1 << 8; -+ blocknr = (csd->c_size+1) * mult; -+ -+ return blocknr * block_len; -+} -+ -+static int isprint (unsigned char ch) -+{ -+ if (ch >= 32 && ch < 127) -+ return (1); -+ -+ return (0); -+} -+ -+static int toprint(char *dst, char c) -+{ -+ if (isprint(c)) { -+ *dst = c; -+ return 1; -+ } -+ -+ return sprintf(dst,"\\x%02x", c); -+ -+} -+ -+static void print_mmc_cid(mv_mmc_cid_t *cid) -+{ -+ printf("MMC found. Card desciption is:\n"); -+ printf("Manufacturer ID = %02x%02x%02x\n", -+ cid->id[0], cid->id[1], cid->id[2]); -+ printf("HW/FW Revision = %x %x\n",cid->hwrev, cid->fwrev); -+ cid->hwrev = cid->fwrev = 0; /* null terminate string */ -+ printf("Product Name = %s\n",cid->name); -+ printf("Serial Number = %02x%02x%02x\n", -+ cid->sn[0], cid->sn[1], cid->sn[2]); -+ printf("Month = %d\n",cid->month); -+ printf("Year = %d\n",1997 + cid->year); -+} -+ -+static void print_sd_cid(mv_sd_cid_t *cid) -+{ -+ int len; -+ char tbuf[64]; -+ -+ printf("SD%s found. Card desciption is:\n", is_sdhc?"HC":""); -+ -+ len = 0; -+ len += toprint(&tbuf[len], cid->oid_0); -+ len += toprint(&tbuf[len], cid->oid_1); -+ tbuf[len] = 0; -+ -+ printf("Manufacturer: 0x%02x, OEM \"%s\"\n", -+ cid->mid, tbuf); -+ -+ len = 0; -+ len += toprint(&tbuf[len], cid->pnm_0); -+ len += toprint(&tbuf[len], cid->pnm_1); -+ len += toprint(&tbuf[len], cid->pnm_2); -+ len += toprint(&tbuf[len], cid->pnm_3); -+ len += toprint(&tbuf[len], cid->pnm_4); -+ tbuf[len] = 0; -+ -+ printf("Product name: \"%s\", revision %d.%d\n", -+ tbuf, -+ cid->prv >> 4, cid->prv & 15); -+ -+ printf("Serial number: %u\n", -+ cid->psn_0 << 24 | cid->psn_1 << 16 | cid->psn_2 << 8 | -+ cid->psn_3); -+ printf("Manufacturing date: %d/%d\n", -+ cid->mdt_1 & 15, -+ 2000+((cid->mdt_0 & 15) << 4)+((cid->mdt_1 & 0xf0) >> 4)); -+ -+ printf("CRC: 0x%02x, b0 = %d\n", -+ cid->crc >> 1, cid->crc & 1); -+} -+ -+static void mvsdio_set_clock(unsigned int clock) -+{ -+ unsigned int m; -+ -+ m = MVSDMMC_BASE_FAST_CLOCK/(2*clock) - 1; -+ -+ pr_debug("mvsdio_set_clock: dividor = 0x%x clock=%d\n", -+ m, clock); -+ -+ -+ writew(m & 0x7ff, &mvsd->CLK_DIV); -+ -+ if (isprint(1)) -+ udelay(10*1000); -+} -+ -+/****************************************************/ -+static ulong * mv_mmc_cmd(ulong cmd, ulong arg, ushort xfermode, ushort resptype, ushort waittype) -+/****************************************************/ -+{ -+ static ulong resp[4]; -+ ushort done ; -+ int err = 0 ; -+ ulong curr, start, diff, hz; -+ ushort response[8]; -+ -+ pr_debug("mv_mmc_cmd %x, arg: %x,xfer: %x,resp: %x, wait : %x\n" -+ , (unsigned int)cmd, (unsigned int)arg, xfermode, resptype, waittype); -+ -+ -+ /* clear status */ -+ writew(0xffff, &mvsd->NOR_INTR_STATUS); -+ writew(0xffff, &mvsd->ERR_INTR_STATUS); -+ -+ start = get_timer(0); -+ hz = CONFIG_SYS_HZ; -+ -+ while((readw(&mvsd->PRESENT_STATE0) & CARD_BUSY)) { -+ curr = get_timer(0); -+ diff = (long) curr - (long) start; -+ if (diff > (3*hz)) -+ { -+ /* 3 seconds timeout, card busy, can't sent cmd */ -+ printf("card too busy \n"); -+ return 0; -+ } -+ } -+ -+ writew((ushort)(arg&0xffff), &mvsd->ARG_LOW); -+ writew((ushort)(arg>>16), &mvsd->ARG_HI); -+ writew(xfermode, &mvsd->XFER_MODE); -+ if( (cmd == MMC_CMD_READ_BLOCK) || (cmd == 25) ) -+ { -+ writew(((cmd << 8) | resptype | 0x3c ) , &mvsd->CMD); -+ pr_debug("cmd reg : %x\n", readw(&mvsd->CMD)) ; -+ -+ } -+ else -+ { -+ writew(((cmd << 8) | resptype ), &mvsd->CMD); -+ } -+ -+ done = readw(&mvsd->NOR_INTR_STATUS) & waittype; -+ start = get_timer(0); -+ -+ while( done!=waittype) -+ { -+ done = readw(&mvsd->NOR_INTR_STATUS) & waittype; -+ -+ if( readw(&mvsd->NOR_INTR_STATUS) & 0x8000 ) -+ { -+ pr_debug("Error! cmd : %d, err : %04x\n", (unsigned int)cmd, readw(&mvsd->ERR_INTR_STATUS)) ; -+ -+ return 0 ; /* error happen */ -+ } -+ -+ curr = get_timer(0); -+ diff = (long) curr - (long) start; -+ if (diff > (3*hz)) -+ { -+ pr_debug("cmd timeout, status : %04x\n", readw(&mvsd->NOR_INTR_STATUS)); -+ pr_debug("xfer mode : %04x\n", readw(&mvsd->XFER_MODE)); -+ -+ err = 1 ; -+ break; -+ } -+ } -+ -+ response[0] = readw(&mvsd->RSP0); -+ response[1] = readw(&mvsd->RSP1); -+ response[2] = readw(&mvsd->RSP2); -+ response[3] = readw(&mvsd->RSP3); -+ response[4] = readw(&mvsd->RSP4); -+ response[5] = readw(&mvsd->RSP5); -+ response[6] = readw(&mvsd->RSP6); -+ response[7] = readw(&mvsd->RSP7); -+ -+ memset(resp, 0, sizeof(resp)); -+ -+ switch (resptype & 0x3) { -+ case SDIO_CMD_RSP_48: -+ case SDIO_CMD_RSP_48BUSY: -+ resp[0] = ((response[2] & 0x3f) << (8 - 8)) | -+ ((response[1] & 0xffff) << (14 - 8)) | -+ ((response[0] & 0x3ff) << (30 - 8)); -+ resp[1] = ((response[0] & 0xfc00) >> 10); -+ break; -+ -+ case SDIO_CMD_RSP_136: -+ resp[3] = ((response[7] & 0x3fff) << 8) | -+ ((response[6] & 0x3ff) << 22); -+ resp[2] = ((response[6] & 0xfc00) >> 10) | -+ ((response[5] & 0xffff) << 6) | -+ ((response[4] & 0x3ff) << 22); -+ resp[1] = ((response[4] & 0xfc00) >> 10) | -+ ((response[3] & 0xffff) << 6) | -+ ((response[2] & 0x3ff) << 22); -+ resp[0] = ((response[2] & 0xfc00) >> 10) | -+ ((response[1] & 0xffff) << 6) | -+ ((response[0] & 0x3ff) << 22); -+ break; -+ default: -+ return 0; -+ } -+ int i; -+ pr_debug("MMC resp :"); -+ for (i=0; i<4; ++i ) { -+ pr_debug(" %08x", (unsigned int)resp[i]); -+ } -+ pr_debug("\n"); -+ if( err ) -+ return NULL ; -+ else -+ return resp; -+} -+ -+/****************************************************/ -+static int mv_mmc_block_read(uchar *dst, ulong src, ulong len) -+/****************************************************/ -+{ -+ ulong *resp; -+ -+ if (len == 0) { -+ return 0; -+ } -+ -+ if (is_sdhc) { -+ /* SDHC: use block address */ -+ src >>= 9; -+ } -+ -+ pr_debug("mmc_block_rd dst %lx src %lx len %d\n", (ulong)dst, src, (int)len); -+ -+ /* prepare for dma transfer */ -+ writew(((ulong)(dst))&0xffff,&mvsd->SYS_ADDR_LOW); -+ writew(((ulong)(dst)>>16)&0xffff,&mvsd->SYS_ADDR_HI); -+ writew(len,&mvsd->BLK_SIZE); -+ writew(1,&mvsd->BLK_COUNT); -+ -+ /* send read command */ -+ resp = mv_mmc_cmd(MMC_CMD_READ_BLOCK, src, 0x10 , -+ SDIO_CMD_RSP_48, SDIO_NOR_XFER_DONE); -+ if (!resp) { -+ pr_debug("mv_mmc_block_read: mmc read block cmd fails\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+/****************************************************/ -+int mv_mmc_read(ulong src, uchar *dst, int size) -+/****************************************************/ -+{ -+ ulong end, part_start, part_end, part_len, aligned_start, aligned_end; -+ ulong mmc_block_size, mmc_block_address; -+ -+ if (size == 0) { -+ return 0; -+ } -+ -+ if (!mmc_ready) { -+ printf("Please initial the MMC first\n"); -+ return -1; -+ } -+ -+ mmc_block_size = MMC_BLOCK_SIZE; -+ mmc_block_address = ~(mmc_block_size - 1); -+ -+ end = src + size; -+ part_start = ~mmc_block_address & src; -+ part_end = ~mmc_block_address & end; -+ aligned_start = mmc_block_address & src; -+ aligned_end = mmc_block_address & end; -+ -+ /* all block aligned accesses */ -+ pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", -+ (long unsigned int)src,(ulong)dst, end, part_start, part_end, aligned_start, aligned_end); -+ -+ if (part_start) { -+ part_len = mmc_block_size - part_start; -+ pr_debug("ps src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", -+ (long unsigned int)src,(ulong)dst, end, part_start, part_end, aligned_start, aligned_end); -+ -+ if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) { -+ return -1; -+ } -+ memcpy(dst, mmc_buf+part_start, part_len); -+ dst += part_len; -+ src += part_len; -+ } -+ pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", -+ (long unsigned int)src,(ulong)dst, end, part_start, part_end, aligned_start, aligned_end); -+ -+ for (; src < aligned_end; aligned_start +=mmc_block_size, src += mmc_block_size, dst += mmc_block_size) { -+ pr_debug("al src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", -+ (long unsigned int)src,(ulong)dst, end, part_start, part_end, aligned_start, aligned_end); -+ -+ if ((mv_mmc_block_read(mmc_buf, aligned_start, mmc_block_size)) < 0) { -+ printf("mmc block read error\n"); -+ return -1; -+ } -+ memcpy(dst, mmc_buf, mmc_block_size); -+ } -+ pr_debug("src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", -+ (long unsigned int)src,(ulong)dst, end, part_start, part_end, aligned_start, aligned_end); -+ -+ if (part_end && src < end) { -+ pr_debug("pe src %lx dst %lx end %lx pstart %lx pend %lx astart %lx aend %lx\n", -+ (long unsigned int)src,(ulong)dst, end, part_start, part_end, aligned_start, aligned_end); -+ -+ if ((mv_mmc_block_read(mmc_buf, aligned_end, mmc_block_size)) < 0) { -+ return -1; -+ } -+ memcpy(dst, mmc_buf, part_end); -+ } -+ return 0; -+} -+ -+/****************************************************/ -+static ulong mv_mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst) -+/****************************************************/ -+{ -+ int mmc_block_size = MMC_BLOCK_SIZE; -+ ulong src = blknr * mmc_block_size; -+ -+ mv_mmc_read(src, (uchar *)dst, blkcnt*mmc_block_size); -+ return blkcnt; -+} -+ -+/****************************************************/ -+int mmc_legacy_init(int verbose) -+/****************************************************/ -+{ -+ int retries, rc = -ENODEV; -+ ulong *resp; -+ int sd_ver20; -+ int is_sd; -+ ushort reg; -+ uchar cidbuf[64]; -+ -+ sd_ver20 = 0; -+ is_sdhc = 0; -+ is_sd = 0; -+ -+ /* Initial Host Ctrl : Timeout : max , Normal Speed mode, 4-bit data mode */ -+ /* Big Endian, SD memory Card, Push_pull CMD Line */ -+ writew( SDIO_HOST_CTRL_TMOUT(0xf) | -+ SDIO_HOST_CTRL_DATA_WIDTH_4_BITS | -+ SDIO_HOST_CTRL_BIG_ENDIAN | -+ SDIO_HOST_CTRL_PUSH_PULL_EN | -+ SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY , -+ &mvsd->HOST_CTRL); -+ -+ writew( 0, &mvsd->CLK_CTRL); -+ -+ /* enable status */ -+ writew( 0xffff, &mvsd->NOR_STATUS_EN); -+ writew( 0xffff, &mvsd->ERR_STATUS_EN); -+ -+ /* disable interrupts */ -+ writew( 0, &mvsd->NOR_INTR_EN); -+ writew( 0, &mvsd->ERR_INTR_EN); -+ -+ writew( 0x100, &mvsd->SW_RESET); -+ udelay(10000); -+ -+ mv_mmc_csd.c_size = 0; -+ -+ /* reset */ -+ retries = 10; -+ resp = mv_mmc_cmd(0, 0, 0, SDIO_CMD_RSP_NONE, SDIO_NOR_CMD_DONE ); -+ pr_debug("cmd 0 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ -+ pr_debug ("trying to detect SD card version\n"); -+ -+ resp = mv_mmc_cmd(8, 0x000001aa, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ pr_debug("cmd 8 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ if (resp && (resp[0] & 0x1ff)==0x1aa) { -+ pr_debug ("SD version 2.0 card detected\n"); -+ -+ sd_ver20 = 1; -+ } -+ -+ if (sd_ver20) -+ retries = 50; -+ else -+ retries = 10; -+ -+ while (retries--) { -+ resp = mv_mmc_cmd(55, 0, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ pr_debug("cmd 55 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ -+ if (sd_ver20) -+ resp = mv_mmc_cmd(41, 0x40300000, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ else -+ resp = mv_mmc_cmd(41, 0x00300000, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ -+ pr_debug("cmd 41 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ -+ if (resp && (resp[0] & 0x80000000)) { -+ pr_debug ("detected SD card\n"); -+ -+ is_sd = 1; -+ break; -+ } -+ -+ udelay(100*1000); -+ } -+ -+ if (retries <= 0 && !is_sd) { -+ pr_debug ("failed to detect SD card, trying MMC\n"); -+ -+ retries = 10; -+ while (retries--) { -+ resp = mv_mmc_cmd(1, 0, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ pr_debug("cmd 01 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ -+ if (resp && (resp[0] & 0x80000000)) { -+ printf ("detected MMC card\n"); -+ reg = readw(&mvsd->HOST_CTRL); -+ reg &= ~(0x3<<1); -+ reg |= SDIO_HOST_CTRL_CARD_TYPE_IO_MMC; -+ writew( reg, &mvsd->HOST_CTRL); -+ break; -+ } -+ -+ udelay(100*1000); -+ } -+ } -+ -+ if (retries <= 0) { -+ pr_debug ("detect fails\n"); -+ -+ return -ENODEV; -+ } -+ -+ /* try to get card id */ -+ resp = mv_mmc_cmd(2, 0, 0, SDIO_CMD_RSP_136, SDIO_NOR_CMD_DONE ); -+ pr_debug("cmd 2 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ -+ if (resp == NULL) { -+ pr_debug ("read cid fails\n"); -+ -+ return -ENODEV; -+ } -+ -+ if (is_sd) { -+ mv_sd_cid_t *cid = (mv_sd_cid_t *) resp; -+ -+ memcpy(cidbuf, resp, sizeof(mv_sd_cid_t)); -+ -+ sprintf((char *) mmc_dev.vendor, -+ "Man %02x OEM %c%c \"%c%c%c%c%c\"", -+ cid->mid, cid->oid_0, cid->oid_1, -+ cid->pnm_0, cid->pnm_1, cid->pnm_2, cid->pnm_3, cid->pnm_4); -+ -+ sprintf((char *) mmc_dev.product, "%d", -+ (cid->psn_0 << 24) | (cid->psn_1 <<16) | (cid->psn_2 << 8) | (cid->psn_3 << 8)); -+ -+ sprintf((char *) mmc_dev.revision, "%d.%d", cid->prv>>4, cid->prv & 0xff); -+ -+ } else { -+ /* TODO configure mmc driver depending on card attributes */ -+ mv_mmc_cid_t *cid = (mv_mmc_cid_t *) resp; -+ -+ memcpy(cidbuf, resp, sizeof(mv_sd_cid_t)); -+ -+ -+ sprintf((char *) mmc_dev.vendor, -+ "Man %02x%02x%02x Snr %02x%02x%02x", -+ cid->id[0], cid->id[1], cid->id[2], -+ cid->sn[0], cid->sn[1], cid->sn[2]); -+ sprintf((char *) mmc_dev.product, "%s", cid->name); -+ sprintf((char *) mmc_dev.revision, "%x %x", cid->hwrev, cid->fwrev); -+ } -+ -+ /* fill in device description */ -+ mmc_dev.if_type = IF_TYPE_MMC; -+ mmc_dev.part_type = PART_TYPE_DOS; -+ mmc_dev.dev = 0; -+ mmc_dev.lun = 0; -+ mmc_dev.type = 0; -+ -+ /* FIXME fill in the correct size (is set to 128MByte) */ -+ mmc_dev.blksz = MMC_BLOCK_SIZE; -+ mmc_dev.lba = 0x10000; -+ -+ mmc_dev.removable = 0; -+ mmc_dev.block_read = (unsigned long) mv_mmc_bread; -+ -+ /* MMC exists, get CSD too */ -+ resp = mv_mmc_cmd(MMC_CMD_SET_RCA, 0, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ if (resp == NULL) { -+ pr_debug ("set rca fails\n"); -+ -+ return -ENODEV; -+ } -+ pr_debug("cmd3 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3]); -+ -+ -+ if (is_sd) -+ rca = resp[0] >> 16; -+ else -+ rca = 0; -+ -+ resp = mv_mmc_cmd(MMC_CMD_SEND_CSD, rca<<16, 0, SDIO_CMD_RSP_136,SDIO_NOR_CMD_DONE ); -+ pr_debug("cmd 9 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ if (resp == NULL) { -+ pr_debug ("read csd fails\n"); -+ -+ return -ENODEV; -+ } -+ -+ memcpy(&mv_mmc_csd, (mv_mmc_csd_t *) resp, sizeof(mv_mmc_csd_t)); -+ rc = 0; -+ mmc_ready = 1; -+ -+ /* FIXME add verbose printout for csd */ -+ pr_debug ("size = %u\n", mv_mmc_size(&mv_mmc_csd)); -+ -+ -+ resp = mv_mmc_cmd(7, rca<<16, 0, SDIO_CMD_RSP_48BUSY, SDIO_NOR_CMD_DONE); -+ if (resp == NULL) { -+ pr_debug ("select card fails\n"); -+ -+ return -ENODEV; -+ } -+ pr_debug("cmd 7 resp : %08x %08x %08x %08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3] ); -+ -+ -+ if (is_sd) { -+ resp = mv_mmc_cmd(55, rca<<16, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ if (resp == NULL) { -+ pr_debug ("cmd55 fails\n"); -+ -+ return -ENODEV; -+ } -+ pr_debug("cmd55 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3]); -+ -+ -+ resp = mv_mmc_cmd(6, (rca<<16) | 0x2 , 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ if (resp == NULL) { -+ pr_debug ("cmd55 fails\n"); -+ -+ return -ENODEV; -+ } -+ pr_debug("cmd6 resp : 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3]); -+ -+ } -+ -+ resp = (ulong *) &mv_mmc_csd; -+ pr_debug("csd: 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ (unsigned int)resp[0], (unsigned int)resp[1], (unsigned int)resp[2], (unsigned int)resp[3]); -+ -+ -+ /* check SDHC */ -+ if ((resp[0]&0xf0000000)==0x40000000) -+ is_sdhc = 1; -+ -+ /* set block len */ -+ resp = mv_mmc_cmd(MMC_CMD_SET_BLOCKLEN, MMC_BLOCK_SIZE, 0, SDIO_CMD_RSP_48, SDIO_NOR_CMD_DONE ); -+ if (!resp) { -+ pr_debug("mv_mmc_block_read: set blk len fails\n"); -+ return -ENODEV; -+ } -+ -+ if (verbose) { -+ if (is_sd) -+ print_sd_cid((mv_sd_cid_t *) cidbuf); -+ else -+ print_mmc_cid((mv_mmc_cid_t *) cidbuf); -+ } -+ -+ mvsdio_set_clock(CONFIG_SYS_MMC_CLK_PP); -+ -+ fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */ -+ -+ return 0; -+} -+ -+#endif /* CONFIG_MMC */ -diff --git a/drivers/mmc/mv_sdio.h b/drivers/mmc/mv_sdio.h -new file mode 100644 -index 0000000..9707000 ---- /dev/null -+++ b/drivers/mmc/mv_sdio.h -@@ -0,0 +1,310 @@ -+/* -+ * (C) Copyright 2009 -+ * Marvell Semiconductor -+ * Written-by: Gérald Kerma -+ * -+ * 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., 51 Franklin Street, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ */ -+ -+#ifndef _MVSDIO_INCLUDE -+#define _MVSDIO_INCLUDE -+ -+//#define SDIO_REG(x) (MV_SDIO_BASE + (x)) -+ -+#define MVSDMMC_DMA_SIZE 65536 -+#define MVSDMMC_CMD_TIMEOUT 2 /* 100 usec*/ -+ -+/* -+ * Clock rates -+ */ -+ -+#define MVSD_CLOCKRATE_MAX 50000000 -+#define MVSD_BASE_DIV_MAX 0x7ff -+ -+#define CONFIG_SYS_MMC_CLK_PP 25000000 -+ -+/* -+ * The base MMC clock rate -+ */ -+ -+#define MVSDMMC_CLOCKRATE_MIN 100000 -+#define MVSDMMC_CLOCKRATE_MAX MVSD_CLOCKRATE_MAX -+#define MVSDMMC_BASE_FAST_CLOCK CONFIG_SYS_TCLK -+ -+ -+/* -+ * SDIO register -+ */ -+#ifndef __ASSEMBLY__ -+ -+/* -+ * Structure for struct SoC access. -+ * Names starting with '_' are fillers. -+ */ -+typedef struct mv_sdio { -+ /* reg Offset */ -+ u32 SYS_ADDR_LOW; /* 0x00 */ -+ u32 SYS_ADDR_HI; /* 0x04 */ -+ u32 BLK_SIZE; /* 0x08 */ -+ u32 BLK_COUNT; /* 0x0c */ -+ u32 ARG_LOW; /* 0x10 */ -+ u32 ARG_HI; /* 0x14 */ -+ u32 XFER_MODE; /* 0x18 */ -+ u32 CMD; /* 0x1c */ -+ u32 RSP0; /* 0x20 */ -+ u32 RSP1; /* 0x24 */ -+ u32 RSP2; /* 0x28 */ -+ u32 RSP3; /* 0x2c */ -+ u32 RSP4; /* 0x30 */ -+ u32 RSP5; /* 0x34 */ -+ u32 RSP6; /* 0x38 */ -+ u32 RSP7; /* 0x3c */ -+ u32 BUF_DATA_PORT; /* 0x40 */ -+ u32 RSVED; /* 0x44 */ -+ u32 PRESENT_STATE0; /* 0x48 */ -+ u32 PRESENT_STATE1; /* 0x4c */ -+ u32 HOST_CTRL; /* 0x50 */ -+ u32 BLK_GAP_CTRL; /* 0x54 */ -+ u32 CLK_CTRL; /* 0x58 */ -+ u32 SW_RESET; /* 0x5c */ -+ u32 NOR_INTR_STATUS; /* 0x60 */ -+ u32 ERR_INTR_STATUS; /* 0x64 */ -+ u32 NOR_STATUS_EN; /* 0x68 */ -+ u32 ERR_STATUS_EN; /* 0x6c */ -+ u32 NOR_INTR_EN; /* 0x70 */ -+ u32 ERR_INTR_EN; /* 0x74 */ -+ u32 AUTOCMD12_ERR_STATUS; /* 0x78 */ -+ u32 CURR_BYTE_LEFT; /* 0x7c */ -+ u32 CURR_BLK_LEFT; /* 0x80 */ -+ u32 AUTOCMD12_ARG_LOW; /* 0x84 */ -+ u32 AUTOCMD12_ARG_HI; /* 0x88 */ -+ u32 AUTOCMD12_INDEX; /* 0x8c */ -+ u32 AUTO_RSP0; /* 0x90 */ -+ u32 AUTO_RSP1; /* 0x94 */ -+ u32 AUTO_RSP2; /* 0x98 */ -+ u32 _9c; /* 0x9c */ -+ u32 _a0[0x78]; /* 0xa0 */ -+ u32 CLK_DIV; /* 0x128 */ -+ -+} mv_sdio_t; -+ -+#endif /* __ASSEMBLY__ */ -+ -+/* -+ * SDIO_PRESENT_STATE -+ */ -+ -+#define CARD_BUSY (1 << 1) -+#define CMD_INHIBIT (1 << 0) -+#define CMD_TXACTIVE (1 << 8) -+#define CMD_RXACTIVE (1 << 9) -+#define CMD_AUTOCMD12ACTIVE (1 << 14) -+ -+#define CMD_BUS_BUSY (CMD_AUTOCMD12ACTIVE| \ -+ CMD_RXACTIVE| \ -+ CMD_TXACTIVE| \ -+ CMD_INHIBIT| \ -+ CARD_BUSY) -+ -+/* -+ * SDIO_CMD -+ */ -+ -+#define SDIO_CMD_RSP_NONE (0 << 0) -+#define SDIO_CMD_RSP_136 (1 << 0) -+#define SDIO_CMD_RSP_48 (2 << 0) -+#define SDIO_CMD_RSP_48BUSY (3 << 0) -+ -+#define SDIO_CMD_CHECK_DATACRC16 (1 << 2) -+#define SDIO_CMD_CHECK_CMDCRC (1 << 3) -+#define SDIO_CMD_INDX_CHECK (1 << 4) -+#define SDIO_CMD_DATA_PRESENT (1 << 5) -+#define SDIO_UNEXPECTED_RESP (1 << 7) -+ -+ -+/* -+ * SDIO_XFER_MODE -+ */ -+ -+#define SDIO_XFER_MODE_STOP_CLK (1 << 5) -+#define SDIO_XFER_MODE_HW_WR_DATA_EN (1 << 1) -+#define SDIO_XFER_MODE_AUTO_CMD12 (1 << 2) -+#define SDIO_XFER_MODE_INT_CHK_EN (1 << 3) -+#define SDIO_XFER_MODE_TO_HOST (1 << 4) -+ -+ -+/* -+ * SDIO_HOST_CTRL -+ */ -+ -+#define SDIO_HOST_CTRL_PUSH_PULL_EN (1 << 0) -+ -+#define SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY (0 << 1) -+#define SDIO_HOST_CTRL_CARD_TYPE_IO_ONLY (1 << 1) -+#define SDIO_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO (2 << 1) -+#define SDIO_HOST_CTRL_CARD_TYPE_IO_MMC (3 << 1) -+#define SDIO_HOST_CTRL_CARD_TYPE_MASK (3 << 1) -+ -+#define SDIO_HOST_CTRL_BIG_ENDIAN (1 << 3) -+#define SDIO_HOST_CTRL_LSB_FIRST (1 << 4) -+#define SDIO_HOST_CTRL_ID_MODE_LOW_FREQ (1 << 5) -+#define SDIO_HOST_CTRL_HALF_SPEED (1 << 6) -+#define SDIO_HOST_CTRL_DATA_WIDTH_4_BITS (1 << 9) -+#define SDIO_HOST_CTRL_HI_SPEED_EN (1 << 10) -+ -+ -+#define SDIO_HOST_CTRL_TMOUT_MASK (0xf << 11) -+#define SDIO_HOST_CTRL_TMOUT_MAX (0xf << 11) -+#define SDIO_HOST_CTRL_TMOUT(x) ((x) << 11) -+#define SDIO_HOST_CTRL_TMOUT_EN (1 << 15) -+ -+#define SDIO_HOST_CTRL_DFAULT_OPEN_DRAIN \ -+ (SDIO_HOST_CTRL_TMOUT(x)(0xf)) -+#define SDIO_HOST_CTRL_DFAULT_PUSH_PULL \ -+ (SDIO_HOST_CTRL_TMOUT(x)(0xf) | SDIO_HOST_CTRL_PUSH_PULL_EN) -+ -+ -+/* -+ * NOR status bits -+ */ -+ -+#define SDIO_NOR_ERROR (1 << 15) -+#define SDIO_NOR_UNEXP_RSP (1 << 14) -+#define SDIO_NOR_AUTOCMD12_DONE (1 << 13) -+#define SDIO_NOR_SUSPEND_ON (1 << 12) -+#define SDIO_NOR_LMB_FF_8W_AVAIL (1 << 11) -+#define SDIO_NOR_LMB_FF_8W_FILLED (1 << 10) -+#define SDIO_NOR_READ_WAIT_ON (1 << 9) -+#define SDIO_NOR_CARD_INT (1 << 8) -+#define SDIO_NOR_READ_READY (1 << 5) -+#define SDIO_NOR_WRITE_READY (1 << 4) -+#define SDIO_NOR_DMA_INI (1 << 3) -+#define SDIO_NOR_BLK_GAP_EVT (1 << 2) -+#define SDIO_NOR_XFER_DONE (1 << 1) -+#define SDIO_NOR_CMD_DONE (1 << 0) -+ -+ -+/* -+ * ERR status bits -+ */ -+ -+#define SDIO_ERR_CRC_STATUS (1 << 14) -+#define SDIO_ERR_CRC_STARTBIT (1 << 13) -+#define SDIO_ERR_CRC_ENDBIT (1 << 12) -+#define SDIO_ERR_RESP_TBIT (1 << 11) -+#define SDIO_ERR_SIZE (1 << 10) -+#define SDIO_ERR_CMD_STARTBIT (1 << 9) -+#define SDIO_ERR_AUTOCMD12 (1 << 8) -+#define SDIO_ERR_DATA_ENDBIT (1 << 6) -+#define SDIO_ERR_DATA_CRC (1 << 5) -+#define SDIO_ERR_DATA_TIMEOUT (1 << 4) -+#define SDIO_ERR_CMD_INDEX (1 << 3) -+#define SDIO_ERR_CMD_ENDBIT (1 << 2) -+#define SDIO_ERR_CMD_CRC (1 << 1) -+#define SDIO_ERR_CMD_TIMEOUT (1 << 0) -+ -+#define SDIO_ERR_INTR_MASK 0xFFFF -+ -+ -+#define MMC_BLOCK_SIZE 512 -+#define MMC_CMD_RESET 0 -+#define MMC_CMD_SEND_OP_COND 1 -+#define MMC_CMD_ALL_SEND_CID 2 -+#define MMC_CMD_SET_RCA 3 -+#define MMC_CMD_SELECT_CARD 7 -+#define MMC_CMD_SEND_CSD 9 -+#define MMC_CMD_SEND_CID 10 -+#define MMC_CMD_SEND_STATUS 13 -+#define MMC_CMD_SET_BLOCKLEN 16 -+#define MMC_CMD_READ_BLOCK 17 -+#define MMC_CMD_RD_BLK_MULTI 18 -+#define MMC_CMD_WRITE_BLOCK 24 -+#define MMC_MAX_BLOCK_SIZE 512 -+ -+typedef struct mv_mmc_cid -+{ -+ /* FIXME: BYTE_ORDER */ -+ uchar year:4, -+ month:4; -+ uchar sn[3]; -+ uchar fwrev:4, -+ hwrev:4; -+ uchar name[6]; -+ uchar id[3]; -+} mv_mmc_cid_t; -+ -+typedef struct mv_mmc_csd -+{ -+ uchar ecc:2, -+ file_format:2, -+ tmp_write_protect:1, -+ perm_write_protect:1, -+ copy:1, -+ file_format_grp:1; -+ uint64_t content_prot_app:1, -+ rsvd3:4, -+ write_bl_partial:1, -+ write_bl_len:4, -+ r2w_factor:3, -+ default_ecc:2, -+ wp_grp_enable:1, -+ wp_grp_size:5, -+ erase_grp_mult:5, -+ erase_grp_size:5, -+ c_size_mult1:3, -+ vdd_w_curr_max:3, -+ vdd_w_curr_min:3, -+ vdd_r_curr_max:3, -+ vdd_r_curr_min:3, -+ c_size:12, -+ rsvd2:2, -+ dsr_imp:1, -+ read_blk_misalign:1, -+ write_blk_misalign:1, -+ read_bl_partial:1; -+ ushort read_bl_len:4, -+ ccc:12; -+ uchar tran_speed; -+ uchar nsac; -+ uchar taac; -+ uchar rsvd1:2, -+ spec_vers:4, -+ csd_structure:2; -+} mv_mmc_csd_t; -+ -+typedef struct { -+ char pnm_0; /* product name */ -+ char oid_1; /* OEM/application ID */ -+ char oid_0; -+ uint8_t mid; /* manufacturer ID */ -+ char pnm_4; -+ char pnm_3; -+ char pnm_2; -+ char pnm_1; -+ uint8_t psn_2; /* product serial number */ -+ uint8_t psn_1; -+ uint8_t psn_0; /* MSB */ -+ uint8_t prv; /* product revision */ -+ uint8_t crc; /* CRC7 checksum, b0 is unused and set to 1 */ -+ uint8_t mdt_1; /* manufacturing date, LSB, RRRRyyyy yyyymmmm */ -+ uint8_t mdt_0; /* MSB */ -+ uint8_t psn_3; /* LSB */ -+} mv_sd_cid_t; -+ -+#endif /* _MVSDIO_INCLUDE */ -diff --git a/include/configs/sheevaplug.h b/include/configs/sheevaplug.h -index 83dd8ff..7c8497c 100644 ---- a/include/configs/sheevaplug.h -+++ b/include/configs/sheevaplug.h -@@ -1,3 +1,4 @@ -+ - /* - * (C) Copyright 2009 - * Marvell Semiconductor -@@ -47,7 +48,9 @@ - #define CONFIG_CMD_DHCP - #define CONFIG_CMD_ENV - #define CONFIG_CMD_MII -+#define CONFIG_CMD_MMC - #define CONFIG_CMD_NAND -+#define CONFIG_JFFS2_NAND - #define CONFIG_CMD_PING - #define CONFIG_CMD_USB - /* -@@ -70,8 +73,8 @@ - * it has to be rounded to sector size - */ - #define CONFIG_ENV_SIZE 0x20000 /* 128k */ --#define CONFIG_ENV_ADDR 0x60000 --#define CONFIG_ENV_OFFSET 0x60000 /* env starts here */ -+#define CONFIG_ENV_ADDR 0xa0000 -+#define CONFIG_ENV_OFFSET 0xa0000 /* env starts here */ - - /* - * Default environment variables -@@ -81,10 +84,11 @@ - "${x_bootcmd_usb}; bootm 0x6400000;" - - #define CONFIG_MTDPARTS "orion_nand:512k(uboot)," \ -- "3m@1m(kernel),1m@4m(psm),13m@5m(rootfs) rw\0" -+ "0x1ff00000@512k(rootfs) rw\0" - - #define CONFIG_EXTRA_ENV_SETTINGS "x_bootargs=console" \ - "=ttyS0,115200 mtdparts="CONFIG_MTDPARTS \ -+ "mtdids=nand0=orion_nand\0" \ - "x_bootcmd_kernel=nand read 0x6400000 0x100000 0x300000\0" \ - "x_bootcmd_usb=usb start\0" \ - "x_bootargs_root=root=/dev/mtdblock3 rw rootfstype=jffs2\0" diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index ac6607daf92..cdf01002506 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -10108,14 +10108,42 @@ let tunctl = callPackage ../os-specific/linux/tunctl { }; - ubootChooser = name : if name == "upstream" then ubootUpstream - else if name == "sheevaplug" then ubootSheevaplug - else if name == "guruplug" then ubootGuruplug - else if name == "nanonote" then ubootNanonote - else throw "Unknown uboot"; + # TODO(dezgeg): either refactor & use ubootTools directly, or remove completely + ubootChooser = name: ubootTools; - ubootUpstream = callPackage ../misc/uboot { }; + # Upstream U-Boots: + ubootTools = callPackage ../misc/uboot { + toolsOnly = true; + targetPlatforms = lib.platforms.linux; + filesToInstall = ["tools/dumpimage" "tools/mkenvimage" "tools/mkimage"]; + }; + ubootJetsonTK1 = callPackage ../misc/uboot { + defconfig = "jetson-tk1_defconfig"; + targetPlatforms = ["armv7l-linux"]; + filesToInstall = ["u-boot-dtb-tegra.bin"]; + }; + + ubootPcduino3Nano = callPackage ../misc/uboot { + defconfig = "Linksprite_pcDuino3_Nano_defconfig"; + targetPlatforms = ["armv7l-linux"]; + filesToInstall = ["u-boot-sunxi-with-spl.bin"]; + }; + + ubootRaspberryPi = callPackage ../misc/uboot { + defconfig = "rpi_defconfig"; + targetPlatforms = ["armv6l-linux"]; + filesToInstall = ["u-boot.bin"]; + }; + + # Intended only for QEMU's vexpress-a9 emulation target! + ubootVersatileExpressCA9 = callPackage ../misc/uboot { + defconfig = "vexpress_ca9x4_defconfig"; + targetPlatforms = ["armv7l-linux"]; + filesToInstall = ["u-boot"]; + }; + + # Non-upstream U-Boots: ubootSheevaplug = callPackage ../misc/uboot/sheevaplug.nix { }; ubootNanonote = callPackage ../misc/uboot/nanonote.nix { }; From 0ec0790348c9788e87bd261734714d96d3e3d211 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Fri, 19 Jun 2015 06:13:34 +0300 Subject: [PATCH 4/4] U-Boot: Patch Versatile Express to use config_distro_bootcmd.h With this patch in place, ARMv7 NixOS can be booted in QEMU: qemu-system-arm -kernel u-boot -M vexpress-a9 -serial stdio -sd nixos-sd-image-armv7l-linux.img -m 1024 ...with all the features that boot.loader.generic-extlinux-compatible supports, like the boot generation menu and seamless kernel upgrades in the VM. --- pkgs/misc/uboot/default.nix | 2 + .../vexpress-Use-config_distro_bootcmd.patch | 141 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 pkgs/misc/uboot/vexpress-Use-config_distro_bootcmd.patch diff --git a/pkgs/misc/uboot/default.nix b/pkgs/misc/uboot/default.nix index 5f4bab9138f..675a6839c86 100644 --- a/pkgs/misc/uboot/default.nix +++ b/pkgs/misc/uboot/default.nix @@ -29,6 +29,8 @@ stdenv.mkDerivation rec { sha256 = "0q2x1wh1f6rjh9rmcnkf28dxcvp9hkhi4vzspqkzamb6b3gp06ha"; }; + patches = [ ./vexpress-Use-config_distro_bootcmd.patch ]; + nativeBuildInputs = [ bc dtc ]; configurePhase = '' diff --git a/pkgs/misc/uboot/vexpress-Use-config_distro_bootcmd.patch b/pkgs/misc/uboot/vexpress-Use-config_distro_bootcmd.patch new file mode 100644 index 00000000000..9c61847f02e --- /dev/null +++ b/pkgs/misc/uboot/vexpress-Use-config_distro_bootcmd.patch @@ -0,0 +1,141 @@ +From 53a8612ff19f360363edaaf70137968f7fd6a1cd Mon Sep 17 00:00:00 2001 +From: Tuomas Tynkkynen +Date: Mon, 8 Jun 2015 22:29:23 +0300 +Subject: [PATCH] vexpress: Use config_distro_bootcmd + +Also had to hack cli_readline.c, as one codepath in +cli_readline_into_buffer doesn't respect the timeout. +--- + common/cli_readline.c | 12 +++++++++++- + include/configs/vexpress_ca9x4.h | 1 - + include/configs/vexpress_common.h | 35 +++++++++++++++++++++++------------ + 3 files changed, 34 insertions(+), 14 deletions(-) + +diff --git a/common/cli_readline.c b/common/cli_readline.c +index 9a9fb35..ca997a9 100644 +--- a/common/cli_readline.c ++++ b/common/cli_readline.c +@@ -517,6 +517,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, + int plen = 0; /* prompt length */ + int col; /* output column cnt */ + char c; ++ int first = 1; + + /* print prompt */ + if (prompt) { +@@ -528,7 +529,16 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, + for (;;) { + if (bootretry_tstc_timeout()) + return -2; /* timed out */ +- WATCHDOG_RESET(); /* Trigger watchdog, if needed */ ++ if (first && timeout) { ++ uint64_t etime = endtick(timeout); ++ ++ while (!tstc()) { /* while no incoming data */ ++ if (get_ticks() >= etime) ++ return -2; /* timed out */ ++ WATCHDOG_RESET(); ++ } ++ first = 0; ++ } + + #ifdef CONFIG_SHOW_ACTIVITY + while (!tstc()) { +diff --git a/include/configs/vexpress_ca9x4.h b/include/configs/vexpress_ca9x4.h +index 38ac4ed..993398c 100644 +--- a/include/configs/vexpress_ca9x4.h ++++ b/include/configs/vexpress_ca9x4.h +@@ -13,6 +13,5 @@ + + #define CONFIG_VEXPRESS_ORIGINAL_MEMORY_MAP + #include "vexpress_common.h" +-#define CONFIG_BOOTP_VCI_STRING "U-boot.armv7.vexpress_ca9x4" + + #endif /* VEXPRESS_CA9X4_H */ +diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h +index db78c85..1dd069b 100644 +--- a/include/configs/vexpress_common.h ++++ b/include/configs/vexpress_common.h +@@ -123,7 +123,6 @@ + #define CONFIG_SYS_L2CACHE_OFF 1 + #define CONFIG_INITRD_TAG 1 + #define CONFIG_SYS_GENERIC_BOARD +-#define CONFIG_OF_LIBFDT 1 + + /* Size of malloc() pool */ + #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024) +@@ -152,6 +151,8 @@ + #define CONFIG_SYS_SERIAL0 V2M_UART0 + #define CONFIG_SYS_SERIAL1 V2M_UART1 + ++#include ++#include + /* Command line configuration */ + #define CONFIG_CMD_BDI + #define CONFIG_CMD_DHCP +@@ -169,7 +170,6 @@ + #define CONFIG_SUPPORT_RAW_INITRD + + #define CONFIG_CMD_FAT +-#define CONFIG_DOS_PARTITION 1 + #define CONFIG_MMC 1 + #define CONFIG_CMD_MMC + #define CONFIG_GENERIC_MMC +@@ -207,17 +207,28 @@ + GENERATED_GBL_DATA_SIZE) + #define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_GBL_DATA_OFFSET + ++#define BOOT_TARGET_DEVICES(func) \ ++ func(MMC, mmc, 0) ++#include ++ + /* Basic environment settings */ +-#define CONFIG_BOOTCOMMAND "run bootflash;" + #ifdef CONFIG_VEXPRESS_ORIGINAL_MEMORY_MAP ++/* ++ * RAM starts at 0x6000_0000 ++ * - U-Boot loaded @ 8M ++ * - Kernel loaded @ 32M ++ * - Initrd loaded @ 128M ++ * - DTB loaded @ 240M ++ */ + #define CONFIG_PLATFORM_ENV_SETTINGS \ +- "loadaddr=0x80008000\0" \ +- "ramdisk_addr_r=0x61000000\0" \ +- "kernel_addr=0x44100000\0" \ +- "ramdisk_addr=0x44800000\0" \ +- "maxramdisk=0x1800000\0" \ +- "pxefile_addr_r=0x88000000\0" \ +- "kernel_addr_r=0x80008000\0" ++ "fdtfile=vexpress-v2p-ca9.dtb\0" \ ++ "kernel_addr_r=0x62000000\0" \ ++ "ramdisk_addr_r=0x68000000\0" \ ++ "maxramdisk=0x06000000\0" \ ++ "fdt_addr_r=0x6f000000\0" \ ++ "loadaddr=0x70000000\0" \ ++ "pxefile_addr_r=0x71000000\0" \ ++ "scriptaddr=0x72000000\0" + #elif defined(CONFIG_VEXPRESS_EXTENDED_MEMORY_MAP) + #define CONFIG_PLATFORM_ENV_SETTINGS \ + "loadaddr=0xa0008000\0" \ +@@ -240,7 +251,8 @@ + "devtmpfs.mount=0 vmalloc=256M\0" \ + "bootflash=run flashargs; " \ + "cp ${ramdisk_addr} ${ramdisk_addr_r} ${maxramdisk}; " \ +- "bootm ${kernel_addr} ${ramdisk_addr_r}\0" ++ "bootm ${kernel_addr} ${ramdisk_addr_r}\0" \ ++ BOOTENV + + /* FLASH and environment organization */ + #define PHYS_FLASH_SIZE 0x04000000 /* 64MB */ +@@ -294,7 +306,6 @@ + #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot args buffer */ + #define CONFIG_CMD_SOURCE + #define CONFIG_SYS_LONGHELP +-#define CONFIG_CMDLINE_EDITING 1 + #define CONFIG_SYS_MAXARGS 16 /* max command args */ + + #endif /* VEXPRESS_COMMON_H */ +-- +2.4.4 +